summaryrefslogtreecommitdiffstats
path: root/test
diff options
context:
space:
mode:
Diffstat (limited to 'test')
-rw-r--r--test/CppunitTest_test_a11y.mk31
-rw-r--r--test/CppunitTest_test_xpath.mk27
-rw-r--r--test/IwyuFilter_test.yaml79
-rw-r--r--test/Library_subsequenttest.mk221
-rw-r--r--test/Library_test.mk61
-rw-r--r--test/Library_test_setupvcl.mk36
-rw-r--r--test/Library_vclbootstrapprotector.mk34
-rw-r--r--test/Makefile7
-rw-r--r--test/Module_test.mk29
-rw-r--r--test/Package_unittest.mk34
-rw-r--r--test/README.md4
-rw-r--r--test/README.vars3
-rw-r--r--test/qa/cppunit/dialog.cxx65
-rw-r--r--test/qa/cppunit/test_xpath.cxx46
-rw-r--r--test/signing-keys/cert9.dbbin0 -> 53248 bytes
-rw-r--r--test/signing-keys/key4.dbbin0 -> 49152 bytes
-rw-r--r--test/signing-keys/pkcs11.txt5
-rw-r--r--test/signing-keys/pubring.gpgbin0 -> 3060 bytes
-rw-r--r--test/signing-keys/random_seed2
-rw-r--r--test/signing-keys/secring.gpgbin0 -> 3832 bytes
-rw-r--r--test/signing-keys/test.p7b249
-rw-r--r--test/signing-keys/trustdb.gpgbin0 -> 1360 bytes
-rw-r--r--test/source/a11y/AccessibilityTools.cxx753
-rw-r--r--test/source/a11y/accessibletestbase.cxx581
-rw-r--r--test/source/a11y/eventposter.cxx46
-rw-r--r--test/source/a11y/swaccessibletestbase.cxx135
-rw-r--r--test/source/beans/xpropertyset.cxx347
-rw-r--r--test/source/bootstrapfixture.cxx281
-rw-r--r--test/source/callgrind.cxx33
-rw-r--r--test/source/chart/xchartdata.cxx97
-rw-r--r--test/source/container/xchild.cxx38
-rw-r--r--test/source/container/xelementaccess.cxx36
-rw-r--r--test/source/container/xenumeration.cxx43
-rw-r--r--test/source/container/xenumerationaccess.cxx31
-rw-r--r--test/source/container/xindexaccess.cxx55
-rw-r--r--test/source/container/xnameaccess.cxx55
-rw-r--r--test/source/container/xnamecontainer.cxx101
-rw-r--r--test/source/container/xnamed.cxx65
-rw-r--r--test/source/container/xnamereplace.cxx37
-rw-r--r--test/source/diff/README5
-rw-r--r--test/source/diff/diff.cxx416
-rw-r--r--test/source/document/xactionlockable.cxx46
-rw-r--r--test/source/document/xembeddedobjectsupplier.cxx30
-rw-r--r--test/source/document/xlinktargetsupplier.cxx30
-rw-r--r--test/source/drawing/captionshape.cxx178
-rw-r--r--test/source/drawing/xdrawpages.cxx50
-rw-r--r--test/source/drawing/xgluepointssupplier.cxx32
-rw-r--r--test/source/drawing/xshape.cxx56
-rw-r--r--test/source/drawing/xshapedescriptor.cxx30
-rw-r--r--test/source/drawing/xshapegrouper.cxx57
-rw-r--r--test/source/drawing/xshapes.cxx38
-rw-r--r--test/source/helper/form.cxx62
-rw-r--r--test/source/helper/shape.cxx71
-rw-r--r--test/source/helper/transferable.cxx82
-rw-r--r--test/source/htmltesttools.cxx39
-rw-r--r--test/source/isheadless.hxx34
-rw-r--r--test/source/lang/xcomponent.cxx77
-rw-r--r--test/source/lang/xserviceinfo.cxx48
-rw-r--r--test/source/lokcallback.cxx188
-rw-r--r--test/source/screenshot_test.cxx279
-rw-r--r--test/source/setupvcl.cxx94
-rw-r--r--test/source/setupvcl.hxx25
-rw-r--r--test/source/sheet/cellarealink.cxx114
-rw-r--r--test/source/sheet/cellproperties.cxx59
-rw-r--r--test/source/sheet/databaseimportdescriptor.cxx102
-rw-r--r--test/source/sheet/databaserange.cxx219
-rw-r--r--test/source/sheet/datapilotfield.cxx189
-rw-r--r--test/source/sheet/datapilotitem.cxx64
-rw-r--r--test/source/sheet/documentsettings.cxx183
-rw-r--r--test/source/sheet/functiondescription.cxx85
-rw-r--r--test/source/sheet/globalsheetsettings.cxx149
-rw-r--r--test/source/sheet/scenario.cxx113
-rw-r--r--test/source/sheet/shape.cxx115
-rw-r--r--test/source/sheet/sheetcell.cxx215
-rw-r--r--test/source/sheet/sheetcellrange.cxx167
-rw-r--r--test/source/sheet/sheetcellranges.cxx142
-rw-r--r--test/source/sheet/sheetfilterdescriptor.cxx151
-rw-r--r--test/source/sheet/sheetlink.cxx67
-rw-r--r--test/source/sheet/sheetsortdescriptor2.cxx123
-rw-r--r--test/source/sheet/spreadsheet.cxx90
-rw-r--r--test/source/sheet/spreadsheetdocumentsettings.cxx190
-rw-r--r--test/source/sheet/spreadsheetviewsettings.cxx251
-rw-r--r--test/source/sheet/subtotaldescriptor.cxx116
-rw-r--r--test/source/sheet/tableautoformat.cxx94
-rw-r--r--test/source/sheet/tablevalidation.cxx153
-rw-r--r--test/source/sheet/xactivationbroadcaster.cxx70
-rw-r--r--test/source/sheet/xarealink.cxx65
-rw-r--r--test/source/sheet/xarealinks.cxx50
-rw-r--r--test/source/sheet/xarrayformularange.cxx54
-rw-r--r--test/source/sheet/xcalculatable.cxx74
-rw-r--r--test/source/sheet/xcelladdressable.cxx34
-rw-r--r--test/source/sheet/xcellformatrangessupplier.cxx39
-rw-r--r--test/source/sheet/xcellrangeaddressable.cxx33
-rw-r--r--test/source/sheet/xcellrangedata.cxx95
-rw-r--r--test/source/sheet/xcellrangeformula.cxx41
-rw-r--r--test/source/sheet/xcellrangemovement.cxx120
-rw-r--r--test/source/sheet/xcellrangereferrer.cxx36
-rw-r--r--test/source/sheet/xcellrangesquery.cxx90
-rw-r--r--test/source/sheet/xcellseries.cxx114
-rw-r--r--test/source/sheet/xconsolidatable.cxx43
-rw-r--r--test/source/sheet/xconsolidationdescriptor.cxx143
-rw-r--r--test/source/sheet/xdatabaserange.cxx173
-rw-r--r--test/source/sheet/xdatabaseranges.cxx45
-rw-r--r--test/source/sheet/xdatapilotdescriptor.cxx191
-rw-r--r--test/source/sheet/xdatapilotfield.cxx40
-rw-r--r--test/source/sheet/xdatapilotfieldgrouping.cxx44
-rw-r--r--test/source/sheet/xdatapilottable.cxx48
-rw-r--r--test/source/sheet/xdatapilottable2.cxx276
-rw-r--r--test/source/sheet/xdatapilottables.cxx53
-rw-r--r--test/source/sheet/xdatapilottablessupplier.cxx29
-rw-r--r--test/source/sheet/xddelink.cxx44
-rw-r--r--test/source/sheet/xddelinks.cxx41
-rw-r--r--test/source/sheet/xdocumentauditing.cxx137
-rw-r--r--test/source/sheet/xformulaquery.cxx66
-rw-r--r--test/source/sheet/xfunctiondescriptions.cxx73
-rw-r--r--test/source/sheet/xgoalseek.cxx36
-rw-r--r--test/source/sheet/xheaderfootercontent.cxx48
-rw-r--r--test/source/sheet/xlabelrange.cxx50
-rw-r--r--test/source/sheet/xlabelranges.cxx44
-rw-r--r--test/source/sheet/xmultiformulatokens.cxx43
-rw-r--r--test/source/sheet/xmultipleoperation.cxx95
-rw-r--r--test/source/sheet/xnamedrange.cxx112
-rw-r--r--test/source/sheet/xnamedranges.cxx194
-rw-r--r--test/source/sheet/xprintareas.cxx40
-rw-r--r--test/source/sheet/xrecentfunctions.cxx77
-rw-r--r--test/source/sheet/xscenario.cxx43
-rw-r--r--test/source/sheet/xscenarioenhanced.cxx38
-rw-r--r--test/source/sheet/xscenarios.cxx43
-rw-r--r--test/source/sheet/xscenariossupplier.cxx28
-rw-r--r--test/source/sheet/xsheetannotation.cxx70
-rw-r--r--test/source/sheet/xsheetannotationanchor.cxx44
-rw-r--r--test/source/sheet/xsheetannotations.cxx212
-rw-r--r--test/source/sheet/xsheetannotationshapesupplier.cxx41
-rw-r--r--test/source/sheet/xsheetannotationssupplier.cxx30
-rw-r--r--test/source/sheet/xsheetauditing.cxx137
-rw-r--r--test/source/sheet/xsheetcellcursor.cxx138
-rw-r--r--test/source/sheet/xsheetcellrange.cxx33
-rw-r--r--test/source/sheet/xsheetcellrangecontainer.cxx101
-rw-r--r--test/source/sheet/xsheetcellranges.cxx50
-rw-r--r--test/source/sheet/xsheetcondition.cxx72
-rw-r--r--test/source/sheet/xsheetconditionalentries.cxx57
-rw-r--r--test/source/sheet/xsheetconditionalentry.cxx35
-rw-r--r--test/source/sheet/xsheetfilterable.cxx95
-rw-r--r--test/source/sheet/xsheetfilterableex.cxx59
-rw-r--r--test/source/sheet/xsheetfilterdescriptor.cxx42
-rw-r--r--test/source/sheet/xsheetfilterdescriptor2.cxx42
-rw-r--r--test/source/sheet/xsheetfilterdescriptor3.cxx42
-rw-r--r--test/source/sheet/xsheetlinkable.cxx50
-rw-r--r--test/source/sheet/xsheetoperation.cxx43
-rw-r--r--test/source/sheet/xsheetoutline.cxx264
-rw-r--r--test/source/sheet/xsheetpagebreak.cxx69
-rw-r--r--test/source/sheet/xspreadsheet.cxx40
-rw-r--r--test/source/sheet/xspreadsheetdocument.cxx32
-rw-r--r--test/source/sheet/xspreadsheets.cxx85
-rw-r--r--test/source/sheet/xspreadsheets2.cxx366
-rw-r--r--test/source/sheet/xspreadsheetview.cxx41
-rw-r--r--test/source/sheet/xsubtotalcalculatable.cxx70
-rw-r--r--test/source/sheet/xsubtotaldescriptor.cxx44
-rw-r--r--test/source/sheet/xsubtotalfield.cxx66
-rw-r--r--test/source/sheet/xuniquecellformatrangessupplier.cxx37
-rw-r--r--test/source/sheet/xusedareacursor.cxx97
-rw-r--r--test/source/sheet/xviewfreezable.cxx32
-rw-r--r--test/source/sheet/xviewpane.cxx52
-rw-r--r--test/source/sheet/xviewsplitable.cxx42
-rw-r--r--test/source/style/xstyleloader.cxx123
-rw-r--r--test/source/table/tablecolumn.cxx53
-rw-r--r--test/source/table/tablerow.cxx40
-rw-r--r--test/source/table/xcell.cxx79
-rw-r--r--test/source/table/xcellcursor.cxx126
-rw-r--r--test/source/table/xcellrange.cxx56
-rw-r--r--test/source/table/xcolumnrowrange.cxx36
-rw-r--r--test/source/table/xtablechart.cxx60
-rw-r--r--test/source/table/xtablecharts.cxx39
-rw-r--r--test/source/table/xtablechartssupplier.cxx31
-rw-r--r--test/source/table/xtablecolumns.cxx173
-rw-r--r--test/source/table/xtablerows.cxx55
-rw-r--r--test/source/text/baseindex.cxx151
-rw-r--r--test/source/text/baseindexmark.cxx45
-rw-r--r--test/source/text/documentindexmark.cxx69
-rw-r--r--test/source/text/footnote.cxx31
-rw-r--r--test/source/text/numberingrules.cxx77
-rw-r--r--test/source/text/textcontent.cxx68
-rw-r--r--test/source/text/textdocumentindex.cxx36
-rw-r--r--test/source/text/textdocumentsettings.cxx42
-rw-r--r--test/source/text/textprintersettings.cxx39
-rw-r--r--test/source/text/textsettings.cxx153
-rw-r--r--test/source/text/xautotextcontainer.cxx54
-rw-r--r--test/source/text/xdocumentindex.cxx66
-rw-r--r--test/source/text/xfootnote.cxx41
-rw-r--r--test/source/text/xsimpletext.cxx76
-rw-r--r--test/source/text/xtext.cxx29
-rw-r--r--test/source/text/xtextcontent.cxx57
-rw-r--r--test/source/text/xtextfield.cxx43
-rw-r--r--test/source/text/xtextrange.cxx61
-rw-r--r--test/source/text/xtextrangecompare.cxx76
-rw-r--r--test/source/unoapi_property_testers.cxx288
-rw-r--r--test/source/unoapi_test.cxx245
-rw-r--r--test/source/unoapixml_test.cxx36
-rw-r--r--test/source/util/searchdescriptor.cxx63
-rw-r--r--test/source/util/xindent.cxx54
-rw-r--r--test/source/util/xmergeable.cxx33
-rw-r--r--test/source/util/xrefreshable.cxx64
-rw-r--r--test/source/util/xreplaceable.cxx88
-rw-r--r--test/source/util/xreplacedescriptor.cxx37
-rw-r--r--test/source/util/xsearchable.cxx62
-rw-r--r--test/source/util/xsearchdescriptor.cxx36
-rw-r--r--test/source/vclbootstrapprotector.cxx56
-rw-r--r--test/source/view/xcontrolaccess.cxx56
-rw-r--r--test/source/view/xformlayeraccess.cxx56
-rw-r--r--test/source/xmltesttools.cxx462
-rw-r--r--test/user-template/empty-directory-dummy0
-rw-r--r--test/user-template/registry-common/modifications.xcd147
-rw-r--r--test/user-template/registry-user-ui/user-ui.xcd20
-rw-r--r--test/user-template/user/autocorr/acor_en-GB.datbin0 -> 2942 bytes
-rw-r--r--test/user-template/user/autocorr/acor_fr.datbin0 -> 9538 bytes
-rw-r--r--test/user-template/user/autotext/en-US/crdbus50.baubin0 -> 29311 bytes
-rw-r--r--test/user-template/user/autotext/en-US/standard.baubin0 -> 64398 bytes
-rw-r--r--test/user-template/user/autotext/en-US/template.baubin0 -> 45671 bytes
-rw-r--r--test/user-template/user/config/javasettingsunopkginstall.xml3
-rw-r--r--test/user-template/user/config/psetup.xpm31
-rw-r--r--test/user-template/user/config/psetupl.xpm49
-rw-r--r--test/user-template/user/config/soffice.cfg/modules/scalc/popupmenu/anchor.xml13
-rw-r--r--test/user-template/user/config/soffice.cfg/modules/scalc/popupmenu/draw.xml69
-rw-r--r--test/user-template/user/config/soffice.cfg/modules/simpress/popupmenu/page.xml49
-rw-r--r--test/user-template/user/config/soffice.cfg/modules/swriter/popupmenu/text.xml53
-rw-r--r--test/user-template/user/config/soffice.cfg/simpress/effects.xml2630
-rw-r--r--test/user-template/user/config/soffice.cfg/simpress/layoutlist.xml86
-rw-r--r--test/user-template/user/config/soffice.cfg/simpress/objectlist.xml41
-rw-r--r--test/user-template/user/config/soffice.cfg/simpress/transitions-ogl.xml48
-rw-r--r--test/user-template/user/config/soffice.cfg/simpress/transitions.xml225
-rw-r--r--test/user-template/user/database/biblio.odbbin0 -> 2687 bytes
-rw-r--r--test/user-template/user/database/biblio/biblio.dbfbin0 -> 418450 bytes
-rw-r--r--test/user-template/user/database/biblio/biblio.dbtbin0 -> 610825 bytes
-rw-r--r--test/user-template/user/wordbook/en-GB.dic46
-rw-r--r--test/user-template/user/wordbook/en-US.dic46
-rw-r--r--test/user-template/user/wordbook/sl.dic24
-rw-r--r--test/user-template/user/wordbook/technical.dic230
237 files changed, 22298 insertions, 0 deletions
diff --git a/test/CppunitTest_test_a11y.mk b/test/CppunitTest_test_a11y.mk
new file mode 100644
index 0000000000..22d1c8bc55
--- /dev/null
+++ b/test/CppunitTest_test_a11y.mk
@@ -0,0 +1,31 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# 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/.
+#
+
+$(eval $(call gb_CppunitTest_CppunitTest,test_a11y))
+
+$(eval $(call gb_CppunitTest_add_exception_objects,test_a11y, \
+ test/qa/cppunit/dialog \
+))
+
+$(eval $(call gb_CppunitTest_use_libraries,test_a11y, \
+ sal \
+ cppu \
+ subsequenttest \
+ test \
+))
+
+$(eval $(call gb_CppunitTest_use_sdk_api,test_a11y))
+$(eval $(call gb_CppunitTest_use_rdb,test_a11y,services))
+$(eval $(call gb_CppunitTest_use_ure,test_a11y))
+$(eval $(call gb_CppunitTest_use_vcl,test_a11y))
+
+$(eval $(call gb_CppunitTest_use_instdir_configuration,test_a11y))
+$(eval $(call gb_CppunitTest_use_common_configuration,test_a11y))
+
+# vim: set noet sw=4 ts=4:
diff --git a/test/CppunitTest_test_xpath.mk b/test/CppunitTest_test_xpath.mk
new file mode 100644
index 0000000000..f367410486
--- /dev/null
+++ b/test/CppunitTest_test_xpath.mk
@@ -0,0 +1,27 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# 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/.
+#
+
+$(eval $(call gb_CppunitTest_CppunitTest,test_xpath))
+
+$(eval $(call gb_CppunitTest_add_exception_objects,test_xpath, \
+ test/qa/cppunit/test_xpath \
+))
+
+$(eval $(call gb_CppunitTest_use_externals,test_xpath,\
+ libxml2 \
+))
+
+$(eval $(call gb_CppunitTest_use_libraries,test_xpath, \
+ sal \
+ test \
+))
+
+$(eval $(call gb_CppunitTest_use_sdk_api,test_xpath))
+
+# vim: set noet sw=4 ts=4:
diff --git a/test/IwyuFilter_test.yaml b/test/IwyuFilter_test.yaml
new file mode 100644
index 0000000000..572a42103d
--- /dev/null
+++ b/test/IwyuFilter_test.yaml
@@ -0,0 +1,79 @@
+---
+assumeFilename: test/source/unoapi_test.cxx
+excludelist:
+ test/source/vclbootstrapprotector.cxx:
+ # Used in Coverity-specific #ifdef
+ - sal/log.hxx
+ test/source/container/xchild.cxx:
+ # Actually used
+ - com/sun/star/uno/XInterface.hpp
+ test/source/container/xnamereplace.cxx:
+ # Actually used
+ - com/sun/star/uno/Any.hxx
+ test/source/drawing/xshape.cxx:
+ # Needed for template
+ - test/cppunitasserthelper.hxx
+ test/source/drawing/captionshape.cxx:
+ # Needed for template
+ - test/cppunitasserthelper.hxx
+ test/source/helper/shape.cxx:
+ # Actually used
+ - com/sun/star/lang/XComponent.hpp
+ test/source/sheet/databaserange.cxx:
+ # Actually used
+ - com/sun/star/sheet/XDatabaseRange.hpp
+ # Needed for template
+ - test/cppunitasserthelper.hxx
+ test/source/sheet/sheetcell.cxx:
+ # Needed for template
+ - test/cppunitasserthelper.hxx
+ test/source/sheet/sheetcellrange.cxx:
+ # Needed for template
+ - test/cppunitasserthelper.hxx
+ test/source/sheet/sheetfilterdescriptor.cxx:
+ # Needed for template
+ - test/cppunitasserthelper.hxx
+ test/source/sheet/xarealink.cxx:
+ # Needed for template
+ - test/cppunitasserthelper.hxx
+ test/source/sheet/xcalculatable.cxx:
+ # Actually used
+ - com/sun/star/table/XCell.hpp
+ test/source/sheet/xcelladdressable.cxx:
+ # Needed for template
+ - test/cppunitasserthelper.hxx
+ test/source/sheet/xcellrangereferrer.cxx:
+ # Needed for template
+ - test/cppunitasserthelper.hxx
+ test/source/sheet/xconsolidationdescriptor.cxx:
+ # Needed for template
+ - test/cppunitasserthelper.hxx
+ test/source/sheet/xdocumentauditing.cxx:
+ # Actually used
+ - com/sun/star/awt/Point.hpp
+ - com/sun/star/beans/PropertyValue.hpp
+ - com/sun/star/frame/XFrame.hpp
+ test/source/sheet/xformulaquery.cxx:
+ # Needed for template
+ - test/cppunitasserthelper.hxx
+ test/source/sheet/xlabelrange.cxx:
+ # Needed for template
+ - test/cppunitasserthelper.hxx
+ test/source/sheet/xnamedrange.cxx:
+ # Actually used
+ - com/sun/star/sheet/XNamedRange.hpp
+ test/source/sheet/xscenarioenhanced.cxx:
+ # Needed for template
+ - test/cppunitasserthelper.hxx
+ test/source/sheet/xsheetannotationanchor.cxx:
+ # Needed for template
+ - test/cppunitasserthelper.hxx
+ test/source/sheet/xsheetcellrangecontainer.cxx:
+ # Needed for template
+ - test/cppunitasserthelper.hxx
+ test/source/table/xtablechart.cxx:
+ # Needed for template
+ - test/cppunitasserthelper.hxx
+ test/source/text/textcontent.cxx:
+ # Actually used
+ - com/sun/star/text/TextContentAnchorType.hpp
diff --git a/test/Library_subsequenttest.mk b/test/Library_subsequenttest.mk
new file mode 100644
index 0000000000..f306904b32
--- /dev/null
+++ b/test/Library_subsequenttest.mk
@@ -0,0 +1,221 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# 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/.
+#
+
+$(eval $(call gb_Library_Library,subsequenttest))
+
+$(eval $(call gb_Library_set_include,subsequenttest,\
+ $$(INCLUDE) \
+))
+
+$(eval $(call gb_Library_add_defs,subsequenttest,\
+ -DOOO_DLLIMPLEMENTATION_TEST \
+))
+
+$(eval $(call gb_Library_use_common_precompiled_header,subsequenttest))
+
+$(eval $(call gb_Library_use_sdk_api,subsequenttest))
+
+$(eval $(call gb_Library_use_libraries,subsequenttest,\
+ comphelper \
+ cppu \
+ cppuhelper \
+ i18nlangtag \
+ sal \
+ sfx \
+ test \
+ tk \
+ tl \
+ utl \
+ unotest \
+ vcl \
+ docmodel \
+))
+
+$(eval $(call gb_Library_use_externals,subsequenttest,\
+ boost_headers \
+ cppunit \
+ libxml2 \
+))
+
+$(eval $(call gb_Library_add_exception_objects,subsequenttest,\
+ test/source/unoapi_test \
+ test/source/unoapixml_test \
+ test/source/a11y/AccessibilityTools \
+ test/source/a11y/accessibletestbase \
+ test/source/a11y/eventposter \
+ test/source/a11y/swaccessibletestbase \
+ test/source/beans/xpropertyset \
+ test/source/chart/xchartdata \
+ test/source/container/xchild \
+ test/source/container/xelementaccess \
+ test/source/container/xenumeration \
+ test/source/container/xenumerationaccess \
+ test/source/container/xindexaccess \
+ test/source/container/xnameaccess \
+ test/source/container/xnamecontainer \
+ test/source/container/xnamed \
+ test/source/container/xnamereplace \
+ test/source/document/xactionlockable \
+ test/source/document/xembeddedobjectsupplier \
+ test/source/document/xlinktargetsupplier \
+ test/source/drawing/captionshape \
+ test/source/drawing/xdrawpages \
+ test/source/drawing/xgluepointssupplier \
+ test/source/drawing/xshapedescriptor \
+ test/source/drawing/xshapegrouper \
+ test/source/drawing/xshape \
+ test/source/drawing/xshapes \
+ test/source/lang/xserviceinfo \
+ test/source/lang/xcomponent \
+ test/source/sheet/cellarealink \
+ test/source/sheet/cellproperties \
+ test/source/sheet/databaseimportdescriptor \
+ test/source/sheet/databaserange \
+ test/source/sheet/datapilotfield \
+ test/source/sheet/datapilotitem \
+ test/source/sheet/documentsettings \
+ test/source/sheet/functiondescription \
+ test/source/sheet/globalsheetsettings \
+ test/source/sheet/scenario \
+ test/source/sheet/shape \
+ test/source/sheet/sheetcell \
+ test/source/sheet/sheetcellrange \
+ test/source/sheet/sheetcellranges \
+ test/source/sheet/sheetfilterdescriptor \
+ test/source/sheet/sheetlink \
+ test/source/sheet/sheetsortdescriptor2 \
+ test/source/sheet/spreadsheet \
+ test/source/sheet/spreadsheetdocumentsettings \
+ test/source/sheet/spreadsheetviewsettings \
+ test/source/sheet/subtotaldescriptor \
+ test/source/sheet/tableautoformat \
+ test/source/sheet/tablevalidation \
+ test/source/sheet/xactivationbroadcaster \
+ test/source/sheet/xarealink \
+ test/source/sheet/xarealinks \
+ test/source/sheet/xarrayformularange \
+ test/source/sheet/xcalculatable \
+ test/source/sheet/xcelladdressable \
+ test/source/sheet/xcellformatrangessupplier \
+ test/source/sheet/xcellrangeaddressable \
+ test/source/sheet/xcellrangedata \
+ test/source/sheet/xcellrangeformula \
+ test/source/sheet/xcellrangemovement \
+ test/source/sheet/xcellrangereferrer \
+ test/source/sheet/xcellrangesquery \
+ test/source/sheet/xcellseries \
+ test/source/sheet/xconsolidatable \
+ test/source/sheet/xconsolidationdescriptor \
+ test/source/sheet/xdatabaserange \
+ test/source/sheet/xdatabaseranges \
+ test/source/sheet/xdatapilotdescriptor \
+ test/source/sheet/xdatapilotfield \
+ test/source/sheet/xdatapilotfieldgrouping \
+ test/source/sheet/xdatapilottable \
+ test/source/sheet/xdatapilottable2 \
+ test/source/sheet/xdatapilottables \
+ test/source/sheet/xdatapilottablessupplier \
+ test/source/sheet/xddelink \
+ test/source/sheet/xddelinks \
+ test/source/sheet/xdocumentauditing \
+ test/source/sheet/xformulaquery \
+ test/source/sheet/xfunctiondescriptions \
+ test/source/sheet/xgoalseek \
+ test/source/sheet/xheaderfootercontent \
+ test/source/sheet/xlabelrange \
+ test/source/sheet/xlabelranges \
+ test/source/sheet/xmultiformulatokens \
+ test/source/sheet/xmultipleoperation \
+ test/source/sheet/xnamedrange \
+ test/source/sheet/xnamedranges \
+ test/source/sheet/xprintareas \
+ test/source/sheet/xrecentfunctions \
+ test/source/sheet/xscenario \
+ test/source/sheet/xscenarioenhanced \
+ test/source/sheet/xscenarios \
+ test/source/sheet/xscenariossupplier \
+ test/source/sheet/xsheetannotation \
+ test/source/sheet/xsheetannotationanchor \
+ test/source/sheet/xsheetannotations \
+ test/source/sheet/xsheetannotationshapesupplier \
+ test/source/sheet/xsheetannotationssupplier \
+ test/source/sheet/xsheetauditing \
+ test/source/sheet/xsheetcellcursor \
+ test/source/sheet/xsheetcellrange \
+ test/source/sheet/xsheetcellrangecontainer \
+ test/source/sheet/xsheetcellranges \
+ test/source/sheet/xsheetcondition \
+ test/source/sheet/xsheetconditionalentries \
+ test/source/sheet/xsheetconditionalentry \
+ test/source/sheet/xsheetfilterable \
+ test/source/sheet/xsheetfilterableex \
+ test/source/sheet/xsheetfilterdescriptor \
+ test/source/sheet/xsheetfilterdescriptor2 \
+ test/source/sheet/xsheetfilterdescriptor3 \
+ test/source/sheet/xsheetlinkable \
+ test/source/sheet/xsheetoperation \
+ test/source/sheet/xsheetoutline \
+ test/source/sheet/xsheetpagebreak \
+ test/source/sheet/xspreadsheet \
+ test/source/sheet/xspreadsheetdocument \
+ test/source/sheet/xspreadsheets \
+ test/source/sheet/xspreadsheets2 \
+ test/source/sheet/xspreadsheetview \
+ test/source/sheet/xsubtotalcalculatable \
+ test/source/sheet/xsubtotaldescriptor \
+ test/source/sheet/xsubtotalfield \
+ test/source/sheet/xuniquecellformatrangessupplier\
+ test/source/sheet/xusedareacursor \
+ test/source/sheet/xviewfreezable \
+ test/source/sheet/xviewpane \
+ test/source/sheet/xviewsplitable \
+ test/source/style/xstyleloader \
+ test/source/table/tablecolumn \
+ test/source/table/tablerow \
+ test/source/table/xcell \
+ test/source/table/xcellcursor \
+ test/source/table/xcellrange \
+ test/source/table/xcolumnrowrange \
+ test/source/table/xtablechart \
+ test/source/table/xtablecharts \
+ test/source/table/xtablechartssupplier \
+ test/source/table/xtablecolumns \
+ test/source/table/xtablerows \
+ test/source/text/baseindex \
+ test/source/text/baseindexmark \
+ test/source/text/documentindexmark \
+ test/source/text/numberingrules \
+ test/source/text/footnote \
+ test/source/text/textcontent \
+ test/source/text/xautotextcontainer \
+ test/source/text/xfootnote \
+ test/source/text/xsimpletext \
+ test/source/text/xtext \
+ test/source/text/xtextcontent \
+ test/source/text/xtextfield \
+ test/source/text/xtextrange \
+ test/source/text/xtextrangecompare \
+ test/source/text/xdocumentindex \
+ test/source/text/textdocumentsettings \
+ test/source/text/textprintersettings \
+ test/source/text/textsettings \
+ test/source/text/textdocumentindex \
+ test/source/util/searchdescriptor \
+ test/source/util/xindent \
+ test/source/util/xmergeable \
+ test/source/util/xrefreshable \
+ test/source/util/xreplaceable \
+ test/source/util/xreplacedescriptor \
+ test/source/util/xsearchable \
+ test/source/util/xsearchdescriptor \
+ test/source/view/xcontrolaccess \
+ test/source/view/xformlayeraccess \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/test/Library_test.mk b/test/Library_test.mk
new file mode 100644
index 0000000000..268a68744e
--- /dev/null
+++ b/test/Library_test.mk
@@ -0,0 +1,61 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# 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/.
+#
+
+$(eval $(call gb_Library_Library,test))
+
+$(eval $(call gb_Library_set_include,test,\
+ $$(INCLUDE) \
+))
+
+$(eval $(call gb_Library_add_defs,test,\
+ -DOOO_DLLIMPLEMENTATION_TEST \
+))
+
+$(eval $(call gb_Library_use_sdk_api,test))
+
+$(eval $(call gb_Library_use_externals,test,\
+ boost_headers \
+ cppunit \
+ libxml2 \
+ valgrind \
+))
+
+$(eval $(call gb_Library_use_libraries,test,\
+ basegfx \
+ comphelper \
+ cppu \
+ cppuhelper \
+ i18nlangtag \
+ sal \
+ sfx \
+ svt \
+ test-setupvcl \
+ tl \
+ utl \
+ unotest \
+ vcl \
+ drawinglayer \
+ drawinglayercore \
+))
+
+$(eval $(call gb_Library_add_exception_objects,test,\
+ test/source/bootstrapfixture \
+ test/source/diff/diff \
+ test/source/callgrind \
+ test/source/xmltesttools \
+ test/source/htmltesttools \
+ test/source/screenshot_test \
+ test/source/unoapi_property_testers \
+ test/source/lokcallback \
+ test/source/helper/form \
+ test/source/helper/shape \
+ test/source/helper/transferable \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/test/Library_test_setupvcl.mk b/test/Library_test_setupvcl.mk
new file mode 100644
index 0000000000..16f79ddf3a
--- /dev/null
+++ b/test/Library_test_setupvcl.mk
@@ -0,0 +1,36 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# 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/.
+#
+
+$(eval $(call gb_Library_Library,test-setupvcl))
+
+$(eval $(call gb_Library_add_defs,test-setupvcl,\
+ -DOOO_DLLIMPLEMENTATION_TEST_SETUPVCL \
+))
+
+$(eval $(call gb_Library_add_exception_objects,test-setupvcl, \
+ test/source/setupvcl \
+))
+
+$(eval $(call gb_Library_use_externals,test-setupvcl, \
+ boost_headers \
+))
+
+$(eval $(call gb_Library_use_libraries,test-setupvcl, \
+ comphelper \
+ cppu \
+ i18nlangtag \
+ sal \
+ tl \
+ utl \
+ vcl \
+))
+
+$(eval $(call gb_Library_use_sdk_api,test-setupvcl))
+
+# vim: set noet sw=4 ts=4:
diff --git a/test/Library_vclbootstrapprotector.mk b/test/Library_vclbootstrapprotector.mk
new file mode 100644
index 0000000000..d01bc66795
--- /dev/null
+++ b/test/Library_vclbootstrapprotector.mk
@@ -0,0 +1,34 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# 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/.
+#
+
+$(eval $(call gb_Library_Library,vclbootstrapprotector))
+
+$(eval $(call gb_Library_add_exception_objects,vclbootstrapprotector, \
+ test/source/vclbootstrapprotector \
+))
+
+$(eval $(call gb_Library_use_externals,vclbootstrapprotector, \
+ boost_headers \
+ cppunit \
+))
+
+$(eval $(call gb_Library_use_libraries,vclbootstrapprotector, \
+ comphelper \
+ cppu \
+ i18nlangtag \
+ sal \
+ test-setupvcl \
+ tl \
+ utl \
+ vcl \
+))
+
+$(eval $(call gb_Library_use_sdk_api,vclbootstrapprotector))
+
+# vim: set noet sw=4 ts=4:
diff --git a/test/Makefile b/test/Makefile
new file mode 100644
index 0000000000..ccb1c85a04
--- /dev/null
+++ b/test/Makefile
@@ -0,0 +1,7 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+
+module_directory:=$(dir $(realpath $(firstword $(MAKEFILE_LIST))))
+
+include $(module_directory)/../solenv/gbuild/partial_build.mk
+
+# vim: set noet sw=4 ts=4:
diff --git a/test/Module_test.mk b/test/Module_test.mk
new file mode 100644
index 0000000000..99e7229051
--- /dev/null
+++ b/test/Module_test.mk
@@ -0,0 +1,29 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# 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/.
+#
+
+$(eval $(call gb_Module_Module,test))
+
+ifneq (,$(filter DESKTOP,$(BUILD_TYPE)))
+
+$(eval $(call gb_Module_add_targets,test,\
+ Library_test \
+ Library_test_setupvcl \
+ Library_subsequenttest \
+ Library_vclbootstrapprotector \
+ Package_unittest \
+))
+
+$(eval $(call gb_Module_add_check_targets,test,\
+ CppunitTest_test_a11y \
+ CppunitTest_test_xpath \
+))
+
+endif
+
+# vim: set noet sw=4 ts=4:
diff --git a/test/Package_unittest.mk b/test/Package_unittest.mk
new file mode 100644
index 0000000000..a187fcf8b1
--- /dev/null
+++ b/test/Package_unittest.mk
@@ -0,0 +1,34 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# 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/.
+#
+
+$(eval $(call gb_Package_Package,test_unittest,$(SRCDIR)/test/user-template))
+
+$(eval $(call gb_Package_set_outdir,test_unittest,$(WORKDIR)))
+
+$(eval $(call gb_Package_add_file,test_unittest,unittest/registry-common/modifications.xcd,registry-common/modifications.xcd))
+$(eval $(call gb_Package_add_file,test_unittest,unittest/registry-user-ui/user-ui.xcd,registry-user-ui/user-ui.xcd))
+$(eval $(call gb_Package_add_file,test_unittest,unittest/user/wordbook/sl.dic,user/wordbook/sl.dic))
+$(eval $(call gb_Package_add_file,test_unittest,unittest/user/wordbook/en-US.dic,user/wordbook/en-US.dic))
+$(eval $(call gb_Package_add_file,test_unittest,unittest/user/database/biblio.odb,user/database/biblio.odb))
+$(eval $(call gb_Package_add_file,test_unittest,unittest/user/database/biblio/biblio.dbf,user/database/biblio/biblio.dbf))
+$(eval $(call gb_Package_add_file,test_unittest,unittest/user/database/biblio/biblio.dbt,user/database/biblio/biblio.dbt))
+$(eval $(call gb_Package_add_file,test_unittest,unittest/user/wordbook/technical.dic,user/wordbook/technical.dic))
+$(eval $(call gb_Package_add_file,test_unittest,unittest/user/wordbook/en-GB.dic,user/wordbook/en-GB.dic))
+$(eval $(call gb_Package_add_file,test_unittest,unittest/user/autotext/en-US/template.bau,user/autotext/en-US/template.bau))
+$(eval $(call gb_Package_add_file,test_unittest,unittest/user/autotext/en-US/standard.bau,user/autotext/en-US/standard.bau))
+$(eval $(call gb_Package_add_file,test_unittest,unittest/user/autotext/en-US/crdbus50.bau,user/autotext/en-US/crdbus50.bau))
+$(eval $(call gb_Package_add_file,test_unittest,unittest/user/config/soffice.cfg/.dummy,empty-directory-dummy))
+$(eval $(call gb_Package_add_file,test_unittest,unittest/user/autocorr/acor_en-US.dat,user/autocorr/acor_fr.dat))
+$(eval $(call gb_Package_add_file,test_unittest,unittest/user/autocorr/acor_en-GB.dat,user/autocorr/acor_en-GB.dat))
+$(eval $(call gb_Package_add_file,test_unittest,unittest/user/config/soffice.cfg/modules/scalc/popupmenu/draw.xml,user/config/soffice.cfg/modules/scalc/popupmenu/draw.xml))
+$(eval $(call gb_Package_add_file,test_unittest,unittest/user/config/soffice.cfg/modules/scalc/popupmenu/anchor.xml,user/config/soffice.cfg/modules/scalc/popupmenu/anchor.xml))
+$(eval $(call gb_Package_add_file,test_unittest,unittest/user/config/soffice.cfg/modules/swriter/popupmenu/text.xml,user/config/soffice.cfg/modules/swriter/popupmenu/text.xml))
+$(eval $(call gb_Package_add_file,test_unittest,unittest/user/config/soffice.cfg/modules/simpress/popupmenu/page.xml,user/config/soffice.cfg/modules/simpress/popupmenu/page.xml))
+
+# vim: set noet sw=4 ts=4:
diff --git a/test/README.md b/test/README.md
new file mode 100644
index 0000000000..0845e3f735
--- /dev/null
+++ b/test/README.md
@@ -0,0 +1,4 @@
+# Test Harness Code for C++ Unit Testing
+
+Many of these tests are run during the build process. In that case on
+unix, if a test fails follow the error messages to debug it under `gdb`.
diff --git a/test/README.vars b/test/README.vars
new file mode 100644
index 0000000000..2157d9497d
--- /dev/null
+++ b/test/README.vars
@@ -0,0 +1,3 @@
+Environment variables in VCL:
+
+LO_TEST_LOCALE - the locale to be used during unit tests. Defaults to en-US.
diff --git a/test/qa/cppunit/dialog.cxx b/test/qa/cppunit/dialog.cxx
new file mode 100644
index 0000000000..eb6996fa68
--- /dev/null
+++ b/test/qa/cppunit/dialog.cxx
@@ -0,0 +1,65 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * 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 <test/a11y/accessibletestbase.hxx>
+
+// FIXME: dialog API doesn't work on macos yet
+#if !defined(MACOSX)
+
+/* Checks an unexpected dialog opening (instead of the expected one) is properly caught, as it would
+ * otherwise block the test potentially indefinitely */
+CPPUNIT_TEST_FIXTURE(test::AccessibleTestBase, SelfTestIncorrectDialog)
+{
+ load(u"private:factory/swriter"_ustr);
+
+ auto dialogWaiter = awaitDialog(u"This Dialog Does Not Exist", [](Dialog&) {
+ CPPUNIT_ASSERT_MESSAGE("This code should not be reached", false);
+ });
+
+ CPPUNIT_ASSERT(activateMenuItem(u"Insert", u"Section..."));
+ /* Make sure an incorrect dialog popping up is caught and raises. The exception is thrown in
+ * waitEndDialog() for consistency even though the error itself is likely to have been triggered
+ * by the activateMenuItem() call above */
+ CPPUNIT_ASSERT_THROW(dialogWaiter->waitEndDialog(), css::uno::RuntimeException);
+}
+
+/* Checks that an exception in the dialog callback code is properly handled and won't disturb
+ * subsequent tests if caught -- especially that DialogWaiter::waitEndDialog() won't timeout. */
+CPPUNIT_TEST_FIXTURE(test::AccessibleTestBase, SelfTestThrowInDialogCallback)
+{
+ load(u"private:factory/swriter"_ustr);
+
+ class DummyException : public std::exception
+ {
+ };
+
+ auto dialogWaiter = awaitDialog(u"Hyperlink", [](Dialog&) { throw DummyException(); });
+
+ CPPUNIT_ASSERT(activateMenuItem(u"Insert", u"Hyperlink..."));
+ CPPUNIT_ASSERT_THROW(dialogWaiter->waitEndDialog(), DummyException);
+}
+
+// Checks timeout if dialog does not show up as expected
+CPPUNIT_TEST_FIXTURE(test::AccessibleTestBase, SelfTestNoDialog)
+{
+ load(u"private:factory/swriter"_ustr);
+
+ auto dialogWaiter = awaitDialog(u"This Dialog Did Not Show Up", [](Dialog&) {
+ CPPUNIT_ASSERT_MESSAGE("This code should not be reached", false);
+ });
+
+ // as we don't actually call any dialog up, this should fail after a timeout
+ CPPUNIT_ASSERT(!dialogWaiter->waitEndDialog());
+}
+
+#endif //defined(MACOSX)
+
+CPPUNIT_PLUGIN_IMPLEMENT();
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/test/qa/cppunit/test_xpath.cxx b/test/qa/cppunit/test_xpath.cxx
new file mode 100644
index 0000000000..8d105dd4ea
--- /dev/null
+++ b/test/qa/cppunit/test_xpath.cxx
@@ -0,0 +1,46 @@
+/* -*- 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/types.h>
+#include <test/xmltesttools.hxx>
+
+#include <cppunit/TestFixture.h>
+#include <cppunit/extensions/HelperMacros.h>
+#include <cppunit/plugin/TestPlugIn.h>
+
+class TestXPath : public CppUnit::TestFixture, public XmlTestTools
+{
+};
+
+CPPUNIT_TEST_FIXTURE(TestXPath, test_getXPath)
+{
+ const xmlChar s_xml[] = "<?xml version='1.0' encoding='UTF-8' standalone='yes'?>"
+ "<xml><item attrib='val'>text</item></xml>";
+ xmlDocUniquePtr pTable(xmlParseDoc(s_xml));
+ CPPUNIT_ASSERT(pTable);
+ // Must get existing element content without errors
+ CPPUNIT_ASSERT_ASSERTION_PASS(assertXPath(pTable, "/xml/item"_ostr));
+ // Must error out when getting non-existing element
+ CPPUNIT_ASSERT_ASSERTION_FAIL(assertXPath(pTable, "/xml/no_item"_ostr));
+ // Must get existing attribute value correctly
+ CPPUNIT_ASSERT_ASSERTION_PASS(getXPath(pTable, "/xml/item"_ostr, "attrib"_ostr));
+ // Must fail when requested non-empty attribute doesn't exist
+ CPPUNIT_ASSERT_ASSERTION_FAIL(getXPath(pTable, "/xml/item"_ostr, "no_attrib"_ostr));
+ // Must properly return attribute content
+ CPPUNIT_ASSERT_EQUAL(OUString("val"), getXPath(pTable, "/xml/item"_ostr, "attrib"_ostr));
+ // Trying to get position of missing child of a node must fail assertion
+ CPPUNIT_ASSERT_ASSERTION_FAIL(getXPathPosition(pTable, "/xml/item"_ostr, "absent"));
+ // Asserting that an attribute is absent
+ CPPUNIT_ASSERT_ASSERTION_FAIL(assertXPathNoAttribute(pTable, "/xml/item"_ostr, "attrib"_ostr));
+ CPPUNIT_ASSERT_ASSERTION_PASS(assertXPathNoAttribute(pTable, "/xml/item"_ostr, "foo"_ostr));
+}
+
+CPPUNIT_PLUGIN_IMPLEMENT();
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/test/signing-keys/cert9.db b/test/signing-keys/cert9.db
new file mode 100644
index 0000000000..c4064e419f
--- /dev/null
+++ b/test/signing-keys/cert9.db
Binary files differ
diff --git a/test/signing-keys/key4.db b/test/signing-keys/key4.db
new file mode 100644
index 0000000000..34a7fa28aa
--- /dev/null
+++ b/test/signing-keys/key4.db
Binary files differ
diff --git a/test/signing-keys/pkcs11.txt b/test/signing-keys/pkcs11.txt
new file mode 100644
index 0000000000..22c8f8519e
--- /dev/null
+++ b/test/signing-keys/pkcs11.txt
@@ -0,0 +1,5 @@
+library=
+name=NSS Internal PKCS #11 Module
+parameters=configdir='sql:test/new' certPrefix='' keyPrefix='' secmod='secmod.db' flags= updatedir='' updateCertPrefix='' updateKeyPrefix='' updateid='' updateTokenDescription=''
+NSS=Flags=internal,critical trustOrder=75 cipherOrder=100 slotParams=(1={slotFlags=[ECC,RSA,DSA,DH,RC2,RC4,DES,RANDOM,SHA1,MD5,MD2,SSL,TLS,AES,Camellia,SEED,SHA256,SHA512] askpw=any timeout=30})
+
diff --git a/test/signing-keys/pubring.gpg b/test/signing-keys/pubring.gpg
new file mode 100644
index 0000000000..007ea98afd
--- /dev/null
+++ b/test/signing-keys/pubring.gpg
Binary files differ
diff --git a/test/signing-keys/random_seed b/test/signing-keys/random_seed
new file mode 100644
index 0000000000..8e68109a88
--- /dev/null
+++ b/test/signing-keys/random_seed
@@ -0,0 +1,2 @@
+°Á,A? ´ p£Ôj`\ÚGkV¿feTâ*ì;¼^hÌFÖ™¾3µ}‡²´iõÅsAØr¾‘9©B´h¡oWF€æÀ! !‹7(â;9µ±xÚ*L¯zY„¡8=ë#ç6æñÇï3ˆY&](^“浊4änZ?ålÿ.÷®ÔÓïØ‹}Öµ]¡5w6!Ç?ç¼l†ãÁ'%k©.^,IfÏVîVÏÓ ¥'_R!QºéUݪiDöUZ" ¦ö°­Z°$R^Mf“Øç— àï )_~»‰ñûw‡oʇÃ6–c©3ž/ CÌñ÷Åù*‰EÅ;BzQ"MÛúÖ¶QCú-é× Òí¾¼'…Ý•y ³$…ë_ ӛϟ!^s2zht¯LÇNÖ;¼©Íè¶\ûÁÅ«çÌ 0m冑øöG¼÷9õ‘M_­®“'ÕÆm‡(K·HÏ|‚ñôôŠ®ÌézšŸU ;0žAz|ñ½°§8‘òX‡=aÙHºX>cÂ4&›Å6¢ãÜkñÓ/TìCä–Æýš¿sÈÀÊ_‘O`ä %M–{UDš çù¸– “{Ô;[cV9Ä]!ýf@—û(p˜^ÝÐ[ÿî‡híÌáyòöséTäëotf(«Ž"™Î(×qN²©—c¤r ÚÓ½aµÔÐÜŸµ ‡Û›§õ·³*³?Œ>õYC6Å“øaŽ%'Ë]Ìi=g¯lR
+/R°?uÿâñ âê7[ÄF (È \ No newline at end of file
diff --git a/test/signing-keys/secring.gpg b/test/signing-keys/secring.gpg
new file mode 100644
index 0000000000..f7626df5ae
--- /dev/null
+++ b/test/signing-keys/secring.gpg
Binary files differ
diff --git a/test/signing-keys/test.p7b b/test/signing-keys/test.p7b
new file mode 100644
index 0000000000..44723697a2
--- /dev/null
+++ b/test/signing-keys/test.p7b
@@ -0,0 +1,249 @@
+-----BEGIN PKCS7-----
+MIIuNgYJKoZIhvcNAQcCoIIuJzCCLiMCAQExADALBgkqhkiG9w0BBwGggi4LMIIF
+sjCCA5qgAwIBAgICEAAwDQYJKoZIhvcNAQELBQAwZTELMAkGA1UEBhMCVUsxEDAO
+BgNVBAgMB0VuZ2xhbmQxHTAbBgNVBAoMFFhtbHNlY3VyaXR5IFJTQSBUZXN0MSUw
+IwYDVQQDDBxYbWxzZWN1cml0eSBSU0EgVGVzdCBSb290IENBMCAXDTE4MDYwNjE1
+MjAwNloYDzIxMTgwNTEzMTUyMDA2WjBpMQswCQYDVQQGEwJVSzEQMA4GA1UECAwH
+RW5nbGFuZDEdMBsGA1UECgwUWG1sc2VjdXJpdHkgUlNBIFRlc3QxKTAnBgNVBAMM
+IFhtbHNlY3VyaXR5IEludGVybWVkaWF0ZSBSb290IENBMIICIjANBgkqhkiG9w0B
+AQEFAAOCAg8AMIICCgKCAgEA+uBkXt39Yc0aOe2UkBWlVIqQcvlSwLheXlcGeDDI
+PSwSRaDcuGdGQXs+WFM65xDak8eZJwyyQSWtoDRV0lXEP63OJk/ktWLjFywLP69g
+Br2E4vsjOdr9DR94AAQY2WTW2/UXxcI92nB+sq6ZhVF5I9rfzDHPGYEiWTQqtnTM
+JDGpO5eo9JBjQtaB/sHG7ZnxF1FOl6V85F/dfGG3MBGp9glg5qE6QDjA11DsTuki
+V5OeP8vZsmoYkyNmViA7L+xuOM6iVUGY+b4XDCeI1Kgr5ZhF9xL7ByVTxtZrdMXz
+cPu+Dgcr9VF7QqhAYg/W/0s4WzoyXV/f1fjC5+uKXWSuttrRHNt16DMOh5T1lS4q
+HLfMoDYZ+AK8L0JrjQMXCzCp4WTmqplBg6bYWFpHvyzp0uccYJdUXv5o6PFhpIV6
+VpdVtT6fVfh9V5C5jDKBv+n14rZ9hPYzvIxVAnF6SYtXRTbrSzSDi5QqCiWwU56u
+SAWyyrwdED1zETgTDmGOFv5j2tIEcAbQ6TT8n/Mit5NuL98M5XxPnKduCQ39ssKD
+wO146lAe5kREJRv4Va/o47tards6tdkaV5267rXZA7ndvnov0TmZFNwDMQz9tRZJ
+ov07V7kriLS47xD/eDH7IyEOWYsgoU3N1J1GZKCYSRxZ3Wh6AiZy211PYwuJpP3x
+ugUCAwEAAaNmMGQwHQYDVR0OBBYEFDXB8g347TUPMvCNXTBSRQpVRvroMB8GA1Ud
+IwQYMBaAFOOqggO/I6PkIyJZqJ16mbDbtiXxMBIGA1UdEwEB/wQIMAYBAf8CAQAw
+DgYDVR0PAQH/BAQDAgGGMA0GCSqGSIb3DQEBCwUAA4ICAQAiyaCtGnPZRsfGD69y
+jkPptc6cwa8icyF9iiJwdngjvdMTCOJHhUAtzGTOuUITJEh0OJYzabB+EUgHmZWe
+6hwrWCzhJQysDktdsARQOB91Vi19VyDrcHPxnn43zObnbkLpFvZXg3Q3/S+eiTn/
+UWMg7f2tQjaCdj6xx1DGTiJmZBRI/CG24EWzYy+H7/MBNFuW3+1CdoDuPR3lkbWm
+YFJbvkOaWR8+faL6o5u7IagKCSmMaNDjRQA8/LKwJ8waD61Hw4S4H465I16UVCT4
+d226anZIfz7N3/NbVw0B8emJP1ZtVty1vDPEx/6A7+sXfgAYgjfMeiHhGHs17i2d
+7EvdwxlyvKq/iQkLMzkyAkA5kpUbZ/kpOQh8sR9JHxv3QEz0clRvRIwlJU5W+Pa1
+e3dNYTDR9x0fBaLwPUIc5RnnSZ5Aws2qxnp7yYrQzxTtLd3IoDU4BuuyBE+/Pauk
+bbfJUnr+e9Pwt+OXqrECnhxz+f0FDAMlX0CEe7Vlx8p37roBiT4sf3anXrNyrUZM
+QWQFLs9H3+yooEJJWTgs7QjFZ0l5LIQyTv1I4UmGBgEWlW8UNIJhvAeq1ykY+WZw
+At9JDlNwiAbFbFoMqGkVZDko1foTE8KUJfgth63ZmdWw1yzX8H9+zDlhpHCehJsJ
+68Rk7INjBNZr6IxpVViGLsW1qTCCBbgwggOgoAMCAQICAhAAMA0GCSqGSIb3DQEB
+CwUAMGkxCzAJBgNVBAYTAlVLMRAwDgYDVQQIDAdFbmdsYW5kMR8wHQYDVQQKDBZY
+bWxzZWN1cml0eSBFQ0RTQSBUZXN0MScwJQYDVQQDDB5YbWxzZWN1cml0eSBFQ0RT
+QSBUZXN0IFJvb3QgQ0EwIBcNMTgwNjA2MTUyMDIxWhgPMjExODA1MTMxNTIwMjFa
+MGsxCzAJBgNVBAYTAlVLMRAwDgYDVQQIDAdFbmdsYW5kMR8wHQYDVQQKDBZYbWxz
+ZWN1cml0eSBFQ0RTQSBUZXN0MSkwJwYDVQQDDCBYbWxzZWN1cml0eSBJbnRlcm1l
+ZGlhdGUgUm9vdCBDQTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAKlB
+Wij1qE0sYqzYZ8p9FAejgwuf0npT2uplFdq2VZGJaMRS+dbbxnjAh7N78q8aSkag
+kYOQcWtp/XmBCAsGC7D5MA+H6eyPAfZdnb+CycwGkvTH3CfJHCS9QVHRk4HGmAgO
+DEQtLzA5z65wrfZDD5utBtItWd5brhjDQTROmfjbm7t4V/+2uTr94WrMvykj5Cye
+vo2VeAz/zjJIgN+eNQwGnCZWWpITwzq6II4oUIz+/oHSHox4Q8s0XdjXpkfvZfN4
+lVOXlqnUC3pZEPSn4siJEkw26s5fwt9oeoyGDWoKPZmy9jlkxIOiaBz8RAGYPsSS
+sfZ28w0XCxG70WIzOBbLe5IuCGzpv7jzygAWjSVxeyVuGFs1ev8t77Ij/9wPXg0c
+tDclq/nGqIWBNsXFezUpmf0Pjp/owUOmdE+eX7IiPHCqiqyZAzk8NmQTz81UfzA5
+gemdXY1PwXj1ubIM80oLynGmgyWGP4QQJKk2X0o6iLKIkjJzf0VG7kz6pd/MryJC
+esPAdHJ5XkGsOcNDTGxJrVcHii91puRkllIUB/Pa99R6/tDdNpwfsQHbVydhknLt
+lPzQaL04Jx8qglFxS6UGVXThGe809s9KOjCI8jw9+k9u1Aj1XeEtrqXe1bkUbtgP
+UPb0OS9pZbzEEH8ayKQ9mZX/AxCGBSKnkeYn1ywvAgMBAAGjZjBkMB0GA1UdDgQW
+BBTQTJbg+FLm6ZFV0dKdvzzzxEgyRzAfBgNVHSMEGDAWgBQgN6w+MdwLFedzVTyQ
+o/oFcYBa1TASBgNVHRMBAf8ECDAGAQH/AgEAMA4GA1UdDwEB/wQEAwIBhjANBgkq
+hkiG9w0BAQsFAAOCAgEAQArGH6CD7ouqF8lg3apFkGl2jnutJdRLtCfGt2iwAxZo
+DArpQyYw5OGvbr8J9DTf4jdGFsjDTK4Ir82B6nUWCJuOnf7leuG1CsPLFL9QYhK/
+JJCO3hgqDPJqxsF1wtNMCowTTo71wdOLIUnIiKVULEJ55YHGvUjv9ufDUMhtViEj
+lA0TLjLMk1NQDi8wArZ0uR71yoqsjkQcwqXanmmE/iQU/wJSEtTtlHgXNeHR35Sr
+mSqBinCfIIxab6zGsq8TrnkDlpxCZ+5I70Ly65WAvrmGn4a9mm96F0UpXlllCtg9
+AAC/cIydTZlwLxsM+wgMAVuEPHC6njnubregPvhiVs0Bx2o+IIdZT6vqlheD4GdA
+DB7m9yOV9sS2VSjD7yuH76FtfybJZvm5MEdIatgxqnWSQH+uSjbjiXujagkuaI9L
+Jlsf5hwO9D6VCTl8rgIUecSLDRS9qBAjZBZZ5HHld3c6W8D+mXnIfJuJBh9/1J/w
+/meA58hVGVrJPEfjLADE9FF/PeHj0mRI8E98JZGdQs8WXHjkWe+yPectC+clkvLm
+fH8lINEj7A+2Ji6uduIxBrAXbhpKcdanL6epqNHXY1tw4TqjjYtvggBkjsRJ8QEV
+aeDthXGh/Z8NxXp/SKh1DeKtt0VH0Uy+ouAcZSDPH00wqTZqyX2mS+LaGAZsYGww
+ggS2MIIDnqADAgECAhAMealEsIwRlSCSYV/iax2DMA0GCSqGSIb3DQEBCwUAMGwx
+CzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3
+dy5kaWdpY2VydC5jb20xKzApBgNVBAMTIkRpZ2lDZXJ0IEhpZ2ggQXNzdXJhbmNl
+IEVWIFJvb3QgQ0EwHhcNMTMxMDIyMTIwMDAwWhcNMjgxMDIyMTIwMDAwWjB1MQsw
+CQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cu
+ZGlnaWNlcnQuY29tMTQwMgYDVQQDEytEaWdpQ2VydCBTSEEyIEV4dGVuZGVkIFZh
+bGlkYXRpb24gU2VydmVyIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC
+AQEA11OkBFH4maYWSEtnJ6qTSdA57QywsACH8WcohoWMjmPavLFAOOLT9eylBRi4
+PT7FmRcy7BiM+vEMpmQhhcsHEDSwUogrH2ib0rGPErCz0ueIHx/vOHdUU1+AeT8u
+GqqoHksrDau3Y7k1t30UvFlL31FK0qHiDOKQgodqrurXZNaYVej9rxpQbFS8EfL9
+SvKdu38O9NW+jhaJElXYwHE07vbcLezEhyWGjdgh5LBNDIncOSYX3fbXlIXYBCFw
+nW9v/1y6GeFFy1ZXKH4cDUFXqre4J7ux5Poq7yEjdRqtLZuGNYycd7VzrdiULeTz
+DJ3uwU5ifhfAcZ4s3vH5ECgZMwIDAQABo4IBSTCCAUUwEgYDVR0TAQH/BAgwBgEB
+/wIBADAOBgNVHQ8BAf8EBAMCAYYwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUF
+BwMCMDQGCCsGAQUFBwEBBCgwJjAkBggrBgEFBQcwAYYYaHR0cDovL29jc3AuZGln
+aWNlcnQuY29tMEsGA1UdHwREMEIwQKA+oDyGOmh0dHA6Ly9jcmw0LmRpZ2ljZXJ0
+LmNvbS9EaWdpQ2VydEhpZ2hBc3N1cmFuY2VFVlJvb3RDQS5jcmwwPQYDVR0gBDYw
+NDAyBgRVHSAAMCowKAYIKwYBBQUHAgEWHGh0dHBzOi8vd3d3LmRpZ2ljZXJ0LmNv
+bS9DUFMwHQYDVR0OBBYEFD3TUKXWoK3u80pgCmXTIdT4+NYPMB8GA1UdIwQYMBaA
+FLE+w2kD+L9HAdSYJhoIAu9jZCvDMA0GCSqGSIb3DQEBCwUAA4IBAQCdttCQhuGG
+Au3FoPA0HHTBjXbMhgqo8EqKQtY/yKlNrXwIrea2ULiiGk2IB7EpIdzn2sY8IeDj
+EUlwrHodAaTKETpXq31XKkB0/dMdhRhQ31dHdaF9VSAuRzdQcox/ghvSYo8tA1ra
+w8ihzixSogBj63O6cchJJyOXZIWeOA6tY2g8ulKBWHmjLAzf3m3rMfK6oHxs8SzU
+4b13hDcDzjK1yJqBGkqSTjtGmoX+g6L5noyjzA1esz3PBHiPFBR7MpzHAKZcxLWh
+VY1aVmikInCqPIFx2Z2oRTv05faiUd3He2Lobwx067ja+L+HDXlQkZCbGDuRWSfx
+NSgTqyZ+1fd6MIIElDCCA3ygAwIBAgIQAf2j627KdciIQ4tyS8+8kTANBgkqhkiG
+9w0BAQsFADBhMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkw
+FwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9i
+YWwgUm9vdCBDQTAeFw0xMzAzMDgxMjAwMDBaFw0yMzAzMDgxMjAwMDBaME0xCzAJ
+BgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxJzAlBgNVBAMTHkRpZ2lD
+ZXJ0IFNIQTIgU2VjdXJlIFNlcnZlciBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEP
+ADCCAQoCggEBANyuWJBNwcQwFZA1W248ghX1LFy949v/cUP6ZCWA1O4Yok3wZtAK
+c24RmDYXZK83nf36QYSvx6+M/hpzTc8zl5CilodTgyu5pnVILR1WN3vaMTIa16yr
+BvSqXUu3R0bdKpPDkC55gIDvEwRqFDu1m5K+wgdlTvza/P96rtxcflUxDOg5B6TX
+vi/TC2rSsd9f/ld0Uzs1gN2ujkSYs58O09rg1/RrKatEp0tYhG2SS4HD2nOLEpdI
+kARFdRrdNzGXkujNVA075ME/OV4uuPNcfhCOhkEAjUVmR7ChZc6gqikJTvOX6+gu
+qw9ypzAO+sf0/RR3w6RbKFfCs/mC/bdFWJsCAwEAAaOCAVowggFWMBIGA1UdEwEB
+/wQIMAYBAf8CAQAwDgYDVR0PAQH/BAQDAgGGMDQGCCsGAQUFBwEBBCgwJjAkBggr
+BgEFBQcwAYYYaHR0cDovL29jc3AuZGlnaWNlcnQuY29tMHsGA1UdHwR0MHIwN6A1
+oDOGMWh0dHA6Ly9jcmwzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydEdsb2JhbFJvb3RD
+QS5jcmwwN6A1oDOGMWh0dHA6Ly9jcmw0LmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydEds
+b2JhbFJvb3RDQS5jcmwwPQYDVR0gBDYwNDAyBgRVHSAAMCowKAYIKwYBBQUHAgEW
+HGh0dHBzOi8vd3d3LmRpZ2ljZXJ0LmNvbS9DUFMwHQYDVR0OBBYEFA+AYRyCMWHV
+LyjnjUY4tCzhxtniMB8GA1UdIwQYMBaAFAPeUDVW0Uy7ZvCj4hsbw5eyPdFVMA0G
+CSqGSIb3DQEBCwUAA4IBAQAjPt9L0jFCpbZ+QlwaRMxp0Wi0XUvgBCFsS+JtzLHg
+l4+mUwnNqipl5TlPHoOlblyYoiQm5vuh7ZPHLgLGTUq/sELfeNqzqPlt/yGFUzZg
+THbO7Djc1lGA8MXW5dRNJ2Srm8c+cftIl7gzbckTB+6WohsYFfZcTEDts8Ls/3HB
+40f/1LkAtDdC2iDJ6m6K7hQGrn2iWZiIqBtvLfTyyRRfJs8sjX7tN8Cp1Tm5gr8Z
+DOo0rwAhaPitc+LJMto4JQtV05od8GiG7S5BNO98pVAdvzr508EIDObtHopYJeS4
+d60tbvVS3bR0j6tJLp07kzQoH3jOlOrHvdPJbRzeXDLzMIIEXDCCA0SgAwIBAgIN
+AeOpMBz8cgY4P5pTHTANBgkqhkiG9w0BAQsFADBMMSAwHgYDVQQLExdHbG9iYWxT
+aWduIFJvb3QgQ0EgLSBSMjETMBEGA1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMK
+R2xvYmFsU2lnbjAeFw0xNzA2MTUwMDAwNDJaFw0yMTEyMTUwMDAwNDJaMFQxCzAJ
+BgNVBAYTAlVTMR4wHAYDVQQKExVHb29nbGUgVHJ1c3QgU2VydmljZXMxJTAjBgNV
+BAMTHEdvb2dsZSBJbnRlcm5ldCBBdXRob3JpdHkgRzMwggEiMA0GCSqGSIb3DQEB
+AQUAA4IBDwAwggEKAoIBAQDKUkvqHv/OJGuo2nIYaNVWXQ5IWi01CXZaz6TIHLGp
+/lOJ+600/4hbn7vn6AAB3DVzdQOts7G5pH0rJnnOFUAK71G4nzKMfHCGUksW/mon
+a+Y2emJQ2N+aicwJKetPKRSIgAuPOB6Aahh8Hb2XO3h9RUk2T0HNouB2VzxoMXlk
+yW7XUR5mw6JkLHnA52XDVoRTWkNty5oCINLvGmnRsJ1zouAqYGVQMc/7sy+/EYhA
+LrVJEA8KbtyX+r8snwU5C1hUrwaW6MWOARa8qBpNQcWTkaIeoYvy/sGIJEmjR0vF
+EwHdp1cSaWIr6/4g72n7OqXwfinu7ZYW97EfoOSQJeAzAgMBAAGjggEzMIIBLzAO
+BgNVHQ8BAf8EBAMCAYYwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMBIG
+A1UdEwEB/wQIMAYBAf8CAQAwHQYDVR0OBBYEFHfCuFCaZ3Z2sS3ChtCDoH6mfrpL
+MB8GA1UdIwQYMBaAFJviB1dnHB7AagbeWbSaLd/cGYYuMDUGCCsGAQUFBwEBBCkw
+JzAlBggrBgEFBQcwAYYZaHR0cDovL29jc3AucGtpLmdvb2cvZ3NyMjAyBgNVHR8E
+KzApMCegJaAjhiFodHRwOi8vY3JsLnBraS5nb29nL2dzcjIvZ3NyMi5jcmwwPwYD
+VR0gBDgwNjA0BgZngQwBAgIwKjAoBggrBgEFBQcCARYcaHR0cHM6Ly9wa2kuZ29v
+Zy9yZXBvc2l0b3J5LzANBgkqhkiG9w0BAQsFAAOCAQEAHLeJluRT7bvs26gyAZ8s
+o81trUISd7O45skDUmAge1cnxhG1P2cNmSxbWsoiCt2eux9LSD+PAj2LIYRFHW31
+/6xoic1k4tbWXkDCjir37xTTNqRAMPUyFRWSdvt+nlPqwnb8Oa2I/maSJukcxDjN
+SfpDh/Bd1lZNgdd/8cLdsE3+wypufJ9uXO1iQpnh9zbuFIwsIONGl1p3A8CgxkqI
+/UAih3JaGOqcpcdaCIzkBaR9uYQ1X4k2Vg5APRLouzVy7a8IVk6wuy6pm+T7HT4L
+Y8ibS5FEZlfAFLSW8NwsVz9SBK2Vqn1N0PIMn5xA6NZVc7o835DLAFshEWfC7TIe
+3jCCBFMwggI7oAMCAQICAhAAMA0GCSqGSIb3DQEBCwUAMGsxCzAJBgNVBAYTAlVL
+MRAwDgYDVQQIDAdFbmdsYW5kMR8wHQYDVQQKDBZYbWxzZWN1cml0eSBFQ0RTQSBU
+ZXN0MSkwJwYDVQQDDCBYbWxzZWN1cml0eSBJbnRlcm1lZGlhdGUgUm9vdCBDQTAg
+Fw0xODA2MDYxNTIwMjFaGA8yMTE4MDUxMzE1MjAyMVowbzELMAkGA1UEBhMCVUsx
+EDAOBgNVBAgMB0VuZ2xhbmQxHzAdBgNVBAoMFlhtbHNlY3VyaXR5IEVDRFNBIFRl
+c3QxLTArBgNVBAMMJFhtbHNlY3VyaXR5IEVDRFNBIFRlc3QgZXhhbXBsZSBBbGlj
+ZTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABARLFn7pnI5fqVyPKZsn+1aFSgoF
+NxwX30u97S9Ti3v0LkMhzCvJgCMRTRFE5Utzrg1tmNvAO1gl5Cn3VeRv/qWjgcUw
+gcIwCQYDVR0TBAIwADARBglghkgBhvhCAQEEBAMCBaAwMwYJYIZIAYb4QgENBCYW
+JE9wZW5TU0wgR2VuZXJhdGVkIENsaWVudCBDZXJ0aWZpY2F0ZTAdBgNVHQ4EFgQU
+6iBLx5qDOXkoKU2kRXYBsRuOKEQwHwYDVR0jBBgwFoAU0EyW4PhS5umRVdHSnb88
+88RIMkcwDgYDVR0PAQH/BAQDAgXgMB0GA1UdJQQWMBQGCCsGAQUFBwMCBggrBgEF
+BQcDBDANBgkqhkiG9w0BAQsFAAOCAgEACu+ViKlFl5euwbhuysQro10mplQXhocM
+EpLyN4ZwSkplKbyfQIDahoCU1GSVUr6r5/3oOOjeqHNqeRYpd2hGQbmLaDydTbLO
+7Eb/i9u4VIYKrSKQCz4Q5Z7Hc/8hD+YFuwN8xQdzQRE5tMqHQ2PmEYwYkt0ABbqA
+El0Ae5nII98ejz5b1S7a4wPSr4CLVhSUDBTUSglJxaT5ZTa/rhmUjgOg4cFgE+Qm
+OQuaD2VEy65eCWcjUY7r7ZNP6+JbHVBW8DxiWvBd2YZwh4A4TwxUwRwcOgDMh8Z8
+B2D+xz+We4KQF+hhlA1CyKDcLcJR5OujQX4C2/zhzzmKOA1ilmH8HrJ0iTAf4mOo
+7l2vpRhDR3W3q4l7WsthCJhno/UGKz9F/v8E7fXQC7WnmffXgGzBDdOF+nojZLFn
+JMe62Zd38vydfcl7QPnJS4G+g7XZIg1pn5YlrygCcyCkOIJZ2qdigPm5tDWwweP9
+fDANlfmyVRDPJ1hfQkpgP9tIdgyoYx1AR6SBGXgXNNb1fl3t+sBYt8n4Vb2O/7sN
+9Cvr8zxrxflJ3qK8asp7XSy3cQCUfGyTLsH43u+uv5l9Q/iX1KfXo3KYR4fzv8dZ
+uNjrFunhQIb7HTbtgIDp+jerBSCIWBAhqGvwMEKEcWNj7uig9BHvKG7npeZyzaB5
+/gsM/nofo5UwggUYMIIDAKADAgECAgIQADANBgkqhkiG9w0BAQsFADBpMQswCQYD
+VQQGEwJVSzEQMA4GA1UECAwHRW5nbGFuZDEdMBsGA1UECgwUWG1sc2VjdXJpdHkg
+UlNBIFRlc3QxKTAnBgNVBAMMIFhtbHNlY3VyaXR5IEludGVybWVkaWF0ZSBSb290
+IENBMCAXDTE4MDYwNjE1MjAwNloYDzIxMTgwNTEzMTUyMDA2WjBrMQswCQYDVQQG
+EwJVSzEQMA4GA1UECAwHRW5nbGFuZDEdMBsGA1UECgwUWG1sc2VjdXJpdHkgUlNB
+IFRlc3QxKzApBgNVBAMMIlhtbHNlY3VyaXR5IFJTQSBUZXN0IGV4YW1wbGUgQWxp
+Y2UwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC/jNbYTvv/epCVWXDp
+cJJ2vicKBt4GkzmOXTVBKRRJE0KodEldWdsCySMvT1aCfcZAf8l+CGCNyim7f4Fl
+L1IJ7j+N0Rhsi105mkFAZ1EkU2mfHdx3j9c7+ybbc1219cfMEAzgwjnGNGqpD9ZR
+dTWgipeFCOwSt1hcWV+bvuP5DnKJFQtoEObkXUE/Ehb3a8FfXnH+2sBTEkKmjL5J
+Bg46NRv1cA7gTTbh9JrYAEmGRnt4fjkV3Njc2phzPryoOYZudb9CWE6HUIyhw7BI
+oc/OlvFypoykuz4ciTviVh7bAKS/OMugbX9fz4CRljilDw3LIIKMtFR5ohWRPBcr
+rfo7AgMBAAGjgcUwgcIwCQYDVR0TBAIwADARBglghkgBhvhCAQEEBAMCBaAwMwYJ
+YIZIAYb4QgENBCYWJE9wZW5TU0wgR2VuZXJhdGVkIENsaWVudCBDZXJ0aWZpY2F0
+ZTAdBgNVHQ4EFgQUoMyXNKeDde/7MDve+sSR2rKd10QwHwYDVR0jBBgwFoAUNcHy
+DfjtNQ8y8I1dMFJFClVG+ugwDgYDVR0PAQH/BAQDAgXgMB0GA1UdJQQWMBQGCCsG
+AQUFBwMCBggrBgEFBQcDBDANBgkqhkiG9w0BAQsFAAOCAgEAIxT1eA8eDG44lGUp
+OroRAqFAzhrX11s5OlAJPdXtjE4OrSQ4105eNbsARsrgEuEdvTR+KGzsRO90iHYd
+3DXUVr1QrcDb0lExbQk5fXMqaKdyXta+DUMdbEl1F7j8kKwr73y7zthziKnY8Ehd
+DOmUUjGf7AbYyZIaizgqWBjHMOgDhaq9t+vW15SJfNF9P5h+xNFZO1xqkad6ATvd
+vQ6NjHKjps6kU08AUpRk2L+Tx4sRu03zCMFdgqMhjdvDSDjDl38FCvNwCTCik1U5
+NhqIwjsXBhmkm9NZ/5UDXBLnTiPiWCFzF4+bWzeahLN1ky1roiFX9AOwP2z1Px2G
+V7VhC//f2nDvKPHNswcGLHoXsyg0hYJyGA+Hnvl2g8StD3Lk2DZzbjbC99BDPMKL
+g2s4w7Hpz7fLjKe8k6w6GrSOoyCDCK4oBL3ZY0g/rMR+ZybhW0K0bo+h3y9s6292
+Btsk24EacgGNx8XPZe5BEmX1n8rELCpcYxLvzo4yNMIptL9dlofC87Cskej2KC9D
+nTYM/7YbDOdmqAAhyHG1ZnEzMgjfpA9Wl2dO6Mb+QJTBSq+61Xee6ylyKhaeL3L5
+61M3frsI2irETwU0HSZTgl5zGFQs/VTMMwE+5wLyoo+JgIQo38J9fp3gpmNlqoVs
+w1sPLs4AeXm5/0jhMUx3ZMCdE8YwggWyMIIDmqADAgECAgkAlxa9qhMuSpowDQYJ
+KoZIhvcNAQELBQAwZTELMAkGA1UEBhMCVUsxEDAOBgNVBAgMB0VuZ2xhbmQxHTAb
+BgNVBAoMFFhtbHNlY3VyaXR5IFJTQSBUZXN0MSUwIwYDVQQDDBxYbWxzZWN1cml0
+eSBSU0EgVGVzdCBSb290IENBMCAXDTE4MDYwNjE1MjAwNFoYDzIxMTgwNTEzMTUy
+MDA0WjBlMQswCQYDVQQGEwJVSzEQMA4GA1UECAwHRW5nbGFuZDEdMBsGA1UECgwU
+WG1sc2VjdXJpdHkgUlNBIFRlc3QxJTAjBgNVBAMMHFhtbHNlY3VyaXR5IFJTQSBU
+ZXN0IFJvb3QgQ0EwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC+iaaD
+NjD39bYz7vlqzWlXpRnxav6GmJyLROygf8odZgtaZL2LwgDVh/oFjchIC4q8N+pN
+aDKgMV4nJNXM01QeVh/piashiAbQNvauehyKFwwwW5WddETBtCCKBZj3eII2LYqm
+gY5YHrdm6nJ8xN7KPsW69i3gCW0ntDSj5EhEbHrVp4/aCgaLH2jWOSME3pOffBDd
+4mChrQJI+R9p5j7BU755QSVgTfkXCY9ZHrwCcXuGD9JLVEQ1JDhmpUDUYrZ8pqRf
+p7vOSokJvpm5DadfkY0lYUVKUFclatWqkFm94osx8ZBqRlSzDPcVE9c3SpQrjS8p
+duURK43fk8depV9IA8RDqIYolTtULe5M90LIHO3AlsgCz5Gr13FvrJm/rxcKEaF5
+7dVbT9p78amuQcSd48GTyluRKpLTnZn3Lfo2eNHBlFWdGZCPDpdLWHZzpx1GxX3H
+YXCaWUBCHPpXatm7851L2IIbcITjmcOeBiDhWcPDin2OcJ5roxhU8G09T1/Y2Oci
+cjFQZGJ1fY3arXL1SI85TzuaWiXJABJX5K3HAeSbslrrD4xF/CBTb+g4uVzcykzL
+jityxECWFsngJZdHATD7EmgdvdbSX6LLjvoy18xofBpET/Gw+b4xeBcyP55sTn1x
+4LoYlLo4DmfnkpHrnOmZCwziffLMmtT2EzEMowIDAQABo2MwYTAdBgNVHQ4EFgQU
+46qCA78jo+QjIlmonXqZsNu2JfEwHwYDVR0jBBgwFoAU46qCA78jo+QjIlmonXqZ
+sNu2JfEwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAYYwDQYJKoZIhvcN
+AQELBQADggIBACRuAgJickA2ogZ+3/RyGDW5Kbp5kyuXSR8AJkoWkvwo6GPsLrpw
+h6yR/tZwlsdA5bcICDQ5mmRL2eG8/E7KxBuVL6xDCj11aI3s0BOiRPHJJgYV2sQ1
+dJR0Yj0wwWyLODyo3TsS1vKept0nAU0NqiYnPSZRdiXG0JHiBMaitaYvwTMkg33w
+te4wObmCiZ3lFMKCpzWEFP4OrQTdZqmdRWUwWvUpLx7H9Ep9UFDmAlEnXRkhqxpV
+2kKXeAYV3wwAzKqplc7KW07VFFNNdjO3nQbVSYAR3ZIMfoAOqPxPTgjRSKumxDtv
+gZqwmiZZAG4K/2NjrmsA593uZYfhEOZWfY/hcJVnr76gKavYIwRF+hGxUi3fGDHk
+665Xgx0BxUHDosyRDPolGn3aQQY8wT3HXCcNFyeSznzOcK+ixlETAtj+y1arZ4ts
+4pnl0ImqILjEZxrmXTAkRO51TlYt0iA8NQVDa1Ne64Fy2N3OHz4XJzo3aoynf5Ta
+bakQCsh3/prFpCGMYkQMkxXonTdaJnyX/0aMiVfYdAZupG8cAvuRQSQ/i1k5SLAY
+ai1qQW8kmJVYPKdWmEvyBNqZHWVpNiG3SZka1nklMxzCkTfv7Z2Ix8DL+GqM5cNz
+I0DDfG0sOVfqLlcraumu7wZpY+KRGSBN9EF1ZZ9GOX7SwTn57U3yYd0xMIIFujCC
+A6KgAwIBAgIJAMtBg6xEFRDTMA0GCSqGSIb3DQEBCwUAMGkxCzAJBgNVBAYTAlVL
+MRAwDgYDVQQIDAdFbmdsYW5kMR8wHQYDVQQKDBZYbWxzZWN1cml0eSBFQ0RTQSBU
+ZXN0MScwJQYDVQQDDB5YbWxzZWN1cml0eSBFQ0RTQSBUZXN0IFJvb3QgQ0EwIBcN
+MTgwNjA2MTUyMDIxWhgPMjExODA1MTMxNTIwMjFaMGkxCzAJBgNVBAYTAlVLMRAw
+DgYDVQQIDAdFbmdsYW5kMR8wHQYDVQQKDBZYbWxzZWN1cml0eSBFQ0RTQSBUZXN0
+MScwJQYDVQQDDB5YbWxzZWN1cml0eSBFQ0RTQSBUZXN0IFJvb3QgQ0EwggIiMA0G
+CSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCjKXY/LOLDioXDCWBi3GLP29BMDoYx
+J0tkL9Pdir7mBACxRshI9K/eHfzzBURDWycUfW9jU9xPtt2NfJFB3TfUjet4uHkr
+f2K9oZW9QxloVvBSAMPR5393o/cSrcijJ1BA77hilZJQ75t8xOgqBu5uxLfR3yS2
+GHnZAqckavR9y7oQEbmf/b1b+Fa1WWz21RuT82E02M0Ew2/NpvrP7dpkgovyvLPz
+J/pDrdTWOzzYmvNxuKRnHsaDdBSPvgsGmokbZr5GevK5CUYhSumpcD+orZVelFxI
+Fv+KAMAZGlIyyW6Ipv5fs4fGORLJy0h1z2SYzNz41bqnWZsDCruZmEI4RCZkCfq2
+7gEoPQVRjP+RsgpZmnuI2Deyw33Uh/pLtUYf3bjOPnKRThRqzDl7JC27sRhgdUDM
+2KLOPC7IVMG+u94ejOvzSJ5zVdujNvki5OEscN4xPWUDYj/y3QOnDp8MarCd7al4
+P+Dk3niNnkFMLFSl+gbbLjDNcrabtVqCnd/dmgjwiU9k80oNa0jKx7pdKPqPvxKM
+e5xffmkDp9XFdKl7qeDprk5KQ9PtCO00JTVQGhyxapmMuUsJgezpGQSqF5wAKrNm
+dcdHWtFeZDq1IoLMQUS9uMCzzHV5tAfFDX/GnAz2xnPq88RW7nt9LFjzWA8ZsTYf
+/LPjaO+tYim8wQIDAQABo2MwYTAdBgNVHQ4EFgQUIDesPjHcCxXnc1U8kKP6BXGA
+WtUwHwYDVR0jBBgwFoAUIDesPjHcCxXnc1U8kKP6BXGAWtUwDwYDVR0TAQH/BAUw
+AwEB/zAOBgNVHQ8BAf8EBAMCAYYwDQYJKoZIhvcNAQELBQADggIBAByhIRpqnRqr
+z/NrI2+LsQawI5PYFyyA8QDxHJveId8DX7OIJDqoXxdl0pqhPSli+2f1ZaLzfTfY
+av1BT2+ALcVY1DDz4RHSUg1YLk6n+1IPeq4hSAf7JVa13tA8tyK7ghjZMCIzX08Z
+Ux9Wz5FlnGSC/jFg2qRjjlZyHQB4N9mLtPp83OEuQBuFJ2LMd6dHcDDpERjrRGpH
+tLFxYnLKgT745h0A/k/HjZLKs46xJBO1y8ZruOoNKklsTkiysGImhRW4KnLJ5iSS
+/V6vzfaCGcDxSSYlbIT1twEN1lRcCuPlPmm7LgV/X12lACg+UR12/dcJnCe94x4E
+QaydT0wsAzT5WSNh69UOrRp0sDJrKtehhQ+7oGeIqTYQNpnmvA3L3MssRvcyw9wB
+ZUdAAw0Jr3jsgy0wZuYIFSbEUWzTlyhkL2Rhp9zzq4f0AW61m+yDb8QXkPnWJPln
+NrKqKYGTfzQNcMSIkcLiDnAmsBeZOze+iXpnuzZSWqlkPQfGhlFRkJ4jm63H15cX
+Hz2OE7zr/HoMJCxXXUbFVIyHDL2i9GbShHr+DVIM9OgBJ6UEPNEN2RZo4vncNCnQ
+zRZe4H1bvaGnh0SUKoLiE2Jy93LBUKrSygHLOtweerXL2dtHad2qi+SQjWXjYBUr
+Y3U3LDo+kQfo7hfVZ/HdrhK7ldhXbz7nMQA=
+-----END PKCS7-----
diff --git a/test/signing-keys/trustdb.gpg b/test/signing-keys/trustdb.gpg
new file mode 100644
index 0000000000..1966b5374c
--- /dev/null
+++ b/test/signing-keys/trustdb.gpg
Binary files differ
diff --git a/test/source/a11y/AccessibilityTools.cxx b/test/source/a11y/AccessibilityTools.cxx
new file mode 100644
index 0000000000..f0a28d4cda
--- /dev/null
+++ b/test/source/a11y/AccessibilityTools.cxx
@@ -0,0 +1,753 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * 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/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <test/a11y/AccessibilityTools.hxx>
+
+#include <com/sun/star/accessibility/AccessibleEventId.hpp>
+#include <com/sun/star/accessibility/AccessibleRelationType.hpp>
+#include <com/sun/star/accessibility/AccessibleRole.hpp>
+#include <com/sun/star/accessibility/AccessibleStateType.hpp>
+#include <com/sun/star/accessibility/XAccessible.hpp>
+#include <com/sun/star/accessibility/XAccessibleAction.hpp>
+#include <com/sun/star/accessibility/XAccessibleContext.hpp>
+#include <com/sun/star/awt/KeyModifier.hpp>
+
+#include <rtl/ustrbuf.hxx>
+#include <sal/log.hxx>
+#include <toolkit/awt/vclxaccessiblecomponent.hxx>
+#include <vcl/scheduler.hxx>
+#include <vcl/timer.hxx>
+#include <vcl/window.hxx>
+#include <o3tl/string_view.hxx>
+
+using namespace css;
+
+uno::Reference<accessibility::XAccessibleContext>
+AccessibilityTools::getAccessibleObjectForPredicate(
+ const uno::Reference<accessibility::XAccessibleContext>& xCtx,
+ const std::function<bool(const uno::Reference<accessibility::XAccessibleContext>&)>& cPredicate)
+{
+ if (cPredicate(xCtx))
+ {
+ return xCtx;
+ }
+ else
+ {
+ sal_Int64 count = xCtx->getAccessibleChildCount();
+
+ for (sal_Int64 i = 0; i < count && i < AccessibilityTools::MAX_CHILDREN; i++)
+ {
+ uno::Reference<accessibility::XAccessibleContext> xCtx2
+ = getAccessibleObjectForPredicate(xCtx->getAccessibleChild(i), cPredicate);
+ if (xCtx2.is())
+ return xCtx2;
+ }
+ }
+ return nullptr;
+}
+
+uno::Reference<accessibility::XAccessibleContext>
+AccessibilityTools::getAccessibleObjectForPredicate(
+ const uno::Reference<accessibility::XAccessible>& xAcc,
+ const std::function<bool(const uno::Reference<accessibility::XAccessibleContext>&)>& cPredicate)
+{
+ return getAccessibleObjectForPredicate(xAcc->getAccessibleContext(), cPredicate);
+}
+
+uno::Reference<accessibility::XAccessibleContext> AccessibilityTools::getAccessibleObjectForRole(
+ const uno::Reference<accessibility::XAccessibleContext>& xCtx, sal_Int16 role)
+{
+ return getAccessibleObjectForPredicate(
+ xCtx, [&role](const uno::Reference<accessibility::XAccessibleContext>& xObjCtx) {
+ return (xObjCtx->getAccessibleRole() == role
+ && xObjCtx->getAccessibleStateSet()
+ & accessibility::AccessibleStateType::SHOWING);
+ });
+}
+
+css::uno::Reference<css::accessibility::XAccessibleContext>
+AccessibilityTools::getAccessibleObjectForRole(
+ const css::uno::Reference<css::accessibility::XAccessible>& xacc, sal_Int16 role)
+{
+ return getAccessibleObjectForRole(xacc->getAccessibleContext(), role);
+}
+
+/* this is basically the same as getAccessibleObjectForPredicate() but specialized for efficiency,
+ * and because the template version will not work with getAccessibleObjectForPredicate() anyway */
+css::uno::Reference<css::accessibility::XAccessibleContext>
+AccessibilityTools::getAccessibleObjectForName(
+ const css::uno::Reference<css::accessibility::XAccessibleContext>& xCtx, const sal_Int16 role,
+ std::u16string_view name)
+{
+ if (xCtx->getAccessibleRole() == role && nameEquals(xCtx, name))
+ return xCtx;
+
+ auto nChildren = xCtx->getAccessibleChildCount();
+ for (decltype(nChildren) i = 0; i < nChildren && i < AccessibilityTools::MAX_CHILDREN; i++)
+ {
+ if (auto xMatchChild = getAccessibleObjectForName(xCtx->getAccessibleChild(i), role, name))
+ return xMatchChild;
+ }
+
+ return nullptr;
+}
+
+bool AccessibilityTools::equals(const uno::Reference<accessibility::XAccessible>& xacc1,
+ const uno::Reference<accessibility::XAccessible>& xacc2)
+{
+ if (!xacc1.is() || !xacc2.is())
+ return xacc1.is() == xacc2.is();
+ return equals(xacc1->getAccessibleContext(), xacc2->getAccessibleContext());
+}
+
+bool AccessibilityTools::equals(const uno::Reference<accessibility::XAccessibleContext>& xctx1,
+ const uno::Reference<accessibility::XAccessibleContext>& xctx2)
+{
+ if (!xctx1.is() || !xctx2.is())
+ return xctx1.is() == xctx2.is();
+
+ if (xctx1->getAccessibleRole() != xctx2->getAccessibleRole())
+ return false;
+
+ if (xctx1->getAccessibleName() != xctx2->getAccessibleName())
+ return false;
+
+ if (xctx1->getAccessibleDescription() != xctx2->getAccessibleDescription())
+ return false;
+
+ if (xctx1->getAccessibleChildCount() != xctx2->getAccessibleChildCount())
+ return false;
+
+ /* this one was not in the Java version */
+ if (xctx1->getAccessibleIndexInParent() != xctx2->getAccessibleIndexInParent())
+ return false;
+
+ /* because in Writer at least some children only are referenced by their relations to others
+ * objects, we need to account for that as their index in parent is incorrect (so not
+ * necessarily unique) */
+ auto relset1 = xctx1->getAccessibleRelationSet();
+ auto relset2 = xctx2->getAccessibleRelationSet();
+ if (relset1.is() != relset2.is())
+ return false;
+ else if (relset1.is())
+ {
+ auto relCount1 = relset1->getRelationCount();
+ auto relCount2 = relset2->getRelationCount();
+ if (relCount1 != relCount2)
+ return false;
+
+ for (sal_Int32 i = 0; i < relCount1; ++i)
+ {
+ if (relset1->getRelation(i) != relset2->getRelation(i))
+ return false;
+ }
+ }
+
+ return equals(xctx1->getAccessibleParent(), xctx2->getAccessibleParent());
+}
+
+bool AccessibilityTools::nameEquals(const uno::Reference<accessibility::XAccessibleContext>& xCtx,
+ const std::u16string_view name)
+{
+ auto ctxName = xCtx->getAccessibleName();
+ std::u16string_view rest;
+
+ if (!o3tl::starts_with(ctxName, name, &rest))
+ return false;
+ if (rest == u"")
+ return true;
+
+#if defined(_WIN32)
+ // see OAccessibleMenuItemComponent::GetAccessibleName():
+ // on Win32, ignore a \tSHORTCUT suffix on a menu item
+ switch (xCtx->getAccessibleRole())
+ {
+ case accessibility::AccessibleRole::MENU_ITEM:
+ case accessibility::AccessibleRole::RADIO_MENU_ITEM:
+ case accessibility::AccessibleRole::CHECK_MENU_ITEM:
+ return rest[0] == '\t';
+
+ default:
+ break;
+ }
+#endif
+
+#if OSL_DEBUG_LEVEL > 0
+ // see VCLXAccessibleComponent::getAccessibleName()
+ static const char* pEnvAppendType = getenv("LIBO_APPEND_WINDOW_TYPE_TO_ACCESSIBLE_NAME");
+ if (pEnvAppendType && OUString::createFromAscii(pEnvAppendType) != u"0")
+ {
+ auto pVCLXAccessibleComponent = dynamic_cast<VCLXAccessibleComponent*>(xCtx.get());
+ if (pVCLXAccessibleComponent)
+ {
+ auto windowType = pVCLXAccessibleComponent->GetWindow()->GetType();
+ if (rest
+ == Concat2View(u" (Type = " + OUString::number(static_cast<sal_Int32>(windowType))
+ + ")"))
+ return true;
+ }
+ }
+#endif
+ return false;
+}
+
+static OUString unknownName(const sal_Int64 value)
+{
+ return "unknown (" + OUString::number(value) + ")";
+}
+
+OUString AccessibilityTools::getRoleName(const sal_Int16 role)
+{
+ switch (role)
+ {
+ case accessibility::AccessibleRole::UNKNOWN:
+ return "UNKNOWN";
+ case accessibility::AccessibleRole::ALERT:
+ return "ALERT";
+ case accessibility::AccessibleRole::BLOCK_QUOTE:
+ return "BLOCK_QUOTE";
+ case accessibility::AccessibleRole::BUTTON_DROPDOWN:
+ return "BUTTON_DROPDOWN";
+ case accessibility::AccessibleRole::BUTTON_MENU:
+ return "BUTTON_MENU";
+ case accessibility::AccessibleRole::CANVAS:
+ return "CANVAS";
+ case accessibility::AccessibleRole::CAPTION:
+ return "CAPTION";
+ case accessibility::AccessibleRole::CHART:
+ return "CHART";
+ case accessibility::AccessibleRole::CHECK_BOX:
+ return "CHECK_BOX";
+ case accessibility::AccessibleRole::CHECK_MENU_ITEM:
+ return "CHECK_MENU_ITEM";
+ case accessibility::AccessibleRole::COLOR_CHOOSER:
+ return "COLOR_CHOOSER";
+ case accessibility::AccessibleRole::COLUMN_HEADER:
+ return "COLUMN_HEADER";
+ case accessibility::AccessibleRole::COMBO_BOX:
+ return "COMBO_BOX";
+ case accessibility::AccessibleRole::COMMENT:
+ return "COMMENT";
+ case accessibility::AccessibleRole::COMMENT_END:
+ return "COMMENT_END";
+ case accessibility::AccessibleRole::DATE_EDITOR:
+ return "DATE_EDITOR";
+ case accessibility::AccessibleRole::DESKTOP_ICON:
+ return "DESKTOP_ICON";
+ case accessibility::AccessibleRole::DESKTOP_PANE:
+ return "DESKTOP_PANE";
+ case accessibility::AccessibleRole::DIALOG:
+ return "DIALOG";
+ case accessibility::AccessibleRole::DIRECTORY_PANE:
+ return "DIRECTORY_PANE";
+ case accessibility::AccessibleRole::DOCUMENT:
+ return "DOCUMENT";
+ case accessibility::AccessibleRole::DOCUMENT_PRESENTATION:
+ return "DOCUMENT_PRESENTATION";
+ case accessibility::AccessibleRole::DOCUMENT_SPREADSHEET:
+ return "DOCUMENT_SPREADSHEET";
+ case accessibility::AccessibleRole::DOCUMENT_TEXT:
+ return "DOCUMENT_TEXT";
+ case accessibility::AccessibleRole::EDIT_BAR:
+ return "EDIT_BAR";
+ case accessibility::AccessibleRole::EMBEDDED_OBJECT:
+ return "EMBEDDED_OBJECT";
+ case accessibility::AccessibleRole::END_NOTE:
+ return "END_NOTE";
+ case accessibility::AccessibleRole::FILE_CHOOSER:
+ return "FILE_CHOOSER";
+ case accessibility::AccessibleRole::FILLER:
+ return "FILLER";
+ case accessibility::AccessibleRole::FONT_CHOOSER:
+ return "FONT_CHOOSER";
+ case accessibility::AccessibleRole::FOOTER:
+ return "FOOTER";
+ case accessibility::AccessibleRole::FOOTNOTE:
+ return "FOOTNOTE";
+ case accessibility::AccessibleRole::FORM:
+ return "FORM";
+ case accessibility::AccessibleRole::FRAME:
+ return "FRAME";
+ case accessibility::AccessibleRole::GLASS_PANE:
+ return "GLASS_PANE";
+ case accessibility::AccessibleRole::GRAPHIC:
+ return "GRAPHIC";
+ case accessibility::AccessibleRole::GROUP_BOX:
+ return "GROUP_BOX";
+ case accessibility::AccessibleRole::HEADER:
+ return "HEADER";
+ case accessibility::AccessibleRole::HEADING:
+ return "HEADING";
+ case accessibility::AccessibleRole::HYPER_LINK:
+ return "HYPER_LINK";
+ case accessibility::AccessibleRole::ICON:
+ return "ICON";
+ case accessibility::AccessibleRole::IMAGE_MAP:
+ return "IMAGE_MAP";
+ case accessibility::AccessibleRole::INTERNAL_FRAME:
+ return "INTERNAL_FRAME";
+ case accessibility::AccessibleRole::LABEL:
+ return "LABEL";
+ case accessibility::AccessibleRole::LAYERED_PANE:
+ return "LAYERED_PANE";
+ case accessibility::AccessibleRole::LIST:
+ return "LIST";
+ case accessibility::AccessibleRole::LIST_ITEM:
+ return "LIST_ITEM";
+ case accessibility::AccessibleRole::MENU:
+ return "MENU";
+ case accessibility::AccessibleRole::MENU_BAR:
+ return "MENU_BAR";
+ case accessibility::AccessibleRole::MENU_ITEM:
+ return "MENU_ITEM";
+ case accessibility::AccessibleRole::NOTE:
+ return "NOTE";
+ case accessibility::AccessibleRole::OPTION_PANE:
+ return "OPTION_PANE";
+ case accessibility::AccessibleRole::PAGE:
+ return "PAGE";
+ case accessibility::AccessibleRole::PAGE_TAB:
+ return "PAGE_TAB";
+ case accessibility::AccessibleRole::PAGE_TAB_LIST:
+ return "PAGE_TAB_LIST";
+ case accessibility::AccessibleRole::PANEL:
+ return "PANEL";
+ case accessibility::AccessibleRole::PARAGRAPH:
+ return "PARAGRAPH";
+ case accessibility::AccessibleRole::PASSWORD_TEXT:
+ return "PASSWORD_TEXT";
+ case accessibility::AccessibleRole::POPUP_MENU:
+ return "POPUP_MENU";
+ case accessibility::AccessibleRole::PROGRESS_BAR:
+ return "PROGRESS_BAR";
+ case accessibility::AccessibleRole::PUSH_BUTTON:
+ return "PUSH_BUTTON";
+ case accessibility::AccessibleRole::RADIO_BUTTON:
+ return "RADIO_BUTTON";
+ case accessibility::AccessibleRole::RADIO_MENU_ITEM:
+ return "RADIO_MENU_ITEM";
+ case accessibility::AccessibleRole::ROOT_PANE:
+ return "ROOT_PANE";
+ case accessibility::AccessibleRole::ROW_HEADER:
+ return "ROW_HEADER";
+ case accessibility::AccessibleRole::RULER:
+ return "RULER";
+ case accessibility::AccessibleRole::SCROLL_BAR:
+ return "SCROLL_BAR";
+ case accessibility::AccessibleRole::SCROLL_PANE:
+ return "SCROLL_PANE";
+ case accessibility::AccessibleRole::SECTION:
+ return "SECTION";
+ case accessibility::AccessibleRole::SEPARATOR:
+ return "SEPARATOR";
+ case accessibility::AccessibleRole::SHAPE:
+ return "SHAPE";
+ case accessibility::AccessibleRole::SLIDER:
+ return "SLIDER";
+ case accessibility::AccessibleRole::SPIN_BOX:
+ return "SPIN_BOX";
+ case accessibility::AccessibleRole::SPLIT_PANE:
+ return "SPLIT_PANE";
+ case accessibility::AccessibleRole::STATIC:
+ return "STATIC";
+ case accessibility::AccessibleRole::STATUS_BAR:
+ return "STATUS_BAR";
+ case accessibility::AccessibleRole::TABLE:
+ return "TABLE";
+ case accessibility::AccessibleRole::TABLE_CELL:
+ return "TABLE_CELL";
+ case accessibility::AccessibleRole::TEXT:
+ return "TEXT";
+ case accessibility::AccessibleRole::TEXT_FRAME:
+ return "TEXT_FRAME";
+ case accessibility::AccessibleRole::TOGGLE_BUTTON:
+ return "TOGGLE_BUTTON";
+ case accessibility::AccessibleRole::TOOL_BAR:
+ return "TOOL_BAR";
+ case accessibility::AccessibleRole::TOOL_TIP:
+ return "TOOL_TIP";
+ case accessibility::AccessibleRole::TREE:
+ return "TREE";
+ case accessibility::AccessibleRole::TREE_ITEM:
+ return "TREE_ITEM";
+ case accessibility::AccessibleRole::TREE_TABLE:
+ return "TREE_TABLE";
+ case accessibility::AccessibleRole::VIEW_PORT:
+ return "VIEW_PORT";
+ case accessibility::AccessibleRole::WINDOW:
+ return "WINDOW";
+ };
+ return unknownName(role);
+}
+
+OUString AccessibilityTools::debugAccessibleStateSet(const sal_Int64 nCombinedState)
+{
+ OUString combinedName;
+
+ for (int i = 0; i < 63; i++)
+ {
+ sal_Int64 state = sal_Int64(1) << i;
+ if (!(state & nCombinedState))
+ continue;
+ OUString name;
+ switch (state)
+ {
+ case accessibility::AccessibleStateType::ACTIVE:
+ name = "ACTIVE";
+ break;
+ case accessibility::AccessibleStateType::ARMED:
+ name = "ARMED";
+ break;
+ case accessibility::AccessibleStateType::BUSY:
+ name = "BUSY";
+ break;
+ case accessibility::AccessibleStateType::CHECKABLE:
+ name = "CHECKABLE";
+ break;
+ case accessibility::AccessibleStateType::CHECKED:
+ name = "CHECKED";
+ break;
+ case accessibility::AccessibleStateType::COLLAPSE:
+ name = "COLLAPSE";
+ break;
+ case accessibility::AccessibleStateType::DEFAULT:
+ name = "DEFAULT";
+ break;
+ case accessibility::AccessibleStateType::DEFUNC:
+ name = "DEFUNC";
+ break;
+ case accessibility::AccessibleStateType::EDITABLE:
+ name = "EDITABLE";
+ break;
+ case accessibility::AccessibleStateType::ENABLED:
+ name = "ENABLED";
+ break;
+ case accessibility::AccessibleStateType::EXPANDABLE:
+ name = "EXPANDABLE";
+ break;
+ case accessibility::AccessibleStateType::EXPANDED:
+ name = "EXPANDED";
+ break;
+ case accessibility::AccessibleStateType::FOCUSABLE:
+ name = "FOCUSABLE";
+ break;
+ case accessibility::AccessibleStateType::FOCUSED:
+ name = "FOCUSED";
+ break;
+ case accessibility::AccessibleStateType::HORIZONTAL:
+ name = "HORIZONTAL";
+ break;
+ case accessibility::AccessibleStateType::ICONIFIED:
+ name = "ICONIFIED";
+ break;
+ case accessibility::AccessibleStateType::INDETERMINATE:
+ name = "INDETERMINATE";
+ break;
+ case accessibility::AccessibleStateType::INVALID:
+ name = "INVALID";
+ break;
+ case accessibility::AccessibleStateType::MANAGES_DESCENDANTS:
+ name = "MANAGES_DESCENDANTS";
+ break;
+ case accessibility::AccessibleStateType::MODAL:
+ name = "MODAL";
+ break;
+ case accessibility::AccessibleStateType::MOVEABLE:
+ name = "MOVEABLE";
+ break;
+ case accessibility::AccessibleStateType::MULTI_LINE:
+ name = "MULTI_LINE";
+ break;
+ case accessibility::AccessibleStateType::MULTI_SELECTABLE:
+ name = "MULTI_SELECTABLE";
+ break;
+ case accessibility::AccessibleStateType::OFFSCREEN:
+ name = "OFFSCREEN";
+ break;
+ case accessibility::AccessibleStateType::OPAQUE:
+ name = "OPAQUE";
+ break;
+ case accessibility::AccessibleStateType::PRESSED:
+ name = "PRESSED";
+ break;
+ case accessibility::AccessibleStateType::RESIZABLE:
+ name = "RESIZABLE";
+ break;
+ case accessibility::AccessibleStateType::SELECTABLE:
+ name = "SELECTABLE";
+ break;
+ case accessibility::AccessibleStateType::SELECTED:
+ name = "SELECTED";
+ break;
+ case accessibility::AccessibleStateType::SENSITIVE:
+ name = "SENSITIVE";
+ break;
+ case accessibility::AccessibleStateType::SHOWING:
+ name = "SHOWING";
+ break;
+ case accessibility::AccessibleStateType::SINGLE_LINE:
+ name = "SINGLE_LINE";
+ break;
+ case accessibility::AccessibleStateType::STALE:
+ name = "STALE";
+ break;
+ case accessibility::AccessibleStateType::TRANSIENT:
+ name = "TRANSIENT";
+ break;
+ case accessibility::AccessibleStateType::VERTICAL:
+ name = "VERTICAL";
+ break;
+ case accessibility::AccessibleStateType::VISIBLE:
+ name = "VISIBLE";
+ break;
+ default:
+ name = unknownName(state);
+ break;
+ }
+ if (combinedName.getLength())
+ combinedName += " | ";
+ combinedName += name;
+ }
+
+ if (combinedName.isEmpty())
+ return "unknown";
+ return combinedName;
+}
+
+OUString AccessibilityTools::getEventIdName(const sal_Int16 event_id)
+{
+ switch (event_id)
+ {
+ case accessibility::AccessibleEventId::ACTION_CHANGED:
+ return "ACTION_CHANGED";
+ case accessibility::AccessibleEventId::ACTIVE_DESCENDANT_CHANGED:
+ return "ACTIVE_DESCENDANT_CHANGED";
+ case accessibility::AccessibleEventId::ACTIVE_DESCENDANT_CHANGED_NOFOCUS:
+ return "ACTIVE_DESCENDANT_CHANGED_NOFOCUS";
+ case accessibility::AccessibleEventId::BOUNDRECT_CHANGED:
+ return "BOUNDRECT_CHANGED";
+ case accessibility::AccessibleEventId::CARET_CHANGED:
+ return "CARET_CHANGED";
+ case accessibility::AccessibleEventId::CHILD:
+ return "CHILD";
+ case accessibility::AccessibleEventId::COLUMN_CHANGED:
+ return "COLUMN_CHANGED";
+ case accessibility::AccessibleEventId::CONTENT_FLOWS_FROM_RELATION_CHANGED:
+ return "CONTENT_FLOWS_FROM_RELATION_CHANGED";
+ case accessibility::AccessibleEventId::CONTENT_FLOWS_TO_RELATION_CHANGED:
+ return "CONTENT_FLOWS_TO_RELATION_CHANGED";
+ case accessibility::AccessibleEventId::CONTROLLED_BY_RELATION_CHANGED:
+ return "CONTROLLED_BY_RELATION_CHANGED";
+ case accessibility::AccessibleEventId::CONTROLLER_FOR_RELATION_CHANGED:
+ return "CONTROLLER_FOR_RELATION_CHANGED";
+ case accessibility::AccessibleEventId::DESCRIPTION_CHANGED:
+ return "DESCRIPTION_CHANGED";
+ case accessibility::AccessibleEventId::HYPERTEXT_CHANGED:
+ return "HYPERTEXT_CHANGED";
+ case accessibility::AccessibleEventId::INVALIDATE_ALL_CHILDREN:
+ return "INVALIDATE_ALL_CHILDREN";
+ case accessibility::AccessibleEventId::LABELED_BY_RELATION_CHANGED:
+ return "LABELED_BY_RELATION_CHANGED";
+ case accessibility::AccessibleEventId::LABEL_FOR_RELATION_CHANGED:
+ return "LABEL_FOR_RELATION_CHANGED";
+ case accessibility::AccessibleEventId::LISTBOX_ENTRY_COLLAPSED:
+ return "LISTBOX_ENTRY_COLLAPSED";
+ case accessibility::AccessibleEventId::LISTBOX_ENTRY_EXPANDED:
+ return "LISTBOX_ENTRY_EXPANDED";
+ case accessibility::AccessibleEventId::MEMBER_OF_RELATION_CHANGED:
+ return "MEMBER_OF_RELATION_CHANGED";
+ case accessibility::AccessibleEventId::NAME_CHANGED:
+ return "NAME_CHANGED";
+ case accessibility::AccessibleEventId::PAGE_CHANGED:
+ return "PAGE_CHANGED";
+ case accessibility::AccessibleEventId::ROLE_CHANGED:
+ return "ROLE_CHANGED";
+ case accessibility::AccessibleEventId::SECTION_CHANGED:
+ return "SECTION_CHANGED";
+ case accessibility::AccessibleEventId::SELECTION_CHANGED:
+ return "SELECTION_CHANGED";
+ case accessibility::AccessibleEventId::SELECTION_CHANGED_ADD:
+ return "SELECTION_CHANGED_ADD";
+ case accessibility::AccessibleEventId::SELECTION_CHANGED_REMOVE:
+ return "SELECTION_CHANGED_REMOVE";
+ case accessibility::AccessibleEventId::SELECTION_CHANGED_WITHIN:
+ return "SELECTION_CHANGED_WITHIN";
+ case accessibility::AccessibleEventId::STATE_CHANGED:
+ return "STATE_CHANGED";
+ case accessibility::AccessibleEventId::SUB_WINDOW_OF_RELATION_CHANGED:
+ return "SUB_WINDOW_OF_RELATION_CHANGED";
+ case accessibility::AccessibleEventId::TABLE_CAPTION_CHANGED:
+ return "TABLE_CAPTION_CHANGED";
+ case accessibility::AccessibleEventId::TABLE_COLUMN_DESCRIPTION_CHANGED:
+ return "TABLE_COLUMN_DESCRIPTION_CHANGED";
+ case accessibility::AccessibleEventId::TABLE_COLUMN_HEADER_CHANGED:
+ return "TABLE_COLUMN_HEADER_CHANGED";
+ case accessibility::AccessibleEventId::TABLE_MODEL_CHANGED:
+ return "TABLE_MODEL_CHANGED";
+ case accessibility::AccessibleEventId::TABLE_ROW_DESCRIPTION_CHANGED:
+ return "TABLE_ROW_DESCRIPTION_CHANGED";
+ case accessibility::AccessibleEventId::TABLE_ROW_HEADER_CHANGED:
+ return "TABLE_ROW_HEADER_CHANGED";
+ case accessibility::AccessibleEventId::TABLE_SUMMARY_CHANGED:
+ return "TABLE_SUMMARY_CHANGED";
+ case accessibility::AccessibleEventId::TEXT_ATTRIBUTE_CHANGED:
+ return "TEXT_ATTRIBUTE_CHANGED";
+ case accessibility::AccessibleEventId::TEXT_CHANGED:
+ return "TEXT_CHANGED";
+ case accessibility::AccessibleEventId::TEXT_SELECTION_CHANGED:
+ return "TEXT_SELECTION_CHANGED";
+ case accessibility::AccessibleEventId::VALUE_CHANGED:
+ return "VALUE_CHANGED";
+ case accessibility::AccessibleEventId::VISIBLE_DATA_CHANGED:
+ return "VISIBLE_DATA_CHANGED";
+ }
+ return unknownName(event_id);
+}
+
+OUString AccessibilityTools::getRelationTypeName(const sal_Int16 rel_type)
+{
+ switch (rel_type)
+ {
+ case accessibility::AccessibleRelationType::CONTENT_FLOWS_FROM:
+ return "CONTENT_FLOWS_FROM";
+ case accessibility::AccessibleRelationType::CONTENT_FLOWS_TO:
+ return "CONTENT_FLOWS_TO";
+ case accessibility::AccessibleRelationType::CONTROLLED_BY:
+ return "CONTROLLED_BY";
+ case accessibility::AccessibleRelationType::CONTROLLER_FOR:
+ return "CONTROLLER_FOR";
+ case accessibility::AccessibleRelationType::DESCRIBED_BY:
+ return "DESCRIBED_BY";
+ case accessibility::AccessibleRelationType::INVALID:
+ return "INVALID";
+ case accessibility::AccessibleRelationType::LABELED_BY:
+ return "LABELED_BY";
+ case accessibility::AccessibleRelationType::LABEL_FOR:
+ return "LABEL_FOR";
+ case accessibility::AccessibleRelationType::MEMBER_OF:
+ return "MEMBER_OF";
+ case accessibility::AccessibleRelationType::NODE_CHILD_OF:
+ return "NODE_CHILD_OF";
+ case accessibility::AccessibleRelationType::SUB_WINDOW_OF:
+ return "SUB_WINDOW_OF";
+ }
+ return unknownName(rel_type);
+}
+
+OUString AccessibilityTools::debugName(accessibility::XAccessibleContext* ctx)
+{
+ return "role=" + AccessibilityTools::getRoleName(ctx->getAccessibleRole()) + " name=\""
+ + ctx->getAccessibleName() + "\" description=\"" + ctx->getAccessibleDescription()
+ + "\"";
+}
+
+OUString AccessibilityTools::debugName(accessibility::XAccessible* acc)
+{
+ return debugName(acc->getAccessibleContext().get());
+}
+
+OUString AccessibilityTools::debugName(accessibility::XAccessibleAction* xAct)
+{
+ OUStringBuffer r = "actions=[";
+
+ const sal_Int32 nActions = xAct->getAccessibleActionCount();
+ for (sal_Int32 i = 0; i < nActions; i++)
+ {
+ if (i > 0)
+ r.append(", ");
+
+ r.append("description=\"" + xAct->getAccessibleActionDescription(i) + "\"");
+
+ const auto& xKeyBinding = xAct->getAccessibleActionKeyBinding(i);
+ if (xKeyBinding)
+ {
+ r.append(" keybindings=[");
+ const sal_Int32 nKeyBindings = xKeyBinding->getAccessibleKeyBindingCount();
+ for (sal_Int32 j = 0; j < nKeyBindings; j++)
+ {
+ if (j > 0)
+ r.append(", ");
+
+ int k = 0;
+ for (const auto& keyStroke : xKeyBinding->getAccessibleKeyBinding(j))
+ {
+ if (k++ > 0)
+ r.append(", ");
+
+ r.append('"');
+ if (keyStroke.Modifiers & awt::KeyModifier::MOD1)
+ r.append("<Mod1>");
+ if (keyStroke.Modifiers & awt::KeyModifier::MOD2)
+ r.append("<Mod2>");
+ if (keyStroke.Modifiers & awt::KeyModifier::MOD3)
+ r.append("<Mod3>");
+ if (keyStroke.Modifiers & awt::KeyModifier::SHIFT)
+ r.append("<Shift>");
+ r.append(OUStringChar(keyStroke.KeyChar) + "\"");
+ }
+ }
+ r.append("]");
+ }
+ }
+ r.append("]");
+ return r.makeStringAndClear();
+}
+
+OUString AccessibilityTools::debugName(accessibility::XAccessibleText* xTxt)
+{
+ uno::Reference<accessibility::XAccessibleContext> xCtx(xTxt, uno::UNO_QUERY);
+ return debugName(xCtx.get());
+}
+
+OUString AccessibilityTools::debugName(const accessibility::AccessibleEventObject* evobj)
+{
+ return "(AccessibleEventObject) { id=" + getEventIdName(evobj->EventId)
+ + " old=" + evobj->OldValue.getValueTypeName()
+ + " new=" + evobj->NewValue.getValueTypeName() + " }";
+}
+
+bool AccessibilityTools::Await(const std::function<bool()>& cUntilCallback, sal_uInt64 nTimeoutMs)
+{
+ bool success = false;
+ Timer aTimer("wait for event");
+ aTimer.SetTimeout(nTimeoutMs);
+ aTimer.Start();
+ do
+ {
+ Scheduler::ProcessEventsToIdle();
+ success = cUntilCallback();
+ } while (!success && aTimer.IsActive());
+ SAL_WARN_IF(!success, "test", "timeout reached");
+ return success;
+}
+
+void AccessibilityTools::Wait(sal_uInt64 nTimeoutMs)
+{
+ Timer aTimer("wait for event");
+ aTimer.SetTimeout(nTimeoutMs);
+ aTimer.Start();
+ std::cout << "waiting for " << nTimeoutMs << "ms... ";
+ do
+ {
+ Scheduler::ProcessEventsToIdle();
+ } while (aTimer.IsActive());
+ std::cout << "ok." << std::endl;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/test/source/a11y/accessibletestbase.cxx b/test/source/a11y/accessibletestbase.cxx
new file mode 100644
index 0000000000..92a40e87f7
--- /dev/null
+++ b/test/source/a11y/accessibletestbase.cxx
@@ -0,0 +1,581 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * 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 <test/a11y/accessibletestbase.hxx>
+
+#include <string>
+
+#include <com/sun/star/accessibility/AccessibleRole.hpp>
+#include <com/sun/star/accessibility/AccessibleStateType.hpp>
+#include <com/sun/star/accessibility/XAccessible.hpp>
+#include <com/sun/star/accessibility/XAccessibleAction.hpp>
+#include <com/sun/star/accessibility/XAccessibleContext.hpp>
+#include <com/sun/star/awt/XDialog2.hpp>
+#include <com/sun/star/awt/XExtendedToolkit.hpp>
+#include <com/sun/star/awt/XTopWindow.hpp>
+#include <com/sun/star/awt/XTopWindowListener.hpp>
+#include <com/sun/star/frame/Desktop.hpp>
+#include <com/sun/star/frame/FrameSearchFlag.hpp>
+#include <com/sun/star/frame/XFrame.hpp>
+#include <com/sun/star/frame/XFrame2.hpp>
+#include <com/sun/star/frame/XModel.hpp>
+#include <com/sun/star/uno/Reference.hxx>
+#include <com/sun/star/uno/RuntimeException.hpp>
+#include <com/sun/star/util/XCloseable.hpp>
+
+#include <vcl/idle.hxx>
+#include <vcl/scheduler.hxx>
+#include <vcl/svapp.hxx>
+
+#include <cppuhelper/implbase.hxx>
+
+#include <test/a11y/AccessibilityTools.hxx>
+
+using namespace css;
+
+void test::AccessibleTestBase::setUp()
+{
+ test::BootstrapFixture::setUp();
+
+ mxDesktop = frame::Desktop::create(mxComponentContext);
+}
+
+void test::AccessibleTestBase::close()
+{
+ if (mxDocument.is())
+ {
+ uno::Reference<util::XCloseable> xCloseable(mxDocument, uno::UNO_QUERY_THROW);
+ xCloseable->close(false);
+ mxDocument.clear();
+ }
+}
+
+void test::AccessibleTestBase::tearDown() { close(); }
+
+void test::AccessibleTestBase::load(const rtl::OUString& sURL)
+{
+ // make sure there is no open document in case it is called more than once
+ close();
+ mxDocument = mxDesktop->loadComponentFromURL(sURL, "_blank", frame::FrameSearchFlag::AUTO, {});
+
+ uno::Reference<frame::XModel> xModel(mxDocument, uno::UNO_QUERY_THROW);
+ mxWindow.set(xModel->getCurrentController()->getFrame()->getContainerWindow());
+
+ // bring window to front
+ uno::Reference<awt::XTopWindow> xTopWindow(mxWindow, uno::UNO_QUERY_THROW);
+ xTopWindow->toFront();
+}
+
+void test::AccessibleTestBase::loadFromSrc(const rtl::OUString& sSrcPath)
+{
+ load(m_directories.getURLFromSrc(sSrcPath));
+}
+
+uno::Reference<accessibility::XAccessibleContext>
+test::AccessibleTestBase::getWindowAccessibleContext()
+{
+ uno::Reference<accessibility::XAccessible> xAccessible(mxWindow, uno::UNO_QUERY_THROW);
+
+ return xAccessible->getAccessibleContext();
+}
+
+bool test::AccessibleTestBase::isDocumentRole(const sal_Int16 role)
+{
+ return (role == accessibility::AccessibleRole::DOCUMENT
+ || role == accessibility::AccessibleRole::DOCUMENT_PRESENTATION
+ || role == accessibility::AccessibleRole::DOCUMENT_SPREADSHEET
+ || role == accessibility::AccessibleRole::DOCUMENT_TEXT);
+}
+
+uno::Reference<accessibility::XAccessibleContext>
+test::AccessibleTestBase::getDocumentAccessibleContext()
+{
+ uno::Reference<frame::XModel> xModel(mxDocument, uno::UNO_QUERY_THROW);
+ uno::Reference<accessibility::XAccessible> xAccessible(
+ xModel->getCurrentController()->getFrame()->getComponentWindow(), uno::UNO_QUERY_THROW);
+
+ return AccessibilityTools::getAccessibleObjectForPredicate(
+ xAccessible->getAccessibleContext(),
+ [](const uno::Reference<accessibility::XAccessibleContext>& xCtx) {
+ return (isDocumentRole(xCtx->getAccessibleRole())
+ && xCtx->getAccessibleStateSet() & accessibility::AccessibleStateType::SHOWING);
+ });
+}
+
+uno::Reference<accessibility::XAccessibleContext>
+test::AccessibleTestBase::getFirstRelationTargetOfType(
+ const uno::Reference<accessibility::XAccessibleContext>& xContext, sal_Int16 relationType)
+{
+ auto relset = xContext->getAccessibleRelationSet();
+
+ if (relset.is())
+ {
+ for (sal_Int32 i = 0; i < relset->getRelationCount(); ++i)
+ {
+ const auto& rel = relset->getRelation(i);
+ if (rel.RelationType == relationType)
+ {
+ for (auto& target : rel.TargetSet)
+ {
+ uno::Reference<accessibility::XAccessible> targetAccessible(target,
+ uno::UNO_QUERY);
+ if (targetAccessible.is())
+ return targetAccessible->getAccessibleContext();
+ }
+ }
+ }
+ }
+
+ return nullptr;
+}
+
+std::deque<uno::Reference<accessibility::XAccessibleContext>>
+test::AccessibleTestBase::getAllChildren(
+ const uno::Reference<accessibility::XAccessibleContext>& xContext)
+{
+ std::deque<uno::Reference<accessibility::XAccessibleContext>> children;
+ auto childCount = xContext->getAccessibleChildCount();
+
+ for (sal_Int64 i = 0; i < childCount && i < AccessibilityTools::MAX_CHILDREN; i++)
+ {
+ auto child = xContext->getAccessibleChild(i);
+ children.push_back(child->getAccessibleContext());
+ }
+
+ return children;
+}
+
+/** Prints the tree of accessible objects starting at @p xContext to stdout */
+void test::AccessibleTestBase::dumpA11YTree(
+ const uno::Reference<accessibility::XAccessibleContext>& xContext, const int depth)
+{
+ Scheduler::ProcessEventsToIdle();
+ auto xRelSet = xContext->getAccessibleRelationSet();
+
+ std::cout << AccessibilityTools::debugString(xContext);
+ /* relation set is not included in AccessibilityTools::debugString(), but might be useful in
+ * this context, so we compute it here */
+ if (xRelSet.is())
+ {
+ auto relCount = xRelSet->getRelationCount();
+ if (relCount)
+ {
+ std::cout << " rels=[";
+ for (sal_Int32 i = 0; i < relCount; ++i)
+ {
+ if (i > 0)
+ std::cout << ", ";
+
+ const auto& rel = xRelSet->getRelation(i);
+ std::cout << "(type=" << AccessibilityTools::getRelationTypeName(rel.RelationType)
+ << " (" << rel.RelationType << ")";
+ std::cout << " targets=[";
+ int j = 0;
+ for (auto& target : rel.TargetSet)
+ {
+ if (j++ > 0)
+ std::cout << ", ";
+ uno::Reference<accessibility::XAccessible> ta(target, uno::UNO_QUERY_THROW);
+ std::cout << AccessibilityTools::debugString(ta);
+ }
+ std::cout << "])";
+ }
+ std::cout << "]";
+ }
+ }
+ std::cout << std::endl;
+
+ sal_Int32 i = 0;
+ for (auto& child : getAllChildren(xContext))
+ {
+ for (int j = 0; j < depth; j++)
+ std::cout << " ";
+ std::cout << " * child " << i++ << ": ";
+ dumpA11YTree(child, depth + 1);
+ }
+}
+
+/** Gets a child by name (usually in a menu) */
+uno::Reference<accessibility::XAccessibleContext> test::AccessibleTestBase::getItemFromName(
+ const uno::Reference<accessibility::XAccessibleContext>& xMenuCtx, std::u16string_view name)
+{
+ auto childCount = xMenuCtx->getAccessibleChildCount();
+
+ std::cout << "looking up item " << OUString(name) << " in "
+ << AccessibilityTools::debugString(xMenuCtx) << std::endl;
+ for (sal_Int64 i = 0; i < childCount && i < AccessibilityTools::MAX_CHILDREN; i++)
+ {
+ auto item = xMenuCtx->getAccessibleChild(i)->getAccessibleContext();
+ if (AccessibilityTools::nameEquals(item, name))
+ {
+ std::cout << "-> found " << AccessibilityTools::debugString(item) << std::endl;
+ return item;
+ }
+ }
+
+ std::cout << "-> NOT FOUND!" << std::endl;
+ std::cout << " Contents was: ";
+ dumpA11YTree(xMenuCtx, 1);
+
+ return uno::Reference<accessibility::XAccessibleContext>();
+}
+
+bool test::AccessibleTestBase::activateMenuItem(
+ const uno::Reference<accessibility::XAccessibleAction>& xAction)
+{
+ // assume first action is the right one, there's not description anyway
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xAction->getAccessibleActionCount());
+ if (xAction->doAccessibleAction(0))
+ {
+ Scheduler::ProcessEventsToIdle();
+ return true;
+ }
+ return false;
+}
+
+uno::Reference<accessibility::XAccessibleContext> test::AccessibleTestBase::getFocusedObject(
+ const uno::Reference<accessibility::XAccessibleContext>& xCtx)
+{
+ return AccessibilityTools::getAccessibleObjectForPredicate(
+ xCtx, [](const uno::Reference<accessibility::XAccessibleContext>& xCandidateCtx) {
+ const auto states = (accessibility::AccessibleStateType::FOCUSED
+ | accessibility::AccessibleStateType::SHOWING);
+ return (xCandidateCtx->getAccessibleStateSet() & states) == states;
+ });
+}
+
+uno::Reference<accessibility::XAccessibleContext>
+test::AccessibleTestBase::tabTo(const uno::Reference<accessibility::XAccessible>& xRoot,
+ const sal_Int16 role, const std::u16string_view name,
+ const EventPosterHelperBase* pEventPosterHelper)
+{
+ AccessibleEventPosterHelper eventHelper;
+ if (!pEventPosterHelper)
+ {
+ eventHelper.setWindow(xRoot);
+ pEventPosterHelper = &eventHelper;
+ }
+
+ auto xOriginalFocus = getFocusedObject(xRoot);
+ auto xFocus = xOriginalFocus;
+ int nSteps = 0;
+
+ std::cout << "Tabbing to '" << OUString(name) << "'..." << std::endl;
+ while (xFocus && (nSteps == 0 || xFocus != xOriginalFocus))
+ {
+ std::cout << " focused object is: " << AccessibilityTools::debugString(xFocus)
+ << std::endl;
+ if (xFocus->getAccessibleRole() == role && AccessibilityTools::nameEquals(xFocus, name))
+ {
+ std::cout << " -> OK, focus matches" << std::endl;
+ return xFocus;
+ }
+ if (++nSteps > 100)
+ {
+ std::cerr << "Object not found after tabbing 100 times! bailing out" << std::endl;
+ break;
+ }
+
+ std::cout << " -> no match, sending <TAB>" << std::endl;
+ pEventPosterHelper->postKeyEventAsync(0, awt::Key::TAB);
+ Scheduler::ProcessEventsToIdle();
+
+ const auto xPrevFocus = xFocus;
+ xFocus = getFocusedObject(xRoot);
+ if (!xFocus)
+ std::cerr << "Focus lost after sending <TAB>!" << std::endl;
+ else if (xPrevFocus == xFocus)
+ {
+ std::cerr << "Focus didn't move after sending <TAB>! bailing out" << std::endl;
+ std::cerr << "Focused object(s):" << std::endl;
+ int iFocusedCount = 0;
+ // count and print out objects with focused state
+ AccessibilityTools::getAccessibleObjectForPredicate(
+ xRoot,
+ [&iFocusedCount](const uno::Reference<accessibility::XAccessibleContext>& xCtx) {
+ const auto states = (accessibility::AccessibleStateType::FOCUSED
+ | accessibility::AccessibleStateType::SHOWING);
+ if ((xCtx->getAccessibleStateSet() & states) == states)
+ {
+ std::cerr << " * " << AccessibilityTools::debugString(xCtx) << std::endl;
+ iFocusedCount++;
+ }
+ return false; // keep going
+ });
+ std::cerr << "Total focused element(s): " << iFocusedCount << std::endl;
+ if (iFocusedCount > 1)
+ std::cerr << "WARNING: there are more than one focused object! This usually means "
+ "there is a BUG in the focus handling of that accessibility tree."
+ << std::endl;
+ break;
+ }
+ }
+
+ std::cerr << "NOT FOUND" << std::endl;
+ return nullptr;
+}
+
+bool test::AccessibleTestBase::tabTo(
+ const uno::Reference<accessibility::XAccessible>& xRoot,
+ const uno::Reference<accessibility::XAccessibleContext>& xChild,
+ const EventPosterHelperBase* pEventPosterHelper)
+{
+ AccessibleEventPosterHelper eventHelper;
+ if (!pEventPosterHelper)
+ {
+ eventHelper.setWindow(xRoot);
+ pEventPosterHelper = &eventHelper;
+ }
+
+ std::cout << "Tabbing to " << AccessibilityTools::debugString(xChild) << "..." << std::endl;
+ for (int i = 0; i < 100; i++)
+ {
+ if (xChild->getAccessibleStateSet() & accessibility::AccessibleStateType::FOCUSED)
+ return true;
+
+ std::cout << " no match, sending <TAB>" << std::endl;
+ pEventPosterHelper->postKeyEventAsync(0, awt::Key::TAB);
+ Scheduler::ProcessEventsToIdle();
+ }
+
+ std::cerr << "NOT FOUND" << std::endl;
+ return false;
+}
+
+#if !defined(MACOSX)
+/* Dialog handling
+ *
+ * For now this doesn't actually work under macos, so the API is not available there not to create
+ * confusion. The problem there is we don't get notified of new dialogs, so we can't manage them
+ * or interact with them.
+ */
+
+test::AccessibleTestBase::Dialog::Dialog(uno::Reference<awt::XDialog2>& xDialog2, bool bAutoClose)
+ : mbAutoClose(bAutoClose)
+ , mxDialog2(xDialog2)
+{
+ CPPUNIT_ASSERT(xDialog2.is());
+
+ mxAccessible.set(xDialog2, uno::UNO_QUERY);
+ if (mxAccessible)
+ setWindow(mxAccessible);
+ else
+ {
+ std::cerr << "WARNING: AccessibleTestBase::Dialog() constructed with awt::XDialog2 '"
+ << xDialog2->getTitle()
+ << "' not implementing accessibility::XAccessible. Event delivery will not work."
+ << std::endl;
+ }
+}
+
+test::AccessibleTestBase::Dialog::~Dialog()
+{
+ if (mbAutoClose)
+ close();
+}
+
+void test::AccessibleTestBase::Dialog::close(sal_Int32 result)
+{
+ if (mxDialog2)
+ {
+ mxDialog2->endDialog(result);
+ mxDialog2.clear();
+ }
+}
+
+std::shared_ptr<test::AccessibleTestBase::DialogWaiter>
+test::AccessibleTestBase::awaitDialog(const std::u16string_view name,
+ std::function<void(Dialog&)> callback, bool bAutoClose)
+{
+ /* Helper class to wait on a dialog to pop up and to close, running user code between the
+ * two. This has to work both for "other window"-style dialogues (non-modal), as well as
+ * for modal dialogues using Dialog::Execute() (which runs a nested main loop, hence
+ * blocking our test flow execution.
+ * The approach here is to wait on the WindowActivate event for the dialog, and run the
+ * test code in there. Then, close the dialog if not already done, resuming normal flow to
+ * the caller. */
+ class ListenerHelper : public DialogWaiter
+ {
+ DialogCancelMode miPreviousDialogCancelMode;
+ uno::Reference<awt::XExtendedToolkit> mxToolkit;
+ bool mbWaitingForDialog;
+ std::exception_ptr mpException;
+ std::u16string_view msName;
+ std::function<void(Dialog&)> mCallback;
+ bool mbAutoClose;
+ Timer maTimeoutTimer;
+ Idle maIdleHandler;
+ uno::Reference<awt::XTopWindowListener> mxTopWindowListener;
+ std::unique_ptr<Dialog> mxDialog;
+
+ public:
+ virtual ~ListenerHelper()
+ {
+ Application::SetDialogCancelMode(miPreviousDialogCancelMode);
+ mxToolkit->removeTopWindowListener(mxTopWindowListener);
+ maTimeoutTimer.Stop();
+ maIdleHandler.Stop();
+ }
+
+ ListenerHelper(const std::u16string_view& name, std::function<void(Dialog&)> callback,
+ bool bAutoClose)
+ : mbWaitingForDialog(true)
+ , msName(name)
+ , mCallback(callback)
+ , mbAutoClose(bAutoClose)
+ , maTimeoutTimer("workaround timer if we don't catch WindowActivate")
+ , maIdleHandler("runs user callback in idle time")
+ {
+ mxTopWindowListener.set(new MyTopWindowListener(this));
+ mxToolkit.set(Application::GetVCLToolkit(), uno::UNO_QUERY_THROW);
+ mxToolkit->addTopWindowListener(mxTopWindowListener);
+
+ maTimeoutTimer.SetInvokeHandler(LINK(this, ListenerHelper, timeoutTimerHandler));
+ maTimeoutTimer.SetTimeout(60000);
+ maTimeoutTimer.Start();
+
+ maIdleHandler.SetInvokeHandler(LINK(this, ListenerHelper, idleHandler));
+ maIdleHandler.SetPriority(TaskPriority::DEFAULT_IDLE);
+
+ miPreviousDialogCancelMode = Application::GetDialogCancelMode();
+ Application::SetDialogCancelMode(DialogCancelMode::Off);
+ }
+
+ private:
+ // mimic IMPL_LINK inline
+ static void LinkStubtimeoutTimerHandler(void* instance, Timer* timer)
+ {
+ static_cast<ListenerHelper*>(instance)->timeoutTimerHandler(timer);
+ }
+
+ void timeoutTimerHandler(Timer*)
+ {
+ std::cerr << "timeout waiting for dialog '" << OUString(msName) << "' to show up"
+ << std::endl;
+
+ assert(mbWaitingForDialog);
+
+ // This is not very nice, but it should help fail earlier if we never catch the dialog
+ // yet we're in a sub-loop and waitEndDialog() didn't have a chance to run yet.
+ throw new css::uno::RuntimeException("Timeout waiting for dialog");
+ }
+
+ class MyTopWindowListener : public ::cppu::WeakImplHelper<awt::XTopWindowListener>
+ {
+ private:
+ ListenerHelper* mpHelper;
+
+ public:
+ MyTopWindowListener(ListenerHelper* pHelper)
+ : mpHelper(pHelper)
+ {
+ assert(mpHelper);
+ }
+
+ // XTopWindowListener
+ virtual void SAL_CALL windowOpened(const lang::EventObject&) override {}
+ virtual void SAL_CALL windowClosing(const lang::EventObject&) override {}
+ virtual void SAL_CALL windowClosed(const lang::EventObject&) override {}
+ virtual void SAL_CALL windowMinimized(const lang::EventObject&) override {}
+ virtual void SAL_CALL windowNormalized(const lang::EventObject&) override {}
+ virtual void SAL_CALL windowDeactivated(const lang::EventObject&) override {}
+ virtual void SAL_CALL windowActivated(const lang::EventObject& xEvent) override
+ {
+ assert(mpHelper->mbWaitingForDialog);
+
+ if (!xEvent.Source)
+ return;
+
+ uno::Reference<awt::XDialog2> xDialog(xEvent.Source, uno::UNO_QUERY);
+ if (!xDialog)
+ return;
+
+ // remove ourselves, we don't want to run again
+ mpHelper->mxToolkit->removeTopWindowListener(this);
+
+ mpHelper->mxDialog = std::make_unique<Dialog>(xDialog, true);
+
+ mpHelper->maIdleHandler.Start();
+ }
+
+ // XEventListener
+ virtual void SAL_CALL disposing(const lang::EventObject&) override {}
+ };
+
+ // mimic IMPL_LINK inline
+ static void LinkStubidleHandler(void* instance, Timer* idle)
+ {
+ static_cast<ListenerHelper*>(instance)->idleHandler(idle);
+ }
+
+ void idleHandler(Timer*)
+ {
+ mbWaitingForDialog = false;
+
+ maTimeoutTimer.ClearInvokeHandler();
+ maTimeoutTimer.Stop();
+
+ /* The popping up dialog ought to be the right one, or something's fishy and
+ * we're bound to failure (e.g. waiting on a dialog that either will never come, or
+ * that will not run after the current one -- deadlock style) */
+ if (msName != mxDialog->getWindow()->GetText())
+ {
+ mpException = std::make_exception_ptr(css::uno::RuntimeException(
+ "Unexpected dialog '" + mxDialog->getWindow()->GetText()
+ + "' opened instead of the expected '" + msName + "'"));
+ }
+ else
+ {
+ std::cout << "found dialog, calling user callback" << std::endl;
+
+ // set the real requested auto close now we're just calling the user callback
+ mxDialog->setAutoClose(mbAutoClose);
+
+ try
+ {
+ mCallback(*mxDialog);
+ }
+ catch (...)
+ {
+ mpException = std::current_exception();
+ }
+ }
+
+ mxDialog.reset();
+ }
+
+ public:
+ virtual bool waitEndDialog(sal_uInt64 nTimeoutMs) override
+ {
+ /* Usually this loop will actually never run at all because a previous
+ * Scheduler::ProcessEventsToIdle() would have triggered the dialog already, but we
+ * can't be sure of that or of delays, so be safe and wait with a timeout. */
+ if (mbWaitingForDialog)
+ {
+ Timer aTimer("wait for dialog");
+ aTimer.SetTimeout(nTimeoutMs);
+ aTimer.Start();
+ do
+ {
+ Application::Yield();
+ } while (mbWaitingForDialog && aTimer.IsActive());
+ }
+
+ if (mpException)
+ std::rethrow_exception(mpException);
+
+ return !mbWaitingForDialog;
+ }
+ };
+
+ return std::make_shared<ListenerHelper>(name, callback, bAutoClose);
+}
+#endif //defined(MACOSX)
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/test/source/a11y/eventposter.cxx b/test/source/a11y/eventposter.cxx
new file mode 100644
index 0000000000..39e178e227
--- /dev/null
+++ b/test/source/a11y/eventposter.cxx
@@ -0,0 +1,46 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * 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 <test/a11y/eventposter.hxx>
+
+#include <com/sun/star/accessibility/XAccessible.hpp>
+#include <com/sun/star/accessibility/XAccessibleContext.hpp>
+#include <com/sun/star/uno/Reference.hxx>
+
+#include <sfx2/lokhelper.hxx>
+#include <test/a11y/AccessibilityTools.hxx>
+#include <toolkit/awt/vclxwindow.hxx>
+
+void test::EventPosterHelper::postKeyEventAsync(int nType, int nCharCode, int nKeyCode) const
+{
+ SfxLokHelper::postKeyEventAsync(mxWindow, nType, nCharCode, nKeyCode);
+}
+
+void test::EventPosterHelper::postExtTextEventAsync(int nType, const OUString& rText) const
+{
+ SfxLokHelper::postExtTextEventAsync(mxWindow, nType, rText);
+}
+
+void test::AccessibleEventPosterHelper::setWindow(
+ css::uno::Reference<css::accessibility::XAccessible> xAcc)
+{
+ while (auto xParent = xAcc->getAccessibleContext()->getAccessibleParent())
+ xAcc = xParent;
+ auto vclXWindow = dynamic_cast<VCLXWindow*>(xAcc.get());
+ if (!vclXWindow)
+ {
+ std::cerr << "WARNING: AccessibleEventPosterHelper::setWindow() called on "
+ "unsupported object "
+ << AccessibilityTools::debugString(xAcc) << ". Event delivery will not work."
+ << std::endl;
+ }
+ mxWindow = vclXWindow ? vclXWindow->GetWindow() : nullptr;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/test/source/a11y/swaccessibletestbase.cxx b/test/source/a11y/swaccessibletestbase.cxx
new file mode 100644
index 0000000000..b43d65c0cf
--- /dev/null
+++ b/test/source/a11y/swaccessibletestbase.cxx
@@ -0,0 +1,135 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * 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 <test/a11y/swaccessibletestbase.hxx>
+
+#include <com/sun/star/accessibility/AccessibleRelationType.hpp>
+#include <com/sun/star/accessibility/XAccessibleContext.hpp>
+#include <com/sun/star/accessibility/XAccessibleText.hpp>
+#include <com/sun/star/uno/Reference.hxx>
+
+#include <rtl/ustrbuf.hxx>
+
+#include <test/a11y/AccessibilityTools.hxx>
+
+using namespace css;
+
+uno::Reference<accessibility::XAccessibleContext>
+test::SwAccessibleTestBase::getPreviousFlowingSibling(
+ const uno::Reference<accessibility::XAccessibleContext>& xContext)
+{
+ return getFirstRelationTargetOfType(xContext,
+ accessibility::AccessibleRelationType::CONTENT_FLOWS_FROM);
+}
+
+uno::Reference<accessibility::XAccessibleContext> test::SwAccessibleTestBase::getNextFlowingSibling(
+ const uno::Reference<accessibility::XAccessibleContext>& xContext)
+{
+ return getFirstRelationTargetOfType(xContext,
+ accessibility::AccessibleRelationType::CONTENT_FLOWS_TO);
+}
+
+/* Care has to be taken not to walk sideways as the relation is also used
+ * with children of nested containers (possibly as the "natural"/"perceived" flow?). */
+std::deque<uno::Reference<accessibility::XAccessibleContext>>
+test::SwAccessibleTestBase::getAllChildren(
+ const uno::Reference<accessibility::XAccessibleContext>& xContext)
+{
+ /* first, get all "natural" children */
+ auto children = AccessibleTestBase::getAllChildren(xContext);
+ if (!children.size())
+ return children;
+
+ /* then, try and find flowing siblings at the same levels that are not included in the list */
+ /* first, backwards: */
+ auto child = getPreviousFlowingSibling(children.front());
+ while (child.is() && children.size() < AccessibilityTools::MAX_CHILDREN)
+ {
+ auto childParent = child->getAccessibleParent();
+ if (childParent.is()
+ && AccessibilityTools::equals(xContext, childParent->getAccessibleContext()))
+ children.push_front(child);
+ child = getPreviousFlowingSibling(child);
+ }
+ /* then forward */
+ child = getNextFlowingSibling(children.back());
+ while (child.is() && children.size() < AccessibilityTools::MAX_CHILDREN)
+ {
+ auto childParent = child->getAccessibleParent();
+ if (childParent.is()
+ && AccessibilityTools::equals(xContext, childParent->getAccessibleContext()))
+ children.push_back(child);
+ child = getNextFlowingSibling(child);
+ }
+
+ return children;
+}
+
+void test::SwAccessibleTestBase::collectText(
+ const uno::Reference<accessibility::XAccessibleContext>& xContext, rtl::OUStringBuffer& buffer,
+ bool onlyChildren)
+{
+ const auto& roleName = AccessibilityTools::getRoleName(xContext->getAccessibleRole());
+
+ std::cout << "collecting text for child of role " << roleName << "..." << std::endl;
+
+ if (!onlyChildren)
+ {
+ const struct
+ {
+ std::u16string_view name;
+ rtl::OUString value;
+ } attrs[] = {
+ { u"name", xContext->getAccessibleName() },
+ { u"description", xContext->getAccessibleDescription() },
+ };
+
+ buffer.append('<');
+ buffer.append(roleName);
+ for (auto& attr : attrs)
+ {
+ if (attr.value.getLength() == 0)
+ continue;
+ buffer.append(' ');
+ buffer.append(attr.name);
+ buffer.append(u"=\"" + attr.value.replaceAll(u"\"", u"&quot;") + "\"");
+ }
+ buffer.append('>');
+ }
+ auto openTagLength = buffer.getLength();
+
+ uno::Reference<accessibility::XAccessibleText> xText(xContext, uno::UNO_QUERY);
+ if (xText.is())
+ buffer.append(xText->getText());
+
+ for (auto& childContext : getAllChildren(xContext))
+ collectText(childContext, buffer);
+
+ if (!onlyChildren)
+ {
+ if (buffer.getLength() != openTagLength)
+ buffer.append("</" + roleName + ">");
+ else
+ {
+ /* there was no content, so make is a short tag for more concise output */
+ buffer[openTagLength - 1] = '/';
+ buffer.append('>');
+ }
+ }
+}
+
+OUString test::SwAccessibleTestBase::collectText(
+ const uno::Reference<accessibility::XAccessibleContext>& xContext)
+{
+ rtl::OUStringBuffer buf;
+ collectText(xContext, buf, isDocumentRole(xContext->getAccessibleRole()));
+ return buf.makeStringAndClear();
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/test/source/beans/xpropertyset.cxx b/test/source/beans/xpropertyset.cxx
new file mode 100644
index 0000000000..038b1e5733
--- /dev/null
+++ b/test/source/beans/xpropertyset.cxx
@@ -0,0 +1,347 @@
+/* -*- 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 <test/beans/xpropertyset.hxx>
+
+#include <com/sun/star/beans/Property.hpp>
+#include <com/sun/star/beans/PropertyAttribute.hpp>
+#include <com/sun/star/beans/PropertyChangeEvent.hpp>
+#include <com/sun/star/beans/XPropertyChangeListener.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/beans/XVetoableChangeListener.hpp>
+#include <com/sun/star/lang/EventObject.hpp>
+#include <com/sun/star/util/DateTime.hpp>
+#include <com/sun/star/util/XComplexColor.hpp>
+
+#include <com/sun/star/uno/Any.hxx>
+#include <com/sun/star/uno/Reference.hxx>
+#include <com/sun/star/uno/Type.h>
+
+#include <cppuhelper/implbase.hxx>
+#include <docmodel/uno/UnoComplexColor.hxx>
+#include <rtl/ref.hxx>
+
+#include <cppunit/TestAssert.h>
+
+using namespace css;
+using namespace css::uno;
+
+namespace apitest
+{
+XPropertySet::PropsToTest::PropsToTest()
+ : initialized(false)
+{
+}
+
+namespace
+{
+class MockedPropertyChangeListener : public ::cppu::WeakImplHelper<beans::XPropertyChangeListener>
+{
+public:
+ MockedPropertyChangeListener()
+ : m_bListenerCalled(false)
+ {
+ }
+
+ bool m_bListenerCalled;
+
+ virtual void SAL_CALL propertyChange(const beans::PropertyChangeEvent& /* xEvent */) override
+ {
+ m_bListenerCalled = true;
+ }
+
+ virtual void SAL_CALL disposing(const lang::EventObject& /* xEventObj */) override {}
+};
+
+class MockedVetoableChangeListener : public ::cppu::WeakImplHelper<beans::XVetoableChangeListener>
+{
+public:
+ MockedVetoableChangeListener()
+ : m_bListenerCalled(false)
+ {
+ }
+
+ bool m_bListenerCalled;
+
+ virtual void SAL_CALL vetoableChange(const beans::PropertyChangeEvent& /* xEvent */) override
+ {
+ m_bListenerCalled = true;
+ }
+
+ virtual void SAL_CALL disposing(const lang::EventObject& /* xEventObj */) override {}
+};
+}
+
+void XPropertySet::testPropertyChangeListener()
+{
+ uno::Reference<beans::XPropertySet> xPropSet(init(), uno::UNO_QUERY_THROW);
+ uno::Reference<beans::XPropertySetInfo> xPropInfo = xPropSet->getPropertySetInfo();
+ fillPropsToTest(xPropInfo);
+
+ for (const auto& aName : maPropsToTest.bound)
+ {
+ rtl::Reference<MockedPropertyChangeListener> xListener = new MockedPropertyChangeListener();
+ xPropSet->addPropertyChangeListener(
+ aName, uno::Reference<beans::XPropertyChangeListener>(xListener));
+ if (!isPropertyValueChangeable(aName))
+ continue;
+
+ CPPUNIT_ASSERT(xListener->m_bListenerCalled);
+
+ xListener->m_bListenerCalled = false;
+ xPropSet->removePropertyChangeListener(
+ aName, uno::Reference<beans::XPropertyChangeListener>(xListener));
+ isPropertyValueChangeable(aName);
+ CPPUNIT_ASSERT(!xListener->m_bListenerCalled);
+ }
+}
+
+void XPropertySet::testVetoableChangeListener()
+{
+ uno::Reference<beans::XPropertySet> xPropSet(init(), uno::UNO_QUERY_THROW);
+ uno::Reference<beans::XPropertySetInfo> xPropInfo = xPropSet->getPropertySetInfo();
+ fillPropsToTest(xPropInfo);
+
+ for (const auto& aName : maPropsToTest.bound)
+ {
+ rtl::Reference<MockedVetoableChangeListener> xListener = new MockedVetoableChangeListener();
+ xPropSet->addVetoableChangeListener(
+ aName, uno::Reference<beans::XVetoableChangeListener>(xListener));
+ if (!isPropertyValueChangeable(aName))
+ continue;
+
+ CPPUNIT_ASSERT(xListener->m_bListenerCalled);
+
+ xListener->m_bListenerCalled = false;
+ xPropSet->removeVetoableChangeListener(
+ aName, uno::Reference<beans::XVetoableChangeListener>(xListener));
+ isPropertyValueChangeable(aName);
+ CPPUNIT_ASSERT(!xListener->m_bListenerCalled);
+ }
+}
+
+void XPropertySet::testGetPropertySetInfo()
+{
+ uno::Reference<beans::XPropertySet> xPropSet(init(), UNO_QUERY_THROW);
+ uno::Reference<beans::XPropertySetInfo> xPropInfo = xPropSet->getPropertySetInfo();
+ if (xPropInfo.is())
+ {
+ fillPropsToTest(xPropInfo);
+ }
+ else
+ {
+ // TODO: Add a means for the client code to populate the PropsToTest.
+ }
+}
+
+void XPropertySet::testSetPropertyValue()
+{
+ testGetPropertySetInfo();
+
+ for (size_t i = 0, n = maPropsToTest.normal.size(); i < n; ++i)
+ {
+ bool bSuccess = isPropertyValueChangeable(maPropsToTest.normal[i]);
+ CPPUNIT_ASSERT(bSuccess);
+ }
+}
+
+void XPropertySet::testGetPropertyValue()
+{
+ testGetPropertySetInfo();
+ uno::Reference<beans::XPropertySet> xPropSet(init(), UNO_QUERY_THROW);
+
+ // Check read-only properties.
+ for (size_t i = 0, n = maPropsToTest.readonly.size(); i < n; ++i)
+ {
+ bool bSuccess = getSinglePropertyValue(xPropSet, maPropsToTest.readonly[i]);
+ CPPUNIT_ASSERT(bSuccess);
+ }
+
+ // Check writable properties.
+ for (size_t i = 0, n = maPropsToTest.normal.size(); i < n; ++i)
+ {
+ bool bSuccess = getSinglePropertyValue(xPropSet, maPropsToTest.normal[i]);
+ CPPUNIT_ASSERT(bSuccess);
+ }
+}
+
+bool XPropertySet::isPropertyValueChangeable(const OUString& rName)
+{
+ bool bIgnore = isPropertyIgnored(rName);
+ if (bIgnore)
+ return false;
+
+ uno::Reference<beans::XPropertySet> xPropSet(init(), UNO_QUERY_THROW);
+ try
+ {
+ uno::Any any = xPropSet->getPropertyValue(rName);
+ const uno::Type& type = any.getValueType();
+ if (type == cppu::UnoType<bool>::get())
+ {
+ // boolean type
+ bool bOld = any.get<bool>();
+ xPropSet->setPropertyValue(rName, Any(!bOld));
+ }
+ else if (type == cppu::UnoType<sal_Int8>::get())
+ {
+ // 8-bit integer
+ sal_Int8 nOld = any.get<sal_Int8>();
+ sal_Int8 nNew = nOld + 1;
+ xPropSet->setPropertyValue(rName, Any(nNew));
+ }
+ else if (type == cppu::UnoType<sal_Int16>::get())
+ {
+ // 16-bit integer
+ sal_Int16 nOld = any.get<sal_Int16>();
+ sal_Int16 nNew = nOld + 1;
+ xPropSet->setPropertyValue(rName, Any(nNew));
+ }
+ else if (type == cppu::UnoType<sal_Int32>::get())
+ {
+ // 32-bit integer
+ sal_Int32 nOld = any.get<sal_Int32>();
+ sal_Int32 nNew = nOld + 3;
+ xPropSet->setPropertyValue(rName, Any(nNew));
+ }
+ else if (type == cppu::UnoType<sal_Int64>::get())
+ {
+ // 64-bit integer
+ sal_Int64 nOld = any.get<sal_Int64>();
+ sal_Int64 nNew = nOld + 4;
+ xPropSet->setPropertyValue(rName, Any(nNew));
+ }
+ else if (type == cppu::UnoType<float>::get())
+ {
+ // single precision
+ float fOld = any.get<float>();
+ float fNew = fOld + 1.2;
+ xPropSet->setPropertyValue(rName, Any(fNew));
+ }
+ else if (type == cppu::UnoType<double>::get())
+ {
+ // double precision
+ double fOld = any.get<double>();
+ double fNew = fOld + 1.3;
+ xPropSet->setPropertyValue(rName, Any(fNew));
+ }
+ else if (type == cppu::UnoType<OUString>::get())
+ {
+ // string type
+ OUString aOld = any.get<OUString>();
+ OUString aNew = aOld + "foo";
+ xPropSet->setPropertyValue(rName, Any(aNew));
+ }
+ else if (type == cppu::UnoType<util::DateTime>::get())
+ {
+ // date time type
+ util::DateTime aDT = any.get<util::DateTime>();
+ aDT.Year += 1;
+ xPropSet->setPropertyValue(rName, Any(aDT));
+ }
+ else if (type == cppu::UnoType<uno::Reference<util::XComplexColor>>::get())
+ {
+ auto xComplexColor = any.get<uno::Reference<util::XComplexColor>>();
+ auto aComplexColor = model::color::getFromXComplexColor(xComplexColor);
+ xPropSet->setPropertyValue(rName,
+ Any(model::color::createXComplexColor(aComplexColor)));
+ }
+ else
+ {
+ std::cout << "Unknown type:\n"
+ "Type: "
+ << type.getTypeName()
+ << "\n"
+ "Name: "
+ << rName << "\n";
+ CPPUNIT_ASSERT_MESSAGE(
+ "XPropertySet::isPropertyValueChangeable: unknown type in Any tested.", false);
+ }
+
+ uno::Any anyTest = xPropSet->getPropertyValue(rName);
+ return any != anyTest;
+ }
+ catch (const uno::Exception&)
+ {
+ std::cout << "Exception thrown while retrieving with property: " << rName << "\n";
+ CPPUNIT_ASSERT_MESSAGE("XPropertySet::isPropertyValueChangeable: exception thrown while "
+ "retrieving the property value.",
+ false);
+ }
+
+ return false;
+}
+
+void XPropertySet::fillPropsToTest(const uno::Reference<beans::XPropertySetInfo>& xPropInfo)
+{
+ if (maPropsToTest.initialized)
+ return;
+
+ const uno::Sequence<beans::Property> aProps = xPropInfo->getProperties();
+
+ // some properties should not be changed in a unspecific way.
+ // TODO: Maybe we should mark these properties read-only, instead of
+ // giving them a special treatment here?
+ std::set<OUString> aSkip;
+ aSkip.insert("PrinterName");
+ aSkip.insert("CharRelief");
+ aSkip.insert("IsLayerMode");
+
+ for (const beans::Property& aProp : aProps)
+ {
+ if (aSkip.count(aProp.Name) > 0)
+ continue;
+
+ if ((aProp.Attributes & beans::PropertyAttribute::READONLY) != 0)
+ {
+ maPropsToTest.readonly.push_back(aProp.Name);
+ continue;
+ }
+
+ if ((aProp.Attributes & beans::PropertyAttribute::MAYBEVOID) != 0)
+ continue;
+
+ bool bBound = (aProp.Attributes & beans::PropertyAttribute::BOUND) != 0;
+ bool bConstrained = (aProp.Attributes & beans::PropertyAttribute::CONSTRAINED) != 0;
+ bool bCanChange = isPropertyValueChangeable(aProp.Name);
+
+ if (bBound && bCanChange)
+ maPropsToTest.bound.push_back(aProp.Name);
+
+ if (bConstrained && bCanChange)
+ maPropsToTest.constrained.push_back(aProp.Name);
+
+ if (bCanChange)
+ maPropsToTest.normal.push_back(aProp.Name);
+ }
+
+ maPropsToTest.initialized = true;
+}
+
+bool XPropertySet::getSinglePropertyValue(const uno::Reference<beans::XPropertySet>& xPropSet,
+ const OUString& rName)
+{
+ try
+ {
+ xPropSet->getPropertyValue(rName);
+ return true;
+ }
+ catch (const uno::Exception&)
+ {
+ }
+ return false;
+}
+
+bool XPropertySet::isPropertyIgnored(const OUString& rName)
+{
+ return m_IgnoreValue.count(rName) > 0;
+}
+
+} // namespace apitest
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/test/source/bootstrapfixture.cxx b/test/source/bootstrapfixture.cxx
new file mode 100644
index 0000000000..f1db0bf666
--- /dev/null
+++ b/test/source/bootstrapfixture.cxx
@@ -0,0 +1,281 @@
+/* -*- 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 <config_validation.h>
+
+#include <test/bootstrapfixture.hxx>
+#include <vcl/errinf.hxx>
+#include <sal/log.hxx>
+#include <comphelper/processfactory.hxx>
+
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/ucb/XContentProvider.hpp>
+#include <com/sun/star/ucb/XUniversalContentBroker.hpp>
+
+#include <vcl/outdev.hxx>
+#include <vcl/svapp.hxx>
+#include <tools/link.hxx>
+#include <vcl/graphicfilter.hxx>
+#include <osl/file.hxx>
+#include <osl/process.h>
+#include <unotest/getargument.hxx>
+#include <unotools/tempfile.hxx>
+#include <vcl/salgtype.hxx>
+#include <vcl/scheduler.hxx>
+#include <vcl/virdev.hxx>
+#include <o3tl/string_view.hxx>
+
+#include <memory>
+#include <cstring>
+
+#include "setupvcl.hxx"
+
+using namespace ::com::sun::star;
+
+static void aBasicErrorFunc( const OUString &rErr, const OUString &rAction )
+{
+ OString aErr = "Unexpected dialog: " +
+ OUStringToOString( rAction, RTL_TEXTENCODING_ASCII_US ) +
+ " Error: " +
+ OUStringToOString( rErr, RTL_TEXTENCODING_ASCII_US );
+ CPPUNIT_ASSERT_MESSAGE( aErr.getStr(), false);
+}
+
+// NB. this constructor is called before any tests are run, once for each
+// test function in a rather non-intuitive way. This is why all the 'real'
+// heavy lifting is deferred until setUp. setUp and tearDown are interleaved
+// between the tests as you might expect.
+test::BootstrapFixture::BootstrapFixture( bool bAssertOnDialog, bool bNeedUCB )
+ : m_bNeedUCB( bNeedUCB )
+ , m_bAssertOnDialog( bAssertOnDialog )
+{
+}
+
+extern "C"
+{
+
+static void test_init_impl(bool bAssertOnDialog, bool bNeedUCB,
+ lang::XMultiServiceFactory * pSFactory)
+{
+ if (bAssertOnDialog)
+ ErrorRegistry::RegisterDisplay( aBasicErrorFunc );
+
+ // Make GraphicConverter work, normally done in desktop::Desktop::Main()
+ Application::SetFilterHdl(
+ LINK(nullptr, test::BootstrapFixture, ImplInitFilterHdl));
+
+ if (bNeedUCB)
+ {
+ // initialise unconfigured UCB:
+ uno::Reference<ucb::XUniversalContentBroker> xUcb(pSFactory->createInstance("com.sun.star.ucb.UniversalContentBroker"), uno::UNO_QUERY_THROW);
+ uno::Reference<ucb::XContentProvider> xFileProvider(pSFactory->createInstance("com.sun.star.ucb.FileContentProvider"), uno::UNO_QUERY_THROW);
+ xUcb->registerContentProvider(xFileProvider, "file", true);
+ uno::Reference<ucb::XContentProvider> xTdocProvider(pSFactory->createInstance("com.sun.star.ucb.TransientDocumentsContentProvider"), uno::UNO_QUERY);
+ if (xTdocProvider.is())
+ {
+ xUcb->registerContentProvider(xTdocProvider, "vnd.sun.star.tdoc", true);
+ }
+ }
+}
+
+// this is called from pyuno
+SAL_DLLPUBLIC_EXPORT void test_init(lang::XMultiServiceFactory *pFactory)
+{
+ try
+ {
+ ::comphelper::setProcessServiceFactory(pFactory);
+ test::setUpVcl(true); // hard-code python tests to headless
+ test_init_impl(false, true, pFactory);
+ }
+ catch (...) { abort(); }
+}
+
+// this is called from pyuno
+SAL_DLLPUBLIC_EXPORT void test_deinit()
+{
+ DeInitVCL();
+}
+
+} // extern "C"
+
+void test::BootstrapFixture::setUp()
+{
+ test::BootstrapFixtureBase::setUp();
+
+ test_init_impl(m_bAssertOnDialog, m_bNeedUCB, m_xSFactory.get());
+
+#if OSL_DEBUG_LEVEL > 0
+ Scheduler::ProcessEventsToIdle();
+#endif
+
+ mxComponentContext.set(comphelper::getComponentContext(getMultiServiceFactory()));
+}
+
+test::BootstrapFixture::~BootstrapFixture()
+{
+}
+
+#if HAVE_EXPORT_VALIDATION
+namespace {
+
+OString loadFile(const OUString& rURL)
+{
+ osl::File aFile(rURL);
+ osl::FileBase::RC eStatus = aFile.open(osl_File_OpenFlag_Read);
+ CPPUNIT_ASSERT_EQUAL(osl::FileBase::E_None, eStatus);
+ sal_uInt64 nSize;
+ aFile.getSize(nSize);
+ std::unique_ptr<char[]> aBytes(new char[nSize]);
+ sal_uInt64 nBytesRead;
+ aFile.read(aBytes.get(), nSize, nBytesRead);
+ CPPUNIT_ASSERT_EQUAL(nSize, nBytesRead);
+ OString aContent(aBytes.get(), nBytesRead);
+
+ return aContent;
+}
+
+}
+#endif
+
+void test::BootstrapFixture::validate(const OUString& rPath, test::ValidationFormat eFormat) const
+{
+#if HAVE_EXPORT_VALIDATION
+ OUString var;
+ if( eFormat == test::OOXML )
+ {
+ var = "OFFICEOTRON";
+ }
+ else if ( eFormat == test::ODF )
+ {
+ var = "ODFVALIDATOR";
+ }
+ else if ( eFormat == test::MSBINARY )
+ {
+#if HAVE_BFFVALIDATOR
+ var = "BFFVALIDATOR";
+#else
+ // Binary Format Validator is disabled
+ return;
+#endif
+ }
+ OUString aValidator;
+ oslProcessError e = osl_getEnvironment(var.pData, &aValidator.pData);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(
+ OUString("cannot get env var " + var).toUtf8().getStr(),
+ osl_Process_E_None, e);
+ CPPUNIT_ASSERT_MESSAGE(
+ OUString("empty get env var " + var).toUtf8().getStr(),
+ !aValidator.isEmpty());
+
+ if (eFormat == test::ODF)
+ {
+ // invoke without -e so that we know when something new is written
+ // in loext namespace that isn't yet in the custom schema
+ aValidator += " -M "
+ + m_directories.getPathFromSrc(u"/schema/libreoffice/OpenDocument-v1.3+libreoffice-manifest-schema.rng")
+ + " -D "
+ + m_directories.getPathFromSrc(u"/schema/libreoffice/OpenDocument-v1.3+libreoffice-dsig-schema.rng")
+ + " -O "
+ + m_directories.getPathFromSrc(u"/schema/libreoffice/OpenDocument-v1.3+libreoffice-schema.rng")
+ + " -m "
+ + m_directories.getPathFromSrc(u"/schema/mathml2/mathml2.xsd");
+ }
+
+ utl::TempFileNamed aOutput;
+ aOutput.EnableKillingFile();
+ OUString aOutputFile = aOutput.GetFileName();
+ OUString aCommand = aValidator + " " + rPath + " > " + aOutputFile + " 2>&1";
+
+#if !defined _WIN32
+ // For now, this is only needed by some Linux ASan builds, so keep it simply and disable it on
+ // Windows (which doesn't support the relevant shell syntax for (un-)setting environment
+ // variables).
+ OUString env;
+ if (test::getArgument(u"env", &env)) {
+ auto const n = env.indexOf('=');
+ if (n == -1) {
+ aCommand = "unset -v " + env + " && " + aCommand;
+ } else {
+ aCommand = env + " " + aCommand;
+ }
+ }
+#endif
+
+ SAL_INFO("test", "BootstrapFixture::validate: executing '" << aCommand << "'");
+ int returnValue = system(OUStringToOString(aCommand, RTL_TEXTENCODING_UTF8).getStr());
+
+ OString aContentString = loadFile(aOutput.GetURL());
+ OUString aContentOUString = OStringToOUString(aContentString, RTL_TEXTENCODING_UTF8);
+
+ if( eFormat == test::OOXML && !aContentOUString.isEmpty() )
+ {
+ // check for validation errors here
+ sal_Int32 nIndex = aContentOUString.lastIndexOf("Grand total of errors in submitted package: ");
+ if(nIndex == -1)
+ {
+ SAL_WARN("test", "no summary line");
+ }
+ else
+ {
+ sal_Int32 nStartOfNumber = nIndex + std::strlen("Grand total of errors in submitted package: ");
+ std::u16string_view aNumber = aContentOUString.subView(nStartOfNumber);
+ sal_Int32 nErrors = o3tl::toInt32(aNumber);
+ OString aMsg = "validation error in OOXML export: Errors: " + OString::number(nErrors);
+ if(nErrors)
+ {
+ SAL_WARN("test", aContentOUString);
+ }
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(aMsg.getStr(), sal_Int32(0), nErrors);
+ }
+ }
+ else if( eFormat == test::ODF && !aContentOUString.isEmpty() )
+ {
+ if( aContentOUString.indexOf("Error") != -1 )
+ {
+ SAL_WARN("test", aContentOUString);
+ CPPUNIT_FAIL(aContentString.getStr());
+ }
+ }
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(
+ OString(
+ "failed to execute: " + OUStringToOString(aCommand, RTL_TEXTENCODING_UTF8) + "\n"
+ + OUStringToOString(aContentOUString, RTL_TEXTENCODING_UTF8)).getStr(),
+ 0, returnValue);
+#else
+ (void)rPath;
+ (void)eFormat;
+#endif
+}
+
+IMPL_STATIC_LINK(
+ test::BootstrapFixture, ImplInitFilterHdl, ConvertData&, rData, bool)
+{
+ return GraphicFilter::GetGraphicFilter().GetFilterCallback().Call( rData );
+}
+
+bool test::BootstrapFixture::IsDefaultDPI()
+{
+ return (Application::GetDefaultDevice()->GetDPIX() == 96
+ && Application::GetDefaultDevice()->GetDPIY() == 96);
+}
+
+std::pair<double, double> test::BootstrapFixture::getDPIScaling()
+{
+ return { Application::GetDefaultDevice()->GetDPIX() / 96.0,
+ Application::GetDefaultDevice()->GetDPIY() / 96.0 };
+}
+
+sal_uInt16 test::BootstrapFixture::getDefaultDeviceBitCount()
+{
+ ScopedVclPtr<VirtualDevice> device
+ = VclPtr<VirtualDevice>::Create(DeviceFormat::WITHOUT_ALPHA);
+ return device->GetBitCount();
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/test/source/callgrind.cxx b/test/source/callgrind.cxx
new file mode 100644
index 0000000000..d5e864aa8e
--- /dev/null
+++ b/test/source/callgrind.cxx
@@ -0,0 +1,33 @@
+/* -*- 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 <test/callgrind.hxx>
+
+#ifdef HAVE_VALGRIND_HEADERS
+#include <valgrind/callgrind.h>
+#else
+#define CALLGRIND_START_INSTRUMENTATION
+#define CALLGRIND_ZERO_STATS
+#define CALLGRIND_STOP_INSTRUMENTATION
+#define CALLGRIND_DUMP_STATS_AT(name) (void)name;
+#endif
+
+void callgrindStart()
+{
+ CALLGRIND_ZERO_STATS;
+ CALLGRIND_START_INSTRUMENTATION;
+};
+
+void callgrindDump(const char* name)
+{
+ CALLGRIND_STOP_INSTRUMENTATION;
+ CALLGRIND_DUMP_STATS_AT(name);
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/test/source/chart/xchartdata.cxx b/test/source/chart/xchartdata.cxx
new file mode 100644
index 0000000000..5d0dcb48f1
--- /dev/null
+++ b/test/source/chart/xchartdata.cxx
@@ -0,0 +1,97 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * 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 <test/chart/xchartdata.hxx>
+#include <cppuhelper/implbase.hxx>
+#include <rtl/ref.hxx>
+
+#include <com/sun/star/chart/ChartDataChangeEvent.hpp>
+#include <com/sun/star/chart/XChartData.hpp>
+#include <com/sun/star/chart/XChartDataArray.hpp>
+#include <com/sun/star/chart/XChartDataChangeEventListener.hpp>
+#include <com/sun/star/lang/EventObject.hpp>
+
+#include <cppunit/TestAssert.h>
+
+using namespace css;
+
+namespace apitest
+{
+namespace
+{
+class MockedChartDataChangeEventListener
+ : public ::cppu::WeakImplHelper<chart::XChartDataChangeEventListener>
+{
+public:
+ MockedChartDataChangeEventListener()
+ : m_bListenerCalled(false)
+ {
+ }
+
+ bool m_bListenerCalled;
+ virtual void SAL_CALL chartDataChanged(const chart::ChartDataChangeEvent& /* rEvent */) override
+ {
+ m_bListenerCalled = true;
+ }
+
+ virtual void SAL_CALL disposing(const lang::EventObject& /* xEvent */) override {}
+};
+}
+
+void XChartData::testGetNotANumber()
+{
+ uno::Reference<chart::XChartData> xCD(init(), uno::UNO_QUERY_THROW);
+ const double fNaN = xCD->getNotANumber();
+
+ CPPUNIT_ASSERT(fNaN != 1.0);
+}
+
+void XChartData::testIsNotANumber()
+{
+ uno::Reference<chart::XChartData> xCD(init(), uno::UNO_QUERY_THROW);
+ const double fNaN = xCD->getNotANumber();
+ CPPUNIT_ASSERT(xCD->isNotANumber(fNaN));
+ CPPUNIT_ASSERT(!xCD->isNotANumber(fNaN + 1.0));
+}
+
+void XChartData::testChartDataChangeEventListener()
+{
+ uno::Reference<chart::XChartData> xCD(init(), uno::UNO_QUERY_THROW);
+
+ rtl::Reference<MockedChartDataChangeEventListener> pListener0
+ = new MockedChartDataChangeEventListener();
+ xCD->addChartDataChangeEventListener(
+ uno::Reference<chart::XChartDataChangeEventListener>(pListener0));
+ rtl::Reference<MockedChartDataChangeEventListener> pListener1
+ = new MockedChartDataChangeEventListener();
+ xCD->addChartDataChangeEventListener(
+ uno::Reference<chart::XChartDataChangeEventListener>(pListener1));
+
+ uno::Reference<chart::XChartDataArray> xCDD(xCD, uno::UNO_QUERY_THROW);
+ uno::Sequence<uno::Sequence<double>> aData = xCDD->getData();
+ auto& rFirstCell = aData.getArray()[0].getArray()[0];
+ rFirstCell += 1.0;
+ xCDD->setData(aData);
+ CPPUNIT_ASSERT(pListener0->m_bListenerCalled);
+ CPPUNIT_ASSERT(pListener1->m_bListenerCalled);
+
+ pListener0->m_bListenerCalled = false;
+ pListener1->m_bListenerCalled = false;
+
+ xCD->removeChartDataChangeEventListener(
+ uno::Reference<chart::XChartDataChangeEventListener>(pListener1));
+ rFirstCell += 1.0;
+ xCDD->setData(aData);
+ CPPUNIT_ASSERT(pListener0->m_bListenerCalled);
+ CPPUNIT_ASSERT(!pListener1->m_bListenerCalled);
+}
+
+} // namespace apitest
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/test/source/container/xchild.cxx b/test/source/container/xchild.cxx
new file mode 100644
index 0000000000..eac97b0ebe
--- /dev/null
+++ b/test/source/container/xchild.cxx
@@ -0,0 +1,38 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+* 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 <test/container/xchild.hxx>
+
+#include <com/sun/star/container/XChild.hpp>
+#include <com/sun/star/uno/XInterface.hpp>
+
+#include <com/sun/star/uno/Reference.hxx>
+
+#include <cppunit/TestAssert.h>
+
+using namespace com::sun::star;
+using namespace com::sun::star::uno;
+
+namespace apitest
+{
+void XChild::testGetSetParent()
+{
+ uno::Reference<container::XChild> xChild(init(), UNO_QUERY_THROW);
+ uno::Reference<uno::XInterface> xInterface(xChild, UNO_QUERY_THROW);
+ xInterface = xChild->getParent();
+
+ CPPUNIT_ASSERT_MESSAGE("Successfully able to Get Parent", xInterface);
+
+ xChild->setParent(xInterface);
+
+ CPPUNIT_ASSERT_MESSAGE("Successfully able to Set Parent", xChild);
+}
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/test/source/container/xelementaccess.cxx b/test/source/container/xelementaccess.cxx
new file mode 100644
index 0000000000..4ec7515209
--- /dev/null
+++ b/test/source/container/xelementaccess.cxx
@@ -0,0 +1,36 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * 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 <test/container/xelementaccess.hxx>
+
+#include <com/sun/star/container/XElementAccess.hpp>
+#include <com/sun/star/uno/Reference.hxx>
+
+#include <cppunit/TestAssert.h>
+
+using namespace css;
+using namespace css::uno;
+
+namespace apitest
+{
+void XElementAccess::testGetElementType()
+{
+ uno::Reference<container::XElementAccess> xElementAccess(init(), UNO_QUERY_THROW);
+ CPPUNIT_ASSERT_EQUAL(m_aType, xElementAccess->getElementType());
+}
+
+void XElementAccess::testHasElements()
+{
+ uno::Reference<container::XElementAccess> xElementAccess(init(), UNO_QUERY_THROW);
+ CPPUNIT_ASSERT(xElementAccess->hasElements());
+}
+
+} // namespace apitest
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/test/source/container/xenumeration.cxx b/test/source/container/xenumeration.cxx
new file mode 100644
index 0000000000..190ef27fe7
--- /dev/null
+++ b/test/source/container/xenumeration.cxx
@@ -0,0 +1,43 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * 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 <test/container/xenumeration.hxx>
+
+#include <com/sun/star/container/NoSuchElementException.hpp>
+#include <com/sun/star/container/XEnumeration.hpp>
+
+#include <com/sun/star/uno/Reference.hxx>
+
+#include <cppunit/TestAssert.h>
+
+using namespace com::sun::star;
+using namespace com::sun::star::uno;
+
+namespace apitest
+{
+void XEnumeration::testHasMoreElements()
+{
+ uno::Reference<container::XEnumeration> xEnumeration(init(), uno::UNO_QUERY_THROW);
+ CPPUNIT_ASSERT(xEnumeration->hasMoreElements());
+}
+
+void XEnumeration::testNextElement()
+{
+ uno::Reference<container::XEnumeration> xEnumeration(init(), uno::UNO_QUERY_THROW);
+
+ // unwind all elements from the enumeration
+ while (xEnumeration->hasMoreElements())
+ CPPUNIT_ASSERT_NO_THROW(xEnumeration->nextElement());
+
+ CPPUNIT_ASSERT_THROW_MESSAGE("Incorrect exception", xEnumeration->nextElement(),
+ container::NoSuchElementException);
+}
+} // namespace apitest
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/test/source/container/xenumerationaccess.cxx b/test/source/container/xenumerationaccess.cxx
new file mode 100644
index 0000000000..e3c53064ed
--- /dev/null
+++ b/test/source/container/xenumerationaccess.cxx
@@ -0,0 +1,31 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+* 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 <test/container/xenumerationaccess.hxx>
+
+#include <com/sun/star/container/XEnumerationAccess.hpp>
+
+#include <com/sun/star/uno/Reference.hxx>
+
+#include <cppunit/TestAssert.h>
+
+using namespace com::sun::star;
+using namespace com::sun::star::uno;
+
+namespace apitest
+{
+void XEnumerationAccess::testCreateEnumeration()
+{
+ uno::Reference<container::XEnumerationAccess> xEnumerationAccess(init(), UNO_QUERY_THROW);
+
+ CPPUNIT_ASSERT_MESSAGE("Unable to create enumeration", xEnumerationAccess->createEnumeration());
+}
+} // namespace apitest
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/test/source/container/xindexaccess.cxx b/test/source/container/xindexaccess.cxx
new file mode 100644
index 0000000000..7fc08027c4
--- /dev/null
+++ b/test/source/container/xindexaccess.cxx
@@ -0,0 +1,55 @@
+/* -*- 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 <test/container/xindexaccess.hxx>
+
+#include <com/sun/star/container/XIndexAccess.hpp>
+
+#include <com/sun/star/uno/Reference.hxx>
+
+#include <cppunit/TestAssert.h>
+
+using namespace css;
+using namespace css::uno;
+
+namespace apitest
+{
+void XIndexAccess::testGetCount()
+{
+ uno::Reference<container::XIndexAccess> xIndexAccess(init(), UNO_QUERY_THROW);
+ CPPUNIT_ASSERT_EQUAL(m_nItems, xIndexAccess->getCount());
+}
+
+void XIndexAccess::testGetByIndex()
+{
+ uno::Reference<container::XIndexAccess> xIndexAccess(init(), UNO_QUERY_THROW);
+ CPPUNIT_ASSERT_EQUAL(m_nItems, xIndexAccess->getCount());
+
+ if (m_nItems > 0)
+ {
+ Any aAny = xIndexAccess->getByIndex(0);
+ CPPUNIT_ASSERT(aAny.hasValue());
+
+ aAny = xIndexAccess->getByIndex(m_nItems / 2);
+ CPPUNIT_ASSERT(aAny.hasValue());
+
+ aAny = xIndexAccess->getByIndex(m_nItems - 1);
+ CPPUNIT_ASSERT(aAny.hasValue());
+ }
+}
+
+void XIndexAccess::testGetByIndexException()
+{
+ uno::Reference<container::XIndexAccess> xIndexAccess(init(), UNO_QUERY_THROW);
+ xIndexAccess->getByIndex(m_nItems);
+}
+
+} // namespace apitest
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/test/source/container/xnameaccess.cxx b/test/source/container/xnameaccess.cxx
new file mode 100644
index 0000000000..3616c4cda3
--- /dev/null
+++ b/test/source/container/xnameaccess.cxx
@@ -0,0 +1,55 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * 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 <test/container/xnameaccess.hxx>
+
+#include <com/sun/star/container/NoSuchElementException.hpp>
+#include <com/sun/star/container/XNameAccess.hpp>
+
+#include <com/sun/star/uno/Reference.hxx>
+#include <com/sun/star/uno/Sequence.hxx>
+
+#include <cppunit/TestAssert.h>
+
+using namespace css;
+using namespace css::uno;
+
+namespace apitest
+{
+void XNameAccess::testGetByName()
+{
+ uno::Reference<container::XNameAccess> xNA(init(), uno::UNO_QUERY_THROW);
+
+ // test with existing name
+ CPPUNIT_ASSERT_NO_THROW(xNA->getByName(m_aName));
+ // test with non-existing name
+ CPPUNIT_ASSERT_THROW(xNA->getByName(m_aName + "UnitTest"), container::NoSuchElementException);
+}
+
+void XNameAccess::testGetElementNames()
+{
+ uno::Reference<container::XNameAccess> xNA(init(), uno::UNO_QUERY_THROW);
+ uno::Sequence<OUString> aNames = xNA->getElementNames();
+
+ CPPUNIT_ASSERT(aNames.hasElements());
+}
+
+void XNameAccess::testHasByName()
+{
+ uno::Reference<container::XNameAccess> xNA(init(), uno::UNO_QUERY_THROW);
+
+ // test with existing name
+ CPPUNIT_ASSERT(xNA->hasByName(m_aName));
+ // test with non-existing name
+ CPPUNIT_ASSERT(!xNA->hasByName(m_aName + "UnitTest"));
+}
+
+} // namespace apitest
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/test/source/container/xnamecontainer.cxx b/test/source/container/xnamecontainer.cxx
new file mode 100644
index 0000000000..5df1e76b3e
--- /dev/null
+++ b/test/source/container/xnamecontainer.cxx
@@ -0,0 +1,101 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * 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 <test/container/xnamecontainer.hxx>
+
+#include <com/sun/star/container/ElementExistException.hpp>
+#include <com/sun/star/container/NoSuchElementException.hpp>
+#include <com/sun/star/container/XNameContainer.hpp>
+#include <com/sun/star/lang/IllegalArgumentException.hpp>
+
+#include <com/sun/star/uno/Any.hxx>
+#include <com/sun/star/uno/Reference.hxx>
+
+#include <cppunit/TestAssert.h>
+
+using namespace css;
+
+namespace apitest
+{
+void XNameContainer::testInsertByName()
+{
+ uno::Reference<container::XNameContainer> xNameContainer(init(), uno::UNO_QUERY_THROW);
+
+ CPPUNIT_ASSERT(!xNameContainer->hasByName(m_aName + "Insert"));
+ xNameContainer->insertByName(m_aName + "Insert", m_aElement);
+ CPPUNIT_ASSERT(xNameContainer->hasByName(m_aName + "Insert"));
+}
+
+void XNameContainer::testInsertByNameEmptyName()
+{
+ uno::Reference<container::XNameContainer> xNameContainer(init(), uno::UNO_QUERY_THROW);
+
+ uno::Any aAny;
+ CPPUNIT_ASSERT_THROW(xNameContainer->insertByName("", aAny), lang::IllegalArgumentException);
+}
+
+void XNameContainer::testInsertByNameInvalidElement()
+{
+ uno::Reference<container::XNameContainer> xNameContainer(init(), uno::UNO_QUERY_THROW);
+
+ // TODO: Find a way to create an invalid element.
+ // CPPUNIT_ASSERT_THROW(xNameContainer->insertByName("Dummy", nullptr),
+ // lang::IllegalArgumentException);
+}
+
+void XNameContainer::testInsertByNameDuplicate()
+{
+ uno::Reference<container::XNameContainer> xNameContainer(init(), uno::UNO_QUERY_THROW);
+
+ CPPUNIT_ASSERT(!xNameContainer->hasByName(m_aName + "Duplicate"));
+ xNameContainer->insertByName(m_aName + "Duplicate", m_aElement);
+ CPPUNIT_ASSERT(xNameContainer->hasByName(m_aName + "Duplicate"));
+
+ bool bExceptionThrown = false;
+ try
+ {
+ xNameContainer->insertByName(m_aName + "Duplicate", m_aElement);
+ }
+ catch (const container::ElementExistException&)
+ {
+ bExceptionThrown = true;
+ }
+ catch (const lang::IllegalArgumentException&)
+ {
+ bExceptionThrown = true;
+ }
+ CPPUNIT_ASSERT(bExceptionThrown);
+}
+
+void XNameContainer::testRemoveByName()
+{
+ uno::Reference<container::XNameContainer> xNameContainer(init(), uno::UNO_QUERY_THROW);
+ CPPUNIT_ASSERT(xNameContainer->hasByName(m_aName));
+ xNameContainer->removeByName(m_aName);
+ CPPUNIT_ASSERT(!xNameContainer->hasByName(m_aName));
+}
+
+void XNameContainer::testRemoveByNameEmptyName()
+{
+ uno::Reference<container::XNameContainer> xNameContainer(init(), uno::UNO_QUERY_THROW);
+
+ CPPUNIT_ASSERT_THROW(xNameContainer->removeByName(""), lang::IllegalArgumentException);
+}
+
+void XNameContainer::testRemoveByNameNoneExistingElement()
+{
+ uno::Reference<container::XNameContainer> xNameContainer(init(), uno::UNO_QUERY_THROW);
+
+ CPPUNIT_ASSERT_THROW(xNameContainer->removeByName("UnitTest"),
+ container::NoSuchElementException);
+}
+
+} // namespace apitest
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/test/source/container/xnamed.cxx b/test/source/container/xnamed.cxx
new file mode 100644
index 0000000000..000a9f62e0
--- /dev/null
+++ b/test/source/container/xnamed.cxx
@@ -0,0 +1,65 @@
+/* -*- 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 <test/container/xnamed.hxx>
+#include <rtl/ustring.hxx>
+
+#include <com/sun/star/container/XNamed.hpp>
+#include <com/sun/star/uno/RuntimeException.hpp>
+
+#include <com/sun/star/uno/Reference.hxx>
+
+#include <cppunit/TestAssert.h>
+
+using namespace css;
+using namespace css::uno;
+
+namespace apitest
+{
+void XNamed::testGetName()
+{
+ uno::Reference<container::XNamed> xNamed(init(), UNO_QUERY_THROW);
+ CPPUNIT_ASSERT_EQUAL(m_aTestName, xNamed->getName());
+}
+
+void XNamed::testSetName()
+{
+ uno::Reference<container::XNamed> xNamed(init(), UNO_QUERY_THROW);
+ OUString aTestName("NewName");
+
+ xNamed->setName(aTestName);
+ CPPUNIT_ASSERT_EQUAL(aTestName, xNamed->getName());
+
+ // restore old name
+ xNamed->setName(m_aTestName);
+ CPPUNIT_ASSERT_EQUAL(m_aTestName, xNamed->getName());
+}
+
+void XNamed::testSetNameByScSheetLinkObj()
+{
+ uno::Reference<container::XNamed> xNamed(init(), uno::UNO_QUERY_THROW);
+ OUString aTestName(m_aTestName.replaceAll("ScSheetLinkObj", "NewScSheetLinkObj"));
+
+ xNamed->setName(aTestName);
+ CPPUNIT_ASSERT_EQUAL(aTestName, xNamed->getName());
+
+ // restore old name
+ xNamed->setName(m_aTestName);
+ CPPUNIT_ASSERT_EQUAL(m_aTestName, xNamed->getName());
+}
+
+void XNamed::testSetNameThrowsException()
+{
+ uno::Reference<container::XNamed> xNamed(init(), uno::UNO_QUERY_THROW);
+
+ CPPUNIT_ASSERT_THROW(xNamed->setName("NewName"), uno::RuntimeException);
+}
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/test/source/container/xnamereplace.cxx b/test/source/container/xnamereplace.cxx
new file mode 100644
index 0000000000..2475cb5a00
--- /dev/null
+++ b/test/source/container/xnamereplace.cxx
@@ -0,0 +1,37 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * 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 <test/container/xnamereplace.hxx>
+
+#include <com/sun/star/container/XNameReplace.hpp>
+
+#include <com/sun/star/uno/Any.hxx>
+#include <com/sun/star/uno/Reference.hxx>
+
+#include <cppunit/TestAssert.h>
+
+using namespace css;
+
+namespace apitest
+{
+void XNameReplace::testReplaceByName()
+{
+ uno::Reference<container::XNameReplace> xNameReplace(init(), uno::UNO_QUERY_THROW);
+
+ CPPUNIT_ASSERT_NO_THROW(xNameReplace->replaceByName(m_aReplacementName, m_aReplacementElement));
+ uno::Any aAny = xNameReplace->getByName(m_aReplacementName);
+
+ // we deliberately avoid uno::UNO_QUERY_THROW, so a test on .is() can be made
+ uno::Reference<uno::XInterface> xElement(aAny, uno::UNO_QUERY);
+ CPPUNIT_ASSERT(xElement.is());
+}
+
+} // namespace apitest
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/test/source/diff/README b/test/source/diff/README
new file mode 100644
index 0000000000..2ed65928d2
--- /dev/null
+++ b/test/source/diff/README
@@ -0,0 +1,5 @@
+This xml diff is an adapted version of the version at git://people.freedesktop.org/~mmohrhard/xmldiff.
+Please write a mail to <markus.mohrhard@googlemail.com> after modifying this version with a patch otherwise it
+might get overridden when updating the version in the source tree.
+
+!This xml diff is still experimental!
diff --git a/test/source/diff/diff.cxx b/test/source/diff/diff.cxx
new file mode 100644
index 0000000000..0974526653
--- /dev/null
+++ b/test/source/diff/diff.cxx
@@ -0,0 +1,416 @@
+/* -*- 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/.
+ */
+
+#define USE_CPPUNIT 1
+
+#include <test/xmldiff.hxx>
+
+#include <libxml/xpath.h>
+#include <libxml/parser.h>
+
+#include <set>
+#include <sstream>
+#include <cassert>
+#include <cmath>
+#include <vector>
+
+#if USE_CPPUNIT
+#include <cppunit/TestAssert.h>
+#endif
+
+namespace {
+
+struct tolerance
+{
+ ~tolerance()
+ {
+ xmlFree(elementName);
+ xmlFree(attribName);
+ }
+
+ tolerance()
+ : elementName(nullptr)
+ , attribName(nullptr)
+ , relative(false)
+ , value(0.0)
+ {
+ }
+
+ tolerance(const tolerance& tol)
+ {
+ elementName = xmlStrdup(tol.elementName);
+ attribName = xmlStrdup(tol.attribName);
+ relative = tol.relative;
+ value = tol.value;
+ }
+
+ xmlChar* elementName;
+ xmlChar* attribName;
+ bool relative;
+ double value;
+ bool operator<(const tolerance& rTol) const
+ {
+ int cmp = xmlStrcmp(elementName, rTol.elementName);
+ if(cmp == 0)
+ {
+ cmp = xmlStrcmp(attribName, rTol.attribName);
+ }
+
+ return cmp < 0;
+ }
+};
+
+class XMLDiff
+{
+public:
+ XMLDiff(const char* pFileName, const char* pContent, int size, const char* pToleranceFileName);
+ ~XMLDiff();
+
+ bool compare();
+private:
+ typedef std::set<tolerance> ToleranceContainer;
+
+ void loadToleranceFile(xmlDocPtr xmlTolerance);
+ bool compareAttributes(xmlNodePtr node1, xmlNodePtr node2);
+ bool compareElements(xmlNode* node1, xmlNode* node2);
+
+ /// Error message for cppunit that prints out when expected and found are not equal.
+ void cppunitAssertEqual(const xmlChar *expected, const xmlChar *found);
+
+ /// Error message for cppunit that prints out when expected and found are not equal - for doubles.
+ void cppunitAssertEqualDouble(const xmlNodePtr node, const xmlAttrPtr attr, double expected, double found, double delta);
+
+ ToleranceContainer toleranceContainer;
+ xmlDocPtr xmlFile1;
+ xmlDocPtr xmlFile2;
+ std::string fileName;
+};
+
+}
+
+XMLDiff::XMLDiff( const char* pFileName, const char* pContent, int size, const char* pToleranceFile)
+ : xmlFile1(xmlParseFile(pFileName))
+ , xmlFile2(xmlParseMemory(pContent, size))
+ , fileName(pFileName)
+{
+ if(pToleranceFile)
+ {
+ xmlDocPtr xmlToleranceFile = xmlParseFile(pToleranceFile);
+ loadToleranceFile(xmlToleranceFile);
+ xmlFreeDoc(xmlToleranceFile);
+ }
+}
+
+XMLDiff::~XMLDiff()
+{
+ xmlFreeDoc(xmlFile1);
+ xmlFreeDoc(xmlFile2);
+}
+
+namespace {
+
+void readAttributesForTolerance(xmlNodePtr node, tolerance& tol)
+{
+ xmlChar* elementName = xmlGetProp(node, BAD_CAST("elementName"));
+ tol.elementName = elementName;
+
+ xmlChar* attribName = xmlGetProp(node, BAD_CAST("attribName"));
+ tol.attribName = attribName;
+
+ xmlChar* value = xmlGetProp(node, BAD_CAST("value"));
+ double val = xmlXPathCastStringToNumber(value);
+ xmlFree(value);
+ tol.value = val;
+
+ xmlChar* relative = xmlGetProp(node, BAD_CAST("relative"));
+ bool rel = false;
+ if(xmlStrEqual(relative, BAD_CAST("true")))
+ rel = true;
+ xmlFree(relative);
+ tol.relative = rel;
+}
+
+}
+
+void XMLDiff::loadToleranceFile(xmlDocPtr xmlToleranceFile)
+{
+ xmlNodePtr root = xmlDocGetRootElement(xmlToleranceFile);
+#if USE_CPPUNIT
+ CPPUNIT_ASSERT_MESSAGE("did not find correct tolerance file", xmlStrEqual( root->name, BAD_CAST("tolerances") ));
+#else
+ if(!xmlStrEqual( root->name, BAD_CAST("tolerances") ))
+ {
+ assert(false);
+ return;
+ }
+#endif
+ xmlNodePtr child = nullptr;
+ for (child = root->children; child != nullptr; child = child->next)
+ {
+ // assume a valid xml file
+ if(child->type != XML_ELEMENT_NODE)
+ continue;
+
+ assert(xmlStrEqual(child->name, BAD_CAST("tolerance")));
+
+ tolerance tol;
+ readAttributesForTolerance(child, tol);
+ toleranceContainer.insert(tol);
+ }
+}
+
+bool XMLDiff::compare()
+{
+ xmlNode* root1 = xmlDocGetRootElement(xmlFile1);
+ xmlNode* root2 = xmlDocGetRootElement(xmlFile2);
+
+#if USE_CPPUNIT
+ CPPUNIT_ASSERT(root1);
+ CPPUNIT_ASSERT(root2);
+ cppunitAssertEqual(root1->name, root2->name);
+#else
+ if (!root1 || !root2)
+ return false;
+ if(!xmlStrEqual(root1->name, root2->name))
+ return false;
+#endif
+ return compareElements(root1, root2);
+}
+
+namespace {
+
+bool checkForEmptyChildren(xmlNodePtr node)
+{
+ if(!node)
+ return true;
+
+ for(; node != nullptr; node = node->next)
+ {
+ if (node->type == XML_ELEMENT_NODE)
+ return false;
+ }
+ return true;
+}
+
+}
+
+bool XMLDiff::compareElements(xmlNode* node1, xmlNode* node2)
+{
+#if USE_CPPUNIT
+ cppunitAssertEqual(node1->name, node2->name);
+#else
+ if (!xmlStrEqual( node1->name, node2->name ))
+ return false;
+#endif
+
+ //compare attributes
+ bool sameAttribs = compareAttributes(node1, node2);
+#if USE_CPPUNIT
+ CPPUNIT_ASSERT(sameAttribs);
+#else
+ if (!sameAttribs)
+ return false;
+#endif
+
+ // compare children
+ xmlNode* child2 = nullptr;
+ xmlNode* child1 = nullptr;
+ for(child1 = node1->children, child2 = node2->children; child1 != nullptr && child2 != nullptr; child1 = child1->next, child2 = child2->next)
+ {
+ if (child1->type == XML_ELEMENT_NODE)
+ {
+ bool bCompare = compareElements(child1, child2);
+ if(!bCompare)
+ {
+ return false;
+ }
+ }
+ }
+
+#if USE_CPPUNIT
+ CPPUNIT_ASSERT(checkForEmptyChildren(child1));
+ CPPUNIT_ASSERT(checkForEmptyChildren(child2));
+#else
+ if(!checkForEmptyChildren(child1) || !checkForEmptyChildren(child2))
+ return false;
+#endif
+
+ return true;
+}
+
+void XMLDiff::cppunitAssertEqual(const xmlChar *expected, const xmlChar *found)
+{
+#if USE_CPPUNIT
+ std::stringstream stringStream;
+ stringStream << "Reference: " << fileName << "\n- Expected: " << reinterpret_cast<const char*>(expected) << "\n- Found: " << reinterpret_cast<const char*>(found);
+
+ CPPUNIT_ASSERT_MESSAGE(stringStream.str(), xmlStrEqual(expected, found));
+#endif
+}
+
+void XMLDiff::cppunitAssertEqualDouble(const xmlNodePtr node, const xmlAttrPtr attr, double expected, double found, double delta)
+{
+#if USE_CPPUNIT
+ xmlChar * path = xmlGetNodePath(node);
+ std::stringstream stringStream;
+ stringStream << "Reference: " << fileName << "\n- Node: " << reinterpret_cast<const char*>(path) << "\n- Attr: " << reinterpret_cast<const char*>(attr->name);
+ xmlFree(path);
+
+ CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE(stringStream.str(), expected, found, delta);
+#endif
+}
+
+namespace {
+
+bool compareValuesWithTolerance(double val1, double val2, double tolerance, bool relative)
+{
+ if(relative)
+ {
+ return (val1/tolerance) <= val2 && val2 <= (val1*tolerance);
+ }
+ else
+ {
+ return (val1 - tolerance) <= val2 && val2 <= (val1 + tolerance);
+ }
+}
+
+}
+
+bool XMLDiff::compareAttributes(xmlNodePtr node1, xmlNodePtr node2)
+{
+ xmlAttrPtr attr1 = nullptr;
+ xmlAttrPtr attr2 = nullptr;
+ for(attr1 = node1->properties, attr2 = node2->properties; attr1 != nullptr && attr2 != nullptr; attr1 = attr1->next, attr2 = attr2->next)
+ {
+#if USE_CPPUNIT
+ cppunitAssertEqual(attr1->name, attr2->name);
+#else
+ if (!xmlStrEqual( attr1->name, attr2->name ))
+ return false;
+#endif
+
+ xmlChar* val1 = xmlGetProp(node1, attr1->name);
+ xmlChar* val2 = xmlGetProp(node2, attr2->name);
+
+ double dVal1 = xmlXPathCastStringToNumber(val1);
+ double dVal2 = xmlXPathCastStringToNumber(val2);
+
+ if(!std::isnan(dVal1) || !std::isnan(dVal2))
+ {
+ //compare by value and respect tolerance
+ tolerance tol;
+ tol.elementName = xmlStrdup(node1->name);
+ tol.attribName = xmlStrdup(attr1->name);
+ ToleranceContainer::iterator itr = toleranceContainer.find( tol );
+ bool useTolerance = false;
+ if (itr != toleranceContainer.end())
+ {
+ useTolerance = true;
+ }
+
+ if (useTolerance)
+ {
+ bool valInTolerance = compareValuesWithTolerance(dVal1, dVal2, itr->value, itr->relative);
+#if USE_CPPUNIT
+ std::stringstream stringStream("Expected Value: ");
+ stringStream << dVal1 << "; Found Value: " << dVal2 << "; Tolerance: " << itr->value;
+ stringStream << "; Relative: " << itr->relative;
+ CPPUNIT_ASSERT_MESSAGE(stringStream.str(), valInTolerance);
+#else
+ if (!valInTolerance)
+ return false;
+#endif
+ }
+ else
+ {
+#if USE_CPPUNIT
+ cppunitAssertEqualDouble(node1, attr1, dVal1, dVal2, 1e-08);
+#else
+ if (dVal1 != dVal2)
+ return false;
+#endif
+ }
+ }
+ else
+ {
+
+#if USE_CPPUNIT
+ cppunitAssertEqual(val1, val2);
+#else
+ if(!xmlStrEqual( val1, val2 ))
+ return false;
+#endif
+ }
+
+ xmlFree(val1);
+ xmlFree(val2);
+ }
+
+ // unequal number of attributes
+#ifdef CPPUNIT_ASSERT
+ if (attr1 || attr2)
+ {
+ std::stringstream failStream;
+ failStream << "Unequal number of attributes in ";
+ // print chain from document root
+ std::vector<std::string> parents;
+ auto n = node1;
+ while (n)
+ {
+ if (n->name)
+ parents.push_back(std::string(reinterpret_cast<const char *>(n->name)));
+ n = n->parent;
+ }
+ bool first = true;
+ for (auto it = parents.rbegin(); it != parents.rend(); ++it)
+ {
+ if (!first)
+ failStream << "->";
+ first = false;
+ failStream << *it;
+ }
+ failStream << " Attr1: ";
+ attr1 = node1->properties;
+ while (attr1 != nullptr)
+ {
+ xmlChar* val1 = xmlGetProp(node1, attr1->name);
+ failStream << BAD_CAST(attr1->name) << "=" << BAD_CAST(val1) << ", ";
+ xmlFree(val1);
+ attr1 = attr1->next;
+ }
+
+ failStream << " Attr2: ";
+ attr2 = node2->properties;
+ while (attr2 != nullptr)
+ {
+ xmlChar* val2 = xmlGetProp(node2, attr2->name);
+ failStream << BAD_CAST(attr2->name) << "=" << BAD_CAST(val2) << ", ";
+ xmlFree(val2);
+ attr2 = attr2->next;
+ }
+ CPPUNIT_ASSERT_MESSAGE(failStream.str(), false);
+ }
+#else
+ if (attr1 || attr2)
+ return false;
+#endif
+
+ return true;
+}
+
+
+bool
+doXMLDiff(char const*const pFileName, char const*const pContent, int const size,
+ char const*const pToleranceFileName)
+{
+ XMLDiff aDiff(pFileName, pContent, size, pToleranceFileName);
+ return aDiff.compare();
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/test/source/document/xactionlockable.cxx b/test/source/document/xactionlockable.cxx
new file mode 100644
index 0000000000..47d2774ae6
--- /dev/null
+++ b/test/source/document/xactionlockable.cxx
@@ -0,0 +1,46 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * 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 <test/document/xactionlockable.hxx>
+#include <sal/types.h>
+
+#include <com/sun/star/document/XActionLockable.hpp>
+
+#include <com/sun/star/uno/Reference.hxx>
+
+#include <cppunit/TestAssert.h>
+
+using namespace css;
+
+namespace apitest
+{
+void XActionLockable::testAddRemoveActionLock()
+{
+ uno::Reference<document::XActionLockable> xAL(init(), uno::UNO_QUERY_THROW);
+
+ xAL->addActionLock();
+ CPPUNIT_ASSERT(xAL->isActionLocked());
+
+ xAL->removeActionLock();
+ CPPUNIT_ASSERT(!xAL->isActionLocked());
+}
+
+void XActionLockable::testSetResetActionLock()
+{
+ uno::Reference<document::XActionLockable> xAL(init(), uno::UNO_QUERY_THROW);
+
+ CPPUNIT_ASSERT_NO_THROW(xAL->setActionLocks(0));
+
+ const sal_Int16 nLocks = xAL->resetActionLocks();
+ CPPUNIT_ASSERT_EQUAL(sal_Int16(0), nLocks);
+ CPPUNIT_ASSERT(!xAL->isActionLocked());
+}
+} // namespace apitest
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/test/source/document/xembeddedobjectsupplier.cxx b/test/source/document/xembeddedobjectsupplier.cxx
new file mode 100644
index 0000000000..baa2ecbfbe
--- /dev/null
+++ b/test/source/document/xembeddedobjectsupplier.cxx
@@ -0,0 +1,30 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * 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 <test/document/xembeddedobjectsupplier.hxx>
+
+#include <com/sun/star/document/XEmbeddedObjectSupplier.hpp>
+
+#include <com/sun/star/uno/Reference.hxx>
+
+#include <cppunit/TestAssert.h>
+
+using namespace css;
+
+namespace apitest
+{
+void XEmbeddedObjectSupplier::testGetEmbeddedObject()
+{
+ uno::Reference<document::XEmbeddedObjectSupplier> xEOS(init(), uno::UNO_QUERY_THROW);
+
+ CPPUNIT_ASSERT(xEOS->getEmbeddedObject());
+}
+} // namespace apitest
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/test/source/document/xlinktargetsupplier.cxx b/test/source/document/xlinktargetsupplier.cxx
new file mode 100644
index 0000000000..eec08a9004
--- /dev/null
+++ b/test/source/document/xlinktargetsupplier.cxx
@@ -0,0 +1,30 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+* 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 <test/document/xlinktargetsupplier.hxx>
+
+#include <com/sun/star/document/XLinkTargetSupplier.hpp>
+
+#include <com/sun/star/uno/Reference.hxx>
+
+#include <cppunit/TestAssert.h>
+
+using namespace com::sun::star;
+using namespace com::sun::star::uno;
+
+namespace apitest
+{
+void XLinkTargetSupplier::testGetLinks()
+{
+ uno::Reference<document::XLinkTargetSupplier> xLinkTargetSupplier(init(), UNO_QUERY_THROW);
+ CPPUNIT_ASSERT(xLinkTargetSupplier->getLinks());
+}
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/test/source/drawing/captionshape.cxx b/test/source/drawing/captionshape.cxx
new file mode 100644
index 0000000000..66093e70dd
--- /dev/null
+++ b/test/source/drawing/captionshape.cxx
@@ -0,0 +1,178 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * 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 <test/cppunitasserthelper.hxx>
+#include <test/drawing/captionshape.hxx>
+
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/uno/Any.hxx>
+#include <com/sun/star/uno/Reference.hxx>
+#include <com/sun/star/awt/Point.hpp>
+
+#include <cppunit/TestAssert.h>
+
+using namespace com::sun::star;
+using namespace com::sun::star::uno;
+
+namespace apitest
+{
+void CaptionShape::testCaptionShapeProperties()
+{
+ uno::Reference<beans::XPropertySet> xCaptionShape(init(), UNO_QUERY_THROW);
+ OUString propName;
+ uno::Any aNewValue;
+
+ propName = "CornerRadius";
+ sal_Int32 nCornerRadiusGet = 5;
+ sal_Int32 nCornerRadiusSet = 0;
+ CPPUNIT_ASSERT_MESSAGE("Unable to get PropertyValue CornerRadius",
+ xCaptionShape->getPropertyValue(propName) >>= nCornerRadiusGet);
+
+ aNewValue <<= nCornerRadiusGet + 5;
+ xCaptionShape->setPropertyValue(propName, aNewValue);
+ CPPUNIT_ASSERT(xCaptionShape->getPropertyValue(propName) >>= nCornerRadiusSet);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Unable to set PropertyValue CornerRadius", nCornerRadiusGet + 5,
+ nCornerRadiusSet);
+
+ propName = "CaptionPoint";
+ awt::Point aCaptionPointGet;
+ CPPUNIT_ASSERT_MESSAGE("Unable to get PropertyValue of CaptionPoint",
+ xCaptionShape->getPropertyValue(propName) >>= aCaptionPointGet);
+
+ awt::Point aCaptionPointSet;
+ aNewValue <<= awt::Point(5, 5);
+ xCaptionShape->setPropertyValue(propName, aNewValue);
+ CPPUNIT_ASSERT(xCaptionShape->getPropertyValue(propName) >>= aCaptionPointSet);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Able to set PropertyValue of CaptionPoint", aCaptionPointSet,
+ awt::Point(5, 5));
+
+ propName = "CaptionType";
+ sal_Int16 captionTypeGet = 0;
+ CPPUNIT_ASSERT_MESSAGE("Unable to get PropertyValue of CaptionType",
+ xCaptionShape->getPropertyValue(propName) >>= captionTypeGet);
+
+ sal_Int16 captionTypeSet = 0;
+ const sal_Int16 FIVE = 5;
+ aNewValue <<= FIVE;
+ xCaptionShape->setPropertyValue(propName, aNewValue);
+ CPPUNIT_ASSERT(xCaptionShape->getPropertyValue(propName) >>= captionTypeSet);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Unable to set the PropertyValue of CaptionType", FIVE,
+ captionTypeSet);
+
+ propName = "CaptionIsFixedAngle";
+ bool captionIsFixedAngleGet = false;
+ CPPUNIT_ASSERT_MESSAGE("Unable to get PropertyValue of CaptionPointIsFixedAngle",
+ xCaptionShape->getPropertyValue(propName) >>= captionIsFixedAngleGet);
+
+ bool captionIsFixedAngleSet = false;
+ aNewValue <<= !captionIsFixedAngleGet;
+ xCaptionShape->setPropertyValue(propName, aNewValue);
+ CPPUNIT_ASSERT(xCaptionShape->getPropertyValue(propName) >>= captionIsFixedAngleSet);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Unable to set the PropertyValue of CaptionPointisFixedAngle",
+ captionIsFixedAngleSet, !captionIsFixedAngleGet);
+
+ propName = "CaptionAngle";
+ sal_Int32 captionAngleGet = {};
+ CPPUNIT_ASSERT_MESSAGE("Unable to get the PropertyValue of CaptionAngle",
+ xCaptionShape->getPropertyValue(propName) >>= captionAngleGet);
+
+ sal_Int32 captionAngleSet = 0;
+ aNewValue <<= captionAngleGet + 5;
+ xCaptionShape->setPropertyValue(propName, aNewValue);
+ CPPUNIT_ASSERT(xCaptionShape->getPropertyValue(propName) >>= captionAngleSet);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Unable to set the PropertyValue of CaptionAngle", captionAngleSet,
+ captionAngleGet + 5);
+
+ propName = "CaptionGap";
+ sal_Int32 captionGapGet = {};
+ CPPUNIT_ASSERT_MESSAGE("Unable to get the PropertyValue of CaptionGap",
+ xCaptionShape->getPropertyValue(propName) >>= captionGapGet);
+
+ sal_Int32 captionGapSet = 0;
+ aNewValue <<= captionGapGet + 5;
+ xCaptionShape->setPropertyValue(propName, aNewValue);
+ CPPUNIT_ASSERT(xCaptionShape->getPropertyValue(propName) >>= captionGapSet);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Unable to set the PropertyValue of CaptionGap", captionGapSet,
+ captionGapGet + 5);
+
+ propName = "CaptionEscapeDirection";
+ sal_Int32 captionEscapeDirectionGet = {};
+ CPPUNIT_ASSERT_MESSAGE("Unable to get the PropertyValue of CaptionEscapeDirection",
+ xCaptionShape->getPropertyValue(propName) >>= captionEscapeDirectionGet);
+
+ sal_Int32 captionEscapeDirectionSet = 0;
+ aNewValue <<= captionEscapeDirectionGet + 5;
+ xCaptionShape->setPropertyValue(propName, aNewValue);
+ CPPUNIT_ASSERT(xCaptionShape->getPropertyValue(propName) >>= captionEscapeDirectionSet);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Unable to set the PropertyValue of CaptionEscapeDirection",
+ captionEscapeDirectionSet, captionEscapeDirectionGet + 5);
+
+ propName = "CaptionIsEscapeRelative";
+ bool captionIsEscapeRelativeGet = false;
+ CPPUNIT_ASSERT_MESSAGE("Unable to get PropertyValue of CaptionIsEscapeRelative",
+ xCaptionShape->getPropertyValue(propName)
+ >>= captionIsEscapeRelativeGet);
+
+ bool captionIsEscapeRelativeSet = false;
+ aNewValue <<= !captionIsEscapeRelativeGet;
+ xCaptionShape->setPropertyValue(propName, aNewValue);
+ CPPUNIT_ASSERT(xCaptionShape->getPropertyValue(propName) >>= captionIsEscapeRelativeSet);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Unable to set the PropertyValue of CaptionIsEscapeRelative",
+ captionIsEscapeRelativeSet, !captionIsEscapeRelativeGet);
+
+ propName = "CaptionEscapeRelative";
+ sal_Int32 captionEscapeRelativeGet = {};
+ CPPUNIT_ASSERT_MESSAGE("Unable to get the PropertyValue of CaptionEscapeRelative",
+ xCaptionShape->getPropertyValue(propName) >>= captionEscapeRelativeGet);
+
+ sal_Int32 captionEscapeRelativeSet = 0;
+ aNewValue <<= captionEscapeRelativeGet + 5;
+ xCaptionShape->setPropertyValue(propName, aNewValue);
+ CPPUNIT_ASSERT(xCaptionShape->getPropertyValue(propName) >>= captionEscapeRelativeSet);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Unable to set the PropertyValue of CaptionEscapeRelative",
+ captionEscapeRelativeSet, captionEscapeRelativeGet + 5);
+
+ propName = "CaptionEscapeAbsolute";
+ sal_Int32 captionEscapeAbsoluteGet = {};
+ CPPUNIT_ASSERT_MESSAGE("Unable to get the PropertyValue of CaptionEscapeAbsolute",
+ xCaptionShape->getPropertyValue(propName) >>= captionEscapeAbsoluteGet);
+
+ sal_Int32 captionEscapeAbsoluteSet = 0;
+ aNewValue <<= captionEscapeAbsoluteGet + 5;
+ xCaptionShape->setPropertyValue(propName, aNewValue);
+ CPPUNIT_ASSERT(xCaptionShape->getPropertyValue(propName) >>= captionEscapeAbsoluteSet);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Unable to set the PropertyValue of CaptionEscapeAbsolute",
+ captionEscapeAbsoluteSet, captionEscapeAbsoluteGet + 5);
+
+ propName = "CaptionLineLength";
+ sal_Int32 captionLineLengthGet = {};
+ CPPUNIT_ASSERT_MESSAGE("Unable to get the PropertyValue of CaptionLineLength",
+ xCaptionShape->getPropertyValue(propName) >>= captionLineLengthGet);
+
+ sal_Int32 captionLineLengthSet = 0;
+ aNewValue <<= captionLineLengthGet + 5;
+ xCaptionShape->setPropertyValue(propName, aNewValue);
+ CPPUNIT_ASSERT(xCaptionShape->getPropertyValue(propName) >>= captionLineLengthSet);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Unable to set the PropertyValue of CaptionEscapeAbsolute",
+ captionLineLengthSet, captionLineLengthGet + 5);
+
+ propName = "CaptionIsFitLineLength";
+ bool captionIsFitLineLengthGet = false;
+ CPPUNIT_ASSERT_MESSAGE("Unable to get PropertyValue of CaptionIsFitLineLength",
+ xCaptionShape->getPropertyValue(propName) >>= captionIsFitLineLengthGet);
+
+ bool captionIsFitLineLengthSet = false;
+ aNewValue <<= !captionIsFitLineLengthGet;
+ xCaptionShape->setPropertyValue(propName, aNewValue);
+ CPPUNIT_ASSERT(xCaptionShape->getPropertyValue(propName) >>= captionIsFitLineLengthSet);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Unable to set the PropertyValue of CaptionIsFitLineLength",
+ captionIsFitLineLengthSet, !captionIsFitLineLengthGet);
+}
+}
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/test/source/drawing/xdrawpages.cxx b/test/source/drawing/xdrawpages.cxx
new file mode 100644
index 0000000000..be57c48522
--- /dev/null
+++ b/test/source/drawing/xdrawpages.cxx
@@ -0,0 +1,50 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * 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 <test/drawing/xdrawpages.hxx>
+
+#include <com/sun/star/drawing/XDrawPage.hpp>
+#include <com/sun/star/drawing/XDrawPages.hpp>
+
+#include <com/sun/star/uno/Reference.hxx>
+
+#include <sal/types.h>
+
+#include <cppunit/TestAssert.h>
+
+using namespace css;
+using namespace css::uno;
+
+namespace apitest
+{
+void XDrawPages::testInsertNewByIndex()
+{
+ uno::Reference<drawing::XDrawPages> xDrawPages(init(), uno::UNO_QUERY_THROW);
+ const sal_Int32 nCount = xDrawPages->getCount();
+
+ uno::Reference<drawing::XDrawPage> xDP(xDrawPages->insertNewByIndex(0), uno::UNO_SET_THROW);
+ CPPUNIT_ASSERT(xDP.is());
+ CPPUNIT_ASSERT_EQUAL(nCount + 1, xDrawPages->getCount());
+}
+
+void XDrawPages::testRemove()
+{
+ uno::Reference<drawing::XDrawPages> xDrawPages(init(), uno::UNO_QUERY_THROW);
+ const sal_Int32 nCount = xDrawPages->getCount();
+
+ uno::Reference<drawing::XDrawPage> xDP(xDrawPages->insertNewByIndex(0), uno::UNO_SET_THROW);
+ CPPUNIT_ASSERT(xDP.is());
+
+ xDrawPages->remove(xDP);
+ CPPUNIT_ASSERT_EQUAL(nCount, xDrawPages->getCount());
+}
+
+} // namespace apitest
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/test/source/drawing/xgluepointssupplier.cxx b/test/source/drawing/xgluepointssupplier.cxx
new file mode 100644
index 0000000000..186c18d71a
--- /dev/null
+++ b/test/source/drawing/xgluepointssupplier.cxx
@@ -0,0 +1,32 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * 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 <test/drawing/xgluepointssupplier.hxx>
+
+#include <com/sun/star/container/XIndexContainer.hpp>
+#include <com/sun/star/drawing/XGluePointsSupplier.hpp>
+
+#include <com/sun/star/uno/Reference.hxx>
+
+#include <cppunit/TestAssert.h>
+
+using namespace css;
+
+namespace apitest
+{
+void XGluePointsSupplier::testGetGluePoints()
+{
+ uno::Reference<drawing::XGluePointsSupplier> xGPS(init(), uno::UNO_QUERY_THROW);
+
+ uno::Reference<container::XIndexContainer> xIC = xGPS->getGluePoints();
+ CPPUNIT_ASSERT(xIC->getCount());
+}
+} // namespace apitest
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/test/source/drawing/xshape.cxx b/test/source/drawing/xshape.cxx
new file mode 100644
index 0000000000..a63b892657
--- /dev/null
+++ b/test/source/drawing/xshape.cxx
@@ -0,0 +1,56 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * 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 <test/drawing/xshape.hxx>
+#include <test/cppunitasserthelper.hxx>
+
+#include <com/sun/star/awt/Point.hpp>
+#include <com/sun/star/awt/Size.hpp>
+#include <com/sun/star/drawing/XShape.hpp>
+
+#include <com/sun/star/uno/Reference.hxx>
+
+#include <cppunit/TestAssert.h>
+
+using namespace css;
+
+namespace apitest
+{
+void XShape::testGetSetPosition()
+{
+ uno::Reference<drawing::XShape> xShape(init(), uno::UNO_QUERY_THROW);
+ if (m_bObjSupportsPosition)
+ {
+ awt::Point aOldPoint = xShape->getPosition();
+ CPPUNIT_ASSERT_NO_THROW(
+ xShape->setPosition(awt::Point(aOldPoint.X + 100, aOldPoint.Y + 100)));
+
+ awt::Point aNewPoint = xShape->getPosition();
+ CPPUNIT_ASSERT_EQUAL(awt::Point(aOldPoint.X + 100, aOldPoint.Y + 100), aNewPoint);
+ }
+ CPPUNIT_ASSERT(true);
+}
+
+void XShape::testGetSetSize()
+{
+ uno::Reference<drawing::XShape> xShape(init(), uno::UNO_QUERY_THROW);
+
+ awt::Size aOldSize = xShape->getSize();
+
+ CPPUNIT_ASSERT_NO_THROW(xShape->setSize(awt::Size(aOldSize.Width + 10, aOldSize.Height + 10)));
+
+ awt::Size aNewSize = xShape->getSize();
+ const sal_Int16 aAcceptableLimit = 2;
+ CPPUNIT_ASSERT(aOldSize.Height - aNewSize.Height <= aAcceptableLimit);
+ CPPUNIT_ASSERT(aOldSize.Height - aNewSize.Height <= aAcceptableLimit);
+}
+
+} // namespace apitest
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/test/source/drawing/xshapedescriptor.cxx b/test/source/drawing/xshapedescriptor.cxx
new file mode 100644
index 0000000000..ff14513ef8
--- /dev/null
+++ b/test/source/drawing/xshapedescriptor.cxx
@@ -0,0 +1,30 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * 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 <test/drawing/xshapedescriptor.hxx>
+
+#include <com/sun/star/drawing/XShapeDescriptor.hpp>
+
+#include <com/sun/star/uno/Reference.hxx>
+
+#include <cppunit/TestAssert.h>
+
+using namespace css;
+
+namespace apitest
+{
+void XShapeDescriptor::testGetShapeType()
+{
+ uno::Reference<drawing::XShapeDescriptor> xSD(init(), uno::UNO_QUERY_THROW);
+
+ CPPUNIT_ASSERT_EQUAL(m_aShapeType, xSD->getShapeType());
+}
+} // namespace apitest
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/test/source/drawing/xshapegrouper.cxx b/test/source/drawing/xshapegrouper.cxx
new file mode 100644
index 0000000000..353faa1e78
--- /dev/null
+++ b/test/source/drawing/xshapegrouper.cxx
@@ -0,0 +1,57 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * 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 <test/drawing/xshapegrouper.hxx>
+#include <sal/types.h>
+
+#include <com/sun/star/drawing/XShape.hpp>
+#include <com/sun/star/drawing/XShapeGroup.hpp>
+#include <com/sun/star/drawing/XShapeGrouper.hpp>
+#include <com/sun/star/drawing/XShapes.hpp>
+
+#include <com/sun/star/uno/Reference.hxx>
+
+#include <cppunit/TestAssert.h>
+
+using namespace css;
+
+namespace apitest
+{
+void XShapeGrouper::testGroup()
+{
+ uno::Reference<drawing::XShapeGrouper> xSG(init(), uno::UNO_QUERY_THROW);
+
+ uno::Reference<drawing::XShapes> xShapes(m_xDrawPage, uno::UNO_QUERY_THROW);
+ const sal_Int32 nCountBeforeGroup = xShapes->getCount();
+
+ uno::Reference<drawing::XShape> xShape(xSG->group(xShapes), uno::UNO_QUERY_THROW);
+ const sal_Int32 nCountAfterGroup = xShapes->getCount();
+
+ CPPUNIT_ASSERT(xShape.is());
+ CPPUNIT_ASSERT(nCountAfterGroup < nCountBeforeGroup);
+}
+
+void XShapeGrouper::testUngroup()
+{
+ uno::Reference<drawing::XShapeGrouper> xSG(init(), uno::UNO_QUERY_THROW);
+
+ uno::Reference<drawing::XShapes> xShapes(m_xDrawPage, uno::UNO_QUERY_THROW);
+ uno::Reference<drawing::XShape> xShape(xSG->group(xShapes), uno::UNO_QUERY_THROW);
+ uno::Reference<drawing::XShapeGroup> xShapeGroup(xShape, uno::UNO_QUERY_THROW);
+
+ const sal_Int32 nCountAfterGroup = xShapes->getCount();
+
+ xSG->ungroup(xShapeGroup);
+ const sal_Int32 nCountAfterUngroup = xShapes->getCount();
+
+ CPPUNIT_ASSERT(nCountAfterUngroup != nCountAfterGroup);
+}
+} // namespace apitest
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/test/source/drawing/xshapes.cxx b/test/source/drawing/xshapes.cxx
new file mode 100644
index 0000000000..d836daf2b7
--- /dev/null
+++ b/test/source/drawing/xshapes.cxx
@@ -0,0 +1,38 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * 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 <test/drawing/xshapes.hxx>
+#include <sal/types.h>
+
+#include <com/sun/star/drawing/XShapes.hpp>
+#include <com/sun/star/uno/Reference.hxx>
+
+#include <cppunit/TestAssert.h>
+
+using namespace css;
+
+namespace apitest
+{
+void XShapes::testAddRemove()
+{
+ uno::Reference<drawing::XShapes> xShapes(init(), uno::UNO_QUERY_THROW);
+
+ const sal_Int32 nCountBeforeAdd = xShapes->getCount();
+ xShapes->add(m_xShape);
+ const sal_Int32 nCountAfterAdd = xShapes->getCount();
+ CPPUNIT_ASSERT_EQUAL(nCountBeforeAdd + 1, nCountAfterAdd);
+
+ xShapes->remove(m_xShape);
+ const sal_Int32 nCountAfterRemove = xShapes->getCount();
+ CPPUNIT_ASSERT_EQUAL(nCountBeforeAdd, nCountAfterRemove);
+}
+
+} // namespace apitest
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/test/source/helper/form.cxx b/test/source/helper/form.cxx
new file mode 100644
index 0000000000..5727909a60
--- /dev/null
+++ b/test/source/helper/form.cxx
@@ -0,0 +1,62 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * 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 <test/helper/form.hxx>
+#include <sal/types.h>
+
+#include <com/sun/star/awt/Point.hpp>
+#include <com/sun/star/awt/Size.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/drawing/XControlShape.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/uno/XInterface.hpp>
+
+#include <com/sun/star/uno/Any.hxx>
+#include <com/sun/star/uno/Reference.hxx>
+
+using namespace css;
+
+namespace apitest::helper::form
+{
+uno::Reference<drawing::XControlShape>
+ OOO_DLLPUBLIC_TEST createCommandButton(const uno::Reference<lang::XComponent>& r_xComponent,
+ const sal_Int32 nX, const sal_Int32 nY,
+ const sal_Int32 nHeight, const sal_Int32 nWidth)
+{
+ return createControlShape(r_xComponent, u"CommandButton", nX, nY, nHeight, nWidth);
+}
+
+uno::Reference<drawing::XControlShape> OOO_DLLPUBLIC_TEST createControlShape(
+ const uno::Reference<lang::XComponent>& r_xComponent, std::u16string_view r_aKind,
+ const sal_Int32 nX, const sal_Int32 nY, const sal_Int32 nHeight, const sal_Int32 nWidth)
+{
+ uno::Reference<lang::XMultiServiceFactory> xMSF(r_xComponent, uno::UNO_QUERY_THROW);
+
+ uno::Reference<drawing::XControlShape> xControlShape(
+ xMSF->createInstance("com.sun.star.drawing.ControlShape"), uno::UNO_QUERY_THROW);
+
+ uno::Reference<uno::XInterface> aComponent(
+ xMSF->createInstance(OUString::Concat("com.sun.star.form.component.") + r_aKind),
+ uno::UNO_SET_THROW);
+ uno::Reference<beans::XPropertySet> xPropertySet(aComponent, uno::UNO_QUERY_THROW);
+ xPropertySet->setPropertyValue(
+ "DefaultControl", uno::Any(OUString::Concat("com.sun.star.form.control.") + r_aKind));
+ uno::Reference<awt::XControlModel> xControlModel(aComponent, uno::UNO_QUERY_THROW);
+
+ xControlShape->setSize(awt::Size(nHeight, nWidth));
+ xControlShape->setPosition(awt::Point(nX, nY));
+
+ xControlShape->setControl(xControlModel);
+
+ return xControlShape;
+}
+
+} // namespace apitest::helper::form
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/test/source/helper/shape.cxx b/test/source/helper/shape.cxx
new file mode 100644
index 0000000000..0fbc3bc6d3
--- /dev/null
+++ b/test/source/helper/shape.cxx
@@ -0,0 +1,71 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * 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 <test/helper/shape.hxx>
+#include <sal/types.h>
+
+#include <com/sun/star/drawing/XShape.hpp>
+#include <com/sun/star/lang/XComponent.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/beans/PropertyVetoException.hpp>
+
+#include <com/sun/star/uno/Reference.hxx>
+
+using namespace css;
+
+namespace apitest::helper::shape
+{
+uno::Reference<drawing::XShape>
+ OOO_DLLPUBLIC_TEST createEllipse(const uno::Reference<lang::XComponent>& r_xComponent,
+ const sal_Int32 nX, const sal_Int32 nY, const sal_Int32 nWidth,
+ const sal_Int32 nHeight)
+{
+ return createShape(r_xComponent, u"Ellipse", nX, nY, nWidth, nHeight);
+}
+
+uno::Reference<drawing::XShape>
+ OOO_DLLPUBLIC_TEST createLine(const uno::Reference<lang::XComponent>& r_xComponent,
+ const sal_Int32 nX, const sal_Int32 nY, const sal_Int32 nWidth,
+ const sal_Int32 nHeight)
+{
+ return createShape(r_xComponent, u"Line", nX, nY, nWidth, nHeight);
+}
+
+uno::Reference<drawing::XShape>
+ OOO_DLLPUBLIC_TEST createRectangle(const uno::Reference<lang::XComponent>& r_xComponent,
+ const sal_Int32 nX, const sal_Int32 nY,
+ const sal_Int32 nWidth, const sal_Int32 nHeight)
+{
+ return createShape(r_xComponent, u"Rectangle", nX, nY, nWidth, nHeight);
+}
+
+uno::Reference<drawing::XShape> OOO_DLLPUBLIC_TEST
+createShape(const uno::Reference<lang::XComponent>& r_xComponent, std::u16string_view r_aKind,
+ const sal_Int32 nX, const sal_Int32 nY, const sal_Int32 nWidth, const sal_Int32 nHeight)
+{
+ uno::Reference<lang::XMultiServiceFactory> xMSF(r_xComponent, uno::UNO_QUERY_THROW);
+ uno::Reference<drawing::XShape> xShape(
+ xMSF->createInstance(OUString::Concat("com.sun.star.drawing.") + r_aKind + "Shape"),
+ uno::UNO_QUERY_THROW);
+
+ try
+ {
+ xShape->setPosition(awt::Point(nX, nY));
+ xShape->setSize(awt::Size(nWidth, nHeight));
+ }
+ catch (const beans::PropertyVetoException&)
+ {
+ }
+
+ return xShape;
+}
+
+} // namespace apitest::helper::shape
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/test/source/helper/transferable.cxx b/test/source/helper/transferable.cxx
new file mode 100644
index 0000000000..e264dba1ab
--- /dev/null
+++ b/test/source/helper/transferable.cxx
@@ -0,0 +1,82 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * 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 <test/helper/transferable.hxx>
+#include <com/sun/star/datatransfer/UnsupportedFlavorException.hpp>
+#include <o3tl/string_view.hxx>
+
+using namespace css;
+
+namespace apitest::helper::transferable
+{
+OString OOO_DLLPUBLIC_TEST getTextSelection(
+ const css::uno::Reference<css::datatransfer::XTransferable>& xTransferable, OString mimeType)
+{
+ if (!xTransferable.is())
+ return OString();
+
+ // Take care of UTF-8 text here.
+ bool bConvert = false;
+ sal_Int32 nIndex = 0;
+ if (o3tl::getToken(mimeType, 0, ';', nIndex) == "text/plain")
+ {
+ if (o3tl::getToken(mimeType, 0, ';', nIndex) == "charset=utf-8")
+ {
+ mimeType = "text/plain;charset=utf-16"_ostr;
+ bConvert = true;
+ }
+ }
+
+ datatransfer::DataFlavor aFlavor;
+ aFlavor.MimeType = OUString::fromUtf8(mimeType);
+ if (mimeType == "text/plain;charset=utf-16")
+ aFlavor.DataType = cppu::UnoType<OUString>::get();
+ else
+ aFlavor.DataType = cppu::UnoType<uno::Sequence<sal_Int8>>::get();
+
+ if (!xTransferable.is() || !xTransferable->isDataFlavorSupported(aFlavor))
+ return OString();
+
+ uno::Any aAny;
+ try
+ {
+ aAny = xTransferable->getTransferData(aFlavor);
+ }
+ catch (const css::datatransfer::UnsupportedFlavorException&)
+ {
+ return OString();
+ }
+ catch (const css::uno::Exception&)
+ {
+ return OString();
+ }
+
+ OString aRet;
+ if (aFlavor.DataType == cppu::UnoType<OUString>::get())
+ {
+ OUString aString;
+ aAny >>= aString;
+ if (bConvert)
+ aRet = OUStringToOString(aString, RTL_TEXTENCODING_UTF8);
+ else
+ aRet = OString(reinterpret_cast<const char*>(aString.getStr()),
+ aString.getLength() * sizeof(sal_Unicode));
+ }
+ else
+ {
+ uno::Sequence<sal_Int8> aSequence;
+ aAny >>= aSequence;
+ aRet = OString(reinterpret_cast<char*>(aSequence.getArray()), aSequence.getLength());
+ }
+ return aRet;
+}
+
+} // namespace apitest::helper::transferable
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/test/source/htmltesttools.cxx b/test/source/htmltesttools.cxx
new file mode 100644
index 0000000000..dedda5f982
--- /dev/null
+++ b/test/source/htmltesttools.cxx
@@ -0,0 +1,39 @@
+/* -*- 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 <test/htmltesttools.hxx>
+#include <sal/log.hxx>
+
+#include <memory>
+
+htmlDocUniquePtr HtmlTestTools::parseHtml(utl::TempFileNamed const & aTempFile)
+{
+ SvFileStream aFileStream(aTempFile.GetURL(), StreamMode::READ);
+ htmlDocUniquePtr doc = parseHtmlStream(&aFileStream);
+ xmlFree(doc->name);
+ doc->name = reinterpret_cast<char *>(
+ xmlStrdup(
+ reinterpret_cast<xmlChar const *>(
+ OUStringToOString(
+ aTempFile.GetURL(), RTL_TEXTENCODING_UTF8).getStr())));
+ return doc;
+}
+
+htmlDocUniquePtr HtmlTestTools::parseHtmlStream(SvStream* pStream)
+{
+ std::size_t nSize = pStream->remainingSize();
+ std::unique_ptr<sal_uInt8[]> pBuffer(new sal_uInt8[nSize + 1]);
+ pStream->ReadBytes(pBuffer.get(), nSize);
+ pBuffer[nSize] = 0;
+ auto pCharBuffer = reinterpret_cast<xmlChar*>(pBuffer.get());
+ SAL_INFO("test", "HtmlTestTools::parseXmlStream: pBuffer is '" << pCharBuffer << "'");
+ return htmlDocUniquePtr(htmlParseDoc(pCharBuffer, nullptr));
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/test/source/isheadless.hxx b/test/source/isheadless.hxx
new file mode 100644
index 0000000000..c9f22232bd
--- /dev/null
+++ b/test/source/isheadless.hxx
@@ -0,0 +1,34 @@
+/* -*- 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/.
+ */
+
+#pragma once
+
+#include <sal/config.h>
+
+#include <rtl/process.h>
+#include <rtl/ustring.hxx>
+#include <sal/types.h>
+
+namespace test {
+
+inline bool isHeadless() {
+ sal_uInt32 n = rtl_getAppCommandArgCount();
+ for (sal_uInt32 i = 0; i != n; ++i) {
+ OUString arg;
+ rtl_getAppCommandArg(i, &arg.pData);
+ if (arg == "--headless") {
+ return true;
+ }
+ }
+ return false;
+}
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/test/source/lang/xcomponent.cxx b/test/source/lang/xcomponent.cxx
new file mode 100644
index 0000000000..286f66c5c7
--- /dev/null
+++ b/test/source/lang/xcomponent.cxx
@@ -0,0 +1,77 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * 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 <cppuhelper/implbase.hxx>
+#include <test/lang/xcomponent.hxx>
+#include <rtl/ref.hxx>
+
+#include <com/sun/star/lang/XComponent.hpp>
+#include <com/sun/star/lang/XEventListener.hpp>
+
+#include <cppunit/TestAssert.h>
+
+using namespace css;
+using namespace css::uno;
+namespace
+{
+struct TestEventListener final : ::cppu::WeakImplHelper<lang::XEventListener>
+{
+ bool m_hasDisposingCalled;
+ TestEventListener()
+ : m_hasDisposingCalled(false)
+ {
+ }
+ virtual void SAL_CALL disposing(const lang::EventObject&) override
+ {
+ m_hasDisposingCalled = true;
+ }
+};
+}
+
+namespace apitest
+{
+void XComponent::testAddEventListener()
+{
+ Reference<lang::XComponent> xComponent(init(), uno::UNO_QUERY_THROW);
+ rtl::Reference<TestEventListener> pListenerAdded(new TestEventListener());
+ xComponent->addEventListener(pListenerAdded);
+ xComponent->dispose();
+ CPPUNIT_ASSERT_EQUAL(true, pListenerAdded->m_hasDisposingCalled);
+}
+
+void XComponent::testRemoveEventListener()
+{
+ Reference<lang::XComponent> xComponent(init(), uno::UNO_QUERY_THROW);
+ rtl::Reference<TestEventListener> pListenerAddedAndRemoved(new TestEventListener());
+ xComponent->addEventListener(pListenerAddedAndRemoved);
+ xComponent->removeEventListener(pListenerAddedAndRemoved);
+ xComponent->dispose();
+ CPPUNIT_ASSERT_EQUAL(false, pListenerAddedAndRemoved->m_hasDisposingCalled);
+}
+
+void XComponent::testDispose()
+{
+ Reference<lang::XComponent> xComponent(init(), uno::UNO_QUERY_THROW);
+ rtl::Reference<TestEventListener> pListenerAdded(new TestEventListener());
+ xComponent->addEventListener(pListenerAdded);
+ xComponent->dispose();
+ CPPUNIT_ASSERT_EQUAL(true, pListenerAdded->m_hasDisposingCalled);
+}
+
+void XComponent::testDisposedByDesktopTerminate()
+{
+ Reference<lang::XComponent> xComponent(init(), uno::UNO_QUERY_THROW);
+ rtl::Reference<TestEventListener> pListenerAdded(new TestEventListener());
+ xComponent->addEventListener(pListenerAdded);
+ triggerDesktopTerminate();
+ CPPUNIT_ASSERT_EQUAL(true, pListenerAdded->m_hasDisposingCalled);
+}
+} // namespace apitest
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/test/source/lang/xserviceinfo.cxx b/test/source/lang/xserviceinfo.cxx
new file mode 100644
index 0000000000..54a19cf2ac
--- /dev/null
+++ b/test/source/lang/xserviceinfo.cxx
@@ -0,0 +1,48 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * 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 <test/lang/xserviceinfo.hxx>
+
+#include <com/sun/star/lang/XServiceInfo.hpp>
+
+#include <com/sun/star/uno/Reference.hxx>
+#include <com/sun/star/uno/Sequence.hxx>
+
+#include <cppunit/TestAssert.h>
+
+using namespace css;
+
+namespace apitest
+{
+void XServiceInfo::testGetImplementationName()
+{
+ uno::Reference<lang::XServiceInfo> xSI(init(), uno::UNO_QUERY_THROW);
+
+ CPPUNIT_ASSERT_EQUAL(m_aImplName, xSI->getImplementationName());
+}
+
+void XServiceInfo::testGetSupportedServiceNames()
+{
+ uno::Reference<lang::XServiceInfo> xSI(init(), uno::UNO_QUERY_THROW);
+
+ uno::Sequence<OUString> aServiceNames = xSI->getSupportedServiceNames();
+ CPPUNIT_ASSERT(aServiceNames.hasElements());
+}
+
+void XServiceInfo::testSupportsService()
+{
+ uno::Reference<lang::XServiceInfo> xSI(init(), uno::UNO_QUERY_THROW);
+
+ for (const auto& aServiceName : m_aServiceNames)
+ CPPUNIT_ASSERT(xSI->supportsService(aServiceName));
+}
+
+} // namespace apitest
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/test/source/lokcallback.cxx b/test/source/lokcallback.cxx
new file mode 100644
index 0000000000..767448c771
--- /dev/null
+++ b/test/source/lokcallback.cxx
@@ -0,0 +1,188 @@
+/* -*- 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 <test/lokcallback.hxx>
+
+#include <LibreOfficeKit/LibreOfficeKitEnums.h>
+#include <rtl/strbuf.hxx>
+#include <tools/gen.hxx>
+#include <comphelper/lok.hxx>
+#include <sfx2/viewsh.hxx>
+
+TestLokCallbackWrapper::TestLokCallbackWrapper(LibreOfficeKitCallback callback, void* data)
+ : Idle("TestLokCallbackWrapper flush timer")
+ , m_callback(callback)
+ , m_data(data)
+{
+ // Flushing timer needs to run with the lowest priority, so that all pending tasks
+ // such as invalidations are processed before it.
+ SetPriority(TaskPriority::LOWEST);
+}
+
+void TestLokCallbackWrapper::clear()
+{
+ m_viewId = -1;
+ m_updatedTypes.clear();
+ m_updatedTypesPerViewId.clear();
+}
+
+inline void TestLokCallbackWrapper::startTimer()
+{
+ if (!IsActive())
+ Start();
+}
+
+constexpr int NO_VIEWID = -1;
+
+inline void TestLokCallbackWrapper::callCallback(int nType, const char* pPayload, int nViewId)
+{
+ discardUpdatedTypes(nType, nViewId);
+ m_callback(nType, pPayload, m_data);
+ startTimer();
+}
+
+void TestLokCallbackWrapper::libreOfficeKitViewCallback(int nType, const rtl::OString& pPayload)
+{
+ callCallback(nType, pPayload.getStr(), NO_VIEWID);
+}
+
+void TestLokCallbackWrapper::libreOfficeKitViewCallbackWithViewId(int nType,
+ const rtl::OString& pPayload,
+ int nViewId)
+{
+ callCallback(nType, pPayload.getStr(), nViewId);
+}
+
+void TestLokCallbackWrapper::libreOfficeKitViewInvalidateTilesCallback(
+ const tools::Rectangle* pRect, int nPart, int nMode)
+{
+ OStringBuffer buf(64);
+ if (pRect)
+ buf.append(pRect->toString());
+ else
+ buf.append("EMPTY");
+ if (comphelper::LibreOfficeKit::isPartInInvalidation())
+ {
+ buf.append(", " + OString::number(static_cast<sal_Int32>(nPart)) + ", "
+ + OString::number(static_cast<sal_Int32>(nMode)));
+ }
+ callCallback(LOK_CALLBACK_INVALIDATE_TILES, buf.makeStringAndClear().getStr(), NO_VIEWID);
+}
+
+// TODO This is probably a pointless code duplication with CallbackFlushHandler,
+// and using this in unittests also means that CallbackFlushHandler does not get
+// tested as thoroughly as it could. On the other hand, this class is simpler,
+// so debugging those unittests should also be simpler. The proper solution
+// is presumably this class using CallbackFlushHandler internally by default,
+// but having an option to use this simpler code when needed.
+
+void TestLokCallbackWrapper::libreOfficeKitViewUpdatedCallback(int nType)
+{
+ if (std::find(m_updatedTypes.begin(), m_updatedTypes.end(), nType) == m_updatedTypes.end())
+ {
+ m_updatedTypes.push_back(nType);
+ startTimer();
+ }
+}
+
+void TestLokCallbackWrapper::libreOfficeKitViewUpdatedCallbackPerViewId(int nType, int nViewId,
+ int nSourceViewId)
+{
+ const PerViewIdData data{ nType, nViewId, nSourceViewId };
+ auto& l = m_updatedTypesPerViewId;
+ // The source view doesn't matter for uniqueness, just keep the latest one.
+ auto it = std::find_if(l.begin(), l.end(), [data](const PerViewIdData& other) {
+ return data.type == other.type && data.viewId == other.viewId;
+ });
+ if (it != l.end())
+ *it = data;
+ else
+ l.push_back(data);
+ startTimer();
+}
+
+void TestLokCallbackWrapper::libreOfficeKitViewAddPendingInvalidateTiles()
+{
+ // Invoke() will call flushPendingLOKInvalidateTiles().
+ startTimer();
+}
+
+void TestLokCallbackWrapper::discardUpdatedTypes(int nType, int nViewId)
+{
+ // If a callback is called directly with an event, drop the updated flag for it, since
+ // the direct event replaces it.
+ for (auto it = m_updatedTypes.begin(); it != m_updatedTypes.end();)
+ {
+ if (*it == nType)
+ it = m_updatedTypes.erase(it);
+ else
+ ++it;
+ }
+ // If we do not have a specific view id, drop flag for all views.
+ bool allViewIds = false;
+ if (nViewId < 0)
+ allViewIds = true;
+ if (nType == LOK_CALLBACK_INVALIDATE_VISIBLE_CURSOR
+ && !comphelper::LibreOfficeKit::isViewIdForVisCursorInvalidation())
+ allViewIds = true;
+ for (auto it = m_updatedTypesPerViewId.begin(); it != m_updatedTypesPerViewId.end();)
+ {
+ if (it->type == nType && (allViewIds || it->viewId == nViewId))
+ it = m_updatedTypesPerViewId.erase(it);
+ else
+ ++it;
+ }
+}
+
+void TestLokCallbackWrapper::flushLOKData()
+{
+ if (m_updatedTypes.empty() && m_updatedTypesPerViewId.empty())
+ return;
+ // Ask for payloads of all the pending types that need updating, and call the generic callback with that data.
+ assert(m_viewId >= 0);
+ SfxViewShell* viewShell = SfxViewShell::GetFirst(false, [this](const SfxViewShell* shell) {
+ return shell->GetViewShellId().get() == m_viewId;
+ });
+ assert(viewShell != nullptr);
+ // First move data to local structures, so that callbacks don't possibly modify it.
+ std::vector<int> updatedTypes;
+ std::swap(updatedTypes, m_updatedTypes);
+ std::vector<PerViewIdData> updatedTypesPerViewId;
+ std::swap(updatedTypesPerViewId, m_updatedTypesPerViewId);
+
+ for (int type : updatedTypes)
+ {
+ std::optional<OString> payload = viewShell->getLOKPayload(type, m_viewId);
+ if (payload)
+ libreOfficeKitViewCallback(type, *payload);
+ }
+ for (const PerViewIdData& data : updatedTypesPerViewId)
+ {
+ viewShell = SfxViewShell::GetFirst(false, [data](const SfxViewShell* shell) {
+ return shell->GetViewShellId().get() == data.sourceViewId;
+ });
+ assert(viewShell != nullptr);
+ std::optional<OString> payload = viewShell->getLOKPayload(data.type, data.viewId);
+ if (payload)
+ libreOfficeKitViewCallbackWithViewId(data.type, *payload, data.viewId);
+ }
+}
+
+void TestLokCallbackWrapper::Invoke()
+{
+ // Timer timeout, flush any possibly pending data.
+ for (SfxViewShell* viewShell = SfxViewShell::GetFirst(false); viewShell != nullptr;
+ viewShell = SfxViewShell::GetNext(*viewShell, false))
+ {
+ viewShell->flushPendingLOKInvalidateTiles();
+ }
+ flushLOKData();
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/test/source/screenshot_test.cxx b/test/source/screenshot_test.cxx
new file mode 100644
index 0000000000..b4c188fdbc
--- /dev/null
+++ b/test/source/screenshot_test.cxx
@@ -0,0 +1,279 @@
+/* -*- 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 <iostream>
+
+#include <test/screenshot_test.hxx>
+
+#include <com/sun/star/frame/Desktop.hpp>
+#include <comphelper/processfactory.hxx>
+#include <vcl/abstdlg.hxx>
+#include <vcl/filter/PngImageWriter.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/virdev.hxx>
+#include <vcl/weld.hxx>
+#include <tools/stream.hxx>
+
+
+namespace {
+ void splitHelpId( const OUString& rHelpId, OUString& rDirname, OUString &rBasename )
+ {
+ sal_Int32 nIndex = rHelpId.lastIndexOf( '/' );
+
+ if( nIndex > 0 )
+ rDirname = rHelpId.subView( 0, nIndex );
+
+ if( rHelpId.getLength() > nIndex+1 )
+ rBasename = rHelpId.subView( nIndex+1 );
+ }
+}
+
+using namespace css;
+using namespace css::uno;
+
+ /// the target directory for screenshots
+constexpr OUString g_aScreenshotDirectory(u"screenshots"_ustr);
+
+ScreenshotTest::ScreenshotTest()
+ : maParent(nullptr, "vcl/ui/screenshotparent.ui", "ScreenShot")
+ , mxParentWidget(maParent.getDialog()->weld_content_area())
+{
+ if (auto const env = getenv("LO_TEST_LOCALE")) {
+ maCurrentLanguage = OUString::fromUtf8(env);
+ }
+}
+
+ScreenshotTest::~ScreenshotTest()
+{
+}
+
+void ScreenshotTest::setUp()
+{
+ test::BootstrapFixture::setUp();
+
+ mxDesktop = css::frame::Desktop::create( comphelper::getComponentContext(getMultiServiceFactory()) );
+ CPPUNIT_ASSERT_MESSAGE("no desktop!", mxDesktop.is());
+
+ osl::Directory::create( m_directories.getURLFromWorkdir( g_aScreenshotDirectory)) ;
+
+ // initialize maKnownDialogs
+ if (maKnownDialogs.empty())
+ {
+ registerKnownDialogsByID(maKnownDialogs);
+ }
+}
+
+void ScreenshotTest::implSaveScreenshot(const BitmapEx& rScreenshot, const OUString& rScreenshotId)
+{
+ OUString aDirname, aBasename;
+ splitHelpId(rScreenshotId, aDirname, aBasename);
+ aDirname = g_aScreenshotDirectory + "/" + aDirname +
+ ( (maCurrentLanguage == "en-US") ? OUString() : "/" + maCurrentLanguage );
+
+ auto const dirUrl = m_directories.getURLFromWorkdir(aDirname);
+ auto const e = osl::Directory::createPath(dirUrl);
+ if (e != osl::FileBase::E_EXIST) {
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(
+ OString("Failed to create " + OUStringToOString(dirUrl, RTL_TEXTENCODING_UTF8))
+ .getStr(),
+ osl::FileBase::E_None, e);
+ }
+
+ auto const pngUrl = OUString(dirUrl + "/" + aBasename + ".png");
+ SvFileStream aNew(pngUrl, StreamMode::WRITE | StreamMode::TRUNC);
+ CPPUNIT_ASSERT_MESSAGE(OString("Failed to open <" + OUStringToOString(pngUrl, RTL_TEXTENCODING_UTF8) + ">: " + OString::number(sal_uInt32(aNew.GetErrorCode()))).getStr(), aNew.IsOpen());
+
+ std::cout << "saving " << pngUrl << ":\n";
+ vcl::PngImageWriter aPNGWriter(aNew);
+ aPNGWriter.write(rScreenshot);
+}
+
+void ScreenshotTest::saveScreenshot(VclAbstractDialog const & rDialog)
+{
+ const BitmapEx aScreenshot(rDialog.createScreenshot());
+
+ if (!aScreenshot.IsEmpty())
+ {
+ const OUString aScreenshotId = rDialog.GetScreenshotId();
+
+ if (!aScreenshotId.isEmpty())
+ {
+ implSaveScreenshot(aScreenshot, aScreenshotId);
+ }
+ }
+}
+
+void ScreenshotTest::saveScreenshot(weld::Window& rDialog)
+{
+ VclPtr<VirtualDevice> xDialogSurface(rDialog.screenshot());
+ const BitmapEx aScreenshot(xDialogSurface->GetBitmapEx(Point(), xDialogSurface->GetOutputSizePixel()));
+
+ if (!aScreenshot.IsEmpty())
+ {
+ const OUString aScreenshotId = rDialog.get_help_id();
+ assert(!aScreenshotId.isEmpty());
+ implSaveScreenshot(aScreenshot, aScreenshotId);
+ }
+}
+
+VclPtr<VclAbstractDialog> ScreenshotTest::createDialogByName(const OString& rName)
+{
+ const mapType::const_iterator aHit = maKnownDialogs.find(rName);
+
+ if (aHit != maKnownDialogs.end())
+ {
+ return createDialogByID((*aHit).second);
+ }
+
+ return VclPtr<VclAbstractDialog>();
+}
+
+void ScreenshotTest::dumpDialogToPath(VclAbstractDialog& rDialog)
+{
+ const std::vector<OUString> aPageDescriptions(rDialog.getAllPageUIXMLDescriptions());
+
+ if (!aPageDescriptions.empty())
+ {
+ for (size_t a(0); a < aPageDescriptions.size(); a++)
+ {
+ if (rDialog.selectPageByUIXMLDescription(aPageDescriptions[a]))
+ {
+ saveScreenshot(rDialog);
+ }
+ else
+ {
+ CPPUNIT_ASSERT(false);
+ }
+ }
+ }
+ else
+ {
+ saveScreenshot(rDialog);
+ }
+}
+
+void ScreenshotTest::dumpDialogToPath(weld::Builder& rBuilder)
+{
+ std::unique_ptr<weld::Window> xDialog(rBuilder.create_screenshot_window());
+
+ auto xTabCtrl = rBuilder.weld_notebook("tabcontrol");
+
+ int nPages = xTabCtrl ? xTabCtrl->get_n_pages() : 0;
+ if (nPages)
+ {
+ for (int i = 0; i < nPages; ++i)
+ {
+ OUString sIdent(xTabCtrl->get_page_ident(i));
+ xTabCtrl->set_current_page(sIdent);
+ if (xTabCtrl->get_current_page_ident() == sIdent)
+ {
+ OUString sOrigHelpId(xDialog->get_help_id());
+ // skip empty pages
+ weld::Container* pPage = xTabCtrl->get_page(sIdent);
+ OUString sBuildableName(pPage->get_buildable_name());
+ if (!sBuildableName.isEmpty() && !sBuildableName.startsWith("__"))
+ xDialog->set_help_id(pPage->get_help_id());
+ saveScreenshot(*xDialog);
+ xDialog->set_help_id(sOrigHelpId);
+ }
+ else
+ {
+ CPPUNIT_ASSERT(false);
+ }
+ }
+ }
+ else
+ {
+ saveScreenshot(*xDialog);
+ }
+}
+
+void ScreenshotTest::dumpDialogToPath(std::string_view rUIXMLDescription)
+{
+ if (rUIXMLDescription.empty())
+ return;
+
+ bool bNonConforming = rUIXMLDescription == "modules/swriter/ui/sidebarstylepresets.ui" ||
+ rUIXMLDescription == "modules/swriter/ui/sidebartheme.ui" ||
+ rUIXMLDescription == "modules/swriter/ui/notebookbar.ui" ||
+ rUIXMLDescription == "modules/scalc/ui/sidebaralignment.ui" ||
+ rUIXMLDescription == "modules/scalc/ui/sidebarcellappearance.ui" ||
+ rUIXMLDescription == "modules/scalc/ui/sidebarnumberformat.ui" ||
+ rUIXMLDescription == "sfx/ui/helpbookmarkpage.ui" ||
+ rUIXMLDescription == "sfx/ui/helpcontentpage.ui" ||
+ rUIXMLDescription == "sfx/ui/helpindexpage.ui" ||
+ rUIXMLDescription == "sfx/ui/helpsearchpage.ui" ||
+ rUIXMLDescription == "sfx/ui/startcenter.ui" ||
+ rUIXMLDescription == "svx/ui/datanavigator.ui" ||
+ rUIXMLDescription == "svx/ui/xformspage.ui" ||
+ rUIXMLDescription == "modules/dbreport/ui/conditionwin.ui";
+ if (bNonConforming) // skip these broken ones
+ return;
+ std::unique_ptr<weld::Builder> xBuilder(Application::CreateBuilder(mxParentWidget.get(), OStringToOUString(rUIXMLDescription, RTL_TEXTENCODING_UTF8)));
+ dumpDialogToPath(*xBuilder);
+}
+
+void ScreenshotTest::processAllKnownDialogs()
+{
+ for (const auto& rDialog : getKnownDialogs())
+ {
+ ScopedVclPtr<VclAbstractDialog> pDlg(createDialogByID(rDialog.second));
+
+ if (pDlg)
+ {
+ // known dialog, dump screenshot to path
+ dumpDialogToPath(*pDlg);
+ }
+ else
+ {
+ // unknown dialog, should not happen in this basic loop.
+ // You have probably forgotten to add a case and
+ // implementation to createDialogByID, please do this
+ }
+ }
+}
+
+void ScreenshotTest::processDialogBatchFile(std::u16string_view rFile)
+{
+ test::Directories aDirectories;
+ const OUString aURL(aDirectories.getURLFromSrc(rFile));
+ SvFileStream aStream(aURL, StreamMode::READ);
+ OString aNextUIFile;
+ static constexpr OStringLiteral aComment("#");
+
+ while (aStream.ReadLine(aNextUIFile))
+ {
+ if (!aNextUIFile.isEmpty() && !aNextUIFile.startsWith(aComment))
+ {
+ std::cout << "processing " << aNextUIFile << ":\n";
+
+ // first check if it's a known dialog
+ ScopedVclPtr<VclAbstractDialog> pDlg(createDialogByName(aNextUIFile));
+
+ if (pDlg)
+ {
+ // known dialog, dump screenshot to path
+ dumpDialogToPath(*pDlg);
+ }
+ else
+ {
+ // unknown dialog, try fallback to generic created
+ // Builder-generated instance. Keep in mind that Dialogs
+ // using this mechanism will probably not be layouted well
+ // since the setup/initialization part is missing. Thus,
+ // only use for fallback when only the UI file is available.
+ dumpDialogToPath(aNextUIFile);
+ }
+ }
+ }
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/test/source/setupvcl.cxx b/test/source/setupvcl.cxx
new file mode 100644
index 0000000000..7e489effb3
--- /dev/null
+++ b/test/source/setupvcl.cxx
@@ -0,0 +1,94 @@
+/* -*- 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 <com/sun/star/configuration/theDefaultProvider.hpp>
+#include <com/sun/star/lang/XComponent.hpp>
+#include <com/sun/star/util/XFlushable.hpp>
+#include <com/sun/star/frame/Desktop.hpp>
+#include <comphelper/processfactory.hxx>
+#include <i18nlangtag/languagetag.hxx>
+#include <i18nlangtag/mslangid.hxx>
+#include <unotools/configmgr.hxx>
+#include <unotools/syslocaleoptions.hxx>
+#include <vcl/svapp.hxx>
+
+#include "isheadless.hxx"
+#include "setupvcl.hxx"
+
+namespace {
+
+struct Hook { // LINK only works as a member of a class...
+ DECL_STATIC_LINK(Hook, deinitHook, LinkParamNone *, void);
+};
+
+// HACK so that defaultBootstrap_InitialComponentContext (in
+// unobootstrapprotector) is called before InitVCL (below), but component
+// context is disposed (redundantly again in unobootstrapprotector) from within
+// DeInitVCL (cf. Desktop::DeInit, desktop/source/app/app.cxx):
+IMPL_STATIC_LINK_NOARG(Hook, deinitHook, LinkParamNone *, void) {
+ css::uno::Reference<css::uno::XComponentContext> context;
+ try {
+ context = comphelper::getProcessComponentContext();
+ } catch (css::uno::RuntimeException &) {}
+
+ if (!context)
+ return;
+
+ css::uno::Reference<css::lang::XMultiServiceFactory> config;
+ try {
+ config = css::configuration::theDefaultProvider::get(context);
+ } catch (css::uno::DeploymentException &) {}
+ if (config) {
+ utl::ConfigManager::storeConfigItems();
+ css::uno::Reference<css::util::XFlushable>(
+ config, css::uno::UNO_QUERY_THROW)->flush();
+ }
+
+ // the desktop has to be terminate() before it can be dispose()
+ css::uno::Reference<css::frame::XDesktop> xDesktop;
+ try {
+ xDesktop = css::frame::Desktop::create(comphelper::getProcessComponentContext());
+ } catch (css::uno::DeploymentException &) {}
+ if (xDesktop)
+ try {
+ xDesktop->terminate();
+ } catch (css::uno::DeploymentException &) {}
+
+ css::uno::Reference<css::lang::XComponent>(
+ context, css::uno::UNO_QUERY_THROW)->dispose();
+
+ comphelper::setProcessServiceFactory(nullptr);
+}
+
+}
+
+void test::setUpVcl(bool const forceHeadless) {
+ // Force locale (and resource files loaded):
+ OUString locale;
+ if (getenv("LO_TEST_LOCALE") != nullptr)
+ locale = OUString::fromUtf8(getenv("LO_TEST_LOCALE"));
+ else
+ locale = "en-US";
+
+ SvtSysLocaleOptions localOptions;
+ localOptions.SetLocaleConfigString(locale);
+ localOptions.SetUILocaleConfigString(locale);
+ LanguageTag tag(locale);
+ MsLangId::setConfiguredSystemUILanguage(tag.getLanguageType(false));
+ LanguageTag::setConfiguredSystemLanguage(tag.getLanguageType(false));
+ InitVCL();
+ if (forceHeadless || isHeadless()) {
+ Application::EnableHeadlessMode(false);
+ }
+ Application::setDeInitHook(LINK(nullptr, Hook, deinitHook));
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/test/source/setupvcl.hxx b/test/source/setupvcl.hxx
new file mode 100644
index 0000000000..5da3b19e03
--- /dev/null
+++ b/test/source/setupvcl.hxx
@@ -0,0 +1,25 @@
+/* -*- 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/.
+ */
+
+#ifndef INCLUDED_TEST_SETUPVCL_HXX
+#define INCLUDED_TEST_SETUPVCL_HXX
+
+#include <sal/config.h>
+
+#include <test/testdllapi.hxx>
+
+namespace test
+{
+// Calls InitVCL etc.; needed from multiple places in the test infrastructure:
+OOO_DLLPUBLIC_TEST_SETUPVCL void setUpVcl(bool forceHeadless = false);
+}
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/test/source/sheet/cellarealink.cxx b/test/source/sheet/cellarealink.cxx
new file mode 100644
index 0000000000..93319542cb
--- /dev/null
+++ b/test/source/sheet/cellarealink.cxx
@@ -0,0 +1,114 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * 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 <test/sheet/cellarealink.hxx>
+
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/uno/Reference.hxx>
+
+#include <cppunit/TestAssert.h>
+
+using namespace css;
+
+namespace apitest
+{
+void CellAreaLink::testUrl()
+{
+ uno::Reference<beans::XPropertySet> xCellAreaLink(init(), uno::UNO_QUERY_THROW);
+
+ static constexpr OUString propName(u"Url"_ustr);
+
+ OUString aUrl;
+ CPPUNIT_ASSERT(xCellAreaLink->getPropertyValue(propName) >>= aUrl);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Default Url already changed", m_aFileURL, aUrl);
+
+ uno::Any aNewUrl;
+ aNewUrl <<= OUString("file:///tmp");
+ xCellAreaLink->setPropertyValue(propName, aNewUrl);
+ CPPUNIT_ASSERT(xCellAreaLink->getPropertyValue(propName) >>= aUrl);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Value of Url wasn't changed", OUString("file:///tmp"), aUrl);
+}
+
+void CellAreaLink::testFilter()
+{
+ uno::Reference<beans::XPropertySet> xCellAreaLink(init(), uno::UNO_QUERY_THROW);
+
+ static constexpr OUString propName(u"Filter"_ustr);
+
+ OUString aFilter;
+ CPPUNIT_ASSERT(xCellAreaLink->getPropertyValue(propName) >>= aFilter);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Default Filter already changed", OUString("calc8"), aFilter);
+
+ uno::Any aNewFilter;
+ aNewFilter <<= OUString("UnitTest");
+ xCellAreaLink->setPropertyValue(propName, aNewFilter);
+ CPPUNIT_ASSERT(xCellAreaLink->getPropertyValue(propName) >>= aFilter);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Value of Filter wasn't changed", OUString("UnitTest"), aFilter);
+}
+
+void CellAreaLink::testFilterOptions()
+{
+ uno::Reference<beans::XPropertySet> xCellAreaLink(init(), uno::UNO_QUERY_THROW);
+
+ static constexpr OUString propName(u"FilterOptions"_ustr);
+
+ OUString aFilterOptions;
+ CPPUNIT_ASSERT(xCellAreaLink->getPropertyValue(propName) >>= aFilterOptions);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Default FilterOptions already changed", OUString(""),
+ aFilterOptions);
+
+ uno::Any aNewFilterOptions;
+ aNewFilterOptions <<= OUString("UnitTest");
+ xCellAreaLink->setPropertyValue(propName, aNewFilterOptions);
+ CPPUNIT_ASSERT(xCellAreaLink->getPropertyValue(propName) >>= aFilterOptions);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Value of FilterOptions wasn't changed", OUString("UnitTest"),
+ aFilterOptions);
+}
+
+void CellAreaLink::testRefreshDelay()
+{
+ uno::Reference<beans::XPropertySet> xCellAreaLink(init(), uno::UNO_QUERY_THROW);
+
+ static constexpr OUString propName(u"RefreshDelay"_ustr);
+
+ sal_Int32 aRefreshDelay = 0;
+ CPPUNIT_ASSERT(xCellAreaLink->getPropertyValue(propName) >>= aRefreshDelay);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Default RefreshDelay already changed", sal_Int32(0),
+ aRefreshDelay);
+
+ uno::Any aNewRefreshDelay;
+ aNewRefreshDelay <<= static_cast<sal_Int32>(42);
+ xCellAreaLink->setPropertyValue(propName, aNewRefreshDelay);
+ CPPUNIT_ASSERT(xCellAreaLink->getPropertyValue(propName) >>= aRefreshDelay);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Value of RefreshDelay wasn't changed", sal_Int32(42),
+ aRefreshDelay);
+}
+
+void CellAreaLink::testRefreshPeriod()
+{
+ uno::Reference<beans::XPropertySet> xCellAreaLink(init(), uno::UNO_QUERY_THROW);
+
+ static constexpr OUString propName(u"RefreshPeriod"_ustr);
+
+ sal_Int32 aRefreshPeriod = 0;
+ CPPUNIT_ASSERT(xCellAreaLink->getPropertyValue(propName) >>= aRefreshPeriod);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Default RefreshPeriod already changed", sal_Int32(0),
+ aRefreshPeriod);
+
+ uno::Any aNewRefreshPeriod;
+ aNewRefreshPeriod <<= static_cast<sal_Int32>(42);
+ xCellAreaLink->setPropertyValue(propName, aNewRefreshPeriod);
+ CPPUNIT_ASSERT(xCellAreaLink->getPropertyValue(propName) >>= aRefreshPeriod);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Value of RefreshPeriod wasn't changed", sal_Int32(42),
+ aRefreshPeriod);
+}
+
+} // namespace apitest
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/test/source/sheet/cellproperties.cxx b/test/source/sheet/cellproperties.cxx
new file mode 100644
index 0000000000..3d7908be78
--- /dev/null
+++ b/test/source/sheet/cellproperties.cxx
@@ -0,0 +1,59 @@
+/* -*- 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 <test/sheet/cellproperties.hxx>
+
+#include <com/sun/star/beans/XPropertySet.hpp>
+
+#include <cppunit/TestAssert.h>
+#include <iostream>
+
+using namespace css;
+using namespace css::uno;
+
+namespace apitest
+{
+void CellProperties::testVertJustify()
+{
+ uno::Reference<beans::XPropertySet> xCellRangeBase(init(), UNO_QUERY_THROW);
+ OUString aVertJustify("VertJustify");
+ uno::Any aOldVertJustify = xCellRangeBase->getPropertyValue(aVertJustify);
+ sal_Int32 aValue = 0;
+ CPPUNIT_ASSERT(aOldVertJustify >>= aValue);
+ std::cout << "Old VertJustify value: " << aValue << std::endl;
+
+ uno::Any aNewVertJustify;
+ aNewVertJustify <<= static_cast<sal_Int32>(3);
+ xCellRangeBase->setPropertyValue(aVertJustify, aNewVertJustify);
+ uno::Any aVertJustifyControllValue = xCellRangeBase->getPropertyValue(aVertJustify);
+ CPPUNIT_ASSERT(aVertJustifyControllValue >>= aValue);
+ std::cout << "New VertJustify value: " << aValue << std::endl;
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("value has not been changed", sal_Int32(3), aValue);
+}
+
+void CellProperties::testRotateReference()
+{
+ uno::Reference<beans::XPropertySet> xCellRangeBase(init(), UNO_QUERY_THROW);
+ OUString aRotateReference("RotateReference");
+ uno::Any aOldRotateReference = xCellRangeBase->getPropertyValue(aRotateReference);
+ sal_Int32 aValue = 0;
+ CPPUNIT_ASSERT(aOldRotateReference >>= aValue);
+ std::cout << "Old RotateReference Value: " << aValue << std::endl;
+
+ uno::Any aNewRotateReference;
+ aNewRotateReference <<= static_cast<sal_Int32>(3);
+ xCellRangeBase->setPropertyValue(aRotateReference, aNewRotateReference);
+ uno::Any aRotateReferenceControllValue = xCellRangeBase->getPropertyValue(aRotateReference);
+ CPPUNIT_ASSERT(aRotateReferenceControllValue >>= aValue);
+ std::cout << "New RotateReference value: " << aValue << std::endl;
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("value has not been changed", sal_Int32(3), aValue);
+}
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/test/source/sheet/databaseimportdescriptor.cxx b/test/source/sheet/databaseimportdescriptor.cxx
new file mode 100644
index 0000000000..132f88817f
--- /dev/null
+++ b/test/source/sheet/databaseimportdescriptor.cxx
@@ -0,0 +1,102 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * 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 <test/sheet/databaseimportdescriptor.hxx>
+
+#include <com/sun/star/beans/PropertyValue.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/sheet/DataImportMode.hpp>
+#include <com/sun/star/util/XImportable.hpp>
+#include <com/sun/star/uno/Any.hxx>
+#include <com/sun/star/uno/Reference.hxx>
+#include <com/sun/star/uno/Sequence.hxx>
+
+#include <cppunit/TestAssert.h>
+
+using namespace com::sun::star;
+using namespace com::sun::star::uno;
+
+namespace apitest
+{
+void DatabaseImportDescriptor::testDatabaseImportDescriptorProperties()
+{
+ uno::Reference<beans::XPropertySet> xDatabaseImportDescriptor(init(), UNO_QUERY_THROW);
+ uno::Reference<util::XImportable> xImportable(getXImportable(), UNO_QUERY_THROW);
+ uno::Sequence<beans::PropertyValue> aPropValues = xImportable->createImportDescriptor(true);
+
+ for (auto& rPropValue : asNonConstRange(aPropValues))
+ {
+ uno::Any aOldValue;
+ uno::Any aNewValue;
+ if (rPropValue.Name == "DatabaseName" || rPropValue.Name == "SourceObject"
+ || rPropValue.Name == "ConnectionResource")
+ {
+ OUString aValue;
+ aOldValue = rPropValue.Value;
+ aOldValue >>= aValue;
+ OString aMsgGet = "Unable to get PropertyValue "
+ + OUStringToOString(rPropValue.Name, RTL_TEXTENCODING_UTF8);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(aMsgGet.getStr(), OUString(""), aValue);
+
+ aNewValue <<= OUString("New");
+ rPropValue.Value = aNewValue;
+
+ aOldValue = rPropValue.Value;
+ aOldValue >>= aValue;
+ OString aMsgSet = "Unable to set PropertyValue "
+ + OUStringToOString(rPropValue.Name, RTL_TEXTENCODING_UTF8);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(aMsgSet.getStr(), OUString("New"), aValue);
+ }
+ else if (rPropValue.Name == "IsNative")
+ {
+ bool aValue = true;
+ aOldValue = rPropValue.Value;
+ aOldValue >>= aValue;
+ OString aMsgGet = "Unable to get PropertyValue "
+ + OUStringToOString(rPropValue.Name, RTL_TEXTENCODING_UTF8);
+ CPPUNIT_ASSERT_MESSAGE(aMsgGet.getStr(), !aValue);
+
+ aNewValue <<= true;
+ rPropValue.Value = aNewValue;
+
+ aOldValue = rPropValue.Value;
+ aOldValue >>= aValue;
+ OString aMsgSet = "Unable to set PropertyValue "
+ + OUStringToOString(rPropValue.Name, RTL_TEXTENCODING_UTF8);
+ CPPUNIT_ASSERT_MESSAGE(aMsgSet.getStr(), aValue);
+ }
+ else if (rPropValue.Name == "SourceType")
+ {
+ sheet::DataImportMode aValue;
+ aOldValue = rPropValue.Value;
+ aOldValue >>= aValue;
+ OString aMsgGet = "Unable to get PropertyValue "
+ + OUStringToOString(rPropValue.Name, RTL_TEXTENCODING_UTF8);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(aMsgGet.getStr(), sheet::DataImportMode_NONE, aValue);
+
+ aNewValue <<= sheet::DataImportMode_SQL;
+ rPropValue.Value = aNewValue;
+
+ aOldValue = rPropValue.Value;
+ aOldValue >>= aValue;
+ OString aMsgSet = "Unable to set PropertyValue "
+ + OUStringToOString(rPropValue.Name, RTL_TEXTENCODING_UTF8);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(aMsgSet.getStr(), sheet::DataImportMode_SQL, aValue);
+ }
+ else
+ {
+ OString aMsg = "Unsupported PropertyValue "
+ + OUStringToOString(rPropValue.Name, RTL_TEXTENCODING_UTF8);
+ CPPUNIT_FAIL(aMsg.getStr());
+ }
+ }
+}
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/test/source/sheet/databaserange.cxx b/test/source/sheet/databaserange.cxx
new file mode 100644
index 0000000000..5bae62ce43
--- /dev/null
+++ b/test/source/sheet/databaserange.cxx
@@ -0,0 +1,219 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * 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 <test/sheet/databaserange.hxx>
+#include <test/cppunitasserthelper.hxx>
+
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/sheet/XDatabaseRange.hpp>
+#include <com/sun/star/table/CellRangeAddress.hpp>
+#include <com/sun/star/uno/Reference.hxx>
+
+#include <cppunit/TestAssert.h>
+
+using namespace com::sun::star;
+using namespace com::sun::star::uno;
+
+namespace apitest
+{
+void DatabaseRange::testMoveCells()
+{
+ uno::Reference<beans::XPropertySet> xDatabaseRange(init("DataArea"), UNO_QUERY_THROW);
+
+ static constexpr OUString propName(u"MoveCells"_ustr);
+
+ bool bMoveCells = true;
+ CPPUNIT_ASSERT(xDatabaseRange->getPropertyValue(propName) >>= bMoveCells);
+ CPPUNIT_ASSERT_MESSAGE("Default MoveCells already changed", !bMoveCells);
+
+ uno::Any aNewMoveCells;
+ aNewMoveCells <<= true;
+ xDatabaseRange->setPropertyValue(propName, aNewMoveCells);
+ CPPUNIT_ASSERT(xDatabaseRange->getPropertyValue(propName) >>= bMoveCells);
+ CPPUNIT_ASSERT_MESSAGE("Value of MoveCells wasn't changed", bMoveCells);
+}
+
+void DatabaseRange::testKeepFormats()
+{
+ uno::Reference<beans::XPropertySet> xDatabaseRange(init("DataArea"), UNO_QUERY_THROW);
+
+ static constexpr OUString propName(u"KeepFormats"_ustr);
+
+ bool bKeepFormats = true;
+ CPPUNIT_ASSERT(xDatabaseRange->getPropertyValue(propName) >>= bKeepFormats);
+ CPPUNIT_ASSERT_MESSAGE("Default KeepFormats already changed", !bKeepFormats);
+
+ uno::Any aNewKeepFormats;
+ aNewKeepFormats <<= true;
+ xDatabaseRange->setPropertyValue(propName, aNewKeepFormats);
+ CPPUNIT_ASSERT(xDatabaseRange->getPropertyValue(propName) >>= bKeepFormats);
+ CPPUNIT_ASSERT_MESSAGE("Value of KeepFormats wasn't changed", bKeepFormats);
+}
+
+void DatabaseRange::testStripData()
+{
+ uno::Reference<beans::XPropertySet> xDatabaseRange(init("DataArea"), UNO_QUERY_THROW);
+
+ static constexpr OUString propName(u"StripData"_ustr);
+
+ bool bStripData = true;
+ CPPUNIT_ASSERT(xDatabaseRange->getPropertyValue(propName) >>= bStripData);
+ CPPUNIT_ASSERT_MESSAGE("Default StripData already changed", !bStripData);
+
+ uno::Any aNewStripData;
+ aNewStripData <<= true;
+ xDatabaseRange->setPropertyValue(propName, aNewStripData);
+ CPPUNIT_ASSERT(xDatabaseRange->getPropertyValue(propName) >>= bStripData);
+ CPPUNIT_ASSERT_MESSAGE("Value of StripData wasn't changed", bStripData);
+}
+
+void DatabaseRange::testAutoFilter()
+{
+ uno::Reference<beans::XPropertySet> xDatabaseRange(init("DataArea"), UNO_QUERY_THROW);
+
+ static constexpr OUString propName(u"AutoFilter"_ustr);
+
+ bool bAutoFilter = true;
+ CPPUNIT_ASSERT(xDatabaseRange->getPropertyValue(propName) >>= bAutoFilter);
+ CPPUNIT_ASSERT_MESSAGE("Default AutoFilter already changed", !bAutoFilter);
+
+ uno::Any aNewAutoFilter;
+ aNewAutoFilter <<= true;
+ xDatabaseRange->setPropertyValue(propName, aNewAutoFilter);
+ CPPUNIT_ASSERT(xDatabaseRange->getPropertyValue(propName) >>= bAutoFilter);
+ CPPUNIT_ASSERT_MESSAGE("Value of AutoFilter wasn't changed", bAutoFilter);
+}
+
+void DatabaseRange::testUseFilterCriteriaSource()
+{
+ uno::Reference<beans::XPropertySet> xDatabaseRange(init("DataArea"), UNO_QUERY_THROW);
+
+ static constexpr OUString propName(u"UseFilterCriteriaSource"_ustr);
+
+ bool bUseFilterCriteriaSource = true;
+ CPPUNIT_ASSERT(xDatabaseRange->getPropertyValue(propName) >>= bUseFilterCriteriaSource);
+ CPPUNIT_ASSERT_MESSAGE("Default UseFilterCriteriaSource already changed",
+ !bUseFilterCriteriaSource);
+
+ uno::Any aNewUseFilterCriteriaSource;
+ aNewUseFilterCriteriaSource <<= true;
+ xDatabaseRange->setPropertyValue(propName, aNewUseFilterCriteriaSource);
+ CPPUNIT_ASSERT(xDatabaseRange->getPropertyValue(propName) >>= bUseFilterCriteriaSource);
+ CPPUNIT_ASSERT_MESSAGE("Value of UseFilterCriteriaSource wasn't changed",
+ bUseFilterCriteriaSource);
+}
+
+void DatabaseRange::testFilterCriteriaSource()
+{
+ uno::Reference<beans::XPropertySet> xDatabaseRange(init("DataArea"), UNO_QUERY_THROW);
+
+ static constexpr OUString propName(u"FilterCriteriaSource"_ustr);
+
+ table::CellRangeAddress cellRangeAddress;
+ CPPUNIT_ASSERT(xDatabaseRange->getPropertyValue(propName) >>= cellRangeAddress);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Default RefreshPeriod already changed",
+ table::CellRangeAddress(0, 0, 0, 0, 0), cellRangeAddress);
+
+ uno::Any aFilterCriteriaSource;
+ aFilterCriteriaSource <<= table::CellRangeAddress(1, 1, 1, 1, 1);
+ xDatabaseRange->setPropertyValue(propName, aFilterCriteriaSource);
+ CPPUNIT_ASSERT(xDatabaseRange->getPropertyValue(propName) >>= cellRangeAddress);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Value of FilterCriteriaSource wasn't changed",
+ table::CellRangeAddress(1, 1, 1, 1, 1), cellRangeAddress);
+}
+
+void DatabaseRange::testRefreshPeriod()
+{
+ uno::Reference<beans::XPropertySet> xDatabaseRange(init("DataArea"), UNO_QUERY_THROW);
+
+ static constexpr OUString propName(u"RefreshPeriod"_ustr);
+
+ sal_Int32 aRefreshPeriod = 1;
+ CPPUNIT_ASSERT(xDatabaseRange->getPropertyValue(propName) >>= aRefreshPeriod);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Default RefreshPeriod already changed", sal_Int32(0),
+ aRefreshPeriod);
+
+ uno::Any aNewRefreshPeriod;
+ aNewRefreshPeriod <<= static_cast<sal_Int32>(42);
+ xDatabaseRange->setPropertyValue(propName, aNewRefreshPeriod);
+ CPPUNIT_ASSERT(xDatabaseRange->getPropertyValue(propName) >>= aRefreshPeriod);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Value of RefreshPeriod wasn't changed", sal_Int32(42),
+ aRefreshPeriod);
+}
+
+void DatabaseRange::testFromSelection()
+{
+ uno::Reference<beans::XPropertySet> xDatabaseRange(init("DataArea"), UNO_QUERY_THROW);
+
+ static constexpr OUString propName(u"FromSelection"_ustr);
+
+ bool bFromSelection = true;
+ CPPUNIT_ASSERT(xDatabaseRange->getPropertyValue(propName) >>= bFromSelection);
+ CPPUNIT_ASSERT_MESSAGE("Default FromSelection already changed", !bFromSelection);
+
+ uno::Any aNewFromSelection;
+ aNewFromSelection <<= true;
+ xDatabaseRange->setPropertyValue(propName, aNewFromSelection);
+ CPPUNIT_ASSERT(xDatabaseRange->getPropertyValue(propName) >>= bFromSelection);
+ CPPUNIT_ASSERT_MESSAGE("Value of FromSelection wasn't changed", bFromSelection);
+}
+
+void DatabaseRange::testTokenIndex()
+{
+ uno::Reference<beans::XPropertySet> xDatabaseRange(init("DataArea"), UNO_QUERY_THROW);
+
+ static constexpr OUString propName(u"TokenIndex"_ustr);
+
+ sal_Int32 aTokenIndex = 0;
+ CPPUNIT_ASSERT(xDatabaseRange->getPropertyValue(propName) >>= aTokenIndex);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Default TotalIndex already changed", sal_Int32(1), aTokenIndex);
+
+ uno::Any aNewTokenIndex;
+ aNewTokenIndex <<= static_cast<sal_Int32>(42);
+ xDatabaseRange->setPropertyValue(propName, aNewTokenIndex);
+ CPPUNIT_ASSERT(xDatabaseRange->getPropertyValue(propName) >>= aTokenIndex);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Value of TotalIndex was changed", sal_Int32(1), aTokenIndex);
+}
+
+void DatabaseRange::testTotalsRow()
+{
+ uno::Reference<beans::XPropertySet> xDatabaseRange(init("DataArea"), UNO_QUERY_THROW);
+
+ static constexpr OUString propName(u"TotalsRow"_ustr);
+
+ bool bTotalsRow = true;
+ CPPUNIT_ASSERT(xDatabaseRange->getPropertyValue(propName) >>= bTotalsRow);
+ CPPUNIT_ASSERT_MESSAGE("Default TotalsRow already changed", !bTotalsRow);
+
+ uno::Any aNewTotalsRow;
+ aNewTotalsRow <<= true;
+ xDatabaseRange->setPropertyValue(propName, aNewTotalsRow);
+ CPPUNIT_ASSERT(xDatabaseRange->getPropertyValue(propName) >>= bTotalsRow);
+ CPPUNIT_ASSERT_MESSAGE("Value of TotalsRow wasn't changed", bTotalsRow);
+}
+
+void DatabaseRange::testContainsHeader()
+{
+ uno::Reference<beans::XPropertySet> xDatabaseRange(init("DataArea"), UNO_QUERY_THROW);
+
+ static constexpr OUString propName(u"ContainsHeader"_ustr);
+
+ bool bContainsHeader = false;
+ CPPUNIT_ASSERT(xDatabaseRange->getPropertyValue(propName) >>= bContainsHeader);
+ CPPUNIT_ASSERT_MESSAGE("Default ContainsHeader already changed", bContainsHeader);
+
+ uno::Any aNewContainsHeader;
+ aNewContainsHeader <<= false;
+ xDatabaseRange->setPropertyValue(propName, aNewContainsHeader);
+ CPPUNIT_ASSERT(xDatabaseRange->getPropertyValue(propName) >>= bContainsHeader);
+ CPPUNIT_ASSERT_MESSAGE("Value of ContainsHeader wasn't changed", !bContainsHeader);
+}
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/test/source/sheet/datapilotfield.cxx b/test/source/sheet/datapilotfield.cxx
new file mode 100644
index 0000000000..020f33680d
--- /dev/null
+++ b/test/source/sheet/datapilotfield.cxx
@@ -0,0 +1,189 @@
+/* -*- 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 <test/sheet/datapilotfield.hxx>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/sheet/DataPilotFieldSortInfo.hpp>
+#include <com/sun/star/sheet/DataPilotFieldSortMode.hpp>
+#include <com/sun/star/sheet/DataPilotFieldReferenceItemType.hpp>
+#include <com/sun/star/sheet/DataPilotFieldLayoutMode.hpp>
+#include <com/sun/star/sheet/DataPilotFieldLayoutInfo.hpp>
+#include <com/sun/star/sheet/DataPilotFieldReference.hpp>
+#include <com/sun/star/sheet/DataPilotFieldAutoShowInfo.hpp>
+
+#include <rtl/ustring.hxx>
+#include <cppunit/TestAssert.h>
+#include <iostream>
+
+using namespace css;
+using namespace css::uno;
+
+namespace apitest {
+
+void DataPilotField::testSortInfo()
+{
+ uno::Reference< beans::XPropertySet> xPropSet(init(),UNO_QUERY_THROW);
+ sheet::DataPilotFieldSortInfo aSortInfoValue;
+ OUString aSortInfo("SortInfo");
+ aSortInfoValue.Field = "Col1";
+ aSortInfoValue.IsAscending = false;
+ aSortInfoValue.Mode = sheet::DataPilotFieldSortMode::MANUAL;
+ uno::Any aValue;
+ aValue <<= aSortInfoValue;
+ xPropSet->setPropertyValue(aSortInfo, aValue);
+
+ sheet::DataPilotFieldSortInfo aNewSortInfoValue;
+ aValue = xPropSet->getPropertyValue(aSortInfo);
+ CPPUNIT_ASSERT( aValue >>= aNewSortInfoValue );
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("set value should be the same as got value", aSortInfoValue.Field, aNewSortInfoValue.Field);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("set value should be the same as got value", aSortInfoValue.Mode, aNewSortInfoValue.Mode);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("set value should be the same as got value", aSortInfoValue.IsAscending, aNewSortInfoValue.IsAscending);
+
+ //setting HasSortInfo only makes sense for false, for true the uno implementation does nothing
+ bool bHasSortInfo(false);
+ OUString aHasSortInfo("HasSortInfo");
+ aValue = xPropSet->getPropertyValue(aHasSortInfo);
+ CPPUNIT_ASSERT( aValue >>= bHasSortInfo );
+ CPPUNIT_ASSERT_MESSAGE("should have sort info", bHasSortInfo);
+
+ bHasSortInfo = false;
+ aValue <<= bHasSortInfo;
+ xPropSet->setPropertyValue(aHasSortInfo, aValue);
+
+ aValue = xPropSet->getPropertyValue(aHasSortInfo);
+ CPPUNIT_ASSERT( aValue >>= bHasSortInfo );
+ CPPUNIT_ASSERT_MESSAGE("should have no sort info", !bHasSortInfo);
+}
+
+void DataPilotField::testLayoutInfo()
+{
+ uno::Reference< beans::XPropertySet > xPropSet(init(),UNO_QUERY_THROW);
+ sheet::DataPilotFieldLayoutInfo aLayoutInfoValue;
+ OUString aLayoutInfo("LayoutInfo");
+ aLayoutInfoValue.AddEmptyLines = false;
+ aLayoutInfoValue.LayoutMode = sheet::DataPilotFieldLayoutMode::OUTLINE_SUBTOTALS_BOTTOM;
+ uno::Any aValue;
+ aValue <<= aLayoutInfoValue;
+ xPropSet->setPropertyValue(aLayoutInfo, aValue);
+
+ sheet::DataPilotFieldLayoutInfo aNewLayoutInfoValue;
+ aValue = xPropSet->getPropertyValue(aLayoutInfo);
+ CPPUNIT_ASSERT( aValue >>= aNewLayoutInfoValue );
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("set value should be the same as the got value", aLayoutInfoValue.LayoutMode, aNewLayoutInfoValue.LayoutMode);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("set value should be the same as the got value", aLayoutInfoValue.AddEmptyLines, aNewLayoutInfoValue.AddEmptyLines);
+
+ //setting HasLayoutInfo only makes sense for false, tor true the uno implementation does nothing
+ bool bHasLayoutInfo(false);
+ OUString aHasLayoutInfo("HasLayoutInfo");
+ aValue = xPropSet->getPropertyValue(aHasLayoutInfo);
+ CPPUNIT_ASSERT( aValue >>= bHasLayoutInfo );
+ CPPUNIT_ASSERT_MESSAGE("should have layout information", bHasLayoutInfo);
+
+ bHasLayoutInfo = false;
+ aValue <<= bHasLayoutInfo;
+ xPropSet->setPropertyValue(aHasLayoutInfo, aValue);
+
+ aValue = xPropSet->getPropertyValue(aHasLayoutInfo);
+ CPPUNIT_ASSERT( aValue >>= bHasLayoutInfo );
+ CPPUNIT_ASSERT_MESSAGE("should have no longer sort information", !bHasLayoutInfo);
+}
+
+void DataPilotField::testAutoShowInfo()
+{
+ uno::Reference< beans::XPropertySet > xPropSet(init(),UNO_QUERY_THROW);
+ sheet::DataPilotFieldAutoShowInfo aAutoShowInfoValue;
+ aAutoShowInfoValue.DataField = "Col1";
+ aAutoShowInfoValue.IsEnabled = true;
+ OUString aAutoShowInfo("AutoShowInfo");
+ uno::Any aValue;
+ aValue <<= aAutoShowInfoValue;
+ xPropSet->setPropertyValue(aAutoShowInfo, aValue);
+
+ sheet::DataPilotFieldAutoShowInfo aNewAutoShowInfoValue;
+ aValue = xPropSet->getPropertyValue(aAutoShowInfo);
+ CPPUNIT_ASSERT( aValue >>= aNewAutoShowInfoValue );
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("set value should be the same as the got value", aAutoShowInfoValue.DataField, aNewAutoShowInfoValue.DataField);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("set value should be the same as the got value", aAutoShowInfoValue.IsEnabled, aNewAutoShowInfoValue.IsEnabled);
+
+ //setting HasLayoutInfo only makes sense for false, tor true the uno implementation does nothing
+ bool bHasAutoShowInfo(false);
+ OUString aHasAutoShowInfo("HasAutoShowInfo");
+ aValue = xPropSet->getPropertyValue(aHasAutoShowInfo);
+ CPPUNIT_ASSERT( aValue >>= bHasAutoShowInfo );
+ CPPUNIT_ASSERT_MESSAGE("should have AutoShow information", bHasAutoShowInfo);
+
+ bHasAutoShowInfo = false;
+ aValue <<= bHasAutoShowInfo;
+ xPropSet->setPropertyValue(aHasAutoShowInfo, aValue);
+
+ aValue = xPropSet->getPropertyValue(aHasAutoShowInfo);
+ CPPUNIT_ASSERT( aValue >>= bHasAutoShowInfo );
+ CPPUNIT_ASSERT_MESSAGE("should have no longer AutoShow information", !bHasAutoShowInfo);
+}
+
+void DataPilotField::testReference()
+{
+ uno::Reference< beans::XPropertySet > xPropSet(init(),UNO_QUERY_THROW);
+ sheet::DataPilotFieldReference aReferenceValue;
+ aReferenceValue.ReferenceField = "Col1";
+ aReferenceValue.ReferenceItemType = sheet::DataPilotFieldReferenceItemType::NAMED;
+ OUString aReference("Reference");
+ uno::Any aValue;
+ aValue <<= aReferenceValue;
+ xPropSet->setPropertyValue(aReference, aValue);
+
+ sheet::DataPilotFieldReference aNewReferenceValue;
+ aValue = xPropSet->getPropertyValue(aReference);
+ CPPUNIT_ASSERT( aValue >>= aNewReferenceValue );
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("set value should be the same as the got value", aReferenceValue.ReferenceField, aNewReferenceValue.ReferenceField);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("set value should be the same as the got value", aReferenceValue.ReferenceItemType, aNewReferenceValue.ReferenceItemType);
+
+ //setting HasReference only makes sense for false, tor true the uno implementation does nothing
+ bool bHasReference(false);
+ OUString aHasReference("HasReference");
+ aValue = xPropSet->getPropertyValue(aHasReference);
+ CPPUNIT_ASSERT( aValue >>= bHasReference );
+ CPPUNIT_ASSERT_MESSAGE("should have Reference information", bHasReference);
+
+ bHasReference = false;
+ aValue <<= bHasReference;
+ xPropSet->setPropertyValue(aHasReference, aValue);
+
+ aValue = xPropSet->getPropertyValue(aHasReference);
+ CPPUNIT_ASSERT( aValue >>= bHasReference );
+ CPPUNIT_ASSERT_MESSAGE("should have no longer reference information", !bHasReference);
+}
+
+void DataPilotField::testIsGroupField()
+{
+ uno::Reference< beans::XPropertySet > xPropSet(init(),UNO_QUERY_THROW);
+ uno::Any aValue;
+ OUString aIsGroupField("IsGroupField");
+ bool bIsGroupField(false);
+
+ aValue = xPropSet->getPropertyValue(aIsGroupField);
+ CPPUNIT_ASSERT( aValue >>= bIsGroupField);
+ //only setting to false is supported
+ if (bIsGroupField)
+ {
+ bIsGroupField = false;
+ aValue <<= bIsGroupField;
+
+ xPropSet->setPropertyValue(aIsGroupField, aValue);
+ aValue = xPropSet->getPropertyValue(aIsGroupField);
+ CPPUNIT_ASSERT(aValue >>= bIsGroupField);
+ CPPUNIT_ASSERT_MESSAGE("setting IsGroupField is supported and should have happened", !bIsGroupField);
+ }
+ else
+ std::cout << "Could not test IsGroupField" << std::endl;
+}
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/test/source/sheet/datapilotitem.cxx b/test/source/sheet/datapilotitem.cxx
new file mode 100644
index 0000000000..7433097035
--- /dev/null
+++ b/test/source/sheet/datapilotitem.cxx
@@ -0,0 +1,64 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * 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 <test/sheet/datapilotitem.hxx>
+
+#include <com/sun/star/beans/XPropertySet.hpp>
+
+#include <com/sun/star/uno/Reference.hxx>
+
+#include <cppunit/TestAssert.h>
+
+using namespace com::sun::star;
+using namespace com::sun::star::uno;
+
+namespace apitest
+{
+void DataPilotItem::testProperties()
+{
+ uno::Reference<beans::XPropertySet> xItem(init(), UNO_QUERY_THROW);
+
+ static constexpr OUString propNameIS(u"IsHidden"_ustr);
+
+ bool bIsHidden = true;
+ CPPUNIT_ASSERT(xItem->getPropertyValue(propNameIS) >>= bIsHidden);
+ CPPUNIT_ASSERT_MESSAGE("Default IsHidden already changed", !bIsHidden);
+
+ uno::Any aNewIsHidden;
+ aNewIsHidden <<= false;
+ xItem->setPropertyValue(propNameIS, aNewIsHidden);
+ CPPUNIT_ASSERT(xItem->getPropertyValue(propNameIS) >>= bIsHidden);
+ CPPUNIT_ASSERT_MESSAGE("Value of IsHidden wasn't changed", !bIsHidden);
+
+ static constexpr OUString propNameSD(u"ShowDetail"_ustr);
+
+ bool bShowDetail = false;
+ CPPUNIT_ASSERT(xItem->getPropertyValue(propNameSD) >>= bShowDetail);
+ CPPUNIT_ASSERT_MESSAGE("Default ShowDetail already changed", bShowDetail);
+
+ uno::Any aNewShowDetail;
+ aNewShowDetail <<= true;
+ xItem->setPropertyValue(propNameSD, aNewShowDetail);
+ CPPUNIT_ASSERT(xItem->getPropertyValue(propNameSD) >>= bShowDetail);
+ CPPUNIT_ASSERT_MESSAGE("Value of ShowDetail wasn't changed", bShowDetail);
+
+ sal_Int32 nPosition = 42;
+ CPPUNIT_ASSERT(xItem->getPropertyValue("Position") >>= nPosition);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Default Position already changed", sal_Int32(0), nPosition);
+
+ // FIXME: This throws somehow a com.sun.star.lang.IllegalArgumentException
+ //uno::Any aNewPosition;
+ //aNewPosition <<= static_cast<sal_Int32>(42);
+ //xItem->setPropertyValue(propNameP, aNewPosition);
+ //CPPUNIT_ASSERT(xItem->getPropertyValue(propNameP) >>= nPosition);
+ //CPPUNIT_ASSERT_EQUAL_MESSAGE("Value of Position wasn't changed", sal_Int32(42), nPosition);
+}
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/test/source/sheet/documentsettings.cxx b/test/source/sheet/documentsettings.cxx
new file mode 100644
index 0000000000..644b7273c8
--- /dev/null
+++ b/test/source/sheet/documentsettings.cxx
@@ -0,0 +1,183 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * 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 <test/sheet/documentsettings.hxx>
+
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/uno/Any.hxx>
+#include <com/sun/star/uno/Reference.hxx>
+
+#include <cppunit/TestAssert.h>
+
+using namespace com::sun::star;
+using namespace com::sun::star::uno;
+
+namespace apitest
+{
+void DocumentSettings::testDocumentSettingsProperties()
+{
+ uno::Reference<beans::XPropertySet> xDocumentSettings(init(), UNO_QUERY_THROW);
+ OUString propName;
+ uno::Any aNewValue;
+
+ propName = "ShowZeroValues";
+ bool aShowZeroValues = false;
+ CPPUNIT_ASSERT(xDocumentSettings->getPropertyValue(propName) >>= aShowZeroValues);
+ CPPUNIT_ASSERT_MESSAGE("Unable to get PropertyValue ShowZeroValues", aShowZeroValues);
+
+ aNewValue <<= false;
+ xDocumentSettings->setPropertyValue(propName, aNewValue);
+ CPPUNIT_ASSERT(xDocumentSettings->getPropertyValue(propName) >>= aShowZeroValues);
+ CPPUNIT_ASSERT_MESSAGE("Unable to set PropertyValue ShowZeroValues", !aShowZeroValues);
+
+ propName = "ShowNotes";
+ bool aShowNotes = false;
+ CPPUNIT_ASSERT(xDocumentSettings->getPropertyValue(propName) >>= aShowNotes);
+ CPPUNIT_ASSERT_MESSAGE("Unable to get PropertyValue ShowNotes", aShowNotes);
+
+ aNewValue <<= false;
+ xDocumentSettings->setPropertyValue(propName, aNewValue);
+ CPPUNIT_ASSERT(xDocumentSettings->getPropertyValue(propName) >>= aShowNotes);
+ CPPUNIT_ASSERT_MESSAGE("Unable to set PropertyValue ShowNotes", !aShowNotes);
+
+ propName = "ShowGrid";
+ bool aShowGrid = false;
+ CPPUNIT_ASSERT(xDocumentSettings->getPropertyValue(propName) >>= aShowGrid);
+ CPPUNIT_ASSERT_MESSAGE("Unable to get PropertyValue ShowGrid", aShowGrid);
+
+ aNewValue <<= false;
+ xDocumentSettings->setPropertyValue(propName, aNewValue);
+ CPPUNIT_ASSERT(xDocumentSettings->getPropertyValue(propName) >>= aShowGrid);
+ CPPUNIT_ASSERT_MESSAGE("Unable to set PropertyValue ShowGrid", !aShowGrid);
+
+ propName = "ShowPageBreaks";
+ bool aShowPageBreaks = false;
+ CPPUNIT_ASSERT(xDocumentSettings->getPropertyValue(propName) >>= aShowPageBreaks);
+ CPPUNIT_ASSERT_MESSAGE("Unable to get PropertyValue ShowPageBreaks", aShowPageBreaks);
+
+ aNewValue <<= false;
+ xDocumentSettings->setPropertyValue(propName, aNewValue);
+ CPPUNIT_ASSERT(xDocumentSettings->getPropertyValue(propName) >>= aShowPageBreaks);
+ CPPUNIT_ASSERT_MESSAGE("Unable to set PropertyValue ShowPageBreaks", !aShowPageBreaks);
+
+ propName = "HasColumnRowHeaders";
+ bool aHasColumnRowHeaders = false;
+ CPPUNIT_ASSERT(xDocumentSettings->getPropertyValue(propName) >>= aHasColumnRowHeaders);
+ CPPUNIT_ASSERT_MESSAGE("Unable to get PropertyValue HasColumnRowHeaders", aHasColumnRowHeaders);
+
+ aNewValue <<= false;
+ xDocumentSettings->setPropertyValue(propName, aNewValue);
+ CPPUNIT_ASSERT(xDocumentSettings->getPropertyValue(propName) >>= aHasColumnRowHeaders);
+ CPPUNIT_ASSERT_MESSAGE("Unable to set PropertyValue HasColumnRowHeaders",
+ !aHasColumnRowHeaders);
+
+ propName = "HasSheetTabs";
+ bool aHasSheetTabs = false;
+ CPPUNIT_ASSERT(xDocumentSettings->getPropertyValue(propName) >>= aHasSheetTabs);
+ CPPUNIT_ASSERT_MESSAGE("Unable to get PropertyValue HasSheetTabs", aHasSheetTabs);
+
+ aNewValue <<= false;
+ xDocumentSettings->setPropertyValue(propName, aNewValue);
+ CPPUNIT_ASSERT(xDocumentSettings->getPropertyValue(propName) >>= aHasSheetTabs);
+ CPPUNIT_ASSERT_MESSAGE("Unable to set PropertyValue HasSheetTabs", !aHasSheetTabs);
+
+ propName = "IsOutlineSymbolsSet";
+ bool aIsOutlineSymbolsSet = false;
+ CPPUNIT_ASSERT(xDocumentSettings->getPropertyValue(propName) >>= aIsOutlineSymbolsSet);
+ CPPUNIT_ASSERT_MESSAGE("Unable to get PropertyValue IsOutlineSymbolsSet", aIsOutlineSymbolsSet);
+
+ aNewValue <<= false;
+ xDocumentSettings->setPropertyValue(propName, aNewValue);
+ CPPUNIT_ASSERT(xDocumentSettings->getPropertyValue(propName) >>= aIsOutlineSymbolsSet);
+ CPPUNIT_ASSERT_MESSAGE("Unable to set PropertyValue IsOutlineSymbolsSet",
+ !aIsOutlineSymbolsSet);
+
+ propName = "IsSnapToRaster";
+ bool aIsSnapToRaster = true;
+ CPPUNIT_ASSERT(xDocumentSettings->getPropertyValue(propName) >>= aIsSnapToRaster);
+ CPPUNIT_ASSERT_MESSAGE("Unable to get PropertyValue IsSnapToRaster", !aIsSnapToRaster);
+
+ aNewValue <<= true;
+ xDocumentSettings->setPropertyValue(propName, aNewValue);
+ CPPUNIT_ASSERT(xDocumentSettings->getPropertyValue(propName) >>= aIsSnapToRaster);
+ CPPUNIT_ASSERT_MESSAGE("Unable to set PropertyValue IsSnapToRaster", aIsSnapToRaster);
+
+ propName = "RasterIsVisible";
+ bool aRasterIsVisible = true;
+ CPPUNIT_ASSERT(xDocumentSettings->getPropertyValue(propName) >>= aRasterIsVisible);
+ CPPUNIT_ASSERT_MESSAGE("Unable to get PropertyValue RasterIsVisible", !aRasterIsVisible);
+
+ aNewValue <<= true;
+ xDocumentSettings->setPropertyValue(propName, aNewValue);
+ CPPUNIT_ASSERT(xDocumentSettings->getPropertyValue(propName) >>= aRasterIsVisible);
+ CPPUNIT_ASSERT_MESSAGE("Unable to set PropertyValue RasterIsVisible", aRasterIsVisible);
+
+ propName = "RasterResolutionX";
+ sal_Int32 aRasterResolutionX = 0;
+ CPPUNIT_ASSERT(xDocumentSettings->getPropertyValue(propName) >>= aRasterResolutionX);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Unable to get PropertyValue RasterResolutionX", sal_Int32(1270),
+ aRasterResolutionX);
+
+ aNewValue <<= sal_Int32(42);
+ xDocumentSettings->setPropertyValue(propName, aNewValue);
+ CPPUNIT_ASSERT(xDocumentSettings->getPropertyValue(propName) >>= aRasterResolutionX);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Unable to set PropertyValue RasterResolutionX", sal_Int32(42),
+ aRasterResolutionX);
+
+ propName = "RasterResolutionY";
+ sal_Int32 aRasterResolutionY = 0;
+ CPPUNIT_ASSERT(xDocumentSettings->getPropertyValue(propName) >>= aRasterResolutionY);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Unable to get PropertyValue RasterResolutionY", sal_Int32(1270),
+ aRasterResolutionY);
+
+ aNewValue <<= sal_Int32(42);
+ xDocumentSettings->setPropertyValue(propName, aNewValue);
+ CPPUNIT_ASSERT(xDocumentSettings->getPropertyValue(propName) >>= aRasterResolutionY);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Unable to set PropertyValue RasterResolutionY", sal_Int32(42),
+ aRasterResolutionY);
+
+ propName = "RasterSubdivisionX";
+ sal_Int32 aRasterSubdivisionX = 0;
+ CPPUNIT_ASSERT(xDocumentSettings->getPropertyValue(propName) >>= aRasterSubdivisionX);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Unable to get PropertyValue RasterSubdivisionX", sal_Int32(1),
+ aRasterSubdivisionX);
+
+ aNewValue <<= sal_Int32(42);
+ xDocumentSettings->setPropertyValue(propName, aNewValue);
+ CPPUNIT_ASSERT(xDocumentSettings->getPropertyValue(propName) >>= aRasterSubdivisionX);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Unable to set PropertyValue RasterSubdivisionX", sal_Int32(42),
+ aRasterSubdivisionX);
+
+ propName = "RasterSubdivisionY";
+ sal_Int32 aRasterSubdivisionY = 0;
+ CPPUNIT_ASSERT(xDocumentSettings->getPropertyValue(propName) >>= aRasterSubdivisionY);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Unable to get PropertyValue RasterSubdivisionY", sal_Int32(1),
+ aRasterSubdivisionY);
+
+ aNewValue <<= sal_Int32(42);
+ xDocumentSettings->setPropertyValue(propName, aNewValue);
+ CPPUNIT_ASSERT(xDocumentSettings->getPropertyValue(propName) >>= aRasterSubdivisionY);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Unable to set PropertyValue RasterSubdivisionY", sal_Int32(42),
+ aRasterSubdivisionY);
+
+ propName = "IsRasterAxisSynchronized";
+ bool aIsRasterAxisSynchronized = false;
+ CPPUNIT_ASSERT(xDocumentSettings->getPropertyValue(propName) >>= aIsRasterAxisSynchronized);
+ CPPUNIT_ASSERT_MESSAGE("Unable to get PropertyValue IsRasterAxisSynchronized",
+ aIsRasterAxisSynchronized);
+
+ aNewValue <<= false;
+ xDocumentSettings->setPropertyValue(propName, aNewValue);
+ CPPUNIT_ASSERT(xDocumentSettings->getPropertyValue(propName) >>= aIsRasterAxisSynchronized);
+ CPPUNIT_ASSERT_MESSAGE("Unable to set PropertyValue IsRasterAxisSynchronized",
+ !aIsRasterAxisSynchronized);
+}
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/test/source/sheet/functiondescription.cxx b/test/source/sheet/functiondescription.cxx
new file mode 100644
index 0000000000..e90a138e82
--- /dev/null
+++ b/test/source/sheet/functiondescription.cxx
@@ -0,0 +1,85 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * 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 <vector>
+
+#include <test/sheet/functiondescription.hxx>
+
+#include <com/sun/star/beans/PropertyValue.hpp>
+#include <com/sun/star/sheet/FunctionArgument.hpp>
+
+#include <cppunit/TestAssert.h>
+
+using namespace com::sun::star;
+using namespace com::sun::star::uno;
+
+namespace apitest
+{
+void FunctionDescription::testFunctionDescriptionProperties()
+{
+ const uno::Sequence<beans::PropertyValue> aFunctionDescription(init());
+
+ std::vector<OUString> names;
+ // Only test the get/read operation of the values, because set/write operation doesn't
+ // make any sense. It doesn't trigger any changes.
+ // See discussion: nabble.documentfoundation.org/Testing-UNO-API-service-properties-td4236286.html.
+ for (const auto& value : aFunctionDescription)
+ {
+ if (value.Name == "Id")
+ {
+ names.push_back(value.Name);
+ sal_Int32 nValue = 0;
+ CPPUNIT_ASSERT(value.Value >>= nValue);
+ }
+ else if (value.Name == "Category")
+ {
+ names.push_back(value.Name);
+ sal_Int32 nValue = 0;
+ CPPUNIT_ASSERT(value.Value >>= nValue);
+ }
+ else if (value.Name == "Name")
+ {
+ names.push_back(value.Name);
+ OUString sValue;
+ CPPUNIT_ASSERT(value.Value >>= sValue);
+ }
+ else if (value.Name == "Description")
+ {
+ names.push_back(value.Name);
+ OUString sValue;
+ CPPUNIT_ASSERT(value.Value >>= sValue);
+ }
+ else if (value.Name == "Arguments")
+ {
+ names.push_back(value.Name);
+ uno::Sequence<sheet::FunctionArgument> sArguments;
+ CPPUNIT_ASSERT(value.Value >>= sArguments);
+ }
+ else
+ {
+ OString aMsg = "Unsupported PropertyValue: "
+ + OUStringToOString(value.Name, RTL_TEXTENCODING_UTF8);
+ CPPUNIT_FAIL(aMsg.getStr());
+ }
+ }
+
+ CPPUNIT_ASSERT_MESSAGE("Property Id not found",
+ std::count(std::begin(names), std::end(names), "Id"));
+ CPPUNIT_ASSERT_MESSAGE("Property Category not found",
+ std::count(std::begin(names), std::end(names), "Category"));
+ CPPUNIT_ASSERT_MESSAGE("Property Name not found",
+ std::count(std::begin(names), std::end(names), "Name"));
+ CPPUNIT_ASSERT_MESSAGE("Property Description not found",
+ std::count(std::begin(names), std::end(names), "Description"));
+ CPPUNIT_ASSERT_MESSAGE("Property Arguments not found",
+ std::count(std::begin(names), std::end(names), "Arguments"));
+}
+} // namespace apitest
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/test/source/sheet/globalsheetsettings.cxx b/test/source/sheet/globalsheetsettings.cxx
new file mode 100644
index 0000000000..40d01fe45d
--- /dev/null
+++ b/test/source/sheet/globalsheetsettings.cxx
@@ -0,0 +1,149 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * 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 <test/sheet/globalsheetsettings.hxx>
+
+#include <com/sun/star/beans/NamedValue.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/configuration/theDefaultProvider.hpp>
+#include <com/sun/star/uno/Any.hxx>
+#include <com/sun/star/uno/Reference.hxx>
+#include <com/sun/star/util/XChangesBatch.hpp>
+
+#include <comphelper/processfactory.hxx>
+
+#include <cppunit/TestAssert.h>
+
+using namespace com::sun::star;
+using namespace com::sun::star::uno;
+
+namespace apitest
+{
+void GlobalSheetSettings::testGlobalSheetSettingsProperties()
+{
+ uno::Reference<beans::XPropertySet> xGlobalSheetSettings(init(), UNO_QUERY_THROW);
+ auto configProvider
+ = css::configuration::theDefaultProvider::get(comphelper::getProcessComponentContext());
+
+ auto DoCheck = [&xGlobalSheetSettings, &configProvider](
+ const OUString& propName, const auto& origValue, const auto& newValue,
+ const OUString& regNodeName, const OUString& regValueName) {
+ OString sMessage = "PropertyValue " + propName.toUtf8();
+ css::uno::Any aOrigValue(origValue), aNewValue(newValue);
+
+ css::uno::Sequence<css::uno::Any> args{ css::uno::Any(
+ css::beans::NamedValue("nodepath", css::uno::Any(regNodeName))) };
+ css::uno::Reference<beans::XPropertySet> xRegNodeRO(
+ configProvider->createInstanceWithArguments(
+ "com.sun.star.configuration.ConfigurationAccess", args),
+ css::uno::UNO_QUERY_THROW);
+ css::uno::Reference<beans::XPropertySet> xRegNodeRW(
+ configProvider->createInstanceWithArguments(
+ "com.sun.star.configuration.ConfigurationUpdateAccess", args),
+ css::uno::UNO_QUERY_THROW);
+ css::uno::Reference<css::util::XChangesBatch> xBatch(xRegNodeRW, css::uno::UNO_QUERY_THROW);
+
+ // 1. Check initial value
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(sMessage.getStr(), aOrigValue,
+ xGlobalSheetSettings->getPropertyValue(propName));
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(sMessage.getStr(), aOrigValue,
+ xRegNodeRO->getPropertyValue(regValueName));
+
+ // 2. Check setting the value through GlobalSheetSettings
+ xGlobalSheetSettings->setPropertyValue(propName, aNewValue);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(sMessage.getStr(), aNewValue,
+ xGlobalSheetSettings->getPropertyValue(propName));
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(sMessage.getStr(), aNewValue,
+ xRegNodeRO->getPropertyValue(regValueName));
+
+ // 3. Check setting the value through ConfigurationUpdateAccess
+ xRegNodeRW->setPropertyValue(regValueName, aOrigValue);
+ xBatch->commitChanges();
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(sMessage.getStr(), aOrigValue,
+ xRegNodeRO->getPropertyValue(regValueName));
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(sMessage.getStr(), aOrigValue,
+ xGlobalSheetSettings->getPropertyValue(propName));
+ };
+
+ OUString node = "/org.openoffice.Office.Calc/Input";
+ DoCheck("MoveSelection", true, false, node, "MoveSelection");
+ DoCheck("MoveDirection", sal_Int16(0), sal_Int16(1), node, "MoveSelectionDirection");
+ DoCheck("EnterEdit", false, true, node, "SwitchToEditMode");
+ DoCheck("ExtendFormat", false, true, node, "ExpandFormatting");
+ DoCheck("RangeFinder", true, false, node, "ShowReference");
+ DoCheck("ExpandReferences", false, true, node, "ExpandReference");
+ DoCheck("MarkHeader", true, false, node, "HighlightSelection");
+ DoCheck("UseTabCol", false, true, node, "UseTabCol");
+ DoCheck("ReplaceCellsWarning", true, false, node, "ReplaceCellsWarning");
+
+ node = "/org.openoffice.Office.Calc/Layout/Other/MeasureUnit";
+ DoCheck("Metric", sal_Int16(8), sal_Int16(1), node, "NonMetric"); // Test uses en-US locale
+
+ node = "/org.openoffice.Office.Calc/Input";
+ DoCheck("DoAutoComplete", true, false, node, "AutoInput");
+
+ node = "/org.openoffice.Office.Calc/Content/Update";
+ DoCheck("LinkUpdateMode", sal_Int16(2), sal_Int16(1), node, "Link");
+
+ node = "/org.openoffice.Office.Calc/Print/";
+ DoCheck("PrintAllSheets", false, true, node + "Other", "AllSheets");
+ DoCheck("PrintEmptyPages", false, true, node + "Page", "EmptyPages");
+
+ OUString propName;
+ uno::Any aNewValue;
+
+ propName = "Scale";
+ sal_Int16 aScale = 42;
+ CPPUNIT_ASSERT(xGlobalSheetSettings->getPropertyValue(propName) >>= aScale);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Unable to get PropertyValue Scale", sal_Int16(100), aScale);
+
+ aNewValue <<= sal_Int16(-1);
+ xGlobalSheetSettings->setPropertyValue(propName, aNewValue);
+ CPPUNIT_ASSERT(xGlobalSheetSettings->getPropertyValue(propName) >>= aScale);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Unable to set PropertyValue Scale", sal_Int16(-1), aScale);
+
+ propName = "StatusBarFunction";
+ sal_Int16 aStatusBarFunction = 42;
+ CPPUNIT_ASSERT(xGlobalSheetSettings->getPropertyValue(propName) >>= aStatusBarFunction);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Unable to get PropertyValue StatusBarFunction", sal_Int16(514),
+ aStatusBarFunction);
+
+ aNewValue <<= sal_Int16(1);
+ xGlobalSheetSettings->setPropertyValue(propName, aNewValue);
+ CPPUNIT_ASSERT(xGlobalSheetSettings->getPropertyValue(propName) >>= aStatusBarFunction);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Unable to set PropertyValue StatusBarFunction", sal_Int16(1),
+ aStatusBarFunction);
+
+ propName = "UserLists";
+ uno::Sequence<OUString> aSeq{
+ "Sun,Mon,Tue,Wed,Thu,Fri,Sat",
+ "Sunday,Monday,Tuesday,Wednesday,Thursday,Friday,Saturday",
+ "Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov,Dec",
+ "January,February,March,April,May,June,July,August,September,October,November,December",
+ "Sunday,Monday,Tuesday,Wednesday,Thursday,Friday,Shabbat",
+ "Nissan,Iyar,Sivan,Tammuz,Av,Elul,Tishri,Heshvan,Kislev,Tevet,Shevat,Adar,Adar B"
+ };
+
+ uno::Sequence<OUString> aUserLists;
+ CPPUNIT_ASSERT(xGlobalSheetSettings->getPropertyValue(propName) >>= aUserLists);
+ for (auto i = 0; i < aUserLists.getLength(); i++)
+ {
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Unable to get PropertyValue UserLists[" + std::to_string(i)
+ + "]",
+ aSeq[i], aUserLists[i]);
+ }
+
+ aNewValue <<= uno::Sequence<OUString>();
+ xGlobalSheetSettings->setPropertyValue(propName, aNewValue);
+ CPPUNIT_ASSERT(xGlobalSheetSettings->getPropertyValue(propName) >>= aUserLists);
+ CPPUNIT_ASSERT_MESSAGE("Unable to set PropertyValue UserLists", !aUserLists.hasElements());
+}
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/test/source/sheet/scenario.cxx b/test/source/sheet/scenario.cxx
new file mode 100644
index 0000000000..dc96e3cc32
--- /dev/null
+++ b/test/source/sheet/scenario.cxx
@@ -0,0 +1,113 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * 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 <test/sheet/scenario.hxx>
+
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/uno/Any.hxx>
+#include <com/sun/star/uno/Reference.hxx>
+
+#include <cppunit/TestAssert.h>
+
+using namespace com::sun::star;
+using namespace com::sun::star::uno;
+
+namespace apitest
+{
+void Scenario::testScenarioProperties()
+{
+ uno::Reference<beans::XPropertySet> xScenario(getScenarioSpreadsheet(), UNO_QUERY_THROW);
+ OUString propName;
+ uno::Any aNewValue;
+
+ propName = "IsActive";
+ bool aIsActive = false;
+ CPPUNIT_ASSERT(xScenario->getPropertyValue(propName) >>= aIsActive);
+ CPPUNIT_ASSERT_MESSAGE("Unable to get property value IsActive", aIsActive);
+
+ aNewValue <<= false;
+ xScenario->setPropertyValue(propName, aNewValue);
+ CPPUNIT_ASSERT(xScenario->getPropertyValue(propName) >>= aIsActive);
+ CPPUNIT_ASSERT_MESSAGE("Unable to set property value IsActive", !aIsActive);
+
+ propName = "BorderColor";
+ sal_Int32 aBorderColor = 0;
+ CPPUNIT_ASSERT(xScenario->getPropertyValue(propName) >>= aBorderColor);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Unable to get property value BorderColor", sal_Int32(12632256),
+ aBorderColor);
+
+ aNewValue <<= sal_Int32(42);
+ xScenario->setPropertyValue(propName, aNewValue);
+ CPPUNIT_ASSERT(xScenario->getPropertyValue(propName) >>= aBorderColor);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Unable to set property value BorderColor", sal_Int32(42),
+ aBorderColor);
+
+ propName = "Protected";
+ bool aProtected = false;
+ CPPUNIT_ASSERT(xScenario->getPropertyValue(propName) >>= aProtected);
+ CPPUNIT_ASSERT_MESSAGE("Unable to get property value Protected", aProtected);
+
+ aNewValue <<= false;
+ xScenario->setPropertyValue(propName, aNewValue);
+ CPPUNIT_ASSERT(xScenario->getPropertyValue(propName) >>= aProtected);
+ CPPUNIT_ASSERT_MESSAGE("Unable to set property value Protected", !aProtected);
+
+ propName = "ShowBorder";
+ bool aShowBorder = false;
+ CPPUNIT_ASSERT(xScenario->getPropertyValue(propName) >>= aShowBorder);
+ CPPUNIT_ASSERT_MESSAGE("Unable to get property value ShowBorder", aShowBorder);
+
+ aNewValue <<= false;
+ xScenario->setPropertyValue(propName, aNewValue);
+ CPPUNIT_ASSERT(xScenario->getPropertyValue(propName) >>= aShowBorder);
+ CPPUNIT_ASSERT_MESSAGE("Unable to set property value ShowBorder", !aShowBorder);
+
+ propName = "PrintBorder";
+ bool aPrintBorder = false;
+ CPPUNIT_ASSERT(xScenario->getPropertyValue(propName) >>= aPrintBorder);
+ CPPUNIT_ASSERT_MESSAGE("Unable to get property value PrintBorder", aPrintBorder);
+
+ aNewValue <<= false;
+ xScenario->setPropertyValue(propName, aNewValue);
+ CPPUNIT_ASSERT(xScenario->getPropertyValue(propName) >>= aPrintBorder);
+ CPPUNIT_ASSERT_MESSAGE("Unable to set property value PrintBorder", !aPrintBorder);
+
+ propName = "CopyBack";
+ bool aCopyBack = false;
+ CPPUNIT_ASSERT(xScenario->getPropertyValue(propName) >>= aCopyBack);
+ CPPUNIT_ASSERT_MESSAGE("Unable to get property value CopyBack", aCopyBack);
+
+ aNewValue <<= false;
+ xScenario->setPropertyValue(propName, aNewValue);
+ CPPUNIT_ASSERT(xScenario->getPropertyValue(propName) >>= aCopyBack);
+ CPPUNIT_ASSERT_MESSAGE("Unable to set property value CopyBack", !aCopyBack);
+
+ propName = "CopyStyles";
+ bool aCopyStyles = true;
+ CPPUNIT_ASSERT(xScenario->getPropertyValue(propName) >>= aCopyStyles);
+ CPPUNIT_ASSERT_MESSAGE("Unable to get property value CopyStyles", !aCopyStyles);
+
+ aNewValue <<= true;
+ xScenario->setPropertyValue(propName, aNewValue);
+ CPPUNIT_ASSERT(xScenario->getPropertyValue(propName) >>= aCopyStyles);
+ CPPUNIT_ASSERT_MESSAGE("Unable to set property value CopyStyles", aCopyStyles);
+
+ propName = "CopyFormulas";
+ bool aCopyFormulas = false;
+ CPPUNIT_ASSERT(xScenario->getPropertyValue(propName) >>= aCopyFormulas);
+ CPPUNIT_ASSERT_MESSAGE("Unable to get property value CopyFormulas", aCopyFormulas);
+
+ aNewValue <<= false;
+ xScenario->setPropertyValue(propName, aNewValue);
+ CPPUNIT_ASSERT(xScenario->getPropertyValue(propName) >>= aCopyFormulas);
+ CPPUNIT_ASSERT_MESSAGE("Unable to set property value CopyFormulas", !aCopyFormulas);
+}
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/test/source/sheet/shape.cxx b/test/source/sheet/shape.cxx
new file mode 100644
index 0000000000..ab2abec6e8
--- /dev/null
+++ b/test/source/sheet/shape.cxx
@@ -0,0 +1,115 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * 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 <test/sheet/shape.hxx>
+
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/sheet/XSpreadsheet.hpp>
+#include <com/sun/star/sheet/XSpreadsheetDocument.hpp>
+#include <com/sun/star/sheet/XSpreadsheets.hpp>
+#include <com/sun/star/table/XCell.hpp>
+#include <com/sun/star/uno/Any.hxx>
+#include <com/sun/star/uno/Reference.hxx>
+#include <com/sun/star/uno/Sequence.hxx>
+
+#include <cppunit/TestAssert.h>
+
+using namespace com::sun::star;
+using namespace com::sun::star::uno;
+
+namespace apitest
+{
+void Shape::testShapePropertiesAnchor()
+{
+ uno::Reference<beans::XPropertySet> xShape(init(), UNO_QUERY_THROW);
+ uno::Any aNewValue;
+
+ uno::Reference<sheet::XSpreadsheetDocument> xDoc(getXSheetDocument(), UNO_QUERY_THROW);
+ uno::Reference<sheet::XSpreadsheets> xSheets(xDoc->getSheets(), UNO_SET_THROW);
+ uno::Sequence<OUString> sheetNames = xSheets->getElementNames();
+ uno::Reference<sheet::XSpreadsheet> xSheet(xSheets->getByName(sheetNames[0]), UNO_QUERY_THROW);
+ uno::Reference<table::XCell> xCell(xSheet->getCellByPosition(0, 0), UNO_SET_THROW);
+
+ // Shape should be anchored to sheet by default
+ uno::Reference<sheet::XSpreadsheet> xSheetGet;
+ CPPUNIT_ASSERT_MESSAGE("Unable to get PropertyValue Anchor (XSpreadsheet)",
+ xShape->getPropertyValue("Anchor") >>= xSheetGet);
+
+ // Anchor the shape to a cell
+ aNewValue <<= xCell;
+ xShape->setPropertyValue("Anchor", aNewValue);
+ uno::Reference<table::XCell> xCellGet;
+ CPPUNIT_ASSERT_MESSAGE("Unable to get PropertyValue Anchor (XCell)",
+ xShape->getPropertyValue("Anchor") >>= xCellGet);
+
+ // Shape should not resize with cell by default
+ bool bIsResizeWithCell = {};
+ CPPUNIT_ASSERT(xShape->getPropertyValue("ResizeWithCell") >>= bIsResizeWithCell);
+ CPPUNIT_ASSERT_MESSAGE("Shape should not resize with the cell", !bIsResizeWithCell);
+
+ xShape->setPropertyValue("ResizeWithCell", uno::Any(true));
+ CPPUNIT_ASSERT(xShape->getPropertyValue("ResizeWithCell") >>= bIsResizeWithCell);
+ CPPUNIT_ASSERT_MESSAGE("Shape should resize with the cell", bIsResizeWithCell);
+
+ // Anchoring to a different cell should keep the "ResizeWithCell" attribute
+ uno::Reference<table::XCell> xCell2(xSheet->getCellByPosition(1, 2), UNO_SET_THROW);
+ aNewValue <<= xCell2;
+ xShape->setPropertyValue("Anchor", aNewValue);
+ CPPUNIT_ASSERT(xShape->getPropertyValue("ResizeWithCell") >>= bIsResizeWithCell);
+ CPPUNIT_ASSERT_MESSAGE("ResizeWithCell should still be set", bIsResizeWithCell);
+
+ // Now anchor to sheet again
+ aNewValue <<= xSheet;
+ xShape->setPropertyValue("Anchor", aNewValue);
+ CPPUNIT_ASSERT(xShape->getPropertyValue("Anchor") >>= xSheetGet);
+ CPPUNIT_ASSERT_MESSAGE("Unable to get PropertyValue Anchor (XSpreadsheet)",
+ xShape->getPropertyValue("Anchor") >>= xSheetGet);
+
+ // Setting ResizeWithCell while anchored to page should not have any effect
+ CPPUNIT_ASSERT(xShape->getPropertyValue("ResizeWithCell") >>= bIsResizeWithCell);
+ CPPUNIT_ASSERT_MESSAGE("ResizeWithCell should be false for sheet anchored shapes",
+ !bIsResizeWithCell);
+ xShape->setPropertyValue("ResizeWithCell", uno::Any(true));
+ CPPUNIT_ASSERT(xShape->getPropertyValue("ResizeWithCell") >>= bIsResizeWithCell);
+ CPPUNIT_ASSERT_MESSAGE("ResizeWithCell should be unchangeable for sheet anchored shapes",
+ !bIsResizeWithCell);
+}
+
+void Shape::testShapePropertiesPosition()
+{
+ uno::Reference<beans::XPropertySet> xShape(init(), UNO_QUERY_THROW);
+ uno::Any aNewValue;
+
+ sal_Int32 nHoriOrientPositionGet = 0;
+ sal_Int32 nHoriOrientPositionSet = 0;
+ CPPUNIT_ASSERT_MESSAGE("Unable to get PropertyValue HoriOrientPosition",
+ xShape->getPropertyValue("HoriOrientPosition")
+ >>= nHoriOrientPositionGet);
+
+ aNewValue <<= nHoriOrientPositionGet + 42;
+ xShape->setPropertyValue("HoriOrientPosition", aNewValue);
+ CPPUNIT_ASSERT(xShape->getPropertyValue("HoriOrientPosition") >>= nHoriOrientPositionSet);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Unable to set PropertyValue HoriOrientPosition",
+ nHoriOrientPositionGet + 42, nHoriOrientPositionSet);
+
+ sal_Int32 nVertOrientPositionGet = 0;
+ sal_Int32 nVertOrientPositionSet = 0;
+ CPPUNIT_ASSERT_MESSAGE("Unable to get PropertyValue VertOrientPosition",
+ xShape->getPropertyValue("VertOrientPosition")
+ >>= nVertOrientPositionGet);
+
+ aNewValue <<= nVertOrientPositionGet + 42;
+ xShape->setPropertyValue("VertOrientPosition", aNewValue);
+ CPPUNIT_ASSERT(xShape->getPropertyValue("VertOrientPosition") >>= nVertOrientPositionSet);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Unable to set PropertyValue VertOrientPosition",
+ nVertOrientPositionGet + 42, nVertOrientPositionSet);
+}
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/test/source/sheet/sheetcell.cxx b/test/source/sheet/sheetcell.cxx
new file mode 100644
index 0000000000..d0a2c6c032
--- /dev/null
+++ b/test/source/sheet/sheetcell.cxx
@@ -0,0 +1,215 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * 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 <test/cppunitasserthelper.hxx>
+#include <test/sheet/sheetcell.hxx>
+
+#include <com/sun/star/awt/Point.hpp>
+#include <com/sun/star/awt/Size.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/sheet/ValidationType.hpp>
+#include <com/sun/star/sheet/XSheetConditionalEntry.hpp>
+#include <com/sun/star/sheet/XSheetConditionalEntries.hpp>
+#include <com/sun/star/table/CellContentType.hpp>
+#include <com/sun/star/uno/Any.hxx>
+#include <com/sun/star/uno/Reference.hxx>
+#include <com/sun/star/uno/Sequence.hxx>
+
+#include <comphelper/propertyvalue.hxx>
+#include <cppunit/TestAssert.h>
+
+using namespace com::sun::star;
+using namespace com::sun::star::uno;
+
+namespace apitest
+{
+void SheetCell::testSheetCellProperties()
+{
+ uno::Reference<beans::XPropertySet> xSheetCell(init(), UNO_QUERY_THROW);
+ OUString propName;
+ uno::Any aNewValue;
+
+ propName = "Position";
+ awt::Point aPositionGet;
+ CPPUNIT_ASSERT_MESSAGE("Unable to get PropertyValue Position",
+ xSheetCell->getPropertyValue(propName) >>= aPositionGet);
+
+ awt::Point aPositionSet(42, 42);
+ aNewValue <<= aPositionSet;
+ xSheetCell->setPropertyValue(propName, aNewValue);
+ CPPUNIT_ASSERT(xSheetCell->getPropertyValue(propName) >>= aPositionSet);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Able to set PropertyValue Position", aPositionGet, aPositionGet);
+
+ propName = "Size";
+ awt::Size aSizeGet;
+ CPPUNIT_ASSERT_MESSAGE("Unable to get PropertyValue Size",
+ xSheetCell->getPropertyValue(propName) >>= aSizeGet);
+
+ awt::Size aSizeSet(42, 42);
+ aNewValue <<= aSizeGet;
+ xSheetCell->setPropertyValue(propName, aNewValue);
+ CPPUNIT_ASSERT(xSheetCell->getPropertyValue(propName) >>= aSizeSet);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Able to set PropertyValue Size", aSizeGet, aSizeSet);
+
+ propName = "FormulaLocal";
+ OUString aFormulaLocal = "";
+ CPPUNIT_ASSERT_MESSAGE("Unable to get PropertyValue FormulaLocal",
+ xSheetCell->getPropertyValue(propName) >>= aFormulaLocal);
+
+ aNewValue <<= OUString("FormulaLocal");
+ xSheetCell->setPropertyValue(propName, aNewValue);
+ CPPUNIT_ASSERT(xSheetCell->getPropertyValue(propName) >>= aFormulaLocal);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Unable to set PropertyValue FormulaLocal",
+ OUString("FormulaLocal"), aFormulaLocal);
+
+ propName = "CellContentType";
+ table::CellContentType aCellContentTypeGet;
+ CPPUNIT_ASSERT_MESSAGE("Unable to get PropertyValue CellContentType",
+ xSheetCell->getPropertyValue(propName) >>= aCellContentTypeGet);
+
+ table::CellContentType aCellContentTypeSet = table::CellContentType_TEXT;
+ aNewValue <<= aCellContentTypeSet;
+ xSheetCell->setPropertyValue(propName, aNewValue);
+ CPPUNIT_ASSERT(xSheetCell->getPropertyValue(propName) >>= aCellContentTypeSet);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Able to set PropertyValue CellContentType", aCellContentTypeGet,
+ aCellContentTypeSet);
+
+ // Special case, because the API returns the wrong type.
+ propName = "FormulaResultType";
+ table::CellContentType aFormulaResultTypeGet;
+ CPPUNIT_ASSERT_MESSAGE("Unable to get PropertyValue FormulaResultType",
+ xSheetCell->getPropertyValue(propName) >>= aFormulaResultTypeGet);
+
+ table::CellContentType aFormulaResultTypeSet = table::CellContentType_TEXT;
+ aNewValue <<= aFormulaResultTypeSet;
+ xSheetCell->setPropertyValue(propName, aNewValue);
+ CPPUNIT_ASSERT(xSheetCell->getPropertyValue(propName) >>= aFormulaResultTypeSet);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Able to set PropertyValue FormulaResultType",
+ aFormulaResultTypeGet, aFormulaResultTypeSet);
+
+ propName = "FormulaResultType2";
+ sal_Int32 aFormulaResultType2Get = 42;
+ CPPUNIT_ASSERT_MESSAGE("Unable to get PropertyValue FormulaResultType2",
+ xSheetCell->getPropertyValue(propName) >>= aFormulaResultType2Get);
+
+ sal_Int32 aFormulaResultType2Set = 42;
+ aNewValue <<= aFormulaResultType2Set;
+ xSheetCell->setPropertyValue(propName, aNewValue);
+ CPPUNIT_ASSERT(xSheetCell->getPropertyValue(propName) >>= aFormulaResultType2Set);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Able to set PropertyValue FormulaResultType2",
+ aFormulaResultType2Get, aFormulaResultType2Set);
+
+ uno::Sequence<beans::PropertyValue> aPropValue{ comphelper::makePropertyValue(
+ "StyleName", OUString("Result2")) };
+
+ propName = "ConditionalFormat";
+ uno::Reference<sheet::XSheetConditionalEntries> aConditionalFormatGet;
+ uno::Reference<sheet::XSheetConditionalEntries> aConditionalFormatSet;
+
+ CPPUNIT_ASSERT_MESSAGE("Unable to get PropertyValue ConditionalFormat",
+ xSheetCell->getPropertyValue(propName) >>= aConditionalFormatGet);
+
+ uno::Reference<sheet::XSheetConditionalEntries> aConditionalFormatNew(aConditionalFormatGet,
+ UNO_SET_THROW);
+ aConditionalFormatNew->addNew(aPropValue);
+
+ aNewValue <<= aConditionalFormatNew;
+ xSheetCell->setPropertyValue(propName, aNewValue);
+ CPPUNIT_ASSERT(xSheetCell->getPropertyValue(propName) >>= aConditionalFormatSet);
+ for (auto i = 0; i < aConditionalFormatSet->getCount(); i++)
+ {
+ uno::Reference<sheet::XSheetConditionalEntry> xSCENew(aConditionalFormatNew->getByIndex(i),
+ UNO_QUERY_THROW);
+ uno::Reference<sheet::XSheetConditionalEntry> xSCESet(aConditionalFormatSet->getByIndex(i),
+ UNO_QUERY_THROW);
+
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Unable to set PropertyValue ConditionalFormat["
+ + std::to_string(i) + "]",
+ xSCENew->getStyleName(), xSCESet->getStyleName());
+ }
+
+ propName = "ConditionalFormatLocal";
+ uno::Reference<sheet::XSheetConditionalEntries> aConditionalFormatLocalGet;
+ uno::Reference<sheet::XSheetConditionalEntries> aConditionalFormatLocalSet;
+
+ CPPUNIT_ASSERT_MESSAGE("Unable to get PropertyValue ConditionalFormatLocal",
+ xSheetCell->getPropertyValue(propName) >>= aConditionalFormatLocalGet);
+
+ uno::Reference<sheet::XSheetConditionalEntries> aConditionalFormatLocalNew(
+ aConditionalFormatLocalGet, UNO_SET_THROW);
+ aConditionalFormatLocalNew->addNew(aPropValue);
+
+ aNewValue <<= aConditionalFormatLocalNew;
+ xSheetCell->setPropertyValue(propName, aNewValue);
+ CPPUNIT_ASSERT(xSheetCell->getPropertyValue(propName) >>= aConditionalFormatLocalSet);
+ for (auto i = 0; i < aConditionalFormatLocalSet->getCount(); i++)
+ {
+ uno::Reference<sheet::XSheetConditionalEntry> xSCENew(
+ aConditionalFormatLocalNew->getByIndex(i), UNO_QUERY_THROW);
+ uno::Reference<sheet::XSheetConditionalEntry> xSCESet(
+ aConditionalFormatLocalSet->getByIndex(i), UNO_QUERY_THROW);
+
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Unable to set PropertyValue ConditionalFormatLocal["
+ + std::to_string(i) + "]",
+ xSCENew->getStyleName(), xSCESet->getStyleName());
+ }
+
+ propName = "Validation";
+ uno::Reference<beans::XPropertySet> aValidationGet;
+ uno::Reference<beans::XPropertySet> aValidationSet;
+
+ CPPUNIT_ASSERT_MESSAGE("Unable to get PropertyValue Validation",
+ xSheetCell->getPropertyValue(propName) >>= aValidationGet);
+
+ uno::Reference<beans::XPropertySet> aValidationNew(aValidationGet, UNO_SET_THROW);
+ uno::Any aValidationType;
+ aValidationType <<= sheet::ValidationType_WHOLE;
+ aValidationNew->setPropertyValue("Type", aValidationType);
+
+ aNewValue <<= aValidationNew;
+ xSheetCell->setPropertyValue(propName, aNewValue);
+ CPPUNIT_ASSERT(xSheetCell->getPropertyValue(propName) >>= aValidationSet);
+ sheet::ValidationType aType;
+ aValidationSet->getPropertyValue("Type") >>= aType;
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Unable to set PropertyValue Validation",
+ sheet::ValidationType_WHOLE, aType);
+
+ propName = "ValidationLocal";
+ uno::Reference<beans::XPropertySet> aValidationLocalGet;
+ uno::Reference<beans::XPropertySet> aValidationLocalSet;
+
+ CPPUNIT_ASSERT_MESSAGE("Unable to get PropertyValue ValidationLocal",
+ xSheetCell->getPropertyValue(propName) >>= aValidationLocalGet);
+
+ uno::Reference<beans::XPropertySet> aValidationLocalNew(aValidationLocalGet, UNO_SET_THROW);
+ aValidationType <<= sheet::ValidationType_WHOLE;
+ aValidationLocalNew->setPropertyValue("Type", aValidationType);
+
+ aNewValue <<= aValidationLocalNew;
+ xSheetCell->setPropertyValue(propName, aNewValue);
+ CPPUNIT_ASSERT(xSheetCell->getPropertyValue(propName) >>= aValidationLocalSet);
+ aValidationLocalSet->getPropertyValue("Type") >>= aType;
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Unable to set PropertyValue ValidationLocal",
+ sheet::ValidationType_WHOLE, aType);
+
+ propName = "AbsoluteName";
+ OUString aAbsoluteNameGet = "";
+ CPPUNIT_ASSERT_MESSAGE("Unable to get PropertyValue AbsoluteName",
+ xSheetCell->getPropertyValue(propName) >>= aAbsoluteNameGet);
+
+ OUString aAbsoluteNameSet = "$Sheet1.$C$3";
+ aNewValue <<= aAbsoluteNameSet;
+ xSheetCell->setPropertyValue(propName, aNewValue);
+ CPPUNIT_ASSERT(xSheetCell->getPropertyValue(propName) >>= aAbsoluteNameSet);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Able to set PropertyValue AbsoluteName", aAbsoluteNameGet,
+ aAbsoluteNameSet);
+}
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/test/source/sheet/sheetcellrange.cxx b/test/source/sheet/sheetcellrange.cxx
new file mode 100644
index 0000000000..bf56849360
--- /dev/null
+++ b/test/source/sheet/sheetcellrange.cxx
@@ -0,0 +1,167 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * 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 <test/cppunitasserthelper.hxx>
+#include <test/sheet/sheetcellrange.hxx>
+
+#include <com/sun/star/awt/Point.hpp>
+#include <com/sun/star/awt/Size.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/sheet/ValidationType.hpp>
+#include <com/sun/star/sheet/XSheetConditionalEntry.hpp>
+#include <com/sun/star/sheet/XSheetConditionalEntries.hpp>
+#include <com/sun/star/uno/Any.hxx>
+#include <com/sun/star/uno/Reference.hxx>
+#include <com/sun/star/uno/Sequence.hxx>
+
+#include <comphelper/propertyvalue.hxx>
+#include <cppunit/TestAssert.h>
+
+using namespace com::sun::star;
+using namespace com::sun::star::uno;
+
+namespace apitest
+{
+void SheetCellRange::testSheetCellRangeProperties()
+{
+ uno::Reference<beans::XPropertySet> xSheetCellRange(init(), UNO_QUERY_THROW);
+ OUString propName;
+ uno::Any aNewValue;
+
+ propName = "Position";
+ awt::Point aPositionGet;
+ CPPUNIT_ASSERT_MESSAGE("Unable to get PropertyValue Position",
+ xSheetCellRange->getPropertyValue(propName) >>= aPositionGet);
+
+ awt::Point aPositionSet(42, 42);
+ aNewValue <<= aPositionSet;
+ xSheetCellRange->setPropertyValue(propName, aNewValue);
+ CPPUNIT_ASSERT(xSheetCellRange->getPropertyValue(propName) >>= aPositionSet);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Able to set PropertyValue Position", aPositionGet, aPositionGet);
+
+ propName = "Size";
+ awt::Size aSizeGet;
+ CPPUNIT_ASSERT_MESSAGE("Unable to get PropertyValue Size",
+ xSheetCellRange->getPropertyValue(propName) >>= aSizeGet);
+
+ awt::Size aSizeSet(42, 42);
+ aNewValue <<= aSizeGet;
+ xSheetCellRange->setPropertyValue(propName, aNewValue);
+ CPPUNIT_ASSERT(xSheetCellRange->getPropertyValue(propName) >>= aSizeSet);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Able to set PropertyValue Size", aSizeGet, aSizeSet);
+
+ uno::Sequence<beans::PropertyValue> aPropValue{ comphelper::makePropertyValue(
+ "StyleName", OUString("Result2")) };
+
+ propName = "ConditionalFormat";
+ uno::Reference<sheet::XSheetConditionalEntries> aConditionalFormatGet;
+ uno::Reference<sheet::XSheetConditionalEntries> aConditionalFormatSet;
+
+ CPPUNIT_ASSERT_MESSAGE("Unable to get PropertyValue ConditionalFormat",
+ xSheetCellRange->getPropertyValue(propName) >>= aConditionalFormatGet);
+
+ uno::Reference<sheet::XSheetConditionalEntries> aConditionalFormatNew(aConditionalFormatGet,
+ UNO_SET_THROW);
+ aConditionalFormatNew->addNew(aPropValue);
+
+ aNewValue <<= aConditionalFormatNew;
+ xSheetCellRange->setPropertyValue(propName, aNewValue);
+ CPPUNIT_ASSERT(xSheetCellRange->getPropertyValue(propName) >>= aConditionalFormatSet);
+ for (auto i = 0; i < aConditionalFormatSet->getCount(); i++)
+ {
+ uno::Reference<sheet::XSheetConditionalEntry> xSCENew(aConditionalFormatNew->getByIndex(i),
+ UNO_QUERY_THROW);
+ uno::Reference<sheet::XSheetConditionalEntry> xSCESet(aConditionalFormatSet->getByIndex(i),
+ UNO_QUERY_THROW);
+
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Unable to set PropertyValue ConditionalFormat["
+ + std::to_string(i) + "]",
+ xSCENew->getStyleName(), xSCESet->getStyleName());
+ }
+
+ propName = "ConditionalFormatLocal";
+ uno::Reference<sheet::XSheetConditionalEntries> aConditionalFormatLocalGet;
+ uno::Reference<sheet::XSheetConditionalEntries> aConditionalFormatLocalSet;
+
+ CPPUNIT_ASSERT_MESSAGE("Unable to get PropertyValue ConditionalFormatLocal",
+ xSheetCellRange->getPropertyValue(propName)
+ >>= aConditionalFormatLocalGet);
+
+ uno::Reference<sheet::XSheetConditionalEntries> aConditionalFormatLocalNew(
+ aConditionalFormatLocalGet, UNO_SET_THROW);
+ aConditionalFormatLocalNew->addNew(aPropValue);
+
+ aNewValue <<= aConditionalFormatLocalNew;
+ xSheetCellRange->setPropertyValue(propName, aNewValue);
+ CPPUNIT_ASSERT(xSheetCellRange->getPropertyValue(propName) >>= aConditionalFormatLocalSet);
+ for (auto i = 0; i < aConditionalFormatLocalSet->getCount(); i++)
+ {
+ uno::Reference<sheet::XSheetConditionalEntry> xSCENew(
+ aConditionalFormatLocalNew->getByIndex(i), UNO_QUERY_THROW);
+ uno::Reference<sheet::XSheetConditionalEntry> xSCESet(
+ aConditionalFormatLocalSet->getByIndex(i), UNO_QUERY_THROW);
+
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Unable to set PropertyValue ConditionalFormatLocal["
+ + std::to_string(i) + "]",
+ xSCENew->getStyleName(), xSCESet->getStyleName());
+ }
+
+ propName = "Validation";
+ uno::Reference<beans::XPropertySet> aValidationGet;
+ uno::Reference<beans::XPropertySet> aValidationSet;
+
+ CPPUNIT_ASSERT_MESSAGE("Unable to get PropertyValue Validation",
+ xSheetCellRange->getPropertyValue(propName) >>= aValidationGet);
+
+ uno::Reference<beans::XPropertySet> aValidationNew(aValidationGet, UNO_SET_THROW);
+ uno::Any aValidationType;
+ aValidationType <<= sheet::ValidationType_WHOLE;
+ aValidationNew->setPropertyValue("Type", aValidationType);
+
+ aNewValue <<= aValidationNew;
+ xSheetCellRange->setPropertyValue(propName, aNewValue);
+ CPPUNIT_ASSERT(xSheetCellRange->getPropertyValue(propName) >>= aValidationSet);
+ sheet::ValidationType aType;
+ aValidationSet->getPropertyValue("Type") >>= aType;
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Unable to set PropertyValue Validation",
+ sheet::ValidationType_WHOLE, aType);
+
+ propName = "ValidationLocal";
+ uno::Reference<beans::XPropertySet> aValidationLocalGet;
+ uno::Reference<beans::XPropertySet> aValidationLocalSet;
+
+ CPPUNIT_ASSERT_MESSAGE("Unable to get PropertyValue ValidationLocal",
+ xSheetCellRange->getPropertyValue(propName) >>= aValidationLocalGet);
+
+ uno::Reference<beans::XPropertySet> aValidationLocalNew(aValidationLocalGet, UNO_SET_THROW);
+ aValidationType <<= sheet::ValidationType_WHOLE;
+ aValidationLocalNew->setPropertyValue("Type", aValidationType);
+
+ aNewValue <<= aValidationLocalNew;
+ xSheetCellRange->setPropertyValue(propName, aNewValue);
+ CPPUNIT_ASSERT(xSheetCellRange->getPropertyValue(propName) >>= aValidationLocalSet);
+ aValidationLocalSet->getPropertyValue("Type") >>= aType;
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Unable to set PropertyValue ValidationLocal",
+ sheet::ValidationType_WHOLE, aType);
+
+ propName = "AbsoluteName";
+ OUString aAbsoluteNameGet = "";
+ CPPUNIT_ASSERT_MESSAGE("Unable to get PropertyValue AbsoluteName",
+ xSheetCellRange->getPropertyValue(propName) >>= aAbsoluteNameGet);
+
+ OUString aAbsoluteNameSet = "$Sheet1.$C$3";
+ aNewValue <<= aAbsoluteNameSet;
+ xSheetCellRange->setPropertyValue(propName, aNewValue);
+ CPPUNIT_ASSERT(xSheetCellRange->getPropertyValue(propName) >>= aAbsoluteNameSet);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Able to set PropertyValue AbsoluteName", aAbsoluteNameGet,
+ aAbsoluteNameSet);
+}
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/test/source/sheet/sheetcellranges.cxx b/test/source/sheet/sheetcellranges.cxx
new file mode 100644
index 0000000000..9611a33bd5
--- /dev/null
+++ b/test/source/sheet/sheetcellranges.cxx
@@ -0,0 +1,142 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * 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 <test/sheet/sheetcellranges.hxx>
+
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/sheet/ValidationType.hpp>
+#include <com/sun/star/sheet/XSheetConditionalEntry.hpp>
+#include <com/sun/star/sheet/XSheetConditionalEntries.hpp>
+#include <com/sun/star/uno/Any.hxx>
+#include <com/sun/star/uno/Reference.hxx>
+#include <com/sun/star/uno/Sequence.hxx>
+
+#include <comphelper/propertyvalue.hxx>
+#include <cppunit/TestAssert.h>
+
+using namespace com::sun::star;
+using namespace com::sun::star::uno;
+
+namespace apitest
+{
+void SheetCellRanges::testSheetCellRangesProperties()
+{
+ uno::Reference<beans::XPropertySet> xSheetCellRanges(init(), UNO_QUERY_THROW);
+ OUString propName;
+ uno::Any aNewValue;
+
+ uno::Sequence<beans::PropertyValue> aPropValue{ comphelper::makePropertyValue(
+ "StyleName", OUString("Result2")) };
+
+ propName = "ConditionalFormat";
+ uno::Reference<sheet::XSheetConditionalEntries> aConditionalFormatGet;
+ uno::Reference<sheet::XSheetConditionalEntries> aConditionalFormatSet;
+
+ CPPUNIT_ASSERT_MESSAGE("Unable to get PropertyValue ConditionalFormat",
+ xSheetCellRanges->getPropertyValue(propName) >>= aConditionalFormatGet);
+
+ uno::Reference<sheet::XSheetConditionalEntries> aConditionalFormatNew(aConditionalFormatGet,
+ UNO_SET_THROW);
+ aConditionalFormatNew->addNew(aPropValue);
+
+ aNewValue <<= aConditionalFormatNew;
+ xSheetCellRanges->setPropertyValue(propName, aNewValue);
+ CPPUNIT_ASSERT(xSheetCellRanges->getPropertyValue(propName) >>= aConditionalFormatSet);
+ for (auto i = 0; i < aConditionalFormatSet->getCount(); i++)
+ {
+ uno::Reference<sheet::XSheetConditionalEntry> xSCENew(aConditionalFormatNew->getByIndex(i),
+ UNO_QUERY_THROW);
+ uno::Reference<sheet::XSheetConditionalEntry> xSCESet(aConditionalFormatSet->getByIndex(i),
+ UNO_QUERY_THROW);
+
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Unable to set PropertyValue ConditionalFormat["
+ + std::to_string(i) + "]",
+ xSCENew->getStyleName(), xSCESet->getStyleName());
+ }
+
+ propName = "ConditionalFormatLocal";
+ uno::Reference<sheet::XSheetConditionalEntries> aConditionalFormatLocalGet;
+ uno::Reference<sheet::XSheetConditionalEntries> aConditionalFormatLocalSet;
+
+ CPPUNIT_ASSERT_MESSAGE("Unable to get PropertyValue ConditionalFormatLocal",
+ xSheetCellRanges->getPropertyValue(propName)
+ >>= aConditionalFormatLocalGet);
+
+ uno::Reference<sheet::XSheetConditionalEntries> aConditionalFormatLocalNew(
+ aConditionalFormatLocalGet, UNO_SET_THROW);
+ aConditionalFormatLocalNew->addNew(aPropValue);
+
+ aNewValue <<= aConditionalFormatLocalNew;
+ xSheetCellRanges->setPropertyValue(propName, aNewValue);
+ CPPUNIT_ASSERT(xSheetCellRanges->getPropertyValue(propName) >>= aConditionalFormatLocalSet);
+ for (auto i = 0; i < aConditionalFormatLocalSet->getCount(); i++)
+ {
+ uno::Reference<sheet::XSheetConditionalEntry> xSCENew(
+ aConditionalFormatLocalNew->getByIndex(i), UNO_QUERY_THROW);
+ uno::Reference<sheet::XSheetConditionalEntry> xSCESet(
+ aConditionalFormatLocalSet->getByIndex(i), UNO_QUERY_THROW);
+
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Unable to set PropertyValue ConditionalFormatLocal["
+ + std::to_string(i) + "]",
+ xSCENew->getStyleName(), xSCESet->getStyleName());
+ }
+
+ propName = "Validation";
+ uno::Reference<beans::XPropertySet> aValidationGet;
+ uno::Reference<beans::XPropertySet> aValidationSet;
+
+ CPPUNIT_ASSERT_MESSAGE("Unable to get PropertyValue Validation",
+ xSheetCellRanges->getPropertyValue(propName) >>= aValidationGet);
+
+ uno::Reference<beans::XPropertySet> aValidationNew(aValidationGet, UNO_SET_THROW);
+ uno::Any aValidationType;
+ aValidationType <<= sheet::ValidationType_WHOLE;
+ aValidationNew->setPropertyValue("Type", aValidationType);
+
+ aNewValue <<= aValidationNew;
+ xSheetCellRanges->setPropertyValue(propName, aNewValue);
+ CPPUNIT_ASSERT(xSheetCellRanges->getPropertyValue(propName) >>= aValidationSet);
+ sheet::ValidationType aType;
+ aValidationSet->getPropertyValue("Type") >>= aType;
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Unable to set PropertyValue Validation",
+ sheet::ValidationType_WHOLE, aType);
+
+ propName = "ValidationLocal";
+ uno::Reference<beans::XPropertySet> aValidationLocalGet;
+ uno::Reference<beans::XPropertySet> aValidationLocalSet;
+
+ CPPUNIT_ASSERT_MESSAGE("Unable to get PropertyValue ValidationLocal",
+ xSheetCellRanges->getPropertyValue(propName) >>= aValidationLocalGet);
+
+ uno::Reference<beans::XPropertySet> aValidationLocalNew(aValidationLocalGet, UNO_SET_THROW);
+ aValidationType <<= sheet::ValidationType_WHOLE;
+ aValidationLocalNew->setPropertyValue("Type", aValidationType);
+
+ aNewValue <<= aValidationLocalNew;
+ xSheetCellRanges->setPropertyValue(propName, aNewValue);
+ CPPUNIT_ASSERT(xSheetCellRanges->getPropertyValue(propName) >>= aValidationLocalSet);
+ aValidationLocalSet->getPropertyValue("Type") >>= aType;
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Unable to set PropertyValue ValidationLocal",
+ sheet::ValidationType_WHOLE, aType);
+
+ propName = "AbsoluteName";
+ OUString aAbsoluteNameGet = "";
+ CPPUNIT_ASSERT_MESSAGE("Unable to get PropertyValue AbsoluteName",
+ xSheetCellRanges->getPropertyValue(propName) >>= aAbsoluteNameGet);
+
+ OUString aAbsoluteNameSet = "$Sheet1.$C$3";
+ aNewValue <<= aAbsoluteNameSet;
+ xSheetCellRanges->setPropertyValue(propName, aNewValue);
+ CPPUNIT_ASSERT(xSheetCellRanges->getPropertyValue(propName) >>= aAbsoluteNameSet);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Able to set PropertyValue AbsoluteName", aAbsoluteNameGet,
+ aAbsoluteNameSet);
+}
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/test/source/sheet/sheetfilterdescriptor.cxx b/test/source/sheet/sheetfilterdescriptor.cxx
new file mode 100644
index 0000000000..3a0b1364d5
--- /dev/null
+++ b/test/source/sheet/sheetfilterdescriptor.cxx
@@ -0,0 +1,151 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * 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 <test/cppunitasserthelper.hxx>
+#include <test/sheet/sheetfilterdescriptor.hxx>
+
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/table/CellAddress.hpp>
+#include <com/sun/star/table/TableOrientation.hpp>
+#include <com/sun/star/uno/Any.hxx>
+#include <com/sun/star/uno/Reference.hxx>
+
+#include <cppunit/TestAssert.h>
+
+using namespace com::sun::star;
+using namespace com::sun::star::uno;
+
+namespace apitest
+{
+void SheetFilterDescriptor::testSheetFilterDescriptorProperties()
+{
+ uno::Reference<beans::XPropertySet> xSheetFilterDescriptor(init(), UNO_QUERY_THROW);
+ OUString propName;
+ uno::Any aNewValue;
+
+ propName = "IsCaseSensitive";
+ bool bIsCaseSensitiveGet = false;
+ bool bIsCaseSensitiveSet = false;
+ CPPUNIT_ASSERT_MESSAGE("Unable to get PropertyValue IsCaseSensitive",
+ xSheetFilterDescriptor->getPropertyValue(propName)
+ >>= bIsCaseSensitiveGet);
+
+ aNewValue <<= !bIsCaseSensitiveGet;
+ xSheetFilterDescriptor->setPropertyValue(propName, aNewValue);
+ CPPUNIT_ASSERT(xSheetFilterDescriptor->getPropertyValue(propName) >>= bIsCaseSensitiveSet);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Unable to set PropertyValue IsCaseSensitive",
+ !bIsCaseSensitiveGet, bIsCaseSensitiveSet);
+
+ propName = "SkipDuplicates";
+ bool bSkipDuplicatesGet = false;
+ bool bSkipDuplicatesSet = false;
+ CPPUNIT_ASSERT_MESSAGE("Unable to get PropertyValue SkipDuplicates",
+ xSheetFilterDescriptor->getPropertyValue(propName)
+ >>= bSkipDuplicatesGet);
+
+ aNewValue <<= !bSkipDuplicatesGet;
+ xSheetFilterDescriptor->setPropertyValue(propName, aNewValue);
+ CPPUNIT_ASSERT(xSheetFilterDescriptor->getPropertyValue(propName) >>= bSkipDuplicatesSet);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Unable to set PropertyValue SkipDuplicates", !bSkipDuplicatesGet,
+ bSkipDuplicatesSet);
+
+ propName = "UseRegularExpressions";
+ bool bUseRegularExpressionsGet = false;
+ bool bUseRegularExpressionsSet = false;
+ CPPUNIT_ASSERT_MESSAGE("Unable to get PropertyValue UseRegularExpressions",
+ xSheetFilterDescriptor->getPropertyValue(propName)
+ >>= bUseRegularExpressionsGet);
+
+ aNewValue <<= !bUseRegularExpressionsGet;
+ xSheetFilterDescriptor->setPropertyValue(propName, aNewValue);
+ CPPUNIT_ASSERT(xSheetFilterDescriptor->getPropertyValue(propName)
+ >>= bUseRegularExpressionsSet);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Unable to set PropertyValue UseRegularExpressions",
+ !bUseRegularExpressionsGet, bUseRegularExpressionsSet);
+
+ propName = "SaveOutputPosition";
+ bool bSaveOutputPositionGet = false;
+ bool bSaveOutputPositionSet = false;
+ CPPUNIT_ASSERT_MESSAGE("Unable to get PropertyValue SaveOutputPosition",
+ xSheetFilterDescriptor->getPropertyValue(propName)
+ >>= bSaveOutputPositionGet);
+
+ aNewValue <<= !bSaveOutputPositionGet;
+ xSheetFilterDescriptor->setPropertyValue(propName, aNewValue);
+ CPPUNIT_ASSERT(xSheetFilterDescriptor->getPropertyValue(propName) >>= bSaveOutputPositionSet);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Unable to set PropertyValue SaveOutputPosition",
+ !bSaveOutputPositionGet, bSaveOutputPositionSet);
+
+ propName = "Orientation";
+ table::TableOrientation aOrientationGet;
+ table::TableOrientation aOrientationSet;
+ CPPUNIT_ASSERT_MESSAGE("Unable to get PropertyValue Orientation",
+ xSheetFilterDescriptor->getPropertyValue(propName) >>= aOrientationGet);
+
+ aNewValue <<= table::TableOrientation_COLUMNS;
+ xSheetFilterDescriptor->setPropertyValue(propName, aNewValue);
+ CPPUNIT_ASSERT(xSheetFilterDescriptor->getPropertyValue(propName) >>= aOrientationSet);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Unable to set PropertyValue Orientation",
+ table::TableOrientation_COLUMNS, aOrientationSet);
+
+ propName = "ContainsHeader";
+ bool bContainsHeaderGet = false;
+ bool bContainsHeaderSet = false;
+ CPPUNIT_ASSERT_MESSAGE("Unable to get PropertyValue ContainsHeader",
+ xSheetFilterDescriptor->getPropertyValue(propName)
+ >>= bContainsHeaderGet);
+
+ aNewValue <<= !bContainsHeaderGet;
+ xSheetFilterDescriptor->setPropertyValue(propName, aNewValue);
+ CPPUNIT_ASSERT(xSheetFilterDescriptor->getPropertyValue(propName) >>= bContainsHeaderSet);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Unable to set PropertyValue ContainsHeader", !bContainsHeaderGet,
+ bContainsHeaderSet);
+
+ propName = "CopyOutputData";
+ bool bCopyOutputDataGet = false;
+ bool bCopyOutputDataSet = false;
+ CPPUNIT_ASSERT_MESSAGE("Unable to get PropertyValue CopyOutputData",
+ xSheetFilterDescriptor->getPropertyValue(propName)
+ >>= bCopyOutputDataGet);
+
+ aNewValue <<= !bCopyOutputDataGet;
+ xSheetFilterDescriptor->setPropertyValue(propName, aNewValue);
+ CPPUNIT_ASSERT(xSheetFilterDescriptor->getPropertyValue(propName) >>= bCopyOutputDataSet);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Unable to set PropertyValue CopyOutputData", !bCopyOutputDataGet,
+ bCopyOutputDataSet);
+
+ propName = "OutputPosition";
+ table::CellAddress aCellAddressGet;
+ table::CellAddress aCellAddressSet;
+ CPPUNIT_ASSERT_MESSAGE("Unable to get PropertyValue OutputPosition",
+ xSheetFilterDescriptor->getPropertyValue(propName) >>= aCellAddressGet);
+
+ aCellAddressGet = table::CellAddress(0, 42, 42);
+ aNewValue <<= aCellAddressGet;
+ xSheetFilterDescriptor->setPropertyValue(propName, aNewValue);
+ CPPUNIT_ASSERT(xSheetFilterDescriptor->getPropertyValue(propName) >>= aCellAddressSet);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Unable to set PropertyValue OutputPosition", aCellAddressGet,
+ aCellAddressSet);
+
+ propName = "MaxFieldCount";
+ sal_Int32 nMaxFieldCountGet = 0;
+ sal_Int32 nMaxFieldCountSet = 0;
+ CPPUNIT_ASSERT_MESSAGE("Unable to get PropertyValue MaxFieldCount",
+ xSheetFilterDescriptor->getPropertyValue(propName)
+ >>= nMaxFieldCountGet);
+
+ aNewValue <<= nMaxFieldCountGet + 42;
+ xSheetFilterDescriptor->setPropertyValue(propName, aNewValue);
+ CPPUNIT_ASSERT(xSheetFilterDescriptor->getPropertyValue(propName) >>= nMaxFieldCountSet);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Able to set PropertyValue MaxFieldCount", nMaxFieldCountGet,
+ nMaxFieldCountSet);
+}
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/test/source/sheet/sheetlink.cxx b/test/source/sheet/sheetlink.cxx
new file mode 100644
index 0000000000..de6a2148e9
--- /dev/null
+++ b/test/source/sheet/sheetlink.cxx
@@ -0,0 +1,67 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * 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 <test/sheet/sheetlink.hxx>
+
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/uno/Any.hxx>
+#include <com/sun/star/uno/Reference.hxx>
+
+#include <cppunit/TestAssert.h>
+
+using namespace com::sun::star;
+using namespace com::sun::star::uno;
+
+namespace apitest
+{
+void SheetLink::testSheetLinkProperties()
+{
+ uno::Reference<beans::XPropertySet> xSheetLink(init(), UNO_QUERY_THROW);
+ OUString propName;
+ uno::Any aNewValue;
+
+ propName = "Url";
+ OUString aUrlGet;
+ OUString aUrlSet;
+ CPPUNIT_ASSERT_MESSAGE("Unable to get PropertyValue Url",
+ xSheetLink->getPropertyValue(propName) >>= aUrlGet);
+
+ aNewValue <<= OUString("file:///tmp/ScSheetLinkObj.ods");
+ xSheetLink->setPropertyValue(propName, aNewValue);
+ CPPUNIT_ASSERT(xSheetLink->getPropertyValue(propName) >>= aUrlSet);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Unable to set PropertyValue Url",
+ OUString("file:///tmp/ScSheetLinkObj.ods"), aUrlSet);
+
+ propName = "Filter";
+ OUString aFilterGet;
+ OUString aFilterSet;
+ CPPUNIT_ASSERT_MESSAGE("Unable to get PropertyValue Filter",
+ xSheetLink->getPropertyValue(propName) >>= aFilterGet);
+
+ aNewValue <<= OUString("Text - txt - csv (StarCalc)");
+ xSheetLink->setPropertyValue(propName, aNewValue);
+ CPPUNIT_ASSERT(xSheetLink->getPropertyValue(propName) >>= aFilterSet);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Unable to set PropertyValue Filter",
+ OUString("Text - txt - csv (StarCalc)"), aFilterSet);
+
+ propName = "FilterOptions";
+ OUString aFilterOptionsGet;
+ OUString aFilterOptionsSet;
+ CPPUNIT_ASSERT_MESSAGE("Unable to get PropertyValue FilterOptions",
+ xSheetLink->getPropertyValue(propName) >>= aFilterOptionsGet);
+
+ aNewValue <<= OUString("NewValue");
+ xSheetLink->setPropertyValue(propName, aNewValue);
+ CPPUNIT_ASSERT(xSheetLink->getPropertyValue(propName) >>= aFilterOptionsSet);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Unable to set PropertyValue FilterOptions", OUString("NewValue"),
+ aFilterOptionsSet);
+}
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/test/source/sheet/sheetsortdescriptor2.cxx b/test/source/sheet/sheetsortdescriptor2.cxx
new file mode 100644
index 0000000000..3f84d9577f
--- /dev/null
+++ b/test/source/sheet/sheetsortdescriptor2.cxx
@@ -0,0 +1,123 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * 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 <test/cppunitasserthelper.hxx>
+#include <test/sheet/sheetsortdescriptor2.hxx>
+
+#include <com/sun/star/beans/PropertyValue.hpp>
+#include <com/sun/star/util/XSortable.hpp>
+#include <com/sun/star/table/CellAddress.hpp>
+#include <com/sun/star/table/TableSortField.hpp>
+#include <com/sun/star/uno/Reference.hxx>
+#include <com/sun/star/uno/Sequence.hxx>
+
+#include <cppunit/TestAssert.h>
+
+#include <vector>
+
+using namespace com::sun::star;
+using namespace com::sun::star::uno;
+
+namespace apitest
+{
+void SheetSortDescriptor2::testSheetSortDescriptor2Properties()
+{
+ uno::Reference<util::XSortable> xSortable(init(), UNO_QUERY_THROW);
+ const uno::Sequence<beans::PropertyValue> values = xSortable->createSortDescriptor();
+
+ std::vector<OUString> names;
+ // Only test the get/read operation of the values, because set/write operation doesn't
+ // make any sense. It doesn't trigger any changes.
+ // See discussion: nabble.documentfoundation.org/Testing-UNO-API-service-properties-td4236286.html.
+ for (const auto& value : values)
+ {
+ if (value.Name == "BindFormatsToContent")
+ {
+ names.push_back(value.Name);
+ bool bValue = false;
+ CPPUNIT_ASSERT(value.Value >>= bValue);
+ }
+ else if (value.Name == "IsUserListEnabled")
+ {
+ names.push_back(value.Name);
+ bool bValue = false;
+ CPPUNIT_ASSERT(value.Value >>= bValue);
+ }
+ else if (value.Name == "UserListIndex")
+ {
+ names.push_back(value.Name);
+ sal_Int32 nValue = 0;
+ CPPUNIT_ASSERT(value.Value >>= nValue);
+ }
+ else if (value.Name == "CopyOutputData")
+ {
+ names.push_back(value.Name);
+ bool bValue = false;
+ CPPUNIT_ASSERT(value.Value >>= bValue);
+ }
+ else if (value.Name == "OutputPosition")
+ {
+ names.push_back(value.Name);
+ table::CellAddress cellAddr;
+ CPPUNIT_ASSERT(value.Value >>= cellAddr);
+ }
+ else if (value.Name == "SortFields")
+ {
+ names.push_back(value.Name);
+ uno::Sequence<table::TableSortField> sSortFields;
+ CPPUNIT_ASSERT(value.Value >>= sSortFields);
+ }
+ else if (value.Name == "MaxFieldCount")
+ {
+ names.push_back(value.Name);
+ sal_Int32 nValue = 0;
+ CPPUNIT_ASSERT(value.Value >>= nValue);
+ }
+ else if (value.Name == "IsSortColumns")
+ {
+ names.push_back(value.Name);
+ bool bValue = false;
+ CPPUNIT_ASSERT(value.Value >>= bValue);
+ }
+ else if (value.Name == "ContainsHeader")
+ {
+ names.push_back(value.Name);
+ bool bValue = false;
+ CPPUNIT_ASSERT(value.Value >>= bValue);
+ }
+ else
+ {
+ OString sMsg = "Unsupported PropertyValue: "
+ + OUStringToOString(value.Name, RTL_TEXTENCODING_UTF8);
+ CPPUNIT_FAIL(sMsg.getStr());
+ }
+ }
+
+ CPPUNIT_ASSERT_MESSAGE("Property BindFormatsToContent not found",
+ std::count(std::begin(names), std::end(names), "BindFormatsToContent"));
+ CPPUNIT_ASSERT_MESSAGE("Property IsUserListEnabled not found",
+ std::count(std::begin(names), std::end(names), "IsUserListEnabled"));
+ CPPUNIT_ASSERT_MESSAGE("Property UserListIndex not found",
+ std::count(std::begin(names), std::end(names), "UserListIndex"));
+ CPPUNIT_ASSERT_MESSAGE("Property CopyOutputData not found",
+ std::count(std::begin(names), std::end(names), "CopyOutputData"));
+ CPPUNIT_ASSERT_MESSAGE("Property OutputPosition not found",
+ std::count(std::begin(names), std::end(names), "OutputPosition"));
+ CPPUNIT_ASSERT_MESSAGE("Property SortFields not found",
+ std::count(std::begin(names), std::end(names), "SortFields"));
+ CPPUNIT_ASSERT_MESSAGE("Property MaxFieldCount not found",
+ std::count(std::begin(names), std::end(names), "MaxFieldCount"));
+ CPPUNIT_ASSERT_MESSAGE("Property IsSortColumns not found",
+ std::count(std::begin(names), std::end(names), "IsSortColumns"));
+ CPPUNIT_ASSERT_MESSAGE("Property ContainsHeader not found",
+ std::count(std::begin(names), std::end(names), "ContainsHeader"));
+}
+} // namespace apitest
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/test/source/sheet/spreadsheet.cxx b/test/source/sheet/spreadsheet.cxx
new file mode 100644
index 0000000000..8e2ca12cf8
--- /dev/null
+++ b/test/source/sheet/spreadsheet.cxx
@@ -0,0 +1,90 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * 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 <test/sheet/spreadsheet.hxx>
+#include <test/unoapi_property_testers.hxx>
+
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/container/XIndexAccess.hpp>
+#include <com/sun/star/container/XNameContainer.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/sheet/XConditionalFormats.hpp>
+#include <com/sun/star/sheet/XSpreadsheetDocument.hpp>
+#include <com/sun/star/sheet/XSpreadsheet.hpp>
+#include <com/sun/star/text/WritingMode2.hpp>
+#include <com/sun/star/util/Color.hpp>
+#include <com/sun/star/uno/Any.hxx>
+#include <com/sun/star/uno/Reference.hxx>
+
+#include <cppunit/TestAssert.h>
+
+using namespace com::sun::star;
+using namespace com::sun::star::uno;
+
+namespace apitest
+{
+void Spreadsheet::testSpreadsheetProperties()
+{
+ uno::Reference<beans::XPropertySet> xSpreadsheet(init(), UNO_QUERY_THROW);
+ OUString propName;
+ uno::Any aNewValue;
+
+ propName = "IsVisible";
+ testBooleanProperty(xSpreadsheet, propName);
+
+ propName = "PageStyle";
+ testStringProperty(xSpreadsheet, propName, "Report");
+
+ propName = "TableLayout";
+ testShortProperty(xSpreadsheet, propName, text::WritingMode2::RL_TB);
+
+ propName = "AutomaticPrintArea";
+ testBooleanProperty(xSpreadsheet, propName);
+
+ propName = "TabColor";
+ util::Color aColorGet;
+ util::Color aColorSet;
+ CPPUNIT_ASSERT_MESSAGE("Unable to get PropertyValue: TabColor",
+ xSpreadsheet->getPropertyValue(propName) >>= aColorGet);
+
+ aNewValue <<= util::Color(42);
+ xSpreadsheet->setPropertyValue(propName, aNewValue);
+ CPPUNIT_ASSERT(xSpreadsheet->getPropertyValue(propName) >>= aColorSet);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Unable to set PropertyValue: TabColor", util::Color(42),
+ aColorSet);
+
+ propName = "ConditionalFormats";
+ uno::Reference<sheet::XConditionalFormats> xConditionalFormatsGet;
+ uno::Reference<sheet::XConditionalFormats> xConditionalFormatsSet;
+ CPPUNIT_ASSERT_MESSAGE("Unable to get PropertyValue: ConditionalFormats",
+ xSpreadsheet->getPropertyValue(propName) >>= xConditionalFormatsGet);
+
+ uno::Reference<sheet::XSpreadsheetDocument> xDoc(getXSpreadsheetDocument(), UNO_QUERY_THROW);
+ uno::Reference<container::XIndexAccess> xIA(xDoc->getSheets(), UNO_QUERY_THROW);
+ uno::Reference<sheet::XSpreadsheet> xSheet(xIA->getByIndex(0), UNO_QUERY_THROW);
+
+ uno::Reference<lang::XMultiServiceFactory> xMSF(xDoc, UNO_QUERY_THROW);
+ uno::Reference<container::XNameContainer> xRanges(
+ xMSF->createInstance("com.sun.star.sheet.SheetCellRanges"), UNO_QUERY_THROW);
+ uno::Reference<sheet::XSheetCellRanges> xSheetCellRanges(xRanges, UNO_QUERY_THROW);
+
+ uno::Any xCellRange;
+ xCellRange <<= xSheet->getCellRangeByName("C1:D4");
+ xRanges->insertByName("Range1", xCellRange);
+ xConditionalFormatsGet->createByRange(xSheetCellRanges);
+
+ aNewValue <<= xConditionalFormatsGet;
+ xSpreadsheet->setPropertyValue(propName, aNewValue);
+ CPPUNIT_ASSERT(xSpreadsheet->getPropertyValue(propName) >>= xConditionalFormatsSet);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Unable to set PropertyValue: ConditionalFormats", sal_Int32(1),
+ xConditionalFormatsSet->getLength());
+}
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/test/source/sheet/spreadsheetdocumentsettings.cxx b/test/source/sheet/spreadsheetdocumentsettings.cxx
new file mode 100644
index 0000000000..a1eec4d0de
--- /dev/null
+++ b/test/source/sheet/spreadsheetdocumentsettings.cxx
@@ -0,0 +1,190 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * 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 <test/unoapi_property_testers.hxx>
+#include <test/sheet/spreadsheetdocumentsettings.hxx>
+
+#include <com/sun/star/awt/XDevice.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/lang/Locale.hpp>
+#include <com/sun/star/i18n/XForbiddenCharacters.hpp>
+#include <com/sun/star/util/Date.hpp>
+#include <com/sun/star/uno/Any.hxx>
+#include <com/sun/star/uno/Reference.hxx>
+
+#include <cppunit/TestAssert.h>
+
+using namespace com::sun::star;
+using namespace com::sun::star::uno;
+
+namespace apitest
+{
+void SpreadsheetDocumentSettings::testSpreadsheetDocumentSettingsProperties()
+{
+ uno::Reference<beans::XPropertySet> xSpreadsheetDocumentSettings(init(), UNO_QUERY_THROW);
+ OUString propName;
+ uno::Any aNewValue;
+
+ propName = "IsIterationEnabled";
+ testBooleanProperty(xSpreadsheetDocumentSettings, propName);
+
+ propName = "IterationCount";
+ testLongProperty(xSpreadsheetDocumentSettings, propName);
+
+ propName = "IterationEpsilon";
+ testDoubleProperty(xSpreadsheetDocumentSettings, propName);
+
+ propName = "StandardDecimals";
+ testShortProperty(xSpreadsheetDocumentSettings, propName);
+
+ propName = "NullDate";
+ util::Date aNullDateGet;
+ util::Date aNullDateSet;
+ CPPUNIT_ASSERT_MESSAGE("Unable to get PropertyValue: NullDate",
+ xSpreadsheetDocumentSettings->getPropertyValue(propName)
+ >>= aNullDateGet);
+
+ aNewValue <<= util::Date(1, 1, 2000);
+ xSpreadsheetDocumentSettings->setPropertyValue(propName, aNewValue);
+ CPPUNIT_ASSERT(xSpreadsheetDocumentSettings->getPropertyValue(propName) >>= aNullDateSet);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Unable to set PropertyValue: NullDate", sal_Int16(2000),
+ aNullDateSet.Year);
+
+ propName = "DefaultTabStop";
+ testShortProperty(xSpreadsheetDocumentSettings, propName);
+
+ propName = "IgnoreCase";
+ testBooleanProperty(xSpreadsheetDocumentSettings, propName);
+
+ propName = "CalcAsShown";
+ testBooleanProperty(xSpreadsheetDocumentSettings, propName);
+
+ propName = "MatchWholeCell";
+ testBooleanProperty(xSpreadsheetDocumentSettings, propName);
+
+ propName = "SpellOnline";
+ testBooleanProperty(xSpreadsheetDocumentSettings, propName);
+
+ propName = "LookUpLabels";
+ testBooleanProperty(xSpreadsheetDocumentSettings, propName);
+
+ propName = "RegularExpressions";
+ testBooleanProperty(xSpreadsheetDocumentSettings, propName);
+
+ propName = "ForbiddenCharacters";
+ uno::Reference<i18n::XForbiddenCharacters> xForbiddenCharactersGet;
+ uno::Reference<i18n::XForbiddenCharacters> xForbiddenCharactersSet;
+ CPPUNIT_ASSERT_MESSAGE("Unable to get PropertyValue: ForbiddenCharacters",
+ xSpreadsheetDocumentSettings->getPropertyValue(propName)
+ >>= xForbiddenCharactersGet);
+
+ lang::Locale aForbiddenCharactersLocale;
+ aForbiddenCharactersLocale.Language = "ru";
+ aForbiddenCharactersLocale.Country = "RU";
+
+ uno::Reference<i18n::XForbiddenCharacters> xForbiddenCharactersNew;
+ aNewValue <<= xForbiddenCharactersNew;
+ xSpreadsheetDocumentSettings->setPropertyValue(propName, aNewValue);
+ CPPUNIT_ASSERT(xSpreadsheetDocumentSettings->getPropertyValue(propName)
+ >>= xForbiddenCharactersSet);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(
+ "Able to set PropertyValue: ForbiddenCharacters",
+ xForbiddenCharactersGet->hasForbiddenCharacters(aForbiddenCharactersLocale),
+ xForbiddenCharactersSet->hasForbiddenCharacters(aForbiddenCharactersLocale));
+
+ propName = "HasDrawPages";
+ testBooleanReadonlyProperty(xSpreadsheetDocumentSettings, propName);
+
+ propName = "CharLocale";
+ lang::Locale aCharLocaleGet;
+ lang::Locale aCharLocaleSet;
+ CPPUNIT_ASSERT_MESSAGE("Unable to get PropertyValue: CharLocale",
+ xSpreadsheetDocumentSettings->getPropertyValue(propName)
+ >>= aCharLocaleGet);
+
+ lang::Locale aCharLocaleNew;
+ aCharLocaleNew.Language = "en";
+ aCharLocaleNew.Country = "CA";
+ aNewValue <<= aCharLocaleNew;
+ xSpreadsheetDocumentSettings->setPropertyValue(propName, aNewValue);
+ CPPUNIT_ASSERT(xSpreadsheetDocumentSettings->getPropertyValue(propName) >>= aCharLocaleSet);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Unable to set PropertyValue: CharLocale", aCharLocaleNew.Country,
+ aCharLocaleSet.Country);
+
+ propName = "CharLocaleAsian";
+ lang::Locale aCharLocaleAsianGet;
+ lang::Locale aCharLocaleAsianSet;
+ CPPUNIT_ASSERT_MESSAGE("Unable to get PropertyValue: CharLocaleAsian",
+ xSpreadsheetDocumentSettings->getPropertyValue(propName)
+ >>= aCharLocaleAsianGet);
+
+ lang::Locale aCharLocaleAsianNew;
+ aCharLocaleAsianNew.Language = "en";
+ aCharLocaleAsianNew.Country = "CA";
+ aNewValue <<= aCharLocaleAsianNew;
+ xSpreadsheetDocumentSettings->setPropertyValue(propName, aNewValue);
+ CPPUNIT_ASSERT(xSpreadsheetDocumentSettings->getPropertyValue(propName)
+ >>= aCharLocaleAsianSet);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Unable to set PropertyValue: CharLocaleAsian",
+ aCharLocaleAsianNew.Country, aCharLocaleAsianSet.Country);
+
+ propName = "CharLocaleComplex";
+ lang::Locale aCharLocaleComplexGet;
+ lang::Locale aCharLocaleComplexSet;
+ CPPUNIT_ASSERT_MESSAGE("Unable to get PropertyValue: CharLocaleComplex",
+ xSpreadsheetDocumentSettings->getPropertyValue(propName)
+ >>= aCharLocaleComplexGet);
+
+ lang::Locale aCharLocaleComplexNew;
+ aCharLocaleComplexNew.Language = "en";
+ aCharLocaleComplexNew.Country = "CA";
+ aNewValue <<= aCharLocaleComplexNew;
+ xSpreadsheetDocumentSettings->setPropertyValue(propName, aNewValue);
+ CPPUNIT_ASSERT(xSpreadsheetDocumentSettings->getPropertyValue(propName)
+ >>= aCharLocaleComplexSet);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Unable to set PropertyValue: CharLocaleComplex",
+ aCharLocaleComplexNew.Country, aCharLocaleComplexSet.Country);
+
+ propName = "IsLoaded";
+ testBooleanProperty(xSpreadsheetDocumentSettings, propName);
+
+ propName = "IsUndoEnabled";
+ testBooleanProperty(xSpreadsheetDocumentSettings, propName);
+
+ propName = "IsAdjustHeightEnabled";
+ testBooleanProperty(xSpreadsheetDocumentSettings, propName);
+
+ propName = "IsExecuteLinkEnabled";
+ testBooleanProperty(xSpreadsheetDocumentSettings, propName);
+
+ propName = "ReferenceDevice";
+ uno::Reference<awt::XDevice> xDeviceGet;
+ uno::Reference<awt::XDevice> xDeviceSet;
+ CPPUNIT_ASSERT_MESSAGE("Unable to get PropertyValue: ReferenceDevice",
+ xSpreadsheetDocumentSettings->getPropertyValue(propName) >>= xDeviceGet);
+
+ uno::Reference<awt::XDevice> xDeviceNew;
+ aNewValue <<= xDeviceNew;
+ xSpreadsheetDocumentSettings->setPropertyValue(propName, aNewValue);
+ CPPUNIT_ASSERT(xSpreadsheetDocumentSettings->getPropertyValue(propName) >>= xDeviceSet);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Able to set PropertyValue: ReferenceDevice",
+ xDeviceSet->getInfo().Width, xDeviceGet->getInfo().Width);
+
+ propName = "RecordChanges";
+ testBooleanProperty(xSpreadsheetDocumentSettings, propName);
+
+ propName = "IsRecordChangesProtected";
+ testBooleanReadonlyProperty(xSpreadsheetDocumentSettings, propName);
+
+ propName = "Wildcards";
+ testBooleanProperty(xSpreadsheetDocumentSettings, propName);
+}
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/test/source/sheet/spreadsheetviewsettings.cxx b/test/source/sheet/spreadsheetviewsettings.cxx
new file mode 100644
index 0000000000..1a5916dcfe
--- /dev/null
+++ b/test/source/sheet/spreadsheetviewsettings.cxx
@@ -0,0 +1,251 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * 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 <test/sheet/spreadsheetviewsettings.hxx>
+
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/util/Color.hpp>
+#include <com/sun/star/uno/Any.hxx>
+#include <com/sun/star/uno/Reference.hxx>
+
+#include <cppunit/TestAssert.h>
+
+using namespace com::sun::star;
+using namespace com::sun::star::uno;
+
+namespace apitest
+{
+void SpreadsheetViewSettings::testSpreadsheetViewSettingsProperties()
+{
+ uno::Reference<beans::XPropertySet> xSpreadsheetViewSettings(init(), UNO_QUERY_THROW);
+ OUString propName;
+ uno::Any aNewValue;
+
+ propName = "ShowFormulas";
+ bool aShowFormulas = true;
+ CPPUNIT_ASSERT(xSpreadsheetViewSettings->getPropertyValue(propName) >>= aShowFormulas);
+ CPPUNIT_ASSERT_MESSAGE("Unable to get PropertyValue ShowFormulas", !aShowFormulas);
+
+ aNewValue <<= true;
+ xSpreadsheetViewSettings->setPropertyValue(propName, aNewValue);
+ CPPUNIT_ASSERT(xSpreadsheetViewSettings->getPropertyValue(propName) >>= aShowFormulas);
+ CPPUNIT_ASSERT_MESSAGE("Unable to set PropertyValue ShowFormulas", aShowFormulas);
+
+ propName = "ShowZeroValues";
+ bool aShowZeroValues = false;
+ CPPUNIT_ASSERT(xSpreadsheetViewSettings->getPropertyValue(propName) >>= aShowZeroValues);
+ CPPUNIT_ASSERT_MESSAGE("Unable to get PropertyValue ShowZeroValues", aShowZeroValues);
+
+ aNewValue <<= false;
+ xSpreadsheetViewSettings->setPropertyValue(propName, aNewValue);
+ CPPUNIT_ASSERT(xSpreadsheetViewSettings->getPropertyValue(propName) >>= aShowZeroValues);
+ CPPUNIT_ASSERT_MESSAGE("Unable to set PropertyValue ShowZeroValues", !aShowZeroValues);
+
+ propName = "IsValueHighlightingEnabled";
+ bool aIsValueHighlightingEnabled = true;
+ CPPUNIT_ASSERT(xSpreadsheetViewSettings->getPropertyValue(propName)
+ >>= aIsValueHighlightingEnabled);
+ CPPUNIT_ASSERT_MESSAGE("Unable to get PropertyValue IsValueHighlightingEnabled",
+ !aIsValueHighlightingEnabled);
+
+ aNewValue <<= true;
+ xSpreadsheetViewSettings->setPropertyValue(propName, aNewValue);
+ CPPUNIT_ASSERT(xSpreadsheetViewSettings->getPropertyValue(propName)
+ >>= aIsValueHighlightingEnabled);
+ CPPUNIT_ASSERT_MESSAGE("Unable to set PropertyValue IsValueHighlightingEnabled",
+ aIsValueHighlightingEnabled);
+
+ propName = "ShowNotes";
+ bool aShowNotes = false;
+ CPPUNIT_ASSERT(xSpreadsheetViewSettings->getPropertyValue(propName) >>= aShowNotes);
+ CPPUNIT_ASSERT_MESSAGE("Unable to get PropertyValue ShowNotes", aShowNotes);
+
+ aNewValue <<= false;
+ xSpreadsheetViewSettings->setPropertyValue(propName, aNewValue);
+ CPPUNIT_ASSERT(xSpreadsheetViewSettings->getPropertyValue(propName) >>= aShowNotes);
+ CPPUNIT_ASSERT_MESSAGE("Unable to set PropertyValue ShowNotes", !aShowNotes);
+
+ propName = "HasVerticalScrollBar";
+ bool aHasVerticalScrollBar = false;
+ CPPUNIT_ASSERT(xSpreadsheetViewSettings->getPropertyValue(propName) >>= aHasVerticalScrollBar);
+ CPPUNIT_ASSERT_MESSAGE("Unable to get PropertyValue HasVerticalScrollBar",
+ aHasVerticalScrollBar);
+
+ aNewValue <<= false;
+ xSpreadsheetViewSettings->setPropertyValue(propName, aNewValue);
+ CPPUNIT_ASSERT(xSpreadsheetViewSettings->getPropertyValue(propName) >>= aHasVerticalScrollBar);
+ CPPUNIT_ASSERT_MESSAGE("Unable to set PropertyValue HasVerticalScrollBar",
+ !aHasVerticalScrollBar);
+
+ propName = "HasHorizontalScrollBar";
+ bool aHasHorizontalScrollBar = false;
+ CPPUNIT_ASSERT(xSpreadsheetViewSettings->getPropertyValue(propName)
+ >>= aHasHorizontalScrollBar);
+ CPPUNIT_ASSERT_MESSAGE("Unable to get PropertyValue HasHorizontalScrollBar",
+ aHasHorizontalScrollBar);
+
+ aNewValue <<= false;
+ xSpreadsheetViewSettings->setPropertyValue(propName, aNewValue);
+ CPPUNIT_ASSERT(xSpreadsheetViewSettings->getPropertyValue(propName)
+ >>= aHasHorizontalScrollBar);
+ CPPUNIT_ASSERT_MESSAGE("Unable to set PropertyValue HasHorizontalScrollBar",
+ !aHasHorizontalScrollBar);
+
+ propName = "HasSheetTabs";
+ bool aHasSheetTabs = false;
+ CPPUNIT_ASSERT(xSpreadsheetViewSettings->getPropertyValue(propName) >>= aHasSheetTabs);
+ CPPUNIT_ASSERT_MESSAGE("Unable to get PropertyValue HasSheetTabs", aHasSheetTabs);
+
+ aNewValue <<= false;
+ xSpreadsheetViewSettings->setPropertyValue(propName, aNewValue);
+ CPPUNIT_ASSERT(xSpreadsheetViewSettings->getPropertyValue(propName) >>= aHasSheetTabs);
+ CPPUNIT_ASSERT_MESSAGE("Unable to set PropertyValue HasSheetTabs", !aHasSheetTabs);
+
+ propName = "IsOutlineSymbolsSet";
+ bool aIsOutlineSymbolsSet = false;
+ CPPUNIT_ASSERT(xSpreadsheetViewSettings->getPropertyValue(propName) >>= aIsOutlineSymbolsSet);
+ CPPUNIT_ASSERT_MESSAGE("Unable to get PropertyValue IsOutlineSymbolsSet", aIsOutlineSymbolsSet);
+
+ aNewValue <<= false;
+ xSpreadsheetViewSettings->setPropertyValue(propName, aNewValue);
+ CPPUNIT_ASSERT(xSpreadsheetViewSettings->getPropertyValue(propName) >>= aIsOutlineSymbolsSet);
+ CPPUNIT_ASSERT_MESSAGE("Unable to set PropertyValue IsOutlineSymbolsSet",
+ !aIsOutlineSymbolsSet);
+
+ propName = "HasColumnRowHeaders";
+ bool aHasColumnRowHeaders = false;
+ CPPUNIT_ASSERT(xSpreadsheetViewSettings->getPropertyValue(propName) >>= aHasColumnRowHeaders);
+ CPPUNIT_ASSERT_MESSAGE("Unable to get PropertyValue HasColumnRowHeaders", aHasColumnRowHeaders);
+
+ aNewValue <<= false;
+ xSpreadsheetViewSettings->setPropertyValue(propName, aNewValue);
+ CPPUNIT_ASSERT(xSpreadsheetViewSettings->getPropertyValue(propName) >>= aHasColumnRowHeaders);
+ CPPUNIT_ASSERT_MESSAGE("Unable to set PropertyValue HasColumnRowHeaders",
+ !aHasColumnRowHeaders);
+
+ propName = "ShowGrid";
+ bool aShowGrid = false;
+ CPPUNIT_ASSERT(xSpreadsheetViewSettings->getPropertyValue(propName) >>= aShowGrid);
+ CPPUNIT_ASSERT_MESSAGE("Unable to get PropertyValue ShowGrid", aShowGrid);
+
+ aNewValue <<= false;
+ xSpreadsheetViewSettings->setPropertyValue(propName, aNewValue);
+ CPPUNIT_ASSERT(xSpreadsheetViewSettings->getPropertyValue(propName) >>= aShowGrid);
+ CPPUNIT_ASSERT_MESSAGE("Unable to set PropertyValue ShowGrid", !aShowGrid);
+
+ propName = "GridColor";
+ util::Color aGridColor;
+ xSpreadsheetViewSettings->getPropertyValue(propName) >>= aGridColor;
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Unable to get PropertyValue GridColor", sal_Int32(12632256),
+ aGridColor);
+
+ aNewValue <<= sal_Int32(42);
+ xSpreadsheetViewSettings->setPropertyValue(propName, aNewValue);
+ xSpreadsheetViewSettings->getPropertyValue(propName) >>= aGridColor;
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Unable to set PropertyValue GridColor", sal_Int32(42),
+ aGridColor);
+
+ propName = "ShowHelpLines";
+ bool aShowHelpLines = true;
+ CPPUNIT_ASSERT(xSpreadsheetViewSettings->getPropertyValue(propName) >>= aShowHelpLines);
+ CPPUNIT_ASSERT_MESSAGE("Unable to get PropertyValue ShowHelpLines", !aShowHelpLines);
+
+ aNewValue <<= true;
+ xSpreadsheetViewSettings->setPropertyValue(propName, aNewValue);
+ CPPUNIT_ASSERT(xSpreadsheetViewSettings->getPropertyValue(propName) >>= aShowHelpLines);
+ CPPUNIT_ASSERT_MESSAGE("Unable to set PropertyValue ShowHelpLines", aShowHelpLines);
+
+ propName = "ShowAnchor";
+ bool aShowAnchor = false;
+ CPPUNIT_ASSERT(xSpreadsheetViewSettings->getPropertyValue(propName) >>= aShowAnchor);
+ CPPUNIT_ASSERT_MESSAGE("Unable to get PropertyValue ShowAnchor", aShowAnchor);
+
+ aNewValue <<= false;
+ xSpreadsheetViewSettings->setPropertyValue(propName, aNewValue);
+ CPPUNIT_ASSERT(xSpreadsheetViewSettings->getPropertyValue(propName) >>= aShowAnchor);
+ CPPUNIT_ASSERT_MESSAGE("Unable to set PropertyValue ShowAnchor", !aShowAnchor);
+
+ propName = "ShowPageBreaks";
+ bool aShowPageBreaks = false;
+ CPPUNIT_ASSERT(xSpreadsheetViewSettings->getPropertyValue(propName) >>= aShowPageBreaks);
+ CPPUNIT_ASSERT_MESSAGE("Unable to get PropertyValue ShowPageBreaks", aShowPageBreaks);
+
+ aNewValue <<= false;
+ xSpreadsheetViewSettings->setPropertyValue(propName, aNewValue);
+ CPPUNIT_ASSERT(xSpreadsheetViewSettings->getPropertyValue(propName) >>= aShowPageBreaks);
+ CPPUNIT_ASSERT_MESSAGE("Unable to set PropertyValue ShowPageBreaks", !aShowPageBreaks);
+
+ propName = "ShowObjects";
+ sal_Int16 aShowObjects = 42;
+ CPPUNIT_ASSERT(xSpreadsheetViewSettings->getPropertyValue(propName) >>= aShowObjects);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Unable to get PropertyValue ShowObjects", sal_Int16(0),
+ aShowObjects);
+
+ aNewValue <<= sal_Int16(1);
+ xSpreadsheetViewSettings->setPropertyValue(propName, aNewValue);
+ CPPUNIT_ASSERT(xSpreadsheetViewSettings->getPropertyValue(propName) >>= aShowObjects);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Unable to set PropertyValue ShowObjects", sal_Int16(1),
+ aShowObjects);
+
+ propName = "ShowCharts";
+ sal_Int16 aShowCharts = 42;
+ CPPUNIT_ASSERT(xSpreadsheetViewSettings->getPropertyValue(propName) >>= aShowCharts);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Unable to get PropertyValue ShowCharts", sal_Int16(0),
+ aShowCharts);
+
+ aNewValue <<= sal_Int16(1);
+ xSpreadsheetViewSettings->setPropertyValue(propName, aNewValue);
+ CPPUNIT_ASSERT(xSpreadsheetViewSettings->getPropertyValue(propName) >>= aShowCharts);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Unable to set PropertyValue ShowCharts", sal_Int16(1),
+ aShowCharts);
+
+ propName = "ShowDrawing";
+ sal_Int16 aShowDrawing = 42;
+ CPPUNIT_ASSERT(xSpreadsheetViewSettings->getPropertyValue(propName) >>= aShowDrawing);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Unable to get PropertyValue ShowDrawing", sal_Int16(0),
+ aShowDrawing);
+
+ aNewValue <<= sal_Int16(1);
+ xSpreadsheetViewSettings->setPropertyValue(propName, aNewValue);
+ CPPUNIT_ASSERT(xSpreadsheetViewSettings->getPropertyValue(propName) >>= aShowDrawing);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Unable to set PropertyValue ShowDrawing", sal_Int16(1),
+ aShowDrawing);
+
+ propName = "ZoomType";
+ sal_Int16 aZoomType = 42;
+ CPPUNIT_ASSERT(xSpreadsheetViewSettings->getPropertyValue(propName) >>= aZoomType);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Unable to get PropertyValue ZoomType", sal_Int16(3), aZoomType);
+
+ aNewValue <<= sal_Int16(1);
+ xSpreadsheetViewSettings->setPropertyValue(propName, aNewValue);
+ CPPUNIT_ASSERT(xSpreadsheetViewSettings->getPropertyValue(propName) >>= aZoomType);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Unable to set PropertyValue ZoomType", sal_Int16(1), aZoomType);
+
+ propName = "ZoomValue";
+ sal_Int16 aZoomValue = 42;
+ CPPUNIT_ASSERT(xSpreadsheetViewSettings->getPropertyValue(propName) >>= aZoomValue);
+
+ aNewValue <<= sal_Int16(1);
+ xSpreadsheetViewSettings->setPropertyValue(propName, aNewValue);
+ CPPUNIT_ASSERT(xSpreadsheetViewSettings->getPropertyValue(propName) >>= aZoomValue);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Unable to set PropertyValue ZoomValue", sal_Int16(1), aZoomValue);
+
+ propName = "FormulaBarHeight";
+ sal_Int16 aFormulaBarHeight;
+ CPPUNIT_ASSERT(xSpreadsheetViewSettings->getPropertyValue(propName) >>= aFormulaBarHeight);
+
+ aNewValue <<= sal_Int16(15);
+ xSpreadsheetViewSettings->setPropertyValue(propName, aNewValue);
+ CPPUNIT_ASSERT(xSpreadsheetViewSettings->getPropertyValue(propName) >>= aFormulaBarHeight);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Unable to set PropertyValue FormulaBarHeight", sal_Int16(15),
+ aFormulaBarHeight);
+}
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/test/source/sheet/subtotaldescriptor.cxx b/test/source/sheet/subtotaldescriptor.cxx
new file mode 100644
index 0000000000..e9dffdb752
--- /dev/null
+++ b/test/source/sheet/subtotaldescriptor.cxx
@@ -0,0 +1,116 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * 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 <test/sheet/subtotaldescriptor.hxx>
+
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/uno/Any.hxx>
+#include <com/sun/star/uno/Reference.hxx>
+
+#include <cppunit/TestAssert.h>
+
+using namespace com::sun::star;
+using namespace com::sun::star::uno;
+
+namespace apitest
+{
+void SubTotalDescriptor::testSubTotalDescriptorProperties()
+{
+ uno::Reference<beans::XPropertySet> xSubTotalDescriptor(init(), UNO_QUERY_THROW);
+ OUString propName;
+ uno::Any aNewValue;
+
+ propName = "InsertPageBreaks";
+ bool aInsertPageBreaks = true;
+ CPPUNIT_ASSERT(xSubTotalDescriptor->getPropertyValue(propName) >>= aInsertPageBreaks);
+ CPPUNIT_ASSERT_MESSAGE("Unable to get PropertyValue InsertPageBreaks", !aInsertPageBreaks);
+
+ aNewValue <<= true;
+ xSubTotalDescriptor->setPropertyValue(propName, aNewValue);
+ CPPUNIT_ASSERT(xSubTotalDescriptor->getPropertyValue(propName) >>= aInsertPageBreaks);
+ CPPUNIT_ASSERT_MESSAGE("Unable to set PropertyValue InsertPageBreaks", aInsertPageBreaks);
+
+ propName = "IsCaseSensitive";
+ bool aIsCaseSensitive = true;
+ CPPUNIT_ASSERT(xSubTotalDescriptor->getPropertyValue(propName) >>= aIsCaseSensitive);
+ CPPUNIT_ASSERT_MESSAGE("Unable to get PropertyValue IsCaseSensitive", !aIsCaseSensitive);
+
+ aNewValue <<= true;
+ xSubTotalDescriptor->setPropertyValue(propName, aNewValue);
+ CPPUNIT_ASSERT(xSubTotalDescriptor->getPropertyValue(propName) >>= aIsCaseSensitive);
+ CPPUNIT_ASSERT_MESSAGE("Unable to set PropertyValue IsCaseSensitive", aIsCaseSensitive);
+
+ propName = "EnableUserSortList";
+ bool aEnableUserSortList = true;
+ CPPUNIT_ASSERT(xSubTotalDescriptor->getPropertyValue(propName) >>= aEnableUserSortList);
+ CPPUNIT_ASSERT_MESSAGE("Unable to get PropertyValue EnableUserSortList", !aEnableUserSortList);
+
+ aNewValue <<= true;
+ xSubTotalDescriptor->setPropertyValue(propName, aNewValue);
+ CPPUNIT_ASSERT(xSubTotalDescriptor->getPropertyValue(propName) >>= aEnableUserSortList);
+ CPPUNIT_ASSERT_MESSAGE("Unable to set PropertyValue EnableUserSortList", aEnableUserSortList);
+
+ propName = "UserSortListIndex";
+ sal_Int32 aUserSortListIndex = 42;
+ CPPUNIT_ASSERT(xSubTotalDescriptor->getPropertyValue(propName) >>= aUserSortListIndex);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Unable to get PropertyValue UserSortListIndex", sal_Int32(0),
+ aUserSortListIndex);
+
+ aNewValue <<= sal_Int32(42);
+ xSubTotalDescriptor->setPropertyValue(propName, aNewValue);
+ CPPUNIT_ASSERT(xSubTotalDescriptor->getPropertyValue(propName) >>= aUserSortListIndex);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Unable to set PropertyValue UserSortListIndex", sal_Int32(42),
+ aUserSortListIndex);
+
+ propName = "BindFormatsToContent";
+ bool aBindFormatsToContent = true;
+ CPPUNIT_ASSERT(xSubTotalDescriptor->getPropertyValue(propName) >>= aBindFormatsToContent);
+ CPPUNIT_ASSERT_MESSAGE("Unable to get PropertyValue BindFormatsToContent",
+ !aBindFormatsToContent);
+
+ aNewValue <<= true;
+ xSubTotalDescriptor->setPropertyValue(propName, aNewValue);
+ CPPUNIT_ASSERT(xSubTotalDescriptor->getPropertyValue(propName) >>= aBindFormatsToContent);
+ CPPUNIT_ASSERT_MESSAGE("Unable to set PropertyValue BindFormatsToContent",
+ aBindFormatsToContent);
+
+ propName = "EnableSort";
+ bool aEnableSort = false;
+ CPPUNIT_ASSERT(xSubTotalDescriptor->getPropertyValue(propName) >>= aEnableSort);
+ CPPUNIT_ASSERT_MESSAGE("Unable to get PropertyValue EnableSort", aEnableSort);
+
+ aNewValue <<= false;
+ xSubTotalDescriptor->setPropertyValue(propName, aNewValue);
+ CPPUNIT_ASSERT(xSubTotalDescriptor->getPropertyValue(propName) >>= aEnableSort);
+ CPPUNIT_ASSERT_MESSAGE("Unable to set PropertyValue EnableSort", !aEnableSort);
+
+ propName = "SortAscending";
+ bool aSortAscending = false;
+ CPPUNIT_ASSERT(xSubTotalDescriptor->getPropertyValue(propName) >>= aSortAscending);
+ CPPUNIT_ASSERT_MESSAGE("Unable to get PropertyValue SortAscending", aSortAscending);
+
+ aNewValue <<= false;
+ xSubTotalDescriptor->setPropertyValue(propName, aNewValue);
+ CPPUNIT_ASSERT(xSubTotalDescriptor->getPropertyValue(propName) >>= aSortAscending);
+ CPPUNIT_ASSERT_MESSAGE("Unable to set PropertyValue SortAscending", !aSortAscending);
+
+ propName = "MaxFieldCount";
+ sal_Int32 aMaxFieldCount = 42;
+ CPPUNIT_ASSERT(xSubTotalDescriptor->getPropertyValue(propName) >>= aMaxFieldCount);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Unable to get PropertyValue MaxFieldCount", sal_Int32(3),
+ aMaxFieldCount);
+
+ aNewValue <<= sal_Int32(42);
+ CPPUNIT_ASSERT_THROW_MESSAGE("Able to change PropertyValue MaxFieldCount",
+ xSubTotalDescriptor->setPropertyValue(propName, aNewValue),
+ lang::IllegalArgumentException);
+}
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/test/source/sheet/tableautoformat.cxx b/test/source/sheet/tableautoformat.cxx
new file mode 100644
index 0000000000..2d5595f0a2
--- /dev/null
+++ b/test/source/sheet/tableautoformat.cxx
@@ -0,0 +1,94 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * 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 <test/sheet/tableautoformat.hxx>
+
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/uno/Any.hxx>
+#include <com/sun/star/uno/Reference.hxx>
+
+#include <cppunit/TestAssert.h>
+
+using namespace com::sun::star;
+using namespace com::sun::star::uno;
+
+namespace apitest
+{
+void TableAutoFormat::testTableAutoFormatProperties()
+{
+ uno::Reference<beans::XPropertySet> xTableAutoFormat(init(), UNO_QUERY_THROW);
+ OUString propName;
+ uno::Any aNewValue;
+
+ propName = "IncludeFont";
+ bool aIncludeFont = false;
+ CPPUNIT_ASSERT_MESSAGE("Unable to get property value IncludeFont",
+ xTableAutoFormat->getPropertyValue(propName) >>= aIncludeFont);
+
+ aNewValue <<= false;
+ xTableAutoFormat->setPropertyValue(propName, aNewValue);
+ CPPUNIT_ASSERT(xTableAutoFormat->getPropertyValue(propName) >>= aIncludeFont);
+ CPPUNIT_ASSERT_MESSAGE("Unable to set property value IncludeFont", !aIncludeFont);
+
+ propName = "IncludeJustify";
+ bool aIncludeJustify = false;
+ CPPUNIT_ASSERT_MESSAGE("Unable to get property value IncludeJustify",
+ xTableAutoFormat->getPropertyValue(propName) >>= aIncludeJustify);
+
+ aNewValue <<= false;
+ xTableAutoFormat->setPropertyValue(propName, aNewValue);
+ CPPUNIT_ASSERT(xTableAutoFormat->getPropertyValue(propName) >>= aIncludeJustify);
+ CPPUNIT_ASSERT_MESSAGE("Unable to set property value IncludeJustify", !aIncludeJustify);
+
+ propName = "IncludeBorder";
+ bool aIncludeBorder = false;
+ CPPUNIT_ASSERT_MESSAGE("Unable to get property value IncludeBorder",
+ xTableAutoFormat->getPropertyValue(propName) >>= aIncludeBorder);
+
+ aNewValue <<= false;
+ xTableAutoFormat->setPropertyValue(propName, aNewValue);
+ CPPUNIT_ASSERT(xTableAutoFormat->getPropertyValue(propName) >>= aIncludeBorder);
+ CPPUNIT_ASSERT_MESSAGE("Unable to set property value IncludeBorder", !aIncludeBorder);
+
+ propName = "IncludeBackground";
+ bool aIncludeBackground = false;
+ CPPUNIT_ASSERT_MESSAGE("Unable to get property value IncludeBackground",
+ xTableAutoFormat->getPropertyValue(propName) >>= aIncludeBackground);
+
+ aNewValue <<= false;
+ xTableAutoFormat->setPropertyValue(propName, aNewValue);
+ CPPUNIT_ASSERT(xTableAutoFormat->getPropertyValue(propName) >>= aIncludeBackground);
+ CPPUNIT_ASSERT_MESSAGE("Unable to set property value IncludeBackground", !aIncludeBackground);
+
+ propName = "IncludeNumberFormat";
+ bool aIncludeNumberFormat = false;
+ CPPUNIT_ASSERT_MESSAGE("Unable to get property value IncludeNumberFormat",
+ xTableAutoFormat->getPropertyValue(propName) >>= aIncludeNumberFormat);
+
+ aNewValue <<= false;
+ xTableAutoFormat->setPropertyValue(propName, aNewValue);
+ CPPUNIT_ASSERT(xTableAutoFormat->getPropertyValue(propName) >>= aIncludeNumberFormat);
+ CPPUNIT_ASSERT_MESSAGE("Unable to set property value IncludeNumberFormat",
+ !aIncludeNumberFormat);
+
+ propName = "IncludeWidthAndHeight";
+ bool aIncludeWidthAndHeight = false;
+ CPPUNIT_ASSERT(xTableAutoFormat->getPropertyValue(propName) >>= aIncludeWidthAndHeight);
+ CPPUNIT_ASSERT_MESSAGE("Unable to get property value IncludeWidthAndHeight",
+ aIncludeWidthAndHeight);
+
+ aNewValue <<= false;
+ xTableAutoFormat->setPropertyValue(propName, aNewValue);
+ CPPUNIT_ASSERT(xTableAutoFormat->getPropertyValue(propName) >>= aIncludeWidthAndHeight);
+ CPPUNIT_ASSERT_MESSAGE("Unable to set property value IncludeWidthAndHeight",
+ !aIncludeWidthAndHeight);
+}
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/test/source/sheet/tablevalidation.cxx b/test/source/sheet/tablevalidation.cxx
new file mode 100644
index 0000000000..4383019602
--- /dev/null
+++ b/test/source/sheet/tablevalidation.cxx
@@ -0,0 +1,153 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * 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 <test/sheet/tablevalidation.hxx>
+
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/sheet/ValidationAlertStyle.hpp>
+#include <com/sun/star/sheet/ValidationType.hpp>
+#include <com/sun/star/uno/Any.hxx>
+#include <com/sun/star/uno/Reference.hxx>
+
+#include <cppunit/TestAssert.h>
+
+using namespace com::sun::star;
+using namespace com::sun::star::uno;
+
+namespace apitest
+{
+void TableValidation::testTableValidationProperties()
+{
+ uno::Reference<beans::XPropertySet> xTableValidation(init(), UNO_QUERY_THROW);
+ OUString propName;
+ uno::Any aNewValue;
+
+ propName = "Type";
+ uno::Any aValue = xTableValidation->getPropertyValue(propName);
+ sheet::ValidationType aValidationType;
+ aValue >>= aValidationType;
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Unable to get property value Type", sheet::ValidationType_ANY,
+ aValidationType);
+
+ aNewValue <<= sheet::ValidationType_WHOLE;
+ xTableValidation->setPropertyValue(propName, aNewValue);
+ aValue = xTableValidation->getPropertyValue(propName);
+ aValue >>= aValidationType;
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Unable to set property value Type", sheet::ValidationType_WHOLE,
+ aValidationType);
+
+ propName = "ShowInputMessage";
+ bool aShowInputMessage = true;
+ CPPUNIT_ASSERT(xTableValidation->getPropertyValue(propName) >>= aShowInputMessage);
+ CPPUNIT_ASSERT_MESSAGE("Unable to get property value ShowInputMessage", !aShowInputMessage);
+
+ aNewValue <<= true;
+ xTableValidation->setPropertyValue(propName, aNewValue);
+ CPPUNIT_ASSERT(xTableValidation->getPropertyValue(propName) >>= aShowInputMessage);
+ CPPUNIT_ASSERT_MESSAGE("Unable to set property value ShowInputMessage", aShowInputMessage);
+
+ // only possible if ShowInputMessage is true
+ propName = "InputMessage";
+ OUString aInputMessage;
+ CPPUNIT_ASSERT(xTableValidation->getPropertyValue(propName) >>= aInputMessage);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Unable to get property value InputMessage", OUString(""),
+ aInputMessage);
+
+ aNewValue <<= OUString("UnitTest InputMessage");
+ xTableValidation->setPropertyValue(propName, aNewValue);
+ CPPUNIT_ASSERT(xTableValidation->getPropertyValue(propName) >>= aInputMessage);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Unable to get property value InputMessage",
+ OUString("UnitTest InputMessage"), aInputMessage);
+
+ // only possible if ShowInputMessage is true
+ propName = "InputTitle";
+ OUString aInputTitle;
+ CPPUNIT_ASSERT(xTableValidation->getPropertyValue(propName) >>= aInputTitle);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Unable to get property value InputTitle", OUString(""),
+ aInputTitle);
+
+ aNewValue <<= OUString("UnitTest InputTitle");
+ xTableValidation->setPropertyValue(propName, aNewValue);
+ CPPUNIT_ASSERT(xTableValidation->getPropertyValue(propName) >>= aInputTitle);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Unable to get property value InputTitle",
+ OUString("UnitTest InputTitle"), aInputTitle);
+
+ propName = "ShowErrorMessage";
+ bool aShowErrorMessage = true;
+ CPPUNIT_ASSERT(xTableValidation->getPropertyValue(propName) >>= aShowErrorMessage);
+ CPPUNIT_ASSERT_MESSAGE("Unable to get property value ShowErrorMessage", !aShowErrorMessage);
+
+ aNewValue <<= true;
+ xTableValidation->setPropertyValue(propName, aNewValue);
+ CPPUNIT_ASSERT(xTableValidation->getPropertyValue(propName) >>= aShowErrorMessage);
+ CPPUNIT_ASSERT_MESSAGE("Unable to set property value ShowErrorMessage", aShowErrorMessage);
+
+ // only possible if ShowErrorMessage is true
+ propName = "ErrorMessage";
+ OUString aErrorMessage;
+ CPPUNIT_ASSERT(xTableValidation->getPropertyValue(propName) >>= aErrorMessage);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Unable to get property value ErrorMessage", OUString(""),
+ aErrorMessage);
+
+ aNewValue <<= OUString("UnitTest ErrorMessage");
+ xTableValidation->setPropertyValue(propName, aNewValue);
+ CPPUNIT_ASSERT(xTableValidation->getPropertyValue(propName) >>= aErrorMessage);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Unable to get property value ErrorMessage",
+ OUString("UnitTest ErrorMessage"), aErrorMessage);
+
+ // only possible if ShowErrorMessage is true
+ propName = "ErrorTitle";
+ OUString aErrorTitle;
+ CPPUNIT_ASSERT(xTableValidation->getPropertyValue(propName) >>= aErrorTitle);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Unable to get property value ErrorTitle", OUString(""),
+ aErrorTitle);
+
+ aNewValue <<= OUString("UnitTest ErrorTitle");
+ xTableValidation->setPropertyValue(propName, aNewValue);
+ CPPUNIT_ASSERT(xTableValidation->getPropertyValue(propName) >>= aErrorTitle);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Unable to get property value ErrorTitle",
+ OUString("UnitTest ErrorTitle"), aErrorTitle);
+
+ propName = "IgnoreBlankCells";
+ bool aIgnoreBlankCells = false;
+ CPPUNIT_ASSERT(xTableValidation->getPropertyValue(propName) >>= aIgnoreBlankCells);
+ CPPUNIT_ASSERT_MESSAGE("Unable to get property value IgnoreBlankCells", aIgnoreBlankCells);
+
+ aNewValue <<= false;
+ xTableValidation->setPropertyValue(propName, aNewValue);
+ CPPUNIT_ASSERT(xTableValidation->getPropertyValue(propName) >>= aIgnoreBlankCells);
+ CPPUNIT_ASSERT_MESSAGE("Unable to set property value IgnoreBlankCells", !aIgnoreBlankCells);
+
+ propName = "ErrorAlertStyle";
+ aValue = xTableValidation->getPropertyValue(propName);
+ sheet::ValidationAlertStyle aValidationAlertStyle;
+ aValue >>= aValidationAlertStyle;
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Unable to get property value ValidationAlertStyle",
+ sheet::ValidationAlertStyle_STOP, aValidationAlertStyle);
+
+ aNewValue <<= sheet::ValidationAlertStyle_WARNING;
+ xTableValidation->setPropertyValue(propName, aNewValue);
+ aValue = xTableValidation->getPropertyValue(propName);
+ aValue >>= aValidationAlertStyle;
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Unable to set property value ValidationAlertStyle",
+ sheet::ValidationAlertStyle_WARNING, aValidationAlertStyle);
+
+ propName = "ShowList";
+ sal_Int16 aShowList = 0;
+ CPPUNIT_ASSERT(xTableValidation->getPropertyValue(propName) >>= aShowList);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Unable to get property value ShowList", sal_Int16(1), aShowList);
+
+ aNewValue <<= sal_Int16(42);
+ xTableValidation->setPropertyValue(propName, aNewValue);
+ CPPUNIT_ASSERT(xTableValidation->getPropertyValue(propName) >>= aShowList);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Unable to set property value ShowList", sal_Int16(42), aShowList);
+}
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/test/source/sheet/xactivationbroadcaster.cxx b/test/source/sheet/xactivationbroadcaster.cxx
new file mode 100644
index 0000000000..6c7769db5a
--- /dev/null
+++ b/test/source/sheet/xactivationbroadcaster.cxx
@@ -0,0 +1,70 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * 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 <test/sheet/xactivationbroadcaster.hxx>
+
+#include <com/sun/star/lang/EventObject.hpp>
+#include <com/sun/star/sheet/ActivationEvent.hpp>
+#include <com/sun/star/sheet/XActivationBroadcaster.hpp>
+#include <com/sun/star/sheet/XActivationEventListener.hpp>
+#include <com/sun/star/sheet/XSpreadsheetView.hpp>
+#include <com/sun/star/uno/Reference.hxx>
+
+#include <cppuhelper/implbase.hxx>
+#include <rtl/ref.hxx>
+
+#include <cppunit/TestAssert.h>
+
+using namespace com::sun::star;
+using namespace com::sun::star::uno;
+
+namespace apitest
+{
+namespace
+{
+class MockedActivationEventListener : public ::cppu::WeakImplHelper<sheet::XActivationEventListener>
+{
+public:
+ MockedActivationEventListener()
+ : mbListenerCalled(false)
+ {
+ }
+ bool mbListenerCalled;
+ virtual void SAL_CALL
+ activeSpreadsheetChanged(const sheet::ActivationEvent& /* xEvent */) override
+ {
+ mbListenerCalled = true;
+ }
+ virtual void SAL_CALL disposing(const lang::EventObject& /* xEventObj */) override {}
+};
+}
+
+void XActivationBroadcaster::testAddRemoveActivationEventListener()
+{
+ uno::Reference<sheet::XActivationBroadcaster> xAB(init(), UNO_QUERY_THROW);
+ xAB->addActivationEventListener(nullptr);
+
+ rtl::Reference<MockedActivationEventListener> xListener = new MockedActivationEventListener();
+ xAB->addActivationEventListener(uno::Reference<sheet::XActivationEventListener>(xListener));
+
+ uno::Reference<sheet::XSpreadsheetView> xView(xAB, UNO_QUERY_THROW);
+ uno::Reference<sheet::XSpreadsheet> xSheet1(xView->getActiveSheet(), UNO_SET_THROW);
+ uno::Reference<sheet::XSpreadsheet> xSheet2(getXSpreadsheet(1), UNO_QUERY_THROW);
+
+ xView->setActiveSheet(xSheet2);
+
+ CPPUNIT_ASSERT_MESSAGE("Listener wasn't called", xListener->mbListenerCalled);
+
+ xAB->removeActivationEventListener(uno::Reference<sheet::XActivationEventListener>(xListener));
+ xView->setActiveSheet(xSheet1);
+ CPPUNIT_ASSERT_MESSAGE("Listener still called after removal", xListener->mbListenerCalled);
+}
+} // namespace apitest
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/test/source/sheet/xarealink.cxx b/test/source/sheet/xarealink.cxx
new file mode 100644
index 0000000000..77e9cb98b8
--- /dev/null
+++ b/test/source/sheet/xarealink.cxx
@@ -0,0 +1,65 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * 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 <test/sheet/xarealink.hxx>
+#include <test/cppunitasserthelper.hxx>
+
+#include <com/sun/star/sheet/XAreaLink.hpp>
+#include <com/sun/star/table/CellRangeAddress.hpp>
+#include <com/sun/star/uno/Reference.hxx>
+
+#include <cppunit/TestAssert.h>
+
+using namespace com::sun::star;
+using namespace com::sun::star::uno;
+
+namespace apitest {
+
+void XAreaLink::testSetDestArea()
+{
+ uno::Reference< sheet::XAreaLink > xAreaLink(init(), UNO_QUERY_THROW);
+
+ xAreaLink->setDestArea(table::CellRangeAddress(1,3,4,5,8));
+ // After setting the destination area, the link is refreshed and the area
+ // is adjusted to the size of the source data.
+ // Only test the 'Sheet', 'StartCol', and 'StartRow'
+ table::CellRangeAddress aDestArea = xAreaLink->getDestArea();
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Couldn't set new DestArea (Sheet)", sal_Int16(1), aDestArea.Sheet);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Couldn't set new DestArea (StartCol)", sal_Int32(3), aDestArea.StartColumn);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Couldn't set new DestArea (StartRow)", sal_Int32(4), aDestArea.StartRow);
+}
+
+void XAreaLink::testSetSourceArea()
+{
+ uno::Reference< sheet::XAreaLink > xAreaLink(init(), UNO_QUERY_THROW);
+
+ xAreaLink->setSourceArea("Sheet1.A1:B1");
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Couldn't set new source area",
+ OUString("Sheet1.A1:B1"), xAreaLink->getSourceArea());
+}
+
+void XAreaLink::testGetDestArea()
+{
+ uno::Reference< sheet::XAreaLink > xAreaLink(init(), UNO_QUERY_THROW);
+
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Couldn't get dest area",
+ table::CellRangeAddress(1,2,3,3,6), xAreaLink->getDestArea());
+}
+
+void XAreaLink::testGetSourceArea()
+{
+ uno::Reference< sheet::XAreaLink > xAreaLink(init(), UNO_QUERY_THROW);
+
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Couldn't get source area",
+ OUString("a2:b5"), xAreaLink->getSourceArea());
+}
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/test/source/sheet/xarealinks.cxx b/test/source/sheet/xarealinks.cxx
new file mode 100644
index 0000000000..f52dcc35b1
--- /dev/null
+++ b/test/source/sheet/xarealinks.cxx
@@ -0,0 +1,50 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * 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 <test/sheet/xarealinks.hxx>
+
+#include <com/sun/star/sheet/XAreaLinks.hpp>
+#include <com/sun/star/table/CellAddress.hpp>
+#include <com/sun/star/uno/Reference.hxx>
+
+#include <cppunit/TestAssert.h>
+
+using namespace com::sun::star;
+using namespace com::sun::star::uno;
+
+namespace apitest {
+
+void XAreaLinks::testInsertAtPosition()
+{
+ uno::Reference< sheet::XAreaLinks > xAreaLinks(init(), UNO_QUERY_THROW);
+
+ table::CellAddress aCellAddress(1, 2, 3);
+ xAreaLinks->insertAtPosition(aCellAddress, "", "a2:b5", "", "");
+
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Unable to insert new CellAddress",
+ sal_Int32(1), xAreaLinks->getCount());
+}
+
+void XAreaLinks::testRemoveByIndex()
+{
+ uno::Reference< sheet::XAreaLinks > xAreaLinks(init(), UNO_QUERY_THROW);
+
+ table::CellAddress aCellAddress(1, 2, 3);
+ xAreaLinks->insertAtPosition(aCellAddress, "", "a2:b5", "", "");
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Unable to insert CellAddress for removal",
+ sal_Int32(1), xAreaLinks->getCount());
+
+ xAreaLinks->removeByIndex(0);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Unable to remove CellAddress",
+ sal_Int32(0), xAreaLinks->getCount());
+}
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/test/source/sheet/xarrayformularange.cxx b/test/source/sheet/xarrayformularange.cxx
new file mode 100644
index 0000000000..fb924a78bf
--- /dev/null
+++ b/test/source/sheet/xarrayformularange.cxx
@@ -0,0 +1,54 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * 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 <test/sheet/xarrayformularange.hxx>
+
+#include <com/sun/star/sheet/XArrayFormulaRange.hpp>
+#include <com/sun/star/sheet/XCellRangeAddressable.hpp>
+#include <com/sun/star/sheet/XSpreadsheet.hpp>
+#include <com/sun/star/table/CellRangeAddress.hpp>
+#include <com/sun/star/table/XCell.hpp>
+#include <com/sun/star/uno/Reference.hxx>
+
+#include <cppunit/TestAssert.h>
+
+using namespace com::sun::star;
+using namespace com::sun::star::uno;
+
+namespace apitest
+{
+void XArrayFormulaRange::testGetSetArrayFormula()
+{
+ uno::Reference<sheet::XArrayFormulaRange> xAFR(init(), UNO_QUERY_THROW);
+
+ static constexpr OUString sFormula(u"=1 + 2 * 5"_ustr);
+
+ xAFR->setArrayFormula(sFormula);
+ uno::Reference<sheet::XCellRangeAddressable> xCRA(xAFR, UNO_QUERY_THROW);
+ table::CellRangeAddress cellRangeAddress = xCRA->getRangeAddress();
+
+ uno::Reference<sheet::XSpreadsheet> xSheet(getXSpreadsheet(), UNO_QUERY_THROW);
+
+ for (auto i = cellRangeAddress.StartColumn; i <= cellRangeAddress.EndColumn; i++)
+ {
+ for (auto j = cellRangeAddress.StartRow; j <= cellRangeAddress.EndRow; j++)
+ {
+ uno::Reference<table::XCell> xCell = xSheet->getCellByPosition(i, j);
+ CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Value of Cell " + std::to_string(i) + ","
+ + std::to_string(j),
+ 11.0, xCell->getValue(), 0.5);
+ }
+ }
+
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Unable to test getArrayFormula()", OUString("{" + sFormula + "}"),
+ xAFR->getArrayFormula());
+}
+} // namespace apitest
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/test/source/sheet/xcalculatable.cxx b/test/source/sheet/xcalculatable.cxx
new file mode 100644
index 0000000000..44c2015340
--- /dev/null
+++ b/test/source/sheet/xcalculatable.cxx
@@ -0,0 +1,74 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * 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 <test/sheet/xcalculatable.hxx>
+
+#include <com/sun/star/sheet/XCalculatable.hpp>
+#include <com/sun/star/table/XCell.hpp>
+
+#include <com/sun/star/uno/Reference.hxx>
+#include <com/sun/star/uno/Sequence.hxx>
+
+#include <cppunit/TestAssert.h>
+
+using namespace com::sun::star;
+using namespace com::sun::star::uno;
+
+namespace apitest
+{
+void XCalculatable::testEnableAutomaticCalculation()
+{
+ uno::Reference<sheet::XCalculatable> xCalculatable(init(), UNO_QUERY_THROW);
+
+ bool bIsAutomaticCalculationEnabled = xCalculatable->isAutomaticCalculationEnabled();
+ xCalculatable->enableAutomaticCalculation(!bIsAutomaticCalculationEnabled);
+ bool bIsAutomaticCalculationEnabledNew = xCalculatable->isAutomaticCalculationEnabled();
+ CPPUNIT_ASSERT_MESSAGE("Unable to set enableAutomaticCalculation()",
+ bIsAutomaticCalculationEnabled != bIsAutomaticCalculationEnabledNew);
+}
+
+void XCalculatable::testCalculate()
+{
+ uno::Reference<sheet::XCalculatable> xCalculatable(init(), UNO_QUERY_THROW);
+ xCalculatable->enableAutomaticCalculation(false);
+
+ uno::Sequence<uno::Reference<table::XCell>> xCells = getXCells();
+
+ double dProduct = xCells[2]->getValue();
+ double dFactor1 = xCells[0]->getValue();
+ xCells[0]->setValue(dFactor1 + 1.0);
+ double dProduct2 = xCells[2]->getValue();
+ CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Calculated products are equal", dProduct, dProduct2, 0.5);
+
+ xCalculatable->calculate();
+ dProduct2 = xCells[2]->getValue();
+ CPPUNIT_ASSERT_MESSAGE("Calculated products are not equal", dProduct != dProduct2);
+}
+
+void XCalculatable::testCalculateAll()
+{
+ uno::Reference<sheet::XCalculatable> xCalculatable(init(), UNO_QUERY_THROW);
+ xCalculatable->enableAutomaticCalculation(false);
+
+ uno::Sequence<uno::Reference<table::XCell>> xCells = getXCells();
+
+ double dProduct = xCells[2]->getValue();
+ double dFactor1 = xCells[0]->getValue();
+ xCells[0]->setValue(dFactor1 + 1.0);
+ double dProduct2 = xCells[2]->getValue();
+ CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Calculated products are equal", dProduct, dProduct2, 0.5);
+
+ xCalculatable->calculateAll();
+ dProduct2 = xCells[2]->getValue();
+ CPPUNIT_ASSERT_MESSAGE("Calculated products are not equal", dProduct != dProduct2);
+ xCalculatable->calculateAll();
+}
+} // namespace apitest
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/test/source/sheet/xcelladdressable.cxx b/test/source/sheet/xcelladdressable.cxx
new file mode 100644
index 0000000000..e428091705
--- /dev/null
+++ b/test/source/sheet/xcelladdressable.cxx
@@ -0,0 +1,34 @@
+/* -*- 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 <test/sheet/xcelladdressable.hxx>
+#include <test/cppunitasserthelper.hxx>
+
+#include <com/sun/star/sheet/XCellAddressable.hpp>
+#include <com/sun/star/table/CellAddress.hpp>
+
+#include <cppunit/TestAssert.h>
+
+using namespace com::sun::star;
+using namespace com::sun::star::uno;
+
+namespace apitest
+{
+void XCellAddressable::testGetCellAddress()
+{
+ uno::Reference<sheet::XCellAddressable> xCellAddressable(init(), UNO_QUERY_THROW);
+ table::CellAddress xCellAddress = xCellAddressable->getCellAddress();
+ table::CellAddress defaultCellAddress(0, 2, 3);
+
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("getCellAddress() didn't returned default cell address",
+ defaultCellAddress, xCellAddress);
+}
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/test/source/sheet/xcellformatrangessupplier.cxx b/test/source/sheet/xcellformatrangessupplier.cxx
new file mode 100644
index 0000000000..d4390b5385
--- /dev/null
+++ b/test/source/sheet/xcellformatrangessupplier.cxx
@@ -0,0 +1,39 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * 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 <test/sheet/xcellformatrangessupplier.hxx>
+
+#include <com/sun/star/container/XIndexAccess.hpp>
+#include <com/sun/star/sheet/XCellFormatRangesSupplier.hpp>
+#include <com/sun/star/uno/Reference.hxx>
+
+#include <cppunit/TestAssert.h>
+
+using namespace css;
+using namespace css::uno;
+
+namespace apitest
+{
+void XCellFormatRangesSupplier::testGetCellFormatRanges()
+{
+ uno::Reference<sheet::XCellFormatRangesSupplier> xCFRS(init(), UNO_QUERY_THROW);
+
+ uno::Reference<container::XIndexAccess> xIA(xCFRS->getCellFormatRanges(), UNO_SET_THROW);
+
+ const sal_Int32 nCount = xIA->getCount();
+ CPPUNIT_ASSERT_MESSAGE("No items found", sal_Int32(0) != nCount);
+ for (auto i = 0; i < nCount; i++)
+ {
+ CPPUNIT_ASSERT_NO_THROW_MESSAGE("Unable to access element at position " + std::to_string(i),
+ xIA->getByIndex(i));
+ }
+}
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/test/source/sheet/xcellrangeaddressable.cxx b/test/source/sheet/xcellrangeaddressable.cxx
new file mode 100644
index 0000000000..179a56fa1f
--- /dev/null
+++ b/test/source/sheet/xcellrangeaddressable.cxx
@@ -0,0 +1,33 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * 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 <test/sheet/xcellrangeaddressable.hxx>
+
+#include <com/sun/star/sheet/XCellRangeAddressable.hpp>
+#include <com/sun/star/table/CellRangeAddress.hpp>
+#include <com/sun/star/uno/Reference.hxx>
+
+#include <cppunit/TestAssert.h>
+
+using namespace css;
+using namespace css::uno;
+
+namespace apitest
+{
+void XCellRangeAddressable::testGetRangeAddress()
+{
+ uno::Reference<sheet::XCellRangeAddressable> xCRA(init(), UNO_QUERY_THROW);
+
+ table::CellRangeAddress aCellRangeAddr = xCRA->getRangeAddress();
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Unable to get CellRangeAddress", sal_Int16(0),
+ aCellRangeAddr.Sheet);
+}
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/test/source/sheet/xcellrangedata.cxx b/test/source/sheet/xcellrangedata.cxx
new file mode 100644
index 0000000000..eff1041475
--- /dev/null
+++ b/test/source/sheet/xcellrangedata.cxx
@@ -0,0 +1,95 @@
+/* -*- 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 <test/sheet/xcellrangedata.hxx>
+
+#include <com/sun/star/sheet/XCellRangeData.hpp>
+#include <com/sun/star/uno/Any.hxx>
+#include <com/sun/star/uno/Reference.hxx>
+#include <com/sun/star/uno/RuntimeException.hpp>
+#include <com/sun/star/uno/Sequence.hxx>
+
+#include <cppunit/TestAssert.h>
+
+using namespace css;
+using namespace css::uno;
+
+namespace apitest {
+
+namespace {
+
+void setValues(uno::Sequence< uno::Sequence < Any > >& rColRow, double nOffset)
+{
+ auto pColRow = rColRow.getArray();
+ for (sal_Int32 i = 0; i < 4; ++i)
+ {
+ pColRow[i].realloc(4);
+ auto pCol = pColRow[i].getArray();
+ for (sal_Int32 j = 0; j < 4; ++j)
+ {
+ Any& aAny = pCol[j];
+ double nValue = i + j + nOffset;
+ aAny <<= nValue;
+ }
+ }
+}
+
+}
+
+void XCellRangeData::testSetDataArray()
+{
+ uno::Reference< sheet::XCellRangeData > xCellRangeData( getXCellRangeData(), UNO_QUERY_THROW);
+
+ uno::Sequence< uno::Sequence < Any > > aColRow(4);
+ setValues(aColRow, 1);
+ xCellRangeData->setDataArray(aColRow);
+
+ for ( sal_Int32 i = 0; i < aColRow.getLength(); ++i)
+ {
+ for ( sal_Int32 j = 0; j < aColRow[i].getLength(); ++j)
+ {
+ const Any& aAny = aColRow[i][j];
+ double nValue = 0.0;
+ CPPUNIT_ASSERT( aAny >>= nValue);
+ CPPUNIT_ASSERT_DOUBLES_EQUAL(static_cast<double>(i+j+1), nValue, 0.000001);
+ }
+ }
+
+ // set old values
+ setValues(aColRow, 0);
+ xCellRangeData->setDataArray(aColRow);
+}
+
+void XCellRangeData::testGetDataArray()
+{
+ uno::Reference< sheet::XCellRangeData > xCellRangeData( getXCellRangeData(), UNO_QUERY_THROW);
+ uno::Sequence< uno::Sequence < Any > > aColRow = xCellRangeData->getDataArray();
+ CPPUNIT_ASSERT(aColRow.hasElements());
+}
+
+void XCellRangeData::testGetDataArrayOnTableSheet()
+{
+ uno::Reference< sheet::XCellRangeData > xCellRangeData( getXCellRangeData(), UNO_QUERY_THROW);
+ CPPUNIT_ASSERT_THROW_MESSAGE("No RuntimeException thrown", xCellRangeData->getDataArray(),
+ css::uno::RuntimeException);
+}
+
+void XCellRangeData::testSetDataArrayOnTableSheet()
+{
+ uno::Reference< sheet::XCellRangeData > xCellRangeData( getXCellRangeData(), UNO_QUERY_THROW);
+
+ uno::Sequence< uno::Sequence < Any > > aColRow;
+ aColRow.realloc(4);
+ setValues(aColRow, 1);
+ CPPUNIT_ASSERT_THROW_MESSAGE("No RuntimeException thrown", xCellRangeData->setDataArray(aColRow),
+ css::uno::RuntimeException);
+}
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/test/source/sheet/xcellrangeformula.cxx b/test/source/sheet/xcellrangeformula.cxx
new file mode 100644
index 0000000000..ce7fc54eb6
--- /dev/null
+++ b/test/source/sheet/xcellrangeformula.cxx
@@ -0,0 +1,41 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * 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 <test/sheet/xcellrangeformula.hxx>
+
+#include <com/sun/star/sheet/XCellRangeFormula.hpp>
+#include <com/sun/star/uno/Reference.hxx>
+#include <com/sun/star/uno/Sequence.hxx>
+
+#include <cppunit/TestAssert.h>
+
+using namespace com::sun::star;
+using namespace com::sun::star::uno;
+
+namespace apitest
+{
+void XCellRangeFormula::testGetSetFormulaArray()
+{
+ uno::Reference<sheet::XCellRangeFormula> xCRF(init(), UNO_QUERY_THROW);
+
+ uno::Sequence<uno::Sequence<OUString>> aFormulaArrayOriginal = xCRF->getFormulaArray();
+ uno::Sequence<uno::Sequence<OUString>> aFormulaArrayNew = xCRF->getFormulaArray();
+ aFormulaArrayNew.getArray()[0].getArray()[0] = "NewValue";
+
+ xCRF->setFormulaArray(aFormulaArrayNew);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Unable to get new FormulaArray", OUString("NewValue"),
+ xCRF->getFormulaArray()[0][0]);
+
+ xCRF->setFormulaArray(aFormulaArrayOriginal);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Unable to set new FormulaArray", aFormulaArrayOriginal[0][0],
+ xCRF->getFormulaArray()[0][0]);
+}
+} // namespace apitest
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/test/source/sheet/xcellrangemovement.cxx b/test/source/sheet/xcellrangemovement.cxx
new file mode 100644
index 0000000000..ac25a4603e
--- /dev/null
+++ b/test/source/sheet/xcellrangemovement.cxx
@@ -0,0 +1,120 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * 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 <test/sheet/xcellrangemovement.hxx>
+
+#include <com/sun/star/sheet/CellDeleteMode.hpp>
+#include <com/sun/star/sheet/CellInsertMode.hpp>
+#include <com/sun/star/sheet/XCellRangeAddressable.hpp>
+#include <com/sun/star/sheet/XCellRangeMovement.hpp>
+#include <com/sun/star/sheet/XSpreadsheet.hpp>
+#include <com/sun/star/table/CellAddress.hpp>
+#include <com/sun/star/table/CellRangeAddress.hpp>
+#include <com/sun/star/uno/Reference.hxx>
+
+#include <cppunit/TestAssert.h>
+
+using namespace com::sun::star;
+using namespace com::sun::star::uno;
+
+namespace apitest
+{
+void XCellRangeMovement::testInsertCells()
+{
+ uno::Reference<sheet::XCellRangeMovement> xCRM(init(), UNO_QUERY_THROW);
+ uno::Reference<sheet::XSpreadsheet> xSheet(xCRM, UNO_QUERY_THROW);
+
+ uno::Reference<sheet::XCellRangeAddressable> xCRA(xCRM, UNO_QUERY_THROW);
+ const sal_Int16 nSheet = xCRA->getRangeAddress().Sheet;
+
+ xSheet->getCellByPosition(0, 20)->setValue(100);
+ xSheet->getCellByPosition(1, 20)->setValue(100);
+ xSheet->getCellByPosition(2, 20)->setValue(100);
+ xSheet->getCellByPosition(3, 20)->setValue(100);
+ xSheet->getCellByPosition(0, 21)->setValue(200);
+ xSheet->getCellByPosition(1, 21)->setValue(200);
+ xSheet->getCellByPosition(2, 21)->setValue(200);
+ xSheet->getCellByPosition(3, 21)->setValue(200);
+
+ table::CellRangeAddress aSrcCellRangeAddr(nSheet, 0, 21, 5, 21);
+ xCRM->insertCells(aSrcCellRangeAddr, sheet::CellInsertMode_DOWN);
+
+ CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Unable to insert cells", 0.0,
+ xSheet->getCellByPosition(1, 21)->getValue(), 0.0);
+}
+
+void XCellRangeMovement::testCopyRange()
+{
+ uno::Reference<sheet::XCellRangeMovement> xCRM(init(), UNO_QUERY_THROW);
+ uno::Reference<sheet::XSpreadsheet> xSheet(xCRM, UNO_QUERY_THROW);
+
+ xSheet->getCellByPosition(1, 1)->setValue(100);
+ xSheet->getCellByPosition(1, 2)->setValue(200);
+ xSheet->getCellByPosition(2, 1)->setValue(300);
+ xSheet->getCellByPosition(2, 2)->setValue(400);
+
+ uno::Reference<sheet::XCellRangeAddressable> xCRA(xCRM, UNO_QUERY_THROW);
+ const sal_Int16 nSheet = xCRA->getRangeAddress().Sheet;
+
+ table::CellRangeAddress aSrcCellRangeAddr(nSheet, 1, 1, 2, 2);
+ table::CellAddress aDstCellAddr(nSheet, 1, 10);
+
+ xCRM->copyRange(aDstCellAddr, aSrcCellRangeAddr);
+
+ CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Value was not copied from position 1,1 to 1,10", 100.0,
+ xSheet->getCellByPosition(1, 10)->getValue(), 0.1);
+ CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Value was not copied from position 1,2 to 1,11", 200.0,
+ xSheet->getCellByPosition(1, 11)->getValue(), 0.1);
+ CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Value was not copied from position 2,1 to 2,10", 300.0,
+ xSheet->getCellByPosition(2, 10)->getValue(), 0.1);
+ CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Value was not copied from position 2,2 to 2,11", 400.0,
+ xSheet->getCellByPosition(2, 11)->getValue(), 0.1);
+}
+void XCellRangeMovement::testMoveRange()
+{
+ uno::Reference<sheet::XCellRangeMovement> xCRM(init(), UNO_QUERY_THROW);
+ uno::Reference<sheet::XSpreadsheet> xSheet(xCRM, UNO_QUERY_THROW);
+
+ xSheet->getCellByPosition(4, 0)->setValue(111);
+ xSheet->getCellByPosition(4, 1)->setValue(222);
+
+ uno::Reference<sheet::XCellRangeAddressable> xCRA(xCRM, UNO_QUERY_THROW);
+ const sal_Int16 nSheet = xCRA->getRangeAddress().Sheet;
+
+ table::CellRangeAddress aSrcCellRangeAddr(nSheet, 4, 0, 4, 1);
+ table::CellAddress aDstCellAddr(nSheet, 4, 4);
+
+ xCRM->moveRange(aDstCellAddr, aSrcCellRangeAddr);
+ CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Unable to move range", 333.0,
+ xSheet->getCellByPosition(4, 4)->getValue()
+ + xSheet->getCellByPosition(4, 5)->getValue(),
+ 0.0);
+}
+void XCellRangeMovement::testRemoveRange()
+{
+ uno::Reference<sheet::XCellRangeMovement> xCRM(init(), UNO_QUERY_THROW);
+ uno::Reference<sheet::XSpreadsheet> xSheet(xCRM, UNO_QUERY_THROW);
+
+ xSheet->getCellByPosition(5, 0)->setValue(333);
+ xSheet->getCellByPosition(5, 1)->setValue(444);
+
+ uno::Reference<sheet::XCellRangeAddressable> xCRA(xCRM, UNO_QUERY_THROW);
+ const sal_Int16 nSheet = xCRA->getRangeAddress().Sheet;
+
+ table::CellRangeAddress aSrcCellRangeAddr(nSheet, 5, 0, 5, 1);
+
+ xCRM->removeRange(aSrcCellRangeAddr, sheet::CellDeleteMode_UP);
+ CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Unable to remove range", 0.0,
+ xSheet->getCellByPosition(5, 0)->getValue()
+ + xSheet->getCellByPosition(5, 1)->getValue(),
+ 0.0);
+}
+} // namespace apitest
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/test/source/sheet/xcellrangereferrer.cxx b/test/source/sheet/xcellrangereferrer.cxx
new file mode 100644
index 0000000000..575bee05e6
--- /dev/null
+++ b/test/source/sheet/xcellrangereferrer.cxx
@@ -0,0 +1,36 @@
+/* -*- 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 <test/cppunitasserthelper.hxx>
+#include <test/sheet/xcellrangereferrer.hxx>
+
+#include <com/sun/star/table/XCellRange.hpp>
+#include <com/sun/star/sheet/XCellRangeAddressable.hpp>
+#include <com/sun/star/sheet/XCellRangeReferrer.hpp>
+
+#include <cppunit/TestAssert.h>
+
+using namespace css;
+using namespace css::uno;
+
+namespace apitest
+{
+void XCellRangeReferrer::testGetReferredCells()
+{
+ uno::Reference<sheet::XCellRangeReferrer> xReferrer(init(), UNO_QUERY_THROW);
+ uno::Reference<table::XCellRange> xReferredRange = xReferrer->getReferredCells();
+
+ uno::Reference<sheet::XCellRangeAddressable> xAddressable(xReferredRange, UNO_QUERY_THROW);
+ table::CellRangeAddress aCellRange = xAddressable->getRangeAddress();
+
+ CPPUNIT_ASSERT_EQUAL(aCellRange, getCellRange());
+}
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/test/source/sheet/xcellrangesquery.cxx b/test/source/sheet/xcellrangesquery.cxx
new file mode 100644
index 0000000000..55d24224ab
--- /dev/null
+++ b/test/source/sheet/xcellrangesquery.cxx
@@ -0,0 +1,90 @@
+/* -*- 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 <test/sheet/xcellrangesquery.hxx>
+
+#include <com/sun/star/sheet/XCellRangesQuery.hpp>
+#include <com/sun/star/sheet/XSheetCellRanges.hpp>
+#include <com/sun/star/table/CellAddress.hpp>
+#include <com/sun/star/sheet/CellFlags.hpp>
+
+#include <cppunit/TestAssert.h>
+
+using namespace com::sun::star;
+using namespace com::sun::star::uno;
+
+
+namespace apitest {
+
+void XCellRangesQuery::testQueryColumnDifference()
+{
+ uno::Reference<sheet::XCellRangesQuery> xCellRangesQuery(init(),UNO_QUERY_THROW);
+ uno::Reference<sheet::XSheetCellRanges> xRanges = xCellRangesQuery->queryColumnDifferences(table::CellAddress(0, 1, 1));
+ OUString aResult = xRanges->getRangeAddressesAsString();
+ std::cout << "testQueryColumnDifference: Result: " << aResult << std::endl;
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("testQueryColumnDifference", OUString( "Sheet1.B1:C1,Sheet1.B3:C5" ), aResult);
+}
+
+void XCellRangesQuery::testQueryContentDifference()
+{
+ uno::Reference<sheet::XCellRangesQuery> xCellRangesQuery(init(),UNO_QUERY_THROW);
+ uno::Reference<sheet::XSheetCellRanges> xRanges = xCellRangesQuery->queryContentCells(sheet::CellFlags::VALUE);
+ OUString aResult = xRanges->getRangeAddressesAsString();
+ std::cout << "testQueryContentDifference: Result: " << aResult << std::endl;
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("testQueryContentDifference", OUString( "Sheet1.B3,Sheet1.C2" ), aResult);
+}
+
+void XCellRangesQuery::testQueryEmptyCells()
+{
+ uno::Reference<sheet::XCellRangesQuery> xCellRangesQuery(init(),UNO_QUERY_THROW);
+ uno::Reference<sheet::XSheetCellRanges> xRanges = xCellRangesQuery->queryEmptyCells();
+ OUString aResult = xRanges->getRangeAddressesAsString();
+ std::cout << "testQueryEmptyCells: Result: " << aResult << std::endl;
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("testQueryEmptyCells", OUString( "Sheet1.A1:A5,Sheet1.B1:C1,Sheet1.B5,Sheet1.C3:C5,Sheet1.D1:E5" ), aResult);
+}
+
+void XCellRangesQuery::testQueryFormulaCells()
+{
+ uno::Reference<sheet::XCellRangesQuery> xCellRangesQuery(init(),UNO_QUERY_THROW);
+ uno::Reference<sheet::XSheetCellRanges> xRanges = xCellRangesQuery->queryFormulaCells(sheet::CellFlags::FORMULA);
+ OUString aResult = xRanges->getRangeAddressesAsString();
+ std::cout << "testQueryFormulaCells: Result: " << aResult << std::endl;
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("testQueryFormulaCells", OUString( "Sheet1.B2" ), aResult);
+}
+
+void XCellRangesQuery::testQueryIntersection()
+{
+ uno::Reference<sheet::XCellRangesQuery> xCellRangesQuery(init(),UNO_QUERY_THROW);
+ uno::Reference<sheet::XSheetCellRanges> xRanges = xCellRangesQuery->queryIntersection(table::CellRangeAddress(0,3,3,7,7));
+ OUString aResult = xRanges->getRangeAddressesAsString();
+ std::cout << "testQueryIntersection: Result: " << aResult << std::endl;
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("testQueryIntersection", OUString( "Sheet1.D4:E5" ), aResult);
+}
+
+void XCellRangesQuery::testQueryRowDifference()
+{
+ uno::Reference<sheet::XCellRangesQuery> xCellRangesQuery(init(),UNO_QUERY_THROW);
+ uno::Reference<sheet::XSheetCellRanges> xRanges = xCellRangesQuery->queryRowDifferences(table::CellAddress(0,1,1));
+ OUString aResult = xRanges->getRangeAddressesAsString();
+ std::cout << "testQueryRowDifference: Result: " << aResult << std::endl;
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("testQueryRowDifference", OUString( "Sheet1.A2:A4,Sheet1.C2:E4" ), aResult);
+}
+
+void XCellRangesQuery::testQueryVisibleCells()
+{
+ uno::Reference<sheet::XCellRangesQuery> xCellRangesQuery(init(),UNO_QUERY_THROW);
+ uno::Reference<sheet::XSheetCellRanges> xRanges = xCellRangesQuery->queryVisibleCells();
+ OUString aResult = xRanges->getRangeAddressesAsString();
+ std::cout << "testQueryVisibleCells: Result: " << aResult << std::endl;
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("testQueryVisibleCells", OUString( "Sheet1.A1:E5" ), aResult);
+}
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/test/source/sheet/xcellseries.cxx b/test/source/sheet/xcellseries.cxx
new file mode 100644
index 0000000000..3aff084f8e
--- /dev/null
+++ b/test/source/sheet/xcellseries.cxx
@@ -0,0 +1,114 @@
+/* -*- 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 <test/sheet/xcellseries.hxx>
+
+#include <com/sun/star/sheet/XCellSeries.hpp>
+#include <com/sun/star/table/XCellRange.hpp>
+
+#include <cppunit/TestAssert.h>
+
+using namespace com::sun::star;
+using namespace com::sun::star::uno;
+
+namespace apitest {
+
+void XCellSeries::testFillAuto()
+{
+ uno::Reference<table::XCellRange> xCellRange(init(), UNO_QUERY_THROW);
+ sal_Int32 maValue = xCellRange->getCellByPosition(maStartX, maStartY)->getValue();
+
+ uno::Reference<table::XCellRange> xCellRangeH(xCellRange->getCellRangeByPosition(maStartX, maStartY, maStartX + 2, maStartY), UNO_SET_THROW);
+ uno::Reference<sheet::XCellSeries> xCellSeriesH(xCellRangeH, UNO_QUERY_THROW);
+ xCellSeriesH->fillAuto(sheet::FillDirection_TO_RIGHT, 1);
+ sal_Int32 sumH = 0;
+ for(sal_Int32 i = 0; i < 3; i++) {
+ uno::Reference<table::XCell> xCellResultH(xCellRange->getCellByPosition(maStartX + i, maStartY), UNO_SET_THROW);
+ sumH += xCellResultH->getValue();
+ }
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Wrong result for fillAuto with TO_RIGHT", maValue * 3 + 3, sumH);
+
+ uno::Reference<table::XCellRange> xCellRangeV(xCellRange->getCellRangeByPosition(maStartX, maStartY, maStartX, maStartY + 2), UNO_SET_THROW);
+ uno::Reference<sheet::XCellSeries> xCellSeriesV(xCellRangeV, UNO_QUERY_THROW);
+ xCellSeriesV->fillAuto(sheet::FillDirection_TO_BOTTOM, 1);
+ sal_Int32 sumV = 0;
+ for(sal_Int32 i = 0; i < 3; i++) {
+ uno::Reference<table::XCell> xCellResultV(xCellRange->getCellByPosition(maStartX, maStartY + i), UNO_SET_THROW);
+ sumV += xCellResultV->getValue();
+ }
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Wrong result for fillAuto with TO_BOTTOM", maValue * 3 + 3, sumV);
+
+ for(sal_Int32 i = 1; i < 3; i++) {
+ uno::Reference<table::XCell> xCellResultH(xCellRange->getCellByPosition(maStartX + i, maStartY), UNO_SET_THROW);
+ xCellResultH->setFormula("");
+ uno::Reference<table::XCell> xCellResultV(xCellRange->getCellByPosition(maStartX, maStartY + i), UNO_SET_THROW);
+ xCellResultV->setFormula("");
+ }
+}
+
+void XCellSeries::testFillSeries()
+{
+ uno::Reference<table::XCellRange> xCellRange(init(), UNO_QUERY_THROW);
+ sal_Int32 maValue = xCellRange->getCellByPosition(maStartX, maStartY)->getValue();
+
+ uno::Reference<table::XCellRange> xCellRangeH(xCellRange->getCellRangeByPosition(maStartX, maStartY, maStartX + 2, maStartY), UNO_SET_THROW);
+ uno::Reference<sheet::XCellSeries> xCellSeriesH(xCellRangeH, UNO_QUERY_THROW);
+ xCellSeriesH->fillSeries(sheet::FillDirection_TO_RIGHT,
+ sheet::FillMode_LINEAR,
+ sheet::FillDateMode_FILL_DATE_DAY, 2, 1000);
+ sal_Int32 sumH = 0;
+ for(sal_Int32 i = 0; i < 3; i++) {
+ uno::Reference<table::XCell> xCellResultH(xCellRange->getCellByPosition(maStartX + i, maStartY), UNO_SET_THROW);
+ sumH += xCellResultH->getValue();
+ }
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Wrong result for fillSeries with TO_RIGHT and LINEAR", maValue * 3 + 6, sumH);
+
+ xCellSeriesH->fillSeries(sheet::FillDirection_TO_RIGHT,
+ sheet::FillMode_GROWTH,
+ sheet::FillDateMode_FILL_DATE_DAY, 2, 1000);
+ sumH = 0;
+ for(sal_Int32 i = 0; i < 3; i++) {
+ uno::Reference<table::XCell> xCellResultH(xCellRange->getCellByPosition(maStartX + i, maStartY), UNO_SET_THROW);
+ sumH += xCellResultH->getValue();
+ }
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Wrong result for fillSeries with TO_RIGHT and GROWTH", maValue + maValue * 2 + maValue * 4, sumH);
+
+ uno::Reference<table::XCellRange> xCellRangeV(xCellRange->getCellRangeByPosition(maStartX, maStartY, maStartX, maStartY + 2), UNO_SET_THROW);
+ uno::Reference<sheet::XCellSeries> xCellSeriesV(xCellRangeV, UNO_QUERY_THROW);
+ xCellSeriesV->fillSeries(sheet::FillDirection_TO_BOTTOM,
+ sheet::FillMode_LINEAR,
+ sheet::FillDateMode_FILL_DATE_DAY, 2, 1000);
+ sal_Int32 sumV = 0;
+ for(sal_Int32 i = 0; i < 3; i++) {
+ uno::Reference<table::XCell> xCellResultV(xCellRange->getCellByPosition(maStartX, maStartY + i), UNO_SET_THROW);
+ sumV += xCellResultV->getValue();
+ }
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Wrong result for fillSeries with TO_BOTTOM and LINEAR", maValue * 3 + 6, sumV);
+
+ xCellSeriesV->fillSeries(sheet::FillDirection_TO_BOTTOM,
+ sheet::FillMode_GROWTH,
+ sheet::FillDateMode_FILL_DATE_DAY, 2, 1000);
+ sumV = 0;
+ for(sal_Int32 i = 0; i < 3; i++) {
+ uno::Reference<table::XCell> xCellResultV(xCellRange->getCellByPosition(maStartX, maStartY + i), UNO_SET_THROW);
+ sumV += xCellResultV->getValue();
+ }
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Wrong result for fillSeries with TO_BOTTOM and GROWTH", maValue + maValue * 2 + maValue * 4, sumV);
+
+ for(sal_Int32 i = 1; i < 3; i++) {
+ uno::Reference<table::XCell> xCellResultH(xCellRange->getCellByPosition(maStartX + i, maStartY), UNO_SET_THROW);
+ xCellResultH->setFormula("");
+ uno::Reference<table::XCell> xCellResultV(xCellRange->getCellByPosition(maStartX, maStartY + i), UNO_SET_THROW);
+ xCellResultV->setFormula("");
+ }
+}
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/test/source/sheet/xconsolidatable.cxx b/test/source/sheet/xconsolidatable.cxx
new file mode 100644
index 0000000000..0efa16b697
--- /dev/null
+++ b/test/source/sheet/xconsolidatable.cxx
@@ -0,0 +1,43 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * 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 <test/sheet/xconsolidatable.hxx>
+
+#include <com/sun/star/sheet/XConsolidatable.hpp>
+#include <com/sun/star/sheet/XConsolidationDescriptor.hpp>
+#include <com/sun/star/uno/Reference.hxx>
+
+#include <cppunit/TestAssert.h>
+
+using namespace css;
+using namespace css::uno;
+
+namespace apitest
+{
+void XConsolidatable::testCreateConsolidationDescriptor()
+{
+ uno::Reference<sheet::XConsolidatable> xConsolidatable(init(), UNO_QUERY_THROW);
+
+ uno::Reference<sheet::XConsolidationDescriptor> xConsolidationDescriptor(
+ xConsolidatable->createConsolidationDescriptor(true), UNO_SET_THROW);
+}
+
+void XConsolidatable::testConsolidate()
+{
+ uno::Reference<sheet::XConsolidatable> xConsolidatable(init(), UNO_QUERY_THROW);
+
+ uno::Reference<sheet::XConsolidationDescriptor> xConsolidationDescriptor(
+ xConsolidatable->createConsolidationDescriptor(true), UNO_SET_THROW);
+
+ xConsolidatable->consolidate(xConsolidationDescriptor);
+ CPPUNIT_ASSERT_MESSAGE("consolidate()", true);
+}
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/test/source/sheet/xconsolidationdescriptor.cxx b/test/source/sheet/xconsolidationdescriptor.cxx
new file mode 100644
index 0000000000..45ba69877e
--- /dev/null
+++ b/test/source/sheet/xconsolidationdescriptor.cxx
@@ -0,0 +1,143 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * 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 <test/sheet/xconsolidationdescriptor.hxx>
+#include <test/cppunitasserthelper.hxx>
+
+#include <com/sun/star/sheet/GeneralFunction.hpp>
+#include <com/sun/star/sheet/XConsolidationDescriptor.hpp>
+#include <com/sun/star/table/CellAddress.hpp>
+#include <com/sun/star/table/CellRangeAddress.hpp>
+#include <com/sun/star/uno/Reference.hxx>
+#include <com/sun/star/uno/Sequence.hxx>
+
+#include <cppunit/TestAssert.h>
+
+using namespace css;
+using namespace css::uno;
+
+namespace apitest
+{
+void XConsolidationDescriptor::testGetFunction()
+{
+ uno::Reference<sheet::XConsolidationDescriptor> xConsolidationDescriptor(init(),
+ UNO_QUERY_THROW);
+
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Unable to get function", sheet::GeneralFunction_SUM,
+ xConsolidationDescriptor->getFunction());
+}
+
+void XConsolidationDescriptor::testSetFunction()
+{
+ uno::Reference<sheet::XConsolidationDescriptor> xConsolidationDescriptor(init(),
+ UNO_QUERY_THROW);
+
+ xConsolidationDescriptor->setFunction(sheet::GeneralFunction_COUNT);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Unable to set function", sheet::GeneralFunction_COUNT,
+ xConsolidationDescriptor->getFunction());
+}
+
+void XConsolidationDescriptor::testGetSources()
+{
+ uno::Reference<sheet::XConsolidationDescriptor> xConsolidationDescriptor(init(),
+ UNO_QUERY_THROW);
+
+ uno::Sequence<table::CellRangeAddress> aSources = xConsolidationDescriptor->getSources();
+ CPPUNIT_ASSERT_MESSAGE("Unable to get sources", !aSources.hasElements());
+}
+
+void XConsolidationDescriptor::testSetSources()
+{
+ uno::Reference<sheet::XConsolidationDescriptor> xConsolidationDescriptor(init(),
+ UNO_QUERY_THROW);
+
+ uno::Sequence<table::CellRangeAddress> aSources{ table::CellRangeAddress(0, 1, 1, 5, 5) };
+ xConsolidationDescriptor->setSources(aSources);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Unable to set sources", table::CellRangeAddress(0, 1, 1, 5, 5),
+ xConsolidationDescriptor->getSources()[0]);
+}
+
+void XConsolidationDescriptor::testGetStartOutputPosition()
+{
+ uno::Reference<sheet::XConsolidationDescriptor> xConsolidationDescriptor(init(),
+ UNO_QUERY_THROW);
+
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Unable to get start output position", table::CellAddress(0, 0, 0),
+ xConsolidationDescriptor->getStartOutputPosition());
+}
+
+void XConsolidationDescriptor::testSetStartOutputPosition()
+{
+ uno::Reference<sheet::XConsolidationDescriptor> xConsolidationDescriptor(init(),
+ UNO_QUERY_THROW);
+
+ xConsolidationDescriptor->setStartOutputPosition(table::CellAddress(0, 1, 2));
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Unable to set start output position", table::CellAddress(0, 1, 2),
+ xConsolidationDescriptor->getStartOutputPosition());
+}
+
+void XConsolidationDescriptor::testGetUseColumnHeaders()
+{
+ uno::Reference<sheet::XConsolidationDescriptor> xConsolidationDescriptor(init(),
+ UNO_QUERY_THROW);
+
+ CPPUNIT_ASSERT_MESSAGE("Unable to get use column headers",
+ !xConsolidationDescriptor->getUseColumnHeaders());
+}
+
+void XConsolidationDescriptor::testSetUseColumnHeaders()
+{
+ uno::Reference<sheet::XConsolidationDescriptor> xConsolidationDescriptor(init(),
+ UNO_QUERY_THROW);
+
+ xConsolidationDescriptor->setUseColumnHeaders(true);
+ CPPUNIT_ASSERT_MESSAGE("Unable to set use column headers",
+ xConsolidationDescriptor->getUseColumnHeaders());
+}
+
+void XConsolidationDescriptor::testGetUseRowHeaders()
+{
+ uno::Reference<sheet::XConsolidationDescriptor> xConsolidationDescriptor(init(),
+ UNO_QUERY_THROW);
+
+ CPPUNIT_ASSERT_MESSAGE("Unable to get use row headers",
+ !xConsolidationDescriptor->getUseRowHeaders());
+}
+
+void XConsolidationDescriptor::testSetUseRowHeaders()
+{
+ uno::Reference<sheet::XConsolidationDescriptor> xConsolidationDescriptor(init(),
+ UNO_QUERY_THROW);
+
+ xConsolidationDescriptor->setUseRowHeaders(true);
+ CPPUNIT_ASSERT_MESSAGE("Unable to set use row headers",
+ xConsolidationDescriptor->getUseRowHeaders());
+}
+
+void XConsolidationDescriptor::testGetInsertLinks()
+{
+ uno::Reference<sheet::XConsolidationDescriptor> xConsolidationDescriptor(init(),
+ UNO_QUERY_THROW);
+
+ CPPUNIT_ASSERT_MESSAGE("Unable to get use insert links",
+ !xConsolidationDescriptor->getInsertLinks());
+}
+
+void XConsolidationDescriptor::testSetInsertLinks()
+{
+ uno::Reference<sheet::XConsolidationDescriptor> xConsolidationDescriptor(init(),
+ UNO_QUERY_THROW);
+
+ xConsolidationDescriptor->setInsertLinks(true);
+ CPPUNIT_ASSERT_MESSAGE("Unable to set use insert links",
+ xConsolidationDescriptor->getInsertLinks());
+}
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/test/source/sheet/xdatabaserange.cxx b/test/source/sheet/xdatabaserange.cxx
new file mode 100644
index 0000000000..9f0828a305
--- /dev/null
+++ b/test/source/sheet/xdatabaserange.cxx
@@ -0,0 +1,173 @@
+/* -*- 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 <test/sheet/xdatabaserange.hxx>
+
+#include <com/sun/star/sheet/XSubTotalDescriptor.hpp>
+#include <com/sun/star/beans/PropertyValue.hpp>
+#include <com/sun/star/sheet/XDatabaseRange.hpp>
+#include <com/sun/star/table/CellRangeAddress.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/sheet/XCellRangeReferrer.hpp>
+#include <com/sun/star/table/XCell.hpp>
+#include <com/sun/star/table/XTableRows.hpp>
+#include <com/sun/star/table/XColumnRowRange.hpp>
+
+#include <rtl/ustring.hxx>
+#include <cppunit/TestAssert.h>
+#include <iostream>
+
+using namespace css;
+using namespace css::uno;
+
+namespace apitest
+{
+/**
+ * tests setDataArea and getDataArea
+ */
+void XDatabaseRange::testDataArea()
+{
+ uno::Reference<sheet::XDatabaseRange> xDBRange(init("DataArea"), UNO_QUERY_THROW);
+
+ table::CellRangeAddress aCellAddress;
+ aCellAddress.Sheet = 0;
+ aCellAddress.StartColumn = 1;
+ aCellAddress.EndColumn = 4;
+ aCellAddress.StartRow = 2;
+ aCellAddress.EndRow = 5;
+ xDBRange->setDataArea(aCellAddress);
+ table::CellRangeAddress aValue = xDBRange->getDataArea();
+ CPPUNIT_ASSERT_EQUAL(aCellAddress.Sheet, aValue.Sheet);
+ CPPUNIT_ASSERT_EQUAL(aCellAddress.StartRow, aValue.StartRow);
+ CPPUNIT_ASSERT_EQUAL(aCellAddress.EndRow, aValue.EndRow);
+ CPPUNIT_ASSERT_EQUAL(aCellAddress.StartColumn, aValue.StartColumn);
+ CPPUNIT_ASSERT_EQUAL(aCellAddress.EndColumn, aValue.EndColumn);
+}
+
+void XDatabaseRange::testGetSubtotalDescriptor()
+{
+ uno::Reference<sheet::XDatabaseRange> xDBRange(init("SubtotalDescriptor"), UNO_QUERY_THROW);
+ uno::Reference<sheet::XSubTotalDescriptor> xSubtotalDescr = xDBRange->getSubTotalDescriptor();
+ CPPUNIT_ASSERT(xSubtotalDescr.is());
+}
+
+void XDatabaseRange::testGetSortDescriptor()
+{
+ uno::Reference<sheet::XDatabaseRange> xDBRange(init("SortDescriptor"), UNO_QUERY_THROW);
+ const uno::Sequence<beans::PropertyValue> xSortDescr = xDBRange->getSortDescriptor();
+ for (const beans::PropertyValue& aProp : xSortDescr)
+ {
+ //std::cout << "Prop " << i << " Name: " << OUString(aProp.Name) << std::endl;
+
+ if (aProp.Name == "IsSortColumns")
+ {
+ bool bIsSortColumns = true;
+ aProp.Value >>= bIsSortColumns;
+ CPPUNIT_ASSERT(!bIsSortColumns);
+ }
+ else if (aProp.Name == "ContainsHeader")
+ {
+ bool bContainsHeader = true;
+ aProp.Value >>= bContainsHeader;
+ CPPUNIT_ASSERT(bContainsHeader);
+ }
+ else if (aProp.Name == "MaxFieldCount")
+ {
+ sal_Int32 nMaxFieldCount = 0;
+ aProp.Value >>= nMaxFieldCount;
+ std::cout << "Value: " << nMaxFieldCount << std::endl;
+ }
+ else if (aProp.Name == "SortFields")
+ {
+ }
+ else if (aProp.Name == "BindFormatsToContent")
+ {
+ bool bBindFormatsToContent = false;
+ aProp.Value >>= bBindFormatsToContent;
+ CPPUNIT_ASSERT(bBindFormatsToContent);
+ }
+ else if (aProp.Name == "CopyOutputData")
+ {
+ bool bCopyOutputData = true;
+ aProp.Value >>= bCopyOutputData;
+ CPPUNIT_ASSERT(!bCopyOutputData);
+ }
+ else if (aProp.Name == "OutputPosition")
+ {
+ }
+ else if (aProp.Name == "IsUserListEnabled")
+ {
+ bool bIsUserListEnabled = true;
+ aProp.Value >>= bIsUserListEnabled;
+ CPPUNIT_ASSERT(!bIsUserListEnabled);
+ }
+ else if (aProp.Name == "UserListIndex")
+ {
+ sal_Int32 nUserListIndex = 1;
+ aProp.Value >>= nUserListIndex;
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(0), nUserListIndex);
+ }
+ }
+}
+
+void XDatabaseRange::testGetFilterDescriptor()
+{
+ uno::Reference<sheet::XDatabaseRange> xDBRange(init("FilterDescriptor"), UNO_QUERY_THROW);
+ uno::Reference<uno::XInterface> xFilterDescr(xDBRange->getFilterDescriptor(), UNO_QUERY_THROW);
+}
+
+void XDatabaseRange::testGetImportDescriptor()
+{
+ uno::Reference<sheet::XDatabaseRange> xDBRange(init("ImportDescriptor"), UNO_QUERY_THROW);
+ (void)xDBRange->getImportDescriptor();
+}
+
+void XDatabaseRange::testRefresh()
+{
+ uno::Reference<sheet::XDatabaseRange> xDBRange(init("Refresh"), UNO_QUERY_THROW);
+
+ const sal_Int32 nCol = 0;
+ OUString aHidden("IsVisible");
+ uno::Reference<sheet::XCellRangeReferrer> xCellRangeReferrer(xDBRange, UNO_QUERY_THROW);
+ uno::Reference<table::XCellRange> xCellRange = xCellRangeReferrer->getReferredCells();
+
+ for (sal_Int32 i = 1; i < 5; ++i)
+ {
+ uno::Reference<table::XCell> xCell = xCellRange->getCellByPosition(nCol, i);
+ xCell->setValue(0);
+ }
+
+ for (sal_Int32 i = 2; i < 5; ++i)
+ {
+ uno::Reference<table::XColumnRowRange> xColRowRange(xCellRange, UNO_QUERY_THROW);
+ uno::Reference<table::XTableRows> xRows = xColRowRange->getRows();
+ uno::Reference<table::XCellRange> xRow(xRows->getByIndex(i), UNO_QUERY_THROW);
+ uno::Reference<beans::XPropertySet> xPropRow(xRow, UNO_QUERY_THROW);
+ Any aAny = xPropRow->getPropertyValue(aHidden);
+
+ CPPUNIT_ASSERT(aAny.get<bool>());
+ }
+
+ xDBRange->refresh();
+ std::cout << "after refresh" << std::endl;
+
+ for (sal_Int32 i = 1; i < 5; ++i)
+ {
+ uno::Reference<table::XColumnRowRange> xColRowRange(xCellRange, UNO_QUERY_THROW);
+ uno::Reference<table::XTableRows> xRows = xColRowRange->getRows();
+ uno::Reference<table::XCellRange> xRow(xRows->getByIndex(i), UNO_QUERY_THROW);
+ uno::Reference<beans::XPropertySet> xPropRow(xRow, UNO_QUERY_THROW);
+ Any aAny = xPropRow->getPropertyValue(aHidden);
+
+ CPPUNIT_ASSERT(!aAny.get<bool>());
+ }
+}
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/test/source/sheet/xdatabaseranges.cxx b/test/source/sheet/xdatabaseranges.cxx
new file mode 100644
index 0000000000..650a0faa39
--- /dev/null
+++ b/test/source/sheet/xdatabaseranges.cxx
@@ -0,0 +1,45 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * 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 <test/sheet/xdatabaseranges.hxx>
+
+#include <com/sun/star/sheet/XDatabaseRanges.hpp>
+#include <com/sun/star/table/CellRangeAddress.hpp>
+#include <com/sun/star/uno/RuntimeException.hpp>
+#include <com/sun/star/uno/Reference.hxx>
+
+#include <cppunit/TestAssert.h>
+
+using namespace css;
+using namespace css::uno;
+
+namespace apitest
+{
+void XDatabaseRanges::testAddRemoveDbRanges()
+{
+ uno::Reference<sheet::XDatabaseRanges> xDbRanges(init(), UNO_QUERY_THROW);
+
+ xDbRanges->addNewByName("addNewRange", table::CellRangeAddress(0, 1, 2, 3, 4));
+ CPPUNIT_ASSERT_MESSAGE("Unable to add new db range", xDbRanges->hasByName("addNewRange"));
+
+ CPPUNIT_ASSERT_THROW_MESSAGE(
+ "No exception thrown, when adding range with existing name",
+ xDbRanges->addNewByName("addNewRange", table::CellRangeAddress(0, 1, 2, 3, 4)),
+ css::uno::RuntimeException);
+
+ xDbRanges->removeByName("addNewRange");
+ CPPUNIT_ASSERT_MESSAGE("Unable to remove db range", !xDbRanges->hasByName("addNewRange"));
+
+ CPPUNIT_ASSERT_THROW_MESSAGE("No exception, when removing none-existing range",
+ xDbRanges->removeByName("addNewRange"),
+ css::uno::RuntimeException);
+}
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/test/source/sheet/xdatapilotdescriptor.cxx b/test/source/sheet/xdatapilotdescriptor.cxx
new file mode 100644
index 0000000000..20392ff8ae
--- /dev/null
+++ b/test/source/sheet/xdatapilotdescriptor.cxx
@@ -0,0 +1,191 @@
+/* -*- 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 <test/sheet/xdatapilotdescriptor.hxx>
+
+#include <com/sun/star/sheet/XDataPilotDescriptor.hpp>
+#include <com/sun/star/table/CellRangeAddress.hpp>
+#include <com/sun/star/sheet/DataPilotFieldOrientation.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+
+#include <cppunit/TestAssert.h>
+
+#include <rtl/ustring.hxx>
+
+using namespace css;
+using namespace css::uno;
+
+namespace apitest {
+
+std::vector< OUString > XDataPilotDescriptor::maFieldNames;
+
+void XDataPilotDescriptor::testTag()
+{
+ OUString aTag("DataPilotDescriptor_Tag");
+ uno::Reference< sheet::XDataPilotDescriptor > xDescr(init(), UNO_QUERY_THROW);
+ xDescr->setTag(aTag);
+ OUString aNewTag = xDescr->getTag();
+ CPPUNIT_ASSERT_EQUAL( aTag, aNewTag );
+}
+
+void XDataPilotDescriptor::testSourceRange()
+{
+ uno::Reference< sheet::XDataPilotDescriptor > xDescr(init(), UNO_QUERY_THROW);
+ table::CellRangeAddress aOldAddress = xDescr->getSourceRange();
+
+ table::CellRangeAddress aAddress;
+ aAddress.Sheet = 1;
+ aAddress.StartColumn = 1;
+ aAddress.StartRow = 1;
+ aAddress.EndColumn = 5;
+ aAddress.EndRow = 5;
+ xDescr->setSourceRange(aAddress);
+
+ table::CellRangeAddress aReturn = xDescr->getSourceRange();
+
+ CPPUNIT_ASSERT_EQUAL(aAddress.Sheet, aReturn.Sheet);
+ CPPUNIT_ASSERT_EQUAL(aAddress.StartColumn, aReturn.StartColumn);
+ CPPUNIT_ASSERT_EQUAL(aAddress.StartRow, aReturn.StartRow);
+ CPPUNIT_ASSERT_EQUAL(aAddress.EndColumn, aReturn.EndColumn);
+ CPPUNIT_ASSERT_EQUAL(aAddress.EndRow, aReturn.EndRow);
+
+ //restore old settings
+ xDescr->setSourceRange(aOldAddress);
+}
+
+void XDataPilotDescriptor::testGetFilterDescriptor()
+{
+ uno::Reference< sheet::XDataPilotDescriptor > xDescr(init(), UNO_QUERY_THROW);
+ uno::Reference< sheet::XSheetFilterDescriptor > xSheetFilterDescr = xDescr->getFilterDescriptor();
+ CPPUNIT_ASSERT(xSheetFilterDescr.is());
+}
+
+void XDataPilotDescriptor::testGetDataPilotFields_Impl( uno::Reference< sheet::XDataPilotDescriptor > const & xDescr)
+{
+ uno::Reference< container::XIndexAccess > xIndex(xDescr->getDataPilotFields(), UNO_SET_THROW);
+
+ sal_Int32 nCount = xIndex->getCount();
+
+ OUString aOrientation("Orientation");
+ for (sal_Int32 i = 0; i < nCount && i < 5; ++i)
+ {
+ uno::Reference< container::XNamed > xNamed( xIndex->getByIndex( i ), UNO_QUERY_THROW);
+ OUString aName = xNamed->getName();
+ maFieldNames.push_back(aName);
+ CPPUNIT_ASSERT( aName != "Data" );
+
+ uno::Reference< beans::XPropertySet > xPropSet( xNamed, UNO_QUERY_THROW);
+
+ switch ( i % 5 )
+ {
+ case 0:
+ {
+ uno::Any aAny;
+ aAny<<= sheet::DataPilotFieldOrientation_COLUMN;
+ xPropSet->setPropertyValue(aOrientation, aAny);
+ }
+ break;
+ case 1:
+ {
+ uno::Any aAny;
+ aAny<<= sheet::DataPilotFieldOrientation_ROW;
+ xPropSet->setPropertyValue(aOrientation, aAny);
+ }
+ break;
+ case 2:
+ {
+ uno::Any aAny;
+ aAny<<= sheet::DataPilotFieldOrientation_DATA;
+ xPropSet->setPropertyValue(aOrientation, aAny);
+ }
+ break;
+ case 3:
+ {
+ uno::Any aAny;
+ aAny<<= sheet::DataPilotFieldOrientation_HIDDEN;
+ xPropSet->setPropertyValue(aOrientation, aAny);
+ }
+ break;
+ case 4:
+ {
+ uno::Any aAny;
+ aAny<<= sheet::DataPilotFieldOrientation_PAGE;
+ xPropSet->setPropertyValue(aOrientation, aAny);
+ }
+ break;
+ }
+ }
+}
+
+void XDataPilotDescriptor::testGetDataPilotFields()
+{
+ uno::Reference< sheet::XDataPilotDescriptor > xDescr(init(), UNO_QUERY_THROW);
+ testGetDataPilotFields_Impl( xDescr );
+}
+
+void XDataPilotDescriptor::testGetColumnFields()
+{
+ uno::Reference< sheet::XDataPilotDescriptor > xDescr(init(),UNO_QUERY_THROW);
+ testGetDataPilotFields_Impl( xDescr );
+ uno::Reference< container::XIndexAccess > xIndex(xDescr->getColumnFields(), UNO_SET_THROW);
+
+ checkName( xIndex, 0 );
+}
+
+void XDataPilotDescriptor::testGetRowFields()
+{
+ uno::Reference< sheet::XDataPilotDescriptor > xDescr(init(),UNO_QUERY_THROW);
+ testGetDataPilotFields_Impl( xDescr );
+ uno::Reference< container::XIndexAccess > xIndex(xDescr->getRowFields(), UNO_SET_THROW);
+
+ //checkName( xIndex, 1 );
+}
+
+void XDataPilotDescriptor::testGetPageFields()
+{
+ uno::Reference< sheet::XDataPilotDescriptor > xDescr(init(), UNO_QUERY_THROW);
+ testGetDataPilotFields_Impl( xDescr );
+ uno::Reference< container::XIndexAccess > xIndex(xDescr->getPageFields(), UNO_SET_THROW);
+
+ checkName( xIndex, 4 );
+}
+
+void XDataPilotDescriptor::testGetDataFields()
+{
+ uno::Reference< sheet::XDataPilotDescriptor > xDescr(init(),UNO_QUERY_THROW);
+ testGetDataPilotFields_Impl( xDescr );
+ uno::Reference< container::XIndexAccess > xIndex(xDescr->getDataFields(), UNO_SET_THROW);
+
+ checkName( xIndex, 2 );
+}
+
+void XDataPilotDescriptor::testGetHiddenFields()
+{
+ uno::Reference< sheet::XDataPilotDescriptor > xDescr(init(),UNO_QUERY_THROW);
+ testGetDataPilotFields_Impl( xDescr );
+ uno::Reference< container::XIndexAccess > xIndex(xDescr->getHiddenFields(), UNO_SET_THROW);
+
+ checkName( xIndex, 3 );
+}
+
+void XDataPilotDescriptor::checkName( uno::Reference< container::XIndexAccess > const & xIndex, std::size_t nIndex )
+{
+ CPPUNIT_ASSERT(xIndex.is());
+ CPPUNIT_ASSERT(maFieldNames.size() >= nIndex);
+
+ for (sal_Int32 i = 0; i < xIndex->getCount(); ++i)
+ {
+ uno::Reference< container::XNamed > xNamed( xIndex->getByIndex(i), UNO_QUERY_THROW);
+ CPPUNIT_ASSERT_EQUAL(maFieldNames[nIndex], xNamed->getName());
+ }
+}
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/test/source/sheet/xdatapilotfield.cxx b/test/source/sheet/xdatapilotfield.cxx
new file mode 100644
index 0000000000..9f14709e61
--- /dev/null
+++ b/test/source/sheet/xdatapilotfield.cxx
@@ -0,0 +1,40 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * 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 <test/sheet/xdatapilotfield.hxx>
+
+#include <com/sun/star/container/XIndexAccess.hpp>
+#include <com/sun/star/sheet/XDataPilotField.hpp>
+#include <com/sun/star/uno/Reference.hxx>
+
+#include <cppunit/TestAssert.h>
+
+using namespace css;
+using namespace css::uno;
+
+namespace apitest
+{
+void XDataPilotField::testGetItems()
+{
+ uno::Reference<sheet::XDataPilotField> xDPF(init(), UNO_QUERY_THROW);
+
+ uno::Reference<container::XIndexAccess> xIA(xDPF->getItems(), UNO_SET_THROW);
+
+ const sal_Int32 nCount = xIA->getCount();
+ CPPUNIT_ASSERT_MESSAGE("No items found", sal_Int32(0) != nCount);
+
+ for (auto i = 0; i < nCount; i++)
+ {
+ CPPUNIT_ASSERT_NO_THROW_MESSAGE("Unable to access element at position " + std::to_string(i),
+ xIA->getByIndex(i));
+ }
+}
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/test/source/sheet/xdatapilotfieldgrouping.cxx b/test/source/sheet/xdatapilotfieldgrouping.cxx
new file mode 100644
index 0000000000..d3ca40d13d
--- /dev/null
+++ b/test/source/sheet/xdatapilotfieldgrouping.cxx
@@ -0,0 +1,44 @@
+/* -*- 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 <test/sheet/xdatapilotfieldgrouping.hxx>
+
+#include <com/sun/star/sheet/XDataPilotFieldGrouping.hpp>
+#include <com/sun/star/sheet/DataPilotFieldGroupBy.hpp>
+
+#include <cppunit/TestAssert.h>
+
+using namespace css;
+using namespace css::uno;
+
+namespace apitest {
+
+void XDataPilotFieldGrouping::testCreateNameGroup()
+{
+ uno::Reference< sheet::XDataPilotFieldGrouping > xDataPilotFieldGrouping(init(),UNO_QUERY_THROW);
+ uno::Reference< sheet::XDataPilotField > xDataPilotField( xDataPilotFieldGrouping, UNO_QUERY_THROW );
+ uno::Reference< container::XNameAccess > xNameAccess( xDataPilotField->getItems(), UNO_QUERY_THROW );
+ CPPUNIT_ASSERT(xNameAccess->hasElements());
+
+ uno::Sequence< OUString > aElements = xNameAccess->getElementNames();
+ xDataPilotFieldGrouping->createNameGroup( aElements );
+}
+
+void XDataPilotFieldGrouping::testCreateDateGroup()
+{
+ uno::Reference< sheet::XDataPilotFieldGrouping > xDataPilotFieldGrouping(init(),UNO_QUERY_THROW);
+ sheet::DataPilotFieldGroupInfo aGroupInfo;
+ aGroupInfo.GroupBy = sheet::DataPilotFieldGroupBy::MONTHS;
+ aGroupInfo.HasDateValues = true;
+ xDataPilotFieldGrouping->createDateGroup(aGroupInfo);
+}
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/test/source/sheet/xdatapilottable.cxx b/test/source/sheet/xdatapilottable.cxx
new file mode 100644
index 0000000000..4cfff74ed5
--- /dev/null
+++ b/test/source/sheet/xdatapilottable.cxx
@@ -0,0 +1,48 @@
+/* -*- 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 <test/sheet/xdatapilottable.hxx>
+#include <com/sun/star/sheet/XDataPilotTable.hpp>
+#include <com/sun/star/table/CellRangeAddress.hpp>
+
+using namespace css;
+using namespace css::uno;
+
+namespace apitest
+{
+void XDataPilotTable::testGetOutputRange()
+{
+ uno::Reference<sheet::XDataPilotTable> xDPTable(init(), UNO_QUERY_THROW);
+
+ table::CellRangeAddress aRange = xDPTable->getOutputRange();
+ CPPUNIT_ASSERT_EQUAL(sal_Int16(0), aRange.Sheet);
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(7), aRange.StartColumn);
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(8), aRange.StartRow);
+}
+
+void XDataPilotTable::testRefresh()
+{
+ uno::Reference<sheet::XDataPilotTable> xDPTable(init(), UNO_QUERY_THROW);
+ std::cout << "xCellForChange: Old Value: " << xCellForChange->getValue() << std::endl;
+ std::cout << "xCellForCheck: Old Value: " << xCellForCheck->getValue() << std::endl;
+ double aOldData = xCellForCheck->getValue();
+ xCellForChange->setValue(5);
+
+ xDPTable->refresh();
+ xDPTable->refresh();
+ std::cout << "xCellForChange: Old Value: " << xCellForChange->getValue() << std::endl;
+ std::cout << "xCellForCheck: Old Value: " << xCellForCheck->getValue() << std::endl;
+ double aNewData = xCellForCheck->getValue();
+ CPPUNIT_ASSERT_MESSAGE("value needs to change", aOldData != aNewData);
+}
+
+XDataPilotTable::~XDataPilotTable() {}
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/test/source/sheet/xdatapilottable2.cxx b/test/source/sheet/xdatapilottable2.cxx
new file mode 100644
index 0000000000..2e802eeadb
--- /dev/null
+++ b/test/source/sheet/xdatapilottable2.cxx
@@ -0,0 +1,276 @@
+/* -*- 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 <test/sheet/xdatapilottable2.hxx>
+#include <com/sun/star/sheet/XDataPilotTable2.hpp>
+#include <com/sun/star/sheet/DataPilotTableResultData.hpp>
+#include <com/sun/star/sheet/XDataPilotDescriptor.hpp>
+#include <com/sun/star/sheet/DataPilotFieldOrientation.hpp>
+#include <com/sun/star/sheet/DataPilotTablePositionType.hpp>
+#include <com/sun/star/sheet/DataPilotOutputRangeType.hpp>
+#include <com/sun/star/sheet/XSpreadsheets.hpp>
+#include <com/sun/star/sheet/XCellAddressable.hpp>
+#include <com/sun/star/table/XCellCursor.hpp>
+#include <com/sun/star/sheet/XCellRangeData.hpp>
+#include <com/sun/star/sheet/DataResult.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <cppunit/TestAssert.h>
+#include <numeric>
+
+using namespace css;
+using namespace css::uno;
+
+namespace apitest {
+
+XDataPilotTable2::~XDataPilotTable2()
+{
+}
+
+void XDataPilotTable2::testGetPositionData()
+{
+ uno::Reference< sheet::XDataPilotTable2 > xDPTable(initDP2(), UNO_QUERY_THROW);
+ getOutputRanges(xDPTable);
+ table::CellAddress aAddr;
+
+ aAddr.Sheet = maRangeTable.Sheet;
+ for (sal_Int32 x = maRangeTable.StartColumn; x <= maRangeTable.EndColumn; ++x)
+ {
+ for (sal_Int32 y = maRangeTable.StartRow; y <= maRangeTable.EndRow; ++y)
+ {
+ aAddr.Column = x;
+ aAddr.Row = y;
+
+ sheet::DataPilotTablePositionData aPosData = xDPTable->getPositionData(aAddr);
+ if (aPosData.PositionType == sheet::DataPilotTablePositionType::NOT_IN_TABLE)
+ {
+ CPPUNIT_ASSERT(false);
+ }
+ }
+ }
+}
+
+void XDataPilotTable2::testGetDrillDownData()
+{
+ uno::Reference< sheet::XDataPilotTable2 > xDPTable(initDP2(), UNO_QUERY_THROW);
+
+ getOutputRanges(xDPTable);
+ buildDataFields(xDPTable);
+ buildResultCells(xDPTable);
+
+ for (const auto& rResultCell : maResultCells)
+ {
+ sheet::DataPilotTablePositionData aPosData = xDPTable->getPositionData(rResultCell);
+ Any aTempAny = aPosData.PositionData;
+ sheet::DataPilotTableResultData aResData;
+ CPPUNIT_ASSERT(aTempAny >>= aResData);
+ sal_Int32 nDim = maDataFieldDims[aResData.DataFieldIndex];
+ sheet::DataResult aRes = aResData.Result;
+ double nVal = aRes.Value;
+
+ const Sequence< Sequence<Any> > aData = xDPTable->getDrillDownData(rResultCell);
+ double sum = 0;
+
+ if( aData.getLength() > 1 )
+ {
+ sum = std::accumulate(std::next(aData.begin()), aData.end(), double(0),
+ [nDim](double res, const Sequence<Any>& rSeq) {
+ double nValue = 0;
+ if (rSeq[nDim] >>= nValue)
+ return res + nValue;
+ return res;
+ });
+ }
+
+ CPPUNIT_ASSERT_DOUBLES_EQUAL(nVal, sum, 1E-12);
+ }
+
+
+}
+
+void XDataPilotTable2::testGetOutputRangeByType()
+{
+ uno::Reference< sheet::XDataPilotTable2 > xDPTable(initDP2(), UNO_QUERY_THROW);
+ getOutputRanges(xDPTable);
+
+ // check for wrong arguments
+ bool bCaught = false;
+ try
+ {
+ xDPTable->getOutputRangeByType(-1);
+ }
+ catch ( const lang::IllegalArgumentException& )
+ {
+ bCaught = true;
+ }
+ CPPUNIT_ASSERT(bCaught);
+
+ bCaught = false;
+ try
+ {
+ xDPTable->getOutputRangeByType(100);
+ }
+ catch ( const lang::IllegalArgumentException& )
+ {
+ bCaught = true;
+ }
+ CPPUNIT_ASSERT(bCaught);
+
+ // make sure the whole range is not empty
+ CPPUNIT_ASSERT( maRangeWhole.EndColumn - maRangeWhole.StartColumn > 0);
+ CPPUNIT_ASSERT( maRangeWhole.EndRow - maRangeWhole.StartRow > 0);
+
+ //table range must be of equal width with the whole range, and the same bottom
+ CPPUNIT_ASSERT_EQUAL( maRangeWhole.Sheet, maRangeTable.Sheet );
+ CPPUNIT_ASSERT_EQUAL( maRangeWhole.EndRow, maRangeTable.EndRow );
+ CPPUNIT_ASSERT_EQUAL( maRangeWhole.StartColumn, maRangeTable.StartColumn );
+ CPPUNIT_ASSERT_EQUAL( maRangeWhole.EndColumn, maRangeTable.EndColumn );
+
+ //result range must be smaller than the table range, and must share the same lower-right corner
+ CPPUNIT_ASSERT_EQUAL( maRangeTable.Sheet, maRangeResult.Sheet );
+ CPPUNIT_ASSERT( maRangeResult.StartColumn >= maRangeTable.StartColumn );
+ CPPUNIT_ASSERT( maRangeResult.StartRow >= maRangeTable.StartRow );
+ CPPUNIT_ASSERT_EQUAL( maRangeTable.EndRow, maRangeResult.EndRow );
+ CPPUNIT_ASSERT_EQUAL( maRangeTable.EndColumn, maRangeResult.EndColumn );
+
+}
+
+void XDataPilotTable2::testInsertDrillDownSheet()
+{
+ uno::Reference< sheet::XDataPilotTable2 > xDPTable(initDP2(), UNO_QUERY_THROW);
+ sal_Int32 nCellCount = maResultCells.size();
+
+ uno::Reference< sheet::XSpreadsheets > xSheets(getSheets(), UNO_QUERY_THROW);
+ uno::Reference< container::XIndexAccess > xIA(xSheets, UNO_QUERY_THROW);
+ sal_Int32 nSheetCount = xIA->getCount();
+
+ for (sal_Int32 i = 0; i < nCellCount; ++i)
+ {
+ table::CellAddress aAddr = maResultCells[i];
+ uno::Sequence< uno::Sequence< Any > > aData = xDPTable->getDrillDownData(aAddr);
+ xDPTable->insertDrillDownSheet(aAddr);
+
+ sal_Int32 nNewSheetCount= xIA->getCount();
+ if (nNewSheetCount == nSheetCount + 1)
+ {
+ CPPUNIT_ASSERT(aData.getLength() >= 2);
+ uno::Reference< sheet::XSpreadsheet > xSheet(xIA->getByIndex(aAddr.Sheet),UNO_QUERY_THROW);
+
+ checkDrillDownSheetContent(xSheet, aData);
+
+ uno::Reference< container::XNamed > xNamed(xSheet, UNO_QUERY_THROW);
+ OUString aName = xNamed->getName();
+ xSheets->removeByName(aName);
+ }
+ else if (nNewSheetCount == nSheetCount)
+ {
+ if (aData.getLength() > 1)
+ {
+ CPPUNIT_ASSERT(false);
+ }
+ }
+ else
+ {
+ CPPUNIT_ASSERT(false);
+ }
+
+ }
+}
+
+void XDataPilotTable2::buildResultCells( uno::Reference< sheet::XDataPilotTable2 > const & xDPTable)
+{
+ getOutputRanges(xDPTable);
+ maResultCells.clear();
+
+ for ( sal_Int32 x = maRangeResult.StartColumn; x < maRangeResult.EndColumn; ++x)
+ {
+ for( sal_Int32 y = maRangeResult.StartRow; y < maRangeResult.EndRow; ++y)
+ {
+ table::CellAddress aAddr;
+ aAddr.Sheet = maRangeResult.Sheet;
+ aAddr.Column = x;
+ aAddr.Row = y;
+ sheet::DataPilotTablePositionData aPosData = xDPTable->getPositionData(aAddr);
+ if (aPosData.PositionType != sheet::DataPilotTablePositionType::RESULT)
+ {
+ CPPUNIT_ASSERT(false);
+ }
+ maResultCells.push_back(aAddr);
+ }
+ }
+}
+
+void XDataPilotTable2::getOutputRanges( uno::Reference< sheet::XDataPilotTable2 > const & xDPTable)
+{
+ maRangeWhole = xDPTable->getOutputRangeByType(sheet::DataPilotOutputRangeType::WHOLE);
+ maRangeTable = xDPTable->getOutputRangeByType(sheet::DataPilotOutputRangeType::TABLE);
+ maRangeResult = xDPTable->getOutputRangeByType(sheet::DataPilotOutputRangeType::RESULT);
+}
+
+void XDataPilotTable2::buildDataFields( uno::Reference< sheet::XDataPilotTable2 > const & xDPTable )
+{
+ uno::Reference< sheet::XDataPilotDescriptor > xDesc(xDPTable, UNO_QUERY_THROW);
+ uno::Reference< container::XIndexAccess > xIndex(xDesc->getDataPilotFields(), UNO_SET_THROW);
+
+ sal_Int32 nFieldCount = xIndex->getCount();
+ for( sal_Int32 i = 0; i < nFieldCount; ++i)
+ {
+ uno::Reference< beans::XPropertySet > xPropSet(xIndex->getByIndex(i), UNO_QUERY_THROW);
+ Any aAny = xPropSet->getPropertyValue("Orientation");
+ sheet::DataPilotFieldOrientation aOrientation;
+ CPPUNIT_ASSERT( aAny >>= aOrientation );
+
+ if ( aOrientation == sheet::DataPilotFieldOrientation_DATA )
+ {
+ maDataFieldDims.push_back( i );
+ }
+ }
+}
+
+namespace {
+
+table::CellAddress getLastUsedCellAddress( uno::Reference< sheet::XSpreadsheet > const & xSheet, sal_Int32 nCol, sal_Int32 nRow )
+{
+ uno::Reference< sheet::XSheetCellRange > xSheetRange( xSheet->getCellRangeByPosition(nCol, nRow, nCol, nRow), UNO_QUERY_THROW);
+ uno::Reference< sheet::XSheetCellCursor > xCursor = xSheet->createCursorByRange(xSheetRange);
+ uno::Reference< table::XCellCursor > xCellCursor(xCursor, UNO_QUERY_THROW);
+ xCellCursor->gotoEnd();
+
+ uno::Reference< sheet::XCellAddressable > xCellAddr(xCursor->getCellByPosition(0, 0), UNO_QUERY_THROW);
+ return xCellAddr->getCellAddress();
+}
+
+}
+
+void XDataPilotTable2::checkDrillDownSheetContent(uno::Reference< sheet::XSpreadsheet > const & xSheet, const uno::Sequence< uno::Sequence< Any > >& aData)
+{
+ table::CellAddress aLastCell = getLastUsedCellAddress(xSheet, 0, 0);
+ CPPUNIT_ASSERT(aData.hasElements());
+ CPPUNIT_ASSERT(aLastCell.Row);
+ CPPUNIT_ASSERT(aLastCell.Column);
+
+ CPPUNIT_ASSERT_EQUAL(aData.getLength(), aLastCell.Row + 1);
+ CPPUNIT_ASSERT_EQUAL(aData[0].getLength(), aLastCell.Column + 1);
+
+ uno::Reference< table::XCellRange > xCellRange = xSheet->getCellRangeByPosition(0, 0, aLastCell.Column, aLastCell.Row);
+ uno::Reference< sheet::XCellRangeData > xCellRangeData(xCellRange, UNO_QUERY_THROW);
+
+ uno::Sequence< uno::Sequence< Any > > aSheetData = xCellRangeData->getDataArray();
+ for (sal_Int32 x = 0; x < aSheetData.getLength(); ++x)
+ {
+ for(sal_Int32 y = 0; y < aSheetData[x].getLength(); ++y)
+ {
+ const Any& aCell1 = aSheetData[x][y];
+ const Any& aCell2 = aData[x][y];
+ CPPUNIT_ASSERT_EQUAL(aCell2, aCell1);
+ }
+ }
+}
+
+}
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/test/source/sheet/xdatapilottables.cxx b/test/source/sheet/xdatapilottables.cxx
new file mode 100644
index 0000000000..b666650eaa
--- /dev/null
+++ b/test/source/sheet/xdatapilottables.cxx
@@ -0,0 +1,53 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * 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 <test/sheet/xdatapilottables.hxx>
+
+#include <com/sun/star/sheet/XDataPilotDescriptor.hpp>
+#include <com/sun/star/sheet/XDataPilotTables.hpp>
+#include <com/sun/star/sheet/XSpreadsheet.hpp>
+#include <com/sun/star/table/CellAddress.hpp>
+#include <com/sun/star/uno/RuntimeException.hpp>
+#include <com/sun/star/uno/Reference.hxx>
+
+#include <cppunit/TestAssert.h>
+
+using namespace css;
+using namespace css::uno;
+
+namespace apitest
+{
+void XDataPilotTables::testXDataPilotTables()
+{
+ uno::Reference<sheet::XDataPilotTables> xDPT(init(), UNO_QUERY_THROW);
+ uno::Reference<sheet::XSpreadsheet> xSheet(getXSpreadsheet(), UNO_QUERY_THROW);
+
+ uno::Reference<sheet::XDataPilotDescriptor> xDPD(xDPT->createDataPilotDescriptor(),
+ UNO_SET_THROW);
+
+ xDPT->insertNewByName("XDataPilotTables", table::CellAddress(0, 9, 8), xDPD);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Unable to insert new DataPilotTable", OUString("Filter"),
+ xSheet->getCellByPosition(9, 8)->getFormula());
+
+ CPPUNIT_ASSERT_THROW_MESSAGE(
+ "No exception thrown, when inserting element with existing name",
+ xDPT->insertNewByName("XDataPilotTables", table::CellAddress(0, 7, 7), xDPD),
+ css::uno::RuntimeException);
+
+ xDPT->removeByName("XDataPilotTables");
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Unable to remove DataPilotTable", OUString(""),
+ xSheet->getCellByPosition(9, 8)->getFormula());
+
+ CPPUNIT_ASSERT_THROW_MESSAGE("No exception, when removing no existing element",
+ xDPT->removeByName("XDataPilotTables"),
+ css::uno::RuntimeException);
+}
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/test/source/sheet/xdatapilottablessupplier.cxx b/test/source/sheet/xdatapilottablessupplier.cxx
new file mode 100644
index 0000000000..66b8d44cad
--- /dev/null
+++ b/test/source/sheet/xdatapilottablessupplier.cxx
@@ -0,0 +1,29 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * 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 <test/sheet/xdatapilottablessupplier.hxx>
+
+#include <com/sun/star/sheet/XDataPilotTables.hpp>
+#include <com/sun/star/sheet/XDataPilotTablesSupplier.hpp>
+#include <com/sun/star/uno/Reference.hxx>
+
+using namespace css;
+using namespace css::uno;
+
+namespace apitest
+{
+void XDataPilotTablesSupplier::testGetDataPilotTables()
+{
+ uno::Reference<sheet::XDataPilotTablesSupplier> xDPTS(init(), UNO_QUERY_THROW);
+
+ uno::Reference<sheet::XDataPilotTables> xDPT(xDPTS->getDataPilotTables(), UNO_SET_THROW);
+}
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/test/source/sheet/xddelink.cxx b/test/source/sheet/xddelink.cxx
new file mode 100644
index 0000000000..cf56fe9cdc
--- /dev/null
+++ b/test/source/sheet/xddelink.cxx
@@ -0,0 +1,44 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * 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 <test/sheet/xddelink.hxx>
+
+#include <com/sun/star/sheet/XDDELink.hpp>
+#include <com/sun/star/uno/Reference.hxx>
+
+#include <cppunit/TestAssert.h>
+
+using namespace css;
+using namespace css::uno;
+
+namespace apitest
+{
+void XDDELink::testGetApplication()
+{
+ uno::Reference<sheet::XDDELink> xLink(init(), UNO_QUERY_THROW);
+
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Unable to execute getApplication()", OUString("soffice"),
+ xLink->getApplication());
+}
+void XDDELink::testGetItem()
+{
+ uno::Reference<sheet::XDDELink> xLink(init(), UNO_QUERY_THROW);
+
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Unable to execute getItem()", OUString("Sheet1.A1"),
+ xLink->getItem());
+}
+void XDDELink::testGetTopic()
+{
+ uno::Reference<sheet::XDDELink> xLink(init(), UNO_QUERY_THROW);
+
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Unable to execute getTopic()", m_URL, xLink->getTopic());
+}
+} // namespace apitest
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/test/source/sheet/xddelinks.cxx b/test/source/sheet/xddelinks.cxx
new file mode 100644
index 0000000000..fc18a16a1e
--- /dev/null
+++ b/test/source/sheet/xddelinks.cxx
@@ -0,0 +1,41 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * 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 <test/sheet/xddelinks.hxx>
+
+#include <com/sun/star/sheet/DDELinkMode.hpp>
+#include <com/sun/star/sheet/XDDELink.hpp>
+#include <com/sun/star/sheet/XDDELinks.hpp>
+
+#include <com/sun/star/uno/Reference.hxx>
+
+#include <cppunit/TestAssert.h>
+
+using namespace css;
+using namespace css::uno;
+
+namespace apitest
+{
+void XDDELinks::testAddDDELink()
+{
+ uno::Reference<sheet::XDDELinks> xLinks(init(), UNO_QUERY_THROW);
+
+ uno::Reference<sheet::XDDELink> xLink
+ = xLinks->addDDELink("soffice", m_aTopic, "Sheet1.A1", sheet::DDELinkMode_DEFAULT);
+
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Unable to execute getApplication()", OUString("soffice"),
+ xLink->getApplication());
+ CPPUNIT_ASSERT_MESSAGE("Unable to execute getTopic()",
+ xLink->getTopic().endsWith("ScDDELinksObj.ods"));
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Unable to execute getItem()", OUString("Sheet1.A1"),
+ xLink->getItem());
+}
+} // namespace apitest
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/test/source/sheet/xdocumentauditing.cxx b/test/source/sheet/xdocumentauditing.cxx
new file mode 100644
index 0000000000..8728f02bfd
--- /dev/null
+++ b/test/source/sheet/xdocumentauditing.cxx
@@ -0,0 +1,137 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * 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 <test/sheet/xdocumentauditing.hxx>
+
+#include <com/sun/star/awt/Point.hpp>
+#include <com/sun/star/beans/PropertyValue.hpp>
+#include <com/sun/star/container/XIndexAccess.hpp>
+#include <com/sun/star/container/XNamed.hpp>
+#include <com/sun/star/drawing/XDrawPage.hpp>
+#include <com/sun/star/drawing/XDrawPagesSupplier.hpp>
+#include <com/sun/star/drawing/XShape.hpp>
+#include <com/sun/star/frame/DispatchHelper.hpp>
+#include <com/sun/star/frame/XDispatchHelper.hpp>
+#include <com/sun/star/frame/XDispatchProvider.hpp>
+#include <com/sun/star/frame/XFrame.hpp>
+#include <com/sun/star/frame/XModel.hpp>
+#include <com/sun/star/sheet/XDocumentAuditing.hpp>
+#include <com/sun/star/sheet/XSheetAuditing.hpp>
+#include <com/sun/star/sheet/XSpreadsheet.hpp>
+#include <com/sun/star/sheet/XSpreadsheetDocument.hpp>
+#include <com/sun/star/sheet/XSpreadsheets.hpp>
+#include <com/sun/star/table/CellAddress.hpp>
+#include <com/sun/star/uno/Reference.hxx>
+#include <com/sun/star/uno/Sequence.hxx>
+#include <com/sun/star/uno/XComponentContext.hpp>
+
+#include <comphelper/processfactory.hxx>
+#include <comphelper/propertyvalue.hxx>
+
+#include <cppunit/TestAssert.h>
+
+using namespace com::sun::star;
+using namespace com::sun::star::uno;
+
+namespace apitest
+{
+void XDocumentAuditing::dispatch(const uno::Reference<frame::XFrame>& xFrame,
+ const uno::Sequence<beans::PropertyValue>& rArguments)
+{
+ uno::Reference<uno::XComponentContext> xContext = ::comphelper::getProcessComponentContext();
+ uno::Reference<frame::XDispatchHelper> xDispatchHelper(frame::DispatchHelper::create(xContext),
+ UNO_SET_THROW);
+ CPPUNIT_ASSERT(xDispatchHelper.is());
+
+ uno::Reference<frame::XDispatchProvider> xDispatchProvider(xFrame, UNO_QUERY_THROW);
+ CPPUNIT_ASSERT(xDispatchProvider.is());
+
+ xDispatchHelper->executeDispatch(xDispatchProvider, ".uno:AutoRefreshArrows", "", 0,
+ rArguments);
+}
+
+bool XDocumentAuditing::hasRightAmountOfShapes(const uno::Reference<drawing::XDrawPage>& xDrawPage,
+ sal_Int32 nElementCount, sal_Int32 nShapes)
+{
+ const sal_Int32 nCount = xDrawPage->getCount();
+ if (nCount != nElementCount + nShapes)
+ return false;
+ else
+ {
+ if (nShapes >= 0)
+ {
+ for (sal_Int32 i = nElementCount; i < nCount; i++)
+ {
+ uno::Reference<drawing::XShape> xShape(xDrawPage->getByIndex(i), UNO_QUERY_THROW);
+ m_Position = xShape->getPosition();
+ }
+ }
+ }
+ return true;
+}
+
+void XDocumentAuditing::testRefreshArrows()
+{
+ uno::Reference<sheet::XDocumentAuditing> xDocumentAuditing(init(), UNO_QUERY_THROW);
+
+ uno::Reference<sheet::XSpreadsheetDocument> xDoc(xDocumentAuditing, UNO_QUERY_THROW);
+ uno::Reference<sheet::XSpreadsheets> xSheets(xDoc->getSheets(), UNO_SET_THROW);
+ uno::Reference<container::XIndexAccess> xIA(xSheets, UNO_QUERY_THROW);
+ uno::Reference<sheet::XSpreadsheet> xSheet1(xIA->getByIndex(0), UNO_QUERY_THROW);
+ uno::Reference<sheet::XSpreadsheet> xSheet2(xIA->getByIndex(1), UNO_QUERY_THROW);
+
+ uno::Reference<drawing::XDrawPagesSupplier> xDPS(xDocumentAuditing, UNO_QUERY_THROW);
+ uno::Reference<drawing::XDrawPage> xDrawPage(xDPS->getDrawPages()->getByIndex(1),
+ UNO_QUERY_THROW);
+
+ sal_Int32 nDrawPageElementCount = 0;
+ if (xDrawPage->hasElements())
+ nDrawPageElementCount = xDrawPage->getCount();
+
+ uno::Sequence<beans::PropertyValue> aPropertyValue{ comphelper::makePropertyValue(
+ "AutoRefreshArrows", false) };
+ uno::Reference<frame::XModel> xModel(xDocumentAuditing, UNO_QUERY_THROW);
+ dispatch(xModel->getCurrentController()->getFrame(), aPropertyValue);
+
+ xSheet1->getCellByPosition(6, 6)->setValue(9);
+ uno::Reference<container::XNamed> xNA1(xSheet1, UNO_QUERY_THROW);
+ OUString sSheet1Name = xNA1->getName();
+
+ xSheet2->getCellByPosition(6, 6)->setValue(16);
+ xSheet2->getCellByPosition(6, 7)->setFormula("= SQRT(G7)");
+
+ uno::Reference<sheet::XSheetAuditing> xSheetAuditing(xSheet2, UNO_QUERY_THROW);
+ xSheetAuditing->showPrecedents(table::CellAddress(1, 6, 7));
+ bool bResult = hasRightAmountOfShapes(xDrawPage, nDrawPageElementCount, 1);
+ CPPUNIT_ASSERT_MESSAGE("Wrong amount of shapes on page", bResult);
+ awt::Point Position0 = m_Position;
+
+ CPPUNIT_ASSERT_DOUBLES_EQUAL(4, xSheet2->getCellByPosition(6, 7)->getValue(), 0.1);
+ xSheet2->getCellByPosition(6, 7)->setFormula("= SQRT(" + sSheet1Name + ".G7)");
+ CPPUNIT_ASSERT_DOUBLES_EQUAL(3, xSheet2->getCellByPosition(6, 7)->getValue(), 0.1);
+
+ bResult = hasRightAmountOfShapes(xDrawPage, nDrawPageElementCount, 1);
+ CPPUNIT_ASSERT_MESSAGE("Wrong amount of shapes on page", bResult);
+ awt::Point Position1 = m_Position;
+
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Arrow has been refreshed", Position0.X, Position1.X);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Arrow has been refreshed", Position0.Y, Position1.Y);
+
+ xDocumentAuditing->refreshArrows();
+
+ bResult = hasRightAmountOfShapes(xDrawPage, nDrawPageElementCount, 1);
+ CPPUNIT_ASSERT_MESSAGE("Wrong amount of shapes on page", bResult);
+ awt::Point Position2 = m_Position;
+
+ CPPUNIT_ASSERT_MESSAGE("Arrow has not been refreshed",
+ Position1.X != Position2.X || Position1.Y != Position2.Y);
+}
+} // namespace apitest
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/test/source/sheet/xformulaquery.cxx b/test/source/sheet/xformulaquery.cxx
new file mode 100644
index 0000000000..32540847e0
--- /dev/null
+++ b/test/source/sheet/xformulaquery.cxx
@@ -0,0 +1,66 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * 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 <test/cppunitasserthelper.hxx>
+#include <test/sheet/xformulaquery.hxx>
+
+#include <com/sun/star/sheet/XFormulaQuery.hpp>
+#include <com/sun/star/sheet/XSheetCellRanges.hpp>
+#include <com/sun/star/sheet/XSpreadsheet.hpp>
+#include <com/sun/star/table/CellRangeAddress.hpp>
+#include <com/sun/star/table/XCell.hpp>
+#include <com/sun/star/uno/Reference.hxx>
+#include <com/sun/star/uno/Sequence.hxx>
+
+#include <cppunit/TestAssert.h>
+
+using namespace com::sun::star;
+using namespace com::sun::star::uno;
+
+namespace apitest
+{
+void XFormulaQuery::testQueryDependents()
+{
+ uno::Reference<sheet::XSpreadsheet> xSheet(getXSpreadsheet(), UNO_QUERY_THROW);
+ xSheet->getCellByPosition(0, 0)->setValue(1);
+ xSheet->getCellByPosition(1, 0)->setValue(1);
+ xSheet->getCellByPosition(2, 0)->setValue(1);
+ xSheet->getCellByPosition(3, 0)->setValue(1);
+
+ uno::Reference<table::XCell> xCell = getXCell();
+ xCell->setFormula("=SUM(A1:D1)");
+
+ uno::Reference<sheet::XFormulaQuery> xFormulaQuery(init(), UNO_QUERY_THROW);
+ uno::Reference<sheet::XSheetCellRanges> xSCR = xFormulaQuery->queryDependents(false);
+ uno::Sequence<table::CellRangeAddress> aCellRangeAddress = xSCR->getRangeAddresses();
+
+ CPPUNIT_ASSERT_EQUAL(aCellRangeAddress[m_nIdxDependents], m_aCellRangeAddressDependents);
+}
+
+void XFormulaQuery::testQueryPrecedents()
+{
+ uno::Reference<sheet::XSpreadsheet> xSheet(getXSpreadsheet(), UNO_QUERY_THROW);
+ xSheet->getCellByPosition(0, 0)->setValue(1);
+ xSheet->getCellByPosition(1, 0)->setValue(1);
+ xSheet->getCellByPosition(2, 0)->setValue(1);
+ xSheet->getCellByPosition(3, 0)->setValue(1);
+ xSheet->getCellByPosition(1, 2)->setFormula("=A16 * 2");
+
+ uno::Reference<table::XCell> xCell = getXCell();
+ xCell->setFormula("=SUM(A1:D1)");
+
+ uno::Reference<sheet::XFormulaQuery> xFormulaQuery(init(), UNO_QUERY_THROW);
+ uno::Reference<sheet::XSheetCellRanges> xSCR = xFormulaQuery->queryPrecedents(false);
+ uno::Sequence<table::CellRangeAddress> aCellRangeAddress = xSCR->getRangeAddresses();
+
+ CPPUNIT_ASSERT_EQUAL(aCellRangeAddress[m_nIdxPrecedents], m_aCellRangeAddressPrecedents);
+}
+} // namespace apitest
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/test/source/sheet/xfunctiondescriptions.cxx b/test/source/sheet/xfunctiondescriptions.cxx
new file mode 100644
index 0000000000..1b4ef645e2
--- /dev/null
+++ b/test/source/sheet/xfunctiondescriptions.cxx
@@ -0,0 +1,73 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * 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 <random>
+
+#include <test/sheet/xfunctiondescriptions.hxx>
+
+#include <com/sun/star/beans/PropertyValue.hpp>
+#include <com/sun/star/sheet/XFunctionDescriptions.hpp>
+#include <com/sun/star/lang/IllegalArgumentException.hpp>
+#include <com/sun/star/uno/Reference.hxx>
+
+#include <cppunit/TestAssert.h>
+
+using namespace css;
+using namespace com::sun::star;
+using namespace com::sun::star::uno;
+
+namespace apitest
+{
+void XFunctionDescriptions::testGetById()
+{
+ uno::Reference<sheet::XFunctionDescriptions> xFD(init(), UNO_QUERY_THROW);
+
+ const sal_Int32 nCount = xFD->getCount();
+ CPPUNIT_ASSERT_MESSAGE("No FunctionDescriptions available", 0 < nCount);
+
+ // first grab a random function descriptions
+ std::random_device rd;
+ std::mt19937 gen(rd());
+ std::uniform_int_distribution<> distr(0, nCount - 1);
+ int nNumber = distr(gen);
+
+ sal_Int32 aId1 = 0;
+ OUString aName1;
+ uno::Sequence<beans::PropertyValue> aProps1;
+ CPPUNIT_ASSERT(xFD->getByIndex(nNumber) >>= aProps1);
+ for (const auto& aProp : std::as_const(aProps1))
+ {
+ if (aProp.Name == "Id")
+ aId1 = aProp.Value.get<sal_Int32>();
+ if (aProp.Name == "Name")
+ aName1 = aProp.Value.get<OUString>();
+ }
+
+ // fetch the same descriptions by its id
+ sal_Int32 aId2 = 0;
+ OUString aName2;
+ const uno::Sequence<beans::PropertyValue> aProps2 = xFD->getById(aId1);
+ CPPUNIT_ASSERT_MESSAGE("Received empty FunctionDescriptions from getById()",
+ aProps2.hasElements());
+ for (const auto& aProp : aProps2)
+ {
+ if (aProp.Name == "Id")
+ aId2 = aProp.Value.get<sal_Int32>();
+ if (aProp.Name == "Name")
+ aName2 = aProp.Value.get<OUString>();
+ }
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Received wrong FunctionDescriptions (Id)", aId1, aId2);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Received wrong FunctionDescriptions (Name)", aName1, aName2);
+
+ CPPUNIT_ASSERT_THROW_MESSAGE("No IllegalArgumentException thrown", xFD->getById(-1),
+ css::lang::IllegalArgumentException);
+}
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/test/source/sheet/xgoalseek.cxx b/test/source/sheet/xgoalseek.cxx
new file mode 100644
index 0000000000..b1de09d2e2
--- /dev/null
+++ b/test/source/sheet/xgoalseek.cxx
@@ -0,0 +1,36 @@
+/* -*- 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 <test/sheet/xgoalseek.hxx>
+#include <com/sun/star/sheet/XGoalSeek.hpp>
+#include <com/sun/star/sheet/GoalResult.hpp>
+#include <com/sun/star/table/CellAddress.hpp>
+
+#include <cppunit/TestAssert.h>
+
+using namespace css;
+using namespace css::uno;
+
+namespace apitest
+{
+void XGoalSeek::testSeekGoal()
+{
+ uno::Reference<sheet::XGoalSeek> xGoalSeek(init(), UNO_QUERY_THROW);
+
+ table::CellAddress aFormulaAddr(0, 3, 5);
+ table::CellAddress aVariableAddr(0, 3, 4);
+ sheet::GoalResult aResult = xGoalSeek->seekGoal(aFormulaAddr, aVariableAddr, "4");
+
+ double nDivergence = 0.01;
+ CPPUNIT_ASSERT(aResult.Divergence < nDivergence);
+ CPPUNIT_ASSERT_DOUBLES_EQUAL(16, aResult.Result, nDivergence);
+}
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/test/source/sheet/xheaderfootercontent.cxx b/test/source/sheet/xheaderfootercontent.cxx
new file mode 100644
index 0000000000..1683cc7e77
--- /dev/null
+++ b/test/source/sheet/xheaderfootercontent.cxx
@@ -0,0 +1,48 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * 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 <test/sheet/xheaderfootercontent.hxx>
+
+#include <com/sun/star/sheet/XHeaderFooterContent.hpp>
+#include <com/sun/star/text/XText.hpp>
+#include <com/sun/star/uno/Reference.hxx>
+
+#include <cppunit/TestAssert.h>
+
+using namespace css;
+using namespace css::uno;
+
+namespace apitest
+{
+void XHeaderFooterContent::testGetCenterText()
+{
+ uno::Reference<sheet::XHeaderFooterContent> xHFC(init(), UNO_QUERY_THROW);
+
+ uno::Reference<text::XText> xText(xHFC->getCenterText(), UNO_SET_THROW);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Unable to get center text", OUString("CENTER"),
+ xText->getString());
+}
+
+void XHeaderFooterContent::testGetLeftText()
+{
+ uno::Reference<sheet::XHeaderFooterContent> xHFC(init(), UNO_QUERY_THROW);
+
+ uno::Reference<text::XText> xText(xHFC->getLeftText(), UNO_SET_THROW);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Unable to get left text", OUString("LEFT"), xText->getString());
+}
+void XHeaderFooterContent::testGetRightText()
+{
+ uno::Reference<sheet::XHeaderFooterContent> xHFC(init(), UNO_QUERY_THROW);
+
+ uno::Reference<text::XText> xText(xHFC->getRightText(), UNO_SET_THROW);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Unable to get right text", OUString("RIGHT"), xText->getString());
+}
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/test/source/sheet/xlabelrange.cxx b/test/source/sheet/xlabelrange.cxx
new file mode 100644
index 0000000000..ed71951235
--- /dev/null
+++ b/test/source/sheet/xlabelrange.cxx
@@ -0,0 +1,50 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * 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 <test/sheet/xlabelrange.hxx>
+#include <test/cppunitasserthelper.hxx>
+
+#include <com/sun/star/sheet/XLabelRange.hpp>
+#include <com/sun/star/table/CellRangeAddress.hpp>
+#include <com/sun/star/uno/Reference.hxx>
+
+#include <cppunit/TestAssert.h>
+
+using namespace css;
+using namespace css::uno;
+
+namespace apitest
+{
+void XLabelRange::testGetSetDataArea()
+{
+ uno::Reference<sheet::XLabelRange> xLabelRange(init(), UNO_QUERY_THROW);
+
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Unable to get DataArea", table::CellRangeAddress(0, 0, 0, 0, 1),
+ xLabelRange->getDataArea());
+
+ table::CellRangeAddress aDataAddr(1, 0, 1, 0, 8);
+ xLabelRange->setDataArea(aDataAddr);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Unable to set DataArea", aDataAddr, xLabelRange->getDataArea());
+}
+
+void XLabelRange::testGetSetLabelArea()
+{
+ uno::Reference<sheet::XLabelRange> xLabelRange(init(), UNO_QUERY_THROW);
+
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Unable to get DataArea", table::CellRangeAddress(0, 0, 1, 0, 6),
+ xLabelRange->getLabelArea());
+
+ table::CellRangeAddress aLabelAddr(1, 0, 1, 0, 8);
+ xLabelRange->setLabelArea(aLabelAddr);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Unable to set LabelArea", aLabelAddr,
+ xLabelRange->getLabelArea());
+}
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/test/source/sheet/xlabelranges.cxx b/test/source/sheet/xlabelranges.cxx
new file mode 100644
index 0000000000..36e2edb45e
--- /dev/null
+++ b/test/source/sheet/xlabelranges.cxx
@@ -0,0 +1,44 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * 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 <test/sheet/xlabelranges.hxx>
+
+#include <com/sun/star/sheet/XLabelRanges.hpp>
+#include <com/sun/star/table/CellRangeAddress.hpp>
+#include <com/sun/star/uno/Reference.hxx>
+
+#include <cppunit/TestAssert.h>
+
+using namespace css;
+using namespace css::uno;
+
+namespace apitest
+{
+void XLabelRanges::testAddNew()
+{
+ uno::Reference<sheet::XLabelRanges> xLabelRanges(init(), UNO_QUERY_THROW);
+
+ const sal_Int32 nCount = xLabelRanges->getCount();
+ xLabelRanges->addNew(table::CellRangeAddress(0, 1, 0, 1, 0),
+ table::CellRangeAddress(0, 1, 1, 1, 6));
+
+ CPPUNIT_ASSERT_MESSAGE("Unable to add new range", nCount < xLabelRanges->getCount());
+}
+
+void XLabelRanges::testRemoveByIndex()
+{
+ uno::Reference<sheet::XLabelRanges> xLabelRanges(init(), UNO_QUERY_THROW);
+
+ const sal_Int32 nCount = xLabelRanges->getCount();
+ xLabelRanges->removeByIndex(nCount - 1);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Unable to remove range", (nCount - 1), xLabelRanges->getCount());
+}
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/test/source/sheet/xmultiformulatokens.cxx b/test/source/sheet/xmultiformulatokens.cxx
new file mode 100644
index 0000000000..ac2b76382b
--- /dev/null
+++ b/test/source/sheet/xmultiformulatokens.cxx
@@ -0,0 +1,43 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * 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 <test/sheet/xmultiformulatokens.hxx>
+
+#include <com/sun/star/sheet/FormulaToken.hpp>
+#include <com/sun/star/sheet/XMultiFormulaTokens.hpp>
+
+#include <com/sun/star/uno/Reference.hxx>
+#include <com/sun/star/uno/Sequence.hxx>
+
+#include <cppunit/TestAssert.h>
+
+using namespace css;
+
+namespace apitest
+{
+void XMultiFormulaTokens::testGetCount()
+{
+ uno::Reference<sheet::XMultiFormulaTokens> xMFT(init(), uno::UNO_QUERY_THROW);
+
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(2), xMFT->getCount());
+}
+
+void XMultiFormulaTokens::testGetSetTokens()
+{
+ uno::Reference<sheet::XMultiFormulaTokens> xMFT(init(), uno::UNO_QUERY_THROW);
+
+ uno::Sequence<sheet::FormulaToken> aTokens{ { /* OpCode */ 2, /* Data */ {} } };
+ xMFT->setTokens(0, aTokens);
+
+ CPPUNIT_ASSERT_EQUAL(aTokens[0].OpCode, xMFT->getTokens(0)[0].OpCode);
+}
+
+} // namespace apitest
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/test/source/sheet/xmultipleoperation.cxx b/test/source/sheet/xmultipleoperation.cxx
new file mode 100644
index 0000000000..d97f269340
--- /dev/null
+++ b/test/source/sheet/xmultipleoperation.cxx
@@ -0,0 +1,95 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * 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 <test/sheet/xmultipleoperation.hxx>
+
+#include <com/sun/star/sheet/TableOperationMode.hpp>
+#include <com/sun/star/sheet/XCellAddressable.hpp>
+#include <com/sun/star/sheet/XCellRangeAddressable.hpp>
+#include <com/sun/star/sheet/XMultipleOperation.hpp>
+#include <com/sun/star/sheet/XSpreadsheet.hpp>
+#include <com/sun/star/table/XCell.hpp>
+#include <com/sun/star/table/XCellRange.hpp>
+#include <com/sun/star/uno/Reference.hxx>
+
+#include <cppunit/TestAssert.h>
+
+using namespace css;
+using namespace css::uno;
+
+namespace apitest
+{
+void XMultipleOperation::testSetTableOperation()
+{
+ uno::Reference<sheet::XMultipleOperation> xMultipleOperation(init(), UNO_QUERY_THROW);
+
+ uno::Reference<sheet::XSpreadsheet> xSheet(getXSpreadsheet(), UNO_QUERY_THROW);
+ uno::Reference<table::XCellRange> xCellRange(xSheet->getCellRangeByName("$A$20:$A$20"),
+ UNO_SET_THROW);
+ uno::Reference<sheet::XCellRangeAddressable> xCellRangeAddr(xCellRange, UNO_QUERY_THROW);
+
+ uno::Reference<table::XCell> xCell = xSheet->getCellByPosition(0, 19);
+ xCell->setFormula("=a18+a19");
+
+ uno::Reference<table::XCell> xCell1 = xSheet->getCellByPosition(0, 17);
+ uno::Reference<sheet::XCellAddressable> xCellAddr1(xCell1, UNO_QUERY_THROW);
+
+ uno::Reference<table::XCell> xCell2 = xSheet->getCellByPosition(0, 18);
+ uno::Reference<sheet::XCellAddressable> xCellAddr2(xCell2, UNO_QUERY_THROW);
+
+ fillCells(xSheet);
+ xMultipleOperation->setTableOperation(
+ xCellRangeAddr->getRangeAddress(), sheet::TableOperationMode_ROW,
+ xCellAddr1->getCellAddress(), xCellAddr2->getCellAddress());
+
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Check cell at position 1,1 (OpMode: ROW)", 5.0,
+ xSheet->getCellByPosition(1, 1)->getValue());
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Check cell at position 2,1 (OpMode: ROW)", 10.0,
+ xSheet->getCellByPosition(2, 1)->getValue());
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Check cell at position 3,1 (OpMode: ROW)", 15.0,
+ xSheet->getCellByPosition(3, 1)->getValue());
+
+ fillCells(xSheet);
+ xMultipleOperation->setTableOperation(
+ xCellRangeAddr->getRangeAddress(), sheet::TableOperationMode_COLUMN,
+ xCellAddr1->getCellAddress(), xCellAddr2->getCellAddress());
+
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Check cell at position 1,1 (OpMode: COLUMN)", 12.0,
+ xSheet->getCellByPosition(1, 1)->getValue());
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Check cell at position 1,2 (OpMode: COLUMN)", 24.0,
+ xSheet->getCellByPosition(1, 2)->getValue());
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Check cell at position 1,3 (OpMode: COLUMN)", 36.0,
+ xSheet->getCellByPosition(1, 3)->getValue());
+
+ fillCells(xSheet);
+ xMultipleOperation->setTableOperation(
+ xCellRangeAddr->getRangeAddress(), sheet::TableOperationMode_BOTH,
+ xCellAddr1->getCellAddress(), xCellAddr2->getCellAddress());
+
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Check cell at position 1,1 (OpMode: BOTH)", 17.0,
+ xSheet->getCellByPosition(1, 1)->getValue());
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Check cell at position 2,2 (OpMode: BOTH)", 34.0,
+ xSheet->getCellByPosition(2, 2)->getValue());
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Check cell at position 3,3 (OpMode: BOTH)", 51.0,
+ xSheet->getCellByPosition(3, 3)->getValue());
+}
+
+void XMultipleOperation::fillCells(uno::Reference<sheet::XSpreadsheet> const& xSheet)
+{
+ for (unsigned int i = 1; i < 5; i++)
+ {
+ uno::Reference<table::XCell> xCellFill = xSheet->getCellByPosition(0, i);
+ xCellFill->setValue(i * 12);
+ xCellFill = xSheet->getCellByPosition(i, 0);
+ xCellFill->setValue(i * 5);
+ }
+}
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/test/source/sheet/xnamedrange.cxx b/test/source/sheet/xnamedrange.cxx
new file mode 100644
index 0000000000..ea9fb77819
--- /dev/null
+++ b/test/source/sheet/xnamedrange.cxx
@@ -0,0 +1,112 @@
+/* -*- 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 <test/sheet/xnamedrange.hxx>
+
+#include <com/sun/star/sheet/XNamedRange.hpp>
+#include <com/sun/star/table/CellAddress.hpp>
+#include <com/sun/star/sheet/NamedRangeFlag.hpp>
+
+#include <cppunit/TestAssert.h>
+#include <rtl/ustring.hxx>
+
+using namespace css;
+using namespace css::uno;
+
+namespace apitest {
+
+void XNamedRange::testGetContent()
+{
+ uno::Reference< sheet::XNamedRange > xNamedRange = getNamedRange("initial1");
+
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Wrong expected content for initial1 on GetContent", OUString("$Sheet1.$B$1"), xNamedRange->getContent());
+}
+
+void XNamedRange::testSetContent()
+{
+ uno::Reference< sheet::XNamedRange > xNamedRange = getNamedRange("initial1");
+
+ OUString aExpectedContent;
+
+ // test a cell
+ aExpectedContent = "D1";
+ xNamedRange->setContent(aExpectedContent);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Wrong expected content for initial1 after SetContent a cell", aExpectedContent, xNamedRange->getContent());
+
+ // test a cellrange
+ aExpectedContent = "D1:D10";
+ xNamedRange->setContent(aExpectedContent);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Wrong expected content for initial1 after SetContent a cellrange", aExpectedContent, xNamedRange->getContent());
+
+ // test a formula
+ aExpectedContent = "=D10";
+ xNamedRange->setContent(aExpectedContent);
+ aExpectedContent = "D10";
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Wrong expected content for initial1 after SetContent a formula", aExpectedContent, xNamedRange->getContent());
+}
+
+void XNamedRange::testGetType()
+{
+ uno::Reference< sheet::XNamedRange > xNamedRange = getNamedRange("initial1");
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Wrong expected Type", sal_Int32(0), xNamedRange->getType());
+}
+
+void XNamedRange::testSetType()
+{
+ uno::Reference< sheet::XNamedRange > xNamedRange = getNamedRange("initial1");
+
+ sal_Int32 nType = ::sheet::NamedRangeFlag::ROW_HEADER;
+ xNamedRange->setType(nType);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Wrong expected Type ROW_HEADER after setting it", nType, xNamedRange->getType());
+
+ nType = ::sheet::NamedRangeFlag::COLUMN_HEADER;
+ xNamedRange->setType(nType);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Wrong expected Type COLUMN_HEADER after setting it", nType, xNamedRange->getType());
+
+ nType = ::sheet::NamedRangeFlag::FILTER_CRITERIA;
+ xNamedRange->setType(nType);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Wrong expected Type FILTER_CRITERIA after setting it", nType, xNamedRange->getType());
+
+ nType = ::sheet::NamedRangeFlag::PRINT_AREA;
+ xNamedRange->setType(nType);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Wrong expected Type PRINT_AREA after setting it", nType, xNamedRange->getType());
+
+ nType = 0;
+ xNamedRange->setType(nType);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Wrong expected Type 0 after setting it", nType, xNamedRange->getType());
+}
+
+void XNamedRange::testGetReferencePosition()
+{
+ uno::Reference< sheet::XNamedRange > xNamedRange = getNamedRange("initial2");
+
+ table::CellAddress aCellAddress = xNamedRange->getReferencePosition();
+ // the expected address is on B1, as it was the active cell when initial2 was created
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Wrong SHEET reference position", sal_Int16(0), aCellAddress.Sheet);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Wrong COLUMN reference position", sal_Int32(1), aCellAddress.Column);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Wrong ROW reference position", sal_Int32(0), aCellAddress.Row);
+}
+
+void XNamedRange::testSetReferencePosition()
+{
+ uno::Reference< sheet::XNamedRange > xNamedRange = getNamedRange("initial1");
+
+ table::CellAddress aBaseAddress(1,2,3);
+
+ xNamedRange->setReferencePosition(aBaseAddress);
+
+ table::CellAddress aCellAddress = xNamedRange->getReferencePosition();
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Wrong SHEET reference position after setting it", sal_Int16(1), aCellAddress.Sheet);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Wrong COLUMN reference position after setting it", sal_Int32(2), aCellAddress.Column);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Wrong ROW reference position after setting it", sal_Int32(3), aCellAddress.Row);
+}
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/test/source/sheet/xnamedranges.cxx b/test/source/sheet/xnamedranges.cxx
new file mode 100644
index 0000000000..e07911f421
--- /dev/null
+++ b/test/source/sheet/xnamedranges.cxx
@@ -0,0 +1,194 @@
+/* -*- 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 <test/sheet/xnamedranges.hxx>
+#include <rtl/ustring.hxx>
+
+#include <com/sun/star/container/XIndexAccess.hpp>
+#include <com/sun/star/sheet/Border.hpp>
+#include <com/sun/star/sheet/NamedRangeFlag.hpp>
+#include <com/sun/star/sheet/XCellRangeAddressable.hpp>
+#include <com/sun/star/sheet/XCellRangeReferrer.hpp>
+#include <com/sun/star/sheet/XNamedRange.hpp>
+#include <com/sun/star/sheet/XNamedRanges.hpp>
+#include <com/sun/star/table/CellAddress.hpp>
+#include <com/sun/star/table/CellRangeAddress.hpp>
+#include <com/sun/star/table/XCell.hpp>
+#include <com/sun/star/text/XTextRange.hpp>
+
+#include <com/sun/star/uno/Reference.hxx>
+
+#include <cppunit/TestAssert.h>
+
+#include <iostream>
+
+using namespace css;
+using namespace css::uno;
+
+namespace apitest
+{
+void XNamedRanges::testAddNewByName()
+{
+ uno::Reference<sheet::XNamedRanges> xNamedRanges(init(), UNO_QUERY_THROW);
+ uno::Reference<container::XNameAccess> xNamedRangesNameAccess(getXNamedRanges(1),
+ UNO_QUERY_THROW);
+
+ table::CellAddress aBaseAddress(0, 0, 0);
+
+ sal_Int32 nType = 0;
+ OUString aName1("type_0");
+ xNamedRanges->addNewByName(aName1, "D1", aBaseAddress, nType);
+ CPPUNIT_ASSERT_MESSAGE("Failed to create Namedrange Type 0 - Normal case",
+ xNamedRanges->hasByName(aName1));
+
+ nType = ::sheet::NamedRangeFlag::COLUMN_HEADER;
+ OUString aName2("type_COLUMN_HEADER");
+ xNamedRanges->addNewByName(aName2, "D2", aBaseAddress, nType);
+ CPPUNIT_ASSERT_MESSAGE("Failed to create Namedrange Type COLUMN_HEADER",
+ xNamedRanges->hasByName(aName2));
+
+ nType = ::sheet::NamedRangeFlag::FILTER_CRITERIA;
+ OUString aName3("type_FILTER_CRITERIA");
+ xNamedRanges->addNewByName(aName3, "D3", aBaseAddress, nType);
+ CPPUNIT_ASSERT_MESSAGE("Failed to create Namedrange Type FILTER_CRITERIA",
+ xNamedRanges->hasByName(aName3));
+
+ nType = ::sheet::NamedRangeFlag::PRINT_AREA;
+ OUString aName4("type_PRINT_AREA");
+ xNamedRanges->addNewByName(aName4, "D4", aBaseAddress, nType);
+ CPPUNIT_ASSERT_MESSAGE("Failed to create Namedrange Type PRINT_AREA",
+ xNamedRanges->hasByName(aName4));
+
+ nType = ::sheet::NamedRangeFlag::ROW_HEADER;
+ OUString aName5("type_ROW_HEADER");
+ xNamedRanges->addNewByName(aName5, "D5", aBaseAddress, nType);
+ CPPUNIT_ASSERT_MESSAGE("Failed to create Namedrange Type ROW_HEADER",
+ xNamedRanges->hasByName(aName5));
+
+ // tdf#119457 - check for a valid range name
+ OUString aName6("type_INVALID_BAD_STRING.+:");
+ CPPUNIT_ASSERT_THROW(xNamedRanges->addNewByName(aName6, "D6", aBaseAddress, 0),
+ uno::RuntimeException);
+ CPPUNIT_ASSERT_MESSAGE("Created Namedrange with invalid name",
+ !xNamedRanges->hasByName(aName6));
+}
+
+void XNamedRanges::testAddNewFromTitles()
+{
+ uno::Reference<sheet::XNamedRanges> xNamedRanges(getXNamedRanges(1), UNO_QUERY_THROW);
+ uno::Reference<container::XIndexAccess> xNamedRangesIndex(xNamedRanges, UNO_QUERY_THROW);
+ uno::Reference<container::XNameAccess> xNamedRangesNameAccess(xNamedRanges, UNO_QUERY_THROW);
+
+ table::CellRangeAddress aCellRangeAddress(1, 0, 0, 3, 3);
+
+ OUString aString;
+ uno::Reference<table::XCell> xCell;
+
+ xNamedRanges->addNewFromTitles(aCellRangeAddress, sheet::Border_TOP);
+
+ for (sal_Int32 i = 1; i < 4; i++)
+ {
+ // verify namedrange exists
+ xCell = xSheet->getCellByPosition(i, 0);
+ uno::Reference<text::XTextRange> xTextRange(xCell, UNO_QUERY_THROW);
+ aString = xTextRange->getString();
+ std::cout << "addNewFromTitles: verify " << aString << std::endl;
+ CPPUNIT_ASSERT_MESSAGE("Non existing NamedRange", xNamedRanges->hasByName(aString));
+
+ // verify it points on the right cell
+ uno::Any aNr = xNamedRangesNameAccess->getByName(aString);
+ uno::Reference<sheet::XNamedRange> xNamedRange(aNr, UNO_QUERY_THROW);
+
+ uno::Reference<sheet::XCellRangeReferrer> xCellRangeRef(xNamedRange, UNO_QUERY_THROW);
+ uno::Reference<sheet::XCellRangeAddressable> xCellRangeAdr(
+ xCellRangeRef->getReferredCells(), UNO_QUERY_THROW);
+ table::CellRangeAddress cellRangeAddress = xCellRangeAdr->getRangeAddress();
+
+ CPPUNIT_ASSERT_EQUAL(i, cellRangeAddress.EndColumn);
+ CPPUNIT_ASSERT_EQUAL(i, cellRangeAddress.StartColumn);
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(1), cellRangeAddress.StartRow);
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(3), cellRangeAddress.EndRow);
+ CPPUNIT_ASSERT_EQUAL(sal_Int16(1), cellRangeAddress.Sheet);
+ }
+
+ xNamedRanges->addNewFromTitles(aCellRangeAddress, sheet::Border_LEFT);
+
+ for (sal_Int32 i = 1; i < 4; i++)
+ {
+ // verify namedrange exists
+ xCell = xSheet->getCellByPosition(0, i);
+ uno::Reference<text::XTextRange> xTextRange(xCell, UNO_QUERY_THROW);
+ aString = xTextRange->getString();
+ std::cout << "verify " << aString << std::endl;
+ CPPUNIT_ASSERT_MESSAGE("Non existing NamedRange", xNamedRanges->hasByName(aString));
+
+ // verify it points on the right cell
+ uno::Any aNr = xNamedRangesNameAccess->getByName(aString);
+ uno::Reference<sheet::XNamedRange> xNamedRange(aNr, UNO_QUERY_THROW);
+
+ uno::Reference<sheet::XCellRangeReferrer> xCellRangeRef(xNamedRange, UNO_QUERY_THROW);
+ uno::Reference<sheet::XCellRangeAddressable> xCellRangeAdr(
+ xCellRangeRef->getReferredCells(), UNO_QUERY_THROW);
+ table::CellRangeAddress cellRangeAddress = xCellRangeAdr->getRangeAddress();
+
+ CPPUNIT_ASSERT_EQUAL(i, cellRangeAddress.EndRow);
+ CPPUNIT_ASSERT_EQUAL(i, cellRangeAddress.StartRow);
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(1), cellRangeAddress.StartColumn);
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(3), cellRangeAddress.EndColumn);
+ CPPUNIT_ASSERT_EQUAL(sal_Int16(1), cellRangeAddress.Sheet);
+ }
+}
+
+void XNamedRanges::testRemoveByName()
+{
+ uno::Reference<sheet::XNamedRanges> xNamedRanges(init(), UNO_QUERY_THROW);
+ uno::Reference<container::XIndexAccess> xIndex(xNamedRanges, UNO_QUERY_THROW);
+
+ bool bHasIt = xNamedRanges->hasByName(maNameToRemove);
+ CPPUNIT_ASSERT_MESSAGE("NamedRange initial1 does not exist, can't remove it", bHasIt);
+
+ if (!bHasIt)
+ return;
+
+ // remove existing
+ sal_Int32 nInitialCount = xIndex->getCount();
+ xNamedRanges->removeByName(maNameToRemove);
+ sal_Int32 nNewCount = xIndex->getCount();
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("NamedRange initial1 not removed", nNewCount, nInitialCount - 1);
+ CPPUNIT_ASSERT_MESSAGE("Wrong NamedRange removed, initial1 still present",
+ !xNamedRanges->hasByName(maNameToRemove));
+ // try to remove non existing
+ xNamedRanges->removeByName("dummyNonExistingNamedRange"); // an exception should be raised here
+}
+
+void XNamedRanges::testOutputList()
+{
+ table::CellAddress aCellAddress(0, 2, 0);
+ uno::Reference<sheet::XNamedRanges> xNamedRanges(init(), UNO_QUERY_THROW);
+ uno::Reference<container::XIndexAccess> xNamedRangesIndex(init(), UNO_QUERY_THROW);
+ sal_Int32 nElementsCount = xNamedRangesIndex->getCount();
+
+ xNamedRanges->outputList(aCellAddress);
+
+ OUString aString;
+ uno::Reference<table::XCell> xCell;
+
+ for (sal_Int32 i = 0; i < nElementsCount; i++)
+ {
+ xCell = xSheet->getCellByPosition(2, i);
+ uno::Reference<text::XTextRange> xTextRange(xCell, UNO_QUERY_THROW);
+ aString = xTextRange->getString();
+ std::cout << "verify " << aString << std::endl;
+ CPPUNIT_ASSERT_MESSAGE("Non existing NamedRange", xNamedRanges->hasByName(aString));
+ }
+}
+
+} // namespace apitest
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/test/source/sheet/xprintareas.cxx b/test/source/sheet/xprintareas.cxx
new file mode 100644
index 0000000000..8c5ffe3d05
--- /dev/null
+++ b/test/source/sheet/xprintareas.cxx
@@ -0,0 +1,40 @@
+/* -*- 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 <test/sheet/xprintareas.hxx>
+#include <com/sun/star/sheet/XPrintAreas.hpp>
+
+#include <cppunit/TestAssert.h>
+
+using namespace css;
+using namespace css::uno;
+
+namespace apitest {
+
+ void XPrintAreas::testSetAndGetPrintTitleColumns()
+ {
+ uno::Reference< sheet::XPrintAreas > xPrintAreas(init(), UNO_QUERY_THROW);
+ xPrintAreas->setPrintTitleColumns(true);
+
+ CPPUNIT_ASSERT_MESSAGE("Wrong attribution at PrintTitleColumns", xPrintAreas->getPrintTitleColumns());
+
+ }
+
+ void XPrintAreas::testSetAndGetPrintTitleRows()
+ {
+ uno::Reference< sheet::XPrintAreas > xPrintAreas(init(), UNO_QUERY_THROW);
+ xPrintAreas->setPrintTitleRows(true);
+
+ CPPUNIT_ASSERT_MESSAGE("Wrong attribution at PrintTitleRows", xPrintAreas->getPrintTitleRows());
+ }
+
+ // the rest is right now in progress...
+
+
+}
diff --git a/test/source/sheet/xrecentfunctions.cxx b/test/source/sheet/xrecentfunctions.cxx
new file mode 100644
index 0000000000..5680b666a2
--- /dev/null
+++ b/test/source/sheet/xrecentfunctions.cxx
@@ -0,0 +1,77 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * 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 <random>
+
+#include <test/sheet/xrecentfunctions.hxx>
+
+#include <com/sun/star/sheet/XRecentFunctions.hpp>
+#include <com/sun/star/uno/Reference.hxx>
+#include <com/sun/star/uno/Sequence.hxx>
+
+#include <cppunit/TestAssert.h>
+
+using namespace css;
+using namespace css::uno;
+
+namespace apitest
+{
+void XRecentFunctions::testGetRecentFunctionIds()
+{
+ uno::Reference<sheet::XRecentFunctions> xRecentFunctions(init(), UNO_QUERY_THROW);
+
+ uno::Sequence<sal_Int32> aIds = xRecentFunctions->getRecentFunctionIds();
+ const sal_Int32 nNumber = aIds.getLength();
+ CPPUNIT_ASSERT_MESSAGE("Recent IDs greater the max number",
+ nNumber <= xRecentFunctions->getMaxRecentFunctions());
+ for (int i = 0; i < nNumber - 1; i++)
+ for (int j = i + 1; j < nNumber; j++)
+ CPPUNIT_ASSERT_MESSAGE("Same IDs found", aIds[i] != aIds[j]);
+}
+
+void XRecentFunctions::testSetRecentFunctionIds()
+{
+ uno::Reference<sheet::XRecentFunctions> xRecentFunctions(init(), UNO_QUERY_THROW);
+
+ const sal_Int32 nMaxNumber = xRecentFunctions->getMaxRecentFunctions();
+
+ // empty list
+ uno::Sequence<sal_Int32> aIds;
+ xRecentFunctions->setRecentFunctionIds(aIds);
+
+ aIds = xRecentFunctions->getRecentFunctionIds();
+ CPPUNIT_ASSERT_MESSAGE("Unable to set Ids (empty list)", !aIds.hasElements());
+
+ // max. size list
+ aIds.realloc(nMaxNumber);
+ auto pIds = aIds.getArray();
+ std::random_device rd;
+ std::mt19937 gen(rd());
+ std::uniform_int_distribution<> distr(1, nMaxNumber + 1);
+
+ int nStartIdx = distr(gen);
+ for (int i = nStartIdx; i < nStartIdx + nMaxNumber; i++)
+ pIds[i - nStartIdx] = 1;
+
+ xRecentFunctions->setRecentFunctionIds(aIds);
+
+ aIds = xRecentFunctions->getRecentFunctionIds();
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Unable to set Ids (max. size list)", nMaxNumber,
+ aIds.getLength());
+}
+
+void XRecentFunctions::testGetMaxRecentFunctions()
+{
+ uno::Reference<sheet::XRecentFunctions> xRecentFunctions(init(), UNO_QUERY_THROW);
+ CPPUNIT_ASSERT_MESSAGE("Unable to execute getMaxRecentFunctions()",
+ sal_Int32(0) != xRecentFunctions->getMaxRecentFunctions());
+}
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/test/source/sheet/xscenario.cxx b/test/source/sheet/xscenario.cxx
new file mode 100644
index 0000000000..9d874d9517
--- /dev/null
+++ b/test/source/sheet/xscenario.cxx
@@ -0,0 +1,43 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * 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 <test/sheet/xscenario.hxx>
+
+#include <com/sun/star/sheet/XScenario.hpp>
+#include <com/sun/star/table/CellRangeAddress.hpp>
+#include <com/sun/star/uno/Reference.hxx>
+#include <com/sun/star/uno/Sequence.hxx>
+
+#include <cppunit/TestAssert.h>
+
+using namespace css;
+using namespace css::uno;
+
+namespace apitest
+{
+void XScenario::testScenario()
+{
+ uno::Reference<sheet::XScenario> xScenario(getScenarioSpreadsheet(), UNO_QUERY_THROW);
+ CPPUNIT_ASSERT_MESSAGE("Sheet is not a Scenario sheet", xScenario->getIsScenario());
+
+ uno::Sequence<table::CellRangeAddress> aCellRangeAddr(1);
+ xScenario->addRanges(aCellRangeAddr);
+ xScenario->apply();
+
+ CPPUNIT_ASSERT_MESSAGE("Unable add and apply ranges", xScenario->getIsScenario());
+ CPPUNIT_ASSERT_MESSAGE("Unable execute getScenarioComment()",
+ !xScenario->getScenarioComment().isEmpty());
+
+ xScenario->setScenarioComment("Test");
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Unable execute setScenarioComment()", OUString("Test"),
+ xScenario->getScenarioComment());
+}
+} // namespace apitest
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/test/source/sheet/xscenarioenhanced.cxx b/test/source/sheet/xscenarioenhanced.cxx
new file mode 100644
index 0000000000..ed4d934b6c
--- /dev/null
+++ b/test/source/sheet/xscenarioenhanced.cxx
@@ -0,0 +1,38 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * 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 <test/sheet/xscenarioenhanced.hxx>
+#include <test/cppunitasserthelper.hxx>
+
+#include <com/sun/star/sheet/XScenarioEnhanced.hpp>
+#include <com/sun/star/table/CellRangeAddress.hpp>
+
+#include <com/sun/star/uno/Reference.hxx>
+#include <com/sun/star/uno/Sequence.hxx>
+
+#include <cppunit/TestAssert.h>
+
+using namespace css;
+using namespace css::uno;
+
+namespace apitest
+{
+void XScenarioEnhanced::testGetRanges()
+{
+ uno::Reference<sheet::XScenarioEnhanced> xSE(getScenarioSpreadsheet(), UNO_QUERY_THROW);
+
+ uno::Sequence<table::CellRangeAddress> aCellRangeAddr = xSE->getRanges();
+ CPPUNIT_ASSERT_MESSAGE("No ranges found", aCellRangeAddr.hasElements());
+
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Wrong CellRangeAddres", table::CellRangeAddress(1, 0, 0, 10, 10),
+ aCellRangeAddr[0]);
+}
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/test/source/sheet/xscenarios.cxx b/test/source/sheet/xscenarios.cxx
new file mode 100644
index 0000000000..77781361ea
--- /dev/null
+++ b/test/source/sheet/xscenarios.cxx
@@ -0,0 +1,43 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * 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 <test/sheet/xscenarios.hxx>
+
+#include <com/sun/star/sheet/XScenarios.hpp>
+#include <com/sun/star/table/CellRangeAddress.hpp>
+#include <com/sun/star/uno/Reference.hxx>
+#include <com/sun/star/uno/Sequence.hxx>
+
+#include <cppunit/TestAssert.h>
+
+using namespace css;
+using namespace css::uno;
+
+namespace apitest
+{
+void XScenarios::testAddNewByName()
+{
+ uno::Reference<sheet::XScenarios> xScenarios(init(), UNO_QUERY_THROW);
+
+ uno::Sequence<table::CellRangeAddress> aCellRangeAddresses{ table::CellRangeAddress(0, 0, 0, 0,
+ 0) };
+ xScenarios->addNewByName("XScenarios2", aCellRangeAddresses, "new");
+ CPPUNIT_ASSERT_MESSAGE("Unable to add new XScenario", xScenarios->hasByName("XScenarios2"));
+}
+
+void XScenarios::testRemoveByName()
+{
+ uno::Reference<sheet::XScenarios> xScenarios(init(), UNO_QUERY_THROW);
+
+ xScenarios->removeByName("XScenarios");
+ CPPUNIT_ASSERT_MESSAGE("Unable to remove XScenario", !xScenarios->hasByName("XScenario"));
+}
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/test/source/sheet/xscenariossupplier.cxx b/test/source/sheet/xscenariossupplier.cxx
new file mode 100644
index 0000000000..3b9ff68d49
--- /dev/null
+++ b/test/source/sheet/xscenariossupplier.cxx
@@ -0,0 +1,28 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * 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 <test/sheet/xscenariossupplier.hxx>
+
+#include <com/sun/star/sheet/XScenarios.hpp>
+#include <com/sun/star/sheet/XScenariosSupplier.hpp>
+#include <com/sun/star/uno/Reference.hxx>
+
+using namespace css;
+using namespace css::uno;
+
+namespace apitest
+{
+void XScenariosSupplier::testGetScenarios()
+{
+ uno::Reference<sheet::XScenariosSupplier> xSupplier(init(), UNO_QUERY_THROW);
+ uno::Reference<sheet::XScenarios> xScenarios(xSupplier->getScenarios(), UNO_SET_THROW);
+}
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/test/source/sheet/xsheetannotation.cxx b/test/source/sheet/xsheetannotation.cxx
new file mode 100644
index 0000000000..1ce4e1a796
--- /dev/null
+++ b/test/source/sheet/xsheetannotation.cxx
@@ -0,0 +1,70 @@
+/* -*- 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 <test/sheet/xsheetannotation.hxx>
+
+#include <com/sun/star/table/CellAddress.hpp>
+
+#include <cppunit/TestAssert.h>
+#include <rtl/ustring.hxx>
+
+using namespace css;
+using namespace css::uno;
+
+namespace apitest {
+
+void XSheetAnnotation::testGetPosition()
+{
+ uno::Reference< sheet::XSheetAnnotation > aSheetAnnotation (init(), UNO_QUERY_THROW);
+ table::CellAddress aResultCellAddress = aSheetAnnotation->getPosition();
+
+ //expected result
+ table::CellAddress aExpectedCellAddress;
+ aExpectedCellAddress.Sheet = 0;
+ aExpectedCellAddress.Row = 1;
+ aExpectedCellAddress.Column = 2;
+
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Wrong SHEET reference position", aExpectedCellAddress.Sheet, aResultCellAddress.Sheet);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Wrong COLUMN reference position", aExpectedCellAddress.Column, aResultCellAddress.Column);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Wrong ROW reference position", aExpectedCellAddress.Row, aResultCellAddress.Row);
+}
+
+void XSheetAnnotation::testGetAuthor()
+{
+ uno::Reference< sheet::XSheetAnnotation > aSheetAnnotation (init(), UNO_QUERY_THROW);
+ OUString aAuthor = aSheetAnnotation->getAuthor();
+
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Wrong author", OUString("LG"), aAuthor);
+}
+void XSheetAnnotation::testGetDate()
+{
+ uno::Reference< sheet::XSheetAnnotation > aSheetAnnotation (init(), UNO_QUERY_THROW);
+ OUString aDate = aSheetAnnotation->getDate();
+
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Wrong date", OUString("01/17/2013"), aDate);
+}
+void XSheetAnnotation::testGetIsVisible()
+{
+ uno::Reference< sheet::XSheetAnnotation > aSheetAnnotation (init(), UNO_QUERY_THROW);
+ bool isVisible = aSheetAnnotation->getIsVisible();
+
+ CPPUNIT_ASSERT_MESSAGE("Wrong visible state", isVisible);
+}
+void XSheetAnnotation::testSetIsVisible()
+{
+ uno::Reference< sheet::XSheetAnnotation > aSheetAnnotation (init(), UNO_QUERY_THROW);
+ aSheetAnnotation->setIsVisible(false);
+ bool isVisible = aSheetAnnotation->getIsVisible();
+
+ CPPUNIT_ASSERT_MESSAGE("Visible state not changed", !isVisible);
+}
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/test/source/sheet/xsheetannotationanchor.cxx b/test/source/sheet/xsheetannotationanchor.cxx
new file mode 100644
index 0000000000..8c8467d788
--- /dev/null
+++ b/test/source/sheet/xsheetannotationanchor.cxx
@@ -0,0 +1,44 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * 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 <test/sheet/xsheetannotationanchor.hxx>
+#include <test/cppunitasserthelper.hxx>
+
+#include <com/sun/star/sheet/XSheetAnnotation.hpp>
+#include <com/sun/star/sheet/XSheetAnnotationAnchor.hpp>
+#include <com/sun/star/table/CellAddress.hpp>
+#include <com/sun/star/uno/Reference.hxx>
+
+#include <cppunit/TestAssert.h>
+
+using namespace css;
+using namespace css::uno;
+
+namespace apitest
+{
+void XSheetAnnotationAnchor::testGetAnnotation()
+{
+ uno::Reference<sheet::XSheetAnnotationAnchor> xAnchor(init(), UNO_QUERY_THROW);
+ uno::Reference<sheet::XSheetAnnotation> xAnnotation(xAnchor->getAnnotation(), UNO_SET_THROW);
+ CPPUNIT_ASSERT_MESSAGE("Unable to get XSheetAnnotation", xAnnotation.is());
+
+ CPPUNIT_ASSERT_MESSAGE("Unable to check: getAuthor()", !xAnnotation->getAuthor().isEmpty());
+ CPPUNIT_ASSERT_MESSAGE("Unable to check: getDate()", !xAnnotation->getDate().isEmpty());
+ CPPUNIT_ASSERT_MESSAGE("Unable to check: getIsVisible()", !xAnnotation->getIsVisible());
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Unable to check: getPosition()", table::CellAddress(0, 2, 3),
+ xAnnotation->getPosition());
+
+ xAnnotation->setIsVisible(false);
+ CPPUNIT_ASSERT_MESSAGE("Unable to setIsVisible() to false", !xAnnotation->getIsVisible());
+ xAnnotation->setIsVisible(true);
+ CPPUNIT_ASSERT_MESSAGE("Unable to setIsVisible() to true", xAnnotation->getIsVisible());
+}
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/test/source/sheet/xsheetannotations.cxx b/test/source/sheet/xsheetannotations.cxx
new file mode 100644
index 0000000000..9f082eeb90
--- /dev/null
+++ b/test/source/sheet/xsheetannotations.cxx
@@ -0,0 +1,212 @@
+/* -*- 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 <test/sheet/xsheetannotations.hxx>
+
+#include <com/sun/star/table/CellAddress.hpp>
+#include <com/sun/star/container/XIndexAccess.hpp>
+#include <com/sun/star/sheet/XSheetAnnotation.hpp>
+#include <com/sun/star/text/XTextRange.hpp>
+
+#include <cppunit/TestAssert.h>
+#include <rtl/ustring.hxx>
+
+using namespace css;
+using namespace css::uno;
+
+namespace apitest {
+
+void XSheetAnnotations::testCount()
+{
+ uno::Reference< sheet::XSheetAnnotations > aSheetAnnotations (init(), UNO_QUERY_THROW);
+
+ // count on sheet 1 before inserting
+ uno::Reference< container::XIndexAccess > xAnnotationsIndex (aSheetAnnotations, UNO_QUERY_THROW);
+ sal_Int32 nBefore = xAnnotationsIndex->getCount();
+
+ // get Sheet 2 annotations
+ uno::Reference< sheet::XSheetAnnotations > xSheet2Annotations( getAnnotations(1), UNO_SET_THROW);
+
+ // insert a note on sheet 2
+ table::CellAddress aTargetCellAddress (1,0,0);
+ xSheet2Annotations->insertNew(aTargetCellAddress, "an inserted annotation on sheet 2");
+
+ // count again on sheet 1
+ sal_Int32 nAfter = xAnnotationsIndex->getCount();
+
+ CPPUNIT_ASSERT_EQUAL_MESSAGE( "Annotations count should not change on sheet 1", nBefore, nAfter);
+}
+
+void XSheetAnnotations::testInsertNew()
+{
+ uno::Reference< sheet::XSheetAnnotations > aSheetAnnotations (init(), UNO_QUERY_THROW);
+
+ // count before inserting
+ uno::Reference< container::XIndexAccess > xAnnotationsIndex (aSheetAnnotations, UNO_QUERY_THROW);
+ sal_Int32 nBefore = xAnnotationsIndex->getCount();
+
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(
+ "There should already be one note", sal_Int32(1), nBefore );
+
+ // insert the annotation
+ table::CellAddress aTargetCellAddress (0,3,4);
+ aSheetAnnotations->insertNew(aTargetCellAddress, "an inserted annotation");
+
+ // count after inserting
+ //uno::Reference< container::XIndexAccess > xAnnotationsIndexAfter (aSheetAnnotations, UNO_QUERY_THROW);
+ sal_Int32 nAfter = xAnnotationsIndex->getCount();
+
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(
+ "Annotations index not updated", nBefore + 1, nAfter);
+
+ // is the position ok ?
+ uno::Reference< sheet::XSheetAnnotation > aLastSheetAnnotation (xAnnotationsIndex->getByIndex(nAfter-1), UNO_QUERY_THROW);
+ table::CellAddress aResultCellAddress = aLastSheetAnnotation->getPosition();
+
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(
+ "Insert Annotation - Wrong SHEET reference position",
+ aTargetCellAddress.Sheet, aResultCellAddress.Sheet);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(
+ "Insert Annotation - Wrong COLUMN reference position",
+ aTargetCellAddress.Column, aResultCellAddress.Column);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(
+ "Insert Annotation - Wrong ROW reference position",
+ aTargetCellAddress.Row, aResultCellAddress.Row);
+
+ // is the string ok ?
+ uno::Reference< text::XTextRange > aTextSheetAnnotation(aLastSheetAnnotation, UNO_QUERY_THROW);
+ OUString aString = aTextSheetAnnotation->getString();
+
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(
+ "Insert Annotation - Wrong string", OUString("an inserted annotation"),
+ aString);
+
+}
+
+void XSheetAnnotations::testRemoveByIndex()
+{
+ uno::Reference< sheet::XSheetAnnotations > aSheetAnnotations (init(), UNO_QUERY_THROW);
+
+ // insert some annotations
+ table::CellAddress aTargetCellAddress (0,4,5);
+ aSheetAnnotations->insertNew(aTargetCellAddress, "an inserted annotation 1");
+ table::CellAddress aToBeRemovedCellAddress (0,5,6);
+ aSheetAnnotations->insertNew(aToBeRemovedCellAddress, "an inserted annotation 2");
+ table::CellAddress aOtherCellAddress (0,7,8);
+ aSheetAnnotations->insertNew(aOtherCellAddress, "an inserted annotation 3");
+
+ // count before removing
+ uno::Reference< container::XIndexAccess > xAnnotationsIndex (aSheetAnnotations, UNO_QUERY_THROW);
+ sal_Int32 nBefore = xAnnotationsIndex->getCount();
+
+ // remove the xToBeRemovedCellAddress
+ aSheetAnnotations->removeByIndex(nBefore-2);
+
+ // count after removing
+ //uno::Reference< container::XIndexAccess > xAnnotationsIndex (aSheetAnnotations, UNO_QUERY_THROW);
+ sal_Int32 nAfter = xAnnotationsIndex->getCount();
+
+ // the last position should be xOtherCellAddress
+ uno::Reference< sheet::XSheetAnnotation > aLastSheetAnnotation (xAnnotationsIndex->getByIndex(nAfter-1), UNO_QUERY_THROW);
+ table::CellAddress aResultCellAddress = aLastSheetAnnotation->getPosition();
+
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(
+ "Remove Annotation - Wrong SHEET reference position",
+ aOtherCellAddress.Sheet, aResultCellAddress.Sheet);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(
+ "Remove Annotation - Wrong COLUMN reference position",
+ aOtherCellAddress.Column, aResultCellAddress.Column);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(
+ "Remove Annotation - Wrong ROW reference position",
+ aOtherCellAddress.Row, aResultCellAddress.Row);
+
+ // is the string ok ?
+ uno::Reference< text::XTextRange > aLastTextSheetAnnotation(aLastSheetAnnotation, UNO_QUERY_THROW);
+ OUString aLastString = aLastTextSheetAnnotation->getString();
+
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(
+ "Remove Annotation - Wrong string",
+ OUString("an inserted annotation 3"), aLastString);
+
+ // the previous should be xTargetCellAddress
+ uno::Reference< sheet::XSheetAnnotation > aPreviousSheetAnnotation (xAnnotationsIndex->getByIndex(nAfter-2), UNO_QUERY_THROW);
+ table::CellAddress aPreviousCellAddress = aPreviousSheetAnnotation->getPosition();
+
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(
+ "Remove Annotation - Wrong SHEET reference position",
+ aTargetCellAddress.Sheet, aPreviousCellAddress.Sheet);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(
+ "Remove Annotation - Wrong COLUMN reference position",
+ aTargetCellAddress.Column, aPreviousCellAddress.Column);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(
+ "Remove Annotation - Wrong ROW reference position",
+ aTargetCellAddress.Row, aPreviousCellAddress.Row);
+
+ // is the string ok ?
+ uno::Reference< text::XTextRange > aPreviousTextSheetAnnotation(aPreviousSheetAnnotation, UNO_QUERY_THROW);
+ OUString aPreviousString = aPreviousTextSheetAnnotation->getString();
+
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(
+ "Remove Annotation - Wrong string",
+ OUString("an inserted annotation 1"), aPreviousString);
+}
+
+void XSheetAnnotations::testIndex()
+{
+
+ // testing #fdo80551 - getByIndex not on the first sheet
+
+ // insert annotations in first sheet
+ uno::Reference< sheet::XSheetAnnotations > aSheet0Annotations (init(), UNO_QUERY_THROW);
+ table::CellAddress aTargetCellAddress0 (0,0,1);
+ aSheet0Annotations->insertNew(aTargetCellAddress0, "an inserted annotation 1 on sheet 1");
+ table::CellAddress aSecondTargetCellAddress0 (0,0,2);
+ aSheet0Annotations->insertNew(aSecondTargetCellAddress0, "an inserted annotation 2 on sheet 1");
+ table::CellAddress aThirdCellAddress0 (0,0,3);
+ aSheet0Annotations->insertNew(aThirdCellAddress0, "an inserted annotation 3 on sheet 1");
+
+ // insert annotations in third sheet
+ uno::Reference< sheet::XSheetAnnotations > aSheet2Annotations (getAnnotations(2), UNO_SET_THROW);
+ table::CellAddress aTargetCellAddress2 (2,4,5);
+ aSheet2Annotations->insertNew(aTargetCellAddress2, "an inserted annotation 1 on sheet 3");
+ table::CellAddress aSecondTargetCellAddress2 (2,5,6);
+ aSheet2Annotations->insertNew(aSecondTargetCellAddress2, "an inserted annotation 2 on sheet 3");
+ table::CellAddress aThirdCellAddress2 (2,7,8);
+ aSheet2Annotations->insertNew(aThirdCellAddress2, "an inserted annotation 3 on sheet 3");
+
+ // get second annotation for second sheet
+ uno::Reference< sheet::XSheetAnnotations > aSheetAnnotations (getAnnotations(2), UNO_SET_THROW);
+ uno::Reference< container::XIndexAccess > xAnnotationsIndex (aSheetAnnotations, UNO_QUERY_THROW);
+ uno::Reference< sheet::XSheetAnnotation > aAnnotation (xAnnotationsIndex->getByIndex(1), UNO_QUERY_THROW);
+
+ table::CellAddress aToBeAnalyzedCellAddress = aAnnotation->getPosition();
+
+ // is the CellAddress ok ?
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(
+ "GetByIndex Annotation - Wrong SHEET reference position",
+ aSecondTargetCellAddress2.Sheet, aToBeAnalyzedCellAddress.Sheet);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(
+ "GetByIndex Annotation - Wrong COLUMN reference position",
+ aSecondTargetCellAddress2.Column, aToBeAnalyzedCellAddress.Column);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(
+ "GetByIndex Annotation - Wrong ROW reference position",
+ aSecondTargetCellAddress2.Row, aToBeAnalyzedCellAddress.Row);
+
+ // is the string ok ?
+ uno::Reference< text::XTextRange > aTextSheetAnnotation(aAnnotation, UNO_QUERY_THROW);
+ OUString aString = aTextSheetAnnotation->getString();
+
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(
+ "GetByIndex Annotation - Wrong string",
+ OUString("an inserted annotation 2 on sheet 3"), aString);
+}
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/test/source/sheet/xsheetannotationshapesupplier.cxx b/test/source/sheet/xsheetannotationshapesupplier.cxx
new file mode 100644
index 0000000000..dac446b72b
--- /dev/null
+++ b/test/source/sheet/xsheetannotationshapesupplier.cxx
@@ -0,0 +1,41 @@
+/* -*- 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 <test/sheet/xsheetannotationshapesupplier.hxx>
+
+#include <com/sun/star/drawing/XShape.hpp>
+#include <com/sun/star/sheet/XSheetAnnotationShapeSupplier.hpp>
+
+#include <cppunit/TestAssert.h>
+
+using namespace com::sun::star;
+using namespace com::sun::star::uno;
+
+
+namespace apitest {
+
+void XSheetAnnotationShapeSupplier::testGetAnnotationShape()
+{
+ uno::Reference< sheet::XSheetAnnotationShapeSupplier > xSheetAnnotationShapeSupplier(init(), UNO_QUERY_THROW);
+ uno::Reference< drawing::XShape > xShape = xSheetAnnotationShapeSupplier->getAnnotationShape();
+
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("getAnnotationShape() wrong X position",
+ sal_Int32(7373), xShape->getPosition().X);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("getAnnotationShape() wrong Y position",
+ sal_Int32(451), xShape->getPosition().Y);
+
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("getAnnotationShape() wrong width",
+ sal_Int32(11275), xShape->getSize().Width);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("getAnnotationShape() wrong height",
+ sal_Int32(1386), xShape->getSize().Height);
+}
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/test/source/sheet/xsheetannotationssupplier.cxx b/test/source/sheet/xsheetannotationssupplier.cxx
new file mode 100644
index 0000000000..aa6f7fd1ca
--- /dev/null
+++ b/test/source/sheet/xsheetannotationssupplier.cxx
@@ -0,0 +1,30 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * 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 <test/sheet/xsheetannotationssupplier.hxx>
+
+#include <com/sun/star/sheet/XSheetAnnotations.hpp>
+#include <com/sun/star/sheet/XSheetAnnotationsSupplier.hpp>
+#include <com/sun/star/uno/Reference.hxx>
+
+using namespace css;
+using namespace css::uno;
+
+namespace apitest
+{
+void XSheetAnnotationsSupplier::testGetAnnotations()
+{
+ uno::Reference<sheet::XSheetAnnotationsSupplier> xSupplier(init(), UNO_QUERY_THROW);
+
+ uno::Reference<sheet::XSheetAnnotations> xAnnotations(xSupplier->getAnnotations(),
+ UNO_SET_THROW);
+}
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/test/source/sheet/xsheetauditing.cxx b/test/source/sheet/xsheetauditing.cxx
new file mode 100644
index 0000000000..992a7441ce
--- /dev/null
+++ b/test/source/sheet/xsheetauditing.cxx
@@ -0,0 +1,137 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * 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 <test/sheet/xsheetauditing.hxx>
+
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/drawing/XDrawPage.hpp>
+#include <com/sun/star/drawing/XDrawPageSupplier.hpp>
+#include <com/sun/star/sheet/XSheetAuditing.hpp>
+#include <com/sun/star/sheet/XSpreadsheet.hpp>
+#include <com/sun/star/sheet/ValidationType.hpp>
+#include <com/sun/star/table/CellAddress.hpp>
+#include <com/sun/star/table/XCell.hpp>
+#include <com/sun/star/text/XText.hpp>
+#include <com/sun/star/uno/Any.hxx>
+#include <com/sun/star/uno/Reference.hxx>
+
+#include <cppunit/TestAssert.h>
+
+using namespace css;
+using namespace css::uno;
+
+namespace apitest
+{
+void XSheetAuditing::testShowHideDependents()
+{
+ uno::Reference<sheet::XSheetAuditing> xAuditing(init(), UNO_QUERY_THROW);
+
+ uno::Reference<drawing::XDrawPageSupplier> xDPS(xAuditing, UNO_QUERY_THROW);
+ uno::Reference<drawing::XDrawPage> xDrawPage = xDPS->getDrawPage();
+ const sal_Int32 nElements = xDrawPage->getCount();
+
+ xAuditing->showDependents(table::CellAddress(0, 8, 6));
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Unable to showDependents()", nElements + 1,
+ xDrawPage->getCount());
+
+ xAuditing->hideDependents(table::CellAddress(0, 8, 6));
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Unable to hideDependents()", nElements, xDrawPage->getCount());
+}
+
+void XSheetAuditing::testShowHidePrecedents()
+{
+ uno::Reference<sheet::XSheetAuditing> xAuditing(init(), UNO_QUERY_THROW);
+
+ uno::Reference<drawing::XDrawPageSupplier> xDPS(xAuditing, UNO_QUERY_THROW);
+ uno::Reference<drawing::XDrawPage> xDrawPage = xDPS->getDrawPage();
+ const sal_Int32 nElements = xDrawPage->getCount();
+
+ xAuditing->showPrecedents(table::CellAddress(0, 8, 6));
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Unable to showPrecedents()", nElements + 2,
+ xDrawPage->getCount());
+
+ xAuditing->hidePrecedents(table::CellAddress(0, 8, 6));
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Unable to showPrecedents()", nElements, xDrawPage->getCount());
+}
+
+void XSheetAuditing::testClearArrows()
+{
+ uno::Reference<sheet::XSheetAuditing> xAuditing(init(), UNO_QUERY_THROW);
+
+ uno::Reference<drawing::XDrawPageSupplier> xDPS(xAuditing, UNO_QUERY_THROW);
+ uno::Reference<drawing::XDrawPage> xDrawPage = xDPS->getDrawPage();
+ const sal_Int32 nElements = xDrawPage->getCount();
+
+ xAuditing->showPrecedents(table::CellAddress(0, 8, 6));
+ xAuditing->showDependents(table::CellAddress(0, 8, 6));
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Unable to set arrows", nElements + 3, xDrawPage->getCount());
+
+ xAuditing->clearArrows();
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Unable to clear arrows", nElements, xDrawPage->getCount());
+}
+
+void XSheetAuditing::testShowErrors()
+{
+ uno::Reference<sheet::XSheetAuditing> xAuditing(init(), UNO_QUERY_THROW);
+
+ uno::Reference<drawing::XDrawPageSupplier> xDPS(xAuditing, UNO_QUERY_THROW);
+ uno::Reference<drawing::XDrawPage> xDrawPage = xDPS->getDrawPage();
+ const sal_Int32 nElements = xDrawPage->getCount();
+
+ uno::Reference<sheet::XSpreadsheet> xSheet(xAuditing, UNO_QUERY_THROW);
+ uno::Reference<table::XCell> xCell = xSheet->getCellByPosition(7, 6);
+ xCell->setValue(-9);
+ xCell->setFormula("=SQRT(" + OUStringChar(static_cast<char>('A' + 7)) + OUString::number(7)
+ + ")");
+
+ uno::Reference<text::XText> xText(xCell, UNO_QUERY_THROW);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("No error code", OUString("Err:522"), xText->getString());
+
+ xAuditing->showErrors(table::CellAddress(0, 7, 6));
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Unable to show errors", nElements + 1, xDrawPage->getCount());
+}
+
+void XSheetAuditing::testShowInvalid()
+{
+ uno::Reference<sheet::XSheetAuditing> xAuditing(init(), UNO_QUERY_THROW);
+
+ uno::Reference<drawing::XDrawPageSupplier> xDPS(xAuditing, UNO_QUERY_THROW);
+ uno::Reference<drawing::XDrawPage> xDrawPage = xDPS->getDrawPage();
+ const sal_Int32 nElements = xDrawPage->getCount();
+
+ uno::Reference<sheet::XSpreadsheet> xSheet(xAuditing, UNO_QUERY_THROW);
+ uno::Reference<table::XCell> xCell = xSheet->getCellByPosition(7, 6);
+ xCell->setValue(2.5);
+
+ uno::Reference<beans::XPropertySet> xPropSet(xCell, UNO_QUERY_THROW);
+ uno::Any aValidation = xPropSet->getPropertyValue("Validation");
+ uno::Reference<beans::XPropertySet> xValidation(aValidation, UNO_QUERY_THROW);
+ uno::Any aAny;
+
+ aAny <<= sheet::ValidationType_WHOLE;
+ xValidation->setPropertyValue("Type", aAny);
+ aAny <<= xValidation;
+ xPropSet->setPropertyValue("Validation", aAny);
+ xAuditing->showInvalid();
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Unable to show invalid (WHOLE)", nElements + 1,
+ xDrawPage->getCount());
+
+ xAuditing->clearArrows();
+
+ aAny <<= sheet::ValidationType_ANY;
+ xValidation->setPropertyValue("Type", aAny);
+ aAny <<= xValidation;
+ xPropSet->setPropertyValue("Validation", aAny);
+
+ xAuditing->showInvalid();
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Unable to show invalid (ANY)", nElements, xDrawPage->getCount());
+}
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/test/source/sheet/xsheetcellcursor.cxx b/test/source/sheet/xsheetcellcursor.cxx
new file mode 100644
index 0000000000..fcaeb7fe7e
--- /dev/null
+++ b/test/source/sheet/xsheetcellcursor.cxx
@@ -0,0 +1,138 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * 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 <test/sheet/xsheetcellcursor.hxx>
+
+#include <com/sun/star/sheet/XArrayFormulaRange.hpp>
+#include <com/sun/star/sheet/XCellRangeAddressable.hpp>
+#include <com/sun/star/sheet/XSheetCellCursor.hpp>
+#include <com/sun/star/sheet/XSheetOperation.hpp>
+#include <com/sun/star/sheet/XSpreadsheet.hpp>
+#include <com/sun/star/table/CellRangeAddress.hpp>
+#include <com/sun/star/table/XCellRange.hpp>
+#include <com/sun/star/table/XColumnRowRange.hpp>
+#include <com/sun/star/util/XMergeable.hpp>
+
+#include <com/sun/star/uno/Reference.hxx>
+
+#include <cppunit/TestAssert.h>
+
+using namespace com::sun::star;
+using namespace com::sun::star::uno;
+
+namespace apitest
+{
+void XSheetCellCursor::testCollapseToCurrentArray()
+{
+ uno::Reference<sheet::XSheetCellCursor> xSheetCellCursor(init(), UNO_QUERY_THROW);
+
+ uno::Reference<sheet::XCellRangeAddressable> xCellRangeAddressable(xSheetCellCursor,
+ UNO_QUERY_THROW);
+ table::CellRangeAddress aCellRangeAddr = xCellRangeAddressable->getRangeAddress();
+ const sal_Int32 nHeight = aCellRangeAddr.EndRow - aCellRangeAddr.StartRow + 1;
+
+ uno::Reference<table::XCellRange> xCellRange
+ = xSheetCellCursor->getCellRangeByPosition(0, 0, 0, nHeight - 1);
+ uno::Reference<sheet::XArrayFormulaRange> xArrayFormulaRange(xCellRange, UNO_QUERY_THROW);
+ xArrayFormulaRange->setArrayFormula("A1:A" + OUString::number(nHeight));
+
+ xSheetCellCursor->collapseToSize(1, 1);
+ xSheetCellCursor->collapseToCurrentArray();
+
+ uno::Reference<table::XColumnRowRange> xColRowRange(xSheetCellCursor, UNO_QUERY_THROW);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Unable to collapseToCurrentArray (cols)", sal_Int32(1),
+ xColRowRange->getColumns()->getCount());
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Unable to collapseToCurrentArray (rows)", nHeight,
+ xColRowRange->getRows()->getCount());
+ xArrayFormulaRange->setArrayFormula("");
+}
+
+void XSheetCellCursor::testCollapseToCurrentRegion()
+{
+ uno::Reference<sheet::XSheetCellCursor> xSheetCellCursor(init(), UNO_QUERY_THROW);
+
+ const sal_Int32 nWidth = 4, nHeight = 4;
+ uno::Reference<sheet::XSpreadsheet> xSheet = xSheetCellCursor->getSpreadsheet();
+ uno::Reference<sheet::XSheetOperation> xSheetOp(xSheet, UNO_QUERY_THROW);
+ xSheetOp->clearContents(65535);
+
+ xSheetCellCursor->collapseToCurrentRegion();
+ uno::Reference<table::XColumnRowRange> xColRowRange(xSheetCellCursor, UNO_QUERY_THROW);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Unable to collapseToCurrentRegion (cols)", nWidth,
+ xColRowRange->getColumns()->getCount());
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Unable to collapseToCurrentRegion (rows)", nHeight,
+ xColRowRange->getRows()->getCount());
+}
+
+void XSheetCellCursor::testCollapseToMergedArea()
+{
+ uno::Reference<sheet::XSheetCellCursor> xSheetCellCursor(init(), UNO_QUERY_THROW);
+ xSheetCellCursor->collapseToSize(1, 1);
+
+ const sal_Int32 nLeftCol = 0, nTopRow = 0, nWidth = 8, nHeight = 8;
+ uno::Reference<sheet::XSpreadsheet> xSheet = xSheetCellCursor->getSpreadsheet();
+
+ uno::Reference<table::XCellRange> xCellRange = xSheet->getCellRangeByPosition(
+ nLeftCol + nWidth - 8, nTopRow + nHeight - 8, nLeftCol + nWidth, nTopRow + nHeight);
+
+ uno::Reference<util::XMergeable> xMergeable(xCellRange, UNO_QUERY_THROW);
+ xMergeable->merge(true);
+ CPPUNIT_ASSERT_MESSAGE("Unable to merge area", xMergeable->getIsMerged());
+ xSheetCellCursor->collapseToMergedArea();
+ xMergeable->merge(false);
+
+ uno::Reference<table::XColumnRowRange> xColRowRange(xSheetCellCursor, UNO_QUERY_THROW);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Unable to collapseToMergedArea (cols)", nWidth + 1,
+ xColRowRange->getColumns()->getCount());
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Unable to collapseToMergedArea (rows)", nHeight + 1,
+ xColRowRange->getRows()->getCount());
+}
+
+void XSheetCellCursor::testCollapseToSize()
+{
+ uno::Reference<sheet::XSheetCellCursor> xSheetCellCursor(init(), UNO_QUERY_THROW);
+
+ const sal_Int32 nWidth = 1, nHeight = 1;
+ xSheetCellCursor->collapseToSize(nWidth + 3, nHeight + 3);
+
+ uno::Reference<table::XColumnRowRange> xColRowRange(xSheetCellCursor, UNO_QUERY_THROW);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Unable to collapseToSize (cols)", nWidth + 3,
+ xColRowRange->getColumns()->getCount());
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Unable to collapseToSize (rows)", nHeight + 3,
+ xColRowRange->getRows()->getCount());
+}
+
+void XSheetCellCursor::testExpandToEntireColumns()
+{
+ uno::Reference<sheet::XSheetCellCursor> xSheetCellCursor(init(), UNO_QUERY_THROW);
+
+ xSheetCellCursor->expandToEntireColumns();
+
+ uno::Reference<table::XColumnRowRange> xColRowRange(xSheetCellCursor, UNO_QUERY_THROW);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Unable to expandToEntireColumns (cols)", sal_Int32(4),
+ xColRowRange->getColumns()->getCount());
+ CPPUNIT_ASSERT_MESSAGE("Unable to expandToEntireColumns (rows)",
+ xColRowRange->getRows()->getCount() >= sal_Int32(32000));
+}
+
+void XSheetCellCursor::testExpandToEntireRows()
+{
+ uno::Reference<sheet::XSheetCellCursor> xSheetCellCursor(init(), UNO_QUERY_THROW);
+
+ xSheetCellCursor->expandToEntireRows();
+
+ uno::Reference<table::XColumnRowRange> xColRowRange(xSheetCellCursor, UNO_QUERY_THROW);
+ CPPUNIT_ASSERT_MESSAGE("Unable to expandToEntireRows (cols)",
+ xColRowRange->getColumns()->getCount() >= sal_Int32(256));
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Unable to expandToEntireRows (rows)", sal_Int32(4),
+ xColRowRange->getRows()->getCount());
+}
+}
+
+/* vim:set shiftnWidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/test/source/sheet/xsheetcellrange.cxx b/test/source/sheet/xsheetcellrange.cxx
new file mode 100644
index 0000000000..a5714e3245
--- /dev/null
+++ b/test/source/sheet/xsheetcellrange.cxx
@@ -0,0 +1,33 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * 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 <test/sheet/xsheetcellrange.hxx>
+
+#include <com/sun/star/sheet/XSheetCellRange.hpp>
+#include <com/sun/star/sheet/XSpreadsheet.hpp>
+
+#include <com/sun/star/uno/Reference.hxx>
+
+#include <cppunit/TestAssert.h>
+
+using namespace com::sun::star;
+using namespace com::sun::star::uno;
+
+namespace apitest
+{
+void XSheetCellRange::testGetSpreadsheet()
+{
+ uno::Reference<sheet::XSheetCellRange> xSheetCellRange(init(), UNO_QUERY_THROW);
+ uno::Reference<sheet::XSpreadsheet> xSheet = xSheetCellRange->getSpreadsheet();
+
+ CPPUNIT_ASSERT_MESSAGE("Unable to get spreadsheet", xSheet.is());
+}
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/test/source/sheet/xsheetcellrangecontainer.cxx b/test/source/sheet/xsheetcellrangecontainer.cxx
new file mode 100644
index 0000000000..af5d02d70a
--- /dev/null
+++ b/test/source/sheet/xsheetcellrangecontainer.cxx
@@ -0,0 +1,101 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * 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 <test/sheet/xsheetcellrangecontainer.hxx>
+#include <test/cppunitasserthelper.hxx>
+
+#include <com/sun/star/sheet/XSheetCellRangeContainer.hpp>
+
+#include <com/sun/star/uno/Reference.hxx>
+#include <com/sun/star/uno/Sequence.hxx>
+
+#include <cppunit/TestAssert.h>
+
+using namespace com::sun::star;
+using namespace com::sun::star::uno;
+
+namespace apitest
+{
+void XSheetCellRangeContainer::testAddRemoveRangeAddress()
+{
+ uno::Reference<sheet::XSheetCellRangeContainer> xSCRC(init(), UNO_QUERY_THROW);
+ xSCRC->removeRangeAddresses(xSCRC->getRangeAddresses()); // prepare a clean slate
+ uno::Sequence<table::CellRangeAddress> aAddr = createCellRangeAddresses();
+
+ sal_Int32 cnt = xSCRC->getCount();
+ xSCRC->addRangeAddress(aAddr[0], false);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Unable to add CellRangeAddress (count)", cnt + 1,
+ xSCRC->getCount());
+
+ uno::Sequence<table::CellRangeAddress> aAfterAddAddr = xSCRC->getRangeAddresses();
+ cnt = xSCRC->getCount();
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Unable to add CellRangeAddress (entry)", aAddr[0],
+ aAfterAddAddr[cnt - 1]);
+
+ xSCRC->removeRangeAddress(aAddr[0]);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Unable to remove CellRangeAddress (count)", cnt - 1,
+ xSCRC->getCount());
+
+ const uno::Sequence<table::CellRangeAddress> aAfterRemoveAddr = xSCRC->getRangeAddresses();
+ for (auto const& addr : aAfterRemoveAddr)
+ {
+ CPPUNIT_ASSERT_MESSAGE("Unable to remove CellRangeAddress (entry)", aAddr[0] != addr);
+ }
+}
+
+void XSheetCellRangeContainer::testAddRemoveRangeAddresses()
+{
+ uno::Reference<sheet::XSheetCellRangeContainer> xSCRC(init(), UNO_QUERY_THROW);
+ xSCRC->removeRangeAddresses(xSCRC->getRangeAddresses()); // prepare a clean slate
+ uno::Sequence<table::CellRangeAddress> aAddr = createCellRangeAddresses();
+
+ sal_Int32 cnt = xSCRC->getCount();
+ xSCRC->addRangeAddresses(aAddr, false);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Unable to add CellRangeAddress (count)", cnt + 2,
+ xSCRC->getCount());
+
+ uno::Sequence<table::CellRangeAddress> aAfterAddAddr = xSCRC->getRangeAddresses();
+ cnt = xSCRC->getCount();
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Unable to add CellRangeAddresses (entry: first)", aAddr[0],
+ aAfterAddAddr[cnt - 2]);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Unable to add CellRangeAddresses (entry: second)", aAddr[1],
+ aAfterAddAddr[cnt - 1]);
+
+ xSCRC->removeRangeAddresses(aAddr);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Unable to remove CellRangeAddresses (count)", cnt - 2,
+ xSCRC->getCount());
+
+ const uno::Sequence<table::CellRangeAddress> aAfterRemoveAddr = xSCRC->getRangeAddresses();
+ for (auto const& addr : aAfterRemoveAddr)
+ {
+ CPPUNIT_ASSERT_MESSAGE("Unable to remove CellRangeAddresses (entry: first)",
+ aAddr[0] != addr);
+ CPPUNIT_ASSERT_MESSAGE("Unable to remove CellRangeAddresses (entry: second)",
+ aAddr[1] != addr);
+ }
+}
+
+uno::Sequence<table::CellRangeAddress> XSheetCellRangeContainer::createCellRangeAddresses()
+{
+ uno::Sequence<table::CellRangeAddress> aAddr(2);
+ auto pAddr = aAddr.getArray();
+ for (unsigned int i = 0; i < 2; i++)
+ {
+ pAddr[i].Sheet = i;
+ pAddr[i].StartColumn = i;
+ pAddr[i].StartRow = i;
+ pAddr[i].EndColumn = i + 3;
+ pAddr[i].EndRow = i + 3;
+ }
+
+ return aAddr;
+}
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/test/source/sheet/xsheetcellranges.cxx b/test/source/sheet/xsheetcellranges.cxx
new file mode 100644
index 0000000000..d40a47e032
--- /dev/null
+++ b/test/source/sheet/xsheetcellranges.cxx
@@ -0,0 +1,50 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * 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 <test/sheet/xsheetcellranges.hxx>
+
+#include <com/sun/star/container/XEnumerationAccess.hpp>
+#include <com/sun/star/sheet/XSheetCellRanges.hpp>
+#include <com/sun/star/table/CellRangeAddress.hpp>
+
+#include <com/sun/star/uno/Reference.hxx>
+#include <com/sun/star/uno/Sequence.hxx>
+
+#include <cppunit/TestAssert.h>
+
+using namespace com::sun::star;
+using namespace com::sun::star::uno;
+
+namespace apitest
+{
+void XSheetCellRanges::testGetCells()
+{
+ uno::Reference<sheet::XSheetCellRanges> xSheetCellRanges(init(), UNO_QUERY_THROW);
+ uno::Reference<container::XEnumerationAccess> xEA = xSheetCellRanges->getCells();
+
+ CPPUNIT_ASSERT_MESSAGE("Unable to get cells", xEA->hasElements());
+}
+
+void XSheetCellRanges::testGetRangeAddresses()
+{
+ uno::Reference<sheet::XSheetCellRanges> xSheetCellRanges(init(), UNO_QUERY_THROW);
+ uno::Sequence<table::CellRangeAddress> aCellRangeAddress
+ = xSheetCellRanges->getRangeAddresses();
+ CPPUNIT_ASSERT_MESSAGE("Unable to get RangeAddresses", aCellRangeAddress.getLength() > 2);
+}
+
+void XSheetCellRanges::testGetRangeAddressesAsString()
+{
+ uno::Reference<sheet::XSheetCellRanges> xSheetCellRanges(init(), UNO_QUERY_THROW);
+ CPPUNIT_ASSERT_MESSAGE("Unable to get RangeAddresses (string)",
+ xSheetCellRanges->getRangeAddressesAsString().indexOf("C1:D4") > 0);
+}
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/test/source/sheet/xsheetcondition.cxx b/test/source/sheet/xsheetcondition.cxx
new file mode 100644
index 0000000000..27068fec62
--- /dev/null
+++ b/test/source/sheet/xsheetcondition.cxx
@@ -0,0 +1,72 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * 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 <test/sheet/xsheetcondition.hxx>
+
+#include <com/sun/star/sheet/ConditionOperator.hpp>
+#include <com/sun/star/sheet/XSheetCondition.hpp>
+
+#include <com/sun/star/uno/Reference.hxx>
+
+#include <cppunit/TestAssert.h>
+
+using namespace com::sun::star;
+using namespace com::sun::star::uno;
+
+namespace apitest
+{
+void XSheetCondition::testGetSetFormula1()
+{
+ uno::Reference<sheet::XSheetCondition> xSheetCondition(init(), UNO_QUERY_THROW);
+ OUString aFormula1;
+ CPPUNIT_ASSERT_NO_THROW_MESSAGE("Unable to get Formula1",
+ aFormula1 = xSheetCondition->getFormula1());
+
+ xSheetCondition->setFormula1("$Sheet1.$C$");
+ CPPUNIT_ASSERT_MESSAGE("Unable to set Formula1", aFormula1 != xSheetCondition->getFormula1());
+}
+
+void XSheetCondition::testGetSetFormula2()
+{
+ uno::Reference<sheet::XSheetCondition> xSheetCondition(init(), UNO_QUERY_THROW);
+ OUString aFormula2;
+ CPPUNIT_ASSERT_NO_THROW_MESSAGE("Unable to get Formula2",
+ aFormula2 = xSheetCondition->getFormula2());
+
+ xSheetCondition->setFormula2("$Sheet1.$A$");
+ CPPUNIT_ASSERT_MESSAGE("Unable to set Formula2", aFormula2 != xSheetCondition->getFormula2());
+}
+
+void XSheetCondition::testGetSetOperator()
+{
+ uno::Reference<sheet::XSheetCondition> xSheetCondition(init(), UNO_QUERY_THROW);
+ sheet::ConditionOperator aOperator;
+ CPPUNIT_ASSERT_NO_THROW_MESSAGE("Unable to get Operator",
+ aOperator = xSheetCondition->getOperator());
+
+ xSheetCondition->setOperator(sheet::ConditionOperator_BETWEEN);
+ sheet::ConditionOperator aOperatorNew = xSheetCondition->getOperator();
+ CPPUNIT_ASSERT_MESSAGE("Unable to set Operator", aOperator != aOperatorNew);
+}
+
+void XSheetCondition::testGetSetSourcePosition()
+{
+ uno::Reference<sheet::XSheetCondition> xSheetCondition(init(), UNO_QUERY_THROW);
+ table::CellAddress aSourcePosition(0, 0, 0);
+ CPPUNIT_ASSERT_NO_THROW_MESSAGE("Unable to get SourcePosition",
+ aSourcePosition = xSheetCondition->getSourcePosition());
+
+ xSheetCondition->setSourcePosition(table::CellAddress(0, 1, 1));
+ table::CellAddress aSourcePositionNew = xSheetCondition->getSourcePosition();
+ CPPUNIT_ASSERT_MESSAGE("Unable to set SourcePosition",
+ aSourcePosition.Row != aSourcePositionNew.Row);
+}
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/test/source/sheet/xsheetconditionalentries.cxx b/test/source/sheet/xsheetconditionalentries.cxx
new file mode 100644
index 0000000000..8062d42f5f
--- /dev/null
+++ b/test/source/sheet/xsheetconditionalentries.cxx
@@ -0,0 +1,57 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * 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 <test/sheet/xsheetconditionalentries.hxx>
+
+#include <com/sun/star/sheet/XSheetConditionalEntries.hpp>
+
+#include <com/sun/star/uno/Reference.hxx>
+
+#include <cppunit/TestAssert.h>
+
+using namespace com::sun::star;
+using namespace com::sun::star::uno;
+
+namespace apitest
+{
+void XSheetConditionalEntries::testAddNew()
+{
+ uno::Reference<sheet::XSheetConditionalEntries> xSheetConditionalEntries(init(),
+ UNO_QUERY_THROW);
+ const sal_Int32 aCount = xSheetConditionalEntries->getCount();
+
+ xSheetConditionalEntries->addNew(createCondition(4));
+
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Unable to add new condition", aCount + 1,
+ xSheetConditionalEntries->getCount());
+}
+
+void XSheetConditionalEntries::testClear()
+{
+ uno::Reference<sheet::XSheetConditionalEntries> xSheetConditionalEntries(init(),
+ UNO_QUERY_THROW);
+ xSheetConditionalEntries->clear();
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Unable to clear conditions", sal_Int32(0),
+ xSheetConditionalEntries->getCount());
+}
+
+void XSheetConditionalEntries::testRemoveByIndex()
+{
+ uno::Reference<sheet::XSheetConditionalEntries> xSheetConditionalEntries(init(),
+ UNO_QUERY_THROW);
+ const sal_Int32 aCount = xSheetConditionalEntries->getCount();
+
+ xSheetConditionalEntries->removeByIndex(0);
+
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Unable to remove condition", aCount - 1,
+ xSheetConditionalEntries->getCount());
+}
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/test/source/sheet/xsheetconditionalentry.cxx b/test/source/sheet/xsheetconditionalentry.cxx
new file mode 100644
index 0000000000..0523d9be69
--- /dev/null
+++ b/test/source/sheet/xsheetconditionalentry.cxx
@@ -0,0 +1,35 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * 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 <test/sheet/xsheetconditionalentry.hxx>
+
+#include <com/sun/star/sheet/XSheetConditionalEntry.hpp>
+
+#include <com/sun/star/uno/Reference.hxx>
+
+#include <cppunit/TestAssert.h>
+
+using namespace com::sun::star;
+using namespace com::sun::star::uno;
+
+namespace apitest
+{
+void XSheetConditionalEntry::testGetSetStyleName()
+{
+ uno::Reference<sheet::XSheetConditionalEntry> xSheetConditionalEntry(init(), UNO_QUERY_THROW);
+ OUString aStyleName = xSheetConditionalEntry->getStyleName();
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Unable to get StyleName", OUString("Result2"), aStyleName);
+
+ xSheetConditionalEntry->setStyleName("Heading");
+ CPPUNIT_ASSERT_MESSAGE("Unable to set StyleName",
+ aStyleName != xSheetConditionalEntry->getStyleName());
+}
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/test/source/sheet/xsheetfilterable.cxx b/test/source/sheet/xsheetfilterable.cxx
new file mode 100644
index 0000000000..2f5509e95f
--- /dev/null
+++ b/test/source/sheet/xsheetfilterable.cxx
@@ -0,0 +1,95 @@
+/* -*- 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 <test/sheet/xsheetfilterable.hxx>
+
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/sheet/FilterOperator.hpp>
+#include <com/sun/star/sheet/TableFilterField.hpp>
+#include <com/sun/star/sheet/XSheetFilterable.hpp>
+#include <com/sun/star/sheet/XSheetFilterDescriptor.hpp>
+#include <com/sun/star/sheet/XSpreadsheet.hpp>
+#include <com/sun/star/table/XColumnRowRange.hpp>
+#include <com/sun/star/table/XTableRows.hpp>
+#include <com/sun/star/uno/Reference.hxx>
+#include <com/sun/star/uno/Sequence.hxx>
+
+#include <cppunit/TestAssert.h>
+
+using namespace css;
+using namespace css::uno;
+
+namespace apitest {
+
+void XSheetFilterable::testCreateFilterDescriptor()
+{
+ uno::Reference< sheet::XSheetFilterable > xFA(init(), UNO_QUERY_THROW);
+ uno::Reference< sheet::XSheetFilterDescriptor > xSFD = xFA->createFilterDescriptor(true);
+
+ uno::Sequence< sheet::TableFilterField > xTFF{
+ { /* Connection */ {},
+ /* Field */ 0,
+ /* Operator */ sheet::FilterOperator_GREATER_EQUAL,
+ /* IsNumeric */ true,
+ /* NumericValue */ 2,
+ /* StringValue */ {}},
+ { /* Connection */ {},
+ /* Field */ 1,
+ /* Operator */ sheet::FilterOperator_LESS,
+ /* IsNumeric */ false,
+ /* NumericValue */ {},
+ /* StringValue */ "C" }
+ };
+
+ CPPUNIT_ASSERT_NO_THROW_MESSAGE("Unable to create XSheetFilterDescriptor", xSFD->setFilterFields(xTFF));
+}
+
+void XSheetFilterable::testFilter()
+{
+ uno::Reference< sheet::XSpreadsheet > xSheet(getXSpreadsheet(), UNO_QUERY_THROW);
+
+ uno::Reference< sheet::XSheetFilterable > xFA(xSheet, UNO_QUERY_THROW);
+ uno::Reference< sheet::XSheetFilterDescriptor > xSFD = xFA->createFilterDescriptor(true);
+
+ uno::Sequence< sheet::TableFilterField > xTFF{
+ { /* Connection */ {},
+ /* Field */ 0,
+ /* Operator */ sheet::FilterOperator_GREATER_EQUAL,
+ /* IsNumeric */ true,
+ /* NumericValue */ 2,
+ /* StringValue */ {}},
+ { /* Connection */ {},
+ /* Field */ 1,
+ /* Operator */ sheet::FilterOperator_LESS,
+ /* IsNumeric */ false,
+ /* NumericValue */ {},
+ /* StringValue */ "C" }
+ };
+ xSFD->setFilterFields(xTFF);
+
+ xSheet->getCellByPosition(0, 0)->setValue(1);
+ xSheet->getCellByPosition(0, 1)->setValue(2);
+ xSheet->getCellByPosition(0, 2)->setValue(3);
+ xSheet->getCellByPosition(1, 0)->setFormula("A");
+ xSheet->getCellByPosition(1, 1)->setFormula("B");
+ xSheet->getCellByPosition(1, 2)->setFormula("C");
+ xFA->filter(xSFD);
+
+ uno::Reference< table::XColumnRowRange > xColRowRange(xSheet, UNO_QUERY_THROW);
+ uno::Reference< table::XTableRows > xTableRows = xColRowRange->getRows();
+ uno::Reference< beans::XPropertySet > xRowProps(xTableRows->getByIndex(0), UNO_QUERY_THROW);
+ bool bIsVisible = true;
+ CPPUNIT_ASSERT(xRowProps->getPropertyValue("IsVisible") >>= bIsVisible);
+
+ CPPUNIT_ASSERT_MESSAGE("Row 1 should be invisible", !bIsVisible);
+}
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/test/source/sheet/xsheetfilterableex.cxx b/test/source/sheet/xsheetfilterableex.cxx
new file mode 100644
index 0000000000..eeecf737da
--- /dev/null
+++ b/test/source/sheet/xsheetfilterableex.cxx
@@ -0,0 +1,59 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * 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 <test/sheet/xsheetfilterableex.hxx>
+
+#include <com/sun/star/sheet/FilterConnection.hpp>
+#include <com/sun/star/sheet/FilterOperator.hpp>
+#include <com/sun/star/sheet/TableFilterField.hpp>
+#include <com/sun/star/sheet/XSheetFilterDescriptor.hpp>
+#include <com/sun/star/sheet/XSheetFilterable.hpp>
+#include <com/sun/star/sheet/XSheetFilterableEx.hpp>
+#include <com/sun/star/uno/Reference.hxx>
+#include <com/sun/star/uno/Sequence.hxx>
+
+#include <cppunit/TestAssert.h>
+
+using namespace css;
+using namespace css::uno;
+
+namespace apitest
+{
+void XSheetFilterableEx::testCreateFilterDescriptorByObject()
+{
+ uno::Reference<sheet::XSheetFilterableEx> xSFEx(init(), UNO_QUERY_THROW);
+ uno::Reference<sheet::XSheetFilterable> xSF(getXSpreadsheet(), UNO_QUERY_THROW);
+
+ uno::Reference<sheet::XSheetFilterDescriptor> xSFD = xSFEx->createFilterDescriptorByObject(xSF);
+ CPPUNIT_ASSERT_MESSAGE("no XSheetFilterDescriptor", xSFD.is());
+
+ const uno::Sequence<sheet::TableFilterField> xTFF = xSFD->getFilterFields();
+ CPPUNIT_ASSERT_MESSAGE("The gained XSheetFilterDescriptor is empty", xTFF.hasElements());
+
+ for (const auto& field : xTFF)
+ {
+ // we don't care about the actual value, just that we can access the fields
+ CPPUNIT_ASSERT_MESSAGE("Unable to retrieve field: StringValue",
+ !field.StringValue.isEmpty() || field.StringValue.isEmpty());
+ CPPUNIT_ASSERT_MESSAGE("Unable to retrieve field: IsNumeric",
+ !field.IsNumeric || field.IsNumeric);
+ CPPUNIT_ASSERT_MESSAGE("Unable to retrieve field: NumericValue",
+ field.NumericValue != 0.0 || field.NumericValue == 0.0);
+ CPPUNIT_ASSERT_MESSAGE("Unable to retrieve field: Field",
+ field.Field != 0 || field.Field == 0);
+ CPPUNIT_ASSERT_MESSAGE("Unable to retrieve field: Connection",
+ field.Connection == sheet::FilterConnection_AND
+ || field.Connection == sheet::FilterConnection_OR);
+ CPPUNIT_ASSERT_MESSAGE("Unable to retrieve field: Operator",
+ field.Operator != sheet::FilterOperator_EMPTY);
+ }
+}
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/test/source/sheet/xsheetfilterdescriptor.cxx b/test/source/sheet/xsheetfilterdescriptor.cxx
new file mode 100644
index 0000000000..503cc84f8f
--- /dev/null
+++ b/test/source/sheet/xsheetfilterdescriptor.cxx
@@ -0,0 +1,42 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * 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 <test/sheet/xsheetfilterdescriptor.hxx>
+
+#include <com/sun/star/sheet/TableFilterField.hpp>
+#include <com/sun/star/sheet/XSheetFilterDescriptor.hpp>
+
+#include <com/sun/star/uno/Reference.hxx>
+#include <com/sun/star/uno/Sequence.hxx>
+
+#include <cppunit/TestAssert.h>
+
+using namespace css;
+using namespace css::uno;
+
+namespace apitest
+{
+void XSheetFilterDescriptor::testGetSetFilterFields()
+{
+ uno::Reference<sheet::XSheetFilterDescriptor> xSFD(init(), uno::UNO_QUERY_THROW);
+ uno::Sequence<sheet::TableFilterField> aDefaultTFF = xSFD->getFilterFields();
+
+ CPPUNIT_ASSERT_MESSAGE("Unable to get TableFilterField", !aDefaultTFF.hasElements());
+
+ uno::Sequence<sheet::TableFilterField> aTFF;
+ aTFF.realloc(1);
+
+ xSFD->setFilterFields(aTFF);
+ uno::Sequence<sheet::TableFilterField> aNewTFF = xSFD->getFilterFields();
+ CPPUNIT_ASSERT_MESSAGE("Unable to set TableFilterField", aNewTFF != aDefaultTFF);
+}
+
+} // namespace apitest
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/test/source/sheet/xsheetfilterdescriptor2.cxx b/test/source/sheet/xsheetfilterdescriptor2.cxx
new file mode 100644
index 0000000000..fc060f73cb
--- /dev/null
+++ b/test/source/sheet/xsheetfilterdescriptor2.cxx
@@ -0,0 +1,42 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * 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 <test/sheet/xsheetfilterdescriptor2.hxx>
+
+#include <com/sun/star/sheet/TableFilterField2.hpp>
+#include <com/sun/star/sheet/XSheetFilterDescriptor2.hpp>
+
+#include <com/sun/star/uno/Reference.hxx>
+#include <com/sun/star/uno/Sequence.hxx>
+
+#include <cppunit/TestAssert.h>
+
+using namespace css;
+using namespace css::uno;
+
+namespace apitest
+{
+void XSheetFilterDescriptor2::testGetSetFilterFields2()
+{
+ uno::Reference<sheet::XSheetFilterDescriptor2> xSFD(init(), uno::UNO_QUERY_THROW);
+ uno::Sequence<sheet::TableFilterField2> aDefaultTFF = xSFD->getFilterFields2();
+
+ CPPUNIT_ASSERT_MESSAGE("Unable to get TableFilterField", !aDefaultTFF.hasElements());
+
+ uno::Sequence<sheet::TableFilterField2> aTFF;
+ aTFF.realloc(1);
+
+ xSFD->setFilterFields2(aTFF);
+ uno::Sequence<sheet::TableFilterField2> aNewTFF = xSFD->getFilterFields2();
+ CPPUNIT_ASSERT_MESSAGE("Unable to set TableFilterField", aNewTFF != aDefaultTFF);
+}
+
+} // namespace apitest
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/test/source/sheet/xsheetfilterdescriptor3.cxx b/test/source/sheet/xsheetfilterdescriptor3.cxx
new file mode 100644
index 0000000000..e46a345520
--- /dev/null
+++ b/test/source/sheet/xsheetfilterdescriptor3.cxx
@@ -0,0 +1,42 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * 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 <test/sheet/xsheetfilterdescriptor3.hxx>
+
+#include <com/sun/star/sheet/TableFilterField3.hpp>
+#include <com/sun/star/sheet/XSheetFilterDescriptor3.hpp>
+
+#include <com/sun/star/uno/Reference.hxx>
+#include <com/sun/star/uno/Sequence.hxx>
+
+#include <cppunit/TestAssert.h>
+
+using namespace css;
+using namespace css::uno;
+
+namespace apitest
+{
+void XSheetFilterDescriptor3::testGetSetFilterFields3()
+{
+ uno::Reference<sheet::XSheetFilterDescriptor3> xSFD(init(), uno::UNO_QUERY_THROW);
+ uno::Sequence<sheet::TableFilterField3> aDefaultTFF = xSFD->getFilterFields3();
+
+ CPPUNIT_ASSERT_MESSAGE("Unable to get TableFilterField", !aDefaultTFF.hasElements());
+
+ uno::Sequence<sheet::TableFilterField3> aTFF;
+ aTFF.realloc(1);
+
+ xSFD->setFilterFields3(aTFF);
+ uno::Sequence<sheet::TableFilterField3> aNewTFF = xSFD->getFilterFields3();
+ CPPUNIT_ASSERT_MESSAGE("Unable to set TableFilterField", aNewTFF != aDefaultTFF);
+}
+
+} // namespace apitest
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/test/source/sheet/xsheetlinkable.cxx b/test/source/sheet/xsheetlinkable.cxx
new file mode 100644
index 0000000000..aa394a0064
--- /dev/null
+++ b/test/source/sheet/xsheetlinkable.cxx
@@ -0,0 +1,50 @@
+/* -*- 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 <test/sheet/xsheetlinkable.hxx>
+
+#include <com/sun/star/sheet/SheetLinkMode.hpp>
+#include <com/sun/star/sheet/XSheetLinkable.hpp>
+#include <com/sun/star/uno/Reference.hxx>
+
+#include <cppunit/TestAssert.h>
+
+using namespace css;
+using namespace css::uno;
+
+namespace apitest {
+
+void XSheetLinkable::testSheetLinkable()
+{
+ uno::Reference< sheet::XSheetLinkable > xSheetLinkable(init(), UNO_QUERY_THROW);
+
+ xSheetLinkable->link(getFileURL(), "Sheet1", "", "", sheet::SheetLinkMode_VALUE);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Unable to get link mode",
+ sheet::SheetLinkMode_VALUE, xSheetLinkable->getLinkMode());
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Unable to get link URL",
+ getFileURL(), xSheetLinkable->getLinkUrl());
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Unable to get sheet name",
+ OUString("Sheet1"), xSheetLinkable->getLinkSheetName());
+
+ xSheetLinkable->setLinkMode(sheet::SheetLinkMode_NONE);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Unable to set link mode",
+ sheet::SheetLinkMode_NONE, xSheetLinkable->getLinkMode());
+
+ xSheetLinkable->setLinkSheetName("Sheet2");
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Unable to set sheet name",
+ OUString("Sheet2"), xSheetLinkable->getLinkSheetName());
+
+ xSheetLinkable->setLinkUrl(getFileURL());
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Unable to set link URL",
+ getFileURL(), xSheetLinkable->getLinkUrl());
+}
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/test/source/sheet/xsheetoperation.cxx b/test/source/sheet/xsheetoperation.cxx
new file mode 100644
index 0000000000..6f8496482e
--- /dev/null
+++ b/test/source/sheet/xsheetoperation.cxx
@@ -0,0 +1,43 @@
+/* -*- 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 <test/sheet/xsheetoperation.hxx>
+
+#include <com/sun/star/sheet/CellFlags.hpp>
+#include <com/sun/star/sheet/GeneralFunction.hpp>
+#include <com/sun/star/sheet/XSheetOperation.hpp>
+#include <com/sun/star/uno/Reference.hxx>
+
+#include <cppunit/TestAssert.h>
+
+using namespace css;
+using namespace css::uno;
+
+namespace apitest
+{
+void XSheetOperation::testClearContents()
+{
+ uno::Reference<sheet::XSheetOperation> xSheetOperation(init(), UNO_QUERY_THROW);
+
+ xSheetOperation->clearContents(sheet::CellFlags::VALUE | sheet::CellFlags::FORMULA);
+
+ double sum = xSheetOperation->computeFunction(sheet::GeneralFunction_SUM);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Unable to clean contents", 0.0, sum);
+}
+
+void XSheetOperation::testComputeFunction()
+{
+ uno::Reference<sheet::XSheetOperation> xSheetOperation(init(), UNO_QUERY_THROW);
+
+ double count = xSheetOperation->computeFunction(sheet::GeneralFunction_COUNT);
+ CPPUNIT_ASSERT_MESSAGE("Unable to compute function", count >= 0.0);
+}
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/test/source/sheet/xsheetoutline.cxx b/test/source/sheet/xsheetoutline.cxx
new file mode 100644
index 0000000000..ff3e519d30
--- /dev/null
+++ b/test/source/sheet/xsheetoutline.cxx
@@ -0,0 +1,264 @@
+/* -*- 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 <test/sheet/xsheetoutline.hxx>
+
+#include <com/sun/star/sheet/XSpreadsheet.hpp>
+#include <com/sun/star/table/CellRangeAddress.hpp>
+#include <com/sun/star/table/XCellRange.hpp>
+
+#include <com/sun/star/sheet/XCellRangeAddressable.hpp>
+#include <com/sun/star/table/TableOrientation.hpp>
+
+#include <com/sun/star/sheet/XSheetCellRanges.hpp>
+#include <com/sun/star/sheet/XSheetOutline.hpp>
+#include <com/sun/star/sheet/XCellRangesQuery.hpp>
+
+#include <cppunit/TestAssert.h>
+#include <rtl/ustring.hxx>
+
+using namespace css;
+using namespace css::uno;
+
+namespace apitest {
+
+constexpr OUString colLevel1 = u"OutlineSheet.A1:Z1"_ustr;
+constexpr OUString colLevel2 = u"OutlineSheet.C1:W1"_ustr;
+constexpr OUString colLevel3 = u"OutlineSheet.E1:U1"_ustr;
+constexpr OUStringLiteral colLevel4 = u"OutlineSheet.G1:S1";
+
+constexpr OUString rowLevel1 = u"OutlineSheet.A1:A30"_ustr;
+constexpr OUString rowLevel2 = u"OutlineSheet.A3:A27"_ustr;
+
+static OUString getVisibleAddress(
+ uno::Reference<sheet::XSpreadsheet> const& xSheet,
+ const OUString& aLevelRangeString)
+{
+
+ uno::Reference<table::XCellRange> aSheetRangeAccess(xSheet, UNO_QUERY_THROW);
+ uno::Reference<table::XCellRange> aLevelRange = aSheetRangeAccess->getCellRangeByName(aLevelRangeString);
+
+ uno::Reference<sheet::XCellRangesQuery> xCellRangesQuery(aLevelRange,UNO_QUERY_THROW);
+ uno::Reference<sheet::XSheetCellRanges> xRanges = xCellRangesQuery->queryVisibleCells();
+ OUString aResult = xRanges->getRangeAddressesAsString();
+
+ return aResult;
+
+}
+
+static table::CellRangeAddress getAddressFromRangeString(
+ uno::Reference<sheet::XSpreadsheet> const& xSheet,
+ const OUString& aStringAddress)
+{
+
+ uno::Reference< table::XCellRange > aSheetRangeAccess(xSheet, UNO_QUERY_THROW);
+ uno::Reference<table::XCellRange> aRange = aSheetRangeAccess->getCellRangeByName(aStringAddress);
+
+ uno::Reference<sheet::XCellRangeAddressable> xCellRangeAddressable(aRange, UNO_QUERY_THROW);
+ table::CellRangeAddress aLevelRangeAddress = xCellRangeAddressable->getRangeAddress();
+
+ return aLevelRangeAddress;
+
+}
+
+void XSheetOutline::testHideDetail()
+{
+
+ uno::Reference< sheet::XSpreadsheet > aSheet(init(), UNO_QUERY_THROW);
+ uno::Reference< sheet::XSheetOutline > aSheetOutline(aSheet, UNO_QUERY_THROW);
+
+ // Column level 2
+ table::CellRangeAddress aLevelRangeAddress = getAddressFromRangeString(aSheet, colLevel2);
+ aSheetOutline->hideDetail(aLevelRangeAddress);
+
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Column level 2 not hidden",
+ getVisibleAddress(aSheet, colLevel2), OUString());
+
+ // Row Level 2
+ aLevelRangeAddress = getAddressFromRangeString(aSheet, rowLevel2);
+ aSheetOutline->hideDetail(aLevelRangeAddress);
+
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Row level 2 not hidden",
+ getVisibleAddress(aSheet, rowLevel2), OUString());
+
+}
+
+void XSheetOutline::testShowDetail()
+{
+ uno::Reference< sheet::XSpreadsheet > aSheet(init(), UNO_QUERY_THROW);
+ uno::Reference< sheet::XSheetOutline > aSheetOutline(aSheet, UNO_QUERY_THROW);
+
+ aSheetOutline->showDetail(getAddressFromRangeString(aSheet, colLevel1));
+ aSheetOutline->showDetail(getAddressFromRangeString(aSheet, rowLevel1));
+
+ // Row Level 2
+ table::CellRangeAddress aLevelRangeAddress = getAddressFromRangeString(aSheet, rowLevel2);
+ aSheetOutline->showDetail(aLevelRangeAddress);
+
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Row level 2 still hidden",
+ rowLevel2, getVisibleAddress(aSheet, rowLevel2));
+
+ // Column Level 2
+ aLevelRangeAddress = getAddressFromRangeString(aSheet, colLevel2);
+ aSheetOutline->showDetail(aLevelRangeAddress);
+
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Column level 2 still hidden",
+ colLevel2, getVisibleAddress(aSheet, colLevel2));
+
+}
+
+void XSheetOutline::testShowLevel()
+{
+
+ uno::Reference< sheet::XSpreadsheet > aSheet(init(), UNO_QUERY_THROW);
+ uno::Reference< sheet::XSheetOutline > aSheetOutline(aSheet, UNO_QUERY_THROW);
+
+ // test columns
+
+ table::CellRangeAddress aLevel1 = getAddressFromRangeString(aSheet, colLevel1);
+ table::CellRangeAddress aLevel2 = getAddressFromRangeString(aSheet, colLevel2);
+ table::CellRangeAddress aLevel3 = getAddressFromRangeString(aSheet, colLevel3);
+ table::CellRangeAddress aLevel4 = getAddressFromRangeString(aSheet, colLevel4);
+
+ aSheetOutline->showDetail(getAddressFromRangeString(aSheet, colLevel1));
+ aSheetOutline->showDetail(getAddressFromRangeString(aSheet, colLevel2));
+ aSheetOutline->showDetail(getAddressFromRangeString(aSheet, rowLevel1));
+
+ aSheetOutline->hideDetail(aLevel1);
+ aSheetOutline->hideDetail(aLevel2);
+ aSheetOutline->hideDetail(aLevel3);
+ aSheetOutline->hideDetail(aLevel4);
+
+ aSheetOutline->showLevel(2, table::TableOrientation_COLUMNS);
+
+ std::cout << " verify showLevel col apres" << getVisibleAddress(aSheet, "OutlineSheet.A1:Z30") << std::endl;
+
+ // verify that level 2 and level 1 are shown --> column 0..3 & column 22..26
+ // level 3 & 4 are hidden --> column 4..19
+
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("testShowLevel Column", OUString("OutlineSheet.A1:D1"), getVisibleAddress(aSheet, "OutlineSheet.A1:D1"));
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("testShowLevel Column", OUString("OutlineSheet.V1:Z1"), getVisibleAddress(aSheet, "OutlineSheet.V1:Z1"));
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("testShowLevel Column", OUString(), getVisibleAddress(aSheet, colLevel3));
+
+/* FIXME !!
+
+ // test Rows
+
+ aLevel1 = getAddressFromRangeString(rowLevel1);
+ aLevel2 = getAddressFromRangeString(rowLevel2);
+ aLevel3 = getAddressFromRangeString(rowLevel3);
+ aLevel4 = getAddressFromRangeString(rowLevel4);
+
+ aSheetOutline->showDetail(getAddressFromRangeString(colLevel1));
+ aSheetOutline->showDetail(getAddressFromRangeString(rowLevel1));
+ aSheetOutline->showDetail(getAddressFromRangeString(rowLevel2));
+
+ std::cout << " verify showLevel row before" << OUStringToOString(getVisibleAddress("OutlineSheet.A1:Z30"), RTL_TEXTENCODING_UTF8).getStr() << std::endl;
+
+ aSheetOutline->hideDetail(aLevel1);
+ aSheetOutline->hideDetail(aLevel2);
+ aSheetOutline->hideDetail(aLevel3);
+ aSheetOutline->hideDetail(aLevel4);
+
+ std::cout << " verify showLevel row just before" << OUStringToOString(getVisibleAddress("OutlineSheet.A1:Z30"), RTL_TEXTENCODING_UTF8).getStr() << std::endl;
+
+ aSheetOutline->showLevel(2, table::TableOrientation_ROWS);
+
+ std::cout << " verify showLevel row after" << OUStringToOString(getVisibleAddress("OutlineSheet.A1:Z30"), RTL_TEXTENCODING_UTF8).getStr() << std::endl;
+
+ // verify rows visible 0..3 & 24..29
+ // verify rows hidden 4..23
+
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("testShowLevel Row", OUString("OutlineSheet.A1:A4"), getVisibleAddress("OutlineSheet.A1:A4"));
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("testShowLevel Row", OUString("OutlineSheet.A25:A30"), getVisibleAddress("OutlineSheet.A25:A30"));
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("testShowLevel Row", OUString(), getVisibleAddress(rowLevel3));
+
+*/
+
+}
+
+void XSheetOutline::testGroup()
+{
+
+ uno::Reference< sheet::XSpreadsheet > aSheet(init(), UNO_QUERY_THROW);
+ uno::Reference< sheet::XSheetOutline > aSheetOutline(aSheet, UNO_QUERY_THROW);
+
+ // Column level 2
+ OUString aNewString = "OutlineSheet.AB1:AG1";
+ table::CellRangeAddress aLevelRangeAddress = getAddressFromRangeString(aSheet, aNewString);
+ aSheetOutline->group(aLevelRangeAddress, table::TableOrientation_COLUMNS);
+
+ aSheetOutline->hideDetail(aLevelRangeAddress);
+
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("testGroup Column still visible", getVisibleAddress(aSheet, aNewString), OUString());
+
+ // Row Level 2
+ aNewString = "OutlineSheet.A50:A60";
+ aLevelRangeAddress = getAddressFromRangeString(aSheet, aNewString);
+ aSheetOutline->group(aLevelRangeAddress, table::TableOrientation_ROWS);
+
+ aSheetOutline->hideDetail(aLevelRangeAddress);
+
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("testGroup Row still visible", getVisibleAddress(aSheet, aNewString), OUString());
+
+}
+
+void XSheetOutline::testUngroup()
+{
+ uno::Reference< sheet::XSpreadsheet > aSheet(init(), UNO_QUERY_THROW);
+ uno::Reference< sheet::XSheetOutline > aSheetOutline(aSheet, UNO_QUERY_THROW);
+
+ // New Column level
+ OUString aNewString = "OutlineSheet.BB1:BG1";
+ table::CellRangeAddress aLevelRangeAddress = getAddressFromRangeString(aSheet, aNewString);
+ aSheetOutline->group(aLevelRangeAddress, table::TableOrientation_COLUMNS);
+ aSheetOutline->hideDetail(aLevelRangeAddress);
+
+ aSheetOutline->ungroup(aLevelRangeAddress, table::TableOrientation_COLUMNS);
+
+ aSheetOutline->showDetail(aLevelRangeAddress);
+ // should remain hidden ?
+
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("testUnGroup Column becomes visible after ungroup", getVisibleAddress(aSheet, aNewString), OUString());
+
+ // New Row level
+ aNewString = "OutlineSheet.A70:A80";
+ aLevelRangeAddress = getAddressFromRangeString(aSheet, aNewString);
+ aSheetOutline->group(aLevelRangeAddress, table::TableOrientation_ROWS);
+ aSheetOutline->hideDetail(aLevelRangeAddress);
+
+ aSheetOutline->ungroup(aLevelRangeAddress, table::TableOrientation_ROWS);
+
+ aSheetOutline->showDetail(aLevelRangeAddress);
+ // should remain hidden ?
+
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("testUnGroup Row becomes visible after ungroup", getVisibleAddress(aSheet, aNewString), OUString());
+
+}
+
+void XSheetOutline::testClearOutline()
+{
+ uno::Reference< sheet::XSpreadsheet > aSheet(init(), UNO_QUERY_THROW);
+ uno::Reference< sheet::XSheetOutline > aSheetOutline(aSheet, UNO_QUERY_THROW);
+
+ aSheetOutline->clearOutline();
+
+ table::CellRangeAddress aLevelRangeAddress = getAddressFromRangeString(aSheet, colLevel1);
+ aSheetOutline->hideDetail(aLevelRangeAddress);
+ aLevelRangeAddress = getAddressFromRangeString(aSheet, rowLevel1);
+ aSheetOutline->hideDetail(aLevelRangeAddress);
+
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("testClearOutline Columns are hidden after clear", colLevel1, getVisibleAddress(aSheet, colLevel1));
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("testClearOutline Rows are hidden after clear", rowLevel1, getVisibleAddress(aSheet, rowLevel1));
+
+}
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/test/source/sheet/xsheetpagebreak.cxx b/test/source/sheet/xsheetpagebreak.cxx
new file mode 100644
index 0000000000..a1fde311ca
--- /dev/null
+++ b/test/source/sheet/xsheetpagebreak.cxx
@@ -0,0 +1,69 @@
+/* -*- 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 <test/sheet/xsheetpagebreak.hxx>
+
+#include <com/sun/star/sheet/TablePageBreakData.hpp>
+#include <com/sun/star/sheet/XSheetPageBreak.hpp>
+#include <com/sun/star/uno/Reference.hxx>
+#include <com/sun/star/uno/Sequence.hxx>
+
+#include <cppunit/TestAssert.h>
+
+using namespace css;
+using namespace css::uno;
+
+namespace apitest {
+
+void XSheetPageBreak::testGetColumnPageBreaks()
+{
+ uno::Reference< sheet::XSheetPageBreak > xSheetPageBreak(init(), UNO_QUERY_THROW);
+
+ uno::Sequence< sheet::TablePageBreakData > xColPageBreak = xSheetPageBreak->getColumnPageBreaks();
+ CPPUNIT_ASSERT_MESSAGE("Unable to get column page breaks", xColPageBreak.hasElements());
+}
+
+void XSheetPageBreak::testGetRowPageBreaks()
+{
+ uno::Reference< sheet::XSheetPageBreak > xSheetPageBreak(init(), UNO_QUERY_THROW);
+
+ uno::Sequence< sheet::TablePageBreakData > xRowPageBreak = xSheetPageBreak->getRowPageBreaks();
+ CPPUNIT_ASSERT_MESSAGE("Unable to get row page breaks", xRowPageBreak.hasElements());
+}
+
+void XSheetPageBreak::testRemoveAllManualPageBreaks()
+{
+ uno::Reference< sheet::XSheetPageBreak > xSheetPageBreak(init(), UNO_QUERY_THROW);
+
+ xSheetPageBreak->removeAllManualPageBreaks();
+
+ const uno::Sequence< sheet::TablePageBreakData > xColPageBreak = xSheetPageBreak->getColumnPageBreaks();
+ sal_Int32 manualColPageBreaks = 0;
+ for ( const auto & data : xColPageBreak )
+ {
+ if (data.ManualBreak)
+ manualColPageBreaks++;
+ }
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Found manual column page break",
+ sal_Int32(0), manualColPageBreaks);
+
+ const uno::Sequence< sheet::TablePageBreakData > xRowPageBreak = xSheetPageBreak->getRowPageBreaks();
+ sal_Int32 manualRowPageBreaks = 0;
+ for ( const auto & data : xRowPageBreak )
+ {
+ if (data.ManualBreak)
+ manualRowPageBreaks++;
+ }
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Found manual row page break",
+ sal_Int32(0), manualRowPageBreaks);
+}
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/test/source/sheet/xspreadsheet.cxx b/test/source/sheet/xspreadsheet.cxx
new file mode 100644
index 0000000000..466f995fe9
--- /dev/null
+++ b/test/source/sheet/xspreadsheet.cxx
@@ -0,0 +1,40 @@
+/* -*- 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 <test/sheet/xspreadsheet.hxx>
+
+#include <com/sun/star/sheet/XSheetCellCursor.hpp>
+#include <com/sun/star/sheet/XSheetCellRange.hpp>
+#include <com/sun/star/sheet/XSpreadsheet.hpp>
+#include <com/sun/star/uno/Reference.hxx>
+
+using namespace com::sun::star;
+using namespace com::sun::star::uno;
+
+
+namespace apitest {
+
+void XSpreadsheet::testCreateCursor()
+{
+ uno::Reference< sheet::XSpreadsheet > xSheet(init(), UNO_QUERY_THROW);
+
+ uno::Reference< sheet::XSheetCellCursor > xCursor(xSheet->createCursor(), UNO_SET_THROW);
+}
+
+void XSpreadsheet::testCreateCursorByRange()
+{
+ uno::Reference< sheet::XSpreadsheet > xSheet(init(), UNO_QUERY_THROW);
+
+ uno::Reference< sheet::XSheetCellRange > xCellRange(xSheet->getCellRangeByPosition(1, 1, 2, 3), UNO_QUERY_THROW);
+ uno::Reference< sheet::XSheetCellCursor > xCursor(xSheet->createCursorByRange(xCellRange), UNO_SET_THROW);
+}
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/test/source/sheet/xspreadsheetdocument.cxx b/test/source/sheet/xspreadsheetdocument.cxx
new file mode 100644
index 0000000000..d808d8b31f
--- /dev/null
+++ b/test/source/sheet/xspreadsheetdocument.cxx
@@ -0,0 +1,32 @@
+/* -*- 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 <test/sheet/xspreadsheetdocument.hxx>
+#include <com/sun/star/sheet/XSpreadsheets.hpp>
+#include <com/sun/star/sheet/XSpreadsheetDocument.hpp>
+#include <com/sun/star/container/XIndexAccess.hpp>
+#include <cppunit/TestAssert.h>
+
+using namespace css;
+using namespace css::uno;
+
+namespace apitest
+{
+void XSpreadsheetDocument::testGetSheets()
+{
+ uno::Reference<sheet::XSpreadsheetDocument> xSpreadsheetDoc(init(), UNO_QUERY_THROW);
+ uno::Reference<sheet::XSpreadsheets> xSheets = xSpreadsheetDoc->getSheets();
+ CPPUNIT_ASSERT(xSheets.is());
+
+ uno::Reference<container::XIndexAccess> xIA(xSheets, UNO_QUERY_THROW);
+ CPPUNIT_ASSERT_EQUAL(mnSheets, xIA->getCount());
+}
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/test/source/sheet/xspreadsheets.cxx b/test/source/sheet/xspreadsheets.cxx
new file mode 100644
index 0000000000..14e2bf9965
--- /dev/null
+++ b/test/source/sheet/xspreadsheets.cxx
@@ -0,0 +1,85 @@
+/* -*- 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 <test/sheet/xspreadsheets.hxx>
+
+#include <com/sun/star/container/XIndexAccess.hpp>
+#include <com/sun/star/container/XNamed.hpp>
+#include <com/sun/star/sheet/XSpreadsheets.hpp>
+
+#include <cppunit/TestAssert.h>
+
+using namespace com::sun::star;
+using namespace com::sun::star::uno;
+
+
+namespace apitest {
+
+void XSpreadsheets::testInsertNewByName()
+{
+ uno::Reference< sheet::XSpreadsheets > xSpreadsheets(init(), UNO_QUERY_THROW);
+
+ OUString newSheetName( "SheetToInsert" );
+ xSpreadsheets->insertNewByName(newSheetName, 0);
+
+ uno::Reference< container::XNameAccess > xNameAccess(xSpreadsheets, UNO_QUERY_THROW);
+ CPPUNIT_ASSERT_MESSAGE("Sheet was not insert",
+ xNameAccess->hasByName(newSheetName));
+}
+
+void XSpreadsheets::testInsertNewByNameBadName()
+{
+ uno::Reference< sheet::XSpreadsheets > xSpreadsheets(init(), UNO_QUERY_THROW);
+
+ CPPUNIT_ASSERT_THROW_MESSAGE("No exception thrown",
+ xSpreadsheets->insertNewByName("$%#/?\\", 0),
+ uno::RuntimeException);
+}
+
+void XSpreadsheets::testMoveByName()
+{
+ uno::Reference< sheet::XSpreadsheets > xSpreadsheets(init(), UNO_QUERY_THROW);
+
+ // first insert one that should be moved
+ xSpreadsheets->insertNewByName("SheetToMove", 0);
+ uno::Reference< container::XNameAccess > xNameAccess(xSpreadsheets, UNO_QUERY_THROW);
+ CPPUNIT_ASSERT_MESSAGE("Sheet to move was not insert",
+ xNameAccess->hasByName("SheetToMove"));
+
+ xSpreadsheets->moveByName("SheetToMove", 2);
+
+ // get sheet from the new position
+ uno::Reference< container::XIndexAccess > oIndexAccess(xSpreadsheets, UNO_QUERY_THROW);
+ uno::Any aAny = oIndexAccess->getByIndex(1);
+ uno::Reference< container::XNamed > xNamed;
+ CPPUNIT_ASSERT(aAny >>= xNamed);
+
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Sheet was not moved",
+ OUString("SheetToMove"),
+ xNamed->getName());
+}
+
+void XSpreadsheets::testCopyByName()
+{
+ uno::Reference< sheet::XSpreadsheets > xSpreadsheets(init(), UNO_QUERY_THROW);
+
+ // insert new sheet to copy
+ xSpreadsheets->insertNewByName("SheetToCopySrc", 0);
+ uno::Reference< container::XNameAccess > xNameAccess(xSpreadsheets, UNO_QUERY_THROW);
+ CPPUNIT_ASSERT_MESSAGE("Sheet to copy was not insert",
+ xNameAccess->hasByName("SheetToCopySrc"));
+
+ xSpreadsheets->copyByName("SheetToCopySrc", "SheetToCopyDst", 0);
+ CPPUNIT_ASSERT_MESSAGE("Sheet was not copied",
+ xNameAccess->hasByName("SheetToCopyDst"));
+}
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/test/source/sheet/xspreadsheets2.cxx b/test/source/sheet/xspreadsheets2.cxx
new file mode 100644
index 0000000000..dd0fbbace5
--- /dev/null
+++ b/test/source/sheet/xspreadsheets2.cxx
@@ -0,0 +1,366 @@
+/* -*- 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 <test/sheet/xspreadsheets2.hxx>
+
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/sheet/XSpreadsheetDocument.hpp>
+#include <com/sun/star/sheet/XSpreadsheet.hpp>
+#include <com/sun/star/sheet/XSpreadsheets2.hpp>
+#include <com/sun/star/sheet/XNamedRanges.hpp>
+#include <com/sun/star/sheet/XNamedRange.hpp>
+#include <com/sun/star/table/XCell.hpp>
+#include <com/sun/star/text/XTextRange.hpp>
+#include <com/sun/star/container/XIndexAccess.hpp>
+
+#include <com/sun/star/style/XStyleFamiliesSupplier.hpp>
+#include <com/sun/star/container/XNameContainer.hpp>
+#include <com/sun/star/table/CellVertJustify.hpp>
+#include <com/sun/star/util/XCloseable.hpp>
+
+#include <rtl/ustring.hxx>
+#include <cppunit/TestAssert.h>
+#include <o3tl/string_view.hxx>
+
+using namespace css;
+using namespace css::uno;
+
+namespace apitest {
+
+constexpr OUString gaSrcSheetName(u"SheetToCopy"_ustr);
+constexpr OUStringLiteral gaSrcFileName(u"rangenamessrc.ods");
+constexpr OUString gaDestFileBase(u"ScNamedRangeObj.ods"_ustr);
+
+static sal_Int32 nInsertedSheets(0);
+
+
+XSpreadsheets2::XSpreadsheets2()
+{
+}
+
+XSpreadsheets2::~XSpreadsheets2()
+{
+ if (xDestDoc.is())
+ {
+ uno::Reference<util::XCloseable> xCloseable(xDestDoc, UNO_QUERY_THROW);
+ xCloseable->close(true);
+ }
+}
+
+void XSpreadsheets2::testImportedSheetNameAndIndex()
+{
+/**
+ Verify that the imported sheet has the correct name and is placed at the right requested index
+*/
+
+ importSheetToCopy();
+
+ uno::Reference< container::XNameAccess > xDestSheetNameAccess(xDestDoc->getSheets(), UNO_QUERY_THROW);
+ CPPUNIT_ASSERT_MESSAGE("Wrong sheet name", xDestSheetNameAccess->hasByName(gaSrcSheetName));
+
+}
+
+void XSpreadsheets2::testImportString()
+{
+/**
+ tests the cell A1 containing a string correctly imported
+*/
+ importSheetToCopy();
+
+ uno::Reference< table::XCell > xSrcCell = xSrcSheet->getCellByPosition(0,0);
+ uno::Reference< text::XTextRange > xSrcTextRange(xSrcCell, UNO_QUERY_THROW);
+ OUString aSrcString = xSrcTextRange->getString();
+
+ uno::Reference< table::XCell > xDestCell = xDestSheet->getCellByPosition(0,0);
+ uno::Reference< text::XTextRange > xDestTextRange(xDestCell, UNO_QUERY_THROW);
+ OUString aDestString = xDestTextRange->getString();
+
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Wrong string imported", aSrcString, aDestString);
+}
+
+void XSpreadsheets2::testImportValue()
+{
+/**
+ tests the cell B1 containing a value correctly imported
+*/
+ importSheetToCopy();
+
+ uno::Reference< table::XCell > xSrcCell = xSrcSheet->getCellByPosition(1,0);
+ sal_Int32 aSrcValue = xSrcCell->getValue();
+
+ uno::Reference< table::XCell > xDestCell = xDestSheet->getCellByPosition(1,0);
+ sal_Int32 aDestValue = xDestCell->getValue();
+
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Wrong value imported", aSrcValue, aDestValue);
+}
+
+void XSpreadsheets2::testImportFormulaBasicMath()
+{
+/**
+ tests the cell C1 containing an arithmetic formula correctly imported
+*/
+ importSheetToCopy();
+
+ uno::Reference< table::XCell > xSrcCell = xSrcSheet->getCellByPosition(2,0);
+ OUString aSrcFormula = xSrcCell->getFormula();
+
+ uno::Reference< table::XCell > xDestCell = xDestSheet->getCellByPosition(2,0);
+ OUString aDestFormula = xDestCell->getFormula();
+
+ // potential problem later: formulas might be adjusted
+ // add some tests that the formulas are correctly adjusted
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Wrong formula imported", aSrcFormula, aDestFormula);
+}
+
+void XSpreadsheets2::testImportFormulaWithNamedRange()
+{
+/**
+ tests the cell D1 containing a formula that uses a NamedRange expression
+*/
+ importSheetToCopy();
+
+ uno::Reference< table::XCell > xSrcCell = xSrcSheet->getCellByPosition(3,0);
+ OUString aSrcFormula = xSrcCell->getFormula();
+
+ uno::Reference< table::XCell > xDestCell = xDestSheet->getCellByPosition(3,0);
+ OUString aDestFormula = xDestCell->getFormula();
+
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Wrong Namedrange formula imported", aSrcFormula, aDestFormula);
+}
+
+void XSpreadsheets2::testImportOverExistingNamedRange()
+{
+/**
+ Both Source and Target file define the named range initial1
+ in Source, initial1 is defined outside the copied sheet
+ In Target, after import sheet, initial1 should point on its initial definition $Sheet1.$B$1
+
+ NEED MORE WORK
+*/
+ importSheetToCopy();
+
+ uno::Reference< container::XNameAccess > xDestNamedRangesNameAccess(getNamedRanges(xDestDoc), UNO_QUERY_THROW);
+ uno::Any aNr = xDestNamedRangesNameAccess->getByName("initial1");
+ uno::Reference< sheet::XNamedRange > xDestNamedRange(aNr, UNO_QUERY_THROW);
+ OUString aNrDestContent = xDestNamedRange->getContent();
+
+ std::cout << "testImportSheet : initial1 aNrDestContent " << aNrDestContent << std::endl;
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Wrong address for initial1", OUString("$Sheet1.$B$1"), aNrDestContent);
+
+}
+
+void XSpreadsheets2::testImportNamedRangeDefinedInSource()
+{
+/**
+ in Source file, InSheetRangeName named range is defined in the copied sheet
+ it does not exists in target file
+ test that the range named is created in target and that it points in the target copied sheet
+*/
+ importSheetToCopy();
+
+ // New range name defined in imported sheet $SheetToCopy.$A$7
+ OUString aNewInSheetNamedRangeString("InSheetRangeName");
+ uno::Reference< container::XNameAccess > xDestNamedRangesNameAccess(getNamedRanges(xDestDoc), UNO_QUERY_THROW);
+ CPPUNIT_ASSERT_MESSAGE("InSheetRangeName", xDestNamedRangesNameAccess->hasByName(aNewInSheetNamedRangeString));
+
+ uno::Any aNewInSheetNr = xDestNamedRangesNameAccess->getByName(aNewInSheetNamedRangeString);
+ uno::Reference< sheet::XNamedRange > xDestNewInSheetNamedRange(aNewInSheetNr, UNO_QUERY_THROW);
+ OUString aNewInSheetNrDestContent = xDestNewInSheetNamedRange->getContent();
+ OUString aNewInSheetExpectedContent("$SheetToCopy.$A$7");
+
+ std::cout << "testImportSheet : InSheetRangeName content " << aNewInSheetNrDestContent << std::endl;
+ std::cout << "testImportSheet : InSheetRangeName expected " << aNewInSheetExpectedContent << std::endl;
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Wrong address for InSheetRangeName", aNewInSheetExpectedContent, aNewInSheetNrDestContent);
+}
+
+void XSpreadsheets2::testImportNamedRangeRedefinedInSource()
+{
+/**
+ in Source file, initial2 named range is defined in the copied sheet
+ it is defined in another sheet of target file
+ test that the range named points in the target copied sheet
+*/
+ importSheetToCopy();
+
+ // the source file redefines an existing named range in the imported sheet --> the target should not be changed
+ OUString aRedefinedInSheetNamedRangeString("initial2");
+ uno::Reference< container::XNameAccess > xDestNamedRangesNameAccess(getNamedRanges(xDestDoc), UNO_QUERY_THROW);
+ CPPUNIT_ASSERT_MESSAGE("aRedefinedInSheetNamedRangeString", xDestNamedRangesNameAccess->hasByName(aRedefinedInSheetNamedRangeString));
+
+ uno::Any aRedefinedInSheetNr = xDestNamedRangesNameAccess->getByName(aRedefinedInSheetNamedRangeString);
+ uno::Reference< sheet::XNamedRange > xDestRedefinedInSheetNamedRange(aRedefinedInSheetNr, UNO_QUERY_THROW);
+ OUString aRedefinedInSheetNrDestContent = xDestRedefinedInSheetNamedRange->getContent();
+ std::cout << "testImportSheet : initial2 content " << aRedefinedInSheetNrDestContent << std::endl;
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Wrong address for Redefined InSheet named range", OUString("$Sheet1.$B$2"), aRedefinedInSheetNrDestContent);
+}
+
+void XSpreadsheets2::testImportNewNamedRange()
+{
+/**
+ in Source file, new_rangename range named is defined outside the copied sheet
+ it does not exists in target file test that new_rangename is created and its
+ content points to source file as an external reference
+*/
+ importSheetToCopy();
+
+ //formula with a non-existent named range in dest - new_rangename
+ OUString aNewNamedRangeString("new_rangename");
+ uno::Reference< container::XNameAccess > xDestNamedRangesNameAccess(getNamedRanges(xDestDoc), UNO_QUERY_THROW);
+ CPPUNIT_ASSERT_MESSAGE("New NamedRange not created", xDestNamedRangesNameAccess->hasByName(aNewNamedRangeString));
+
+ // verify the content of this new namedrange, pointing on $Sheet1.$B$1 in source. This address is already defined in target as NR content
+
+ uno::Any aNewNr = xDestNamedRangesNameAccess->getByName(aNewNamedRangeString);
+ uno::Reference< sheet::XNamedRange > xDestNewNamedRange(aNewNr, UNO_QUERY_THROW);
+ OUString aNewNrDestContent = xDestNewNamedRange->getContent();
+
+ OUString aNewExpectedContent("$Sheet1.$B$1");
+
+ std::cout << "testImportSheet : new_rangename aNewExpectedContent " << aNewExpectedContent << std::endl;
+ std::cout << "testImportSheet : new_rangename aNewNrDestContent " << aNewNrDestContent << std::endl;
+ CPPUNIT_ASSERT_MESSAGE("Wrong New NamedRange formula string value", isExternalReference(aNewNrDestContent, aNewExpectedContent));
+}
+
+void XSpreadsheets2::testImportCellStyle()
+{
+/**
+ in source file, imported sheet uses a cellstyle that does not exists in target
+ test that
+ - an imported cell D1 uses the right cellStyle
+ - the cellStyle is created in CellStyles family
+ - a property of the cellStyle (VertJustify) is correctly set
+*/
+ importSheetToCopy();
+
+ uno::Reference< table::XCell > xSrcCell = xSrcSheet->getCellByPosition(3,0);
+ xDestSheet->getCellByPosition(3,0);
+
+ //new style created in dest
+ uno::Reference< beans::XPropertySet > xSrcCellPropSet (xSrcCell, UNO_QUERY_THROW);
+ static constexpr OUString aCellProperty(u"CellStyle"_ustr);
+ OUString aSrcStyleName;
+ CPPUNIT_ASSERT(xSrcCellPropSet->getPropertyValue(aCellProperty) >>= aSrcStyleName);
+
+ uno::Reference< beans::XPropertySet > xDestCellPropSet (xSrcCell, UNO_QUERY_THROW);
+ OUString aDestStyleName;
+ CPPUNIT_ASSERT(xDestCellPropSet->getPropertyValue(aCellProperty) >>= aDestStyleName);
+
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Wrong imported Cell Style", aSrcStyleName, aDestStyleName);
+
+ uno::Reference< style::XStyleFamiliesSupplier > xFamiliesSupplier (xDestDoc, UNO_QUERY_THROW);
+ uno::Reference< container::XNameAccess > xFamiliesNameAccess (xFamiliesSupplier->getStyleFamilies(), UNO_SET_THROW);
+ uno::Any aCellStylesFamily = xFamiliesNameAccess->getByName("CellStyles");
+ uno::Reference< container::XNameContainer > xCellStylesFamilyNameAccess (aCellStylesFamily, UNO_QUERY_THROW);
+
+ CPPUNIT_ASSERT_MESSAGE("New cell style not present", xCellStylesFamilyNameAccess->hasByName(aDestStyleName));
+
+ uno::Any aCellStyle = xCellStylesFamilyNameAccess->getByName(aDestStyleName);
+ uno::Reference< beans::XPropertySet > xCellStyleProp (aCellStyle, UNO_QUERY_THROW);
+ sal_Int32 aVertJustify = 0;
+ CPPUNIT_ASSERT(xCellStyleProp->getPropertyValue("VertJustify") >>= aVertJustify);
+
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("New style: VertJustify not set", table::CellVertJustify_CENTER, static_cast<table::CellVertJustify>(aVertJustify));
+}
+
+void XSpreadsheets2::testLastAfterInsertCopy()
+{
+ /** Test that results in row 1 of all inserted sheets are equal to the
+ source sheet. The loaded destination document is kept open so several
+ sheets are imported.
+ */
+
+ CPPUNIT_ASSERT(nInsertedSheets > 0);
+ constexpr sal_Int32 nCols = 7;
+
+ uno::Reference< container::XNameAccess> xSrcNameAccess(init(),UNO_QUERY_THROW);
+ xSrcSheet.set( xSrcNameAccess->getByName(gaSrcSheetName), UNO_QUERY_THROW);
+
+ OUString aSrcString[nCols];
+ for (sal_Int32 nCol=0; nCol < nCols; ++nCol)
+ {
+ uno::Reference< table::XCell > xSrcCell = xSrcSheet->getCellByPosition(nCol, 0);
+ uno::Reference< text::XTextRange > xSrcTextRange(xSrcCell, UNO_QUERY_THROW);
+ aSrcString[nCol] = xSrcTextRange->getString();
+ }
+ // The named range 'initial2' is already present in the destination
+ // document defined to $Sheet1.$B$2 and thus is not copied, pointing to
+ // "content2" instead.
+ aSrcString[6] = "content2";
+
+ xDestDoc = getDoc(gaDestFileBase);
+ CPPUNIT_ASSERT(xDestDoc.is());
+ uno::Reference< container::XIndexAccess > xDestSheetIndexAccess (xDestDoc->getSheets(), UNO_QUERY_THROW);
+ CPPUNIT_ASSERT( nInsertedSheets < xDestSheetIndexAccess->getCount());
+ for (sal_Int32 nSheet=0; nSheet < nInsertedSheets; ++nSheet)
+ {
+ xDestSheet.set( xDestSheetIndexAccess->getByIndex(nSheet), UNO_QUERY_THROW);
+ for (sal_Int32 nCol=0; nCol < nCols; ++nCol)
+ {
+ uno::Reference< table::XCell > xDestCell = xDestSheet->getCellByPosition(nCol, 0);
+ uno::Reference< text::XTextRange > xDestTextRange(xDestCell, UNO_QUERY_THROW);
+ OUString aDestString = xDestTextRange->getString();
+
+ if (nCol == 4 && aDestString == "Err:540")
+ // The created external reference to the source document not
+ // allowed may result in Err:540
+ continue;
+
+ OString aMessage("Imported result does not match, sheet " + OString::number(nSheet)
+ + " column " + OString::number(nCol));
+ CPPUNIT_ASSERT_EQUAL_MESSAGE( aMessage.getStr(), aSrcString[nCol], aDestString);
+ }
+ }
+}
+
+uno::Reference< sheet::XSpreadsheetDocument> XSpreadsheets2::getDoc(const OUString& aFileBase)
+{
+ uno::Reference< lang::XComponent > xComp = loadFromDesktop(aFileBase);
+ uno::Reference< sheet::XSpreadsheetDocument > xDoc(xComp, UNO_QUERY_THROW);
+ return xDoc;
+}
+
+uno::Reference< sheet::XNamedRanges> XSpreadsheets2::getNamedRanges(uno::Reference< sheet::XSpreadsheetDocument> const & xDoc)
+{
+ uno::Reference< beans::XPropertySet > xPropSet (xDoc, UNO_QUERY_THROW);
+ uno::Reference< sheet::XNamedRanges > xNamedRanges(xPropSet->getPropertyValue("NamedRanges"), UNO_QUERY_THROW);
+ return xNamedRanges;
+}
+
+void XSpreadsheets2::importSheetToCopy()
+{
+ uno::Reference< container::XNameAccess> xSrcNameAccess(init(),UNO_QUERY_THROW);
+ xSrcSheet.set( xSrcNameAccess->getByName(gaSrcSheetName), UNO_QUERY_THROW);
+
+ xDestDoc = getDoc(gaDestFileBase);
+ CPPUNIT_ASSERT(xDestDoc.is());
+
+ // import sheet
+ uno::Reference< sheet::XSpreadsheets2 > xDestSheets (xDestDoc->getSheets(), UNO_QUERY_THROW);
+ sal_Int32 nDestPos = 0;
+ sal_Int32 nDestPosEffective = xDestSheets->importSheet(xDocument, gaSrcSheetName, nDestPos);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Wrong sheet index", nDestPos, nDestPosEffective);
+ ++nInsertedSheets;
+
+ uno::Reference< container::XIndexAccess > xDestSheetIndexAccess (xDestDoc->getSheets(), UNO_QUERY_THROW);
+ xDestSheet.set( xDestSheetIndexAccess->getByIndex(nDestPosEffective), UNO_QUERY_THROW);
+}
+
+bool XSpreadsheets2::isExternalReference(std::u16string_view aDestContent, std::u16string_view aSrcContent )
+{
+ CPPUNIT_ASSERT(o3tl::starts_with(aDestContent, u"'file://"));
+
+ if (!o3tl::endsWithIgnoreAsciiCase(aDestContent, aSrcContent)) // same cell address
+ return false;
+ size_t nPos = aDestContent.find(gaSrcFileName);
+ return nPos != std::u16string_view::npos && nPos > 0; // contains source file name
+}
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/test/source/sheet/xspreadsheetview.cxx b/test/source/sheet/xspreadsheetview.cxx
new file mode 100644
index 0000000000..d8804cf5d9
--- /dev/null
+++ b/test/source/sheet/xspreadsheetview.cxx
@@ -0,0 +1,41 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * 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 <test/sheet/xspreadsheetview.hxx>
+
+#include <com/sun/star/sheet/XSpreadsheet.hpp>
+#include <com/sun/star/sheet/XSpreadsheetView.hpp>
+#include <com/sun/star/uno/Reference.hxx>
+
+#include <cppunit/TestAssert.h>
+
+using namespace com::sun::star;
+using namespace com::sun::star::uno;
+
+namespace apitest
+{
+void XSpreadsheetView::testGetSetActiveSheet()
+{
+ uno::Reference<sheet::XSpreadsheetView> xView(init(), UNO_QUERY_THROW);
+
+ uno::Reference<sheet::XSpreadsheet> xActiveSheet = xView->getActiveSheet();
+ CPPUNIT_ASSERT_MESSAGE("Unable to get default active sheet", xActiveSheet.is());
+
+ uno::Reference<sheet::XSpreadsheet> xNewSheet = xActiveSheet;
+ CPPUNIT_ASSERT_MESSAGE("no sheet", xNewSheet.is());
+ xView->setActiveSheet(xNewSheet);
+
+ uno::Reference<sheet::XSpreadsheet> xNewActiveSheet = xView->getActiveSheet();
+ CPPUNIT_ASSERT_MESSAGE("Unable to get new active sheet", xNewActiveSheet.is());
+ CPPUNIT_ASSERT_MESSAGE("Default and new active sheet are not different",
+ xActiveSheet.get() != xNewActiveSheet.get());
+}
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/test/source/sheet/xsubtotalcalculatable.cxx b/test/source/sheet/xsubtotalcalculatable.cxx
new file mode 100644
index 0000000000..ad29154d60
--- /dev/null
+++ b/test/source/sheet/xsubtotalcalculatable.cxx
@@ -0,0 +1,70 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * 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 <test/sheet/xsubtotalcalculatable.hxx>
+
+#include <com/sun/star/sheet/GeneralFunction.hpp>
+#include <com/sun/star/sheet/SubTotalColumn.hpp>
+#include <com/sun/star/sheet/XSpreadsheet.hpp>
+#include <com/sun/star/sheet/XSubTotalCalculatable.hpp>
+#include <com/sun/star/sheet/XSubTotalDescriptor.hpp>
+
+#include <com/sun/star/uno/Reference.hxx>
+#include <com/sun/star/uno/Sequence.hxx>
+
+#include <cppunit/TestAssert.h>
+
+using namespace com::sun::star;
+using namespace com::sun::star::uno;
+
+namespace apitest {
+
+void XSubTotalCalculatable::testCreateSubTotalDescriptor()
+{
+ uno::Reference< sheet::XSubTotalCalculatable > xSTC(init(), uno::UNO_QUERY_THROW);
+ uno::Reference< sheet::XSubTotalDescriptor > xSTD = xSTC->createSubTotalDescriptor(true);
+
+ uno::Sequence< sheet::SubTotalColumn > xCols{ { /* Column */ 5,
+ /* Function */ sheet::GeneralFunction_SUM } };
+
+ CPPUNIT_ASSERT_NO_THROW_MESSAGE("Unable to create XSubTotalDescriptor", xSTD->addNew(xCols, 1));
+}
+
+void XSubTotalCalculatable::testApplyRemoveSubTotals()
+{
+ uno::Reference< sheet::XSpreadsheet > xSheet(getXSpreadsheet(), UNO_QUERY_THROW);
+ uno::Reference< sheet::XSubTotalCalculatable > xSTC(xSheet, UNO_QUERY_THROW);
+
+ uno::Reference< sheet::XSubTotalDescriptor > xSTD = xSTC->createSubTotalDescriptor(true);
+ uno::Sequence< sheet::SubTotalColumn > xCols{ { /* Column */ 0,
+ /* Function */ sheet::GeneralFunction_SUM } };
+ xSTD->addNew(xCols, 1);
+
+ xSheet->getCellByPosition(0, 0)->setFormula("first");
+ xSheet->getCellByPosition(1, 0)->setFormula("second");
+ xSheet->getCellByPosition(0, 3)->setFormula("");
+ xSheet->getCellByPosition(0, 1)->setValue(5);
+ xSheet->getCellByPosition(0, 2)->setValue(5);
+ xSheet->getCellByPosition(1, 1)->setValue(17);
+ xSheet->getCellByPosition(1, 2)->setValue(17);
+
+ xSTC->applySubTotals(xSTD, true);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Unable to apply SubTotals",
+ OUString("=SUBTOTAL(9;$A$2:$A$3)"),
+ xSheet->getCellByPosition(0, 3)->getFormula());
+
+ xSTC->removeSubTotals();
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Unable to remove SubTotals",
+ OUString(""),
+ xSheet->getCellByPosition(0, 3)->getFormula());
+}
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/test/source/sheet/xsubtotaldescriptor.cxx b/test/source/sheet/xsubtotaldescriptor.cxx
new file mode 100644
index 0000000000..037963a28c
--- /dev/null
+++ b/test/source/sheet/xsubtotaldescriptor.cxx
@@ -0,0 +1,44 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * 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 <test/sheet/xsubtotaldescriptor.hxx>
+
+#include <com/sun/star/sheet/GeneralFunction.hpp>
+#include <com/sun/star/sheet/SubTotalColumn.hpp>
+#include <com/sun/star/sheet/XSubTotalDescriptor.hpp>
+
+#include <com/sun/star/uno/Reference.hxx>
+#include <com/sun/star/uno/Sequence.hxx>
+
+#include <cppunit/TestAssert.h>
+
+using namespace com::sun::star;
+using namespace com::sun::star::uno;
+
+namespace apitest
+{
+void XSubTotalDescriptor::testAddNew()
+{
+ uno::Reference<sheet::XSubTotalDescriptor> xSTD(init(), uno::UNO_QUERY_THROW);
+
+ uno::Sequence<sheet::SubTotalColumn> xCols{ { /* Column */ 5,
+ /* Function */ sheet::GeneralFunction_SUM } };
+
+ CPPUNIT_ASSERT_NO_THROW_MESSAGE("Unable to add column", xSTD->addNew(xCols, 1));
+}
+
+void XSubTotalDescriptor::testClear()
+{
+ uno::Reference<sheet::XSubTotalDescriptor> xSTD(init(), UNO_QUERY_THROW);
+
+ CPPUNIT_ASSERT_NO_THROW_MESSAGE("Unable to clear XSubTotalDescriptor", xSTD->clear());
+}
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/test/source/sheet/xsubtotalfield.cxx b/test/source/sheet/xsubtotalfield.cxx
new file mode 100644
index 0000000000..45588d193c
--- /dev/null
+++ b/test/source/sheet/xsubtotalfield.cxx
@@ -0,0 +1,66 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * 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 <test/sheet/xsubtotalfield.hxx>
+
+#include <com/sun/star/sheet/GeneralFunction.hpp>
+#include <com/sun/star/sheet/SubTotalColumn.hpp>
+#include <com/sun/star/sheet/XSubTotalField.hpp>
+
+#include <com/sun/star/uno/Reference.hxx>
+#include <com/sun/star/uno/Sequence.hxx>
+
+#include <cppunit/TestAssert.h>
+
+using namespace com::sun::star;
+using namespace com::sun::star::uno;
+
+template<> inline std::string
+CPPUNIT_NS::assertion_traits<uno::Sequence< sheet::SubTotalColumn > >::toString(
+ const uno::Sequence< sheet::SubTotalColumn >& x)
+{
+ OStringStream ost;
+ ost << "Sequence: Length: " << x.getLength() << "\n";
+ for (const auto& rElement : x)
+ ost << "Column: " << rElement.Column << " Function:\n";
+ // FIXME: Find a way to print Function
+ //ost << "Column: " << element->Column << " Function: " << element->Function << "\n";
+ return ost.str();
+}
+
+namespace apitest {
+
+void XSubTotalField::testGetSetGroupColumn()
+{
+ uno::Reference< sheet::XSubTotalField > xSTF(init(), uno::UNO_QUERY_THROW);
+
+ CPPUNIT_ASSERT_MESSAGE("Unable to get GroupColumn", xSTF->getGroupColumn() != 0);
+
+ xSTF->setGroupColumn(2);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Unable to set GroupColumn to new value",
+ sal_Int32(2), xSTF->getGroupColumn());
+}
+
+void XSubTotalField::testGetSetTotalColumns()
+{
+ uno::Reference< sheet::XSubTotalField > xSTF(init(), UNO_QUERY_THROW);
+
+ uno::Sequence< sheet::SubTotalColumn > sDefaultCols = xSTF->getSubTotalColumns();
+ CPPUNIT_ASSERT_MESSAGE("Unable to get SubTotalColumns", sDefaultCols.hasElements());
+
+ uno::Sequence< sheet::SubTotalColumn > sNewCols{ { /* Column */ 5,
+ /* Function */ sheet::GeneralFunction_AVERAGE } };
+ xSTF->setSubTotalColumns(sNewCols);
+
+ CPPUNIT_ASSERT_MESSAGE("Unable to set SubTotalColumns", sDefaultCols != xSTF->getSubTotalColumns());
+}
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/test/source/sheet/xuniquecellformatrangessupplier.cxx b/test/source/sheet/xuniquecellformatrangessupplier.cxx
new file mode 100644
index 0000000000..14f4a29b87
--- /dev/null
+++ b/test/source/sheet/xuniquecellformatrangessupplier.cxx
@@ -0,0 +1,37 @@
+/* -*- 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 <test/sheet/xuniquecellformatrangessupplier.hxx>
+
+#include <com/sun/star/container/XIndexAccess.hpp>
+#include <com/sun/star/sheet/XUniqueCellFormatRangesSupplier.hpp>
+
+#include <cppunit/TestAssert.h>
+
+using namespace com::sun::star;
+using namespace com::sun::star::uno;
+
+namespace apitest {
+
+void XUniqueCellFormatRangesSupplier::testGetUniqueCellFormatRanges()
+{
+ uno::Reference< sheet::XUniqueCellFormatRangesSupplier > xSupplier(init(), UNO_QUERY_THROW);
+ uno::Reference< container::XIndexAccess > xIndexAccess = xSupplier->getUniqueCellFormatRanges();
+
+ auto count = xIndexAccess->getCount();
+ CPPUNIT_ASSERT_MESSAGE("No elements found", count);
+ for (auto i = 0; i<count; i++) {
+ CPPUNIT_ASSERT_NO_THROW_MESSAGE(OString("Unable to access element " + OString::number(i)).getStr(),
+ xIndexAccess->getByIndex(i));
+ }
+}
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/test/source/sheet/xusedareacursor.cxx b/test/source/sheet/xusedareacursor.cxx
new file mode 100644
index 0000000000..dcee0cf57e
--- /dev/null
+++ b/test/source/sheet/xusedareacursor.cxx
@@ -0,0 +1,97 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * 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 <test/sheet/xusedareacursor.hxx>
+
+#include <com/sun/star/sheet/XCellRangeAddressable.hpp>
+#include <com/sun/star/sheet/XSheetCellCursor.hpp>
+#include <com/sun/star/sheet/XSpreadsheet.hpp>
+#include <com/sun/star/sheet/XUsedAreaCursor.hpp>
+
+#include <com/sun/star/table/CellRangeAddress.hpp>
+
+#include <cppunit/TestAssert.h>
+
+using namespace com::sun::star;
+using namespace com::sun::star::uno;
+
+
+namespace apitest {
+
+void XUsedAreaCursor::testGotoStartOfUsedArea()
+{
+ uno::Reference< sheet::XSpreadsheet > xSheet(getXSpreadsheet(), UNO_QUERY_THROW);
+ uno::Reference< sheet::XSheetCellCursor > xSheetCellCursor(xSheet->createCursor(), UNO_SET_THROW);
+ uno::Reference< sheet::XCellRangeAddressable> xCellRangeAddressable(xSheetCellCursor, UNO_QUERY_THROW);
+
+ uno::Reference< sheet::XUsedAreaCursor > xUsedAreaCursor(xSheetCellCursor, UNO_QUERY_THROW);
+
+ xUsedAreaCursor->gotoStartOfUsedArea(false);
+ xUsedAreaCursor->gotoEndOfUsedArea(true);
+ table::CellRangeAddress cellRangeAddress = xCellRangeAddressable->getRangeAddress();
+
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Wrong start column",
+ sal_Int32(0), cellRangeAddress.StartColumn);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Wrong end column",
+ sal_Int32(2), cellRangeAddress.EndColumn);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Wrong start row",
+ sal_Int32(0), cellRangeAddress.StartRow);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Wrong end column",
+ sal_Int32(0), cellRangeAddress.EndRow);
+
+ xUsedAreaCursor->gotoEndOfUsedArea(false);
+ cellRangeAddress = xCellRangeAddressable->getRangeAddress();
+
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Wrong start column",
+ sal_Int32(2), cellRangeAddress.StartColumn);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Wrong end column",
+ sal_Int32(2), cellRangeAddress.EndColumn);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Wrong start row",
+ sal_Int32(0), cellRangeAddress.StartRow);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Wrong end column",
+ sal_Int32(0), cellRangeAddress.EndRow);
+}
+
+void XUsedAreaCursor::testGotoEndOfUsedArea()
+{
+ uno::Reference< sheet::XSpreadsheet > xSheet(getXSpreadsheet(), UNO_QUERY_THROW);
+ uno::Reference< sheet::XSheetCellCursor > xSheetCellCursor(xSheet->createCursor(), UNO_SET_THROW);
+ uno::Reference< sheet::XCellRangeAddressable> xCellRangeAddressable(xSheetCellCursor, UNO_QUERY_THROW);
+
+ uno::Reference< sheet::XUsedAreaCursor > xUsedAreaCursor(xSheetCellCursor, UNO_QUERY_THROW);
+
+ xUsedAreaCursor->gotoEndOfUsedArea(false);
+ xUsedAreaCursor->gotoStartOfUsedArea(true);
+ table::CellRangeAddress cellRangeAddress = xCellRangeAddressable->getRangeAddress();
+
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Wrong start column",
+ sal_Int32(0), cellRangeAddress.StartColumn);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Wrong end column",
+ sal_Int32(2), cellRangeAddress.EndColumn);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Wrong start row",
+ sal_Int32(0), cellRangeAddress.StartRow);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Wrong end column",
+ sal_Int32(0), cellRangeAddress.EndRow);
+
+ xUsedAreaCursor->gotoStartOfUsedArea(false);
+ cellRangeAddress = xCellRangeAddressable->getRangeAddress();
+
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Wrong start column",
+ sal_Int32(0), cellRangeAddress.StartColumn);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Wrong end column",
+ sal_Int32(0), cellRangeAddress.EndColumn);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Wrong start row",
+ sal_Int32(0), cellRangeAddress.StartRow);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Wrong end column",
+ sal_Int32(0), cellRangeAddress.EndRow);
+}
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/test/source/sheet/xviewfreezable.cxx b/test/source/sheet/xviewfreezable.cxx
new file mode 100644
index 0000000000..2e13ffd294
--- /dev/null
+++ b/test/source/sheet/xviewfreezable.cxx
@@ -0,0 +1,32 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * 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 <test/sheet/xviewfreezable.hxx>
+
+#include <com/sun/star/sheet/XViewFreezable.hpp>
+
+#include <cppunit/TestAssert.h>
+
+using namespace com::sun::star;
+using namespace com::sun::star::uno;
+
+namespace apitest
+{
+void XViewFreezable::testFreeze()
+{
+ uno::Reference<sheet::XViewFreezable> xViewFreezable(init(), UNO_QUERY_THROW);
+
+ CPPUNIT_ASSERT_MESSAGE("View has already frozen panes", !xViewFreezable->hasFrozenPanes());
+
+ xViewFreezable->freezeAtPosition(1, 1);
+ CPPUNIT_ASSERT_MESSAGE("Unable to freeze pane", xViewFreezable->hasFrozenPanes());
+}
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/test/source/sheet/xviewpane.cxx b/test/source/sheet/xviewpane.cxx
new file mode 100644
index 0000000000..a10c59d9c0
--- /dev/null
+++ b/test/source/sheet/xviewpane.cxx
@@ -0,0 +1,52 @@
+/* -*- 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 <test/sheet/xviewpane.hxx>
+#include <com/sun/star/sheet/XViewPane.hpp>
+#include <com/sun/star/table/CellRangeAddress.hpp>
+
+#include <cppunit/TestAssert.h>
+
+using namespace css;
+using namespace css::uno;
+
+namespace apitest
+{
+void XViewPane::testFirstVisibleColumn()
+{
+ sal_Int32 nCol = 5;
+ uno::Reference<sheet::XViewPane> xViewPane(init(), UNO_QUERY_THROW);
+ xViewPane->setFirstVisibleColumn(nCol);
+ CPPUNIT_ASSERT_EQUAL(xViewPane->getFirstVisibleColumn(), nCol);
+}
+
+void XViewPane::testFirstVisibleRow()
+{
+ sal_Int32 nRow = 3;
+ uno::Reference<sheet::XViewPane> xViewPane(init(), UNO_QUERY_THROW);
+ xViewPane->setFirstVisibleRow(nRow);
+ CPPUNIT_ASSERT_EQUAL(xViewPane->getFirstVisibleRow(), nRow);
+}
+
+void XViewPane::testVisibleRange()
+{
+ constexpr sal_Int32 nCol = 5;
+ constexpr sal_Int32 nRow = 3;
+ uno::Reference<sheet::XViewPane> xViewPane(init(), UNO_QUERY_THROW);
+ xViewPane->setFirstVisibleColumn(nCol);
+ xViewPane->setFirstVisibleRow(nRow);
+
+ table::CellRangeAddress aCellRangeAddress = xViewPane->getVisibleRange();
+ CPPUNIT_ASSERT_EQUAL(short(0), aCellRangeAddress.Sheet);
+ CPPUNIT_ASSERT_EQUAL(nRow, aCellRangeAddress.StartRow);
+ CPPUNIT_ASSERT_EQUAL(nCol, aCellRangeAddress.StartColumn);
+}
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/test/source/sheet/xviewsplitable.cxx b/test/source/sheet/xviewsplitable.cxx
new file mode 100644
index 0000000000..e9f8d62b89
--- /dev/null
+++ b/test/source/sheet/xviewsplitable.cxx
@@ -0,0 +1,42 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * 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 <test/sheet/xviewsplitable.hxx>
+
+#include <com/sun/star/sheet/XViewSplitable.hpp>
+
+#include <cppunit/TestAssert.h>
+
+using namespace com::sun::star;
+using namespace com::sun::star::uno;
+
+namespace apitest {
+
+void XViewSplitable::testSplit()
+{
+ uno::Reference< sheet::XViewSplitable > xViewSplitable(init(), UNO_QUERY_THROW);
+ CPPUNIT_ASSERT_MESSAGE("View is already split", !xViewSplitable->getIsWindowSplit());
+
+ xViewSplitable->splitAtPosition(90, 51);
+
+ CPPUNIT_ASSERT_MESSAGE("View wasn't split", xViewSplitable->getIsWindowSplit());
+
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Wrong horizontal pixel position",
+ sal_Int32(90), xViewSplitable->getSplitHorizontal());
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Wrong vertical pixel position",
+ sal_Int32(51), xViewSplitable->getSplitVertical());
+
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Wrong column",
+ sal_Int32(1), xViewSplitable->getSplitColumn());
+ CPPUNIT_ASSERT_MESSAGE("Wrong row", xViewSplitable->getSplitRow() != 0);
+}
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/test/source/style/xstyleloader.cxx b/test/source/style/xstyleloader.cxx
new file mode 100644
index 0000000000..4b58758d9e
--- /dev/null
+++ b/test/source/style/xstyleloader.cxx
@@ -0,0 +1,123 @@
+/* -*- 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 <test/style/xstyleloader.hxx>
+
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/container/XNameContainer.hpp>
+#include <com/sun/star/io/XInputStream.hpp>
+#include <com/sun/star/sheet/XSpreadsheetDocument.hpp>
+#include <com/sun/star/style/XStyle.hpp>
+#include <com/sun/star/style/XStyleLoader2.hpp>
+
+#include <com/sun/star/uno/Any.hxx>
+#include <com/sun/star/uno/Reference.hxx>
+#include <com/sun/star/uno/Sequence.hxx>
+
+#include <rtl/ustring.hxx>
+#include <cppunit/TestAssert.h>
+#include <comphelper/processfactory.hxx>
+#include <comphelper/storagehelper.hxx>
+
+using namespace comphelper;
+using namespace css;
+using namespace css::uno;
+
+namespace apitest
+{
+void XStyleLoader::testLoadStylesFromURL()
+{
+ uno::Reference<style::XStyleLoader2> xStyleLoader(init(), uno::UNO_QUERY_THROW);
+
+ uno::Reference<sheet::XSpreadsheetDocument> xDoc(getTargetDoc(), uno::UNO_SET_THROW);
+ const OUString aFileURL = getTestURL();
+
+ uno::Sequence<beans::PropertyValue> aOptions = xStyleLoader->getStyleLoaderOptions();
+ xStyleLoader->loadStylesFromURL(aFileURL, aOptions);
+
+ uno::Reference<style::XStyleFamiliesSupplier> xFamilySupplier(xDoc, UNO_QUERY_THROW);
+ checkStyleProperties(xFamilySupplier);
+}
+
+void XStyleLoader::testLoadStylesFromDocument()
+{
+ uno::Reference<style::XStyleLoader2> xStyleLoader(init(), uno::UNO_QUERY_THROW);
+
+ uno::Reference<sheet::XSpreadsheetDocument> xDoc(getTargetDoc(), uno::UNO_SET_THROW);
+ uno::Reference<lang::XComponent> xSrcComponent(getSourceComponent(), UNO_SET_THROW);
+
+ uno::Sequence<beans::PropertyValue> aOptions = xStyleLoader->getStyleLoaderOptions();
+ xStyleLoader->loadStylesFromDocument(xSrcComponent, aOptions);
+
+ uno::Reference<style::XStyleFamiliesSupplier> xFamilySupplier(xDoc, UNO_QUERY_THROW);
+ checkStyleProperties(xFamilySupplier);
+}
+
+void XStyleLoader::testLoadStylesFromStream()
+{
+ uno::Reference<style::XStyleLoader2> xStyleLoader(init(), uno::UNO_QUERY_THROW);
+
+ uno::Reference<sheet::XSpreadsheetDocument> xDoc(getTargetDoc(), uno::UNO_SET_THROW);
+ const OUString aFileURL = getTestURL();
+ const uno::Reference<io::XInputStream> xInputStream
+ = OStorageHelper::GetInputStreamFromURL(aFileURL, getProcessComponentContext());
+
+ uno::Sequence<beans::PropertyValue> aOptions = xStyleLoader->getStyleLoaderOptions();
+ auto nLength = aOptions.getLength();
+ aOptions.realloc(nLength + 1);
+ beans::PropertyValue aInputStream;
+ aInputStream.Name = "InputStream";
+ uno::Any aTmp;
+ aTmp <<= xInputStream;
+ aInputStream.Value = aTmp;
+ aOptions.getArray()[nLength] = aInputStream;
+
+ xStyleLoader->loadStylesFromURL("private:stream", aOptions);
+
+ uno::Reference<style::XStyleFamiliesSupplier> xFamilySupplier(xDoc, UNO_QUERY_THROW);
+ checkStyleProperties(xFamilySupplier);
+}
+
+void XStyleLoader::checkStyleProperties(
+ uno::Reference<style::XStyleFamiliesSupplier> const& xFamilySupplier)
+{
+ // check if targetDocument has myStyle
+ uno::Reference<container::XNameAccess> xFamilies(xFamilySupplier->getStyleFamilies(),
+ UNO_SET_THROW);
+ uno::Reference<container::XNameContainer> xCellStyles(xFamilies->getByName("CellStyles"),
+ UNO_QUERY_THROW);
+
+ CPPUNIT_ASSERT_MESSAGE("Style not imported", xCellStyles->hasByName("myStyle"));
+
+ // test the backgroundcolor is correctly imported
+ uno::Reference<style::XStyle> xMyStyle(xCellStyles->getByName("myStyle"), UNO_QUERY_THROW);
+ uno::Reference<beans::XPropertySet> xPropSet(xMyStyle, UNO_QUERY_THROW);
+
+ uno::Any aBackColor = xPropSet->getPropertyValue("CellBackColor");
+ uno::Any expectedBackColor(sal_Int32(16724787));
+
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Wrong CellBackColor", expectedBackColor, aBackColor);
+
+ // test default pageStyle
+
+ uno::Reference<container::XNameContainer> xPageStyles(xFamilies->getByName("PageStyles"),
+ UNO_QUERY_THROW);
+ uno::Reference<beans::XPropertySet> xPagePropSet(xPageStyles->getByName("Default"),
+ UNO_QUERY_THROW);
+
+ uno::Any aPageBackColor = xPagePropSet->getPropertyValue("BackColor");
+ uno::Any expectedPageBackColor(sal_Int32(13434879));
+
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Wrong page style BackColor", expectedPageBackColor,
+ aPageBackColor);
+}
+
+} // namespace apitest
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/test/source/table/tablecolumn.cxx b/test/source/table/tablecolumn.cxx
new file mode 100644
index 0000000000..08a008ce88
--- /dev/null
+++ b/test/source/table/tablecolumn.cxx
@@ -0,0 +1,53 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * 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 <test/table/tablecolumn.hxx>
+#include <test/unoapi_property_testers.hxx>
+#include <comphelper/types.hxx>
+#include <rtl/ustring.hxx>
+
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/table/XCellRange.hpp>
+
+#include <com/sun/star/uno/Any.hxx>
+#include <com/sun/star/uno/Reference.hxx>
+
+#include <cppunit/TestAssert.h>
+
+using namespace css;
+
+namespace apitest
+{
+void TableColumn::testTableColumnProperties()
+{
+ uno::Reference<beans::XPropertySet> xPS(init(), uno::UNO_QUERY_THROW);
+
+ OUString aPropName = "Width";
+ testLongProperty(xPS, aPropName);
+
+ // currently changing the value to false has no effect
+ aPropName = "OptimalWidth";
+ uno::Reference<table::XCellRange> xCR(m_xSheet, uno::UNO_QUERY_THROW);
+ xCR->getCellByPosition(0, 0)->setFormula("That's a pretty long text.");
+ const sal_Int64 nWidthBefore = ::comphelper::getINT64(xPS->getPropertyValue("Width"));
+ xPS->setPropertyValue(aPropName, uno::Any(true));
+ CPPUNIT_ASSERT(::comphelper::getBOOL(xPS->getPropertyValue(aPropName)));
+ const sal_Int64 nWidthAfter = ::comphelper::getINT64(xPS->getPropertyValue("Width"));
+ CPPUNIT_ASSERT(nWidthBefore != nWidthAfter);
+
+ aPropName = "IsVisible";
+ testBooleanProperty(xPS, aPropName);
+
+ aPropName = "IsStartOfNewPage";
+ testBooleanProperty(xPS, aPropName);
+}
+
+} // namespace apitest
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/test/source/table/tablerow.cxx b/test/source/table/tablerow.cxx
new file mode 100644
index 0000000000..2d14c16253
--- /dev/null
+++ b/test/source/table/tablerow.cxx
@@ -0,0 +1,40 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * 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 <test/table/tablerow.hxx>
+#include <test/unoapi_property_testers.hxx>
+
+#include <com/sun/star/beans/XPropertySet.hpp>
+
+using namespace css;
+
+namespace apitest
+{
+void TableRow::testTableRowProperties()
+{
+ uno::Reference<beans::XPropertySet> xPS(init(), uno::UNO_QUERY_THROW);
+
+ OUString aPropName;
+
+ aPropName = "Height";
+ testLongProperty(xPS, aPropName);
+
+ aPropName = "OptimalHeight";
+ testBooleanProperty(xPS, aPropName);
+
+ aPropName = "IsVisible";
+ testBooleanProperty(xPS, aPropName);
+
+ aPropName = "IsStartOfNewPage";
+ testBooleanProperty(xPS, aPropName);
+}
+
+} // namespace apitest
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/test/source/table/xcell.cxx b/test/source/table/xcell.cxx
new file mode 100644
index 0000000000..8540117a56
--- /dev/null
+++ b/test/source/table/xcell.cxx
@@ -0,0 +1,79 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+* 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 <test/table/xcell.hxx>
+
+#include <com/sun/star/table/XCell.hpp>
+#include <com/sun/star/table/CellContentType.hpp>
+
+#include <com/sun/star/uno/Reference.hxx>
+
+#include <cppunit/TestAssert.h>
+
+using namespace com::sun::star;
+using namespace com::sun::star::uno;
+
+namespace apitest
+{
+void XCell::testGetError()
+{
+ uno::Reference<table::XCell> xCell(init(), UNO_QUERY_THROW);
+ const sal_Int32 nCorrectFormula = xCell->getError();
+ xCell->setFormula("=sqrt(-2)");
+ const sal_Int32 nIncorrectFormula = xCell->getError();
+
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Successfully able to get Error", sal_Int32(0), nCorrectFormula);
+ CPPUNIT_ASSERT_MESSAGE("Successfully able to get Error", (nIncorrectFormula != 0));
+}
+
+void XCell::testGetType()
+{
+ uno::Reference<table::XCell> xCell(init(), UNO_QUERY_THROW);
+ bool aResult = true;
+
+ if (xCell->getType() == table::CellContentType_EMPTY)
+ aResult &= true;
+ else if (xCell->getType() == table::CellContentType_VALUE)
+ aResult &= true;
+ else if (xCell->getType() == table::CellContentType_TEXT)
+ aResult &= true;
+ else if (xCell->getType() == table::CellContentType_FORMULA)
+ aResult &= true;
+ else
+ aResult = false;
+
+ CPPUNIT_ASSERT_MESSAGE("Successfully able to get Type", aResult);
+}
+
+void XCell::testSetGetFormula()
+{
+ uno::Reference<table::XCell> xCell(init(), UNO_QUERY_THROW);
+ OUString aFormula = "=2+2";
+
+ xCell->setFormula(aFormula);
+
+ OUString aFormula2 = xCell->getFormula();
+
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Successfully able to set and get Formula", aFormula, aFormula2);
+}
+
+void XCell::testSetGetValue()
+{
+ uno::Reference<table::XCell> xCell(init(), UNO_QUERY_THROW);
+ double nInValue = 222.555;
+
+ xCell->setValue(nInValue);
+
+ double nCellValue = xCell->getValue();
+
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Successfully able to set and get Value", nInValue, nCellValue);
+}
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/test/source/table/xcellcursor.cxx b/test/source/table/xcellcursor.cxx
new file mode 100644
index 0000000000..6f6cc33e0c
--- /dev/null
+++ b/test/source/table/xcellcursor.cxx
@@ -0,0 +1,126 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+* 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 <test/table/xcellcursor.hxx>
+
+#include <com/sun/star/sheet/XCellRangeAddressable.hpp>
+#include <com/sun/star/sheet/XSheetCellCursor.hpp>
+#include <com/sun/star/sheet/XSheetCellRange.hpp>
+#include <com/sun/star/sheet/XSpreadsheet.hpp>
+#include <com/sun/star/table/CellRangeAddress.hpp>
+#include <com/sun/star/table/XCellCursor.hpp>
+#include <com/sun/star/table/XCellRange.hpp>
+
+#include <com/sun/star/uno/Reference.hxx>
+
+#include <cppunit/TestAssert.h>
+
+using namespace com::sun::star;
+using namespace com::sun::star::uno;
+
+namespace apitest
+{
+void XCellCursor::testGoToNext()
+{
+ uno::Reference<table::XCellCursor> xCellCursor(init(), UNO_QUERY_THROW);
+
+ uno::Reference<sheet::XCellRangeAddressable> xCellRangeAddressable(xCellCursor,
+ UNO_QUERY_THROW);
+ table::CellRangeAddress aCellRangeAddr = xCellRangeAddressable->getRangeAddress();
+ const sal_Int32 startCol = aCellRangeAddr.StartColumn;
+
+ xCellCursor->gotoNext();
+
+ aCellRangeAddr = xCellRangeAddressable->getRangeAddress();
+ const sal_Int32 startCol2 = aCellRangeAddr.StartColumn;
+
+ CPPUNIT_ASSERT_MESSAGE("Successfully able to go to Next", startCol != startCol2);
+}
+
+void XCellCursor::testGoToOffset()
+{
+ uno::Reference<table::XCellCursor> xCellCursor(init(), UNO_QUERY_THROW);
+
+ uno::Reference<sheet::XCellRangeAddressable> xCellRangeAddressable(xCellCursor,
+ UNO_QUERY_THROW);
+ table::CellRangeAddress aCellRangeAddr = xCellRangeAddressable->getRangeAddress();
+ const sal_Int32 startRow = aCellRangeAddr.StartRow;
+ const sal_Int32 startCol = aCellRangeAddr.StartColumn;
+
+ xCellCursor->gotoOffset(4, 4);
+
+ aCellRangeAddr = xCellRangeAddressable->getRangeAddress();
+ const sal_Int32 startRow2 = aCellRangeAddr.StartRow;
+ const sal_Int32 startCol2 = aCellRangeAddr.StartColumn;
+
+ CPPUNIT_ASSERT_MESSAGE("Successfully able to go to Offset",
+ (startCol != startCol2) || (startRow == startRow2));
+}
+
+void XCellCursor::testGoToPrevious()
+{
+ uno::Reference<table::XCellCursor> xCellCursor(init(), UNO_QUERY_THROW);
+
+ uno::Reference<sheet::XCellRangeAddressable> xCellRangeAddressable(xCellCursor,
+ UNO_QUERY_THROW);
+ xCellCursor->gotoOffset(4, 4);
+
+ table::CellRangeAddress aCellRangeAddr = xCellRangeAddressable->getRangeAddress();
+ const sal_Int32 startCol = aCellRangeAddr.StartColumn;
+
+ xCellCursor->gotoPrevious();
+
+ aCellRangeAddr = xCellRangeAddressable->getRangeAddress();
+ const sal_Int32 startCol2 = aCellRangeAddr.StartColumn;
+ CPPUNIT_ASSERT_MESSAGE("Successfully able to go to Previous", startCol != startCol2);
+}
+
+void XCellCursor::testGoToStart()
+{
+ uno::Reference<table::XCellCursor> xCellCursor(init(), UNO_QUERY_THROW);
+
+ uno::Reference<sheet::XCellRangeAddressable> xCellRangeAddressable(xCellCursor,
+ UNO_QUERY_THROW);
+ xCellCursor->gotoStart();
+
+ table::CellRangeAddress aCellRangeAddr = xCellRangeAddressable->getRangeAddress();
+
+ const sal_Int32 startRow = aCellRangeAddr.StartRow;
+ const sal_Int32 startCol = aCellRangeAddr.StartColumn;
+ const sal_Int32 endRow = aCellRangeAddr.EndRow;
+ const sal_Int32 endCol = aCellRangeAddr.EndColumn;
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Successfully able to go to Start", startCol, endCol);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Successfully able to go to Start", endRow, startRow);
+}
+
+void XCellCursor::testGoToEnd()
+{
+ uno::Reference<table::XCellCursor> xCellCursor(init(), UNO_QUERY_THROW);
+ uno::Reference<sheet::XSpreadsheet> xSpreadsheet(getXSpreadsheet(), UNO_QUERY_THROW);
+ uno::Reference<table::XCellRange> xCellRange(xCellCursor, UNO_QUERY_THROW);
+ xCellRange = xSpreadsheet->getCellRangeByName("$A$1:$g$7");
+ uno::Reference<sheet::XSheetCellRange> xSheetCellRange(xCellCursor, UNO_QUERY_THROW);
+ uno::Reference<sheet::XSheetCellCursor> xSheetCellCursor(xCellCursor, UNO_QUERY_THROW);
+ xSheetCellCursor = xSpreadsheet->createCursorByRange(xSheetCellRange);
+ uno::Reference<sheet::XCellRangeAddressable> xCellRangeAddressable(xCellCursor,
+ UNO_QUERY_THROW);
+
+ xCellCursor->gotoEnd();
+
+ table::CellRangeAddress aCellRangeAddr = xCellRangeAddressable->getRangeAddress();
+ const sal_Int32 startRow = aCellRangeAddr.StartRow;
+ const sal_Int32 startCol = aCellRangeAddr.StartColumn;
+ const sal_Int32 endRow = aCellRangeAddr.EndRow;
+ const sal_Int32 endCol = aCellRangeAddr.EndColumn;
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Successfully able to go to End", startCol, endCol);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Successfully able to go to End", endRow, startRow);
+}
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/test/source/table/xcellrange.cxx b/test/source/table/xcellrange.cxx
new file mode 100644
index 0000000000..392904078d
--- /dev/null
+++ b/test/source/table/xcellrange.cxx
@@ -0,0 +1,56 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * 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 <test/table/xcellrange.hxx>
+
+#include <com/sun/star/lang/IndexOutOfBoundsException.hpp>
+#include <com/sun/star/table/XCell.hpp>
+#include <com/sun/star/table/XCellRange.hpp>
+
+#include <com/sun/star/uno/Reference.hxx>
+
+#include <cppunit/TestAssert.h>
+
+using namespace css;
+
+namespace apitest
+{
+void XCellRange::testGetCellByPosition()
+{
+ uno::Reference<table::XCellRange> xCR(init(), uno::UNO_QUERY_THROW);
+
+ uno::Reference<table::XCell> xCell(xCR->getCellByPosition(0, 0), uno::UNO_SET_THROW);
+ CPPUNIT_ASSERT(xCell.is());
+
+ CPPUNIT_ASSERT_THROW(xCR->getCellByPosition(-1, 1), lang::IndexOutOfBoundsException);
+}
+
+void XCellRange::testGetCellRangeByName()
+{
+ uno::Reference<table::XCellRange> xCR(init(), uno::UNO_QUERY_THROW);
+
+ uno::Reference<table::XCellRange> xCellRange(xCR->getCellRangeByName(m_aRangeName),
+ uno::UNO_SET_THROW);
+ CPPUNIT_ASSERT(xCellRange.is());
+}
+
+void XCellRange::testGetCellRangeByPosition()
+{
+ uno::Reference<table::XCellRange> xCR(init(), uno::UNO_QUERY_THROW);
+
+ uno::Reference<table::XCellRange> xCellRange(xCR->getCellRangeByPosition(0, 0, 0, 0),
+ uno::UNO_SET_THROW);
+ CPPUNIT_ASSERT(xCellRange.is());
+
+ CPPUNIT_ASSERT_THROW(xCR->getCellRangeByPosition(-1, 0, -1, 1),
+ lang::IndexOutOfBoundsException);
+}
+} // namespace apitest
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/test/source/table/xcolumnrowrange.cxx b/test/source/table/xcolumnrowrange.cxx
new file mode 100644
index 0000000000..748a4825d1
--- /dev/null
+++ b/test/source/table/xcolumnrowrange.cxx
@@ -0,0 +1,36 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+* 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 <test/table/xcolumnrowrange.hxx>
+
+#include <com/sun/star/table/XColumnRowRange.hpp>
+
+#include <com/sun/star/uno/Reference.hxx>
+
+#include <cppunit/TestAssert.h>
+
+using namespace com::sun::star;
+using namespace com::sun::star::uno;
+
+namespace apitest
+{
+void XColumnRowRange::testGetColumns()
+{
+ uno::Reference<table::XColumnRowRange> xColumnRowRange(init(), UNO_QUERY_THROW);
+ CPPUNIT_ASSERT(xColumnRowRange->getColumns());
+}
+
+void XColumnRowRange::testGetRows()
+{
+ uno::Reference<table::XColumnRowRange> xColumnRowRange(init(), UNO_QUERY_THROW);
+ CPPUNIT_ASSERT(xColumnRowRange->getRows());
+}
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/test/source/table/xtablechart.cxx b/test/source/table/xtablechart.cxx
new file mode 100644
index 0000000000..38a43eee67
--- /dev/null
+++ b/test/source/table/xtablechart.cxx
@@ -0,0 +1,60 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * 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 <test/table/xtablechart.hxx>
+#include <test/cppunitasserthelper.hxx>
+
+#include <com/sun/star/table/CellRangeAddress.hpp>
+#include <com/sun/star/table/XTableChart.hpp>
+
+#include <com/sun/star/uno/Reference.hxx>
+#include <com/sun/star/uno/Sequence.hxx>
+
+#include <cppunit/TestAssert.h>
+
+using namespace css;
+
+namespace apitest
+{
+void XTableChart::testGetSetHasColumnHeaders()
+{
+ uno::Reference<table::XTableChart> xTC(init(), uno::UNO_QUERY_THROW);
+
+ xTC->setHasColumnHeaders(false);
+ CPPUNIT_ASSERT(!xTC->getHasColumnHeaders());
+
+ xTC->setHasColumnHeaders(true);
+ CPPUNIT_ASSERT(xTC->getHasColumnHeaders());
+}
+
+void XTableChart::testGetSetHasRowHeaders()
+{
+ uno::Reference<table::XTableChart> xTC(init(), uno::UNO_QUERY_THROW);
+
+ xTC->setHasRowHeaders(false);
+ CPPUNIT_ASSERT(!xTC->getHasRowHeaders());
+
+ xTC->setHasRowHeaders(true);
+ CPPUNIT_ASSERT(xTC->getHasRowHeaders());
+}
+
+void XTableChart::testGetSetRanges()
+{
+ uno::Reference<table::XTableChart> xTC(init(), uno::UNO_QUERY_THROW);
+
+ uno::Sequence<table::CellRangeAddress> aCRA = xTC->getRanges();
+ aCRA.getArray()[0].EndRow = 1;
+
+ xTC->setRanges(aCRA);
+
+ CPPUNIT_ASSERT_EQUAL(aCRA[0], xTC->getRanges()[0]);
+}
+
+} // namespace apitest
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/test/source/table/xtablecharts.cxx b/test/source/table/xtablecharts.cxx
new file mode 100644
index 0000000000..15aa710ffc
--- /dev/null
+++ b/test/source/table/xtablecharts.cxx
@@ -0,0 +1,39 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * 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 <test/table/xtablecharts.hxx>
+
+#include <com/sun/star/awt/Rectangle.hpp>
+#include <com/sun/star/table/CellRangeAddress.hpp>
+#include <com/sun/star/table/XTableCharts.hpp>
+
+#include <com/sun/star/uno/Reference.hxx>
+#include <com/sun/star/uno/Sequence.hxx>
+
+#include <cppunit/TestAssert.h>
+
+using namespace css;
+
+namespace apitest
+{
+void XTableCharts::testAddNewRemoveByName()
+{
+ uno::Reference<table::XTableCharts> xTC(init(), uno::UNO_QUERY_THROW);
+
+ uno::Sequence<table::CellRangeAddress> aRanges{ table::CellRangeAddress(0, 1, 1, 14, 4) };
+ xTC->addNewByName("XTableCharts", awt::Rectangle(500, 3000, 25000, 11000), aRanges, true, true);
+ CPPUNIT_ASSERT(xTC->hasByName("XTableCharts"));
+
+ xTC->removeByName("XTableCharts");
+ CPPUNIT_ASSERT(!xTC->hasByName("XTableCharts"));
+}
+
+} // namespace apitest
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/test/source/table/xtablechartssupplier.cxx b/test/source/table/xtablechartssupplier.cxx
new file mode 100644
index 0000000000..047695dfce
--- /dev/null
+++ b/test/source/table/xtablechartssupplier.cxx
@@ -0,0 +1,31 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+* 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 <test/table/xtablechartssupplier.hxx>
+
+#include <com/sun/star/table/XTableChartsSupplier.hpp>
+
+#include <com/sun/star/uno/Reference.hxx>
+
+#include <cppunit/TestAssert.h>
+
+using namespace com::sun::star;
+using namespace com::sun::star::uno;
+
+namespace apitest
+{
+void XTableChartsSupplier::testGetCharts()
+{
+ uno::Reference<table::XTableChartsSupplier> xTableChartsSupplier(init(), UNO_QUERY_THROW);
+
+ CPPUNIT_ASSERT_MESSAGE("Successfully able to Get Charts", xTableChartsSupplier->getCharts());
+}
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/test/source/table/xtablecolumns.cxx b/test/source/table/xtablecolumns.cxx
new file mode 100644
index 0000000000..0d72a8dd19
--- /dev/null
+++ b/test/source/table/xtablecolumns.cxx
@@ -0,0 +1,173 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * 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 <test/table/xtablecolumns.hxx>
+
+#include <com/sun/star/table/XCellRange.hpp>
+#include <com/sun/star/table/XTableColumns.hpp>
+#include <com/sun/star/text/XSimpleText.hpp>
+#include <com/sun/star/uno/RuntimeException.hpp>
+
+#include <com/sun/star/uno/Reference.hxx>
+
+#include <cppunit/TestAssert.h>
+
+using namespace css;
+
+namespace apitest
+{
+void XTableColumns::testInsertByIndex()
+{
+ uno::Reference<table::XTableColumns> xTC(init(), uno::UNO_QUERY_THROW);
+ uno::Reference<table::XCellRange> xCR(m_xSheet, uno::UNO_QUERY_THROW);
+
+ // insert one column at position one
+ xTC->insertByIndex(1, 1);
+ CPPUNIT_ASSERT_EQUAL(OUString("0a"), getCellText(xCR->getCellByPosition(0, 0)));
+ CPPUNIT_ASSERT_EQUAL(OUString("0b"), getCellText(xCR->getCellByPosition(0, 1)));
+ CPPUNIT_ASSERT_EQUAL(OUString(""), getCellText(xCR->getCellByPosition(1, 0)));
+ CPPUNIT_ASSERT_EQUAL(OUString(""), getCellText(xCR->getCellByPosition(1, 1)));
+ CPPUNIT_ASSERT_EQUAL(OUString("1a"), getCellText(xCR->getCellByPosition(2, 0)));
+ CPPUNIT_ASSERT_EQUAL(OUString("1b"), getCellText(xCR->getCellByPosition(2, 1)));
+ CPPUNIT_ASSERT_EQUAL(OUString("2a"), getCellText(xCR->getCellByPosition(3, 0)));
+ CPPUNIT_ASSERT_EQUAL(OUString("2b"), getCellText(xCR->getCellByPosition(3, 1)));
+ CPPUNIT_ASSERT_EQUAL(OUString(""), getCellText(xCR->getCellByPosition(4, 0)));
+ CPPUNIT_ASSERT_EQUAL(OUString(""), getCellText(xCR->getCellByPosition(4, 1)));
+
+ // insert one column at position zero
+ xTC->insertByIndex(0, 1);
+ CPPUNIT_ASSERT_EQUAL(OUString(""), getCellText(xCR->getCellByPosition(0, 0)));
+ CPPUNIT_ASSERT_EQUAL(OUString(""), getCellText(xCR->getCellByPosition(0, 1)));
+ CPPUNIT_ASSERT_EQUAL(OUString("0a"), getCellText(xCR->getCellByPosition(1, 0)));
+ CPPUNIT_ASSERT_EQUAL(OUString("0b"), getCellText(xCR->getCellByPosition(1, 1)));
+ CPPUNIT_ASSERT_EQUAL(OUString(""), getCellText(xCR->getCellByPosition(2, 0)));
+ CPPUNIT_ASSERT_EQUAL(OUString(""), getCellText(xCR->getCellByPosition(2, 1)));
+ CPPUNIT_ASSERT_EQUAL(OUString("1a"), getCellText(xCR->getCellByPosition(3, 0)));
+ CPPUNIT_ASSERT_EQUAL(OUString("1b"), getCellText(xCR->getCellByPosition(3, 1)));
+ CPPUNIT_ASSERT_EQUAL(OUString("2a"), getCellText(xCR->getCellByPosition(4, 0)));
+ CPPUNIT_ASSERT_EQUAL(OUString("2b"), getCellText(xCR->getCellByPosition(4, 1)));
+ CPPUNIT_ASSERT_EQUAL(OUString(""), getCellText(xCR->getCellByPosition(5, 0)));
+ CPPUNIT_ASSERT_EQUAL(OUString(""), getCellText(xCR->getCellByPosition(5, 1)));
+
+ // insert two columns at position zero
+ xTC->insertByIndex(0, 2);
+ CPPUNIT_ASSERT_EQUAL(OUString(""), getCellText(xCR->getCellByPosition(0, 0)));
+ CPPUNIT_ASSERT_EQUAL(OUString(""), getCellText(xCR->getCellByPosition(0, 1)));
+ CPPUNIT_ASSERT_EQUAL(OUString(""), getCellText(xCR->getCellByPosition(1, 0)));
+ CPPUNIT_ASSERT_EQUAL(OUString(""), getCellText(xCR->getCellByPosition(1, 1)));
+ CPPUNIT_ASSERT_EQUAL(OUString(""), getCellText(xCR->getCellByPosition(2, 0)));
+ CPPUNIT_ASSERT_EQUAL(OUString(""), getCellText(xCR->getCellByPosition(2, 1)));
+ CPPUNIT_ASSERT_EQUAL(OUString("0a"), getCellText(xCR->getCellByPosition(3, 0)));
+ CPPUNIT_ASSERT_EQUAL(OUString("0b"), getCellText(xCR->getCellByPosition(3, 1)));
+ CPPUNIT_ASSERT_EQUAL(OUString(""), getCellText(xCR->getCellByPosition(4, 0)));
+ CPPUNIT_ASSERT_EQUAL(OUString(""), getCellText(xCR->getCellByPosition(4, 1)));
+ CPPUNIT_ASSERT_EQUAL(OUString("1a"), getCellText(xCR->getCellByPosition(5, 0)));
+ CPPUNIT_ASSERT_EQUAL(OUString("1b"), getCellText(xCR->getCellByPosition(5, 1)));
+ CPPUNIT_ASSERT_EQUAL(OUString("2a"), getCellText(xCR->getCellByPosition(6, 0)));
+ CPPUNIT_ASSERT_EQUAL(OUString("2b"), getCellText(xCR->getCellByPosition(6, 1)));
+ CPPUNIT_ASSERT_EQUAL(OUString(""), getCellText(xCR->getCellByPosition(7, 0)));
+ CPPUNIT_ASSERT_EQUAL(OUString(""), getCellText(xCR->getCellByPosition(7, 1)));
+}
+
+void XTableColumns::testInsertByIndexWithNegativeIndex()
+{
+ uno::Reference<table::XTableColumns> xTC(init(), uno::UNO_QUERY_THROW);
+ CPPUNIT_ASSERT_THROW(xTC->insertByIndex(-1, 1), uno::RuntimeException);
+}
+
+void XTableColumns::testInsertByIndexWithNoColumn()
+{
+ uno::Reference<table::XTableColumns> xTC(init(), uno::UNO_QUERY_THROW);
+ CPPUNIT_ASSERT_THROW(xTC->insertByIndex(0, 0), uno::RuntimeException);
+}
+
+void XTableColumns::testInsertByIndexWithOutOfBoundIndex()
+{
+ uno::Reference<table::XTableColumns> xTC(init(), uno::UNO_QUERY_THROW);
+
+ CPPUNIT_ASSERT_THROW(xTC->insertByIndex(xTC->getCount(), 1), uno::RuntimeException);
+}
+
+void XTableColumns::testRemoveByIndex()
+{
+ uno::Reference<table::XTableColumns> xTC(init(), uno::UNO_QUERY_THROW);
+ uno::Reference<table::XCellRange> xCR(m_xSheet, uno::UNO_QUERY_THROW);
+
+ xTC->insertByIndex(1, 1); // insert one column at position one
+ xTC->insertByIndex(0, 1); // insert one column at position zero
+ xTC->insertByIndex(0, 2); // insert two columns at position zero
+
+ // remove two columns at position zero
+ xTC->removeByIndex(0, 2);
+ CPPUNIT_ASSERT_EQUAL(OUString(""), getCellText(xCR->getCellByPosition(0, 0)));
+ CPPUNIT_ASSERT_EQUAL(OUString(""), getCellText(xCR->getCellByPosition(0, 1)));
+ CPPUNIT_ASSERT_EQUAL(OUString("0a"), getCellText(xCR->getCellByPosition(1, 0)));
+ CPPUNIT_ASSERT_EQUAL(OUString("0b"), getCellText(xCR->getCellByPosition(1, 1)));
+ CPPUNIT_ASSERT_EQUAL(OUString(""), getCellText(xCR->getCellByPosition(2, 0)));
+ CPPUNIT_ASSERT_EQUAL(OUString(""), getCellText(xCR->getCellByPosition(2, 1)));
+ CPPUNIT_ASSERT_EQUAL(OUString("1a"), getCellText(xCR->getCellByPosition(3, 0)));
+ CPPUNIT_ASSERT_EQUAL(OUString("1b"), getCellText(xCR->getCellByPosition(3, 1)));
+ CPPUNIT_ASSERT_EQUAL(OUString("2a"), getCellText(xCR->getCellByPosition(4, 0)));
+ CPPUNIT_ASSERT_EQUAL(OUString("2b"), getCellText(xCR->getCellByPosition(4, 1)));
+ CPPUNIT_ASSERT_EQUAL(OUString(""), getCellText(xCR->getCellByPosition(5, 0)));
+ CPPUNIT_ASSERT_EQUAL(OUString(""), getCellText(xCR->getCellByPosition(5, 1)));
+
+ // remove one column at position zero
+ xTC->removeByIndex(0, 1);
+ CPPUNIT_ASSERT_EQUAL(OUString("0a"), getCellText(xCR->getCellByPosition(0, 0)));
+ CPPUNIT_ASSERT_EQUAL(OUString("0b"), getCellText(xCR->getCellByPosition(0, 1)));
+ CPPUNIT_ASSERT_EQUAL(OUString(""), getCellText(xCR->getCellByPosition(1, 0)));
+ CPPUNIT_ASSERT_EQUAL(OUString(""), getCellText(xCR->getCellByPosition(1, 1)));
+ CPPUNIT_ASSERT_EQUAL(OUString("1a"), getCellText(xCR->getCellByPosition(2, 0)));
+ CPPUNIT_ASSERT_EQUAL(OUString("1b"), getCellText(xCR->getCellByPosition(2, 1)));
+ CPPUNIT_ASSERT_EQUAL(OUString("2a"), getCellText(xCR->getCellByPosition(3, 0)));
+ CPPUNIT_ASSERT_EQUAL(OUString("2b"), getCellText(xCR->getCellByPosition(3, 1)));
+ CPPUNIT_ASSERT_EQUAL(OUString(""), getCellText(xCR->getCellByPosition(4, 0)));
+ CPPUNIT_ASSERT_EQUAL(OUString(""), getCellText(xCR->getCellByPosition(4, 1)));
+
+ // remove one column at position one
+ xTC->removeByIndex(1, 1);
+ CPPUNIT_ASSERT_EQUAL(OUString("0a"), getCellText(xCR->getCellByPosition(0, 0)));
+ CPPUNIT_ASSERT_EQUAL(OUString("0b"), getCellText(xCR->getCellByPosition(0, 1)));
+ CPPUNIT_ASSERT_EQUAL(OUString("1a"), getCellText(xCR->getCellByPosition(1, 0)));
+ CPPUNIT_ASSERT_EQUAL(OUString("1b"), getCellText(xCR->getCellByPosition(1, 1)));
+ CPPUNIT_ASSERT_EQUAL(OUString("2a"), getCellText(xCR->getCellByPosition(2, 0)));
+ CPPUNIT_ASSERT_EQUAL(OUString("2b"), getCellText(xCR->getCellByPosition(2, 1)));
+ CPPUNIT_ASSERT_EQUAL(OUString(""), getCellText(xCR->getCellByPosition(3, 0)));
+ CPPUNIT_ASSERT_EQUAL(OUString(""), getCellText(xCR->getCellByPosition(3, 1)));
+}
+
+void XTableColumns::testRemoveByIndexWithNegativeIndex()
+{
+ uno::Reference<table::XTableColumns> xTC(init(), uno::UNO_QUERY_THROW);
+ CPPUNIT_ASSERT_THROW(xTC->removeByIndex(-1, 1), uno::RuntimeException);
+}
+
+void XTableColumns::testRemoveByIndexWithNoColumn()
+{
+ uno::Reference<table::XTableColumns> xTC(init(), uno::UNO_QUERY_THROW);
+ CPPUNIT_ASSERT_THROW(xTC->removeByIndex(0, 0), uno::RuntimeException);
+}
+
+void XTableColumns::testRemoveByIndexWithOutOfBoundIndex()
+{
+ uno::Reference<table::XTableColumns> xTC(init(), uno::UNO_QUERY_THROW);
+
+ CPPUNIT_ASSERT_THROW(xTC->removeByIndex(xTC->getCount(), 1), uno::RuntimeException);
+}
+
+OUString XTableColumns::getCellText(const uno::Reference<table::XCell>& r_xCell)
+{
+ uno::Reference<text::XSimpleText> xST(r_xCell, uno::UNO_QUERY_THROW);
+ return xST->getString();
+}
+
+} // namespace apitest
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/test/source/table/xtablerows.cxx b/test/source/table/xtablerows.cxx
new file mode 100644
index 0000000000..f44a6fcbce
--- /dev/null
+++ b/test/source/table/xtablerows.cxx
@@ -0,0 +1,55 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * 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 <test/table/xtablerows.hxx>
+
+#include <com/sun/star/table/XCellRange.hpp>
+#include <com/sun/star/table/XTableRows.hpp>
+#include <com/sun/star/uno/RuntimeException.hpp>
+
+#include <com/sun/star/uno/Reference.hxx>
+
+#include <cppunit/TestAssert.h>
+
+using namespace css;
+using namespace css::uno;
+
+namespace apitest
+{
+void XTableRows::testInsertByIndex()
+{
+ uno::Reference<table::XCellRange> xCellRange(getXCellRange(), uno::UNO_QUERY_THROW);
+ xCellRange->getCellByPosition(0, 0)->setValue(17);
+ xCellRange->getCellByPosition(0, 1)->setValue(15);
+
+ uno::Reference<table::XTableRows> xTableRows(init(), uno::UNO_QUERY_THROW);
+ xTableRows->removeByIndex(0, 1);
+
+ xTableRows->insertByIndex(0, 1);
+ CPPUNIT_ASSERT_DOUBLES_EQUAL(15.0, xCellRange->getCellByPosition(0, 1)->getValue(), 0.1);
+
+ CPPUNIT_ASSERT_THROW(xTableRows->insertByIndex(-1, 1), uno::RuntimeException);
+}
+
+void XTableRows::testRemoveByIndex()
+{
+ uno::Reference<table::XCellRange> xCellRange(getXCellRange(), uno::UNO_QUERY_THROW);
+ xCellRange->getCellByPosition(0, 0)->setValue(17);
+ xCellRange->getCellByPosition(0, 1)->setValue(15);
+
+ uno::Reference<table::XTableRows> xTableRows(init(), uno::UNO_QUERY_THROW);
+ xTableRows->removeByIndex(0, 1);
+ CPPUNIT_ASSERT_DOUBLES_EQUAL(15.0, xCellRange->getCellByPosition(0, 0)->getValue(), 0.1);
+
+ CPPUNIT_ASSERT_THROW(xTableRows->removeByIndex(-1, 1), uno::RuntimeException);
+}
+
+} // namespace apitest
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/test/source/text/baseindex.cxx b/test/source/text/baseindex.cxx
new file mode 100644
index 0000000000..172cabb579
--- /dev/null
+++ b/test/source/text/baseindex.cxx
@@ -0,0 +1,151 @@
+/* -*- 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 <cppunit/TestAssert.h>
+
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/graphic/XGraphic.hpp>
+#include <com/sun/star/text/XTextColumns.hpp>
+#include <com/sun/star/text/XTextSection.hpp>
+
+#include <vcl/BitmapTools.hxx>
+#include <vcl/filter/PngImageWriter.hxx>
+#include <unotools/tempfile.hxx>
+#include <tools/stream.hxx>
+
+#include <test/unoapi_property_testers.hxx>
+#include <test/text/baseindex.hxx>
+
+namespace
+{
+BitmapEx createExampleBitmap()
+{
+ vcl::bitmap::RawBitmap aRawBitmap(Size(4, 4), 24);
+ aRawBitmap.SetPixel(0, 0, COL_LIGHTBLUE);
+ aRawBitmap.SetPixel(0, 1, COL_LIGHTGREEN);
+ aRawBitmap.SetPixel(1, 0, COL_LIGHTRED);
+ aRawBitmap.SetPixel(1, 1, COL_LIGHTMAGENTA);
+ return vcl::bitmap::CreateFromData(std::move(aRawBitmap));
+}
+
+void writerFileWithBitmap(OUString const& rURL)
+{
+ BitmapEx aBitmapEx = createExampleBitmap();
+ SvFileStream aFileStream(rURL, StreamMode::READ | StreamMode::WRITE);
+ vcl::PngImageWriter aWriter(aFileStream);
+ aWriter.write(aBitmapEx);
+ aFileStream.Seek(STREAM_SEEK_TO_BEGIN);
+ aFileStream.Close();
+}
+}
+
+namespace apitest
+{
+BaseIndex::~BaseIndex() {}
+
+void BaseIndex::testBaseIndexProperties()
+{
+ css::uno::Reference<css::beans::XPropertySet> xBaseIndex(init(), css::uno::UNO_QUERY_THROW);
+ testStringProperty(xBaseIndex, "Title", "Value");
+ testBooleanProperty(xBaseIndex, "IsProtected");
+
+ testStringProperty(xBaseIndex, "ParaStyleHeading", "Value");
+ testStringProperty(xBaseIndex, "ParaStyleLevel1", "Value");
+ testStringOptionalProperty(xBaseIndex, "ParaStyleLevel2");
+ testStringOptionalProperty(xBaseIndex, "ParaStyleLevel3");
+ testStringOptionalProperty(xBaseIndex, "ParaStyleLevel4");
+ testStringOptionalProperty(xBaseIndex, "ParaStyleLevel5");
+ testStringOptionalProperty(xBaseIndex, "ParaStyleLevel6");
+ testStringOptionalProperty(xBaseIndex, "ParaStyleLevel7");
+ testStringOptionalProperty(xBaseIndex, "ParaStyleLevel8");
+ testStringOptionalProperty(xBaseIndex, "ParaStyleLevel9");
+ testStringOptionalProperty(xBaseIndex, "ParaStyleLevel10");
+ testStringOptionalProperty(xBaseIndex, "ParaStyleSeparator");
+
+ // [property] XTextColumns TextColumns;
+ {
+ OUString name = "TextColumns";
+
+ css::uno::Reference<css::text::XTextColumns> xGetTextColumns;
+ CPPUNIT_ASSERT(xBaseIndex->getPropertyValue(name) >>= xGetTextColumns);
+
+ xGetTextColumns->setColumnCount(xGetTextColumns->getColumnCount() + 1);
+ xBaseIndex->setPropertyValue(name, css::uno::Any(xGetTextColumns));
+
+ css::uno::Reference<css::text::XTextColumns> xSetTextColumns;
+ CPPUNIT_ASSERT(xBaseIndex->getPropertyValue(name) >>= xSetTextColumns);
+
+ //CPPUNIT_ASSERT_EQUAL(xGetTextColumns->getColumnCount(), xSetTextColumns->getColumnCount());
+ }
+
+ // [property] com::sun::star::graphic::XGraphic BackGraphic;
+ // [property] string BackGraphicURL;
+ {
+ OUString name = "BackGraphicURL";
+ bool bOK = false;
+ try
+ {
+ xBaseIndex->getPropertyValue(name);
+ }
+ catch (css::uno::RuntimeException const& /*ex*/)
+ {
+ bOK = true;
+ }
+ // BackGraphicURL is "set-only" attribute
+ CPPUNIT_ASSERT_MESSAGE("Expected RuntimeException wasn't thrown", bOK);
+
+ utl::TempFileNamed aTempFile;
+ aTempFile.EnableKillingFile();
+ writerFileWithBitmap(aTempFile.GetURL());
+
+ css::uno::Reference<css::graphic::XGraphic> xGraphic;
+ CPPUNIT_ASSERT(xBaseIndex->getPropertyValue("BackGraphic") >>= xGraphic);
+ CPPUNIT_ASSERT(!xGraphic.is());
+
+ xBaseIndex->setPropertyValue(name, css::uno::Any(aTempFile.GetURL()));
+
+ CPPUNIT_ASSERT(xBaseIndex->getPropertyValue("BackGraphic") >>= xGraphic);
+ CPPUNIT_ASSERT(xGraphic.is());
+ }
+
+ testStringProperty(xBaseIndex, "BackGraphicFilter", "Value");
+
+ // [property] com::sun::star::style::GraphicLocation BackGraphicLocation;
+
+ testColorProperty(xBaseIndex, "BackColor");
+ testBooleanProperty(xBaseIndex, "BackTransparent");
+
+ // [optional, property] com::sun::star::container::XIndexReplace LevelFormat;
+
+ testBooleanOptionalProperty(xBaseIndex, "CreateFromChapter");
+
+ // [property] com::sun::star::text::XTextSection ContentSection;
+ {
+ OUString name = "ContentSection";
+
+ css::uno::Reference<css::text::XTextSection> xGetTextSection;
+ CPPUNIT_ASSERT_MESSAGE(name.toUtf8().getStr(),
+ xBaseIndex->getPropertyValue(name) >>= xGetTextSection);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(name.toUtf8().getStr(), OUString(""),
+ xGetTextSection->getAnchor()->getString());
+ }
+
+ // [property] com::sun::star::text::XTextSection HeaderSection;
+ {
+ OUString name = "HeaderSection";
+
+ css::uno::Reference<css::text::XTextSection> xGetTextSection;
+ if (xBaseIndex->getPropertyValue(name).hasValue())
+ CPPUNIT_ASSERT_MESSAGE(name.toUtf8().getStr(),
+ xBaseIndex->getPropertyValue(name) >>= xGetTextSection);
+ }
+}
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/test/source/text/baseindexmark.cxx b/test/source/text/baseindexmark.cxx
new file mode 100644
index 0000000000..755b55856c
--- /dev/null
+++ b/test/source/text/baseindexmark.cxx
@@ -0,0 +1,45 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * 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 <test/cppunitasserthelper.hxx>
+#include <test/text/baseindexmark.hxx>
+
+#include <com/sun/star/beans/XPropertySet.hpp>
+
+#include <com/sun/star/uno/Any.hxx>
+#include <com/sun/star/uno/Reference.hxx>
+
+#include <cppunit/TestAssert.h>
+
+using namespace com::sun::star;
+using namespace com::sun::star::uno;
+
+namespace apitest
+{
+void BaseIndexMark::testBaseIndexMarkProperties()
+{
+ Reference<beans::XPropertySet> xBaseIndexMark(init(), UNO_QUERY_THROW);
+ OUString propName;
+ uno::Any aNewValue;
+
+ propName = "AlternativeText";
+ OUString aAlternativeTextGet = "";
+ CPPUNIT_ASSERT_MESSAGE("Unable to get PropertyValue AlternativeText",
+ xBaseIndexMark->getPropertyValue(propName) >>= aAlternativeTextGet);
+
+ OUString aAlternativeTextSet = "testProperty";
+ aNewValue <<= aAlternativeTextSet;
+ xBaseIndexMark->setPropertyValue(propName, aNewValue);
+ CPPUNIT_ASSERT(xBaseIndexMark->getPropertyValue(propName) >>= aAlternativeTextGet);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Unable to set PropertyValue AlternativeText", aAlternativeTextGet,
+ aAlternativeTextSet);
+}
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/test/source/text/documentindexmark.cxx b/test/source/text/documentindexmark.cxx
new file mode 100644
index 0000000000..86c1cd9bc1
--- /dev/null
+++ b/test/source/text/documentindexmark.cxx
@@ -0,0 +1,69 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * 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 <test/cppunitasserthelper.hxx>
+#include <test/text/documentindexmark.hxx>
+
+#include <com/sun/star/beans/XPropertySet.hpp>
+
+#include <com/sun/star/uno/Any.hxx>
+#include <com/sun/star/uno/Reference.hxx>
+
+#include <cppunit/TestAssert.h>
+
+using namespace com::sun::star;
+using namespace com::sun::star::uno;
+
+namespace apitest
+{
+void DocumentIndexMark::testDocumentIndexMarkProperties()
+{
+ Reference<beans::XPropertySet> xDocumentIndexMark(init(), UNO_QUERY_THROW);
+ OUString propName;
+ uno::Any aNewValue;
+
+ propName = "PrimaryKey";
+ OUString aPrimaryKeyGet = "";
+ CPPUNIT_ASSERT_MESSAGE("Unable to get PropertyValue PrimaryKey",
+ xDocumentIndexMark->getPropertyValue(propName) >>= aPrimaryKeyGet);
+
+ OUString aPrimaryKeySet = "testPropertyPK";
+ aNewValue <<= aPrimaryKeySet;
+ xDocumentIndexMark->setPropertyValue(propName, aNewValue);
+ CPPUNIT_ASSERT(xDocumentIndexMark->getPropertyValue(propName) >>= aPrimaryKeyGet);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Unable to set PropertyValue PrimaryKey", aPrimaryKeyGet,
+ aPrimaryKeySet);
+
+ propName = "SecondaryKey";
+ OUString aSecondaryKeyGet = "";
+ CPPUNIT_ASSERT_MESSAGE("Unable to get PropertyValue SecondaryKey",
+ xDocumentIndexMark->getPropertyValue(propName) >>= aSecondaryKeyGet);
+
+ OUString aSecondaryKeySet = "testPropertySK";
+ aNewValue <<= aSecondaryKeySet;
+ xDocumentIndexMark->setPropertyValue(propName, aNewValue);
+ CPPUNIT_ASSERT(xDocumentIndexMark->getPropertyValue(propName) >>= aSecondaryKeyGet);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Unable to set PropertyValue SecondaryKey", aSecondaryKeyGet,
+ aSecondaryKeySet);
+
+ propName = "IsMainEntry";
+ bool bIsMainEntryGet = false;
+ bool bIsMainEntrySet = false;
+ CPPUNIT_ASSERT_MESSAGE("Unable to get PropertyValue IsMainEntry",
+ xDocumentIndexMark->getPropertyValue(propName) >>= bIsMainEntryGet);
+
+ aNewValue <<= !bIsMainEntryGet;
+ xDocumentIndexMark->setPropertyValue(propName, aNewValue);
+ CPPUNIT_ASSERT(xDocumentIndexMark->getPropertyValue(propName) >>= bIsMainEntrySet);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Unable to set PropertyValue IsMainEntry", !bIsMainEntryGet,
+ bIsMainEntrySet);
+}
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/test/source/text/footnote.cxx b/test/source/text/footnote.cxx
new file mode 100644
index 0000000000..9f484cfd30
--- /dev/null
+++ b/test/source/text/footnote.cxx
@@ -0,0 +1,31 @@
+/* -*- 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 <cppunit/TestAssert.h>
+
+#include <com/sun/star/beans/XPropertySet.hpp>
+
+#include <test/unoapi_property_testers.hxx>
+#include <test/text/footnote.hxx>
+
+namespace apitest
+{
+Footnote::~Footnote() {}
+
+void Footnote::testFootnoteProperties()
+{
+ css::uno::Reference<css::beans::XPropertySet> xFootnote(init(), css::uno::UNO_QUERY_THROW);
+
+ short aReferenceIdGet;
+ CPPUNIT_ASSERT_MESSAGE("Unable to get PropertyValue ReferenceId",
+ xFootnote->getPropertyValue("ReferenceId") >>= aReferenceIdGet);
+}
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/test/source/text/numberingrules.cxx b/test/source/text/numberingrules.cxx
new file mode 100644
index 0000000000..c549256505
--- /dev/null
+++ b/test/source/text/numberingrules.cxx
@@ -0,0 +1,77 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * 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 <test/cppunitasserthelper.hxx>
+#include <test/text/numberingrules.hxx>
+
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/table/CellAddress.hpp>
+#include <com/sun/star/table/TableOrientation.hpp>
+#include <com/sun/star/uno/Any.hxx>
+#include <com/sun/star/uno/Reference.hxx>
+
+#include <cppunit/TestAssert.h>
+
+using namespace com::sun::star;
+using namespace com::sun::star::uno;
+
+namespace apitest
+{
+void NumberingRules::testNumberingRulesProperties()
+{
+ Reference<beans::XPropertySet> xNumberingRules(init(), UNO_QUERY_THROW);
+ OUString propName;
+ uno::Any aNewValue;
+
+ propName = "IsAbsoluteMargins";
+ bool bIsAbsoluteMarginsGet = false;
+ bool bIsAbsoluteMarginsSet = false;
+ CPPUNIT_ASSERT_MESSAGE("Unable to get PropertyValue IsAbsoluteMargins",
+ xNumberingRules->getPropertyValue(propName) >>= bIsAbsoluteMarginsGet);
+
+ aNewValue <<= !bIsAbsoluteMarginsGet;
+ xNumberingRules->setPropertyValue(propName, aNewValue);
+ CPPUNIT_ASSERT(xNumberingRules->getPropertyValue(propName) >>= bIsAbsoluteMarginsSet);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Unable to set PropertyValue IsAbsoluteMargins",
+ !bIsAbsoluteMarginsGet, bIsAbsoluteMarginsSet);
+
+ propName = "IsAutomatic";
+ bool bIsAutomaticGet = false;
+ bool bIsAutomaticSet = false;
+ CPPUNIT_ASSERT_MESSAGE("Unable to get PropertyValue IsAutomatic",
+ xNumberingRules->getPropertyValue(propName) >>= bIsAutomaticGet);
+
+ bIsAutomaticGet = false;
+ aNewValue <<= !bIsAutomaticGet;
+ xNumberingRules->setPropertyValue(propName, aNewValue);
+ CPPUNIT_ASSERT(xNumberingRules->getPropertyValue(propName) >>= bIsAutomaticSet);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Unable to set PropertyValue IsAutomatic", !bIsAutomaticGet,
+ bIsAutomaticSet);
+
+ propName = "IsContinuousNumbering";
+ bool bIsContinuousNumberingGet = false;
+ bool bIsContinuousNumberingSet = false;
+ CPPUNIT_ASSERT_MESSAGE("Unable to get PropertyValue IsContinuousNumbering",
+ xNumberingRules->getPropertyValue(propName)
+ >>= bIsContinuousNumberingGet);
+
+ aNewValue <<= !bIsContinuousNumberingGet;
+ xNumberingRules->setPropertyValue(propName, aNewValue);
+ CPPUNIT_ASSERT(xNumberingRules->getPropertyValue(propName) >>= bIsContinuousNumberingSet);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Unable to set PropertyValue IsContinuousNumbering",
+ !bIsContinuousNumberingGet, bIsContinuousNumberingSet);
+
+ propName = "Name";
+ OUString aNameGet = "";
+ CPPUNIT_ASSERT_MESSAGE("Unable to get PropertyValue Name",
+ xNumberingRules->getPropertyValue(propName) >>= aNameGet);
+}
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/test/source/text/textcontent.cxx b/test/source/text/textcontent.cxx
new file mode 100644
index 0000000000..61990d869f
--- /dev/null
+++ b/test/source/text/textcontent.cxx
@@ -0,0 +1,68 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * 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 <test/text/textcontent.hxx>
+
+#include <com/sun/star/text/TextContentAnchorType.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+
+#include <com/sun/star/uno/Any.hxx>
+#include <com/sun/star/uno/Reference.hxx>
+#include <com/sun/star/uno/Sequence.hxx>
+
+#include <cppunit/TestAssert.h>
+
+using namespace css;
+
+namespace apitest
+{
+void TextContent::testTextContentProperties()
+{
+ uno::Reference<beans::XPropertySet> xPS(init(), uno::UNO_QUERY_THROW);
+
+ text::TextContentAnchorType aExpectedTCAT;
+ CPPUNIT_ASSERT(xPS->getPropertyValue("AnchorType") >>= aExpectedTCAT);
+ CPPUNIT_ASSERT_EQUAL(m_aExpectedTCAT, aExpectedTCAT);
+
+ try
+ {
+ xPS->setPropertyValue("AnchorType", uno::Any(m_aNewTCAT));
+ text::TextContentAnchorType aNewTCAT;
+ CPPUNIT_ASSERT(xPS->getPropertyValue("AnchorType") >>= aNewTCAT);
+ CPPUNIT_ASSERT_EQUAL(m_aNewTCAT, aNewTCAT);
+ }
+ catch (const beans::UnknownPropertyException& /* ex */)
+ {
+ // ignore if property is optional
+ }
+
+ uno::Sequence<text::TextContentAnchorType> aAnchorTypes;
+ CPPUNIT_ASSERT(xPS->getPropertyValue("AnchorTypes") >>= aAnchorTypes);
+ CPPUNIT_ASSERT(aAnchorTypes.hasElements());
+
+ text::WrapTextMode aExpectedWTM;
+ CPPUNIT_ASSERT(xPS->getPropertyValue("TextWrap") >>= aExpectedWTM);
+ CPPUNIT_ASSERT_EQUAL(m_aExpectedWTM, aExpectedWTM);
+
+ try
+ {
+ xPS->setPropertyValue("TextWrap", uno::Any(m_aNewWTM));
+ text::WrapTextMode aNewWTM;
+ CPPUNIT_ASSERT(xPS->getPropertyValue("TextWrap") >>= aNewWTM);
+ CPPUNIT_ASSERT_EQUAL(m_aNewWTM, aNewWTM);
+ }
+ catch (const beans::UnknownPropertyException& /* ex */)
+ {
+ // ignore if property is optional
+ }
+}
+
+} // namespace apitest
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/test/source/text/textdocumentindex.cxx b/test/source/text/textdocumentindex.cxx
new file mode 100644
index 0000000000..67f161cf34
--- /dev/null
+++ b/test/source/text/textdocumentindex.cxx
@@ -0,0 +1,36 @@
+/* -*- 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 <com/sun/star/beans/XPropertySet.hpp>
+
+#include <test/unoapi_property_testers.hxx>
+#include <test/text/textdocumentindex.hxx>
+
+namespace apitest
+{
+TextDocumentIndex::~TextDocumentIndex() {}
+
+void TextDocumentIndex::testDocumentIndexProperties()
+{
+ css::uno::Reference<css::beans::XPropertySet> xDocumentIndex(init(), css::uno::UNO_QUERY_THROW);
+
+ testBooleanProperty(xDocumentIndex, "UseAlphabeticalSeparators");
+ testBooleanProperty(xDocumentIndex, "UseKeyAsEntry");
+ testBooleanProperty(xDocumentIndex, "UseCombinedEntries");
+ testBooleanProperty(xDocumentIndex, "IsCaseSensitive");
+ testBooleanProperty(xDocumentIndex, "UsePP");
+ testBooleanProperty(xDocumentIndex, "UseDash");
+ testBooleanProperty(xDocumentIndex, "UseUpperCase");
+ testStringOptionalProperty(xDocumentIndex, "MainEntryCharacterStyleName");
+ // [readonly, property] sequence <com::sun::star::text::XDocumentIndexMark> DocumentIndexMarks;
+ // [property] com::sun::star::lang::Locale Locale;
+ testStringProperty(xDocumentIndex, "SortAlgorithm", "Value");
+}
+}
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/test/source/text/textdocumentsettings.cxx b/test/source/text/textdocumentsettings.cxx
new file mode 100644
index 0000000000..9ef0518b05
--- /dev/null
+++ b/test/source/text/textdocumentsettings.cxx
@@ -0,0 +1,42 @@
+/* -*- 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 <test/text/textdocumentsettings.hxx>
+#include <test/unoapi_property_testers.hxx>
+
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/uno/Reference.hxx>
+
+using namespace css::uno;
+
+namespace apitest
+{
+TextDocumentSettings::~TextDocumentSettings() {}
+
+void TextDocumentSettings::testDocumentSettingsProperties()
+{
+ css::uno::Reference<css::beans::XPropertySet> xDocumentSettings(init(),
+ css::uno::UNO_QUERY_THROW);
+
+ testBooleanOptionalProperty(xDocumentSettings, "ChartAutoUpdate");
+ testBooleanOptionalProperty(xDocumentSettings, "AddParaTableSpacing");
+ testBooleanOptionalProperty(xDocumentSettings, "AddParaTableSpacingAtStart");
+ testBooleanOptionalProperty(xDocumentSettings, "AlignTabStopPosition");
+ testBooleanOptionalProperty(xDocumentSettings, "SaveGlobalDocumentLinks");
+ testBooleanOptionalProperty(xDocumentSettings, "IsLabelDocument");
+ testBooleanOptionalProperty(xDocumentSettings, "UseFormerLineSpacing");
+ testBooleanOptionalProperty(xDocumentSettings, "AddParaSpacingToTableCells");
+ testBooleanOptionalProperty(xDocumentSettings, "UseFormerObjectPositioning");
+ testBooleanOptionalProperty(xDocumentSettings, "ConsiderTextWrapOnObjPos");
+ testBooleanOptionalProperty(xDocumentSettings, "MathBaselineAlignment");
+}
+
+} // end namespace apitest
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/test/source/text/textprintersettings.cxx b/test/source/text/textprintersettings.cxx
new file mode 100644
index 0000000000..b28c652413
--- /dev/null
+++ b/test/source/text/textprintersettings.cxx
@@ -0,0 +1,39 @@
+/* -*- 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 <com/sun/star/beans/XPropertySet.hpp>
+
+#include <test/unoapi_property_testers.hxx>
+#include <test/text/textprintersettings.hxx>
+
+namespace apitest
+{
+TextPrinterSettings::~TextPrinterSettings() {}
+void TextPrinterSettings::testPrinterSettingsProperties()
+{
+ css::uno::Reference<css::beans::XPropertySet> xPrinterSettings(init(),
+ css::uno::UNO_QUERY_THROW);
+
+ testBooleanProperty(xPrinterSettings, "PrintGraphics");
+ testBooleanProperty(xPrinterSettings, "PrintTables");
+ testBooleanProperty(xPrinterSettings, "PrintDrawings");
+ testBooleanProperty(xPrinterSettings, "PrintLeftPages");
+ testBooleanProperty(xPrinterSettings, "PrintRightPages");
+ testBooleanProperty(xPrinterSettings, "PrintControls");
+ testBooleanProperty(xPrinterSettings, "PrintReversed");
+ testBooleanProperty(xPrinterSettings, "PrintControls");
+ testStringProperty(xPrinterSettings, "PrintFaxName", "FaxName");
+ testBooleanProperty(xPrinterSettings, "PrintProspect");
+ testBooleanProperty(xPrinterSettings, "PrintPageBackground");
+ testBooleanProperty(xPrinterSettings, "PrintBlackFonts");
+ testBooleanOptionalProperty(xPrinterSettings, "PrintEmptyPages");
+}
+} // end namespace apitest
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/test/source/text/textsettings.cxx b/test/source/text/textsettings.cxx
new file mode 100644
index 0000000000..0392103907
--- /dev/null
+++ b/test/source/text/textsettings.cxx
@@ -0,0 +1,153 @@
+/* -*- 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 <cppunit/TestAssert.h>
+
+#include <com/sun/star/beans/PropertyAttribute.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/i18n/XForbiddenCharacters.hpp>
+
+#include <test/unoapi_property_testers.hxx>
+#include <test/text/textsettings.hxx>
+
+namespace
+{
+bool extstsProperty(css::uno::Reference<css::beans::XPropertySet> const& rxPropertySet,
+ OUString const& rPropertyName)
+{
+ css::uno::Reference<css::beans::XPropertySetInfo> xPropertySetInfo(
+ rxPropertySet->getPropertySetInfo());
+ return xPropertySetInfo->hasPropertyByName(rPropertyName);
+}
+
+bool isPropertyReadOnly(css::uno::Reference<css::beans::XPropertySet> const& rxPropertySet,
+ std::u16string_view rPropertyName)
+{
+ css::uno::Reference<css::beans::XPropertySetInfo> xPropertySetInfo(
+ rxPropertySet->getPropertySetInfo());
+ const css::uno::Sequence<css::beans::Property> xProperties = xPropertySetInfo->getProperties();
+
+ for (auto const& rProperty : xProperties)
+ {
+ if (rProperty.Name == rPropertyName)
+ return (rProperty.Attributes & com::sun::star::beans::PropertyAttribute::READONLY) != 0;
+ }
+
+ return false;
+}
+// [property] string PrinterName;
+void testPrinterName(css::uno::Reference<css::beans::XPropertySet> const& rxSettings)
+{
+ static constexpr OUString rPropertyName(u"PrinterName"_ustr);
+
+ if (!extstsProperty(rxSettings, rPropertyName))
+ return; // Property is sometimes not set - bug? it is not defined as optional
+
+ OUString aPrinterName_Get;
+
+ CPPUNIT_ASSERT_MESSAGE("Unable to get PropertyValue",
+ rxSettings->getPropertyValue(rPropertyName) >>= aPrinterName_Get);
+
+ OUString aPrinterName_Set;
+ css::uno::Any aNewValue;
+ aNewValue <<= aPrinterName_Get;
+ rxSettings->setPropertyValue(rPropertyName, aNewValue);
+
+ CPPUNIT_ASSERT_MESSAGE("Unable to get PropertyValue",
+ rxSettings->getPropertyValue(rPropertyName) >>= aPrinterName_Set);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Unable to set PropertyValue", aPrinterName_Get, aPrinterName_Set);
+}
+
+// [optional, property] short PrinterIndependentLayout;
+void testPrinterIndependentLayout(css::uno::Reference<css::beans::XPropertySet> const& rxSettings)
+{
+ static constexpr OUString rPropertyName(u"PrinterIndependentLayout"_ustr);
+
+ if (!extstsProperty(rxSettings, rPropertyName))
+ return; // Property is optional
+
+ sal_Int16 aValue_Get = {};
+
+ CPPUNIT_ASSERT_MESSAGE("Unable to get PropertyValue",
+ rxSettings->getPropertyValue(rPropertyName) >>= aValue_Get);
+
+ sal_Int16 aValue_New;
+ aValue_New = (aValue_Get == 1 ? 3 : 1);
+ rxSettings->setPropertyValue(rPropertyName, css::uno::Any(aValue_New));
+
+ sal_Int16 aValue_Set;
+
+ CPPUNIT_ASSERT_MESSAGE("Unable to get PropertyValue",
+ rxSettings->getPropertyValue(rPropertyName) >>= aValue_Set);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Unable to set PropertyValue", aValue_New, aValue_Set);
+}
+
+// [optional, property] com::sun::star::i18n::XForbiddenCharacters ForbiddenCharacters;
+void testForbiddenCharacters(css::uno::Reference<css::beans::XPropertySet> const& rxSettings)
+{
+ static constexpr OUString rPropertyName(u"ForbiddenCharacters"_ustr);
+
+ if (!extstsProperty(rxSettings, rPropertyName))
+ return; // Property is optional
+
+ CPPUNIT_ASSERT_MESSAGE("Property is read-only but shouldn't be",
+ !isPropertyReadOnly(rxSettings, rPropertyName));
+
+ css::uno::Reference<css::i18n::XForbiddenCharacters> aValue_Get;
+
+ CPPUNIT_ASSERT_MESSAGE("Unable to get PropertyValue",
+ rxSettings->getPropertyValue(rPropertyName) >>= aValue_Get);
+ CPPUNIT_ASSERT_MESSAGE("Empty reference to XForbiddenCharacters", aValue_Get.is());
+}
+}
+
+namespace apitest
+{
+TextSettings::~TextSettings() {}
+void TextSettings::testSettingsProperties()
+{
+ css::uno::Reference<css::beans::XPropertySet> xSettings(init(), css::uno::UNO_QUERY_THROW);
+
+ testForbiddenCharacters(xSettings);
+ //testShortOptionalProperty(xSettings, "LinkUpdateMode");
+ testPrinterName(xSettings);
+ // [property] sequence< byte > PrinterSetup;
+ testBooleanOptionalProperty(xSettings, "IsKernAsianPunctuation");
+ //testShortOptionalProperty(xSettings, "CharacterCompressionType");
+ testBooleanOptionalProperty(xSettings, "ApplyUserData");
+ testBooleanOptionalProperty(xSettings, "SaveVersionOnClose");
+ testBooleanOptionalProperty(xSettings, "UpdateFromTemplate");
+ testBooleanOptionalProperty(xSettings, "FieldAutoUpdate");
+ testStringOptionalProperty(xSettings, "CurrentDatabaseDataSource");
+ testStringOptionalProperty(xSettings, "CurrentDatabaseCommand");
+ testLongOptionalProperty(xSettings, "CurrentDatabaseCommandType");
+ testLongOptionalProperty(xSettings, "DefaultTabStop");
+ testBooleanOptionalProperty(xSettings, "IsPrintBooklet");
+ testBooleanOptionalProperty(xSettings, "IsPrintBookletFront");
+ testBooleanOptionalProperty(xSettings, "IsPrintBookletBack");
+ testLongOptionalProperty(xSettings, "PrintQuality");
+ testStringOptionalProperty(xSettings, "ColorTableURL");
+ testStringOptionalProperty(xSettings, "DashTableURL");
+ testStringOptionalProperty(xSettings, "LineEndTableURL");
+ testStringOptionalProperty(xSettings, "HatchTableURL");
+ testStringOptionalProperty(xSettings, "GradientTableURL");
+ testStringOptionalProperty(xSettings, "BitmapTableURL");
+ testBooleanOptionalProperty(xSettings, "AutoCalculate");
+ testPrinterIndependentLayout(xSettings);
+ testBooleanOptionalProperty(xSettings, "AddExternalLeading");
+ testBooleanOptionalProperty(xSettings, "EmbedFonts");
+ testBooleanOptionalProperty(xSettings, "EmbedSystemFonts");
+ testBooleanOptionalProperty(xSettings, "EmbedOnlyUsedFonts");
+ testBooleanOptionalProperty(xSettings, "EmbedLatinScriptFonts");
+ testBooleanOptionalProperty(xSettings, "EmbedAsianScriptFonts");
+ testBooleanOptionalProperty(xSettings, "EmbedComplexScriptFonts");
+}
+} // end namespace apitest
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/test/source/text/xautotextcontainer.cxx b/test/source/text/xautotextcontainer.cxx
new file mode 100644
index 0000000000..b1d001ba4d
--- /dev/null
+++ b/test/source/text/xautotextcontainer.cxx
@@ -0,0 +1,54 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * 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 <test/text/xautotextcontainer.hxx>
+
+#include <com/sun/star/container/ElementExistException.hpp>
+#include <com/sun/star/container/NoSuchElementException.hpp>
+#include <com/sun/star/text/XAutoTextContainer.hpp>
+#include <com/sun/star/text/XAutoTextGroup.hpp>
+#include <com/sun/star/lang/IllegalArgumentException.hpp>
+
+#include <com/sun/star/uno/Any.hxx>
+#include <com/sun/star/uno/Reference.hxx>
+
+#include <cppunit/TestAssert.h>
+
+using namespace css;
+
+namespace apitest
+{
+void XAutoTextContainer::testInsertNewByName()
+{
+ uno::Reference<text::XAutoTextContainer> xAutoTextContainer(init(), uno::UNO_QUERY_THROW);
+
+ try
+ {
+ xAutoTextContainer->removeByName(m_aName + "Insert");
+ }
+ catch (container::NoSuchElementException&)
+ {
+ }
+ uno::Reference<text::XAutoTextGroup> xGroup
+ = xAutoTextContainer->insertNewByName(m_aName + "Insert");
+
+ CPPUNIT_ASSERT(xGroup.is());
+}
+
+void XAutoTextContainer::testRemoveByName()
+{
+ uno::Reference<text::XAutoTextContainer> xAutoTextContainer(init(), uno::UNO_QUERY_THROW);
+ CPPUNIT_ASSERT(xAutoTextContainer->hasByName(m_aName));
+ xAutoTextContainer->removeByName(m_aName);
+ CPPUNIT_ASSERT(!xAutoTextContainer->hasByName(m_aName));
+}
+
+} // namespace apitest
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/test/source/text/xdocumentindex.cxx b/test/source/text/xdocumentindex.cxx
new file mode 100644
index 0000000000..9f9ad73c83
--- /dev/null
+++ b/test/source/text/xdocumentindex.cxx
@@ -0,0 +1,66 @@
+/* -*- 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 <cppunit/TestAssert.h>
+
+#include <com/sun/star/text/XTextDocument.hpp>
+#include <com/sun/star/text/XTextContent.hpp>
+#include <com/sun/star/text/XText.hpp>
+#include <com/sun/star/text/XDocumentIndex.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+
+#include <test/text/xdocumentindex.hxx>
+
+namespace apitest
+{
+XDocumentIndex::~XDocumentIndex() {}
+/**
+ * Gets the document from relation and insert a new index mark.
+ * Then it stores the text content of document index before
+ * update and after.<p>
+ *
+ * Has <b> OK </b> status if index content is changed and
+ * new index contains index mark inserted. <p>
+ */
+void XDocumentIndex::testUpdate()
+{
+ css::uno::Reference<css::text::XDocumentIndex> xDocumentIndex(init(),
+ css::uno::UNO_QUERY_THROW);
+
+ bool bOK = true;
+ try
+ {
+ auto xText = getTextDocument()->getText();
+ auto xTextRange = xText->getEnd();
+ xTextRange->setString("IndexMark");
+ css::uno::Reference<css::lang::XMultiServiceFactory> xFactory(getTextDocument(),
+ css::uno::UNO_QUERY_THROW);
+ css::uno::Reference<css::text::XTextContent> xTextContentMark(
+ xFactory->createInstance("com.sun.star.text.DocumentIndexMark"),
+ css::uno::UNO_QUERY_THROW);
+ xText->insertTextContent(xTextRange, xTextContentMark, true);
+ }
+ catch (css::uno::Exception /*exception*/)
+ {
+ bOK = false;
+ }
+
+ CPPUNIT_ASSERT_MESSAGE("Couldn't create the document index mark", bOK);
+
+ OUString sContentBefore = xDocumentIndex->getAnchor()->getString();
+ xDocumentIndex->update();
+ OUString sContentAfter = xDocumentIndex->getAnchor()->getString();
+
+ CPPUNIT_ASSERT_MESSAGE("Before and after shouldn't be equal", sContentBefore != sContentAfter);
+ CPPUNIT_ASSERT_MESSAGE("Content after should contain string 'IndexMark'",
+ sContentAfter.indexOf("IndexMark") >= 0);
+}
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/test/source/text/xfootnote.cxx b/test/source/text/xfootnote.cxx
new file mode 100644
index 0000000000..d46506bf1f
--- /dev/null
+++ b/test/source/text/xfootnote.cxx
@@ -0,0 +1,41 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * 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 <test/text/xfootnote.hxx>
+
+#include <com/sun/star/text/XText.hpp>
+#include <com/sun/star/text/XTextCursor.hpp>
+#include <com/sun/star/text/XTextDocument.hpp>
+#include <com/sun/star/text/XFootnote.hpp>
+#include <com/sun/star/lang/IllegalArgumentException.hpp>
+
+#include <com/sun/star/uno/Any.hxx>
+#include <com/sun/star/uno/Reference.hxx>
+
+#include <cppunit/TestAssert.h>
+
+using namespace css;
+using namespace css::uno;
+
+namespace apitest
+{
+void XFootnote::testGetSetLabel()
+{
+ Reference<text::XFootnote> xFootnote(init(), UNO_QUERY_THROW);
+
+ rtl::OUString labelName = "New XFootnote Label";
+ xFootnote->setLabel(labelName);
+ rtl::OUString newLabel = xFootnote->getLabel();
+ CPPUNIT_ASSERT(!newLabel.isEmpty());
+ CPPUNIT_ASSERT_EQUAL(labelName, newLabel);
+}
+
+} // namespace apitest
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/test/source/text/xsimpletext.cxx b/test/source/text/xsimpletext.cxx
new file mode 100644
index 0000000000..23ea6c785e
--- /dev/null
+++ b/test/source/text/xsimpletext.cxx
@@ -0,0 +1,76 @@
+/* -*- 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 <test/text/xsimpletext.hxx>
+#include <com/sun/star/text/XTextCursor.hpp>
+#include <com/sun/star/text/ControlCharacter.hpp>
+#include <com/sun/star/lang/IllegalArgumentException.hpp>
+#include <cppunit/TestAssert.h>
+
+using namespace css;
+using namespace css::uno;
+
+namespace apitest
+{
+void XSimpleText::testCreateTextCursor()
+{
+ uno::Reference<text::XSimpleText> xSimpleText(init(), UNO_QUERY_THROW);
+
+ CPPUNIT_ASSERT(xSimpleText->createTextCursor());
+}
+
+void XSimpleText::testCreateTextCursorByRange()
+{
+ uno::Reference<text::XSimpleText> xSimpleText(init(), UNO_QUERY_THROW);
+ uno::Reference<text::XTextCursor> xCursor(xSimpleText->createTextCursor(), UNO_SET_THROW);
+
+ xCursor->gotoStart(false);
+
+ CPPUNIT_ASSERT(xSimpleText->createTextCursorByRange(xCursor));
+}
+
+void XSimpleText::testInsertString()
+{
+ uno::Reference<text::XSimpleText> xSimpleText(init(), UNO_QUERY_THROW);
+ uno::Reference<text::XTextRange> xCursor(xSimpleText->createTextCursor(), UNO_QUERY_THROW);
+ ::rtl::OUString sString = "TestString";
+
+ xSimpleText->insertString(xCursor, sString, false);
+ ::rtl::OUString gString = xSimpleText->getText()->getString();
+
+ CPPUNIT_ASSERT(!gString.isEmpty());
+ CPPUNIT_ASSERT(gString.indexOf(sString) >= 0);
+}
+
+void XSimpleText::testInsertControlCharacter()
+{
+ bool bOK = true;
+
+ uno::Reference<text::XSimpleText> xSimpleText(init(), UNO_QUERY_THROW);
+ uno::Reference<text::XTextRange> xCursor(xSimpleText->createTextCursor(), UNO_QUERY_THROW);
+
+ try
+ {
+ xSimpleText->insertControlCharacter(xCursor, text::ControlCharacter::PARAGRAPH_BREAK,
+ false);
+ xSimpleText->insertControlCharacter(xCursor, text::ControlCharacter::LINE_BREAK, false);
+ xSimpleText->insertString(xSimpleText->createTextCursor(), "newLine", false);
+ }
+ catch (const lang::IllegalArgumentException&)
+ {
+ bOK = false;
+ }
+
+ OUString gString = xSimpleText->getString();
+ CPPUNIT_ASSERT(bOK);
+ CPPUNIT_ASSERT(gString.indexOf("\n") > -1);
+}
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/test/source/text/xtext.cxx b/test/source/text/xtext.cxx
new file mode 100644
index 0000000000..6f62741560
--- /dev/null
+++ b/test/source/text/xtext.cxx
@@ -0,0 +1,29 @@
+/* -*- 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 <test/text/xtext.hxx>
+
+using namespace css;
+using namespace css::uno;
+
+namespace apitest
+{
+XText::~XText() {}
+
+void XText::testInsertRemoveTextContent()
+{
+ uno::Reference<text::XText> xText(init(), UNO_QUERY_THROW);
+ uno::Reference<text::XTextRange> xCursor(xText->createTextCursor(), UNO_QUERY_THROW);
+
+ xText->insertTextContent(xCursor, getTextContent(), false);
+ xText->removeTextContent(getTextContent());
+}
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/test/source/text/xtextcontent.cxx b/test/source/text/xtextcontent.cxx
new file mode 100644
index 0000000000..762584e887
--- /dev/null
+++ b/test/source/text/xtextcontent.cxx
@@ -0,0 +1,57 @@
+/* -*- 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 <test/text/xtextcontent.hxx>
+#include <com/sun/star/text/XTextContent.hpp>
+#include <com/sun/star/text/XTextRange.hpp>
+#include <com/sun/star/lang/IllegalArgumentException.hpp>
+#include <cppunit/TestAssert.h>
+
+using namespace css;
+using namespace css::uno;
+
+namespace apitest
+{
+void XTextContent::testGetAnchor()
+{
+ uno::Reference<text::XTextContent> xTextContent(init(), UNO_QUERY_THROW);
+ uno::Reference<uno::XInterface> xAnchor(xTextContent->getAnchor());
+ CPPUNIT_ASSERT(xAnchor.is());
+}
+
+void XTextContent::testAttach()
+{
+ uno::Reference<text::XTextContent> xTextContent(init(), UNO_QUERY_THROW);
+
+ uno::Reference<text::XTextContent> xContent(getTextContent(), UNO_SET_THROW);
+ uno::Reference<text::XTextRange> xRange(getTextRange(), UNO_SET_THROW);
+
+ try
+ {
+ if (xContent.is())
+ xContent->attach(xRange);
+ else
+ xTextContent->attach(xRange);
+ }
+ catch (const lang::IllegalArgumentException&)
+ {
+ bool bAttachSupported = isAttachSupported();
+ if (bAttachSupported)
+ CPPUNIT_ASSERT(false);
+ }
+ catch (const RuntimeException&)
+ {
+ bool bAttachSupported = isAttachSupported();
+ if (bAttachSupported)
+ CPPUNIT_ASSERT(false);
+ }
+}
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/test/source/text/xtextfield.cxx b/test/source/text/xtextfield.cxx
new file mode 100644
index 0000000000..ceefcceed8
--- /dev/null
+++ b/test/source/text/xtextfield.cxx
@@ -0,0 +1,43 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * 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 <test/text/xtextfield.hxx>
+
+#include <com/sun/star/text/XTextField.hpp>
+
+#include <com/sun/star/uno/Reference.hxx>
+
+#include <cppunit/TestAssert.h>
+
+using namespace css;
+
+namespace apitest
+{
+void XTextField::testGetPresentation()
+{
+ uno::Reference<text::XTextField> xTextField(init(), uno::UNO_QUERY_THROW);
+
+ OUString aString = xTextField->getPresentation(true);
+ CPPUNIT_ASSERT(!aString.isEmpty());
+ aString = xTextField->getPresentation(false);
+ CPPUNIT_ASSERT(!aString.isEmpty());
+}
+
+void XTextField::testGetPresentationEmptyString()
+{
+ uno::Reference<text::XTextField> xTextField(init(), uno::UNO_QUERY_THROW);
+
+ OUString aString = xTextField->getPresentation(true);
+ CPPUNIT_ASSERT(aString.isEmpty());
+ aString = xTextField->getPresentation(false);
+ CPPUNIT_ASSERT(aString.isEmpty());
+}
+} // namespace apitest
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/test/source/text/xtextrange.cxx b/test/source/text/xtextrange.cxx
new file mode 100644
index 0000000000..64428b476e
--- /dev/null
+++ b/test/source/text/xtextrange.cxx
@@ -0,0 +1,61 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * 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 <test/text/xtextrange.hxx>
+
+#include <com/sun/star/text/XText.hpp>
+#include <com/sun/star/text/XTextRange.hpp>
+
+#include <cppunit/TestAssert.h>
+
+using namespace css;
+
+namespace apitest
+{
+void XTextRange::testGetEnd()
+{
+ uno::Reference<text::XTextRange> xTextRange(init(), uno::UNO_QUERY_THROW);
+
+ xTextRange->setString("UnitTest");
+ uno::Reference<text::XTextRange> xTR_end(xTextRange->getEnd(), uno::UNO_SET_THROW);
+ xTR_end->setString("End");
+
+ CPPUNIT_ASSERT(xTextRange->getText()->getString().endsWith("End"));
+}
+
+void XTextRange::testGetSetString()
+{
+ uno::Reference<text::XTextRange> xTextRange(init(), uno::UNO_QUERY_THROW);
+
+ xTextRange->setString("UnitTest");
+ CPPUNIT_ASSERT_EQUAL(OUString("UnitTest"), xTextRange->getString());
+}
+
+void XTextRange::testGetStart()
+{
+ uno::Reference<text::XTextRange> xTextRange(init(), uno::UNO_QUERY_THROW);
+
+ xTextRange->setString("UnitTest");
+ uno::Reference<text::XTextRange> xTR_start(xTextRange->getStart(), uno::UNO_SET_THROW);
+ xTR_start->setString("Start");
+
+ CPPUNIT_ASSERT(xTextRange->getText()->getString().startsWith("Start"));
+}
+
+void XTextRange::testGetText()
+{
+ uno::Reference<text::XTextRange> xTextRange(init(), uno::UNO_QUERY_THROW);
+
+ xTextRange->setString("UnitTest");
+ uno::Reference<text::XText> xText(xTextRange->getText(), uno::UNO_SET_THROW);
+ CPPUNIT_ASSERT_EQUAL(OUString("UnitTest"), xTextRange->getString());
+}
+} // namespace apitest
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/test/source/text/xtextrangecompare.cxx b/test/source/text/xtextrangecompare.cxx
new file mode 100644
index 0000000000..b31d6b8643
--- /dev/null
+++ b/test/source/text/xtextrangecompare.cxx
@@ -0,0 +1,76 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * 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 <test/text/xtextrangecompare.hxx>
+
+#include <com/sun/star/text/XText.hpp>
+#include <com/sun/star/text/XTextCursor.hpp>
+#include <com/sun/star/text/XTextDocument.hpp>
+#include <com/sun/star/text/XTextRangeCompare.hpp>
+#include <com/sun/star/lang/IllegalArgumentException.hpp>
+
+#include <com/sun/star/uno/Any.hxx>
+#include <com/sun/star/uno/Reference.hxx>
+
+#include <cppunit/TestAssert.h>
+
+using namespace css;
+using namespace css::uno;
+
+namespace apitest
+{
+void XTextRangeCompare::testCompareRegionStarts()
+{
+ Reference<text::XTextRangeCompare> xCompare(init(), UNO_QUERY_THROW);
+ Reference<text::XText> xText(xCompare, UNO_QUERY_THROW);
+
+ try
+ {
+ Reference<text::XTextCursor> xCursor1 = xText->createTextCursor();
+ xText->insertString(xCursor1, "XTextRangeCompare", false);
+
+ xCursor1->gotoStart(false);
+ xCursor1->goRight(5, true);
+ Reference<text::XTextCursor> xCursor2 = xText->createTextCursor();
+ xCursor2->gotoEnd(false);
+ xCursor2->goLeft(7, true);
+
+ CPPUNIT_ASSERT(xCompare->compareRegionStarts(xCursor1, xCursor2));
+ }
+ catch (lang::IllegalArgumentException&)
+ {
+ }
+}
+
+void XTextRangeCompare::testCompareRegionEnds()
+{
+ Reference<text::XTextRangeCompare> xCompare(init(), UNO_QUERY_THROW);
+ Reference<text::XText> xText(xCompare, UNO_QUERY_THROW);
+
+ try
+ {
+ Reference<text::XTextCursor> xCursor1 = xText->createTextCursor();
+ xText->insertString(xCursor1, "XTextRangeCompare", false);
+
+ xCursor1->gotoStart(false);
+ xCursor1->goRight(5, true);
+ Reference<text::XTextCursor> xCursor2 = xText->createTextCursor();
+ xCursor2->gotoEnd(false);
+ xCursor2->goLeft(7, true);
+
+ CPPUNIT_ASSERT(xCompare->compareRegionEnds(xCursor1, xCursor2));
+ }
+ catch (lang::IllegalArgumentException&)
+ {
+ }
+}
+
+} // namespace apitest
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/test/source/unoapi_property_testers.cxx b/test/source/unoapi_property_testers.cxx
new file mode 100644
index 0000000000..c0987d8c0f
--- /dev/null
+++ b/test/source/unoapi_property_testers.cxx
@@ -0,0 +1,288 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * 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 <test/unoapi_property_testers.hxx>
+
+#include <com/sun/star/uno/Any.hxx>
+#include <cppunit/TestAssert.h>
+
+using namespace css;
+
+namespace apitest
+{
+void testBooleanProperty(uno::Reference<beans::XPropertySet> const& xPropertySet,
+ const OUString& name)
+{
+ uno::Any aNewValue;
+
+ bool bPropertyGet = false;
+ bool bPropertySet = false;
+
+ OString msgGet
+ = "Unable to get PropertyValue: " + OUStringToOString(name, RTL_TEXTENCODING_UTF8);
+ CPPUNIT_ASSERT_MESSAGE(msgGet.getStr(), xPropertySet->getPropertyValue(name) >>= bPropertyGet);
+
+ aNewValue <<= !bPropertyGet;
+ xPropertySet->setPropertyValue(name, aNewValue);
+ CPPUNIT_ASSERT(xPropertySet->getPropertyValue(name) >>= bPropertySet);
+ OString msgSet
+ = "Unable to set PropertyValue: " + OUStringToOString(name, RTL_TEXTENCODING_UTF8);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(msgSet.getStr(), !bPropertyGet, bPropertySet);
+}
+
+void testBooleanOptionalProperty(uno::Reference<beans::XPropertySet> const& xPropertySet,
+ const OUString& rName)
+{
+ try
+ {
+ testBooleanProperty(xPropertySet, rName);
+ }
+ catch (const css::beans::UnknownPropertyException& /*ex*/)
+ {
+ // ignore if the property is unknown as it is optional
+ }
+}
+
+void testBooleanReadonlyProperty(uno::Reference<beans::XPropertySet> const& xPropertySet,
+ const OUString& name)
+{
+ uno::Any aNewValue;
+
+ bool bPropertyGet = false;
+ bool bPropertySet = false;
+
+ OString msgGet
+ = "Unable to get PropertyValue: " + OUStringToOString(name, RTL_TEXTENCODING_UTF8);
+ CPPUNIT_ASSERT_MESSAGE(msgGet.getStr(), xPropertySet->getPropertyValue(name) >>= bPropertyGet);
+
+ aNewValue <<= !bPropertyGet;
+ xPropertySet->setPropertyValue(name, aNewValue);
+ CPPUNIT_ASSERT(xPropertySet->getPropertyValue(name) >>= bPropertySet);
+ OString msgSet = "Able to set PropertyValue: " + OUStringToOString(name, RTL_TEXTENCODING_UTF8);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(msgSet.getStr(), bPropertyGet, bPropertySet);
+}
+
+void testDoubleProperty(uno::Reference<beans::XPropertySet> const& xPropertySet,
+ const OUString& name, const double& dValue)
+{
+ uno::Any aNewValue;
+
+ double dPropertyGet;
+ double dPropertySet = {};
+
+ OString msgGet
+ = "Unable to get PropertyValue: " + OUStringToOString(name, RTL_TEXTENCODING_UTF8);
+ CPPUNIT_ASSERT_MESSAGE(msgGet.getStr(), xPropertySet->getPropertyValue(name) >>= dPropertyGet);
+
+ aNewValue <<= dValue;
+ xPropertySet->setPropertyValue(name, aNewValue);
+ CPPUNIT_ASSERT(xPropertySet->getPropertyValue(name) >>= dPropertySet);
+ OString msgSet
+ = "Unable to set PropertyValue: " + OUStringToOString(name, RTL_TEXTENCODING_UTF8);
+ CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE(msgSet.getStr(), dValue, dPropertySet, 0.5);
+}
+
+void testDoubleReadonlyProperty(uno::Reference<beans::XPropertySet> const& xPropertySet,
+ const OUString& name, const double& dValue)
+{
+ uno::Any aNewValue;
+
+ double dPropertyGet = {};
+ double dPropertySet = {};
+
+ OString msgGet
+ = "Unable to get PropertyValue: " + OUStringToOString(name, RTL_TEXTENCODING_UTF8);
+ CPPUNIT_ASSERT_MESSAGE(msgGet.getStr(), xPropertySet->getPropertyValue(name) >>= dPropertyGet);
+
+ aNewValue <<= dValue;
+ xPropertySet->setPropertyValue(name, aNewValue);
+ CPPUNIT_ASSERT(xPropertySet->getPropertyValue(name) >>= dPropertySet);
+ OString msgSet = "Able to set PropertyValue: " + OUStringToOString(name, RTL_TEXTENCODING_UTF8);
+ CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE(msgSet.getStr(), dPropertyGet, dPropertySet, 0.5);
+}
+
+void testLongProperty(uno::Reference<beans::XPropertySet> const& xPropertySet, const OUString& name,
+ const sal_Int32& nValue)
+{
+ uno::Any aNewValue;
+
+ sal_Int32 nPropertyGet;
+ sal_Int32 nPropertySet;
+
+ OString msgGet
+ = "Unable to get PropertyValue: " + OUStringToOString(name, RTL_TEXTENCODING_UTF8);
+ CPPUNIT_ASSERT_MESSAGE(msgGet.getStr(), xPropertySet->getPropertyValue(name) >>= nPropertyGet);
+
+ aNewValue <<= nValue;
+ xPropertySet->setPropertyValue(name, aNewValue);
+ CPPUNIT_ASSERT(xPropertySet->getPropertyValue(name) >>= nPropertySet);
+ OString msgSet
+ = "Unable to set PropertyValue: " + OUStringToOString(name, RTL_TEXTENCODING_UTF8);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(msgSet.getStr(), nValue, nPropertySet);
+}
+
+void testLongOptionalProperty(uno::Reference<beans::XPropertySet> const& xPropertySet,
+ const OUString& rName, const sal_Int32& rValue)
+{
+ try
+ {
+ testLongProperty(xPropertySet, rName, rValue);
+ }
+ catch (const css::beans::UnknownPropertyException& /*ex*/)
+ {
+ // ignore if the property is unknown as it is optional
+ }
+}
+
+void testLongReadonlyProperty(uno::Reference<beans::XPropertySet> const& xPropertySet,
+ const OUString& name, const sal_Int32& nValue)
+{
+ uno::Any aNewValue;
+
+ sal_Int32 nPropertyGet;
+ sal_Int32 nPropertySet;
+
+ OString msgGet
+ = "Unable to get PropertyValue: " + OUStringToOString(name, RTL_TEXTENCODING_UTF8);
+ CPPUNIT_ASSERT_MESSAGE(msgGet.getStr(), xPropertySet->getPropertyValue(name) >>= nPropertyGet);
+
+ aNewValue <<= nValue;
+ xPropertySet->setPropertyValue(name, aNewValue);
+ CPPUNIT_ASSERT(xPropertySet->getPropertyValue(name) >>= nPropertySet);
+ OString msgSet = "Able to set PropertyValue: " + OUStringToOString(name, RTL_TEXTENCODING_UTF8);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(msgSet.getStr(), nPropertyGet, nPropertySet);
+}
+
+void testShortProperty(uno::Reference<beans::XPropertySet> const& xPropertySet,
+ const OUString& name, const sal_Int16& nValue)
+{
+ uno::Any aNewValue;
+
+ sal_Int16 nPropertyGet;
+ sal_Int16 nPropertySet;
+
+ OString msgGet
+ = "Unable to get PropertyValue: " + OUStringToOString(name, RTL_TEXTENCODING_UTF8);
+ CPPUNIT_ASSERT_MESSAGE(msgGet.getStr(), xPropertySet->getPropertyValue(name) >>= nPropertyGet);
+
+ aNewValue <<= nValue;
+ xPropertySet->setPropertyValue(name, aNewValue);
+ CPPUNIT_ASSERT(xPropertySet->getPropertyValue(name) >>= nPropertySet);
+ OString msgSet
+ = "Unable to set PropertyValue: " + OUStringToOString(name, RTL_TEXTENCODING_UTF8);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(msgSet.getStr(), nValue, nPropertySet);
+}
+
+void testShortOptionalProperty(uno::Reference<beans::XPropertySet> const& xPropertySet,
+ const OUString& rName, const sal_Int16& rValue)
+{
+ try
+ {
+ testShortProperty(xPropertySet, rName, rValue);
+ }
+ catch (const css::beans::UnknownPropertyException& /*ex*/)
+ {
+ // ignore if the property is unknown as it is optional
+ }
+}
+
+void testShortReadonlyProperty(uno::Reference<beans::XPropertySet> const& xPropertySet,
+ const OUString& name, const sal_Int16& nValue)
+{
+ uno::Any aNewValue;
+
+ sal_Int16 nPropertyGet;
+ sal_Int16 nPropertySet;
+
+ OString msgGet
+ = "Unable to get PropertyValue: " + OUStringToOString(name, RTL_TEXTENCODING_UTF8);
+ CPPUNIT_ASSERT_MESSAGE(msgGet.getStr(), xPropertySet->getPropertyValue(name) >>= nPropertyGet);
+
+ aNewValue <<= nValue;
+ xPropertySet->setPropertyValue(name, aNewValue);
+ CPPUNIT_ASSERT(xPropertySet->getPropertyValue(name) >>= nPropertySet);
+ OString msgSet = "Able to set PropertyValue: " + OUStringToOString(name, RTL_TEXTENCODING_UTF8);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(msgSet.getStr(), nPropertyGet, nPropertySet);
+}
+
+void testStringOptionalProperty(uno::Reference<beans::XPropertySet> const& xPropertySet,
+ const OUString& rName, const OUString& rValue)
+{
+ try
+ {
+ testStringProperty(xPropertySet, rName, rValue);
+ }
+ catch (const css::beans::UnknownPropertyException& /*ex*/)
+ {
+ // ignore if the property is unknown as it is optional
+ }
+}
+
+void testStringProperty(uno::Reference<beans::XPropertySet> const& xPropertySet,
+ const OUString& name, const OUString& rValue)
+{
+ uno::Any aNewValue;
+
+ OUString sPropertyGet;
+ OUString sPropertySet;
+
+ OString msgGet
+ = "Unable to get PropertyValue: " + OUStringToOString(name, RTL_TEXTENCODING_UTF8);
+ CPPUNIT_ASSERT_MESSAGE(msgGet.getStr(), xPropertySet->getPropertyValue(name) >>= sPropertyGet);
+
+ aNewValue <<= rValue;
+ xPropertySet->setPropertyValue(name, aNewValue);
+ CPPUNIT_ASSERT(xPropertySet->getPropertyValue(name) >>= sPropertySet);
+ OString msgSet
+ = "Unable to set PropertyValue: " + OUStringToOString(name, RTL_TEXTENCODING_UTF8);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(msgSet.getStr(), rValue, sPropertySet);
+}
+
+void testStringReadonlyProperty(uno::Reference<beans::XPropertySet> const& xPropertySet,
+ const OUString& name, const OUString& rValue)
+{
+ uno::Any aNewValue;
+
+ OUString sPropertyGet;
+ OUString sPropertySet;
+
+ OString msgGet
+ = "Unable to get PropertyValue: " + OUStringToOString(name, RTL_TEXTENCODING_UTF8);
+ CPPUNIT_ASSERT_MESSAGE(msgGet.getStr(), xPropertySet->getPropertyValue(name) >>= sPropertyGet);
+
+ aNewValue <<= rValue;
+ xPropertySet->setPropertyValue(name, aNewValue);
+ CPPUNIT_ASSERT(xPropertySet->getPropertyValue(name) >>= sPropertySet);
+ OString msgSet = "Able to set PropertyValue: " + OUStringToOString(name, RTL_TEXTENCODING_UTF8);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(msgSet.getStr(), sPropertyGet, sPropertySet);
+}
+
+void testColorProperty(uno::Reference<beans::XPropertySet> const& xPropertySet,
+ const OUString& name, const util::Color& rValue)
+{
+ uno::Any aNewValue;
+
+ util::Color sPropertyGet;
+ util::Color sPropertySet;
+
+ OString msgGet
+ = "Unable to get PropertyValue: " + OUStringToOString(name, RTL_TEXTENCODING_UTF8);
+ CPPUNIT_ASSERT_MESSAGE(msgGet.getStr(), xPropertySet->getPropertyValue(name) >>= sPropertyGet);
+
+ aNewValue <<= rValue;
+ xPropertySet->setPropertyValue(name, aNewValue);
+ CPPUNIT_ASSERT(xPropertySet->getPropertyValue(name) >>= sPropertySet);
+ OString msgSet
+ = "Unable to set PropertyValue: " + OUStringToOString(name, RTL_TEXTENCODING_UTF8);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(msgSet.getStr(), rValue, sPropertySet);
+}
+
+} // namespace apitest
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/test/source/unoapi_test.cxx b/test/source/unoapi_test.cxx
new file mode 100644
index 0000000000..ce88aac315
--- /dev/null
+++ b/test/source/unoapi_test.cxx
@@ -0,0 +1,245 @@
+/* -*- 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 <test/unoapi_test.hxx>
+
+#include <com/sun/star/beans/NamedValue.hpp>
+#include <com/sun/star/frame/Desktop.hpp>
+#include <com/sun/star/frame/XStorable.hpp>
+#include <comphelper/processfactory.hxx>
+#include <comphelper/propertyvalue.hxx>
+#include <comphelper/sequence.hxx>
+
+#include <sfx2/app.hxx>
+#include <sfx2/objsh.hxx>
+#include <unotools/mediadescriptor.hxx>
+#include <utility>
+
+using namespace css;
+using namespace css::uno;
+
+UnoApiTest::UnoApiTest(OUString path)
+ : mbSkipValidation(false)
+ , m_aBaseString(std::move(path))
+{
+ maTempFile.EnableKillingFile();
+}
+
+void UnoApiTest::setUp()
+{
+ test::BootstrapFixture::setUp();
+
+ mxDesktop
+ = css::frame::Desktop::create(comphelper::getComponentContext(getMultiServiceFactory()));
+ CPPUNIT_ASSERT_MESSAGE("no desktop!", mxDesktop.is());
+ SfxApplication::GetOrCreate();
+}
+
+void UnoApiTest::tearDown()
+{
+ if (mxComponent2.is())
+ {
+ mxComponent2->dispose();
+ mxComponent2.clear();
+ }
+
+ if (mxComponent.is())
+ {
+ mxComponent->dispose();
+ mxComponent.clear();
+ }
+
+ test::BootstrapFixture::tearDown();
+}
+
+OUString UnoApiTest::createFileURL(std::u16string_view aFileBase)
+{
+ return m_directories.getSrcRootURL() + m_aBaseString + "/" + aFileBase;
+}
+
+OUString UnoApiTest::createFilePath(std::u16string_view aFileBase)
+{
+ return m_directories.getSrcRootPath() + "/" + m_aBaseString + "/" + aFileBase;
+}
+
+void UnoApiTest::setTestInteractionHandler(const char* pPassword,
+ std::vector<beans::PropertyValue>& rFilterOptions)
+{
+ OUString sPassword = OUString::createFromAscii(pPassword);
+ auto& rPropertyValue = rFilterOptions.emplace_back();
+ xInteractionHandler
+ = rtl::Reference<TestInteractionHandler>(new TestInteractionHandler(sPassword));
+ css::uno::Reference<task::XInteractionHandler2> const xInteraction(xInteractionHandler);
+ rPropertyValue.Name = "InteractionHandler";
+ rPropertyValue.Value <<= xInteraction;
+}
+
+void UnoApiTest::load(OUString const& rURL, const char* pPassword)
+{
+ std::vector<beans::PropertyValue> aFilterOptions;
+
+ if (pPassword)
+ {
+ setTestInteractionHandler(pPassword, aFilterOptions);
+ }
+
+ if (!maImportFilterOptions.isEmpty())
+ {
+ beans::PropertyValue aValue;
+ aValue.Name = "FilterOptions";
+ aValue.Value <<= maImportFilterOptions;
+ aFilterOptions.push_back(aValue);
+ }
+
+ if (!maImportFilterName.isEmpty())
+ {
+ beans::PropertyValue aValue;
+ aValue.Name = "FilterName";
+ aValue.Value <<= maImportFilterName;
+ aFilterOptions.push_back(aValue);
+ }
+
+ loadWithParams(rURL, comphelper::containerToSequence(aFilterOptions));
+
+ if (pPassword)
+ {
+ CPPUNIT_ASSERT_MESSAGE("Password set but not requested",
+ xInteractionHandler->wasPasswordRequested());
+ }
+}
+
+void UnoApiTest::loadWithParams(OUString const& rURL,
+ const uno::Sequence<beans::PropertyValue>& rParams)
+{
+ if (mxComponent.is())
+ {
+ mxComponent->dispose();
+ mxComponent.clear();
+ }
+
+ mxComponent = loadFromDesktop(rURL, OUString(), rParams);
+}
+
+OUString UnoApiTest::loadFromFile(std::u16string_view aFileBase, const char* pPassword)
+{
+ OUString aFileName = createFileURL(aFileBase);
+ load(aFileName, pPassword);
+ return aFileName;
+}
+
+uno::Any UnoApiTest::executeMacro(const OUString& rScriptURL,
+ const uno::Sequence<uno::Any>& rParams)
+{
+ uno::Any aRet;
+ uno::Sequence<sal_Int16> aOutParamIndex;
+ uno::Sequence<uno::Any> aOutParam;
+
+ ErrCode result = SfxObjectShell::CallXScript(mxComponent, rScriptURL, rParams, aRet,
+ aOutParamIndex, aOutParam);
+ CPPUNIT_ASSERT_EQUAL(ERRCODE_NONE, result);
+
+ return aRet;
+}
+
+void UnoApiTest::save(const OUString& rFilter, const char* pPassword)
+{
+ utl::MediaDescriptor aMediaDescriptor;
+ aMediaDescriptor["FilterName"] <<= rFilter;
+ if (!maFilterOptions.isEmpty())
+ aMediaDescriptor["FilterOptions"] <<= maFilterOptions;
+
+ if (pPassword)
+ {
+ if (rFilter != "Office Open XML Text" && rFilter != "Calc Office Open XML"
+ && rFilter != "Impress Office Open XML")
+ {
+ aMediaDescriptor["Password"] <<= OUString::createFromAscii(pPassword);
+ }
+ else
+ {
+ OUString sPassword = OUString::createFromAscii(pPassword);
+ uno::Sequence<beans::NamedValue> aEncryptionData{
+ { "CryptoType", uno::Any(OUString("Standard")) },
+ { "OOXPassword", uno::Any(sPassword) }
+ };
+ aMediaDescriptor[utl::MediaDescriptor::PROP_ENCRYPTIONDATA] <<= aEncryptionData;
+
+ // validation fails with "zip END header not found"
+ skipValidation();
+ }
+ }
+
+ saveWithParams(aMediaDescriptor.getAsConstPropertyValueList());
+
+ if (!mbSkipValidation)
+ {
+ if (rFilter == "Calc Office Open XML")
+ validate(maTempFile.GetFileName(), test::OOXML);
+ /*
+ // too many validation errors right now
+ else if (rFilter == "Office Open XML Text")
+ validate(maTempFile.GetFileName(), test::OOXML);
+ */
+ else if (rFilter == "Impress Office Open XML")
+ validate(maTempFile.GetFileName(), test::OOXML);
+ else if (rFilter == "writer8")
+ validate(maTempFile.GetFileName(), test::ODF);
+ else if (rFilter == "calc8")
+ validate(maTempFile.GetFileName(), test::ODF);
+ else if (rFilter == "impress8")
+ validate(maTempFile.GetFileName(), test::ODF);
+ else if (rFilter == "draw8")
+ validate(maTempFile.GetFileName(), test::ODF);
+ else if (rFilter == "OpenDocument Text Flat XML")
+ validate(maTempFile.GetFileName(), test::ODF);
+ else if (rFilter == "MS Word 97")
+ validate(maTempFile.GetFileName(), test::MSBINARY);
+ else if (rFilter == "MS Excel 97")
+ validate(maTempFile.GetFileName(), test::MSBINARY);
+ else if (rFilter == "MS PowerPoint 97")
+ validate(maTempFile.GetFileName(), test::MSBINARY);
+ }
+}
+
+void UnoApiTest::saveWithParams(const uno::Sequence<beans::PropertyValue>& rParams)
+{
+ css::uno::Reference<frame::XStorable> xStorable(mxComponent, css::uno::UNO_QUERY_THROW);
+ xStorable->storeToURL(maTempFile.GetURL(), rParams);
+}
+
+void UnoApiTest::saveAndReload(const OUString& rFilter, const char* pPassword)
+{
+ save(rFilter, pPassword);
+
+ load(maTempFile.GetURL(), pPassword);
+}
+
+std::unique_ptr<vcl::pdf::PDFiumDocument> UnoApiTest::parsePDFExport(const OString& rPassword)
+{
+ SvFileStream aFile(maTempFile.GetURL(), StreamMode::READ);
+ maMemory.WriteStream(aFile);
+ std::shared_ptr<vcl::pdf::PDFium> pPDFium = vcl::pdf::PDFiumLibrary::get();
+ if (!pPDFium)
+ {
+ return nullptr;
+ }
+ std::unique_ptr<vcl::pdf::PDFiumDocument> pPdfDocument
+ = pPDFium->openDocument(maMemory.GetData(), maMemory.GetSize(), rPassword);
+ CPPUNIT_ASSERT(pPdfDocument);
+ return pPdfDocument;
+}
+
+void UnoApiTest::createTempCopy(std::u16string_view fileName)
+{
+ OUString url = createFileURL(fileName);
+ auto const e = osl::File::copy(url, maTempFile.GetURL());
+ CPPUNIT_ASSERT_EQUAL(osl::FileBase::E_None, e);
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/test/source/unoapixml_test.cxx b/test/source/unoapixml_test.cxx
new file mode 100644
index 0000000000..23dc826cbc
--- /dev/null
+++ b/test/source/unoapixml_test.cxx
@@ -0,0 +1,36 @@
+/* -*- 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 <test/unoapixml_test.hxx>
+
+#include <com/sun/star/frame/Desktop.hpp>
+#include <com/sun/star/frame/XStorable.hpp>
+#include <comphelper/processfactory.hxx>
+#include <comphelper/propertyvalue.hxx>
+
+#include <sfx2/app.hxx>
+#include <sfx2/objsh.hxx>
+#include <utility>
+
+using namespace css;
+using namespace css::uno;
+
+UnoApiXmlTest::UnoApiXmlTest(OUString path)
+ : UnoApiTest(path)
+{
+}
+
+xmlDocUniquePtr UnoApiXmlTest::parseExport(OUString const& rStreamName)
+{
+ std::unique_ptr<SvStream> const pStream(parseExportStream(maTempFile.GetURL(), rStreamName));
+ xmlDocUniquePtr pXmlDoc = parseXmlStream(pStream.get());
+ return pXmlDoc;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/test/source/util/searchdescriptor.cxx b/test/source/util/searchdescriptor.cxx
new file mode 100644
index 0000000000..d829945583
--- /dev/null
+++ b/test/source/util/searchdescriptor.cxx
@@ -0,0 +1,63 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * 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 <test/util/searchdescriptor.hxx>
+#include <test/unoapi_property_testers.hxx>
+
+#include <com/sun/star/beans/XPropertySet.hpp>
+
+#include <com/sun/star/uno/Reference.hxx>
+
+using namespace css;
+
+namespace apitest
+{
+void SearchDescriptor::testSearchDescriptorProperties()
+{
+ uno::Reference<beans::XPropertySet> xPS(init(), uno::UNO_QUERY_THROW);
+
+ OUString aPropName;
+
+ aPropName = "SearchBackwards";
+ testBooleanProperty(xPS, aPropName);
+
+ aPropName = "SearchCaseSensitive";
+ testBooleanProperty(xPS, aPropName);
+
+ aPropName = "SearchWords";
+ testBooleanProperty(xPS, aPropName);
+
+ aPropName = "SearchRegularExpression";
+ testBooleanProperty(xPS, aPropName);
+
+ aPropName = "SearchStyles";
+ testBooleanProperty(xPS, aPropName);
+
+ aPropName = "SearchSimilarity";
+ testBooleanProperty(xPS, aPropName);
+
+ aPropName = "SearchSimilarityRelax";
+ testBooleanProperty(xPS, aPropName);
+
+ aPropName = "SearchSimilarityRemove";
+ testShortProperty(xPS, aPropName);
+
+ aPropName = "SearchSimilarityAdd";
+ testShortProperty(xPS, aPropName);
+
+ aPropName = "SearchSimilarityExchange";
+ testShortProperty(xPS, aPropName);
+
+ aPropName = "SearchWildcard";
+ testBooleanOptionalProperty(xPS, aPropName);
+}
+
+} // namespace apitest
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/test/source/util/xindent.cxx b/test/source/util/xindent.cxx
new file mode 100644
index 0000000000..6b15407f97
--- /dev/null
+++ b/test/source/util/xindent.cxx
@@ -0,0 +1,54 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+* 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 <test/util/xindent.hxx>
+
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/util/XIndent.hpp>
+
+#include <com/sun/star/uno/Any.hxx>
+#include <com/sun/star/uno/Reference.hxx>
+
+#include <cppunit/TestAssert.h>
+
+using namespace com::sun::star;
+using namespace com::sun::star::uno;
+
+namespace apitest
+{
+void XIndent::testIncrementIndent()
+{
+ uno::Reference<util::XIndent> xIndent(init(), UNO_QUERY_THROW);
+ uno::Reference<beans::XPropertySet> xPropertySet(xIndent, UNO_QUERY_THROW);
+ uno::Any aAny = xPropertySet->getPropertyValue("ParaIndent");
+ sal_Int32 nOldValue = aAny.get<sal_Int32>();
+
+ xIndent->incrementIndent();
+
+ uno::Any aAny2 = xPropertySet->getPropertyValue("ParaIndent");
+ sal_Int32 nNewValue = aAny2.get<sal_Int32>();
+ CPPUNIT_ASSERT_MESSAGE("Successfully able to Increment Indent", nOldValue < nNewValue);
+}
+void XIndent::testDecrementIndent()
+{
+ uno::Reference<util::XIndent> xIndent(init(), UNO_QUERY_THROW);
+ uno::Reference<beans::XPropertySet> xPropertySet(xIndent, UNO_QUERY_THROW);
+ xIndent->incrementIndent();
+ uno::Any aAny = xPropertySet->getPropertyValue("ParaIndent");
+ sal_Int32 nOldValue = aAny.get<sal_Int32>();
+
+ xIndent->decrementIndent();
+
+ uno::Any aAny2 = xPropertySet->getPropertyValue("ParaIndent");
+ sal_Int32 nNewValue = aAny2.get<sal_Int32>();
+ CPPUNIT_ASSERT_MESSAGE("Successfully able to Decrement Indent", nOldValue > nNewValue);
+}
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/test/source/util/xmergeable.cxx b/test/source/util/xmergeable.cxx
new file mode 100644
index 0000000000..211b2b67f4
--- /dev/null
+++ b/test/source/util/xmergeable.cxx
@@ -0,0 +1,33 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+* 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 <test/util/xmergeable.hxx>
+
+#include <com/sun/star/util/XMergeable.hpp>
+
+#include <com/sun/star/uno/Reference.hxx>
+
+#include <cppunit/TestAssert.h>
+
+using namespace com::sun::star;
+using namespace com::sun::star::uno;
+
+namespace apitest
+{
+void XMergeable::testGetIsMergedMerge()
+{
+ uno::Reference<util::XMergeable> xMergeable(init(), UNO_QUERY_THROW);
+ bool aIsMerged = xMergeable->getIsMerged();
+ xMergeable->merge(!aIsMerged);
+ bool aIsMerged2 = xMergeable->getIsMerged();
+ CPPUNIT_ASSERT_MESSAGE("Successfully able to Get is Merged and Merge", aIsMerged != aIsMerged2);
+}
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/test/source/util/xrefreshable.cxx b/test/source/util/xrefreshable.cxx
new file mode 100644
index 0000000000..5d145e5b2f
--- /dev/null
+++ b/test/source/util/xrefreshable.cxx
@@ -0,0 +1,64 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * 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 <test/util/xrefreshable.hxx>
+
+#include <com/sun/star/lang/EventObject.hpp>
+#include <com/sun/star/util/XRefreshListener.hpp>
+#include <com/sun/star/util/XRefreshable.hpp>
+
+#include <com/sun/star/uno/Reference.hxx>
+
+#include <cppuhelper/implbase.hxx>
+#include <rtl/ref.hxx>
+
+#include <cppunit/TestAssert.h>
+
+using namespace com::sun::star;
+using namespace com::sun::star::uno;
+
+namespace apitest
+{
+namespace
+{
+class MockedRefreshListener : public ::cppu::WeakImplHelper<util::XRefreshListener>
+{
+public:
+ MockedRefreshListener()
+ : m_bListenerCalled(false)
+ {
+ }
+
+ bool m_bListenerCalled;
+ virtual void SAL_CALL refreshed(const lang::EventObject& /* xEvent */) override
+ {
+ m_bListenerCalled = true;
+ }
+ virtual void SAL_CALL disposing(const lang::EventObject& /* xEventObj */) override {}
+};
+}
+
+void XRefreshable::testRefreshListener()
+{
+ uno::Reference<util::XRefreshable> xRefreshable(init(), uno::UNO_QUERY_THROW);
+
+ rtl::Reference<MockedRefreshListener> xListener = new MockedRefreshListener();
+ xRefreshable->addRefreshListener(uno::Reference<util::XRefreshListener>(xListener));
+
+ xRefreshable->refresh();
+ CPPUNIT_ASSERT(xListener->m_bListenerCalled);
+
+ xListener->m_bListenerCalled = false;
+ xRefreshable->removeRefreshListener(uno::Reference<util::XRefreshListener>(xListener));
+ xRefreshable->refresh();
+ CPPUNIT_ASSERT(!xListener->m_bListenerCalled);
+}
+
+} // namespace apitest
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/test/source/util/xreplaceable.cxx b/test/source/util/xreplaceable.cxx
new file mode 100644
index 0000000000..4e315c6653
--- /dev/null
+++ b/test/source/util/xreplaceable.cxx
@@ -0,0 +1,88 @@
+/* -*- 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 <test/util/xreplaceable.hxx>
+
+#include <com/sun/star/util/XReplaceable.hpp>
+#include <com/sun/star/util/XReplaceDescriptor.hpp>
+#include <com/sun/star/util/XSearchDescriptor.hpp>
+#include <cppunit/TestAssert.h>
+
+#include <iostream>
+
+#include <test/callgrind.hxx>
+
+using namespace css;
+using namespace css::uno;
+
+namespace apitest
+{
+void XReplaceable::testCreateReplaceDescriptor()
+{
+ uno::Reference<util::XReplaceable> xReplaceable(init(), UNO_QUERY_THROW);
+ uno::Reference<util::XReplaceDescriptor> xReplaceDescr
+ = xReplaceable->createReplaceDescriptor();
+ CPPUNIT_ASSERT(xReplaceDescr.is());
+}
+
+void XReplaceable::testReplaceAll()
+{
+ std::cout << "testReplaceAll" << std::endl;
+ uno::Reference<util::XReplaceable> xReplaceable(init(), UNO_QUERY_THROW);
+ uno::Reference<util::XReplaceDescriptor> xReplaceDescr
+ = xReplaceable->createReplaceDescriptor();
+ CPPUNIT_ASSERT(xReplaceDescr.is());
+
+ uno::Reference<util::XSearchDescriptor> xSearchDescr = xReplaceable->createSearchDescriptor();
+ xSearchDescr->setSearchString(maSearchString);
+
+ //check that at least one object is there that will be replaced
+ uno::Reference<uno::XInterface> xElement = xReplaceable->findFirst(xSearchDescr);
+ CPPUNIT_ASSERT(xElement.is());
+
+ //check that there is none object with the replace string
+ xSearchDescr->setSearchString(maReplaceString);
+ xElement = xReplaceable->findFirst(xSearchDescr);
+ CPPUNIT_ASSERT(!xElement.is());
+
+ xReplaceDescr->setSearchString(maSearchString);
+ xReplaceDescr->setReplaceString(maReplaceString);
+
+ callgrindStart();
+ xReplaceable->replaceAll(
+ uno::Reference<util::XSearchDescriptor>(xReplaceDescr, UNO_QUERY_THROW));
+ callgrindDump("test:replace_all");
+
+ //check that now at least one element is found
+ xElement = xReplaceable->findFirst(xSearchDescr);
+ CPPUNIT_ASSERT(xElement.is());
+
+ xSearchDescr->setSearchString(maSearchString);
+ xElement = xReplaceable->findFirst(xSearchDescr);
+ CPPUNIT_ASSERT(!xElement.is());
+
+ //redo the whole thing
+ xReplaceDescr->setSearchString(maReplaceString);
+ xReplaceDescr->setReplaceString(maSearchString);
+
+ xReplaceable->replaceAll(
+ uno::Reference<util::XSearchDescriptor>(xReplaceDescr, UNO_QUERY_THROW));
+
+ //check that it works
+ xElement = xReplaceable->findFirst(xSearchDescr);
+ CPPUNIT_ASSERT(xElement.is());
+
+ //check that there is none object with the replace string
+ xSearchDescr->setSearchString(maReplaceString);
+ xElement = xReplaceable->findFirst(xSearchDescr);
+ CPPUNIT_ASSERT(!xElement.is());
+}
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/test/source/util/xreplacedescriptor.cxx b/test/source/util/xreplacedescriptor.cxx
new file mode 100644
index 0000000000..b3b042a2d8
--- /dev/null
+++ b/test/source/util/xreplacedescriptor.cxx
@@ -0,0 +1,37 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * 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 <test/util/xreplacedescriptor.hxx>
+#include <rtl/ustring.hxx>
+
+#include <com/sun/star/util/XReplaceDescriptor.hpp>
+
+#include <com/sun/star/uno/Reference.hxx>
+
+#include <cppunit/TestAssert.h>
+
+using namespace css;
+
+namespace apitest
+{
+void XReplaceDescriptor::testGetSetReplaceString()
+{
+ uno::Reference<util::XReplaceDescriptor> xRD(init(), uno::UNO_QUERY_THROW);
+ const OUString aReplaceStringOld = xRD->getReplaceString();
+ CPPUNIT_ASSERT(aReplaceStringOld.isEmpty());
+
+ xRD->setReplaceString("_XReplaceDescriptor");
+ const OUString aReplaceStringNew = xRD->getReplaceString();
+ CPPUNIT_ASSERT_EQUAL(OUString("_XReplaceDescriptor"), aReplaceStringNew);
+ CPPUNIT_ASSERT(aReplaceStringOld != aReplaceStringNew);
+}
+
+} // namespace apitest
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/test/source/util/xsearchable.cxx b/test/source/util/xsearchable.cxx
new file mode 100644
index 0000000000..15b0cecde2
--- /dev/null
+++ b/test/source/util/xsearchable.cxx
@@ -0,0 +1,62 @@
+/* -*- 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 <com/sun/star/util/XSearchable.hpp>
+#include <com/sun/star/util/XSearchDescriptor.hpp>
+#include <com/sun/star/container/XIndexAccess.hpp>
+#include <cppunit/TestAssert.h>
+
+#include <test/util/xsearchable.hxx>
+
+using namespace css;
+using namespace css::uno;
+
+namespace apitest
+{
+void XSearchable::testFindAll()
+{
+ uno::Reference<util::XSearchable> xSearchable(init(), UNO_QUERY_THROW);
+ uno::Reference<util::XSearchDescriptor> xSearchDescr = xSearchable->createSearchDescriptor();
+ xSearchDescr->setSearchString(maSearchString);
+
+ uno::Reference<container::XIndexAccess> xIndex = xSearchable->findAll(xSearchDescr);
+ CPPUNIT_ASSERT(xIndex.is());
+ CPPUNIT_ASSERT_EQUAL(mnCount, xIndex->getCount());
+}
+
+void XSearchable::testFindFirst()
+{
+ uno::Reference<util::XSearchable> xSearchable(init(), UNO_QUERY_THROW);
+ uno::Reference<util::XSearchDescriptor> xSearchDescr = xSearchable->createSearchDescriptor();
+ xSearchDescr->setSearchString(maSearchString);
+
+ uno::Reference<uno::XInterface> xElement = xSearchable->findFirst(xSearchDescr);
+ CPPUNIT_ASSERT(xElement.is());
+}
+
+void XSearchable::testFindNext()
+{
+ uno::Reference<util::XSearchable> xSearchable(init(), UNO_QUERY_THROW);
+ uno::Reference<util::XSearchDescriptor> xSearchDescr = xSearchable->createSearchDescriptor();
+ xSearchDescr->setSearchString(maSearchString);
+
+ uno::Reference<uno::XInterface> xElement = xSearchable->findFirst(xSearchDescr);
+ CPPUNIT_ASSERT(xElement.is());
+
+ if (mnCount > 1)
+ {
+ uno::Reference<uno::XInterface> xElement2 = xSearchable->findNext(xElement, xSearchDescr);
+ CPPUNIT_ASSERT(xElement2.is());
+ }
+}
+
+XSearchable::~XSearchable() {}
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/test/source/util/xsearchdescriptor.cxx b/test/source/util/xsearchdescriptor.cxx
new file mode 100644
index 0000000000..2740b2e266
--- /dev/null
+++ b/test/source/util/xsearchdescriptor.cxx
@@ -0,0 +1,36 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * 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 <test/util/xsearchdescriptor.hxx>
+
+#include <com/sun/star/util/XSearchDescriptor.hpp>
+
+#include <com/sun/star/uno/Reference.hxx>
+
+#include <cppunit/TestAssert.h>
+
+using namespace css;
+
+namespace apitest
+{
+void XSearchDescriptor::testGetSetSearchString()
+{
+ uno::Reference<util::XSearchDescriptor> xDS(init(), uno::UNO_QUERY_THROW);
+ const OUString aSearchStringOld = xDS->getSearchString();
+ CPPUNIT_ASSERT(aSearchStringOld.isEmpty());
+
+ xDS->setSearchString("_XSearchDescriptor");
+ const OUString aSearchStringNew = xDS->getSearchString();
+ CPPUNIT_ASSERT_EQUAL(OUString("_XSearchDescriptor"), aSearchStringNew);
+ CPPUNIT_ASSERT(aSearchStringOld != aSearchStringNew);
+}
+
+} // namespace apitest
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/test/source/vclbootstrapprotector.cxx b/test/source/vclbootstrapprotector.cxx
new file mode 100644
index 0000000000..f6d1b97620
--- /dev/null
+++ b/test/source/vclbootstrapprotector.cxx
@@ -0,0 +1,56 @@
+/* -*- 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 <cppunit/Protector.h>
+#include <sal/types.h>
+#include <sal/log.hxx>
+#include <vcl/svapp.hxx>
+#include <comphelper/threadpool.hxx>
+#include "setupvcl.hxx"
+
+namespace {
+
+class Protector: public CppUnit::Protector {
+public:
+ Protector() { test::setUpVcl(); }
+ Protector(const Protector&) = delete;
+ Protector& operator=(const Protector&) = delete;
+
+private:
+ virtual ~Protector() override {
+#if defined(__COVERITY__)
+ try {
+#endif
+ DeInitVCL();
+ // for the 6 tests that use it
+ comphelper::ThreadPool::getSharedOptimalPool().shutdown();
+#if defined(__COVERITY__)
+ } catch (const std::exception& e) {
+ SAL_WARN("vcl.app", "Fatal exception: " << e.what());
+ std::terminate();
+ }
+#endif
+ }
+
+ virtual bool protect(
+ CppUnit::Functor const & functor, CppUnit::ProtectorContext const &)
+ override
+ { return functor(); }
+};
+
+}
+
+extern "C" SAL_DLLPUBLIC_EXPORT CppUnit::Protector *
+vclbootstrapprotector() {
+ return new Protector;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/test/source/view/xcontrolaccess.cxx b/test/source/view/xcontrolaccess.cxx
new file mode 100644
index 0000000000..43a98c9c86
--- /dev/null
+++ b/test/source/view/xcontrolaccess.cxx
@@ -0,0 +1,56 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * 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 <test/view/xcontrolaccess.hxx>
+#include <test/helper/form.hxx>
+
+#include <com/sun/star/awt/XControl.hpp>
+#include <com/sun/star/awt/XControlModel.hpp>
+#include <com/sun/star/drawing/XControlShape.hpp>
+#include <com/sun/star/drawing/XDrawPage.hpp>
+#include <com/sun/star/drawing/XDrawPagesSupplier.hpp>
+#include <com/sun/star/drawing/XShape.hpp>
+#include <com/sun/star/drawing/XShapes.hpp>
+#include <com/sun/star/lang/XComponent.hpp>
+#include <com/sun/star/view/XControlAccess.hpp>
+
+#include <com/sun/star/uno/Reference.hxx>
+
+#include <cppunit/TestAssert.h>
+
+using namespace css;
+
+namespace apitest
+{
+void XControlAccess::testGetControl()
+{
+ uno::Reference<view::XControlAccess> xCA(init(), uno::UNO_QUERY_THROW);
+
+ uno::Reference<lang::XComponent> xComponent(getXComponent(), uno::UNO_QUERY_THROW);
+ uno::Reference<drawing::XDrawPagesSupplier> xDPS(xComponent, uno::UNO_QUERY_THROW);
+ uno::Reference<drawing::XDrawPage> xDP(xDPS->getDrawPages()->getByIndex(0),
+ uno::UNO_QUERY_THROW);
+
+ uno::Reference<drawing::XShapes> xShapes(xDP, uno::UNO_QUERY_THROW);
+ uno::Reference<drawing::XShape> xShape(
+ helper::form::createControlShape(xComponent, u"CommandButton", 10000, 50000, 100, 100),
+ uno::UNO_QUERY_THROW);
+
+ xShapes->add(xShape);
+
+ uno::Reference<drawing::XControlShape> xCS(xShape, uno::UNO_QUERY_THROW);
+ uno::Reference<awt::XControlModel> xCM(xCS->getControl(), uno::UNO_SET_THROW);
+ uno::Reference<awt::XControl> xControl(xCA->getControl(xCM), uno::UNO_SET_THROW);
+
+ CPPUNIT_ASSERT(xControl.is());
+}
+
+} // namespace apitest
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/test/source/view/xformlayeraccess.cxx b/test/source/view/xformlayeraccess.cxx
new file mode 100644
index 0000000000..68903fcc02
--- /dev/null
+++ b/test/source/view/xformlayeraccess.cxx
@@ -0,0 +1,56 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * 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 <test/view/xformlayeraccess.hxx>
+
+#include <com/sun/star/form/runtime/XFormController.hpp>
+#include <com/sun/star/view/XFormLayerAccess.hpp>
+
+#include <com/sun/star/uno/Reference.hxx>
+
+#include <cppunit/TestAssert.h>
+
+using namespace css;
+
+namespace apitest
+{
+void XFormLayerAccess::testGetFormController()
+{
+ uno::Reference<view::XFormLayerAccess> xFLA(init(), uno::UNO_QUERY_THROW);
+
+ const bool bCurrentMode = xFLA->isFormDesignMode();
+
+ // deliberately don't use UNO_QUERY_THROW, so we can use
+ // uno::XInterface::is() in CPPUNIT_ASSERT()
+ xFLA->setFormDesignMode(false);
+ uno::Reference<form::runtime::XFormController> xFC = xFLA->getFormController(m_xForm);
+ CPPUNIT_ASSERT(xFC.is());
+
+ xFLA->setFormDesignMode(bCurrentMode);
+}
+
+void XFormLayerAccess::testIsFormDesignMode() { testSetFormDesignMode(); }
+
+void XFormLayerAccess::testSetFormDesignMode()
+{
+ uno::Reference<view::XFormLayerAccess> xFLA(init(), uno::UNO_QUERY_THROW);
+
+ const bool bCurrentMode = xFLA->isFormDesignMode();
+ xFLA->setFormDesignMode(!bCurrentMode);
+
+ const bool bNewMode = xFLA->isFormDesignMode();
+ CPPUNIT_ASSERT_EQUAL(!bCurrentMode, bNewMode);
+
+ xFLA->setFormDesignMode(bCurrentMode);
+ CPPUNIT_ASSERT_EQUAL(bCurrentMode, static_cast<bool>(xFLA->isFormDesignMode()));
+}
+
+} // namespace apitest
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/test/source/xmltesttools.cxx b/test/source/xmltesttools.cxx
new file mode 100644
index 0000000000..14f953557f
--- /dev/null
+++ b/test/source/xmltesttools.cxx
@@ -0,0 +1,462 @@
+/* -*- 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 <test/xmltesttools.hxx>
+
+#include <memory>
+
+#include <vcl/mtfxmldump.hxx>
+#include <sal/log.hxx>
+
+namespace {
+
+OUString convert(xmlChar const * string) {
+ OUString s;
+ CPPUNIT_ASSERT_MESSAGE(
+ "xmlChar string is not UTF-8",
+ rtl_convertStringToUString(
+ &s.pData, reinterpret_cast<char const *>(string), xmlStrlen(string),
+ RTL_TEXTENCODING_UTF8,
+ (RTL_TEXTTOUNICODE_FLAGS_UNDEFINED_ERROR
+ | RTL_TEXTTOUNICODE_FLAGS_MBUNDEFINED_ERROR
+ | RTL_TEXTTOUNICODE_FLAGS_INVALID_ERROR)));
+ return s;
+}
+
+OString oconvert(xmlChar const * string)
+{
+ return reinterpret_cast<char const *>(string);
+}
+
+}
+
+XmlTestTools::XmlTestTools()
+{}
+
+XmlTestTools::~XmlTestTools()
+{}
+
+xmlDocUniquePtr XmlTestTools::parseXml(utl::TempFileNamed const & aTempFile)
+{
+ SvFileStream aFileStream(aTempFile.GetURL(), StreamMode::READ);
+ return parseXmlStream(&aFileStream);
+}
+
+xmlDocUniquePtr XmlTestTools::parseXmlStream(SvStream* pStream)
+{
+ std::size_t nSize = pStream->remainingSize();
+ std::unique_ptr<sal_uInt8[]> pBuffer(new sal_uInt8[nSize + 1]);
+ pStream->ReadBytes(pBuffer.get(), nSize);
+ pBuffer[nSize] = 0;
+ auto pCharBuffer = reinterpret_cast<xmlChar*>(pBuffer.get());
+ SAL_INFO("test", "XmlTestTools::parseXmlStream: pBuffer is '" << pCharBuffer << "'");
+ return xmlDocUniquePtr(xmlParseDoc(pCharBuffer));
+}
+
+xmlDocUniquePtr XmlTestTools::dumpAndParse(MetafileXmlDump& rDumper, const GDIMetaFile& rGDIMetaFile)
+{
+ SvMemoryStream aStream;
+ rDumper.dump(rGDIMetaFile, aStream);
+ aStream.Seek(STREAM_SEEK_TO_BEGIN);
+ return XmlTestTools::parseXmlStream(&aStream);
+}
+
+xmlXPathObjectPtr XmlTestTools::getXPathNode(const xmlDocUniquePtr& pXmlDoc, const OString& rXPath)
+{
+ xmlXPathContextPtr pXmlXpathCtx = xmlXPathNewContext(pXmlDoc.get());
+ registerNamespaces(pXmlXpathCtx);
+ xmlXPathObjectPtr pXmlXpathObj = xmlXPathEvalExpression(BAD_CAST(rXPath.getStr()), pXmlXpathCtx);
+ xmlXPathFreeContext(pXmlXpathCtx);
+ return pXmlXpathObj;
+}
+
+void XmlTestTools::registerNamespaces(xmlXPathContextPtr& pXmlXpathCtx)
+{
+ // ooxml
+ XmlTestTools::registerOOXMLNamespaces(pXmlXpathCtx);
+ // odf
+ XmlTestTools::registerODFNamespaces(pXmlXpathCtx);
+ // reqif-xhtml
+ xmlXPathRegisterNs(pXmlXpathCtx, BAD_CAST("reqif-xhtml"), BAD_CAST("http://www.w3.org/1999/xhtml"));
+}
+
+OUString XmlTestTools::getXPath(const xmlDocUniquePtr& pXmlDoc, const OString& rXPath, const OString& rAttribute)
+{
+ CPPUNIT_ASSERT(pXmlDoc);
+ xmlXPathObjectPtr pXmlObj = getXPathNode(pXmlDoc, rXPath);
+ CPPUNIT_ASSERT(pXmlObj);
+ xmlNodeSetPtr pXmlNodes = pXmlObj->nodesetval;
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(OString(OString::Concat("In <") + pXmlDoc->name + ">, XPath '" + rXPath + "' number of nodes is incorrect").getStr(),
+ 1, xmlXPathNodeSetGetLength(pXmlNodes));
+ CPPUNIT_ASSERT(!rAttribute.isEmpty());
+ xmlNodePtr pXmlNode = pXmlNodes->nodeTab[0];
+ xmlChar * prop = xmlGetProp(pXmlNode, BAD_CAST(rAttribute.getStr()));
+ OString sAttAbsent = OString::Concat("In <") + pXmlDoc->name + ">, XPath '" + rXPath
+ + "' no attribute '" + rAttribute + "' exist";
+ CPPUNIT_ASSERT_MESSAGE(sAttAbsent.getStr(), prop);
+ OUString s(convert(prop));
+ xmlFree(prop);
+ xmlXPathFreeObject(pXmlObj);
+ return s;
+}
+
+OUString XmlTestTools::getXPathContent(const xmlDocUniquePtr& pXmlDoc, const OString& rXPath)
+{
+ xmlXPathObjectPtr pXmlObj = getXPathNode(pXmlDoc, rXPath);
+ switch (pXmlObj->type)
+ {
+ case XPATH_UNDEFINED:
+ CPPUNIT_FAIL("Undefined XPath type");
+ case XPATH_NODESET:
+ {
+ xmlNodeSetPtr pXmlNodes = pXmlObj->nodesetval;
+
+ CPPUNIT_ASSERT_MESSAGE(
+ OString(OString::Concat("In <") + pXmlDoc->name + ">, XPath '" + rXPath + "' not found")
+ .getStr(),
+ xmlXPathNodeSetGetLength(pXmlNodes) > 0);
+
+ xmlNodePtr pXmlNode = pXmlNodes->nodeTab[0];
+ xmlNodePtr pXmlChild = pXmlNode->children;
+ OUString s;
+ while (pXmlChild && pXmlChild->type != XML_TEXT_NODE)
+ pXmlChild = pXmlChild->next;
+ if (pXmlChild && pXmlChild->type == XML_TEXT_NODE)
+ s = convert(pXmlChild->content);
+ xmlXPathFreeObject(pXmlObj);
+ return s;
+ }
+ case XPATH_BOOLEAN:
+ {
+ auto boolVal = pXmlObj->boolval;
+ xmlXPathFreeObject(pXmlObj);
+ return boolVal ? OUString("true") : OUString("false");
+ }
+ case XPATH_NUMBER:
+ {
+ auto floatVal = pXmlObj->floatval;
+ xmlXPathFreeObject(pXmlObj);
+ return OUString::number(floatVal);
+ }
+ case XPATH_STRING:
+ {
+ auto convertedVal = convert(pXmlObj->stringval);
+ xmlXPathFreeObject(pXmlObj);
+ return convertedVal;
+ }
+#if LIBXML_VERSION < 21000 || defined(LIBXML_XPTR_LOCS_ENABLED)
+ case XPATH_POINT:
+ case XPATH_RANGE:
+ case XPATH_LOCATIONSET:
+#endif
+ case XPATH_USERS:
+ case XPATH_XSLT_TREE:
+ xmlXPathFreeObject(pXmlObj);
+ CPPUNIT_FAIL("Unsupported XPath type");
+ }
+
+ CPPUNIT_FAIL("Invalid XPath type");
+}
+
+void XmlTestTools::assertXPath(const xmlDocUniquePtr& pXmlDoc, const OString& rXPath, const OString& rAttribute, const OUString& rExpectedValue)
+{
+ OUString aValue = getXPath(pXmlDoc, rXPath, rAttribute);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(OString(OString::Concat("In <") + pXmlDoc->name + ">, attribute '" + rAttribute + "' of '" + rXPath + "' incorrect value.").getStr(),
+ rExpectedValue, aValue);
+}
+
+void XmlTestTools::assertXPathDoubleValue(const xmlDocUniquePtr& pXmlDoc, const OString& rXPath, const OString& rAttribute, double expectedValue, double delta)
+{
+ OUString aValue = getXPath(pXmlDoc, rXPath, rAttribute);
+ double pathValue = aValue.toDouble();
+ CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE(std::string("In <") + std::string(pXmlDoc->name ? pXmlDoc->name : "") + ">, attribute '" + std::string(rAttribute) + "' of '" + std::string(rXPath) + "' incorrect value.",
+ expectedValue, pathValue, delta);
+}
+
+void XmlTestTools::assertXPathAttrs(const xmlDocUniquePtr& pXmlDoc, const OString& rXPath,
+ const std::vector<std::pair<OString, OUString>>& aPairVector)
+{
+ for (auto& rPair : aPairVector)
+ {
+ assertXPath(pXmlDoc, rXPath, rPair.first, rPair.second);
+ }
+}
+
+int XmlTestTools::countXPathNodes(const xmlDocUniquePtr& pXmlDoc, const OString& rXPath)
+{
+ xmlXPathObjectPtr pXmlObj = getXPathNode(pXmlDoc, rXPath);
+ xmlNodeSetPtr pXmlNodes = pXmlObj->nodesetval;
+ const int n = xmlXPathNodeSetGetLength(pXmlNodes);
+ xmlXPathFreeObject(pXmlObj);
+ return n;
+}
+
+void XmlTestTools::assertXPath(const xmlDocUniquePtr& pXmlDoc, const OString& rXPath, int nNumberOfNodes)
+{
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(OString(OString::Concat("In <") + pXmlDoc->name + ">, XPath '" + rXPath + "' number of nodes is incorrect").getStr(),
+ nNumberOfNodes, countXPathNodes(pXmlDoc, rXPath));
+}
+
+void XmlTestTools::assertXPathContent(const xmlDocUniquePtr& pXmlDoc, const OString& rXPath, const OUString& rContent)
+{
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(OString(OString::Concat("In <") + pXmlDoc->name + ">, XPath contents of child does not match").getStr(), rContent, getXPathContent(pXmlDoc, rXPath));
+}
+
+void XmlTestTools::assertXPathNSDef(const xmlDocUniquePtr& pXmlDoc, const OString& rXPath,
+ std::u16string_view rNSPrefix, std::u16string_view rNSHref)
+{
+ xmlXPathObjectPtr pXmlObj = getXPathNode(pXmlDoc, rXPath);
+ xmlNodeSetPtr pXmlNodes = pXmlObj->nodesetval;
+ CPPUNIT_ASSERT_MESSAGE(
+ OString(OString::Concat("In <") + pXmlDoc->name + ">, XPath '" + rXPath + "' not found").getStr(),
+ xmlXPathNodeSetGetLength(pXmlNodes) > 0);
+
+ xmlNodePtr pXmlNode = pXmlNodes->nodeTab[0];
+ bool bFound = false;
+ for (xmlNsPtr pNamespace = pXmlNode->nsDef; pNamespace; pNamespace = pNamespace->next)
+ {
+ if (!pNamespace->prefix)
+ continue;
+
+ CPPUNIT_ASSERT(pNamespace->href);
+ if (rNSPrefix == convert(pNamespace->prefix) && rNSHref == convert(pNamespace->href))
+ {
+ bFound = true;
+ break;
+ }
+ }
+ xmlXPathFreeObject(pXmlObj);
+ CPPUNIT_ASSERT(bFound);
+}
+
+void XmlTestTools::assertXPathChildren(const xmlDocUniquePtr& pXmlDoc, const OString& rXPath, int nNumberOfChildNodes)
+{
+#if LIBXML_VERSION >= 20703 /* xmlChildElementCount is only available in libxml2 >= 2.7.3 */
+ xmlXPathObjectPtr pXmlObj = getXPathNode(pXmlDoc, rXPath);
+ xmlNodeSetPtr pXmlNodes = pXmlObj->nodesetval;
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(OString(OString::Concat("In <") + pXmlDoc->name + ">, XPath '" + rXPath + "' number of nodes is incorrect").getStr(),
+ 1, xmlXPathNodeSetGetLength(pXmlNodes));
+ xmlNodePtr pXmlNode = pXmlNodes->nodeTab[0];
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(OString(OString::Concat("In <") + pXmlDoc->name + ">, XPath '" + rXPath + "' number of child-nodes is incorrect").getStr(),
+ nNumberOfChildNodes, static_cast<int>(xmlChildElementCount(pXmlNode)));
+ xmlXPathFreeObject(pXmlObj);
+#else
+ (void)pXmlDoc;
+ (void)rXPath;
+ (void)nNumberOfChildNodes;
+#endif
+}
+
+void XmlTestTools::assertXPathNoAttribute(const xmlDocUniquePtr& pXmlDoc, const OString& rXPath, const OString& rAttribute)
+{
+ xmlXPathObjectPtr pXmlObj = getXPathNode(pXmlDoc, rXPath);
+ xmlNodeSetPtr pXmlNodes = pXmlObj->nodesetval;
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(OString(OString::Concat("In <") + pXmlDoc->name + ">, XPath '" + rXPath + "' number of nodes is incorrect").getStr(),
+ 1, xmlXPathNodeSetGetLength(pXmlNodes));
+ xmlNodePtr pXmlNode = pXmlNodes->nodeTab[0];
+ CPPUNIT_ASSERT_MESSAGE(OString(OString::Concat("In <") + pXmlDoc->name + ">, XPath '" + rXPath + "' unexpected '" + rAttribute + "' attribute").getStr(),
+ !xmlGetProp(pXmlNode, BAD_CAST(rAttribute.getStr())));
+ xmlXPathFreeObject(pXmlObj);
+}
+
+int XmlTestTools::getXPathPosition(const xmlDocUniquePtr& pXmlDoc, const OString& rXPath, std::string_view rChildName)
+{
+ xmlXPathObjectPtr pXmlObj = getXPathNode(pXmlDoc, rXPath);
+ xmlNodeSetPtr pXmlNodes = pXmlObj->nodesetval;
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(OString(OString::Concat("In <") + pXmlDoc->name + ">, XPath '" + rXPath + "' number of nodes is incorrect").getStr(),
+ 1,
+ xmlXPathNodeSetGetLength(pXmlNodes));
+ xmlNodePtr pXmlNode = pXmlNodes->nodeTab[0];
+ int nRet = 0;
+ bool bFound = false;
+ for (xmlNodePtr pChild = pXmlNode->children; pChild; pChild = pChild->next)
+ {
+ if (oconvert(pChild->name) == rChildName)
+ {
+ bFound = true;
+ break;
+ }
+ ++nRet;
+ }
+ xmlXPathFreeObject(pXmlObj);
+ CPPUNIT_ASSERT_MESSAGE(OString(OString::Concat("In <") + pXmlDoc->name + ">, XPath '" + rXPath
+ + "' child '" + rChildName + "' not found")
+ .getStr(),
+ bFound);
+ return nRet;
+}
+
+void XmlTestTools::registerODFNamespaces(xmlXPathContextPtr& pXmlXpathCtx)
+{
+ xmlXPathRegisterNs(pXmlXpathCtx, BAD_CAST("office"),
+ BAD_CAST("urn:oasis:names:tc:opendocument:xmlns:office:1.0"));
+ xmlXPathRegisterNs(pXmlXpathCtx, BAD_CAST("style"),
+ BAD_CAST("urn:oasis:names:tc:opendocument:xmlns:style:1.0"));
+ xmlXPathRegisterNs(pXmlXpathCtx, BAD_CAST("text"),
+ BAD_CAST("urn:oasis:names:tc:opendocument:xmlns:text:1.0"));
+ xmlXPathRegisterNs(pXmlXpathCtx, BAD_CAST("table"),
+ BAD_CAST("urn:oasis:names:tc:opendocument:xmlns:table:1.0"));
+ xmlXPathRegisterNs(pXmlXpathCtx, BAD_CAST("draw"),
+ BAD_CAST("urn:oasis:names:tc:opendocument:xmlns:drawing:1.0"));
+ xmlXPathRegisterNs(pXmlXpathCtx, BAD_CAST("fo"),
+ BAD_CAST("urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0"));
+ xmlXPathRegisterNs(pXmlXpathCtx, BAD_CAST("config"),
+ BAD_CAST("urn:oasis:names:tc:opendocument:xmlns:config:1.0"));
+ xmlXPathRegisterNs(pXmlXpathCtx, BAD_CAST("xlink"), BAD_CAST("http://www.w3.org/1999/xlink"));
+ xmlXPathRegisterNs(pXmlXpathCtx, BAD_CAST("dc"), BAD_CAST("http://purl.org/dc/elements/1.1/"));
+ xmlXPathRegisterNs(pXmlXpathCtx, BAD_CAST("meta"),
+ BAD_CAST("urn:oasis:names:tc:opendocument:xmlns:meta:1.0"));
+ xmlXPathRegisterNs(pXmlXpathCtx, BAD_CAST("number"),
+ BAD_CAST("urn:oasis:names:tc:opendocument:xmlns:datastyle:1.0"));
+ xmlXPathRegisterNs(pXmlXpathCtx, BAD_CAST("svg"),
+ BAD_CAST("urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0"));
+ xmlXPathRegisterNs(pXmlXpathCtx, BAD_CAST("chart"),
+ BAD_CAST("urn:oasis:names:tc:opendocument:xmlns:chart:1.0"));
+ xmlXPathRegisterNs(pXmlXpathCtx, BAD_CAST("dr3d"),
+ BAD_CAST("urn:oasis:names:tc:opendocument:xmlns:dr3d:1.0"));
+ xmlXPathRegisterNs(pXmlXpathCtx, BAD_CAST("math"),
+ BAD_CAST("http://www.w3.org/1998/Math/MathML"));
+ xmlXPathRegisterNs(pXmlXpathCtx, BAD_CAST("form"),
+ BAD_CAST("urn:oasis:names:tc:opendocument:xmlns:form:1.0"));
+ xmlXPathRegisterNs(pXmlXpathCtx, BAD_CAST("script"),
+ BAD_CAST("urn:oasis:names:tc:opendocument:xmlns:script:1.0"));
+ xmlXPathRegisterNs(pXmlXpathCtx, BAD_CAST("ooo"),
+ BAD_CAST("http://openoffice.org/2004/office"));
+ xmlXPathRegisterNs(pXmlXpathCtx, BAD_CAST("ooow"),
+ BAD_CAST("http://openoffice.org/2004/writer"));
+ xmlXPathRegisterNs(pXmlXpathCtx, BAD_CAST("oooc"), BAD_CAST("http://openoffice.org/2004/calc"));
+ xmlXPathRegisterNs(pXmlXpathCtx, BAD_CAST("dom"),
+ BAD_CAST("http://www.w3.org/2001/xml-events"));
+ xmlXPathRegisterNs(pXmlXpathCtx, BAD_CAST("xforms"), BAD_CAST("http://www.w3.org/2002/xforms"));
+ xmlXPathRegisterNs(pXmlXpathCtx, BAD_CAST("xsd"), BAD_CAST("http://www.w3.org/2001/XMLSchema"));
+ xmlXPathRegisterNs(pXmlXpathCtx, BAD_CAST("xsi"),
+ BAD_CAST("http://www.w3.org/2001/XMLSchema-instance"));
+ xmlXPathRegisterNs(pXmlXpathCtx, BAD_CAST("rpt"),
+ BAD_CAST("http://openoffice.org/2005/report"));
+ xmlXPathRegisterNs(pXmlXpathCtx, BAD_CAST("of"),
+ BAD_CAST("urn:oasis:names:tc:opendocument:xmlns:of:1.2"));
+ xmlXPathRegisterNs(pXmlXpathCtx, BAD_CAST("xhtml"), BAD_CAST("http://www.w3.org/1999/xhtml"));
+ xmlXPathRegisterNs(pXmlXpathCtx, BAD_CAST("grddl"),
+ BAD_CAST("http://www.w3.org/2003/g/data-view#"));
+ xmlXPathRegisterNs(pXmlXpathCtx, BAD_CAST("officeooo"),
+ BAD_CAST("http://openoffice.org/2009/office"));
+ xmlXPathRegisterNs(pXmlXpathCtx, BAD_CAST("tableooo"),
+ BAD_CAST("http://openoffice.org/2009/table"));
+ xmlXPathRegisterNs(pXmlXpathCtx, BAD_CAST("drawooo"),
+ BAD_CAST("http://openoffice.org/2010/draw"));
+ xmlXPathRegisterNs(
+ pXmlXpathCtx, BAD_CAST("calcext"),
+ BAD_CAST("urn:org:documentfoundation:names:experimental:calc:xmlns:calcext:1.0"));
+ xmlXPathRegisterNs(
+ pXmlXpathCtx, BAD_CAST("loext"),
+ BAD_CAST("urn:org:documentfoundation:names:experimental:office:xmlns:loext:1.0"));
+ xmlXPathRegisterNs(
+ pXmlXpathCtx, BAD_CAST("field"),
+ BAD_CAST("urn:openoffice:names:experimental:ooo-ms-interop:xmlns:field:1.0"));
+ xmlXPathRegisterNs(
+ pXmlXpathCtx, BAD_CAST("formx"),
+ BAD_CAST("urn:openoffice:names:experimental:ooxml-odf-interop:xmlns:form:1.0"));
+ xmlXPathRegisterNs(pXmlXpathCtx, BAD_CAST("css3t"),
+ BAD_CAST("http://www.w3.org/TR/css3-text/"));
+ xmlXPathRegisterNs(pXmlXpathCtx, BAD_CAST("anim"),
+ BAD_CAST("urn:oasis:names:tc:opendocument:xmlns:animation:1.0"));
+ xmlXPathRegisterNs(pXmlXpathCtx, BAD_CAST("smil"),
+ BAD_CAST("urn:oasis:names:tc:opendocument:xmlns:smil-compatible:1.0"));
+ xmlXPathRegisterNs(pXmlXpathCtx, BAD_CAST("presentation"),
+ BAD_CAST("urn:oasis:names:tc:opendocument:xmlns:presentation:1.0"));
+ // user-defined
+ xmlXPathRegisterNs(pXmlXpathCtx, BAD_CAST("foo"),
+ BAD_CAST("http://example.com/"));
+}
+
+void XmlTestTools::registerOOXMLNamespaces(xmlXPathContextPtr& pXmlXpathCtx)
+{
+ xmlXPathRegisterNs(pXmlXpathCtx, BAD_CAST("w"),
+ BAD_CAST("http://schemas.openxmlformats.org/wordprocessingml/2006/main"));
+ xmlXPathRegisterNs(pXmlXpathCtx, BAD_CAST("v"), BAD_CAST("urn:schemas-microsoft-com:vml"));
+ xmlXPathRegisterNs(pXmlXpathCtx, BAD_CAST("mc"),
+ BAD_CAST("http://schemas.openxmlformats.org/markup-compatibility/2006"));
+ xmlXPathRegisterNs(
+ pXmlXpathCtx, BAD_CAST("wps"),
+ BAD_CAST("http://schemas.microsoft.com/office/word/2010/wordprocessingShape"));
+ xmlXPathRegisterNs(
+ pXmlXpathCtx, BAD_CAST("wpg"),
+ BAD_CAST("http://schemas.microsoft.com/office/word/2010/wordprocessingGroup"));
+ xmlXPathRegisterNs(
+ pXmlXpathCtx, BAD_CAST("wp"),
+ BAD_CAST("http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing"));
+ xmlXPathRegisterNs(
+ pXmlXpathCtx, BAD_CAST("wp14"),
+ BAD_CAST("http://schemas.microsoft.com/office/word/2010/wordprocessingDrawing"));
+ xmlXPathRegisterNs(pXmlXpathCtx, BAD_CAST("a"),
+ BAD_CAST("http://schemas.openxmlformats.org/drawingml/2006/main"));
+ xmlXPathRegisterNs(pXmlXpathCtx, BAD_CAST("pic"),
+ BAD_CAST("http://schemas.openxmlformats.org/drawingml/2006/picture"));
+ xmlXPathRegisterNs(pXmlXpathCtx, BAD_CAST("rels"),
+ BAD_CAST("http://schemas.openxmlformats.org/package/2006/relationships"));
+ xmlXPathRegisterNs(pXmlXpathCtx, BAD_CAST("w14"),
+ BAD_CAST("http://schemas.microsoft.com/office/word/2010/wordml"));
+ xmlXPathRegisterNs(pXmlXpathCtx, BAD_CAST("w15"),
+ BAD_CAST("http://schemas.microsoft.com/office/word/2012/wordml"));
+ xmlXPathRegisterNs(pXmlXpathCtx, BAD_CAST("m"),
+ BAD_CAST("http://schemas.openxmlformats.org/officeDocument/2006/math"));
+ xmlXPathRegisterNs(pXmlXpathCtx, BAD_CAST("ContentType"),
+ BAD_CAST("http://schemas.openxmlformats.org/package/2006/content-types"));
+ xmlXPathRegisterNs(pXmlXpathCtx, BAD_CAST("lc"),
+ BAD_CAST("http://schemas.openxmlformats.org/drawingml/2006/lockedCanvas"));
+ xmlXPathRegisterNs(
+ pXmlXpathCtx, BAD_CAST("cp"),
+ BAD_CAST("http://schemas.openxmlformats.org/package/2006/metadata/core-properties"));
+ xmlXPathRegisterNs(
+ pXmlXpathCtx, BAD_CAST("extended-properties"),
+ BAD_CAST("http://schemas.openxmlformats.org/officeDocument/2006/extended-properties"));
+ xmlXPathRegisterNs(
+ pXmlXpathCtx, BAD_CAST("custom-properties"),
+ BAD_CAST("http://schemas.openxmlformats.org/officeDocument/2006/custom-properties"));
+ xmlXPathRegisterNs(
+ pXmlXpathCtx, BAD_CAST("vt"),
+ BAD_CAST("http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes"));
+ xmlXPathRegisterNs(pXmlXpathCtx, BAD_CAST("dcterms"), BAD_CAST("http://purl.org/dc/terms/"));
+ xmlXPathRegisterNs(pXmlXpathCtx, BAD_CAST("a14"),
+ BAD_CAST("http://schemas.microsoft.com/office/drawing/2010/main"));
+ xmlXPathRegisterNs(pXmlXpathCtx, BAD_CAST("c"),
+ BAD_CAST("http://schemas.openxmlformats.org/drawingml/2006/chart"));
+ xmlXPathRegisterNs(pXmlXpathCtx, BAD_CAST("x"),
+ BAD_CAST("http://schemas.openxmlformats.org/spreadsheetml/2006/main"));
+ xmlXPathRegisterNs(pXmlXpathCtx, BAD_CAST("r"),
+ BAD_CAST("http://schemas.openxmlformats.org/officeDocument/2006/relationships"));
+ xmlXPathRegisterNs(pXmlXpathCtx, BAD_CAST("xx"),
+ BAD_CAST("urn:schemas-microsoft-com:office:excel"));
+ xmlXPathRegisterNs(pXmlXpathCtx, BAD_CAST("xdr"),
+ BAD_CAST("http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing"));
+ xmlXPathRegisterNs(pXmlXpathCtx, BAD_CAST("x14"),
+ BAD_CAST("http://schemas.microsoft.com/office/spreadsheetml/2009/9/main"));
+ xmlXPathRegisterNs(pXmlXpathCtx, BAD_CAST("xm"),
+ BAD_CAST("http://schemas.microsoft.com/office/excel/2006/main"));
+ xmlXPathRegisterNs(pXmlXpathCtx, BAD_CAST("x12ac"),
+ BAD_CAST("http://schemas.microsoft.com/office/spreadsheetml/2011/1/ac"));
+ xmlXPathRegisterNs(pXmlXpathCtx, BAD_CAST("o"),
+ BAD_CAST("urn:schemas-microsoft-com:office:office"));
+ xmlXPathRegisterNs(pXmlXpathCtx, BAD_CAST("w10"),
+ BAD_CAST("urn:schemas-microsoft-com:office:word"));
+ xmlXPathRegisterNs(pXmlXpathCtx, BAD_CAST("p"),
+ BAD_CAST("http://schemas.openxmlformats.org/presentationml/2006/main"));
+ xmlXPathRegisterNs(pXmlXpathCtx, BAD_CAST("p14"),
+ BAD_CAST("http://schemas.microsoft.com/office/powerpoint/2010/main"));
+ xmlXPathRegisterNs(pXmlXpathCtx, BAD_CAST("dgm"),
+ BAD_CAST("http://schemas.openxmlformats.org/drawingml/2006/diagram"));
+ xmlXPathRegisterNs(pXmlXpathCtx, BAD_CAST("c15"),
+ BAD_CAST("http://schemas.microsoft.com/office/drawing/2012/chart"));
+ xmlXPathRegisterNs(pXmlXpathCtx, BAD_CAST("xr2"),
+ BAD_CAST("http://schemas.microsoft.com/office/spreadsheetml/2015/revision2"));
+ xmlXPathRegisterNs(pXmlXpathCtx, BAD_CAST("asvg"),
+ BAD_CAST("http://schemas.microsoft.com/office/drawing/2016/SVG/main"));
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/test/user-template/empty-directory-dummy b/test/user-template/empty-directory-dummy
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/test/user-template/empty-directory-dummy
diff --git a/test/user-template/registry-common/modifications.xcd b/test/user-template/registry-common/modifications.xcd
new file mode 100644
index 0000000000..a212242785
--- /dev/null
+++ b/test/user-template/registry-common/modifications.xcd
@@ -0,0 +1,147 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ * 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/.
+ *
+-->
+<oor:data xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:oor="http://openoffice.org/2001/registry">
+ <oor:component-schema oor:package="org.libreoffice" oor:name="unittest">
+ <component>
+ <prop oor:name="localized" oor:localized="true" oor:type="xs:string">
+ </prop>
+ <prop oor:name="noDefaultLang" oor:localized="true" oor:type="xs:string">
+ </prop>
+ </component>
+ </oor:component-schema>
+ <oor:component-data oor:package="org.libreoffice" oor:name="unittest">
+ <prop oor:name="localized">
+ <value>default</value>
+ <value xml:lang="en-US">en-US</value>
+ <value xml:lang="es">es</value>
+ <value xml:lang="pt-PT">pt-PT</value>
+ <value xml:lang="zh-CN">zh-CN</value>
+ <value xml:lang="zh-TW">zh-TW</value>
+ </prop>
+ <prop oor:name="noDefaultLang">
+ <value xml:lang="en-US">en-US</value>
+ </prop>
+ </oor:component-data>
+ <oor:component-data xmlns:install="http://openoffice.org/2004/installation" oor:name="VCL" oor:package="org.openoffice">
+ <node oor:name="DefaultFonts">
+ <node oor:name="ar">
+ <prop oor:name="CTL_HEADING" oor:type="xs:string">
+ <value>DejaVu Sans</value>
+ </prop>
+ <prop oor:name="CTL_TEXT" oor:type="xs:string">
+ <value>DejaVu Sans</value>
+ </prop>
+ </node>
+ <node oor:name="en">
+ <prop oor:name="CJK_HEADING" oor:type="xs:string">
+ <value>DejaVu Sans</value>
+ </prop>
+ <prop oor:name="CTL_HEADING" oor:type="xs:string">
+ <value>DejaVu Sans</value>
+ </prop>
+ <prop oor:name="CTL_TEXT" oor:type="xs:string">
+ <value>DejaVu Sans</value>
+ </prop>
+ <prop oor:name="UI_SANS" oor:type="xs:string">
+ <value>DejaVu Sans</value>
+ </prop>
+ </node>
+ <node oor:name="hi">
+ <prop oor:name="CTL_HEADING" oor:type="xs:string">
+ <value>DejaVu Sans</value>
+ </prop>
+ <prop oor:name="CTL_SPREADSHEET" oor:type="xs:string">
+ <value>DejaVu Sans</value>
+ </prop>
+ <prop oor:name="CTL_TEXT" oor:type="xs:string">
+ <value>DejaVu Sans</value>
+ </prop>
+ </node>
+ <node oor:name="zh-cn">
+ <prop oor:name="CJK_HEADING" oor:type="xs:string">
+ <value>DejaVu Sans</value>
+ </prop>
+ <prop oor:name="CJK_SPREADSHEET" oor:type="xs:string">
+ <value>DejaVu Sans</value>
+ </prop>
+ <prop oor:name="CJK_TEXT" oor:type="xs:string">
+ <value>DejaVu Sans</value>
+ </prop>
+ </node>
+ <node oor:name="zh-tw">
+ <prop oor:name="CJK_HEADING" oor:type="xs:string">
+ <value>DejaVu Sans</value>
+ </prop>
+ <prop oor:name="CJK_SPREADSHEET" oor:type="xs:string">
+ <value>DejaVu Sans</value>
+ </prop>
+ <prop oor:name="CJK_TEXT" oor:type="xs:string">
+ <value>DejaVu Sans</value>
+ </prop>
+ </node>
+ </node>
+ </oor:component-data>
+ <oor:component-data oor:name="Common" oor:package="org.openoffice.Office">
+ <node oor:name="Misc">
+ <prop oor:name="UseDocumentSystemFileLocking">
+ <value>false</value>
+ </prop>
+ <prop oor:name="UseDocumentOOoLockFile">
+ <value>false</value>
+ </prop>
+ <prop oor:name="UseLocking">
+ <value>false</value>
+ </prop>
+ <prop oor:name="ShowTipOfTheDay">
+ <value>false</value>
+ </prop>
+ <prop oor:name="LastTipOfTheDayShown">
+ <value>"32767"</value> <!-- some arbitrary high value (sal_Int32) -->
+ </prop>
+ </node>
+ <node oor:name="Filter">
+ <node oor:name="Graphic">
+ <node oor:name="Export">
+ <node oor:name="SVG">
+ <prop oor:name="EmbedFonts">
+ <value>false</value>
+ </prop>
+ </node>
+ </node>
+ </node>
+ </node>
+ </oor:component-data>
+ <oor:component-data oor:name="Jobs" oor:package="org.openoffice.Office">
+ <node oor:name="Events">
+ <node oor:name="onFirstVisibleTask" oor:op="fuse">
+ <node oor:name="JobList">
+ <node oor:name="UpdateCheck" oor:op="remove"/>
+ </node>
+ </node>
+ </node>
+ </oor:component-data>
+ <oor:component-data oor:name="Setup" oor:package="org.openoffice">
+ <node oor:name="L10N">
+ <prop oor:name="ooLocale">
+ <value>en-US</value>
+ </prop>
+ <prop oor:name="ooSetupSystemLocale">
+ <value>en-US</value>
+ </prop>
+ </node>
+ </oor:component-data>
+ <oor:component-data oor:name="Common" oor:package="org.openoffice.Office">
+ <node oor:name="Security">
+ <prop oor:name="LoadExoticFileFormats">
+ <value>2</value>
+ </prop>
+ </node>
+ </oor:component-data>
+</oor:data>
diff --git a/test/user-template/registry-user-ui/user-ui.xcd b/test/user-template/registry-user-ui/user-ui.xcd
new file mode 100644
index 0000000000..e1ada600c5
--- /dev/null
+++ b/test/user-template/registry-user-ui/user-ui.xcd
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ * 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/.
+ *
+-->
+<oor:data xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:oor="http://openoffice.org/2001/registry">
+ <oor:component-data oor:name="Paths" oor:package="org.openoffice.Office">
+ <node oor:name="Paths">
+ <node oor:name="UIConfig" oor:op="replace">
+ <node oor:name="InternalPaths">
+ <node oor:name="$(userurl)/config" oor:op="fuse"/>
+ </node>
+ </node>
+ </node>
+ </oor:component-data>
+</oor:data>
diff --git a/test/user-template/user/autocorr/acor_en-GB.dat b/test/user-template/user/autocorr/acor_en-GB.dat
new file mode 100644
index 0000000000..ae2f12db59
--- /dev/null
+++ b/test/user-template/user/autocorr/acor_en-GB.dat
Binary files differ
diff --git a/test/user-template/user/autocorr/acor_fr.dat b/test/user-template/user/autocorr/acor_fr.dat
new file mode 100644
index 0000000000..d4ef5567fa
--- /dev/null
+++ b/test/user-template/user/autocorr/acor_fr.dat
Binary files differ
diff --git a/test/user-template/user/autotext/en-US/crdbus50.bau b/test/user-template/user/autotext/en-US/crdbus50.bau
new file mode 100644
index 0000000000..3c140c7445
--- /dev/null
+++ b/test/user-template/user/autotext/en-US/crdbus50.bau
Binary files differ
diff --git a/test/user-template/user/autotext/en-US/standard.bau b/test/user-template/user/autotext/en-US/standard.bau
new file mode 100644
index 0000000000..40cec77a7a
--- /dev/null
+++ b/test/user-template/user/autotext/en-US/standard.bau
Binary files differ
diff --git a/test/user-template/user/autotext/en-US/template.bau b/test/user-template/user/autotext/en-US/template.bau
new file mode 100644
index 0000000000..33bb534e2b
--- /dev/null
+++ b/test/user-template/user/autotext/en-US/template.bau
Binary files differ
diff --git a/test/user-template/user/config/javasettingsunopkginstall.xml b/test/user-template/user/config/javasettingsunopkginstall.xml
new file mode 100644
index 0000000000..3efc8e87fc
--- /dev/null
+++ b/test/user-template/user/config/javasettingsunopkginstall.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<java xmlns="http://openoffice.org/2004/java/framework/1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+</java>
diff --git a/test/user-template/user/config/psetup.xpm b/test/user-template/user/config/psetup.xpm
new file mode 100644
index 0000000000..f512975792
--- /dev/null
+++ b/test/user-template/user/config/psetup.xpm
@@ -0,0 +1,31 @@
+/* XPM */
+static char * L3PSetup_t_pm[] = {
+/* width height ncolors cpp [x_hot y_hot] */
+"16 16 9 1 0 0",
+/* colors */
+" s none m none c none",
+". c #861782078617",
+"X s iconColor1 m black c black",
+"o c #000000008617",
+"O s iconColor2 m white c white",
+"+ c #C71BC30BC71B",
+"@ s iconColor6 m white c yellow",
+"# c #00000000FFFF",
+"$ c #861700000000",
+/* pixels */
+" ",
+" .. XXXXX o",
+" ..OO+XO.OO@Xo",
+" ..OOOOX@.@.OOOo",
+"XXOOOOXOXO.O.@Oo",
+" XOOX@XOX@.OXXo",
+" XOOXOO+XXX o",
+" XX+XOO..+++O+. ",
+"X.++X..+++##++O.",
+"X...++++$$++OOO.",
+"X.....++++OO++O.",
+"X.......OO++++..",
+"XX......+++++.X.",
+" XX....+++.XX ",
+" XX..+.XX ",
+" XXXX "};
diff --git a/test/user-template/user/config/psetupl.xpm b/test/user-template/user/config/psetupl.xpm
new file mode 100644
index 0000000000..f9cca89f10
--- /dev/null
+++ b/test/user-template/user/config/psetupl.xpm
@@ -0,0 +1,49 @@
+/* XPM */
+static char * L3PSetup_m_pm[] = {
+/* width height ncolors cpp [x_hot y_hot] */
+"32 32 11 1 0 0",
+/* colors */
+" s none m none c none",
+". s iconColor1 m black c black",
+"X c #000000008617",
+"o c #861782078617",
+"O s iconColor2 m white c white",
+"+ c #C71BC30BC71B",
+"@ s iconColor6 m white c yellow",
+"# c #00000000FFFF",
+"$ c #861782070000",
+"% c #000082078617",
+"& c #861700000000",
+/* pixels */
+" ",
+" ........ XXXX",
+" .o..oo.OOOOOOO+..X+OX",
+" .+ooOO.@OO@OOOO@OOXOOX",
+" .+oo+O.OO.OOOOOOOOOXXXX",
+" .+oo+O.O@.OOO@OOOO@OXXXX",
+" .+oo+O.@O.O@O.OO@OOOOXXXX",
+" .+oo+O.OO.+.O.OOOOOOOOXXXX",
+" .+oo+O.O@.+O+.O@O.OOO..X.X.",
+" .+oo+O+...+O++o.O.OO@. .X. ",
+" .+oo+O+O+O+O++++o.@O..o ... ",
+" .ooo+O+O+O+O++++ooo.. ",
+" .ooo+O+O+O+O++++o..+Oo ",
+" .oo+O+O+O+O++++o....OO. ",
+" ..+O+O+O+O++++o......OO. ",
+" .o+OO+O+O++#+o....$o..OO. ",
+" .oo+OO+O++%+o....$$$...Oo. ",
+" .ooo+OO++&+o...$$$+$+...o. ",
+" .oooo+O+++o...$$$+$+++..o. ",
+" .oooooOO+o.o.$$++$+OoOO..o ",
+" .ooooo+Oo..O.$++$OOoOO$O.o ",
+"o.ooooooO.o.OO.+$OOoOOoOOO. ",
+"oo.ooooo.O.O.OO.OOoOO$OOoOO. ",
+" oo.oooo+O.OO.OO.OOOoOOoOO.o ",
+" oo.ooo+O.oOo.Oo.O$OO$OO.o ",
+" oo.oo+O.o+o.+o.OOOoOO.o ",
+" oo.o+O.o+o.+o.OOoOO.o ",
+" oo.+..o+o.+o..OOO.o ",
+" oo.oo.+..+o.o.O.o ",
+" ooooo.o.o.ooo.o ",
+" oooo.o oo ",
+" oo "};
diff --git a/test/user-template/user/config/soffice.cfg/modules/scalc/popupmenu/anchor.xml b/test/user-template/user/config/soffice.cfg/modules/scalc/popupmenu/anchor.xml
new file mode 100644
index 0000000000..c269bef3ad
--- /dev/null
+++ b/test/user-template/user/config/soffice.cfg/modules/scalc/popupmenu/anchor.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ * 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/.
+ *
+-->
+<menu:menupopup xmlns:menu="http://openoffice.org/2001/menu">
+ <menu:menuitem menu:id=".uno:SetAnchorToPage" menu:style="radio"/>
+ <menu:menuitem menu:id=".uno:SetAnchorToCell" menu:style="radio"/>
+</menu:menupopup>
diff --git a/test/user-template/user/config/soffice.cfg/modules/scalc/popupmenu/draw.xml b/test/user-template/user/config/soffice.cfg/modules/scalc/popupmenu/draw.xml
new file mode 100644
index 0000000000..e09f817a40
--- /dev/null
+++ b/test/user-template/user/config/soffice.cfg/modules/scalc/popupmenu/draw.xml
@@ -0,0 +1,69 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ * 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/.
+ *
+-->
+<menu:menupopup xmlns:menu="http://openoffice.org/2001/menu">
+ <menu:menuitem menu:id=".uno:Cut"/>
+ <menu:menuitem menu:id=".uno:Copy"/>
+ <menu:menuitem menu:id=".uno:Paste"/>
+ <menu:menuseparator/>
+ <menu:menuitem menu:id=".uno:FormatLine"/>
+ <menu:menuitem menu:id=".uno:FormatArea"/>
+ <menu:menuitem menu:id=".uno:TextAttributes"/>
+ <menu:menuitem menu:id=".uno:TransformDialog"/>
+ <menu:menuseparator/>
+ <menu:menuitem menu:id=".uno:ObjectTitleDescription"/>
+ <menu:menuitem menu:id=".uno:RenameObject"/>
+ <menu:menuseparator/>
+ <menu:menu menu:id=".uno:FlipMenu">
+ <menu:menupopup>
+ <menu:menuitem menu:id=".uno:ObjectMirrorVertical"/>
+ <menu:menuitem menu:id=".uno:ObjectMirrorHorizontal"/>
+ </menu:menupopup>
+ </menu:menu>
+ <menu:menu menu:id=".uno:ArrangeMenu">
+ <menu:menupopup>
+ <menu:menuitem menu:id=".uno:BringToFront"/>
+ <menu:menuitem menu:id=".uno:ObjectForwardOne"/>
+ <menu:menuitem menu:id=".uno:ObjectBackOne"/>
+ <menu:menuitem menu:id=".uno:SendToBack"/>
+ <menu:menuseparator/>
+ <menu:menuitem menu:id=".uno:SetObjectToForeground"/>
+ <menu:menuitem menu:id=".uno:SetObjectToBackground"/>
+ </menu:menupopup>
+ </menu:menu>
+ <menu:menu menu:id=".uno:ObjectAlign">
+ <menu:menupopup>
+ <menu:menuitem menu:id=".uno:ObjectAlignLeft"/>
+ <menu:menuitem menu:id=".uno:AlignCenter"/>
+ <menu:menuitem menu:id=".uno:ObjectAlignRight"/>
+ <menu:menuseparator/>
+ <menu:menuitem menu:id=".uno:AlignUp"/>
+ <menu:menuitem menu:id=".uno:AlignMiddle"/>
+ <menu:menuitem menu:id=".uno:AlignDown"/>
+ </menu:menupopup>
+ </menu:menu>
+ <menu:menuitem menu:id=".uno:AnchorMenu"/>
+ <menu:menuitem menu:id=".uno:AssignMacro"/>
+ <menu:menuseparator/>
+ <menu:menuitem menu:id=".uno:ToggleObjectBezierMode"/>
+ <menu:menuitem menu:id=".uno:FontWork"/>
+ <menu:menuseparator/>
+ <menu:menu menu:id=".uno:GroupMenu">
+ <menu:menupopup>
+ <menu:menuitem menu:id=".uno:FormatGroup"/>
+ <menu:menuitem menu:id=".uno:FormatUngroup"/>
+ <menu:menuitem menu:id=".uno:EnterGroup"/>
+ <menu:menuitem menu:id=".uno:LeaveGroup"/>
+ </menu:menupopup>
+ </menu:menu>
+ <menu:menuseparator/>
+ <menu:menuitem menu:id=".uno:EditHyperlink"/>
+ <menu:menuitem menu:id=".uno:RemoveHyperlink"/>
+ <menu:menuitem menu:id=".uno:OpenHyperlinkOnCursor"/>
+</menu:menupopup>
diff --git a/test/user-template/user/config/soffice.cfg/modules/simpress/popupmenu/page.xml b/test/user-template/user/config/soffice.cfg/modules/simpress/popupmenu/page.xml
new file mode 100644
index 0000000000..02ff497933
--- /dev/null
+++ b/test/user-template/user/config/soffice.cfg/modules/simpress/popupmenu/page.xml
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ * 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/.
+ *
+-->
+<menu:menupopup xmlns:menu="http://openoffice.org/2001/menu">
+ <menu:menuitem menu:id=".uno:Cut"/>
+ <menu:menuitem menu:id=".uno:Copy"/>
+ <menu:menuitem menu:id=".uno:Paste"/>
+ <menu:menuseparator/>
+ <menu:menuitem menu:id=".uno:SlideSetup"/>
+ <menu:menuitem menu:id=".uno:SelectBackground"/>
+ <menu:menuitem menu:id=".uno:SaveBackground"/>
+ <menu:menu menu:id=".uno:SlideFeaturesMenu">
+ <menu:menupopup>
+ <menu:menuitem menu:id=".uno:HideSlide"/>
+ <menu:menuitem menu:id=".uno:ShowSlide"/>
+ <menu:menuseparator/>
+ <menu:menuitem menu:id=".uno:DisplayMasterBackground"/>
+ <menu:menuitem menu:id=".uno:DisplayMasterObjects"/>
+ <menu:menuitem menu:id=".uno:MasterLayouts"/>
+ <menu:menuseparator/>
+ <menu:menuitem menu:id=".uno:PresentationLayout"/>
+ </menu:menupopup>
+ </menu:menu>
+ <menu:menuseparator/>
+ <menu:menuitem menu:id=".uno:ShowRuler"/>
+ <menu:menu menu:id=".uno:GridMenu">
+ <menu:menupopup>
+ <menu:menuitem menu:id=".uno:GridVisible"/>
+ <menu:menuitem menu:id=".uno:GridUse"/>
+ <menu:menuitem menu:id=".uno:GridFront"/>
+ </menu:menupopup>
+ </menu:menu>
+ <menu:menu menu:id=".uno:SnapLinesMenu">
+ <menu:menupopup>
+ <menu:menuitem menu:id=".uno:HelplinesVisible"/>
+ <menu:menuitem menu:id=".uno:HelplinesUse"/>
+ <menu:menuitem menu:id=".uno:HelplinesFront"/>
+ </menu:menupopup>
+ </menu:menu>
+ <menu:menuitem menu:id=".uno:CapturePoint"/>
+ <menu:menuseparator/>
+ <menu:menuitem menu:id=".uno:LeaveGroup"/>
+</menu:menupopup>
diff --git a/test/user-template/user/config/soffice.cfg/modules/swriter/popupmenu/text.xml b/test/user-template/user/config/soffice.cfg/modules/swriter/popupmenu/text.xml
new file mode 100644
index 0000000000..a6a60215aa
--- /dev/null
+++ b/test/user-template/user/config/soffice.cfg/modules/swriter/popupmenu/text.xml
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ * 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/.
+ *
+-->
+<menu:menupopup xmlns:menu="http://openoffice.org/2001/menu">
+ <menu:menuitem menu:id=".uno:Cut"/>
+ <menu:menuitem menu:id=".uno:Copy"/>
+ <menu:menuitem menu:id=".uno:Paste"/>
+ <menu:menu menu:id=".uno:PasteSpecialMenu">
+ <menu:menupopup>
+ <menu:menuitem menu:id=".uno:PasteUnformatted"/>
+ <menu:menuitem menu:id=".uno:PasteSpecial"/>
+ </menu:menupopup>
+ </menu:menu>
+ <menu:menuseparator/>
+ <menu:menuitem menu:id=".uno:NumberingStart"/>
+ <menu:menuitem menu:id=".uno:ContinueNumbering"/>
+ <menu:menuitem menu:id=".uno:IncrementLevel"/>
+ <menu:menuitem menu:id=".uno:DecrementLevel"/>
+ <menu:menuseparator/>
+ <menu:menuitem menu:id=".uno:FontDialog"/>
+ <menu:menuitem menu:id=".uno:ParagraphDialog"/>
+ <menu:menuitem menu:id=".uno:OutlineBullet"/>
+ <menu:menuitem menu:id=".uno:PageDialog"/>
+ <menu:menuseparator/>
+ <menu:menuitem menu:id=".uno:UpdateCurIndex"/>
+ <menu:menuitem menu:id=".uno:EditCurIndex"/>
+ <menu:menuitem menu:id=".uno:RemoveTableOf"/>
+ <menu:menuseparator/>
+ <menu:menuitem menu:id=".uno:FieldDialog"/>
+ <menu:menuitem menu:id=".uno:EditFootnote"/>
+ <menu:menuitem menu:id=".uno:IndexEntryDialog"/>
+ <menu:menuitem menu:id=".uno:AuthoritiesEntryDialog"/>
+ <menu:menuseparator/>
+ <menu:menuitem menu:id=".uno:AcceptTrackedChange"/>
+ <menu:menuitem menu:id=".uno:RejectTrackedChange"/>
+ <menu:menuitem menu:id=".uno:NextTrackedChange"/>
+ <menu:menuitem menu:id=".uno:PreviousTrackedChange"/>
+ <menu:menuseparator/>
+ <menu:menuitem menu:id=".uno:EditStyle"/>
+ <menu:menuseparator/>
+ <menu:menuitem menu:id=".uno:OpenHyperlinkOnCursor"/>
+ <menu:menuitem menu:id=".uno:EditHyperlink"/>
+ <menu:menuitem menu:id=".uno:CopyHyperlinkLocation"/>
+ <menu:menuitem menu:id=".uno:RemoveHyperlink"/>
+ <menu:menuitem menu:id=".uno:OpenSmartTagMenuOnCursor"/>
+ <menu:menuitem menu:id=".uno:ThesaurusFromContext"/>
+</menu:menupopup>
diff --git a/test/user-template/user/config/soffice.cfg/simpress/effects.xml b/test/user-template/user/config/soffice.cfg/simpress/effects.xml
new file mode 100644
index 0000000000..be341ef5e2
--- /dev/null
+++ b/test/user-template/user/config/soffice.cfg/simpress/effects.xml
@@ -0,0 +1,2630 @@
+<?xml version="1.0"?>
+<anim:seq xmlns:office="urn:oasis:names:tc:openoffice:xmlns:office:1.0" xmlns:style="urn:oasis:names:tc:openoffice:xmlns:style:1.0" xmlns:text="urn:oasis:names:tc:openoffice:xmlns:text:1.0" xmlns:table="urn:oasis:names:tc:openoffice:xmlns:table:1.0" xmlns:draw="urn:oasis:names:tc:openoffice:xmlns:drawing:1.0" xmlns:fo="http://www.w3.org/1999/XSL/Format" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:meta="urn:oasis:names:tc:openoffice:xmlns:meta:1.0" xmlns:number="urn:oasis:names:tc:openoffice:xmlns:datastyle:1.0" xmlns:pres="urn:oasis:names:tc:openoffice:xmlns:presentation:1.0" xmlns:svg="http://www.w3.org/2000/svg" xmlns:chart="urn:oasis:names:tc:openoffice:xmlns:chart:1.0" xmlns:dr3d="urn:oasis:names:tc:openoffice:xmlns:dr3d:1.0" xmlns:math="http://www.w3.org/1998/Math/MathML" xmlns:form="urn:oasis:names:tc:openoffice:xmlns:form:1.0" xmlns:script="urn:oasis:names:tc:openoffice:xmlns:script:1.0" xmlns:ooo="http://openoffice.org/2004/office" xmlns:ooow="http://openoffice.org/2004/writer" xmlns:oooc="http://openoffice.org/2004/calc" xmlns:dom="http://www.w3.org/2001/xml-events" xmlns:smil="http://www.w3.org/2001/SMIL20" xmlns:anim="urn:oasis:names:tc:openoffice:xmlns:animation:1.0" pres:node-type="main-sequence">
+
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold" pres:node-type="on-click" pres:preset-class="entrance" pres:preset-id="ooo-entrance-appear">
+ <anim:set smil:begin="0" smil:dur="0.001" smil:fill="hold" smil:attributeName="visibility" smil:to="visible"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par pres:preset-property="Direction" smil:begin="0" smil:fill="hold" pres:node-type="on-click" pres:preset-class="entrance" pres:preset-id="ooo-entrance-venetian-blinds" pres:preset-sub-type="vertical">
+ <anim:set smil:begin="0" smil:dur="0.001" smil:fill="hold" smil:attributeName="visibility" smil:to="visible"/>
+ <anim:transitionFilter smil:dur="0.5" smil:type="blindsWipe" smil:subtype="horizontal"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold" pres:node-type="on-click" pres:preset-class="entrance" pres:preset-id="ooo-entrance-venetian-blinds" pres:preset-sub-type="horizontal">
+ <anim:set smil:begin="0" smil:dur="0.001" smil:fill="hold" smil:attributeName="visibility" smil:to="visible"/>
+ <anim:transitionFilter smil:dur="0.5" smil:type="blindsWipe" smil:subtype="vertical"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par pres:preset-property="Direction" smil:begin="0" smil:fill="hold" pres:node-type="on-click" pres:preset-class="entrance" pres:preset-id="ooo-entrance-box" pres:preset-sub-type="in">
+ <anim:set smil:begin="0" smil:dur="0.001" smil:fill="hold" smil:attributeName="visibility" smil:to="visible"/>
+ <anim:transitionFilter smil:dur="0.5" smil:type="irisWipe" smil:subtype="rectangle" smil:direction="reverse"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par pres:preset-property="Direction" smil:begin="0" smil:fill="hold" pres:node-type="on-click" pres:preset-class="entrance" pres:preset-id="ooo-entrance-box" pres:preset-sub-type="out">
+ <anim:set smil:begin="0" smil:dur="0.001" smil:fill="hold" smil:attributeName="visibility" smil:to="visible"/>
+ <anim:transitionFilter smil:dur="0.5" smil:type="irisWipe" smil:subtype="rectangle"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par pres:preset-property="Direction" smil:begin="0" smil:fill="hold" pres:node-type="on-click" pres:preset-class="entrance" pres:preset-id="ooo-entrance-checkerboard" pres:preset-sub-type="across">
+ <anim:set smil:begin="0" smil:dur="0.001" smil:fill="hold" smil:attributeName="visibility" smil:to="visible"/>
+ <anim:transitionFilter smil:dur="0.5" smil:type="checkerBoardWipe" smil:subtype="across"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par pres:preset-property="Direction" smil:begin="0" smil:fill="hold" pres:node-type="on-click" pres:preset-class="entrance" pres:preset-id="ooo-entrance-checkerboard" pres:preset-sub-type="downward">
+ <anim:set smil:begin="0" smil:dur="0.001" smil:fill="hold" smil:attributeName="visibility" smil:to="visible"/>
+ <anim:transitionFilter smil:dur="0.5" smil:type="checkerBoardWipe" smil:subtype="down"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par pres:preset-property="Direction" smil:begin="0" smil:fill="hold" pres:node-type="on-click" pres:preset-class="entrance" pres:preset-id="ooo-entrance-circle" pres:preset-sub-type="in">
+ <anim:set smil:begin="0" smil:dur="0.001" smil:fill="hold" smil:attributeName="visibility" smil:to="visible"/>
+ <anim:transitionFilter smil:dur="2" smil:type="ellipseWipe" smil:subtype="horizontal" smil:direction="reverse"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par pres:preset-property="Direction" smil:begin="0" smil:fill="hold" pres:node-type="on-click" pres:preset-class="entrance" pres:preset-id="ooo-entrance-circle" pres:preset-sub-type="out">
+ <anim:set smil:begin="0" smil:dur="0.001" smil:fill="hold" smil:attributeName="visibility" smil:to="visible"/>
+ <anim:transitionFilter smil:dur="2" smil:type="ellipseWipe" smil:subtype="horizontal"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par pres:preset-property="Direction" smil:begin="0" smil:fill="hold" pres:node-type="on-click" pres:preset-class="entrance" pres:preset-id="ooo-entrance-fly-in-slow" pres:preset-sub-type="from-bottom">
+ <anim:set smil:begin="0" smil:dur="0.001" smil:fill="hold" smil:attributeName="visibility" smil:to="visible"/>
+ <anim:animate smil:dur="5" smil:fill="hold" smil:attributeName="x" smil:values="x;x" smil:keyTimes="0;1"/>
+ <anim:animate smil:dur="5" smil:fill="hold" smil:attributeName="y" smil:values="1+height/2;y" smil:keyTimes="0;1"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par pres:preset-property="Direction" smil:begin="0" smil:fill="hold" pres:node-type="on-click" pres:preset-class="entrance" pres:preset-id="ooo-entrance-fly-in-slow" pres:preset-sub-type="from-left">
+ <anim:set smil:begin="0" smil:dur="0.001" smil:fill="hold" smil:attributeName="visibility" smil:to="visible"/>
+ <anim:animate smil:dur="5" smil:fill="hold" smil:attributeName="x" smil:values="0-width/2;x" smil:keyTimes="0;1"/>
+ <anim:animate smil:dur="5" smil:fill="hold" smil:attributeName="y" smil:values="y;y" smil:keyTimes="0;1"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par pres:preset-property="Direction" smil:begin="0" smil:fill="hold" pres:node-type="on-click" pres:preset-class="entrance" pres:preset-id="ooo-entrance-fly-in-slow" pres:preset-sub-type="from-right">
+ <anim:set smil:begin="0" smil:dur="0.001" smil:fill="hold" smil:attributeName="visibility" smil:to="visible"/>
+ <anim:animate smil:dur="5" smil:fill="hold" smil:attributeName="x" smil:values="1+width/2;x" smil:keyTimes="0;1"/>
+ <anim:animate smil:dur="5" smil:fill="hold" smil:attributeName="y" smil:values="y;y" smil:keyTimes="0;1"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par pres:preset-property="Direction" smil:begin="0" smil:fill="hold" pres:node-type="on-click" pres:preset-class="entrance" pres:preset-id="ooo-entrance-fly-in-slow" pres:preset-sub-type="from-top">
+ <anim:set smil:begin="0" smil:dur="0.001" smil:fill="hold" smil:attributeName="visibility" smil:to="visible"/>
+ <anim:animate smil:dur="5" smil:fill="hold" smil:attributeName="x" smil:values="x;x" smil:keyTimes="0;1"/>
+ <anim:animate smil:dur="5" smil:fill="hold" smil:attributeName="y" smil:values="0-height/2;y" smil:keyTimes="0;1"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par pres:preset-property="Direction" smil:begin="0" smil:fill="hold" pres:node-type="on-click" pres:preset-class="entrance" pres:preset-id="ooo-entrance-diamond" pres:preset-sub-type="in">
+ <anim:set smil:begin="0" smil:dur="0.001" smil:fill="hold" smil:attributeName="visibility" smil:to="visible"/>
+ <anim:transitionFilter smil:dur="2" smil:type="irisWipe" smil:subtype="diamond" smil:direction="reverse"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par pres:preset-property="Direction" smil:begin="0" smil:fill="hold" pres:node-type="on-click" pres:preset-class="entrance" pres:preset-id="ooo-entrance-diamond" pres:preset-sub-type="out">
+ <anim:set smil:begin="0" smil:dur="0.001" smil:fill="hold" smil:attributeName="visibility" smil:to="visible"/>
+ <anim:transitionFilter smil:dur="2" smil:type="irisWipe" smil:subtype="diamond"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold" pres:node-type="on-click" pres:preset-class="entrance" pres:preset-id="ooo-entrance-dissolve-in">
+ <anim:set smil:begin="0" smil:dur="0.001" smil:fill="hold" smil:attributeName="visibility" smil:to="visible"/>
+ <anim:transitionFilter smil:dur="0.5" smil:type="dissolve"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold" pres:node-type="on-click" pres:preset-class="entrance" pres:preset-id="ooo-entrance-flash-once">
+ <anim:set smil:begin="0" smil:dur="1" smil:attributeName="visibility" smil:to="visible"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par pres:preset-property="Direction;Accelerate;Decelerate" smil:begin="0" smil:fill="hold" pres:node-type="on-click" pres:preset-class="entrance" pres:preset-id="ooo-entrance-fly-in" pres:preset-sub-type="from-bottom">
+ <anim:set smil:begin="0" smil:dur="0.001" smil:fill="hold" smil:attributeName="visibility" smil:to="visible"/>
+ <anim:animate smil:dur="0.5" smil:fill="hold" smil:attributeName="x" smil:values="x;x" smil:keyTimes="0;1"/>
+ <anim:animate smil:dur="0.5" smil:fill="hold" smil:attributeName="y" smil:values="1+height/2;y" smil:keyTimes="0;1"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par pres:preset-property="Direction;Accelerate;Decelerate" smil:begin="0" smil:fill="hold" pres:node-type="on-click" pres:preset-class="entrance" pres:preset-id="ooo-entrance-fly-in" pres:preset-sub-type="from-left">
+ <anim:set smil:begin="0" smil:dur="0.001" smil:fill="hold" smil:attributeName="visibility" smil:to="visible"/>
+ <anim:animate smil:dur="0.5" smil:fill="hold" smil:attributeName="x" smil:values="0-width/2;x" smil:keyTimes="0;1"/>
+ <anim:animate smil:dur="0.5" smil:fill="hold" smil:attributeName="y" smil:values="y;y" smil:keyTimes="0;1"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par pres:preset-property="Direction;Accelerate;Decelerate" smil:begin="0" smil:fill="hold" pres:node-type="on-click" pres:preset-class="entrance" pres:preset-id="ooo-entrance-fly-in" pres:preset-sub-type="from-right">
+ <anim:set smil:begin="0" smil:dur="0.001" smil:fill="hold" smil:attributeName="visibility" smil:to="visible"/>
+ <anim:animate smil:dur="0.5" smil:fill="hold" smil:attributeName="x" smil:values="1+width/2;x" smil:keyTimes="0;1"/>
+ <anim:animate smil:dur="0.5" smil:fill="hold" smil:attributeName="y" smil:values="y;y" smil:keyTimes="0;1"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par pres:preset-property="Direction;Accelerate;Decelerate" smil:begin="0" smil:fill="hold" pres:node-type="on-click" pres:preset-class="entrance" pres:preset-id="ooo-entrance-fly-in" pres:preset-sub-type="from-top">
+ <anim:set smil:begin="0" smil:dur="0.001" smil:fill="hold" smil:attributeName="visibility" smil:to="visible"/>
+ <anim:animate smil:dur="0.5" smil:fill="hold" smil:attributeName="x" smil:values="x;x" smil:keyTimes="0;1"/>
+ <anim:animate smil:dur="0.5" smil:fill="hold" smil:attributeName="y" smil:values="0-height/2;y" smil:keyTimes="0;1"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par pres:preset-property="Direction;Accelerate;Decelerate" smil:begin="0" smil:fill="hold" pres:node-type="on-click" pres:preset-class="entrance" pres:preset-id="ooo-entrance-fly-in" pres:preset-sub-type="from-bottom-left">
+ <anim:set smil:begin="0" smil:dur="0.001" smil:fill="hold" smil:attributeName="visibility" smil:to="visible"/>
+ <anim:animate smil:dur="0.5" smil:fill="hold" smil:attributeName="x" smil:values="0-width/2;x" smil:keyTimes="0;1"/>
+ <anim:animate smil:dur="0.5" smil:fill="hold" smil:attributeName="y" smil:values="1+height/2;y" smil:keyTimes="0;1"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par pres:preset-property="Direction;Accelerate;Decelerate" smil:begin="0" smil:fill="hold" pres:node-type="on-click" pres:preset-class="entrance" pres:preset-id="ooo-entrance-fly-in" pres:preset-sub-type="from-bottom-right">
+ <anim:set smil:begin="0" smil:dur="0.001" smil:fill="hold" smil:attributeName="visibility" smil:to="visible"/>
+ <anim:animate smil:dur="0.5" smil:fill="hold" smil:attributeName="x" smil:values="1+width/2;x" smil:keyTimes="0;1"/>
+ <anim:animate smil:dur="0.5" smil:fill="hold" smil:attributeName="y" smil:values="1+height/2;y" smil:keyTimes="0;1"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par pres:preset-property="Direction;Accelerate;Decelerate" smil:begin="0" smil:fill="hold" pres:node-type="on-click" pres:preset-class="entrance" pres:preset-id="ooo-entrance-fly-in" pres:preset-sub-type="from-top-left">
+ <anim:set smil:begin="0" smil:dur="0.001" smil:fill="hold" smil:attributeName="visibility" smil:to="visible"/>
+ <anim:animate smil:dur="0.5" smil:fill="hold" smil:attributeName="x" smil:values="0-width/2;x" smil:keyTimes="0;1"/>
+ <anim:animate smil:dur="0.5" smil:fill="hold" smil:attributeName="y" smil:values="0-height/2;y" smil:keyTimes="0;1"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par pres:preset-property="Direction;Accelerate;Decelerate" smil:begin="0" smil:fill="hold" pres:node-type="on-click" pres:preset-class="entrance" pres:preset-id="ooo-entrance-fly-in" pres:preset-sub-type="from-top-right">
+ <anim:set smil:begin="0" smil:dur="0.001" smil:fill="hold" smil:attributeName="visibility" smil:to="visible"/>
+ <anim:animate smil:dur="0.5" smil:fill="hold" smil:attributeName="x" smil:values="1+width/2;x" smil:keyTimes="0;1"/>
+ <anim:animate smil:dur="0.5" smil:fill="hold" smil:attributeName="y" smil:values="0-height/2;y" smil:keyTimes="0;1"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par pres:preset-property="Direction" smil:begin="0" smil:fill="hold" pres:node-type="on-click" pres:preset-class="entrance" pres:preset-id="ooo-entrance-peek-in" pres:preset-sub-type="from-bottom">
+ <anim:set smil:begin="0" smil:dur="0.001" smil:fill="hold" smil:attributeName="visibility" smil:to="visible"/>
+ <anim:transitionFilter smil:dur="0.5" smil:type="slideWipe" smil:subtype="fromBottom"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par pres:preset-property="Direction" smil:begin="0" smil:fill="hold" pres:node-type="on-click" pres:preset-class="entrance" pres:preset-id="ooo-entrance-peek-in" pres:preset-sub-type="from-left">
+ <anim:set smil:begin="0" smil:dur="0.001" smil:fill="hold" smil:attributeName="visibility" smil:to="visible"/>
+ <anim:transitionFilter smil:dur="0.5" smil:type="slideWipe" smil:subtype="fromLeft"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par pres:preset-property="Direction" smil:begin="0" smil:fill="hold" pres:node-type="on-click" pres:preset-class="entrance" pres:preset-id="ooo-entrance-peek-in" pres:preset-sub-type="from-right">
+ <anim:set smil:begin="0" smil:dur="0.001" smil:fill="hold" smil:attributeName="visibility" smil:to="visible"/>
+ <anim:transitionFilter smil:dur="0.5" smil:type="slideWipe" smil:subtype="fromRight"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par pres:preset-property="Direction" smil:begin="0" smil:fill="hold" pres:node-type="on-click" pres:preset-class="entrance" pres:preset-id="ooo-entrance-peek-in" pres:preset-sub-type="from-top">
+ <anim:set smil:begin="0" smil:dur="0.001" smil:fill="hold" smil:attributeName="visibility" smil:to="visible"/>
+ <anim:transitionFilter smil:dur="0.5" smil:type="slideWipe" smil:subtype="fromTop"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par pres:preset-property="Direction" smil:begin="0" smil:fill="hold" pres:node-type="on-click" pres:preset-class="entrance" pres:preset-id="ooo-entrance-plus" pres:preset-sub-type="in">
+ <anim:set smil:begin="0" smil:dur="0.001" smil:fill="hold" smil:attributeName="visibility" smil:to="visible"/>
+ <anim:transitionFilter smil:dur="2" smil:type="fourBoxWipe" smil:subtype="cornersIn"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par pres:preset-property="Direction" smil:begin="0" smil:fill="hold" pres:node-type="on-click" pres:preset-class="entrance" pres:preset-id="ooo-entrance-plus" pres:preset-sub-type="out">
+ <anim:set smil:begin="0" smil:dur="0.001" smil:fill="hold" smil:attributeName="visibility" smil:to="visible"/>
+ <anim:transitionFilter smil:dur="2" smil:type="fourBoxWipe" smil:subtype="cornersIn" smil:direction="reverse"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par pres:preset-property="Direction" smil:begin="0" smil:fill="hold" pres:node-type="on-click" pres:preset-class="entrance" pres:preset-id="ooo-entrance-random-bars" pres:preset-sub-type="vertical">
+ <anim:set smil:begin="0" smil:dur="0.001" smil:fill="hold" smil:attributeName="visibility" smil:to="visible"/>
+ <anim:transitionFilter smil:dur="0.5" smil:type="randomBarWipe" smil:subtype="horizontal"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par pres:preset-property="Direction" smil:begin="0" smil:fill="hold" pres:node-type="on-click" pres:preset-class="entrance" pres:preset-id="ooo-entrance-random-bars" pres:preset-sub-type="horizontal">
+ <anim:set smil:begin="0" smil:dur="0.001" smil:fill="hold" smil:attributeName="visibility" smil:to="visible"/>
+ <anim:transitionFilter smil:dur="0.5" smil:type="randomBarWipe" smil:subtype="vertical"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold" pres:node-type="on-click" pres:preset-class="entrance" pres:preset-id="ooo-entrance-random"/>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par pres:preset-property="Direction" smil:begin="0" smil:fill="hold" pres:node-type="on-click" pres:preset-class="entrance" pres:preset-id="ooo-entrance-split" pres:preset-sub-type="horizontal-in">
+ <anim:set smil:begin="0" smil:dur="0.001" smil:fill="hold" smil:attributeName="visibility" smil:to="visible"/>
+ <anim:transitionFilter smil:dur="0.5" smil:type="barnDoorWipe" smil:subtype="horizontal" smil:direction="reverse"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par pres:preset-property="Direction" smil:begin="0" smil:fill="hold" pres:node-type="on-click" pres:preset-class="entrance" pres:preset-id="ooo-entrance-split" pres:preset-sub-type="horizontal-out">
+ <anim:set smil:begin="0" smil:dur="0.001" smil:fill="hold" smil:attributeName="visibility" smil:to="visible"/>
+ <anim:transitionFilter smil:dur="0.5" smil:type="barnDoorWipe" smil:subtype="horizontal"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par pres:preset-property="Direction" smil:begin="0" smil:fill="hold" pres:node-type="on-click" pres:preset-class="entrance" pres:preset-id="ooo-entrance-split" pres:preset-sub-type="vertical-in">
+ <anim:set smil:begin="0" smil:dur="0.001" smil:fill="hold" smil:attributeName="visibility" smil:to="visible"/>
+ <anim:transitionFilter smil:dur="0.5" smil:type="barnDoorWipe" smil:subtype="vertical" smil:direction="reverse"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par pres:preset-property="Direction" smil:begin="0" smil:fill="hold" pres:node-type="on-click" pres:preset-class="entrance" pres:preset-id="ooo-entrance-split" pres:preset-sub-type="vertical-out">
+ <anim:set smil:begin="0" smil:dur="0.001" smil:fill="hold" smil:attributeName="visibility" smil:to="visible"/>
+ <anim:transitionFilter smil:dur="0.5" smil:type="barnDoorWipe" smil:subtype="vertical"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par pres:preset-property="Direction" smil:begin="0" smil:fill="hold" pres:node-type="on-click" pres:preset-class="entrance" pres:preset-id="ooo-entrance-diagonal-squares" pres:preset-sub-type="left-to-bottom">
+ <anim:set smil:begin="0" smil:dur="0.001" smil:fill="hold" smil:attributeName="visibility" smil:to="visible"/>
+ <anim:transitionFilter smil:dur="0.5" smil:type="waterfallWipe" smil:subtype="horizontalRight"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par pres:preset-property="Direction" smil:begin="0" smil:fill="hold" pres:node-type="on-click" pres:preset-class="entrance" pres:preset-id="ooo-entrance-diagonal-squares" pres:preset-sub-type="left-to-top">
+ <anim:set smil:begin="0" smil:dur="0.001" smil:fill="hold" smil:attributeName="visibility" smil:to="visible"/>
+ <anim:transitionFilter smil:dur="0.5" smil:type="waterfallWipe" smil:subtype="horizontalLeft" smil:direction="reverse"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par pres:preset-property="Direction" smil:begin="0" smil:fill="hold" pres:node-type="on-click" pres:preset-class="entrance" pres:preset-id="ooo-entrance-diagonal-squares" pres:preset-sub-type="right-to-bottom">
+ <anim:set smil:begin="0" smil:dur="0.001" smil:fill="hold" smil:attributeName="visibility" smil:to="visible"/>
+ <anim:transitionFilter smil:dur="0.5" smil:type="waterfallWipe" smil:subtype="horizontalLeft"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par pres:preset-property="Direction" smil:begin="0" smil:fill="hold" pres:node-type="on-click" pres:preset-class="entrance" pres:preset-id="ooo-entrance-diagonal-squares" pres:preset-sub-type="right-to-top">
+ <anim:set smil:begin="0" smil:dur="0.001" smil:fill="hold" smil:attributeName="visibility" smil:to="visible"/>
+ <anim:transitionFilter smil:dur="0.5" smil:type="waterfallWipe" smil:subtype="horizontalRight" smil:direction="reverse"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold" pres:node-type="on-click" pres:preset-class="entrance" pres:preset-id="ooo-entrance-wedge">
+ <anim:set smil:begin="0" smil:dur="0.001" smil:fill="hold" smil:attributeName="visibility" smil:to="visible"/>
+ <anim:transitionFilter smil:dur="2" smil:type="fanWipe" smil:subtype="centerTop"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold" pres:node-type="on-click" pres:preset-class="entrance" pres:preset-id="ooo-entrance-clock-wipe" pres:preset-sub-type="clockwise">
+ <anim:set smil:begin="0" smil:dur="0.001" smil:fill="hold" smil:attributeName="visibility" smil:to="visible"/>
+ <anim:transitionFilter smil:dur="2" smil:type="clockWipe" smil:subtype="clockwiseTwelve"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold" pres:node-type="on-click" pres:preset-class="entrance" pres:preset-id="ooo-entrance-clock-wipe" pres:preset-sub-type="counter-clockwise">
+ <anim:set smil:begin="0" smil:dur="0.001" smil:fill="hold" smil:attributeName="visibility" smil:to="visible"/>
+ <anim:transitionFilter smil:dur="2" smil:type="clockWipe" smil:subtype="clockwiseTwelve" smil:direction="reverse"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par pres:preset-property="Spokes" smil:begin="0" smil:fill="hold" pres:node-type="on-click" pres:preset-class="entrance" pres:preset-id="ooo-entrance-wheel" pres:preset-sub-type="1">
+ <anim:set smil:begin="0" smil:dur="0.001" smil:fill="hold" smil:attributeName="visibility" smil:to="visible"/>
+ <anim:transitionFilter smil:dur="2" smil:type="pinWheelWipe" smil:subtype="oneBlade"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par pres:preset-property="Spokes" smil:begin="0" smil:fill="hold" pres:node-type="on-click" pres:preset-class="entrance" pres:preset-id="ooo-entrance-wheel" pres:preset-sub-type="2">
+ <anim:set smil:begin="0" smil:dur="0.001" smil:fill="hold" smil:attributeName="visibility" smil:to="visible"/>
+ <anim:transitionFilter smil:dur="2" smil:type="pinWheelWipe" smil:subtype="twoBladeVertical"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par pres:preset-property="Spokes" smil:begin="0" smil:fill="hold" pres:node-type="on-click" pres:preset-class="entrance" pres:preset-id="ooo-entrance-wheel" pres:preset-sub-type="3">
+ <anim:set smil:begin="0" smil:dur="0.001" smil:fill="hold" smil:attributeName="visibility" smil:to="visible"/>
+ <anim:transitionFilter smil:dur="2" smil:type="pinWheelWipe" smil:subtype="threeBlade"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par pres:preset-property="Spokes" smil:begin="0" smil:fill="hold" pres:node-type="on-click" pres:preset-class="entrance" pres:preset-id="ooo-entrance-wheel" pres:preset-sub-type="4">
+ <anim:set smil:begin="0" smil:dur="0.001" smil:fill="hold" smil:attributeName="visibility" smil:to="visible"/>
+ <anim:transitionFilter smil:dur="2" smil:type="pinWheelWipe" smil:subtype="fourBlade"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par pres:preset-property="Spokes" smil:begin="0" smil:fill="hold" pres:node-type="on-click" pres:preset-class="entrance" pres:preset-id="ooo-entrance-wheel" pres:preset-sub-type="8">
+ <anim:set smil:begin="0" smil:dur="0.001" smil:fill="hold" smil:attributeName="visibility" smil:to="visible"/>
+ <anim:transitionFilter smil:dur="2" smil:type="pinWheelWipe" smil:subtype="eightBlade"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+
+<!-- ooo-entrance-snake-wipe -->
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par pres:preset-property="Direction" smil:begin="0" smil:fill="hold" pres:node-type="on-click" pres:preset-class="entrance" pres:preset-id="ooo-entrance-snake-wipe" pres:preset-sub-type="from-top-left-horizontal">
+ <anim:set smil:begin="0" smil:dur="0.001" smil:fill="hold" smil:attributeName="visibility" smil:to="visible"/>
+ <anim:transitionFilter smil:dur="0.5" smil:type="snakeWipe" smil:subtype="topLeftHorizontal"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par pres:preset-property="Direction" smil:begin="0" smil:fill="hold" pres:node-type="on-click" pres:preset-class="entrance" pres:preset-id="ooo-entrance-snake-wipe" pres:preset-sub-type="from-top-left-vertical">
+ <anim:set smil:begin="0" smil:dur="0.001" smil:fill="hold" smil:attributeName="visibility" smil:to="visible"/>
+ <anim:transitionFilter smil:dur="0.5" smil:type="snakeWipe" smil:subtype="topLeftVertical"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par pres:preset-property="Direction" smil:begin="0" smil:fill="hold" pres:node-type="on-click" pres:preset-class="entrance" pres:preset-id="ooo-entrance-snake-wipe" pres:preset-sub-type="from-bottom-right-vertical">
+ <anim:set smil:begin="0" smil:dur="0.001" smil:fill="hold" smil:attributeName="visibility" smil:to="visible"/>
+ <anim:transitionFilter smil:dur="0.5" smil:type="snakeWipe" smil:subtype="topLeftVertical" smil:direction="reverse"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par pres:preset-property="Direction" smil:begin="0" smil:fill="hold" pres:node-type="on-click" pres:preset-class="entrance" pres:preset-id="ooo-entrance-snake-wipe" pres:preset-sub-type="from-bottom-right-horizontal">
+ <anim:set smil:begin="0" smil:dur="0.001" smil:fill="hold" smil:attributeName="visibility" smil:to="visible"/>
+ <anim:transitionFilter smil:dur="0.5" smil:type="snakeWipe" smil:subtype="topLeftHorizontal" smil:direction="reverse"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+
+<!-- ooo-entrance-spiral-wipe -->
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par pres:preset-property="Direction" smil:begin="0" smil:fill="hold" pres:node-type="on-click" pres:preset-class="entrance" pres:preset-id="ooo-entrance-spiral-wipe" pres:preset-sub-type="from-top-left-clockwise">
+ <anim:set smil:begin="0" smil:dur="0.001" smil:fill="hold" smil:attributeName="visibility" smil:to="visible"/>
+ <anim:transitionFilter smil:dur="0.5" smil:type="spiralWipe" smil:subtype="topLeftClockwise"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par pres:preset-property="Direction" smil:begin="0" smil:fill="hold" pres:node-type="on-click" pres:preset-class="entrance" pres:preset-id="ooo-entrance-spiral-wipe" pres:preset-sub-type="from-top-right-counter-clockwise">
+ <anim:set smil:begin="0" smil:dur="0.001" smil:fill="hold" smil:attributeName="visibility" smil:to="visible"/>
+ <anim:transitionFilter smil:dur="0.5" smil:type="spiralWipe" smil:subtype="topRightCounterClockwise"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par pres:preset-property="Direction" smil:begin="0" smil:fill="hold" pres:node-type="on-click" pres:preset-class="entrance" pres:preset-id="ooo-entrance-spiral-wipe" pres:preset-sub-type="from-center-clockwise">
+ <anim:set smil:begin="0" smil:dur="0.001" smil:fill="hold" smil:attributeName="visibility" smil:to="visible"/>
+ <anim:transitionFilter smil:dur="0.5" smil:type="spiralWipe" smil:subtype="topLeftClockwise" smil:direction="reverse"/>/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par pres:preset-property="Direction" smil:begin="0" smil:fill="hold" pres:node-type="on-click" pres:preset-class="entrance" pres:preset-id="ooo-entrance-spiral-wipe" pres:preset-sub-type="from-center-counter-clockwise">
+ <anim:set smil:begin="0" smil:dur="0.001" smil:fill="hold" smil:attributeName="visibility" smil:to="visible"/>
+ <anim:transitionFilter smil:dur="0.5" smil:type="spiralWipe" smil:subtype="topRightCounterClockwise" smil:direction="reverse"/>/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+
+<!-- ooo-entrance-wipe -->
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par pres:preset-property="Direction" smil:begin="0" smil:fill="hold" pres:node-type="on-click" pres:preset-class="entrance" pres:preset-id="ooo-entrance-wipe" pres:preset-sub-type="from-bottom">
+ <anim:set smil:begin="0" smil:dur="0.001" smil:fill="hold" smil:attributeName="visibility" smil:to="visible"/>
+ <anim:transitionFilter smil:dur="0.5" smil:type="barWipe" smil:subtype="topToBottom" smil:direction="reverse"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par pres:preset-property="Direction" smil:begin="0" smil:fill="hold" pres:node-type="on-click" pres:preset-class="entrance" pres:preset-id="ooo-entrance-wipe" pres:preset-sub-type="from-left">
+ <anim:set smil:begin="0" smil:dur="0.001" smil:fill="hold" smil:attributeName="visibility" smil:to="visible"/>
+ <anim:transitionFilter smil:dur="0.5" smil:type="barWipe" smil:subtype="leftToRight"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par pres:preset-property="Direction" smil:begin="0" smil:fill="hold" pres:node-type="on-click" pres:preset-class="entrance" pres:preset-id="ooo-entrance-wipe" pres:preset-sub-type="from-right">
+ <anim:set smil:begin="0" smil:dur="0.001" smil:fill="hold" smil:attributeName="visibility" smil:to="visible"/>
+ <anim:transitionFilter smil:dur="0.5" smil:type="barWipe" smil:subtype="leftToRight" smil:direction="reverse"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par pres:preset-property="Direction" smil:begin="0" smil:fill="hold" pres:node-type="on-click" pres:preset-class="entrance" pres:preset-id="ooo-entrance-wipe" pres:preset-sub-type="from-top">
+ <anim:set smil:begin="0" smil:dur="0.001" smil:fill="hold" smil:attributeName="visibility" smil:to="visible"/>
+ <anim:transitionFilter smil:dur="0.5" smil:type="barWipe" smil:subtype="topToBottom"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold" pres:node-type="on-click" pres:preset-class="entrance" pres:preset-id="ooo-entrance-expand">
+ <anim:set smil:begin="0" smil:dur="0.001" smil:fill="hold" smil:attributeName="visibility" smil:to="visible"/>
+ <anim:animate smil:dur="1" smil:fill="hold" smil:attributeName="width" smil:values="width*0.70;width" smil:keyTimes="0;1"/>
+ <anim:animate smil:dur="1" smil:fill="hold" smil:attributeName="height" smil:values="height;height" smil:keyTimes="0;1"/>
+ <anim:transitionFilter smil:dur="1" smil:type="fade" smil:subtype="crossfade"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold" pres:node-type="on-click" pres:preset-class="entrance" pres:preset-id="ooo-entrance-fade-in">
+ <anim:set smil:begin="0" smil:dur="0.001" smil:fill="hold" smil:attributeName="visibility" smil:to="visible"/>
+ <anim:transitionFilter smil:dur="2" smil:type="fade" smil:subtype="crossfade"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:iterate pres:text-only="true" smil:begin="0" smil:fill="hold" pres:node-type="on-click" pres:preset-class="entrance" pres:preset-id="ooo-entrance-fade-in-and-swivel" anim:iterate-type="by-letter" anim:iterate-interval="0.2s">
+ <anim:set smil:begin="0" smil:dur="0.001" smil:fill="hold" smil:attributeName="visibility" smil:to="visible"/>
+ <anim:transitionFilter smil:dur="2" smil:type="fade" smil:subtype="crossfade"/>
+ <anim:animate smil:dur="2" smil:fill="hold" smil:attributeName="width" smil:values="0;1" smil:keyTimes="0;1" anim:formula="width*sin(2.5*pi*$)"/>
+ <anim:animate smil:dur="2" smil:fill="hold" smil:attributeName="height" smil:values="height;height" smil:keyTimes="0;1"/>
+ </anim:iterate>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold" pres:node-type="on-click" pres:preset-class="entrance" pres:preset-id="ooo-entrance-fade-in-and-zoom">
+ <anim:set smil:begin="0" smil:dur="0.001" smil:fill="hold" smil:attributeName="visibility" smil:to="visible"/>
+ <anim:animate smil:dur="0.5" smil:fill="hold" smil:attributeName="width" smil:values="0;width" smil:keyTimes="0;1"/>
+ <anim:animate smil:dur="0.5" smil:fill="hold" smil:attributeName="height" smil:values="0;height" smil:keyTimes="0;1"/>
+ <anim:transitionFilter smil:dur="0.5" smil:type="fade" smil:subtype="crossfade"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold" pres:node-type="on-click" pres:preset-class="entrance" pres:preset-id="ooo-entrance-ascend">
+ <anim:set smil:begin="0" smil:dur="0.001" smil:fill="hold" smil:attributeName="visibility" smil:to="visible"/>
+ <anim:transitionFilter smil:dur="1" smil:type="fade" smil:subtype="crossfade"/>
+ <anim:animate smil:dur="1" smil:fill="hold" smil:attributeName="x" smil:values="x;x" smil:keyTimes="0;1"/>
+ <anim:animate smil:dur="1" smil:fill="hold" smil:attributeName="y" smil:values="y+.1;y" smil:keyTimes="0;1"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold" pres:node-type="on-click" pres:preset-class="entrance" pres:preset-id="ooo-entrance-center-revolve">
+ <anim:set smil:begin="0" smil:dur="0.001" smil:fill="hold" smil:attributeName="visibility" smil:to="visible"/>
+ <anim:transitionFilter smil:dur="0.1" smil:type="fade" smil:subtype="crossfade"/>
+ <anim:animate smil:dur="0.4" smil:fill="hold" smil:attributeName="x" smil:values="x;x" smil:keyTimes="0;1"/>
+ <anim:animate smil:dur="0.4" smil:fill="hold" smil:attributeName="y" smil:values="y+0.31;y+0.31" smil:keyTimes="0;1"/>
+ <anim:animate smil:begin="0.4" smil:dur="0.6" smil:fill="hold" smil:decelerate="0.5" smil:attributeName="x" smil:values="x;x+0.0242;x+0.0479;x+0.0704;x+0.0911;x+0.1096;x+0.1254;x+0.1381;x+0.1474;x+0.1531;x+0.1550;x+0.1531;x+0.1474;x+0.1381;x+0.1254;x+0.1096;x+0.0911;x+0.0704;x+0.0479;x+0.0242;x" smil:keyTimes="0;0.05;0.1;0.15;0.2;0.25;0.3;0.35;0.4;0.45;0.5;0.55;0.6;0.65;0.7;0.75;0.8;0.85;0.9;0.95;1"/>
+ <anim:animate smil:begin="0.4" smil:dur="0.6" smil:fill="hold" smil:decelerate="0.5" smil:attributeName="y" smil:values="y+0.31;y+0.308;y+0.3024;y+0.2931;y+0.2804;y+0.2646;y+0.2461;y+0.2253;y+0.2029;y+0.1792;y+0.155;y+0.1307;y+0.1071;y+0.0846;y+0.0639;y+0.0454;y+0.0296;y+0.0169;y+0.0076;y+0.0019;y" smil:keyTimes="0;0.05;0.1;0.15;0.2;0.25;0.3;0.35;0.4;0.45;0.5;0.55;0.6;0.65;0.7;0.75;0.8;0.85;0.9;0.95;1"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:iterate pres:preset-property="Color1;Color2" pres:text-only="true" smil:begin="0" smil:fill="hold" pres:node-type="on-click" pres:preset-class="entrance" pres:preset-id="ooo-entrance-colored-lettering" anim:iterate-type="by-letter" anim:iterate-interval="0.04s">
+ <anim:set smil:begin="0" smil:dur="0.001" smil:fill="hold" smil:attributeName="visibility" smil:to="visible"/>
+ <anim:animate smil:dur="0.08" smil:attributeName="color" smil:values="#333399;#009999" smil:keyTimes="0;0.5" smil:calcMode="discrete"/>
+ <anim:animate smil:dur="0.08" smil:attributeName="fill-color" smil:values="#333399;#009999" smil:keyTimes="0;0.5" smil:calcMode="discrete"/>
+ <anim:set smil:dur="0.08" smil:attributeName="fill" smil:to="solid"/>
+ </anim:iterate>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold" smil:decelerate="1" pres:node-type="on-click" pres:preset-class="entrance" pres:preset-id="ooo-entrance-compress">
+ <anim:set smil:begin="0" smil:dur="0.001" smil:fill="hold" smil:attributeName="visibility" smil:to="visible"/>
+ <anim:animate smil:dur="1" smil:fill="hold" smil:attributeName="width" smil:values="width+.3;width" smil:keyTimes="0;1"/>
+ <anim:animate smil:dur="1" smil:fill="hold" smil:attributeName="height" smil:values="height;height" smil:keyTimes="0;1"/>
+ <anim:transitionFilter smil:dur="1" smil:type="fade" smil:subtype="crossfade"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold" pres:node-type="on-click" pres:preset-class="entrance" pres:preset-id="ooo-entrance-descend">
+ <anim:set smil:begin="0" smil:dur="0.001" smil:fill="hold" smil:attributeName="visibility" smil:to="visible"/>
+ <anim:transitionFilter smil:dur="1" smil:type="fade" smil:subtype="crossfade"/>
+ <anim:animate smil:dur="1" smil:fill="hold" smil:attributeName="x" smil:values="x;x" smil:keyTimes="0;1"/>
+ <anim:animate smil:dur="1" smil:fill="hold" smil:attributeName="y" smil:values="y-.1;y" smil:keyTimes="0;1"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold" pres:node-type="on-click" pres:preset-class="entrance" pres:preset-id="ooo-entrance-ease-in">
+ <anim:set smil:begin="0" smil:dur="0.001" smil:fill="hold" smil:attributeName="visibility" smil:to="visible"/>
+ <anim:animate smil:dur="1" smil:fill="hold" smil:attributeName="x" smil:values="x-.2;x" smil:keyTimes="0;1"/>
+ <anim:animate smil:dur="1" smil:fill="hold" smil:attributeName="y" smil:values="y;y" smil:keyTimes="0;1"/>
+ <anim:transitionFilter smil:dur="1" smil:type="barWipe" smil:subtype="leftToRight" smil:direction="reverse"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:iterate pres:text-only="true" smil:begin="0" smil:fill="hold" pres:node-type="on-click" pres:preset-class="entrance" pres:preset-id="ooo-entrance-turn-and-grow" anim:iterate-type="by-letter" anim:iterate-interval="0.05s">
+ <anim:set smil:begin="0" smil:dur="0.001" smil:fill="hold" smil:attributeName="visibility" smil:to="visible"/>
+ <anim:animate smil:dur="1" smil:fill="hold" smil:attributeName="width" smil:values="0;width" smil:keyTimes="0;1"/>
+ <anim:animate smil:dur="1" smil:fill="hold" smil:attributeName="height" smil:values="0;height" smil:keyTimes="0;1"/>
+ <anim:animate smil:dur="1" smil:fill="hold" smil:attributeName="rotate" smil:values="90;0" smil:keyTimes="0;1"/>
+ <anim:transitionFilter smil:dur="1" smil:type="fade" smil:subtype="crossfade"/>
+ </anim:iterate>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold" pres:node-type="on-click" pres:preset-class="entrance" pres:preset-id="ooo-entrance-rise-up">
+ <anim:set smil:begin="0" smil:dur="0.001" smil:fill="hold" smil:attributeName="visibility" smil:to="visible"/>
+ <anim:transitionFilter smil:dur="1" smil:type="fade" smil:subtype="crossfade"/>
+ <anim:animate smil:dur="1" smil:fill="hold" smil:attributeName="x" smil:values="x;x" smil:keyTimes="0;1"/>
+ <anim:animate smil:dur="0.9" smil:fill="hold" smil:decelerate="1" smil:attributeName="y" smil:values="y+1;y-.03" smil:keyTimes="0;1"/>
+ <anim:animate smil:begin="0.9" smil:dur="0.1" smil:fill="hold" smil:accelerate="1" smil:attributeName="y" smil:values="y-.03;y" smil:keyTimes="0;1"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold" smil:decelerate="1" pres:node-type="on-click" pres:preset-class="entrance" pres:preset-id="ooo-entrance-spin-in">
+ <anim:set smil:begin="0" smil:dur="0.001" smil:fill="hold" smil:attributeName="visibility" smil:to="visible"/>
+ <anim:animate smil:dur="0.5" smil:fill="hold" smil:attributeName="width" smil:values="0;width" smil:keyTimes="0;1"/>
+ <anim:animate smil:dur="0.5" smil:fill="hold" smil:attributeName="height" smil:values="0;height" smil:keyTimes="0;1"/>
+ <anim:animate smil:dur="0.5" smil:fill="hold" smil:attributeName="rotate" smil:values="360;0" smil:keyTimes="0;1"/>
+ <anim:transitionFilter smil:dur="0.5" smil:type="fade" smil:subtype="crossfade"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par pres:preset-property="Direction" smil:begin="0" smil:fill="hold" pres:node-type="on-click" pres:preset-class="entrance" pres:preset-id="ooo-entrance-stretchy" pres:preset-sub-type="across">
+ <anim:set smil:begin="0" smil:dur="0.001" smil:fill="hold" smil:attributeName="visibility" smil:to="visible"/>
+ <anim:animate smil:dur="0.5" smil:fill="hold" smil:attributeName="width" smil:values="0;width" smil:keyTimes="0;1"/>
+ <anim:animate smil:dur="0.5" smil:fill="hold" smil:attributeName="height" smil:values="height;height" smil:keyTimes="0;1"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par pres:preset-property="Direction" smil:begin="0" smil:fill="hold" pres:node-type="on-click" pres:preset-class="entrance" pres:preset-id="ooo-entrance-stretchy" pres:preset-sub-type="downward">
+ <anim:set smil:begin="0" smil:dur="0.001" smil:fill="hold" smil:attributeName="visibility" smil:to="visible"/>
+ <anim:animate smil:dur="0.5" smil:fill="hold" smil:attributeName="width" smil:values="width;width" smil:keyTimes="0;1"/>
+ <anim:animate smil:dur="0.5" smil:fill="hold" smil:attributeName="height" smil:values="0;height" smil:keyTimes="0;1"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par pres:preset-property="Direction" smil:begin="0" smil:fill="hold" pres:node-type="on-click" pres:preset-class="entrance" pres:preset-id="ooo-entrance-stretchy" pres:preset-sub-type="from-bottom">
+ <anim:set smil:begin="0" smil:dur="0.001" smil:fill="hold" smil:attributeName="visibility" smil:to="visible"/>
+ <anim:animate smil:dur="0.5" smil:fill="hold" smil:attributeName="x" smil:values="x;x" smil:keyTimes="0;1"/>
+ <anim:animate smil:dur="0.5" smil:fill="hold" smil:attributeName="y" smil:values="y+height/2;y" smil:keyTimes="0;1"/>
+ <anim:animate smil:dur="0.5" smil:fill="hold" smil:attributeName="width" smil:values="width;width" smil:keyTimes="0;1"/>
+ <anim:animate smil:dur="0.5" smil:fill="hold" smil:attributeName="height" smil:values="0;height" smil:keyTimes="0;1"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par pres:preset-property="Direction" smil:begin="0" smil:fill="hold" pres:node-type="on-click" pres:preset-class="entrance" pres:preset-id="ooo-entrance-stretchy" pres:preset-sub-type="from-left">
+ <anim:set smil:begin="0" smil:dur="0.001" smil:fill="hold" smil:attributeName="visibility" smil:to="visible"/>
+ <anim:animate smil:dur="0.5" smil:fill="hold" smil:attributeName="x" smil:values="x-width/2;x" smil:keyTimes="0;1"/>
+ <anim:animate smil:dur="0.5" smil:fill="hold" smil:attributeName="y" smil:values="y;y" smil:keyTimes="0;1"/>
+ <anim:animate smil:dur="0.5" smil:fill="hold" smil:attributeName="width" smil:values="0;width" smil:keyTimes="0;1"/>
+ <anim:animate smil:dur="0.5" smil:fill="hold" smil:attributeName="height" smil:values="height;height" smil:keyTimes="0;1"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par pres:preset-property="Direction" smil:begin="0" smil:fill="hold" pres:node-type="on-click" pres:preset-class="entrance" pres:preset-id="ooo-entrance-stretchy" pres:preset-sub-type="from-right">
+ <anim:set smil:begin="0" smil:dur="0.001" smil:fill="hold" smil:attributeName="visibility" smil:to="visible"/>
+ <anim:animate smil:dur="0.5" smil:fill="hold" smil:attributeName="x" smil:values="x+width/2;x" smil:keyTimes="0;1"/>
+ <anim:animate smil:dur="0.5" smil:fill="hold" smil:attributeName="y" smil:values="y;y" smil:keyTimes="0;1"/>
+ <anim:animate smil:dur="0.5" smil:fill="hold" smil:attributeName="width" smil:values="0;width" smil:keyTimes="0;1"/>
+ <anim:animate smil:dur="0.5" smil:fill="hold" smil:attributeName="height" smil:values="height;height" smil:keyTimes="0;1"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par pres:preset-property="Direction" smil:begin="0" smil:fill="hold" pres:node-type="on-click" pres:preset-class="entrance" pres:preset-id="ooo-entrance-stretchy" pres:preset-sub-type="from-top">
+ <anim:set smil:begin="0" smil:dur="0.001" smil:fill="hold" smil:attributeName="visibility" smil:to="visible"/>
+ <anim:animate smil:dur="0.5" smil:fill="hold" smil:attributeName="x" smil:values="x;x" smil:keyTimes="0;1"/>
+ <anim:animate smil:dur="0.5" smil:fill="hold" smil:attributeName="y" smil:values="y-height/2;y" smil:keyTimes="0;1"/>
+ <anim:animate smil:dur="0.5" smil:fill="hold" smil:attributeName="width" smil:values="width;width" smil:keyTimes="0;1"/>
+ <anim:animate smil:dur="0.5" smil:fill="hold" smil:attributeName="height" smil:values="0;height" smil:keyTimes="0;1"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par pres:preset-property="Direction" smil:begin="0" smil:fill="hold" pres:node-type="on-click" pres:preset-class="entrance" pres:preset-id="ooo-entrance-stretchy" pres:preset-sub-type="from-top-right">
+ <anim:set smil:begin="0" smil:dur="0.001" smil:fill="hold" smil:attributeName="visibility" smil:to="visible"/>
+ <anim:animate smil:dur="0.5" smil:fill="hold" smil:attributeName="x" smil:values="x+width/2;x" smil:keyTimes="0;1"/>
+ <anim:animate smil:dur="0.5" smil:fill="hold" smil:attributeName="y" smil:values="y-height/2;y" smil:keyTimes="0;1"/>
+ <anim:animate smil:dur="0.5" smil:fill="hold" smil:attributeName="width" smil:values="0;width" smil:keyTimes="0;1"/>
+ <anim:animate smil:dur="0.5" smil:fill="hold" smil:attributeName="height" smil:values="0;height" smil:keyTimes="0;1"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par pres:preset-property="Direction" smil:begin="0" smil:fill="hold" pres:node-type="on-click" pres:preset-class="entrance" pres:preset-id="ooo-entrance-stretchy" pres:preset-sub-type="from-bottom-right">
+ <anim:set smil:begin="0" smil:dur="0.001" smil:fill="hold" smil:attributeName="visibility" smil:to="visible"/>
+ <anim:animate smil:dur="0.5" smil:fill="hold" smil:attributeName="x" smil:values="x+width/2;x" smil:keyTimes="0;1"/>
+ <anim:animate smil:dur="0.5" smil:fill="hold" smil:attributeName="y" smil:values="y+height/2;y" smil:keyTimes="0;1"/>
+ <anim:animate smil:dur="0.5" smil:fill="hold" smil:attributeName="width" smil:values="0;width" smil:keyTimes="0;1"/>
+ <anim:animate smil:dur="0.5" smil:fill="hold" smil:attributeName="height" smil:values="0;height" smil:keyTimes="0;1"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par pres:preset-property="Direction" smil:begin="0" smil:fill="hold" pres:node-type="on-click" pres:preset-class="entrance" pres:preset-id="ooo-entrance-stretchy" pres:preset-sub-type="from-top-left">
+ <anim:set smil:begin="0" smil:dur="0.001" smil:fill="hold" smil:attributeName="visibility" smil:to="visible"/>
+ <anim:animate smil:dur="0.5" smil:fill="hold" smil:attributeName="x" smil:values="x-width/2;x" smil:keyTimes="0;1"/>
+ <anim:animate smil:dur="0.5" smil:fill="hold" smil:attributeName="y" smil:values="y-height/2;y" smil:keyTimes="0;1"/>
+ <anim:animate smil:dur="0.5" smil:fill="hold" smil:attributeName="width" smil:values="0;width" smil:keyTimes="0;1"/>
+ <anim:animate smil:dur="0.5" smil:fill="hold" smil:attributeName="height" smil:values="0;height" smil:keyTimes="0;1"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par pres:preset-property="Direction" smil:begin="0" smil:fill="hold" pres:node-type="on-click" pres:preset-class="entrance" pres:preset-id="ooo-entrance-stretchy" pres:preset-sub-type="from-bottom-left">
+ <anim:set smil:begin="0" smil:dur="0.001" smil:fill="hold" smil:attributeName="visibility" smil:to="visible"/>
+ <anim:animate smil:dur="0.5" smil:fill="hold" smil:attributeName="x" smil:values="x-width/2;x" smil:keyTimes="0;1"/>
+ <anim:animate smil:dur="0.5" smil:fill="hold" smil:attributeName="y" smil:values="y+height/2;y" smil:keyTimes="0;1"/>
+ <anim:animate smil:dur="0.5" smil:fill="hold" smil:attributeName="width" smil:values="0;width" smil:keyTimes="0;1"/>
+ <anim:animate smil:dur="0.5" smil:fill="hold" smil:attributeName="height" smil:values="0;height" smil:keyTimes="0;1"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:iterate pres:text-only="true" smil:begin="0" smil:fill="hold" pres:node-type="on-click" pres:preset-class="entrance" pres:preset-id="ooo-entrance-unfold" anim:iterate-type="by-letter" anim:iterate-interval="0.1s">
+ <anim:set smil:begin="0" smil:dur="0.001" smil:fill="hold" smil:attributeName="visibility" smil:to="visible"/>
+ <anim:transitionFilter smil:dur="1" smil:type="fade" smil:subtype="crossfade"/>
+ <anim:animate smil:dur="1" smil:fill="hold" smil:attributeName="x" smil:values="x-.1;x" smil:keyTimes="0;1"/>
+ <anim:animate smil:dur="1" smil:fill="hold" smil:attributeName="y" smil:values="y;y" smil:keyTimes="0;1"/>
+ </anim:iterate>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par pres:preset-property="Zoom" smil:begin="0" smil:fill="hold" pres:node-type="on-click" pres:preset-class="entrance" pres:preset-id="ooo-entrance-zoom" pres:preset-sub-type="in">
+ <anim:set smil:begin="0" smil:dur="0.001" smil:fill="hold" smil:attributeName="visibility" smil:to="visible"/>
+ <anim:animate smil:dur="0.5" smil:fill="hold" smil:attributeName="width" smil:values="0;width" smil:keyTimes="0;1"/>
+ <anim:animate smil:dur="0.5" smil:fill="hold" smil:attributeName="height" smil:values="0;height" smil:keyTimes="0;1"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par pres:preset-property="Zoom" smil:begin="0" smil:fill="hold" pres:node-type="on-click" pres:preset-class="entrance" pres:preset-id="ooo-entrance-zoom" pres:preset-sub-type="in-from-screen-center">
+ <anim:set smil:begin="0" smil:dur="0.001" smil:fill="hold" smil:attributeName="visibility" smil:to="visible"/>
+ <anim:animate smil:dur="0.5" smil:fill="hold" smil:attributeName="width" smil:values="0;width" smil:keyTimes="0;1"/>
+ <anim:animate smil:dur="0.5" smil:fill="hold" smil:attributeName="height" smil:values="0;height" smil:keyTimes="0;1"/>
+ <anim:animate smil:dur="0.5" smil:fill="hold" smil:attributeName="x" smil:values="0.5;x" smil:keyTimes="0;1"/>
+ <anim:animate smil:dur="0.5" smil:fill="hold" smil:attributeName="y" smil:values="0.5;y" smil:keyTimes="0;1"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par pres:preset-property="Zoom" smil:begin="0" smil:fill="hold" pres:node-type="on-click" pres:preset-class="entrance" pres:preset-id="ooo-entrance-zoom" pres:preset-sub-type="in-slightly">
+ <anim:set smil:begin="0" smil:dur="0.001" smil:fill="hold" smil:attributeName="visibility" smil:to="visible"/>
+ <anim:animate smil:dur="0.5" smil:fill="hold" smil:attributeName="width" smil:values="2/3*width;width" smil:keyTimes="0;1"/>
+ <anim:animate smil:dur="0.5" smil:fill="hold" smil:attributeName="height" smil:values="2/3*height;height" smil:keyTimes="0;1"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par pres:preset-property="Zoom" smil:begin="0" smil:fill="hold" pres:node-type="on-click" pres:preset-class="entrance" pres:preset-id="ooo-entrance-zoom" pres:preset-sub-type="out">
+ <anim:set smil:begin="0" smil:dur="0.001" smil:fill="hold" smil:attributeName="visibility" smil:to="visible"/>
+ <anim:animate smil:dur="0.5" smil:fill="hold" smil:attributeName="width" smil:values="4*width;width" smil:keyTimes="0;1"/>
+ <anim:animate smil:dur="0.5" smil:fill="hold" smil:attributeName="height" smil:values="4*height;height" smil:keyTimes="0;1"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par pres:preset-property="Zoom" smil:begin="0" smil:fill="hold" pres:node-type="on-click" pres:preset-class="entrance" pres:preset-id="ooo-entrance-zoom" pres:preset-sub-type="out-from-screen-center">
+ <anim:set smil:begin="0" smil:dur="0.001" smil:fill="hold" smil:attributeName="visibility" smil:to="visible"/>
+ <anim:animate smil:dur="0.5" smil:fill="hold" smil:attributeName="width" smil:values="(6*min(max(width*height,.3),1)-7.4)/-.7*width;width" smil:keyTimes="0;1"/>
+ <anim:animate smil:dur="0.5" smil:fill="hold" smil:attributeName="height" smil:values="(6*min(max(width*height,.3),1)-7.4)/-.7*height;height" smil:keyTimes="0;1"/>
+ <anim:animate smil:dur="0.5" smil:fill="hold" smil:attributeName="x" smil:values="0.5;x" smil:keyTimes="0;1"/>
+ <anim:animate smil:dur="0.5" smil:fill="hold" smil:attributeName="y" smil:values="1+(6*min(max(width*height,.3),1)-7.4)/-.7*height/2;y" smil:keyTimes="0;1"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par pres:preset-property="Zoom" smil:begin="0" smil:fill="hold" pres:node-type="on-click" pres:preset-class="entrance" pres:preset-id="ooo-entrance-zoom" pres:preset-sub-type="out-slightly">
+ <anim:set smil:begin="0" smil:dur="0.001" smil:fill="hold" smil:attributeName="visibility" smil:to="visible"/>
+ <anim:animate smil:dur="0.5" smil:fill="hold" smil:attributeName="width" smil:values="4/3*width;width" smil:keyTimes="0;1"/>
+ <anim:animate smil:dur="0.5" smil:fill="hold" smil:attributeName="height" smil:values="4/3*height;height" smil:keyTimes="0;1"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold" pres:node-type="on-click" pres:preset-class="entrance" pres:preset-id="ooo-entrance-boomerang">
+ <anim:set smil:begin="0" smil:dur="0.001" smil:fill="hold" smil:attributeName="visibility" smil:to="visible"/>
+ <anim:animate smil:begin="0" smil:dur="0.5" smil:fill="hold" smil:decelerate="0.5" smil:attributeName="rotate" smil:values="-90;0" smil:keyTimes="0;1"/>
+ <anim:animate smil:begin="0" smil:dur="0.5" smil:fill="hold" smil:decelerate="0.5" smil:attributeName="width" smil:values="width;width*.05" smil:keyTimes="0;1"/>
+ <anim:animate smil:begin="0.5" smil:dur="0.5" smil:fill="hold" smil:accelerate="0.5" smil:attributeName="width" smil:values="width*.05;width" smil:keyTimes="0;1"/>
+ <anim:animate smil:dur="1" smil:fill="hold" smil:attributeName="height" smil:values="height;height" smil:keyTimes="0;1"/>
+ <anim:animate smil:begin="0" smil:dur="0.5" smil:fill="hold" smil:decelerate="0.5" smil:attributeName="x" smil:values="x+.4;x" smil:keyTimes="0;1"/>
+ <anim:animate smil:begin="0" smil:dur="0.5" smil:fill="hold" smil:decelerate="0.5" smil:attributeName="y" smil:values="y-.2;y+.1" smil:keyTimes="0;1"/>
+ <anim:animate smil:begin="0.5" smil:dur="0.5" smil:fill="hold" smil:accelerate="0.5" smil:attributeName="y" smil:values="y+.1;y" smil:keyTimes="0;1"/>
+ <anim:transitionFilter smil:begin="0" smil:dur="1" smil:decelerate="0.5" smil:type="fade" smil:subtype="crossfade"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold" pres:node-type="on-click" pres:preset-class="entrance" pres:preset-id="ooo-entrance-bounce">
+ <anim:set smil:begin="0" smil:dur="0.001" smil:fill="hold" smil:attributeName="visibility" smil:to="visible"/>
+ <anim:transitionFilter smil:begin="0" smil:dur="0.58" smil:type="barWipe" smil:subtype="topToBottom"/>
+ <anim:animate smil:begin="0" smil:dur="1.822" smil:attributeName="x" smil:values="x-0.25;x" smil:keyTimes="0;1" smil:keySplines="0,0;0.14,0.36;0.43,0.73;0.71,0.91;1,1"/>
+ <anim:animate smil:begin="0" smil:dur="0.664" smil:attributeName="y" smil:values="0.5;1" smil:keyTimes="0;1" anim:formula="y-sin(pi*$)/3" smil:keySplines="0,0;0.25,0.07;0.5,0.2;0.75,0.467;1,1"/>
+ <anim:animate smil:begin="0.664" smil:dur="0.664" smil:attributeName="y" smil:values="0;1" smil:keyTimes="0;1" anim:formula="y-sin(pi*$)/9" smil:keySplines="0,0;0.125,0.2665;0.25,0.4;0.375,0.465;0.5,0.5;0.625,0.535;0.75,0.6;0.875,0.7335;1,1"/>
+ <anim:animate smil:begin="1.324" smil:dur="0.332" smil:attributeName="y" smil:values="0;1" smil:keyTimes="0;1" anim:formula="y-sin(pi*$)/27" smil:keySplines="0,0;0.125,0.2665;0.25,0.4;0.375,0.465;0.5,0.5;0.625,0.535;0.75,0.6;0.875,0.7335;1,1"/>
+ <anim:animate smil:begin="1.656" smil:dur="0.164" smil:attributeName="y" smil:values="0;1" smil:keyTimes="0;1" anim:formula="y-sin(pi*$)/81" smil:keySplines="0,0;0.125,0.2665;0.25,0.4;0.375,0.465;0.5,0.5;0.625,0.535;0.75,0.6;0.875,0.7335;1,1"/>
+ <anim:animateTransform smil:begin="0.65" smil:dur="0.026" smil:to="1,0.6" svg:type="scale"/>
+ <anim:animateTransform smil:begin="0.676" smil:dur="0.166" smil:decelerate="0.5" smil:to="1,1" svg:type="scale"/>
+ <anim:animateTransform smil:begin="1.312" smil:dur="0.026" smil:to="1,0.8" svg:type="scale"/>
+ <anim:animateTransform smil:begin="1.338" smil:dur="0.166" smil:decelerate="0.5" smil:to="1,1" svg:type="scale"/>
+ <anim:animateTransform smil:begin="1.642" smil:dur="0.026" smil:to="1,0.9" svg:type="scale"/>
+ <anim:animateTransform smil:begin="1.668" smil:dur="0.166" smil:decelerate="0.5" smil:to="1,1" svg:type="scale"/>
+ <anim:animateTransform smil:begin="1.808" smil:dur="0.026" smil:to="1,0.95" svg:type="scale"/>
+ <anim:animateTransform smil:begin="1.834" smil:dur="0.166" smil:decelerate="0.5" smil:to="1,1" svg:type="scale"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold" pres:node-type="on-click" pres:preset-class="entrance" pres:preset-id="ooo-entrance-movie-credits">
+ <anim:set smil:begin="0" smil:dur="0.001" smil:fill="hold" smil:attributeName="visibility" smil:to="visible"/>
+ <anim:animate smil:dur="15" smil:fill="hold" smil:attributeName="x" smil:values="x;x" smil:keyTimes="0;1"/>
+ <anim:animate smil:dur="15" smil:fill="hold" smil:attributeName="y" smil:values="y+1;y-1" smil:keyTimes="0;1"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold" pres:node-type="on-click" pres:preset-class="entrance" pres:preset-id="ooo-entrance-curve-up">
+ <anim:set smil:begin="0" smil:dur="0.001" smil:fill="hold" smil:attributeName="visibility" smil:to="visible"/>
+ <anim:animateTransform smil:begin="0" smil:dur="1" smil:fill="hold" smil:decelerate="0.5" smil:from="2.5,2.5" smil:to="1,1" svg:type="scale"/>
+ <anim:animateMotion smil:begin="0" smil:dur="1" smil:fill="hold" smil:decelerate="0.5" svg:path="M -0.46736 0.92887 C -0.37517 0.88508 -0.02552 0.75279 0.0908 0.66613 C 0.20747 0.57948 0.21649 0.50394 0.23177 0.40825 C 0.24705 0.31256 0.22118 0.15964 0.18264 0.09152 C 0.1441 0.02341 0.03802 0.0 0.0 0.0"/>
+ <anim:transitionFilter smil:dur="1" smil:type="fade" smil:subtype="crossfade"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:iterate pres:text-only="true" smil:begin="0" smil:fill="hold" pres:node-type="on-click" pres:preset-class="entrance" pres:preset-id="ooo-entrance-flip" anim:iterate-type="by-letter" anim:iterate-interval="0.1s">
+ <anim:set smil:begin="0" smil:dur="0.001" smil:fill="hold" smil:attributeName="visibility" smil:to="visible"/>
+ <anim:animate smil:begin="0" smil:dur="0.5" smil:fill="hold" smil:autoReverse="true" smil:attributeName="width" smil:by="(-width*2)"/>
+ <anim:animate smil:begin="0" smil:dur="0.5" smil:fill="hold" smil:decelerate="0.5" smil:autoReverse="true" smil:attributeName="x" smil:by="(width*0.50)"/>
+ <anim:animate smil:begin="0" smil:dur="1" smil:fill="hold" smil:attributeName="y" smil:from="(-height/2)" smil:to="(y)"/>
+ <anim:animateTransform smil:begin="0" smil:dur="1" smil:fill="hold" smil:by="360" svg:type="rotate"/>
+ </anim:iterate>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold" pres:node-type="on-click" pres:preset-class="entrance" pres:preset-id="ooo-entrance-float">
+ <anim:set smil:begin="0" smil:dur="0.001" smil:fill="hold" smil:attributeName="visibility" smil:to="visible"/>
+ <anim:transitionFilter smil:dur="0.8" smil:decelerate="1" smil:type="fade" smil:subtype="crossfade"/>
+ <anim:animate smil:dur="0.8" smil:fill="hold" smil:decelerate="1" smil:attributeName="rotate" smil:values="-90;0" smil:keyTimes="0;1"/>
+ <anim:animate smil:dur="0.8" smil:fill="hold" smil:decelerate="1" smil:attributeName="x" smil:values="x+0.4;x-0.05" smil:keyTimes="0;1"/>
+ <anim:animate smil:dur="0.8" smil:fill="hold" smil:decelerate="1" smil:attributeName="y" smil:values="y-0.4;y+0.1" smil:keyTimes="0;1"/>
+ <anim:animate smil:begin="0.8" smil:dur="0.2" smil:fill="hold" smil:accelerate="1" smil:attributeName="x" smil:values="x-0.05;x" smil:keyTimes="0;1"/>
+ <anim:animate smil:begin="0.8" smil:dur="0.2" smil:fill="hold" smil:accelerate="1" smil:attributeName="y" smil:values="y+0.1;y" smil:keyTimes="0;1"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par pres:text-only="true" smil:begin="0" smil:fill="hold" smil:accelerate="1" pres:node-type="on-click" pres:preset-class="entrance" pres:preset-id="ooo-entrance-fold">
+ <anim:set smil:begin="0" smil:dur="0.001" smil:fill="hold" smil:attributeName="visibility" smil:to="visible"/>
+ <anim:animate smil:dur="0.5" smil:fill="hold" smil:attributeName="width" smil:values="width*2.5;width" smil:keyTimes="0;1"/>
+ <anim:animate smil:dur="0.5" smil:fill="hold" smil:attributeName="height" smil:values="height*0.01;height" smil:keyTimes="0;1"/>
+ <anim:animate smil:dur="0.5" smil:fill="hold" smil:attributeName="x" smil:values="x;x" smil:keyTimes="0;1"/>
+ <anim:animate smil:dur="0.5" smil:fill="hold" smil:attributeName="y" smil:values="height+1;y" smil:keyTimes="0;1"/>
+ <anim:transitionFilter smil:dur="0.5" smil:type="fade" smil:subtype="crossfade"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold" smil:accelerate="1" pres:node-type="on-click" pres:preset-class="entrance" pres:preset-id="ooo-entrance-glide">
+ <anim:set smil:begin="0" smil:dur="0.001" smil:fill="hold" smil:attributeName="visibility" smil:to="visible"/>
+ <anim:animate smil:dur="0.5" smil:fill="hold" smil:attributeName="width" smil:values="width*0.05;width" smil:keyTimes="0;1"/>
+ <anim:animate smil:dur="0.5" smil:fill="hold" smil:attributeName="height" smil:values="height;height" smil:keyTimes="0;1"/>
+ <anim:animate smil:dur="0.5" smil:fill="hold" smil:attributeName="x" smil:values="x-.2;x" smil:keyTimes="0;1"/>
+ <anim:animate smil:dur="0.5" smil:fill="hold" smil:attributeName="y" smil:values="y;y" smil:keyTimes="0;1"/>
+ <anim:transitionFilter smil:dur="0.5" smil:type="fade" smil:subtype="crossfade"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold" pres:node-type="on-click" pres:preset-class="entrance" pres:preset-id="ooo-entrance-breaks">
+ <anim:set smil:begin="0" smil:dur="0.001" smil:fill="hold" smil:attributeName="visibility" smil:to="visible"/>
+ <anim:animate smil:begin="0" smil:dur="0.6" smil:fill="hold" smil:attributeName="x" smil:from="(-width/2)" smil:to="(x)"/>
+ <anim:animate smil:begin="0.6" smil:dur="0.2" smil:fill="hold" smil:decelerate="0.5" smil:autoReverse="true" smil:attributeName="skewX" smil:from="0" smil:to="-1"/>
+ <anim:animateTransform smil:begin="0.6" smil:dur="0.2" smil:fill="hold" smil:decelerate="1" smil:autoReverse="true" smil:from="1,1" smil:to="0.8,1" svg:type="scale"/>
+ <anim:animate smil:begin="0.6" smil:dur="0.2" smil:fill="hold" smil:decelerate="1" smil:autoReverse="true" smil:attributeName="x" smil:by="(height/3+width*0.1)" smil:additive="sum"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold" pres:node-type="on-click" pres:preset-class="entrance" pres:preset-id="ooo-entrance-magnify">
+ <anim:set smil:begin="0" smil:dur="0.001" smil:fill="hold" smil:attributeName="visibility" smil:to="visible"/>
+ <anim:transitionFilter smil:dur="0.77" smil:decelerate="1" smil:type="fade" smil:subtype="crossfade"/>
+ <anim:animateTransform smil:dur="0.77" smil:decelerate="1" smil:from="0.1,0.1" smil:to="2,4.5" svg:type="scale"/>
+ <anim:animateTransform smil:begin="0.77" smil:dur="1.23" smil:fill="hold" smil:accelerate="1" smil:from="2,4.5" smil:to="1,1" svg:type="scale"/>
+ <anim:set smil:dur="0.77" smil:fill="hold" smil:attributeName="x" smil:to="(0.5)"/>
+ <anim:animate smil:begin="0.77" smil:dur="1.23" smil:fill="hold" smil:accelerate="1" smil:attributeName="x" smil:from="(0.5)" smil:to="(x)"/>
+ <anim:set smil:dur="0.77" smil:fill="hold" smil:attributeName="y" smil:to="(y+0.4)"/>
+ <anim:animate smil:begin="0.77" smil:dur="1.23" smil:fill="hold" smil:accelerate="1" smil:attributeName="y" smil:from="(y+0.4)" smil:to="(y)"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold" pres:node-type="on-click" pres:preset-class="entrance" pres:preset-id="ooo-entrance-pinwheel">
+ <anim:set smil:begin="0" smil:dur="0.001" smil:fill="hold" smil:attributeName="visibility" smil:to="visible"/>
+ <anim:transitionFilter smil:dur="2" smil:type="fade" smil:subtype="crossfade"/>
+ <anim:animate smil:dur="2" smil:fill="hold" smil:attributeName="rotate" smil:values="720;0" smil:keyTimes="0;1"/>
+ <anim:animate smil:dur="2" smil:fill="hold" smil:attributeName="height" smil:values="0;height" smil:keyTimes="0;1"/>
+ <anim:animate smil:dur="2" smil:fill="hold" smil:attributeName="width" smil:values="0;width" smil:keyTimes="0;1"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold" smil:accelerate="0.5" pres:node-type="on-click" pres:preset-class="entrance" pres:preset-id="ooo-entrance-sling">
+ <anim:set smil:begin="0" smil:dur="0.001" smil:fill="hold" smil:attributeName="visibility" smil:to="visible"/>
+ <anim:animate smil:dur="1" smil:fill="hold" smil:attributeName="rotate" smil:values="90;90;90;0" smil:keyTimes="0;0.8;0.8;1"/>
+ <anim:animate smil:dur="1" smil:fill="hold" smil:attributeName="x" smil:values="-1;0.949999988079071;x" smil:keyTimes="0;0.5;1"/>
+ <anim:animate smil:dur="1" smil:fill="hold" smil:attributeName="y" smil:values="y;y" smil:keyTimes="0;1"/>
+ <anim:transitionFilter smil:dur="1" smil:type="fade" smil:subtype="crossfade"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold" pres:node-type="on-click" pres:preset-class="entrance" pres:preset-id="ooo-entrance-spiral-in">
+ <anim:set smil:begin="0" smil:dur="0.001" smil:fill="hold" smil:attributeName="visibility" smil:to="visible"/>
+ <anim:animate smil:dur="1" smil:fill="hold" smil:attributeName="width" smil:values="0;width" smil:keyTimes="0;1"/>
+ <anim:animate smil:dur="1" smil:fill="hold" smil:attributeName="height" smil:values="0;height" smil:keyTimes="0;1"/>
+ <anim:animate smil:dur="1" smil:fill="hold" smil:attributeName="x" smil:values="0;1" smil:keyTimes="0;1" anim:formula="x+(cos(-2*pi*(1-$))*-x-sin(-2*pi*(1-$))*(1-y))*(1-$)"/>
+ <anim:animate smil:dur="1" smil:fill="hold" smil:attributeName="y" smil:values="0;1" smil:keyTimes="0;1" anim:formula="y+(sin(-2*pi*(1-$))*-x+cos(-2*pi*(1-$))*(1-y))*(1-$)"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:iterate pres:text-only="true" smil:begin="0" smil:fill="hold" smil:accelerate="0.5" pres:node-type="on-click" pres:preset-class="entrance" pres:preset-id="ooo-entrance-falling-in" anim:iterate-type="by-letter" anim:iterate-interval="0.5s">
+ <anim:set smil:begin="0" smil:dur="0.001" smil:fill="hold" smil:attributeName="visibility" smil:to="visible"/>
+ <anim:set smil:begin="0" smil:dur="0.455" smil:fill="hold" smil:attributeName="rotate" smil:to="-45"/>
+ <anim:animate smil:begin="0.455" smil:dur="0.455" smil:fill="hold" smil:attributeName="rotate" smil:values="-45;45;0" smil:keyTimes="0;0.699;1"/>
+ <anim:animate smil:begin="0" smil:dur="0.455" smil:fill="hold" smil:attributeName="y" smil:values="y-1;y-(0.354*width-0.172*height)" smil:keyTimes="0;1"/>
+ <anim:animate smil:begin="0.455" smil:dur="0.156" smil:fill="hold" smil:decelerate="0.5" smil:autoReverse="true" smil:attributeName="y" smil:values="y-(0.354*width-0.172*height);y-(0.354*width-0.172*height)-height/2" smil:keyTimes="0;1"/>
+ <anim:animate smil:begin="0.864" smil:dur="0.136" smil:fill="hold" smil:attributeName="y" smil:values="y-(0.354*width-0.172*height);y" smil:keyTimes="0;1"/>
+ </anim:iterate>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par pres:preset-property="Direction" smil:begin="0" smil:fill="hold" pres:node-type="on-click" pres:preset-class="entrance" pres:preset-id="ooo-entrance-swivel" pres:preset-sub-type="vertical">
+ <anim:set smil:begin="0" smil:dur="0.001" smil:fill="hold" smil:attributeName="visibility" smil:to="visible"/>
+ <anim:animate smil:dur="5" smil:fill="hold" smil:attributeName="width" smil:values="0;1" smil:keyTimes="0;1" anim:formula="width*sin(2.5*pi*$)"/>
+ <anim:animate smil:dur="5" smil:fill="hold" smil:attributeName="height" smil:values="height;height" smil:keyTimes="0;1"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par pres:preset-property="Direction" smil:begin="0" smil:fill="hold" pres:node-type="on-click" pres:preset-class="entrance" pres:preset-id="ooo-entrance-swivel" pres:preset-sub-type="horizontal">
+ <anim:set smil:begin="0" smil:dur="0.001" smil:fill="hold" smil:attributeName="visibility" smil:to="visible"/>
+ <anim:animate smil:dur="5" smil:fill="hold" smil:attributeName="width" smil:values="width;width" smil:keyTimes="0;1"/>
+ <anim:animate smil:dur="5" smil:fill="hold" smil:attributeName="height" smil:values="0;1" smil:keyTimes="0;1" anim:formula="height*sin(2.5*pi*$)"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold" smil:accelerate="1" pres:node-type="on-click" pres:preset-class="entrance" pres:preset-id="ooo-entrance-thread">
+ <anim:set smil:begin="0" smil:dur="0.001" smil:fill="hold" smil:attributeName="visibility" smil:to="visible"/>
+ <anim:animate smil:dur="0.5" smil:fill="hold" smil:attributeName="height" smil:values="height/20;height/20;height" smil:keyTimes="0;0.5;1"/>
+ <anim:animate smil:dur="0.5" smil:fill="hold" smil:attributeName="width" smil:values="width+.3;width+.3;width" smil:keyTimes="0;0.5;1"/>
+ <anim:animate smil:dur="0.5" smil:fill="hold" smil:attributeName="x" smil:values="x-.3;x;x" smil:keyTimes="0;0.5;1"/>
+ <anim:animate smil:dur="0.5" smil:fill="hold" smil:attributeName="y" smil:values="y;y" smil:keyTimes="0;1"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:iterate pres:text-only="true" smil:begin="0" smil:fill="hold" pres:node-type="on-click" pres:preset-class="entrance" pres:preset-id="ooo-entrance-whip" anim:iterate-type="by-letter" anim:iterate-interval="0.05s">
+ <anim:set smil:begin="0" smil:dur="0.001" smil:fill="hold" smil:attributeName="visibility" smil:to="visible"/>
+ <anim:animate smil:dur="0.5" smil:fill="hold" smil:attributeName="x" smil:values="x;x+.1;x" smil:keyTimes="0;0.5;1"/>
+ <anim:animate smil:dur="0.5" smil:fill="hold" smil:attributeName="y" smil:values="y;y" smil:keyTimes="0;1"/>
+ <anim:animate smil:dur="0.5" smil:fill="hold" smil:attributeName="height" smil:values="height/10;height+.01;height" smil:keyTimes="0;0.5;1"/>
+ <anim:animate smil:dur="0.5" smil:fill="hold" smil:attributeName="width" smil:values="width/10;width+.01;width" smil:keyTimes="0;0.5;1"/>
+ <anim:transitionFilter smil:dur="0.5" smil:keySplines="0,0;0.5,1;1,1" smil:type="fade" smil:subtype="crossfade"/>
+ </anim:iterate>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par pres:preset-property="FillColor;ColorStyle;Accelerate;Decelerate;AutoReverse" smil:begin="0" smil:fill="hold" pres:node-type="on-click" pres:preset-class="emphasis" pres:preset-id="ooo-emphasis-fill-color" pres:preset-sub-type="2">
+ <anim:animateColor smil:dur="2" smil:fill="hold" smil:attributeName="fill-color" smil:to="#333399" anim:color-interpolation="rgb" anim:color-interpolation-direction="clockwise"/>
+ <anim:set smil:dur="2" smil:fill="hold" smil:attributeName="fill" smil:to="solid"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par pres:preset-property="FontStyle" pres:text-only="true" smil:begin="0" pres:node-type="on-click" pres:preset-class="emphasis" pres:preset-id="ooo-emphasis-font">
+ <anim:set smil:dur="indefinite" anim:sub-item="text" smil:attributeName="font-family" smil:to="Times New Roman"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par pres:preset-property="CharColor;ColorStyle;Accelerate;Decelerate;AutoReverse" pres:text-only="true" smil:begin="0" smil:fill="hold" pres:node-type="on-click" pres:preset-class="emphasis" pres:preset-id="ooo-emphasis-font-color" pres:preset-sub-type="2">
+ <anim:animateColor smil:dur="2" smil:fill="hold" anim:sub-item="text" smil:attributeName="color" smil:to="#333399" anim:color-interpolation="rgb" anim:color-interpolation-direction="clockwise"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par pres:preset-property="CharHeight" pres:text-only="true" smil:begin="0" smil:fill="hold" pres:node-type="on-click" pres:preset-class="emphasis" pres:preset-id="ooo-emphasis-font-size" pres:preset-sub-type="2">
+ <anim:animate smil:dur="2" smil:fill="hold" anim:sub-item="text" smil:attributeName="font-size" smil:to="1.5pt"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par pres:preset-property="CharDecoration" pres:text-only="true" smil:begin="0" pres:node-type="on-click" pres:preset-class="emphasis" pres:preset-id="ooo-emphasis-font-style" pres:preset-sub-type="1">
+ <anim:set smil:dur="indefinite" anim:sub-item="text" smil:attributeName="font-style" smil:to="normal"/>
+ <anim:set smil:dur="indefinite" anim:sub-item="text" smil:attributeName="font-weight" smil:to="bold"/>
+ <anim:set smil:dur="indefinite" anim:sub-item="text" smil:attributeName="text-underline" smil:to="none"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par pres:preset-property="LineColor;ColorStyle;Accelerate;Decelerate;AutoReverse" smil:begin="0" smil:fill="hold" pres:node-type="on-click" pres:preset-class="emphasis" pres:preset-id="ooo-emphasis-line-color" pres:preset-sub-type="2">
+ <anim:animateColor smil:dur="2" smil:fill="hold" smil:attributeName="stroke-color" smil:to="#333399" anim:color-interpolation="rgb" anim:color-interpolation-direction="clockwise"/>
+ <anim:set smil:dur="2" smil:fill="hold" smil:attributeName="stroke" smil:to="solid"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par pres:preset-property="Scale;Accelerate;Decelerate;AutoReverse" smil:begin="0" smil:fill="hold" pres:node-type="on-click" pres:preset-class="emphasis" pres:preset-id="ooo-emphasis-grow-and-shrink">
+ <anim:animateTransform smil:dur="2" smil:fill="hold" smil:by="1.5,1.5" svg:type="scale"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par pres:preset-property="Rotate;Accelerate;Decelerate;AutoReverse" smil:begin="0" smil:fill="hold" pres:node-type="on-click" pres:preset-class="emphasis" pres:preset-id="ooo-emphasis-spin">
+ <anim:animateTransform smil:dur="2" smil:fill="hold" smil:by="360" svg:type="rotate"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par pres:preset-property="Transparency" smil:begin="0" pres:node-type="on-click" pres:preset-class="emphasis" pres:preset-id="ooo-emphasis-transparency">
+ <anim:set smil:dur="indefinite" smil:attributeName="opacity" smil:to="0.5"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par pres:text-only="true" smil:begin="0" smil:fill="hold" pres:node-type="on-click" pres:preset-class="emphasis" pres:preset-id="ooo-emphasis-bold-flash">
+ <anim:animate smil:dur="2" smil:fill="hold" anim:sub-item="text" smil:attributeName="font-weight" smil:values="normal;bold;normal;normal" smil:keyTimes="0;0.5;0.6;1" smil:calcMode="discrete"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:iterate pres:preset-property="Color" pres:text-only="true" smil:begin="0" smil:fill="hold" pres:node-type="on-click" pres:preset-class="emphasis" pres:preset-id="ooo-emphasis-color-over-by-word" anim:iterate-type="by-letter" anim:iterate-interval="0.2s">
+ <anim:set smil:dur="0.5" smil:fill="hold" smil:attributeName="color" smil:to="#333399"/>
+ <anim:set smil:dur="0.5" smil:fill="hold" smil:attributeName="fill-color" smil:to="#333399"/>
+ <anim:set smil:dur="0.5" smil:fill="hold" smil:attributeName="fill" smil:to="solid"/>
+ </anim:iterate>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:iterate pres:text-only="true" smil:begin="0" smil:fill="hold" pres:node-type="on-click" pres:preset-class="emphasis" pres:preset-id="ooo-emphasis-reveal-underline" anim:iterate-type="by-letter" anim:iterate-interval="0.2s">
+ <anim:set smil:dur="0.5" smil:fill="hold" anim:sub-item="text" smil:attributeName="text-underline" smil:to="solid"/>
+ </anim:iterate>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par pres:preset-property="Color" smil:begin="0" smil:fill="hold" pres:node-type="on-click" pres:preset-class="emphasis" pres:preset-id="ooo-emphasis-color-blend">
+ <anim:animateColor smil:dur="0.5" smil:fill="hold" smil:attributeName="color" smil:to="#333399" anim:color-interpolation="rgb" anim:color-interpolation-direction="clockwise"/>
+ <anim:animateColor smil:dur="0.5" smil:fill="hold" smil:attributeName="fill-color" smil:to="#333399" anim:color-interpolation="rgb" anim:color-interpolation-direction="clockwise"/>
+ <anim:set smil:dur="0.5" smil:fill="hold" smil:attributeName="fill" smil:to="solid"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:iterate pres:preset-property="Color" pres:text-only="true" smil:begin="0" smil:fill="hold" pres:node-type="on-click" pres:preset-class="emphasis" pres:preset-id="ooo-emphasis-color-over-by-letter" anim:iterate-type="by-letter" anim:iterate-interval="0.05s">
+ <anim:set smil:dur="0.5" smil:fill="hold" smil:autoReverse="true" smil:attributeName="color" smil:to="#333399"/>
+ <anim:set smil:dur="0.5" smil:fill="hold" smil:autoReverse="true" smil:attributeName="fill-color" smil:to="#333399"/>
+ <anim:set smil:dur="0.5" smil:fill="hold" smil:autoReverse="true" smil:attributeName="fill" smil:to="solid"/>
+ </anim:iterate>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold" pres:node-type="on-click" pres:preset-class="emphasis" pres:preset-id="ooo-emphasis-complementary-color">
+ <anim:animateColor smil:dur="0.5" smil:fill="hold" smil:attributeName="color" smil:by="hsl(120,0%,0%)" anim:color-interpolation="hsl" anim:color-interpolation-direction="clockwise"/>
+ <anim:animateColor smil:dur="0.5" smil:fill="hold" smil:attributeName="fill-color" smil:by="hsl(120,0%,0%)" anim:color-interpolation="hsl" anim:color-interpolation-direction="clockwise"/>
+ <anim:animateColor smil:dur="0.5" smil:fill="hold" smil:attributeName="stroke-color" smil:by="hsl(120,0%,0%)" anim:color-interpolation="hsl" anim:color-interpolation-direction="clockwise"/>
+ <anim:set smil:dur="0.5" smil:fill="hold" smil:attributeName="fill" smil:to="solid"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold" pres:node-type="on-click" pres:preset-class="emphasis" pres:preset-id="ooo-emphasis-complementary-color-2">
+ <anim:animateColor smil:dur="0.5" smil:fill="hold" smil:attributeName="color" smil:by="hsl(-120,0%,0%)" anim:color-interpolation="hsl" anim:color-interpolation-direction="clockwise"/>
+ <anim:animateColor smil:dur="0.5" smil:fill="hold" smil:attributeName="fill-color" smil:by="hsl(-120,0%,0%)" anim:color-interpolation="hsl" anim:color-interpolation-direction="clockwise"/>
+ <anim:animateColor smil:dur="0.5" smil:fill="hold" smil:attributeName="stroke-color" smil:by="hsl(-120,0%,0%)" anim:color-interpolation="hsl" anim:color-interpolation-direction="clockwise"/>
+ <anim:set smil:dur="0.5" smil:fill="hold" smil:attributeName="fill" smil:to="solid"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold" pres:node-type="on-click" pres:preset-class="emphasis" pres:preset-id="ooo-emphasis-contrasting-color">
+ <anim:animateColor smil:dur="0.5" smil:fill="hold" smil:attributeName="color" smil:by="hsl(180,0%,0%)" anim:color-interpolation="hsl" anim:color-interpolation-direction="clockwise"/>
+ <anim:animateColor smil:dur="0.5" smil:fill="hold" smil:attributeName="fill-color" smil:by="hsl(180,0%,0%)" anim:color-interpolation="hsl" anim:color-interpolation-direction="clockwise"/>
+ <anim:animateColor smil:dur="0.5" smil:fill="hold" smil:attributeName="stroke-color" smil:by="hsl(180,0%,0%)" anim:color-interpolation="hsl" anim:color-interpolation-direction="clockwise"/>
+ <anim:set smil:dur="0.5" smil:fill="hold" smil:attributeName="fill" smil:to="solid"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold" pres:node-type="on-click" pres:preset-class="emphasis" pres:preset-id="ooo-emphasis-darken">
+ <anim:animateColor smil:dur="0.5" smil:fill="hold" smil:attributeName="color" smil:by="hsl(0,-12%,-25%)" anim:color-interpolation="hsl" anim:color-interpolation-direction="clockwise"/>
+ <anim:animateColor smil:dur="0.5" smil:fill="hold" smil:attributeName="fill-color" smil:by="hsl(0,-12%,-25%)" anim:color-interpolation="hsl" anim:color-interpolation-direction="clockwise"/>
+ <anim:animateColor smil:dur="0.5" smil:fill="hold" smil:attributeName="stroke-color" smil:by="hsl(0,-12%,-25%)" anim:color-interpolation="hsl" anim:color-interpolation-direction="clockwise"/>
+ <anim:set smil:dur="0.5" smil:fill="hold" smil:attributeName="fill" smil:to="solid"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold" pres:node-type="on-click" pres:preset-class="emphasis" pres:preset-id="ooo-emphasis-desaturate">
+ <anim:animateColor smil:dur="0.5" smil:fill="hold" smil:attributeName="color" smil:by="hsl(0,-70%,0%)" anim:color-interpolation="hsl" anim:color-interpolation-direction="clockwise"/>
+ <anim:animateColor smil:dur="0.5" smil:fill="hold" smil:attributeName="fill-color" smil:by="hsl(0,-70%,0%)" anim:color-interpolation="hsl" anim:color-interpolation-direction="clockwise"/>
+ <anim:animateColor smil:dur="0.5" smil:fill="hold" smil:attributeName="stroke-color" smil:by="hsl(0,-70%,0%)" anim:color-interpolation="hsl" anim:color-interpolation-direction="clockwise"/>
+ <anim:set smil:dur="0.5" smil:fill="hold" smil:attributeName="fill" smil:to="solid"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold" pres:node-type="on-click" pres:preset-class="emphasis" pres:preset-id="ooo-emphasis-flash-bulb">
+ <anim:transitionFilter smil:dur="0.5" smil:keySplines="0,0;0.2,0.5;0.8,0.5;1,0" smil:type="fade" smil:subtype="crossfade" smil:mode="out"/>
+ <anim:animateTransform smil:dur="0.25" smil:fill="hold" smil:autoReverse="true" smil:by="1.05,1.05" svg:type="scale"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold" pres:node-type="on-click" pres:preset-class="emphasis" pres:preset-id="ooo-emphasis-lighten">
+ <anim:animateColor smil:dur="0.5" smil:fill="hold" smil:attributeName="color" smil:by="hsl(0,12%,25%)" anim:color-interpolation="hsl" anim:color-interpolation-direction="clockwise"/>
+ <anim:animateColor smil:dur="0.5" smil:fill="hold" smil:attributeName="fill-color" smil:by="hsl(0,12%,25%)" anim:color-interpolation="hsl" anim:color-interpolation-direction="clockwise"/>
+ <anim:animateColor smil:dur="0.5" smil:fill="hold" smil:attributeName="stroke-color" smil:by="hsl(0,12%,25%)" anim:color-interpolation="hsl" anim:color-interpolation-direction="clockwise"/>
+ <anim:set smil:dur="0.5" smil:fill="hold" smil:attributeName="fill" smil:to="solid"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par pres:preset-property="Color" smil:begin="0" smil:fill="remove" pres:node-type="on-click" pres:preset-class="emphasis" pres:preset-id="ooo-emphasis-vertical-highlight">
+ <anim:animateColor smil:begin="0" smil:dur="1.5" smil:fill="hold" smil:accelerate="0.5" smil:autoReverse="true" smil:attributeName="color" smil:to="#333399" smil:keySplines="0,0;0.33333,1;1,1" anim:color-interpolation="rgb" anim:color-interpolation-direction="clockwise"/>
+ <anim:animateColor smil:begin="0" smil:dur="1.5" smil:fill="hold" smil:accelerate="0.5" smil:autoReverse="true" smil:attributeName="fill-color" smil:to="#333399" smil:keySplines="0,0;0.33333,1;1,1" anim:color-interpolation="rgb" anim:color-interpolation-direction="clockwise"/>
+ <anim:set smil:dur="3" smil:fill="hold" smil:attributeName="fill" smil:to="solid"/>
+ <anim:animateTransform smil:begin="0" smil:dur="1.5" smil:fill="hold" smil:accelerate="0.5" smil:autoReverse="true" smil:from="1,1" smil:to="1,1.4" smil:keySplines="0,0;0.33333,1;1,1" svg:type="scale"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par pres:preset-property="Color" smil:begin="0" smil:fill="hold" pres:node-type="on-click" pres:preset-class="emphasis" pres:preset-id="ooo-emphasis-flicker">
+ <anim:animateColor smil:dur="0.25" smil:fill="hold" smil:autoReverse="true" smil:attributeName="color" smil:to="#ffffff" anim:color-interpolation="rgb" anim:color-interpolation-direction="clockwise"/>
+ <anim:animateColor smil:dur="0.25" smil:fill="hold" smil:autoReverse="true" smil:attributeName="fill-color" smil:to="#ffffff" anim:color-interpolation="rgb" anim:color-interpolation-direction="clockwise"/>
+ <anim:set smil:dur="0.25" smil:fill="hold" smil:autoReverse="true" smil:attributeName="fill" smil:to="solid"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:iterate pres:preset-property="Color" pres:text-only="true" smil:begin="0" smil:fill="hold" pres:node-type="on-click" pres:preset-class="emphasis" pres:preset-id="ooo-emphasis-grow-with-color" anim:iterate-type="by-letter" anim:iterate-interval="0.05s">
+ <anim:animateColor smil:dur="0.5" smil:fill="hold" anim:sub-item="text" smil:attributeName="color" smil:to="#333399" anim:color-interpolation="rgb" anim:color-interpolation-direction="clockwise"/>
+ <anim:animateColor smil:dur="0.5" smil:fill="hold" anim:sub-item="text" smil:attributeName="fill-color" smil:to="#333399" anim:color-interpolation="rgb" anim:color-interpolation-direction="clockwise"/>
+ <anim:set smil:dur="0.5" smil:fill="hold" anim:sub-item="text" smil:attributeName="fill" smil:to="solid"/>
+ <anim:animate smil:dur="0.5" smil:fill="hold" anim:sub-item="text" smil:attributeName="font-size" smil:to="1.5pt"/>
+ </anim:iterate>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:iterate pres:text-only="true" smil:begin="0" smil:fill="hold" pres:node-type="on-click" pres:preset-class="emphasis" pres:preset-id="ooo-emphasis-shimmer" anim:iterate-type="by-letter" anim:iterate-interval="0.025s">
+ <anim:animateTransform smil:begin="0" smil:dur="0.25" smil:fill="hold" smil:autoReverse="true" smil:to="0.8,1" svg:type="scale"/>
+ <anim:animate smil:begin="0" smil:dur="0.25" smil:fill="hold" smil:autoReverse="true" smil:attributeName="x" smil:by="(width*0.10)"/>
+ <anim:animate smil:begin="0" smil:dur="0.25" smil:fill="hold" smil:autoReverse="true" smil:attributeName="y" smil:by="(-width*0.10)"/>
+ <anim:animateTransform smil:begin="0" smil:dur="0.25" smil:fill="hold" smil:autoReverse="true" smil:by="-8" svg:type="rotate"/>
+ </anim:iterate>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par pres:preset-property="Color" smil:begin="0" smil:fill="hold" pres:node-type="on-click" pres:preset-class="emphasis" pres:preset-id="ooo-emphasis-teeter">
+ <anim:animateColor smil:dur="0.1" smil:fill="hold" smil:attributeName="color" smil:to="#333399" anim:color-interpolation="rgb" anim:color-interpolation-direction="clockwise"/>
+ <anim:animateColor smil:dur="0.1" smil:fill="hold" smil:attributeName="fill-color" smil:to="#333399" anim:color-interpolation="rgb" anim:color-interpolation-direction="clockwise"/>
+ <anim:set smil:dur="0.1" smil:fill="hold" smil:attributeName="fill" smil:to="solid"/>
+ <anim:animateTransform smil:begin="0" smil:dur="0.1" smil:fill="hold" smil:by="2" svg:type="rotate"/>
+ <anim:animateTransform smil:begin="0.2" smil:dur="0.2" smil:fill="hold" smil:by="-4" svg:type="rotate"/>
+ <anim:animateTransform smil:begin="0.4" smil:dur="0.2" smil:fill="hold" smil:by="4" svg:type="rotate"/>
+ <anim:animateTransform smil:begin="0.6" smil:dur="0.2" smil:fill="hold" smil:by="-4" svg:type="rotate"/>
+ <anim:animateTransform smil:begin="0.8" smil:dur="0.2" smil:fill="hold" smil:by="2" svg:type="rotate"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par pres:preset-property="Color" smil:begin="0" smil:fill="hold" pres:node-type="on-click" pres:preset-class="emphasis" pres:preset-id="ooo-emphasis-blast">
+ <anim:animateColor smil:begin="0.1" smil:dur="1.9" smil:fill="hold" smil:attributeName="color" smil:to="#333399" anim:color-interpolation="rgb" anim:color-interpolation-direction="clockwise"/>
+ <anim:animateColor smil:begin="0.1" smil:dur="1.9" smil:fill="hold" smil:attributeName="fill-color" smil:to="#333399" anim:color-interpolation="rgb" anim:color-interpolation-direction="clockwise"/>
+ <anim:set smil:begin="0.1" smil:dur="1.9" smil:fill="hold" smil:attributeName="fill" smil:to="solid"/>
+ <anim:animateTransform smil:begin="0" smil:dur="0.2" smil:fill="hold" smil:from="1,1" smil:to="1,0.05" svg:type="scale"/>
+ <anim:animateTransform smil:begin="0.2" smil:dur="0.2" smil:fill="hold" smil:from="1,0.05" smil:to="1.2,1.5" svg:type="scale"/>
+ <anim:animateTransform smil:begin="1.4" smil:dur="0.6" smil:fill="hold" smil:to="1.2,1.5" svg:type="scale"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold" pres:node-type="on-click" pres:preset-class="emphasis" pres:preset-id="ooo-emphasis-blink">
+ <anim:animate smil:dur="1" smil:fill="hold" smil:attributeName="visibility" smil:values="hidden;visible" smil:keyTimes="0;0.5" smil:calcMode="discrete"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:iterate pres:text-only="true" smil:begin="0" pres:node-type="on-click" pres:preset-class="emphasis" pres:preset-id="ooo-emphasis-bold-reveal" anim:iterate-type="by-letter" anim:iterate-interval="0.025s">
+ <anim:set smil:dur="indefinite" anim:sub-item="text" smil:attributeName="font-weight" smil:to="bold"/>
+ </anim:iterate>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par pres:preset-property="Color" pres:text-only="true" smil:begin="0" pres:node-type="on-click" pres:preset-class="emphasis" pres:preset-id="ooo-emphasis-style-emphasis">
+ <anim:set smil:dur="0.5" smil:fill="hold" anim:sub-item="text" smil:attributeName="color" smil:to="#333399"/>
+ <anim:set smil:dur="0.5" smil:fill="hold" anim:sub-item="text" smil:attributeName="font-style" smil:to="italic"/>
+ <anim:set smil:dur="0.5" smil:fill="hold" anim:sub-item="text" smil:attributeName="font-weight" smil:to="bold"/>
+ <anim:set smil:dur="0.5" smil:fill="hold" anim:sub-item="text" smil:attributeName="text-underline" smil:to="solid"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:iterate pres:text-only="true" smil:begin="0" smil:fill="hold" pres:node-type="on-click" pres:preset-class="emphasis" pres:preset-id="ooo-emphasis-wave" anim:iterate-type="by-letter" anim:iterate-interval="0.05s">
+ <anim:animateMotion smil:begin="0" smil:dur="0.25" smil:fill="hold" smil:accelerate="0.5" smil:decelerate="0.5" smil:autoReverse="true" svg:path="M 0.0 0.0 L 0.0 -0.07213"/>
+ <anim:animateTransform smil:begin="0" smil:dur="0.125" smil:fill="hold" smil:by="25" svg:type="rotate"/>
+ <anim:animateTransform smil:begin="0.125" smil:dur="0.125" smil:fill="hold" smil:by="-25" svg:type="rotate"/>
+ <anim:animateTransform smil:begin="0.25" smil:dur="0.125" smil:fill="hold" smil:by="-25" svg:type="rotate"/>
+ <anim:animateTransform smil:begin="0.375" smil:dur="0.125" smil:fill="hold" smil:by="25" svg:type="rotate"/>
+ </anim:iterate>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par pres:preset-property="Direction" smil:begin="0" smil:fill="hold" pres:node-type="on-click" pres:preset-class="exit" pres:preset-id="ooo-exit-venetian-blinds" pres:preset-sub-type="vertical">
+ <anim:transitionFilter smil:dur="0.5" smil:type="blindsWipe" smil:subtype="horizontal" smil:mode="out"/>
+ <anim:set smil:begin="0.499" smil:dur="0.001" smil:fill="hold" smil:attributeName="visibility" smil:to="hidden"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par pres:preset-property="Direction" smil:begin="0" smil:fill="hold" pres:node-type="on-click" pres:preset-class="exit" pres:preset-id="ooo-exit-venetian-blinds" pres:preset-sub-type="horizontal">
+ <anim:transitionFilter smil:dur="0.5" smil:type="blindsWipe" smil:subtype="vertical" smil:mode="out"/>
+ <anim:set smil:begin="0.499" smil:dur="0.001" smil:fill="hold" smil:attributeName="visibility" smil:to="hidden"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par pres:preset-property="Direction" smil:begin="0" smil:fill="hold" pres:node-type="on-click" pres:preset-class="exit" pres:preset-id="ooo-exit-box" pres:preset-sub-type="in">
+ <anim:transitionFilter smil:dur="0.5" smil:type="irisWipe" smil:subtype="rectangle" smil:mode="out" smil:direction="reverse"/>
+ <anim:set smil:begin="0.499" smil:dur="0.001" smil:fill="hold" smil:attributeName="visibility" smil:to="hidden"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par pres:preset-property="Direction" smil:begin="0" smil:fill="hold" pres:node-type="on-click" pres:preset-class="exit" pres:preset-id="ooo-exit-box" pres:preset-sub-type="out">
+ <anim:transitionFilter smil:dur="0.5" smil:type="irisWipe" smil:subtype="rectangle" smil:mode="out"/>
+ <anim:set smil:begin="0.499" smil:dur="0.001" smil:fill="hold" smil:attributeName="visibility" smil:to="hidden"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par pres:preset-property="Direction" smil:begin="0" smil:fill="hold" pres:node-type="on-click" pres:preset-class="exit" pres:preset-id="ooo-exit-checkerboard" pres:preset-sub-type="across">
+ <anim:transitionFilter smil:dur="0.5" smil:type="checkerBoardWipe" smil:subtype="across" smil:mode="out"/>
+ <anim:set smil:begin="0.499" smil:dur="0.001" smil:fill="hold" smil:attributeName="visibility" smil:to="hidden"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par pres:preset-property="Direction" smil:begin="0" smil:fill="hold" pres:node-type="on-click" pres:preset-class="exit" pres:preset-id="ooo-exit-checkerboard" pres:preset-sub-type="downward">
+ <anim:transitionFilter smil:dur="0.5" smil:type="checkerBoardWipe" smil:subtype="down" smil:mode="out"/>
+ <anim:set smil:begin="0.499" smil:dur="0.001" smil:fill="hold" smil:attributeName="visibility" smil:to="hidden"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par pres:preset-property="Direction" smil:begin="0" smil:fill="hold" pres:node-type="on-click" pres:preset-class="exit" pres:preset-id="ooo-exit-circle" pres:preset-sub-type="in">
+ <anim:transitionFilter smil:dur="2" smil:type="ellipseWipe" smil:subtype="horizontal" smil:mode="out" smil:direction="reverse"/>
+ <anim:set smil:begin="1.999" smil:dur="0.001" smil:fill="hold" smil:attributeName="visibility" smil:to="hidden"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par pres:preset-property="Direction" smil:begin="0" smil:fill="hold" pres:node-type="on-click" pres:preset-class="exit" pres:preset-id="ooo-exit-circle" pres:preset-sub-type="out">
+ <anim:transitionFilter smil:dur="2" smil:type="ellipseWipe" smil:subtype="horizontal" smil:mode="out"/>
+ <anim:set smil:begin="1.999" smil:dur="0.001" smil:fill="hold" smil:attributeName="visibility" smil:to="hidden"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par pres:preset-property="Direction" smil:begin="0" smil:fill="hold" pres:node-type="on-click" pres:preset-class="exit" pres:preset-id="ooo-exit-crawl-out" pres:preset-sub-type="from-bottom">
+ <anim:animate smil:dur="5" smil:attributeName="x" smil:values="x;x" smil:keyTimes="0;1"/>
+ <anim:animate smil:dur="5" smil:attributeName="y" smil:values="y;1+height/2" smil:keyTimes="0;1"/>
+ <anim:set smil:begin="4.999" smil:dur="0.001" smil:fill="hold" smil:attributeName="visibility" smil:to="hidden"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par pres:preset-property="Direction" smil:begin="0" smil:fill="hold" pres:node-type="on-click" pres:preset-class="exit" pres:preset-id="ooo-exit-crawl-out" pres:preset-sub-type="from-left">
+ <anim:animate smil:dur="5" smil:attributeName="x" smil:values="x;0-width/2" smil:keyTimes="0;1"/>
+ <anim:animate smil:dur="5" smil:attributeName="y" smil:values="y;y" smil:keyTimes="0;1"/>
+ <anim:set smil:begin="4.999" smil:dur="0.001" smil:fill="hold" smil:attributeName="visibility" smil:to="hidden"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par pres:preset-property="Direction" smil:begin="0" smil:fill="hold" pres:node-type="on-click" pres:preset-class="exit" pres:preset-id="ooo-exit-crawl-out" pres:preset-sub-type="from-right">
+ <anim:animate smil:dur="5" smil:attributeName="x" smil:values="x;1+width/2" smil:keyTimes="0;1"/>
+ <anim:animate smil:dur="5" smil:attributeName="y" smil:values="y;y" smil:keyTimes="0;1"/>
+ <anim:set smil:begin="4.999" smil:dur="0.001" smil:fill="hold" smil:attributeName="visibility" smil:to="hidden"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par pres:preset-property="Direction" smil:begin="0" smil:fill="hold" pres:node-type="on-click" pres:preset-class="exit" pres:preset-id="ooo-exit-crawl-out" pres:preset-sub-type="from-top">
+ <anim:animate smil:dur="5" smil:attributeName="x" smil:values="x;x" smil:keyTimes="0;1"/>
+ <anim:animate smil:dur="5" smil:attributeName="y" smil:values="y;0-height/2" smil:keyTimes="0;1"/>
+ <anim:set smil:begin="4.999" smil:dur="0.001" smil:fill="hold" smil:attributeName="visibility" smil:to="hidden"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par pres:preset-property="Direction" smil:begin="0" smil:fill="hold" pres:node-type="on-click" pres:preset-class="exit" pres:preset-id="ooo-exit-diamond" pres:preset-sub-type="in">
+ <anim:transitionFilter smil:dur="2" smil:type="irisWipe" smil:subtype="diamond" smil:mode="out" smil:direction="reverse"/>
+ <anim:set smil:begin="1.999" smil:dur="0.001" smil:fill="hold" smil:attributeName="visibility" smil:to="hidden"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par pres:preset-property="Direction" smil:begin="0" smil:fill="hold" pres:node-type="on-click" pres:preset-class="exit" pres:preset-id="ooo-exit-diamond" pres:preset-sub-type="out">
+ <anim:transitionFilter smil:dur="2" smil:type="irisWipe" smil:subtype="diamond" smil:mode="out"/>
+ <anim:set smil:begin="1.999" smil:dur="0.001" smil:fill="hold" smil:attributeName="visibility" smil:to="hidden"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold" pres:node-type="on-click" pres:preset-class="exit" pres:preset-id="ooo-exit-disappear">
+ <anim:set smil:begin="0" smil:dur="0.001" smil:fill="hold" smil:attributeName="visibility" smil:to="hidden"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold" pres:node-type="on-click" pres:preset-class="exit" pres:preset-id="ooo-exit-dissolve">
+ <anim:transitionFilter smil:dur="0.5" smil:type="dissolve" smil:mode="out"/>
+ <anim:set smil:begin="0.499" smil:dur="0.001" smil:fill="hold" smil:attributeName="visibility" smil:to="hidden"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold" pres:node-type="on-click" pres:preset-class="exit" pres:preset-id="ooo-exit-flash-once">
+ <anim:animate smil:dur="1" smil:attributeName="visibility" smil:values="hidden;visible" smil:keyTimes="0;0.5" smil:calcMode="discrete"/>
+ <anim:set smil:begin="0.999" smil:dur="0.001" smil:fill="hold" smil:attributeName="visibility" smil:to="hidden"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par pres:preset-property="Direction;Accelerate;Decelerate" smil:begin="0" smil:fill="hold" pres:node-type="on-click" pres:preset-class="exit" pres:preset-id="ooo-exit-fly-out" pres:preset-sub-type="from-bottom">
+ <anim:animate smil:dur="0.5" smil:attributeName="x" smil:values="x;x" smil:keyTimes="0;1"/>
+ <anim:animate smil:dur="0.5" smil:attributeName="y" smil:values="y;1+height/2" smil:keyTimes="0;1"/>
+ <anim:set smil:begin="0.499" smil:dur="0.001" smil:fill="hold" smil:attributeName="visibility" smil:to="hidden"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par pres:preset-property="Direction;Accelerate;Decelerate" smil:begin="0" smil:fill="hold" pres:node-type="on-click" pres:preset-class="exit" pres:preset-id="ooo-exit-fly-out" pres:preset-sub-type="from-left">
+ <anim:animate smil:dur="0.5" smil:attributeName="x" smil:values="x;0-width/2" smil:keyTimes="0;1"/>
+ <anim:animate smil:dur="0.5" smil:attributeName="y" smil:values="y;y" smil:keyTimes="0;1"/>
+ <anim:set smil:begin="0.499" smil:dur="0.001" smil:fill="hold" smil:attributeName="visibility" smil:to="hidden"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par pres:preset-property="Direction;Accelerate;Decelerate" smil:begin="0" smil:fill="hold" pres:node-type="on-click" pres:preset-class="exit" pres:preset-id="ooo-exit-fly-out" pres:preset-sub-type="from-right">
+ <anim:animate smil:dur="0.5" smil:attributeName="x" smil:values="x;1+width/2" smil:keyTimes="0;1"/>
+ <anim:animate smil:dur="0.5" smil:attributeName="y" smil:values="y;y" smil:keyTimes="0;1"/>
+ <anim:set smil:begin="0.499" smil:dur="0.001" smil:fill="hold" smil:attributeName="visibility" smil:to="hidden"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par pres:preset-property="Direction;Accelerate;Decelerate" smil:begin="0" smil:fill="hold" pres:node-type="on-click" pres:preset-class="exit" pres:preset-id="ooo-exit-fly-out" pres:preset-sub-type="from-top">
+ <anim:animate smil:dur="0.5" smil:attributeName="x" smil:values="x;x" smil:keyTimes="0;1"/>
+ <anim:animate smil:dur="0.5" smil:attributeName="y" smil:values="y;0-height/2" smil:keyTimes="0;1"/>
+ <anim:set smil:begin="0.499" smil:dur="0.001" smil:fill="hold" smil:attributeName="visibility" smil:to="hidden"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par pres:preset-property="Direction;Accelerate;Decelerate" smil:begin="0" smil:fill="hold" pres:node-type="on-click" pres:preset-class="exit" pres:preset-id="ooo-exit-fly-out" pres:preset-sub-type="from-bottom-left">
+ <anim:animate smil:dur="0.5" smil:attributeName="x" smil:values="x;0-width/2" smil:keyTimes="0;1"/>
+ <anim:animate smil:dur="0.5" smil:attributeName="y" smil:values="y;1+height/2" smil:keyTimes="0;1"/>
+ <anim:set smil:begin="0.499" smil:dur="0.001" smil:fill="hold" smil:attributeName="visibility" smil:to="hidden"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par pres:preset-property="Direction;Accelerate;Decelerate" smil:begin="0" smil:fill="hold" pres:node-type="on-click" pres:preset-class="exit" pres:preset-id="ooo-exit-fly-out" pres:preset-sub-type="from-bottom-right">
+ <anim:animate smil:dur="0.5" smil:attributeName="x" smil:values="x;1+width/2" smil:keyTimes="0;1"/>
+ <anim:animate smil:dur="0.5" smil:attributeName="y" smil:values="y;1+height/2" smil:keyTimes="0;1"/>
+ <anim:set smil:begin="0.499" smil:dur="0.001" smil:fill="hold" smil:attributeName="visibility" smil:to="hidden"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par pres:preset-property="Direction;Accelerate;Decelerate" smil:begin="0" smil:fill="hold" pres:node-type="on-click" pres:preset-class="exit" pres:preset-id="ooo-exit-fly-out" pres:preset-sub-type="from-top-left">
+ <anim:animate smil:dur="0.5" smil:attributeName="x" smil:values="x;0-width/2" smil:keyTimes="0;1"/>
+ <anim:animate smil:dur="0.5" smil:attributeName="y" smil:values="y;0-height/2" smil:keyTimes="0;1"/>
+ <anim:set smil:begin="0.499" smil:dur="0.001" smil:fill="hold" smil:attributeName="visibility" smil:to="hidden"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par pres:preset-property="Direction;Accelerate;Decelerate" smil:begin="0" smil:fill="hold" pres:node-type="on-click" pres:preset-class="exit" pres:preset-id="ooo-exit-fly-out" pres:preset-sub-type="from-top-right">
+ <anim:animate smil:dur="0.5" smil:attributeName="x" smil:values="x;1+width/2" smil:keyTimes="0;1"/>
+ <anim:animate smil:dur="0.5" smil:attributeName="y" smil:values="y;0-height/2" smil:keyTimes="0;1"/>
+ <anim:set smil:begin="0.499" smil:dur="0.001" smil:fill="hold" smil:attributeName="visibility" smil:to="hidden"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par pres:preset-property="Direction" smil:begin="0" smil:fill="hold" pres:node-type="on-click" pres:preset-class="exit" pres:preset-id="ooo-exit-peek-out" pres:preset-sub-type="from-bottom">
+ <anim:transitionFilter smil:dur="0.5" smil:type="slideWipe" smil:subtype="fromBottom" smil:mode="out"/>
+ <anim:set smil:begin="0.499" smil:dur="0.001" smil:fill="hold" smil:attributeName="visibility" smil:to="hidden"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par pres:preset-property="Direction" smil:begin="0" smil:fill="hold" pres:node-type="on-click" pres:preset-class="exit" pres:preset-id="ooo-exit-peek-out" pres:preset-sub-type="from-left">
+ <anim:transitionFilter smil:dur="0.5" smil:type="slideWipe" smil:subtype="fromLeft" smil:mode="out"/>
+ <anim:set smil:begin="0.499" smil:dur="0.001" smil:fill="hold" smil:attributeName="visibility" smil:to="hidden"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par pres:preset-property="Direction" smil:begin="0" smil:fill="hold" pres:node-type="on-click" pres:preset-class="exit" pres:preset-id="ooo-exit-peek-out" pres:preset-sub-type="from-right">
+ <anim:transitionFilter smil:dur="0.5" smil:type="slideWipe" smil:subtype="fromRight" smil:mode="out"/>
+ <anim:set smil:begin="0.499" smil:dur="0.001" smil:fill="hold" smil:attributeName="visibility" smil:to="hidden"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par pres:preset-property="Direction" smil:begin="0" smil:fill="hold" pres:node-type="on-click" pres:preset-class="exit" pres:preset-id="ooo-exit-peek-out" pres:preset-sub-type="from-top">
+ <anim:transitionFilter smil:dur="0.5" smil:type="slideWipe" smil:subtype="fromTop" smil:mode="out"/>
+ <anim:set smil:begin="0.499" smil:dur="0.001" smil:fill="hold" smil:attributeName="visibility" smil:to="hidden"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par pres:preset-property="Direction" smil:begin="0" smil:fill="hold" pres:node-type="on-click" pres:preset-class="exit" pres:preset-id="ooo-exit-plus" pres:preset-sub-type="in">
+ <anim:transitionFilter smil:dur="2" smil:type="fourBoxWipe" smil:subtype="cornersIn" smil:mode="out"/>
+ <anim:set smil:begin="1.999" smil:dur="0.001" smil:fill="hold" smil:attributeName="visibility" smil:to="hidden"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par pres:preset-property="Direction" smil:begin="0" smil:fill="hold" pres:node-type="on-click" pres:preset-class="exit" pres:preset-id="ooo-exit-plus" pres:preset-sub-type="out">
+ <anim:transitionFilter smil:dur="2" smil:type="fourBoxWipe" smil:subtype="cornersIn" smil:mode="out" smil:direction="reverse"/>
+ <anim:set smil:begin="1.999" smil:dur="0.001" smil:fill="hold" smil:attributeName="visibility" smil:to="hidden"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par pres:preset-property="Direction" smil:begin="0" smil:fill="hold" pres:node-type="on-click" pres:preset-class="exit" pres:preset-id="ooo-exit-random-bars" pres:preset-sub-type="vertical">
+ <anim:transitionFilter smil:dur="0.5" smil:type="randomBarWipe" smil:subtype="horizontal" smil:mode="out"/>
+ <anim:set smil:begin="0.499" smil:dur="0.001" smil:fill="hold" smil:attributeName="visibility" smil:to="hidden"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par pres:preset-property="Direction" smil:begin="0" smil:fill="hold" pres:node-type="on-click" pres:preset-class="exit" pres:preset-id="ooo-exit-random-bars" pres:preset-sub-type="horizontal">
+ <anim:transitionFilter smil:dur="0.5" smil:type="randomBarWipe" smil:subtype="vertical" smil:mode="out"/>
+ <anim:set smil:begin="0.499" smil:dur="0.001" smil:fill="hold" smil:attributeName="visibility" smil:to="hidden"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold" pres:node-type="on-click" pres:preset-class="exit" pres:preset-id="ooo-exit-random"/>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par pres:preset-property="Direction" smil:begin="0" smil:fill="hold" pres:node-type="on-click" pres:preset-class="exit" pres:preset-id="ooo-exit-split" pres:preset-sub-type="horizontal-in">
+ <anim:transitionFilter smil:dur="0.5" smil:type="barnDoorWipe" smil:subtype="horizontal" smil:mode="out" smil:direction="reverse"/>
+ <anim:set smil:begin="0.499" smil:dur="0.001" smil:fill="hold" smil:attributeName="visibility" smil:to="hidden"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par pres:preset-property="Direction" smil:begin="0" smil:fill="hold" pres:node-type="on-click" pres:preset-class="exit" pres:preset-id="ooo-exit-split" pres:preset-sub-type="horizontal-out">
+ <anim:transitionFilter smil:dur="0.5" smil:type="barnDoorWipe" smil:subtype="horizontal" smil:mode="out"/>
+ <anim:set smil:begin="0.499" smil:dur="0.001" smil:fill="hold" smil:attributeName="visibility" smil:to="hidden"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par pres:preset-property="Direction" smil:begin="0" smil:fill="hold" pres:node-type="on-click" pres:preset-class="exit" pres:preset-id="ooo-exit-split" pres:preset-sub-type="vertical-in">
+ <anim:transitionFilter smil:dur="0.5" smil:type="barnDoorWipe" smil:subtype="vertical" smil:mode="out" smil:direction="reverse"/>
+ <anim:set smil:begin="0.499" smil:dur="0.001" smil:fill="hold" smil:attributeName="visibility" smil:to="hidden"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par pres:preset-property="Direction" smil:begin="0" smil:fill="hold" pres:node-type="on-click" pres:preset-class="exit" pres:preset-id="ooo-exit-split" pres:preset-sub-type="vertical-out">
+ <anim:transitionFilter smil:dur="0.5" smil:type="barnDoorWipe" smil:subtype="vertical" smil:mode="out"/>
+ <anim:set smil:begin="0.499" smil:dur="0.001" smil:fill="hold" smil:attributeName="visibility" smil:to="hidden"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par pres:preset-property="Direction" smil:begin="0" smil:fill="hold" pres:node-type="on-click" pres:preset-class="exit" pres:preset-id="ooo-exit-diagonal-squares" pres:preset-sub-type="left-to-bottom">
+ <anim:transitionFilter smil:dur="0.5" smil:type="waterfallWipe" smil:subtype="horizontalRight" smil:mode="out"/>
+ <anim:set smil:begin="0.499" smil:dur="0.001" smil:fill="hold" smil:attributeName="visibility" smil:to="hidden"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par pres:preset-property="Direction" smil:begin="0" smil:fill="hold" pres:node-type="on-click" pres:preset-class="exit" pres:preset-id="ooo-exit-diagonal-squares" pres:preset-sub-type="left-to-top">
+ <anim:transitionFilter smil:dur="0.5" smil:type="waterfallWipe" smil:subtype="horizontalRight" smil:mode="out" smil:direction="reverse"/>
+ <anim:set smil:begin="0.499" smil:dur="0.001" smil:fill="hold" smil:attributeName="visibility" smil:to="hidden"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par pres:preset-property="Direction" smil:begin="0" smil:fill="hold" pres:node-type="on-click" pres:preset-class="exit" pres:preset-id="ooo-exit-diagonal-squares" pres:preset-sub-type="right-to-bottom">
+ <anim:transitionFilter smil:dur="0.5" smil:type="waterfallWipe" smil:subtype="horizontalLeft" smil:mode="out"/>
+ <anim:set smil:begin="0.499" smil:dur="0.001" smil:fill="hold" smil:attributeName="visibility" smil:to="hidden"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par pres:preset-property="Direction" smil:begin="0" smil:fill="hold" pres:node-type="on-click" pres:preset-class="exit" pres:preset-id="ooo-exit-diagonal-squares" pres:preset-sub-type="right-to-top">
+ <anim:transitionFilter smil:dur="0.5" smil:type="waterfallWipe" smil:subtype="horizontalLeft" smil:mode="out" smil:direction="reverse"/>
+ <anim:set smil:begin="0.499" smil:dur="0.001" smil:fill="hold" smil:attributeName="visibility" smil:to="hidden"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold" pres:node-type="on-click" pres:preset-class="exit" pres:preset-id="ooo-exit-wedge">
+ <anim:transitionFilter smil:dur="2" smil:type="fanWipe" smil:subtype="centerTop" smil:mode="out"/>
+ <anim:set smil:begin="1.999" smil:dur="0.001" smil:fill="hold" smil:attributeName="visibility" smil:to="hidden"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par pres:preset-property="Spokes" smil:begin="0" smil:fill="hold" pres:node-type="on-click" pres:preset-class="exit" pres:preset-id="ooo-exit-wheel" pres:preset-sub-type="1">
+ <anim:transitionFilter smil:dur="2" smil:type="pinWheelWipe" smil:subtype="oneBlade" smil:mode="out"/>
+ <anim:set smil:begin="1.999" smil:dur="0.001" smil:fill="hold" smil:attributeName="visibility" smil:to="hidden"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par pres:preset-property="Spokes" smil:begin="0" smil:fill="hold" pres:node-type="on-click" pres:preset-class="exit" pres:preset-id="ooo-exit-wheel" pres:preset-sub-type="2">
+ <anim:transitionFilter smil:dur="2" smil:type="pinWheelWipe" smil:subtype="twoBladeVertical" smil:mode="out"/>
+ <anim:set smil:begin="1.999" smil:dur="0.001" smil:fill="hold" smil:attributeName="visibility" smil:to="hidden"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par pres:preset-property="Spokes" smil:begin="0" smil:fill="hold" pres:node-type="on-click" pres:preset-class="exit" pres:preset-id="ooo-exit-wheel" pres:preset-sub-type="3">
+ <anim:transitionFilter smil:dur="2" smil:type="pinWheelWipe" smil:subtype="threeBlade" smil:mode="out"/>
+ <anim:set smil:begin="1.999" smil:dur="0.001" smil:fill="hold" smil:attributeName="visibility" smil:to="hidden"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par pres:preset-property="Spokes" smil:begin="0" smil:fill="hold" pres:node-type="on-click" pres:preset-class="exit" pres:preset-id="ooo-exit-wheel" pres:preset-sub-type="4">
+ <anim:transitionFilter smil:dur="2" smil:type="pinWheelWipe" smil:subtype="fourBlade" smil:mode="out"/>
+ <anim:set smil:begin="1.999" smil:dur="0.001" smil:fill="hold" smil:attributeName="visibility" smil:to="hidden"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par pres:preset-property="Spokes" smil:begin="0" smil:fill="hold" pres:node-type="on-click" pres:preset-class="exit" pres:preset-id="ooo-exit-wheel" pres:preset-sub-type="8">
+ <anim:transitionFilter smil:dur="2" smil:type="pinWheelWipe" smil:subtype="eightBlade" smil:mode="out"/>
+ <anim:set smil:begin="1.999" smil:dur="0.001" smil:fill="hold" smil:attributeName="visibility" smil:to="hidden"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par pres:preset-property="Direction" smil:begin="0" smil:fill="hold" pres:node-type="on-click" pres:preset-class="exit" pres:preset-id="ooo-exit-wipe" pres:preset-sub-type="from-bottom">
+ <anim:transitionFilter smil:dur="0.5" smil:type="barWipe" smil:subtype="topToBottom" smil:mode="out" smil:direction="reverse"/>
+ <anim:set smil:begin="0.499" smil:dur="0.001" smil:fill="hold" smil:attributeName="visibility" smil:to="hidden"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par pres:preset-property="Direction" smil:begin="0" smil:fill="hold" pres:node-type="on-click" pres:preset-class="exit" pres:preset-id="ooo-exit-wipe" pres:preset-sub-type="from-left">
+ <anim:transitionFilter smil:dur="0.5" smil:type="barWipe" smil:subtype="leftToRight" smil:mode="out"/>
+ <anim:set smil:begin="0.499" smil:dur="0.001" smil:fill="hold" smil:attributeName="visibility" smil:to="hidden"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par pres:preset-property="Direction" smil:begin="0" smil:fill="hold" pres:node-type="on-click" pres:preset-class="exit" pres:preset-id="ooo-exit-wipe" pres:preset-sub-type="from-right">
+ <anim:transitionFilter smil:dur="0.5" smil:type="barWipe" smil:subtype="leftToRight" smil:mode="out" smil:direction="reverse"/>
+ <anim:set smil:begin="0.499" smil:dur="0.001" smil:fill="hold" smil:attributeName="visibility" smil:to="hidden"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par pres:preset-property="Direction" smil:begin="0" smil:fill="hold" pres:node-type="on-click" pres:preset-class="exit" pres:preset-id="ooo-exit-wipe" pres:preset-sub-type="from-top">
+ <anim:transitionFilter smil:dur="0.5" smil:type="barWipe" smil:subtype="topToBottom" smil:mode="out"/>
+ <anim:set smil:begin="0.499" smil:dur="0.001" smil:fill="hold" smil:attributeName="visibility" smil:to="hidden"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold" pres:node-type="on-click" pres:preset-class="exit" pres:preset-id="ooo-exit-contract">
+ <anim:animate smil:dur="1" smil:attributeName="width" smil:values="width;width*0.70" smil:keyTimes="0;1"/>
+ <anim:animate smil:dur="1" smil:attributeName="height" smil:values="height;height" smil:keyTimes="0;1"/>
+ <anim:transitionFilter smil:dur="1" smil:type="fade" smil:subtype="crossfade" smil:mode="out"/>
+ <anim:set smil:begin="0.999" smil:dur="0.001" smil:fill="hold" smil:attributeName="visibility" smil:to="hidden"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold" pres:node-type="on-click" pres:preset-class="exit" pres:preset-id="ooo-exit-fade-out">
+ <anim:transitionFilter smil:dur="2" smil:type="fade" smil:subtype="crossfade" smil:mode="out"/>
+ <anim:set smil:begin="1.999" smil:dur="0.001" smil:fill="hold" smil:attributeName="visibility" smil:to="hidden"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:iterate pres:text-only="true" smil:begin="0" smil:fill="hold" pres:node-type="on-click" pres:preset-class="exit" pres:preset-id="ooo-exit-fade-out-and-swivel" anim:iterate-type="by-letter" anim:iterate-interval="0.2s">
+ <anim:transitionFilter smil:dur="2" smil:type="fade" smil:subtype="crossfade" smil:mode="out"/>
+ <anim:animate smil:dur="2" smil:attributeName="width" smil:values="width;0.92*width;0.71*width;0.38*width;0;-0.38*width;-0.71*width;-0.92*width;-width;-0.92*width;-0.71*width;-0.38*width;0;0.38*width;0.71*width;0.92*width;width;0.92*width;0.71*width;0.38*width;0" smil:keyTimes="0;0.05;0.1;0.15;0.2;0.25;0.3;0.35;0.4;0.45;0.5;0.55;0.6;0.65;0.7;0.75;0.8;0.85;0.9;0.95;1"/>
+ <anim:animate smil:dur="2" smil:attributeName="height" smil:values="height;height" smil:keyTimes="0;1"/>
+ <anim:set smil:begin="1.999" smil:dur="0.001" smil:fill="hold" smil:attributeName="visibility" smil:to="hidden"/>
+ </anim:iterate>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold" pres:node-type="on-click" pres:preset-class="exit" pres:preset-id="ooo-exit-fade-out-and-zoom">
+ <anim:animate smil:dur="0.5" smil:attributeName="width" smil:values="width;0" smil:keyTimes="0;1"/>
+ <anim:animate smil:dur="0.5" smil:attributeName="height" smil:values="height;0" smil:keyTimes="0;1"/>
+ <anim:transitionFilter smil:dur="0.5" smil:type="fade" smil:subtype="crossfade" smil:mode="out"/>
+ <anim:set smil:begin="0.499" smil:dur="0.001" smil:fill="hold" smil:attributeName="visibility" smil:to="hidden"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold" pres:node-type="on-click" pres:preset-class="exit" pres:preset-id="ooo-exit-ascend">
+ <anim:transitionFilter smil:dur="1" smil:type="fade" smil:subtype="crossfade" smil:mode="out"/>
+ <anim:animate smil:dur="1" smil:attributeName="x" smil:values="x;x" smil:keyTimes="0;1"/>
+ <anim:animate smil:dur="1" smil:attributeName="y" smil:values="y;y-.1" smil:keyTimes="0;1"/>
+ <anim:set smil:begin="0.999" smil:dur="0.001" smil:fill="hold" smil:attributeName="visibility" smil:to="hidden"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold" pres:node-type="on-click" pres:preset-class="exit" pres:preset-id="ooo-exit-center-revolve">
+ <anim:animate smil:begin="0" smil:dur="0.6" smil:decelerate="0.5" smil:attributeName="x" smil:values="x;x+0.0242;x+0.0479;x+0.0704;x+0.0911;x+0.1096;x+0.1254;x+0.1381;x+0.1474;x+0.1531;x+0.155;x+0.1531;x+0.1474;x+0.1381;x+0.1254;x+0.1096;x+0.0911;x+0.0704;x+0.0479;x+0.0242;x" smil:keyTimes="0;0.05;0.1;0.15;0.2;0.25;0.3;0.35;0.4;0.45;0.5;0.55;0.6;0.65;0.7;0.75;0.8;0.85;0.9;0.95;1"/>
+ <anim:animate smil:begin="0.6" smil:dur="0.4" smil:attributeName="x" smil:values="x;x" smil:keyTimes="0;1"/>
+ <anim:animate smil:begin="0" smil:dur="0.6" smil:decelerate="0.5" smil:attributeName="y" smil:values="y;y+0.0019;y+0.0076;y+0.0169;y+0.0296;y+0.0454;y+0.0639;y+0.0846;y+0.1071;y+0.1307;y+0.155;y+0.1792;y+0.2029;y+0.2253;y+0.2461;y+0.2646;y+0.2804;y+0.2931;y+0.3024;y+0.308;y+0.31" smil:keyTimes="0;0.05;0.1;0.15;0.2;0.25;0.3;0.35;0.4;0.45;0.5;0.55;0.6;0.65;0.7;0.75;0.8;0.85;0.9;0.95;1"/>
+ <anim:animate smil:begin="0.6" smil:dur="0.4" smil:attributeName="y" smil:values="y;y" smil:keyTimes="0;1"/>
+ <anim:transitionFilter smil:begin="0.9" smil:dur="0.1" smil:type="fade" smil:subtype="crossfade" smil:mode="out"/>
+ <anim:set smil:begin="0.999" smil:dur="0.001" smil:fill="hold" smil:attributeName="visibility" smil:to="hidden"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par pres:preset-property="Direction" smil:begin="0" smil:fill="hold" pres:node-type="on-click" pres:preset-class="exit" pres:preset-id="ooo-exit-collapse" pres:preset-sub-type="across">
+ <anim:animate smil:dur="0.5" smil:attributeName="width" smil:values="width;0" smil:keyTimes="0;1"/>
+ <anim:animate smil:dur="0.5" smil:attributeName="height" smil:values="height;height" smil:keyTimes="0;1"/>
+ <anim:set smil:begin="0.499" smil:dur="0.001" smil:fill="hold" smil:attributeName="visibility" smil:to="hidden"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:iterate pres:preset-property="Color1;Color2" pres:text-only="true" smil:begin="0" smil:fill="hold" pres:node-type="on-click" pres:preset-class="exit" pres:preset-id="ooo-exit-colored-lettering" anim:iterate-type="by-letter" anim:iterate-interval="0.04s">
+ <anim:animate smil:dur="0.08" smil:attributeName="color" smil:values="#009999;#333399" smil:keyTimes="0;0.5" smil:calcMode="discrete"/>
+ <anim:animate smil:dur="0.08" smil:attributeName="fill-color" smil:values="#009999;#333399" smil:keyTimes="0;0.5" smil:calcMode="discrete"/>
+ <anim:set smil:dur="0.08" smil:attributeName="fill" smil:to="solid"/>
+ <anim:set smil:begin="0.079" smil:dur="0.001" smil:fill="hold" smil:attributeName="visibility" smil:to="hidden"/>
+ </anim:iterate>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold" pres:node-type="on-click" pres:preset-class="exit" pres:preset-id="ooo-exit-descend">
+ <anim:transitionFilter smil:dur="1" smil:type="fade" smil:subtype="crossfade" smil:mode="out"/>
+ <anim:animate smil:dur="1" smil:attributeName="x" smil:values="x;x" smil:keyTimes="0;1"/>
+ <anim:animate smil:dur="1" smil:attributeName="y" smil:values="y;y+.1" smil:keyTimes="0;1"/>
+ <anim:set smil:begin="0.999" smil:dur="0.001" smil:fill="hold" smil:attributeName="visibility" smil:to="hidden"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold" pres:node-type="on-click" pres:preset-class="exit" pres:preset-id="ooo-exit-ease-out">
+ <anim:animate smil:dur="1" smil:attributeName="x" smil:values="x;x-.2" smil:keyTimes="0;1"/>
+ <anim:animate smil:dur="1" smil:attributeName="y" smil:values="y;y" smil:keyTimes="0;1"/>
+ <anim:transitionFilter smil:dur="1" smil:type="fade" smil:subtype="crossfade" smil:mode="out"/>
+ <anim:set smil:begin="0.999" smil:dur="0.001" smil:fill="hold" smil:attributeName="visibility" smil:to="hidden"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:iterate pres:text-only="true" smil:begin="0" smil:fill="hold" pres:node-type="on-click" pres:preset-class="exit" pres:preset-id="ooo-exit-turn-and-grow" anim:iterate-type="by-letter" anim:iterate-interval="0.05s">
+ <anim:animate smil:dur="1" smil:attributeName="width" smil:values="width;0" smil:keyTimes="0;1"/>
+ <anim:animate smil:dur="1" smil:attributeName="height" smil:values="height;0" smil:keyTimes="0;1"/>
+ <anim:animate smil:dur="1" smil:attributeName="rotate" smil:values="0;90" smil:keyTimes="0;1"/>
+ <anim:transitionFilter smil:dur="1" smil:type="fade" smil:subtype="crossfade" smil:mode="out"/>
+ <anim:set smil:begin="0.999" smil:dur="0.001" smil:fill="hold" smil:attributeName="visibility" smil:to="hidden"/>
+ </anim:iterate>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold" pres:node-type="on-click" pres:preset-class="exit" pres:preset-id="ooo-exit-sink-down">
+ <anim:transitionFilter smil:dur="1" smil:type="fade" smil:subtype="crossfade" smil:mode="out"/>
+ <anim:animate smil:dur="1" smil:attributeName="x" smil:values="x;x" smil:keyTimes="0;1"/>
+ <anim:animate smil:dur="0.1" smil:decelerate="1" smil:attributeName="y" smil:values="y;y-.03" smil:keyTimes="0;1"/>
+ <anim:animate smil:begin="0.1" smil:dur="0.9" smil:accelerate="1" smil:attributeName="y" smil:values="y;y+1" smil:keyTimes="0;1"/>
+ <anim:set smil:begin="0.999" smil:dur="0.001" smil:fill="hold" smil:attributeName="visibility" smil:to="hidden"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold" smil:accelerate="1" pres:node-type="on-click" pres:preset-class="exit" pres:preset-id="ooo-exit-spin-out">
+ <anim:animate smil:dur="0.5" smil:attributeName="width" smil:values="width;0" smil:keyTimes="0;1"/>
+ <anim:animate smil:dur="0.5" smil:attributeName="height" smil:values="height;0" smil:keyTimes="0;1"/>
+ <anim:animate smil:dur="0.5" smil:attributeName="rotate" smil:values="0;360" smil:keyTimes="0;1"/>
+ <anim:transitionFilter smil:dur="0.5" smil:type="fade" smil:subtype="crossfade" smil:mode="out"/>
+ <anim:set smil:begin="0.499" smil:dur="0.001" smil:fill="hold" smil:attributeName="visibility" smil:to="hidden"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold" smil:accelerate="1" pres:node-type="on-click" pres:preset-class="exit" pres:preset-id="ooo-exit-stretchy">
+ <anim:animate smil:dur="1" smil:attributeName="width" smil:values="width;width+.3" smil:keyTimes="0;1"/>
+ <anim:animate smil:dur="1" smil:attributeName="height" smil:values="height;height" smil:keyTimes="0;1"/>
+ <anim:transitionFilter smil:dur="1" smil:type="fade" smil:subtype="crossfade" smil:mode="out"/>
+ <anim:set smil:begin="0.999" smil:dur="0.001" smil:fill="hold" smil:attributeName="visibility" smil:to="hidden"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:iterate pres:text-only="true" smil:begin="0" smil:fill="hold" pres:node-type="on-click" pres:preset-class="exit" pres:preset-id="ooo-exit-unfold" anim:iterate-type="by-letter" anim:iterate-interval="0.1s">
+ <anim:transitionFilter smil:dur="1" smil:type="fade" smil:subtype="crossfade" smil:mode="out"/>
+ <anim:animate smil:dur="1" smil:attributeName="x" smil:values="x;x-.1" smil:keyTimes="0;1"/>
+ <anim:animate smil:dur="1" smil:attributeName="y" smil:values="y;y" smil:keyTimes="0;1"/>
+ <anim:set smil:begin="0.999" smil:dur="0.001" smil:fill="hold" smil:attributeName="visibility" smil:to="hidden"/>
+ </anim:iterate>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par pres:preset-property="Zoom" smil:begin="0" smil:fill="hold" pres:node-type="on-click" pres:preset-class="exit" pres:preset-id="ooo-exit-zoom" pres:preset-sub-type="out">
+ <anim:animate smil:dur="0.5" smil:attributeName="width" smil:values="width;0" smil:keyTimes="0;1"/>
+ <anim:animate smil:dur="0.5" smil:attributeName="height" smil:values="height;0" smil:keyTimes="0;1"/>
+ <anim:set smil:begin="0.499" smil:dur="0.001" smil:fill="hold" smil:attributeName="visibility" smil:to="hidden"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par pres:preset-property="Zoom" smil:begin="0" smil:fill="hold" pres:node-type="on-click" pres:preset-class="exit" pres:preset-id="ooo-exit-zoom" pres:preset-sub-type="544">
+ <anim:animate smil:dur="0.5" smil:attributeName="width" smil:values="width;0" smil:keyTimes="0;1"/>
+ <anim:animate smil:dur="0.5" smil:attributeName="height" smil:values="height;0" smil:keyTimes="0;1"/>
+ <anim:animate smil:dur="0.5" smil:attributeName="x" smil:values="x;0.5" smil:keyTimes="0;1"/>
+ <anim:animate smil:dur="0.5" smil:attributeName="y" smil:values="y;0.5" smil:keyTimes="0;1"/>
+ <anim:set smil:begin="0.499" smil:dur="0.001" smil:fill="hold" smil:attributeName="visibility" smil:to="hidden"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par pres:preset-property="Zoom" smil:begin="0" smil:fill="hold" pres:node-type="on-click" pres:preset-class="exit" pres:preset-id="ooo-exit-zoom" pres:preset-sub-type="out-slightly">
+ <anim:animate smil:dur="0.5" smil:attributeName="width" smil:values="width;2/3*width" smil:keyTimes="0;1"/>
+ <anim:animate smil:dur="0.5" smil:attributeName="height" smil:values="height;2/3*height" smil:keyTimes="0;1"/>
+ <anim:set smil:begin="0.499" smil:dur="0.001" smil:fill="hold" smil:attributeName="visibility" smil:to="hidden"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par pres:preset-property="Zoom" smil:begin="0" smil:fill="hold" pres:node-type="on-click" pres:preset-class="exit" pres:preset-id="ooo-exit-zoom" pres:preset-sub-type="in">
+ <anim:animate smil:dur="0.5" smil:attributeName="width" smil:values="width;4*width" smil:keyTimes="0;1"/>
+ <anim:animate smil:dur="0.5" smil:attributeName="height" smil:values="height;4*height" smil:keyTimes="0;1"/>
+ <anim:set smil:begin="0.499" smil:dur="0.001" smil:fill="hold" smil:attributeName="visibility" smil:to="hidden"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par pres:preset-property="Zoom" smil:begin="0" smil:fill="hold" pres:node-type="on-click" pres:preset-class="exit" pres:preset-id="ooo-exit-zoom" pres:preset-sub-type="20">
+ <anim:animate smil:dur="0.5" smil:attributeName="width" smil:values="width;(6*min(max(width*height,.3),1)-7.4)/-.7*width" smil:keyTimes="0;1"/>
+ <anim:animate smil:dur="0.5" smil:attributeName="height" smil:values="height;(6*min(max(width*height,.3),1)-7.4)/-.7*height" smil:keyTimes="0;1"/>
+ <anim:animate smil:dur="0.5" smil:attributeName="y" smil:values="y;1+(6*min(max(width*height,.3),1)-7.4)/-.7*height/2" smil:keyTimes="0;1"/>
+ <anim:set smil:begin="0.499" smil:dur="0.001" smil:fill="hold" smil:attributeName="visibility" smil:to="hidden"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par pres:preset-property="Zoom" smil:begin="0" smil:fill="hold" pres:node-type="on-click" pres:preset-class="exit" pres:preset-id="ooo-exit-zoom" pres:preset-sub-type="in-slightly">
+ <anim:animate smil:dur="0.5" smil:attributeName="width" smil:values="width;4/3*width" smil:keyTimes="0;1"/>
+ <anim:animate smil:dur="0.5" smil:attributeName="height" smil:values="height;4/3*height" smil:keyTimes="0;1"/>
+ <anim:set smil:begin="0.499" smil:dur="0.001" smil:fill="hold" smil:attributeName="visibility" smil:to="hidden"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold" pres:node-type="on-click" pres:preset-class="exit" pres:preset-id="ooo-exit-boomerang">
+ <anim:transitionFilter smil:begin="0" smil:dur="1" smil:accelerate="0.5" smil:type="fade" smil:subtype="crossfade" smil:mode="out"/>
+ <anim:animate smil:begin="0" smil:dur="0.5" smil:accelerate="0.5" smil:attributeName="y" smil:values="y;y+.1" smil:keyTimes="0;1"/>
+ <anim:animate smil:begin="0.5" smil:dur="0.5" smil:decelerate="0.5" smil:attributeName="y" smil:values="y;y-.1" smil:keyTimes="0;1"/>
+ <anim:animate smil:begin="0.5" smil:dur="0.5" smil:accelerate="0.5" smil:attributeName="x" smil:values="x;x+.4" smil:keyTimes="0;1"/>
+ <anim:animate smil:dur="1" smil:attributeName="height" smil:values="height;height" smil:keyTimes="0;1"/>
+ <anim:animate smil:begin="0" smil:dur="0.5" smil:accelerate="0.5" smil:attributeName="width" smil:values="width;width*.05" smil:keyTimes="0;1"/>
+ <anim:animate smil:begin="0.5" smil:dur="0.5" smil:decelerate="0.5" smil:attributeName="width" smil:values="width;width/.05" smil:keyTimes="0;1"/>
+ <anim:animate smil:begin="0.5" smil:dur="0.5" smil:accelerate="0.5" smil:attributeName="rotate" smil:values="0;-90" smil:keyTimes="0;1"/>
+ <anim:set smil:begin="0.999" smil:dur="0.001" smil:fill="hold" smil:attributeName="visibility" smil:to="hidden"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold" pres:node-type="on-click" pres:preset-class="exit" pres:preset-id="ooo-exit-boomerang">
+ <anim:transitionFilter smil:begin="0" smil:dur="1" smil:accelerate="0.5" smil:type="fade" smil:subtype="crossfade" smil:mode="out"/>
+ <anim:animate smil:begin="0" smil:dur="0.5" smil:accelerate="0.5" smil:attributeName="y" smil:values="y;y+.1" smil:keyTimes="0;1"/>
+ <anim:animate smil:begin="0.5" smil:dur="0.5" smil:decelerate="0.5" smil:attributeName="y" smil:values="y;y-.1" smil:keyTimes="0;1"/>
+ <anim:animate smil:begin="0.5" smil:dur="0.5" smil:accelerate="0.5" smil:attributeName="x" smil:values="x;x+.4" smil:keyTimes="0;1"/>
+ <anim:animate smil:dur="1" smil:attributeName="height" smil:values="height;height" smil:keyTimes="0;1"/>
+ <anim:animate smil:begin="0" smil:dur="0.5" smil:accelerate="0.5" smil:attributeName="width" smil:values="width;width*.05" smil:keyTimes="0;1"/>
+ <anim:animate smil:begin="0.5" smil:dur="0.5" smil:decelerate="0.5" smil:attributeName="width" smil:values="width;width/.05" smil:keyTimes="0;1"/>
+ <anim:animate smil:begin="0.5" smil:dur="0.5" smil:accelerate="0.5" smil:attributeName="rotate" smil:values="0;-90" smil:keyTimes="0;1"/>
+ <anim:set smil:begin="0.999" smil:dur="0.001" smil:fill="hold" smil:attributeName="visibility" smil:to="hidden"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold" pres:node-type="on-click" pres:preset-class="exit" pres:preset-id="ooo-exit-bounce">
+ <anim:transitionFilter smil:begin="1.82" smil:dur="0.18" smil:accelerate="0.5" smil:type="barWipe" smil:subtype="topToBottom" smil:mode="out"/>
+ <anim:animate smil:begin="0" smil:dur="1.822" smil:attributeName="x" smil:values="x;x+0.25" smil:keyTimes="0;1" smil:keySplines="0,0;0.14,0.31;0.43,0.73;0.71,0.91;1,1"/>
+ <anim:animate smil:begin="1.822" smil:dur="0.178" smil:attributeName="x" smil:values="x;x" smil:keyTimes="0;1"/>
+ <anim:animate smil:begin="0" smil:dur="0.664" smil:attributeName="y" smil:values="y;y+0.026;y+0.052;y+0.078;y+0.103;y+0.151;y+0.196;y+0.236;y+0.270;y+0.297;y+0.317;y+0.329;y+0.333" smil:keyTimes="0;0.05;0.1;0.15;0.2;0.3;0.4;0.5;0.6;0.7;0.8;0.9;1" smil:keySplines="0,0;0.25,0.07;0.5,0.2;0.75,0.467;1,1"/>
+ <anim:animate smil:begin="0.664" smil:dur="0.664" smil:attributeName="y" smil:values="y;y-0.034;y-0.065;y-0.090;y-0.106;y-0.111;y-0.106;y-0.090;y-0.065;y-0.034;y" smil:keyTimes="0;0.1;0.2;0.3;0.4;0.5;0.6;0.7;0.8;0.9;1" smil:keySplines="0,0;0.125,0.2665;0.25,0.4;0.375,0.465;0.5,0.5;0.625,0.535;0.75,0.6;0.875,0.7335;1,1"/>
+ <anim:animate smil:begin="1.324" smil:dur="0.332" smil:attributeName="y" smil:values="y;y-0.011;y-0.022;y-0.030;y-0.035;y-0.037;y-0.035;y-0.030;y-0.022;y-0.011;y" smil:keyTimes="0;0.1;0.2;0.3;0.4;0.5;0.6;0.7;0.8;0.9;1" smil:keySplines="0,0;0.125,0.2665;0.25,0.4;0.375,0.465;0.5,0.5;0.625,0.535;0.75,0.6;0.875,0.7335;1,1"/>
+ <anim:animate smil:begin="1.656" smil:dur="0.164" smil:attributeName="y" smil:values="y;y-0.004;y-0.007;y-0.010;y-0.012;y-0.0123;y-0.012;y-0.010;y-0.007;y-0.004;y" smil:keyTimes="0;0.1;0.2;0.3;0.4;0.5;0.6;0.7;0.8;0.9;1" smil:keySplines="0,0;0.125,0.2665;0.25,0.4;0.375,0.465;0.5,0.5;0.625,0.535;0.75,0.6;0.875,0.7335;1,1"/>
+ <anim:animate smil:begin="1.82" smil:dur="0.18" smil:accelerate="0.5" smil:attributeName="y" smil:values="y;y+height" smil:keyTimes="0;1"/>
+ <anim:animateTransform smil:begin="0.62" smil:dur="0.026" smil:to="1,0.6" svg:type="scale"/>
+ <anim:animateTransform smil:begin="0.646" smil:dur="0.166" smil:decelerate="0.5" smil:to="1,1" svg:type="scale"/>
+ <anim:animateTransform smil:begin="1.312" smil:dur="0.026" smil:to="1,0.8" svg:type="scale"/>
+ <anim:animateTransform smil:begin="1.338" smil:dur="0.166" smil:decelerate="0.5" smil:to="1,1" svg:type="scale"/>
+ <anim:animateTransform smil:begin="1.642" smil:dur="0.026" smil:to="1,0.9" svg:type="scale"/>
+ <anim:animateTransform smil:begin="1.668" smil:dur="0.166" smil:decelerate="0.5" smil:to="1,1" svg:type="scale"/>
+ <anim:animateTransform smil:begin="1.808" smil:dur="0.026" smil:to="1,0.95" svg:type="scale"/>
+ <anim:animateTransform smil:begin="1.834" smil:dur="0.166" smil:decelerate="0.5" smil:to="1,1" svg:type="scale"/>
+ <anim:set smil:begin="1.999" smil:dur="0.001" smil:fill="hold" smil:attributeName="visibility" smil:to="hidden"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold" pres:node-type="on-click" pres:preset-class="exit" pres:preset-id="ooo-exit-movie-credits">
+ <anim:animate smil:dur="15" smil:attributeName="x" smil:values="x;x" smil:keyTimes="0;1"/>
+ <anim:animate smil:dur="15" smil:attributeName="y" smil:values="y-1;y+1" smil:keyTimes="0;1"/>
+ <anim:set smil:begin="14.999" smil:dur="0.001" smil:fill="hold" smil:attributeName="visibility" smil:to="hidden"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold" pres:node-type="on-click" pres:preset-class="exit" pres:preset-id="ooo-exit-curve-down">
+ <anim:animateTransform smil:begin="0" smil:dur="1" smil:accelerate="0.5" smil:from="1,1" smil:to="2.5,2.5" svg:type="scale"/>
+ <anim:animateMotion smil:begin="0" smil:dur="1" smil:accelerate="0.5" svg:path="M 0.0000 0.0000 C 0.03802 0.0 0.1441 0.02341 0.1826 0.0915 C 0.22118 0.15964 0.24705 0.31256 0.2318 0.4083 C 0.21649 0.50394 0.20747 0.57948 0.0908 0.6661 C -0.02552 0.75279 -0.37517 0.88508 -0.4674 0.9289"/>
+ <anim:transitionFilter smil:dur="1" smil:type="fade" smil:subtype="crossfade" smil:mode="out"/>
+ <anim:set smil:begin="0.999" smil:dur="0.001" smil:fill="hold" smil:attributeName="visibility" smil:to="hidden"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:iterate pres:text-only="true" smil:begin="0" smil:fill="hold" pres:node-type="on-click" pres:preset-class="exit" pres:preset-id="ooo-exit-flip" anim:iterate-type="by-letter" anim:iterate-interval="0.1s">
+ <anim:animate smil:begin="0" smil:dur="0.5" smil:autoReverse="true" smil:attributeName="width" smil:from="(width)" smil:to="(-width*2)"/>
+ <anim:animate smil:begin="0" smil:dur="0.5" smil:decelerate="0.5" smil:autoReverse="true" smil:attributeName="x" smil:by="(width*0.50)"/>
+ <anim:animate smil:begin="0" smil:dur="1" smil:attributeName="y" smil:from="(y)" smil:to="(1+height/2)"/>
+ <anim:animateTransform smil:begin="0" smil:dur="1" smil:by="360" svg:type="rotate"/>
+ <anim:set smil:begin="0.999" smil:dur="0.001" smil:fill="hold" smil:attributeName="visibility" smil:to="hidden"/>
+ </anim:iterate>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold" pres:node-type="on-click" pres:preset-class="exit" pres:preset-id="ooo-exit-float">
+ <anim:transitionFilter smil:begin="0.2" smil:dur="0.8" smil:accelerate="1" smil:type="fade" smil:subtype="crossfade" smil:mode="out"/>
+ <anim:animate smil:begin="0.2" smil:dur="0.8" smil:accelerate="1" smil:attributeName="rotate" smil:values="0;-90" smil:keyTimes="0;1"/>
+ <anim:animate smil:dur="0.2" smil:decelerate="1" smil:attributeName="x" smil:values="x;x-0.05" smil:keyTimes="0;1"/>
+ <anim:animate smil:dur="0.2" smil:decelerate="1" smil:attributeName="y" smil:values="y;y+0.1" smil:keyTimes="0;1"/>
+ <anim:animate smil:begin="0.2" smil:dur="0.8" smil:accelerate="1" smil:attributeName="x" smil:values="x;x+0.4+0.05" smil:keyTimes="0;1"/>
+ <anim:animate smil:begin="0.2" smil:dur="0.8" smil:accelerate="1" smil:attributeName="y" smil:values="y;y-0.4-0.1" smil:keyTimes="0;1"/>
+ <anim:set smil:begin="0.999" smil:dur="0.001" smil:fill="hold" smil:attributeName="visibility" smil:to="hidden"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par pres:text-only="true" smil:begin="0" smil:fill="hold" smil:decelerate="1" pres:node-type="on-click" pres:preset-class="exit" pres:preset-id="ooo-exit-fold">
+ <anim:animate smil:dur="0.5" smil:attributeName="width" smil:values="width;width*2.5" smil:keyTimes="0;1"/>
+ <anim:animate smil:dur="0.5" smil:attributeName="height" smil:values="height;height*0.01" smil:keyTimes="0;1"/>
+ <anim:animate smil:dur="0.5" smil:attributeName="x" smil:values="x;x" smil:keyTimes="0;1"/>
+ <anim:animate smil:dur="0.5" smil:attributeName="y" smil:values="y;height+1" smil:keyTimes="0;1"/>
+ <anim:transitionFilter smil:dur="0.5" smil:type="fade" smil:subtype="crossfade" smil:mode="out"/>
+ <anim:set smil:begin="0.499" smil:dur="0.001" smil:fill="hold" smil:attributeName="visibility" smil:to="hidden"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold" smil:decelerate="1" pres:node-type="on-click" pres:preset-class="exit" pres:preset-id="ooo-exit-glide">
+ <anim:animate smil:dur="0.5" smil:attributeName="width" smil:values="width;width*0.05" smil:keyTimes="0;1"/>
+ <anim:animate smil:dur="0.5" smil:attributeName="height" smil:values="height;height" smil:keyTimes="0;1"/>
+ <anim:animate smil:dur="0.5" smil:attributeName="x" smil:values="x;x-.2" smil:keyTimes="0;1"/>
+ <anim:animate smil:dur="0.5" smil:attributeName="y" smil:values="y;y" smil:keyTimes="0;1"/>
+ <anim:transitionFilter smil:dur="0.5" smil:type="fade" smil:subtype="crossfade" smil:mode="out"/>
+ <anim:set smil:begin="0.499" smil:dur="0.001" smil:fill="hold" smil:attributeName="visibility" smil:to="hidden"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold" pres:node-type="on-click" pres:preset-class="exit" pres:preset-id="ooo-exit-breaks">
+ <anim:animate smil:begin="0" smil:dur="1" smil:attributeName="x" smil:from="(x)" smil:to="(x+1)"/>
+ <anim:animate smil:begin="0" smil:dur="0.2" smil:accelerate="0.5" smil:attributeName="skewX" smil:from="0" smil:to="-1"/>
+ <anim:set smil:begin="0.2" smil:dur="0.8" smil:attributeName="skewX" smil:to="-1"/>
+ <anim:set smil:begin="0.999" smil:dur="0.001" smil:fill="hold" smil:attributeName="visibility" smil:to="hidden"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold" pres:node-type="on-click" pres:preset-class="exit" pres:preset-id="ooo-exit-magnify">
+ <anim:transitionFilter smil:begin="1.23" smil:dur="0.77" smil:accelerate="1" smil:type="fade" smil:subtype="crossfade" smil:mode="out"/>
+ <anim:animateTransform smil:begin="1.23" smil:dur="0.77" smil:accelerate="1" smil:from="2,4.5" smil:to="0.1,0.1" svg:type="scale"/>
+ <anim:animateTransform smil:dur="1.23" smil:decelerate="1" smil:from="1,1" smil:to="2,4.5" svg:type="scale"/>
+ <anim:animate smil:dur="1.23" smil:decelerate="1" smil:attributeName="x" smil:from="(x)" smil:to="(0.5)"/>
+ <anim:animate smil:begin="1.23" smil:dur="0.77" smil:attributeName="x" smil:from="(0.5)" smil:to="(0.5)"/>
+ <anim:animate smil:dur="1.23" smil:decelerate="1" smil:attributeName="y" smil:from="(y)" smil:to="(y+0.4)"/>
+ <anim:animate smil:begin="1.23" smil:dur="0.77" smil:attributeName="y" smil:from="(y)" smil:to="(y)"/>
+ <anim:set smil:begin="1.999" smil:dur="0.001" smil:fill="hold" smil:attributeName="visibility" smil:to="hidden"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold" pres:node-type="on-click" pres:preset-class="exit" pres:preset-id="ooo-exit-pinwheel">
+ <anim:transitionFilter smil:dur="2" smil:type="fade" smil:subtype="crossfade" smil:mode="out"/>
+ <anim:animate smil:dur="2" smil:attributeName="rotate" smil:values="0;720" smil:keyTimes="0;1"/>
+ <anim:animate smil:dur="2" smil:attributeName="height" smil:values="height;0" smil:keyTimes="0;1"/>
+ <anim:animate smil:dur="2" smil:attributeName="width" smil:values="width;0" smil:keyTimes="0;1"/>
+ <anim:set smil:begin="1.999" smil:dur="0.001" smil:fill="hold" smil:attributeName="visibility" smil:to="hidden"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold" smil:decelerate="0.5" pres:node-type="on-click" pres:preset-class="exit" pres:preset-id="ooo-exit-sling">
+ <anim:animate smil:dur="1" smil:attributeName="rotate" smil:values="0;90;90;90" smil:keyTimes="0;0.2;0.2;1"/>
+ <anim:animate smil:dur="1" smil:attributeName="x" smil:values="x;0.949999988079071;-1" smil:keyTimes="0;0.5;1"/>
+ <anim:animate smil:dur="1" smil:attributeName="y" smil:values="y;y" smil:keyTimes="0;1"/>
+ <anim:transitionFilter smil:dur="1" smil:type="fade" smil:subtype="crossfade" smil:mode="out"/>
+ <anim:set smil:begin="0.999" smil:dur="0.001" smil:fill="hold" smil:attributeName="visibility" smil:to="hidden"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold" pres:node-type="on-click" pres:preset-class="exit" pres:preset-id="ooo-exit-spiral-out">
+ <anim:animate smil:dur="1" smil:attributeName="width" smil:values="width;0" smil:keyTimes="0;1"/>
+ <anim:animate smil:dur="1" smil:attributeName="height" smil:values="height;0" smil:keyTimes="0;1"/>
+ <anim:animate smil:dur="1" smil:attributeName="x" smil:values="x;x+-0.0500*(x*0.9511+(1-y)*0.3090);x+-0.1000*(x*0.8090+(1-y)*0.5878);x+-0.1500*(x*0.5878+(1-y)*0.8090);x+-0.2000*(x*0.3090+(1-y)*0.9511);x+-0.2500*(x*-0.0000+(1-y)*1.0000);x+-0.3000*(x*-0.3090+(1-y)*0.9511);x+-0.3500*(x*-0.5878+(1-y)*0.8090);x+-0.4000*(x*-0.8090+(1-y)*0.5878);x+-0.4500*(x*-0.9511+(1-y)*0.3090);x+-0.5000*(x*-1.0000+(1-y)*-0.0000);x+-0.5500*(x*-0.9511+(1-y)*-0.3090);x+-0.6000*(x*-0.8090+(1-y)*-0.5878);x+-0.6500*(x*-0.5878+(1-y)*-0.8090);x+-0.7000*(x*-0.3090+(1-y)*-0.9511);x+-0.7500*(x*0.0000+(1-y)*-1.0000);x+-0.8000*(x*0.3090+(1-y)*-0.9511);x+-0.8500*(x*0.5878+(1-y)*-0.8090);x+-0.9000*(x*0.8090+(1-y)*-0.5878);x+-0.9500*(x*0.9511+(1-y)*-0.3090);x+-1.0000*(x*1.0000+(1-y)*0.0000)" smil:keyTimes="0;0.05;0.1;0.15;0.2;0.25;0.3;0.35;0.4;0.45;0.5;0.55;0.6;0.65;0.7;0.75;0.8;0.85;0.9;0.95;1"/>
+ <anim:animate smil:dur="1" smil:attributeName="y" smil:values="y;y+-0.0500*(x*0.3090-(1-y)*0.9511);y+-0.1000*(x*0.5878-(1-y)*0.8090);y+-0.1500*(x*0.8090-(1-y)*0.5878);y+-0.2000*(x*0.9511-(1-y)*0.3090);y+-0.2500*(x*1.0000-(1-y)*-0.0000);y+-0.3000*(x*0.9511-(1-y)*-0.3090);y+-0.3500*(x*0.8090-(1-y)*-0.5878);y+-0.4000*(x*0.5878-(1-y)*-0.8090);y+-0.4500*(x*0.3090-(1-y)*-0.9511);y+-0.5000*(x*-0.0000-(1-y)*-1.0000);y+-0.5500*(x*-0.3090-(1-y)*-0.9511);y+-0.6000*(x*-0.5878-(1-y)*-0.8090);y+-0.6500*(x*-0.8090-(1-y)*-0.5878);y+-0.7000*(x*-0.9511-(1-y)*-0.3090);y+-0.7500*(x*-1.0000-(1-y)*0.0000);y+-0.8000*(x*-0.9511-(1-y)*0.3090);y+-0.8500*(x*-0.8090-(1-y)*0.5878);y+-0.9000*(x*-0.5878-(1-y)*0.8090);y+-0.9500*(x*-0.3090-(1-y)*0.9511);y+-1.0000*(x*0.0000-(1-y)*1.0000)" smil:keyTimes="0;0.05;0.1;0.15;0.2;0.25;0.3;0.35;0.4;0.45;0.5;0.55;0.6;0.65;0.7;0.75;0.8;0.85;0.9;0.95;1"/>
+ <anim:set smil:begin="0.999" smil:dur="0.001" smil:fill="hold" smil:attributeName="visibility" smil:to="hidden"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:iterate pres:text-only="true" smil:begin="0" smil:fill="hold" smil:accelerate="0.5" pres:node-type="on-click" pres:preset-class="exit" pres:preset-id="ooo-exit-swish" anim:iterate-type="by-letter" anim:iterate-interval="0.5s">
+ <anim:animate smil:begin="0" smil:dur="1" smil:attributeName="rotate" smil:values="0;45" smil:keyTimes="0;1"/>
+ <anim:animate smil:begin="0" smil:dur="1" smil:attributeName="y" smil:values="y;y+1" smil:keyTimes="0;1"/>
+ <anim:set smil:begin="0.999" smil:dur="0.001" smil:fill="hold" smil:attributeName="visibility" smil:to="hidden"/>
+ </anim:iterate>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par pres:preset-property="Direction" smil:begin="0" smil:fill="hold" pres:node-type="on-click" pres:preset-class="exit" pres:preset-id="ooo-exit-swivel" pres:preset-sub-type="vertical">
+ <anim:animate smil:dur="5" smil:attributeName="height" smil:values="height;height" smil:keyTimes="0;1"/>
+ <anim:animate smil:dur="5" smil:attributeName="width" smil:values="width;0.92*width;0.71*width;0.38*width;0;-0.38*width;-0.71*width;-0.92*width;-width;-0.92*width;-0.71*width;-0.38*width;0;0.38*width;0.71*width;0.92*width;width;0.92*width;0.71*width;0.38*width;0" smil:keyTimes="0;0.05;0.1;0.15;0.2;0.25;0.3;0.35;0.4;0.45;0.5;0.55;0.6;0.65;0.7;0.75;0.8;0.85;0.9;0.95;1"/>
+ <anim:set smil:begin="4.999" smil:dur="0.001" smil:fill="hold" smil:attributeName="visibility" smil:to="hidden"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold" smil:decelerate="1" pres:node-type="on-click" pres:preset-class="exit" pres:preset-id="ooo-exit-thread">
+ <anim:animate smil:dur="0.5" smil:attributeName="height" smil:values="height;height/20;height/20" smil:keyTimes="0;0.5;1"/>
+ <anim:animate smil:dur="0.5" smil:attributeName="width" smil:values="width;width+.3;width+.3" smil:keyTimes="0;0.5;1"/>
+ <anim:animate smil:dur="0.5" smil:attributeName="x" smil:values="x;x;x-.3" smil:keyTimes="0;0.5;1"/>
+ <anim:animate smil:dur="0.5" smil:attributeName="y" smil:values="y;y" smil:keyTimes="0;1"/>
+ <anim:set smil:begin="0.499" smil:dur="0.001" smil:fill="hold" smil:attributeName="visibility" smil:to="hidden"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:iterate pres:text-only="true" smil:begin="0" smil:fill="hold" pres:node-type="on-click" pres:preset-class="exit" pres:preset-id="ooo-exit-whip" anim:iterate-type="by-letter" anim:iterate-interval="0.05s">
+ <anim:animate smil:dur="0.5" smil:attributeName="x" smil:values="x;x+.1;x" smil:keyTimes="0;0.5;1"/>
+ <anim:animate smil:dur="0.5" smil:attributeName="y" smil:values="y;y" smil:keyTimes="0;1"/>
+ <anim:animate smil:dur="0.5" smil:attributeName="height" smil:values="height;height+.01;height/10" smil:keyTimes="0;0.5;1"/>
+ <anim:animate smil:dur="0.5" smil:attributeName="width" smil:values="width;width+.01;width/10" smil:keyTimes="0;0.5;1"/>
+ <anim:transitionFilter smil:dur="0.5" smil:keySplines="0,0;0.5,0;1,1" smil:type="fade" smil:subtype="crossfade" smil:mode="out"/>
+ <anim:set smil:begin="0.499" smil:dur="0.001" smil:fill="hold" smil:attributeName="visibility" smil:to="hidden"/>
+ </anim:iterate>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold" smil:accelerate="0.5" smil:decelerate="0.5" pres:node-type="on-click" pres:preset-class="motion-path" pres:preset-id="ooo-motionpath-4-point-star">
+ <anim:animateMotion smil:dur="2" smil:fill="hold" svg:path="M 0 0 L 0.091 -0.0453 L 0.125 -0.16655 L 0.158 -0.0453 L 0.249 0 L 0.158 0.0453 L 0.125 0.16655 L 0.091 0.0453 L 0 0 Z"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold" smil:accelerate="0.5" smil:decelerate="0.5" pres:node-type="on-click" pres:preset-class="motion-path" pres:preset-id="ooo-motionpath-5-point-star">
+ <anim:animateMotion smil:dur="2" smil:fill="hold" svg:path="M 0 0 L 0.029 0.12125 L 0.125 0.12125 L 0.048 0.19586 L 0.077 0.31711 L 0 0.2425 L -0.077 0.31711 L -0.048 0.19586 L -0.125 0.12125 L -0.029 0.12125 L 0 0 Z"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold" smil:accelerate="0.5" smil:decelerate="0.5" pres:node-type="on-click" pres:preset-class="motion-path" pres:preset-id="ooo-motionpath-6-point-star">
+ <anim:animateMotion smil:dur="2" smil:fill="hold" svg:path="M 0 0 L 0.036 0.08261 L 0.108 0.08261 L 0.072 0.16655 L 0.108 0.24916 L 0.036 0.24916 L 0 0.3331 L -0.036 0.24916 L -0.108 0.24916 L -0.072 0.16655 L -0.108 0.08261 L -0.036 0.08261 L 0 0 Z"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold" smil:accelerate="0.5" smil:decelerate="0.5" pres:node-type="on-click" pres:preset-class="motion-path" pres:preset-id="ooo-motionpath-8-point-star">
+ <anim:animateMotion smil:dur="2" smil:fill="hold" svg:path="M 0 0 L 0.052 0 L 0.089 -0.0493 L 0.125 0 L 0.177 0 L 0.177 0.06929 L 0.213 0.11858 L 0.177 0.16655 L 0.177 0.23584 L 0.125 0.23584 L 0.089 0.2838 L 0.052 0.23584 L 0 0.23584 L 0 0.16655 L -0.037 0.11858 L 0 0.06929 L 0 0 Z"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold" smil:accelerate="0.5" smil:decelerate="0.5" pres:node-type="on-click" pres:preset-class="motion-path" pres:preset-id="ooo-motionpath-circle">
+ <anim:animateMotion smil:dur="2" smil:fill="hold" svg:path="M 0 0 C 0.069 0 0.125 0.07461 0.125 0.16655 C 0.125 0.25849 0.069 0.3331 0 0.3331 C -0.069 0.3331 -0.125 0.25849 -0.125 0.16655 C -0.125 0.07461 -0.069 0 0 0 Z"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold" smil:accelerate="0.5" smil:decelerate="0.5" pres:node-type="on-click" pres:preset-class="motion-path" pres:preset-id="ooo-motionpath-crescent-moon">
+ <anim:animateMotion smil:dur="2" smil:fill="hold" svg:path="M 0 0 C -0.014 -0.00666 -0.029 -0.01199 -0.044 -0.01199 C -0.114 -0.01199 -0.169 0.06396 -0.169 0.15589 C -0.169 0.2465 -0.114 0.32111 -0.044 0.32111 C -0.029 0.32111 -0.014 0.31711 0 0.31045 C -0.047 0.28647 -0.08 0.22651 -0.08 0.15589 C -0.08 0.08394 -0.047 0.02398 0 0 Z"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold" smil:accelerate="0.5" smil:decelerate="0.5" pres:node-type="on-click" pres:preset-class="motion-path" pres:preset-id="ooo-motionpath-diamond">
+ <anim:animateMotion smil:dur="2" smil:fill="hold" svg:path="M 0 0 L 0.125 -0.11192 L 0.25 0 L 0.125 0.11192 L 0 0 Z"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold" smil:accelerate="0.5" smil:decelerate="0.5" pres:node-type="on-click" pres:preset-class="motion-path" pres:preset-id="ooo-motionpath-equal-triangle">
+ <anim:animateMotion smil:dur="2" smil:fill="hold" svg:path="M 0 0 L 0.125 0.2878 L -0.125 0.2878 L 0 0 Z"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold" smil:accelerate="0.5" smil:decelerate="0.5" pres:node-type="on-click" pres:preset-class="motion-path" pres:preset-id="ooo-motionpath-oval">
+ <anim:animateMotion smil:dur="2" smil:fill="hold" svg:path="M 0 0 C 0.03 -0.05063 0.075 -0.08261 0.125 -0.08261 C 0.175 -0.08261 0.22 -0.05063 0.25 0 C 0.22 0.05063 0.175 0.08261 0.125 0.08261 C 0.075 0.08261 0.03 0.05063 0 0 Z"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold" smil:accelerate="0.5" smil:decelerate="0.5" pres:node-type="on-click" pres:preset-class="motion-path" pres:preset-id="ooo-motionpath-heart">
+ <anim:animateMotion smil:dur="2" smil:fill="hold" svg:path="M 0 0 C 0.012 -0.02398 0.033 -0.05863 0.058 -0.05863 C 0.095 -0.05863 0.125 -0.02265 0.125 0.02265 C 0.125 0.03731 0.122 0.05063 0.116 0.06262 C 0.117 0.06262 0 0.2425 0 0.24383 C 0 0.2425 -0.117 0.06262 -0.116 0.06262 C -0.122 0.05063 -0.125 0.03731 -0.125 0.02265 C -0.125 -0.02265 -0.095 -0.05863 -0.057 -0.05863 C -0.033 -0.05863 -0.012 -0.02398 0 0 Z"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold" smil:accelerate="0.5" smil:decelerate="0.5" pres:node-type="on-click" pres:preset-class="motion-path" pres:preset-id="ooo-motionpath-hexagon">
+ <anim:animateMotion smil:dur="2" smil:fill="hold" svg:path="M 0 0 L 0.125 0 L 0.188 0.14523 L 0.125 0.28913 L 0 0.28913 L -0.063 0.14523 L 0 0 Z"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold" smil:accelerate="0.5" smil:decelerate="0.5" pres:node-type="on-click" pres:preset-class="motion-path" pres:preset-id="ooo-motionpath-octagon">
+ <anim:animateMotion smil:dur="2" smil:fill="hold" svg:path="M 0 0 L 0.073 -0.09727 L 0.177 -0.09727 L 0.25 0 L 0.25 0.13857 L 0.177 0.23584 L 0.073 0.23584 L 0 0.13857 L 0 0 Z"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold" smil:accelerate="0.5" smil:decelerate="0.5" pres:node-type="on-click" pres:preset-class="motion-path" pres:preset-id="ooo-motionpath-parallelogram">
+ <anim:animateMotion smil:dur="2" smil:fill="hold" svg:path="M 0 0 L 0.178 0 L 0.25 0.16122 L 0.072 0.16122 L 0 0 Z"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold" smil:accelerate="0.5" smil:decelerate="0.5" pres:node-type="on-click" pres:preset-class="motion-path" pres:preset-id="ooo-motionpath-pentagon">
+ <anim:animateMotion smil:dur="2" smil:fill="hold" svg:path="M 0 0 L 0.125 0.12125 L 0.077 0.31711 L -0.077 0.31711 L -0.125 0.12125 L 0 0 Z"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold" smil:accelerate="0.5" smil:decelerate="0.5" pres:node-type="on-click" pres:preset-class="motion-path" pres:preset-id="ooo-motionpath-right-triangle">
+ <anim:animateMotion smil:dur="2" smil:fill="hold" svg:path="M 0 0 L 0 -0.19586 L 0.25 0 L 0 0 Z"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold" smil:accelerate="0.5" smil:decelerate="0.5" pres:node-type="on-click" pres:preset-class="motion-path" pres:preset-id="ooo-motionpath-square">
+ <anim:animateMotion smil:dur="2" smil:fill="hold" svg:path="M 0 0 L 0.25 0 L 0.25 0.3331 L 0 0.3331 L 0 0 Z"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold" smil:accelerate="0.5" smil:decelerate="0.5" pres:node-type="on-click" pres:preset-class="motion-path" pres:preset-id="ooo-motionpath-teardrop">
+ <anim:animateMotion smil:dur="2" smil:fill="hold" svg:path="M 0 0 C 0.001 0.0453 0.011 0.08661 0.028 0.11325 C 0.028 0.11459 0.055 0.15056 0.055 0.14923 C 0.07 0.16922 0.079 0.1972 0.079 0.22651 C 0.079 0.28514 0.044 0.33177 0 0.3331 C -0.044 0.33177 -0.079 0.28514 -0.079 0.22651 C -0.079 0.1972 -0.07 0.16922 -0.055 0.14923 C -0.055 0.15056 -0.028 0.11459 -0.028 0.11325 C -0.011 0.08661 -0.001 0.0453 0 0 Z"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold" smil:accelerate="0.5" smil:decelerate="0.5" pres:node-type="on-click" pres:preset-class="motion-path" pres:preset-id="ooo-motionpath-trapezoid">
+ <anim:animateMotion smil:dur="2" smil:fill="hold" svg:path="M 0 0 L 0.167 0 L 0.21 0.22251 L -0.04 0.22251 L 0 0 Z"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold" smil:accelerate="0.5" smil:decelerate="0.5" pres:node-type="on-click" pres:preset-class="motion-path" pres:preset-id="ooo-motionpath-arc-down">
+ <anim:animateMotion smil:dur="2" smil:fill="hold" svg:path="M 0 0 L 0.067 0.0533 C 0.081 0.06529 0.102 0.07195 0.124 0.07195 C 0.149 0.07195 0.169 0.06529 0.183 0.0533 L 0.25 0"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold" smil:accelerate="0.5" smil:decelerate="0.5" pres:node-type="on-click" pres:preset-class="motion-path" pres:preset-id="ooo-motionpath-arc-left">
+ <anim:animateMotion smil:dur="2" smil:fill="hold" svg:path="M 0 0 L -0.04 0.08927 C -0.049 0.10793 -0.054 0.13591 -0.054 0.16522 C -0.054 0.19853 -0.049 0.22518 -0.04 0.24383 L 0 0.3331"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold" smil:accelerate="0.5" smil:decelerate="0.5" pres:node-type="on-click" pres:preset-class="motion-path" pres:preset-id="ooo-motionpath-arc-right">
+ <anim:animateMotion smil:dur="2" smil:fill="hold" svg:path="M 0 0 L 0.04 0.08927 C 0.049 0.10793 0.054 0.13591 0.054 0.16522 C 0.054 0.19853 0.049 0.22518 0.04 0.24383 L 0 0.3331"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold" smil:accelerate="0.5" smil:decelerate="0.5" pres:node-type="on-click" pres:preset-class="motion-path" pres:preset-id="ooo-motionpath-arc-up">
+ <anim:animateMotion smil:dur="2" smil:fill="hold" svg:path="M 0 0 L 0.067 -0.0533 C 0.081 -0.06529 0.102 -0.07195 0.124 -0.07195 C 0.149 -0.07195 0.169 -0.06529 0.183 -0.0533 L 0.25 0"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold" smil:accelerate="0.5" smil:decelerate="0.5" pres:node-type="on-click" pres:preset-class="motion-path" pres:preset-id="ooo-motionpath-bounce-left">
+ <anim:animateMotion smil:dur="2" smil:fill="hold" svg:path="M 0 0 c -0.004 -0.01066 -0.018 -0.02132 -0.023 -0.02132 c -0.031 0 -0.063 0.16655 -0.063 0.3331 c 0 -0.08394 -0.016 -0.16655 -0.031 -0.16655 c -0.016 0 -0.031 0.08394 -0.031 0.16655 c 0 -0.0413 -0.008 -0.08394 -0.016 -0.08394 c -0.008 0 -0.016 0.0413 -0.016 0.08394 c 0 -0.02132 -0.004 -0.0413 -0.008 -0.0413 c -0.004 0 -0.008 0.02132 -0.008 0.0413 c 0 -0.01066 -0.002 -0.02132 -0.004 -0.02132 c -0.001 0 -0.004 0.01066 -0.004 0.02132 c 0 -0.00533 -0.001 -0.01066 -0.002 -0.01066 c 0 -0.00133 -0.002 0.00533 -0.002 0.01066 c 0 -0.00266 0 -0.00533 -0.001 -0.00533 c 0 0.00133 -0.001 0.00266 -0.001 0.00533 c 0 -0.00133 0 -0.00266 0 -0.004 c -0.001 0 -0.001 0.00133 -0.001 0.00266 c -0.001 0 -0.001 -0.00133 -0.001 -0.00266 c -0.001 0 -0.001 0.00133 -0.001 0.00266"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold" smil:accelerate="0.5" smil:decelerate="0.5" pres:node-type="on-click" pres:preset-class="motion-path" pres:preset-id="ooo-motionpath-bounce-right">
+ <anim:animateMotion smil:dur="2" smil:fill="hold" svg:path="M 0 0 c 0.004 -0.01066 0.018 -0.02132 0.023 -0.02132 c 0.031 0 0.063 0.16655 0.063 0.3331 c 0 -0.08394 0.016 -0.16655 0.031 -0.16655 c 0.016 0 0.031 0.08394 0.031 0.16655 c 0 -0.0413 0.008 -0.08394 0.016 -0.08394 c 0.008 0 0.016 0.0413 0.016 0.08394 c 0 -0.02132 0.004 -0.0413 0.008 -0.0413 c 0.004 0 0.008 0.02132 0.008 0.0413 c 0 -0.01066 0.002 -0.02132 0.004 -0.02132 c 0.001 0 0.004 0.01066 0.004 0.02132 c 0 -0.00533 0.001 -0.01066 0.002 -0.01066 c 0 0.00133 0.002 0.00533 0.002 0.01066 c 0 -0.00266 0 -0.00533 0.001 -0.00533 c 0 0.00133 0.001 0.00266 0.001 0.00533 c 0 -0.00133 0 -0.00266 0 -0.004 c 0.001 0 0.001 0.00133 0.001 0.00266 c 0.001 0 0.001 -0.00133 0.001 -0.00266 c 0.001 0 0.001 0.00133 0.001 0.00266"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold" smil:accelerate="0.5" smil:decelerate="0.5" pres:node-type="on-click" pres:preset-class="motion-path" pres:preset-id="ooo-motionpath-curvy-left">
+ <anim:animateMotion smil:dur="2" smil:fill="hold" svg:path="M 0 0 C 0.008 0.01066 0.017 0.02132 0.021 0.03464 C 0.025 0.0493 0.027 0.06662 0.029 0.08394 C 0.031 0.10126 0.029 0.11592 0.027 0.13191 C 0.025 0.14656 0.022 0.16255 0.015 0.17588 C 0.009 0.1892 -0.001 0.19986 -0.012 0.20786 C -0.022 0.21585 -0.034 0.22118 -0.046 0.22384 C -0.058 0.22651 -0.07 0.22651 -0.081 0.22384 C -0.093 0.22118 -0.104 0.21452 -0.113 0.20386 C -0.122 0.19453 -0.13 0.18254 -0.134 0.16788 C -0.139 0.15456 -0.141 0.13591 -0.141 0.12125 C -0.142 0.10659 -0.141 0.08927 -0.136 0.07461 C -0.131 0.06129 -0.122 0.05063 -0.11 0.0453 C -0.098 0.0413 -0.086 0.04663 -0.078 0.05596 C -0.071 0.06529 -0.066 0.07994 -0.065 0.09727 C -0.065 0.11459 -0.066 0.13058 -0.071 0.1439 C -0.076 0.15722 -0.075 0.15989 -0.095 0.17721 C -0.113 0.19586 -0.131 0.19053 -0.142 0.19187 C -0.153 0.19187 -0.162 0.18654 -0.173 0.18121 C -0.185 0.17455 -0.195 0.16255 -0.202 0.15189 C -0.209 0.14124 -0.212 0.12791 -0.216 0.10659 C -0.219 0.08527 -0.219 0.07461 -0.219 0.05863 C -0.219 0.04264 -0.219 0.02665 -0.219 0.01066"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold" smil:accelerate="0.5" smil:decelerate="0.5" pres:node-type="on-click" pres:preset-class="motion-path" pres:preset-id="ooo-motionpath-curvy-right">
+ <anim:animateMotion smil:dur="2" smil:fill="hold" svg:path="M 0 0 C -0.008 0.01066 -0.017 0.02132 -0.021 0.03464 C -0.025 0.0493 -0.027 0.06662 -0.029 0.08394 C -0.031 0.10126 -0.029 0.11592 -0.027 0.13191 C -0.025 0.14656 -0.022 0.16255 -0.015 0.17588 C -0.009 0.1892 0.001 0.19986 0.012 0.20786 C 0.022 0.21585 0.034 0.22118 0.046 0.22384 C 0.058 0.22651 0.07 0.22651 0.081 0.22384 C 0.093 0.22118 0.104 0.21452 0.113 0.20386 C 0.122 0.19453 0.13 0.18254 0.134 0.16788 C 0.139 0.15456 0.141 0.13591 0.141 0.12125 C 0.142 0.10659 0.141 0.08927 0.136 0.07461 C 0.131 0.06129 0.122 0.05063 0.11 0.0453 C 0.098 0.0413 0.086 0.04663 0.078 0.05596 C 0.071 0.06529 0.066 0.07994 0.065 0.09727 C 0.065 0.11459 0.066 0.13058 0.071 0.1439 C 0.076 0.15722 0.075 0.15989 0.095 0.17721 C 0.113 0.19586 0.131 0.19053 0.142 0.19187 C 0.153 0.19187 0.162 0.18654 0.173 0.18121 C 0.185 0.17455 0.195 0.16255 0.202 0.15189 C 0.209 0.14124 0.212 0.12791 0.216 0.10659 C 0.219 0.08527 0.219 0.07461 0.219 0.05863 C 0.219 0.04264 0.219 0.02665 0.219 0.01066"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold" smil:accelerate="0.5" smil:decelerate="0.5" pres:node-type="on-click" pres:preset-class="motion-path" pres:preset-id="ooo-motionpath-decaying-wave">
+ <anim:animateMotion smil:dur="2" smil:fill="hold" svg:path="M 0 0 C 0.002 0.07062 0.007 0.16922 0.025 0.16788 C 0.051 0.16788 0.053 -0.16255 0.084 -0.16389 C 0.112 -0.16389 0.097 0.12525 0.124 0.12391 C 0.152 0.12391 0.137 -0.08527 0.167 -0.08527 C 0.194 -0.08527 0.179 0.05596 0.203 0.05596 C 0.226 0.05596 0.214 -0.05196 0.235 -0.05196 C 0.247 -0.05196 0.248 -0.02265 0.249 0"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold" smil:accelerate="0.5" smil:decelerate="0.5" pres:node-type="on-click" pres:preset-class="motion-path" pres:preset-id="ooo-motionpath-diagonal-down-right">
+ <anim:animateMotion smil:dur="2" smil:fill="hold" svg:path="M 0 0 L 0.25 0.3331"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold" smil:accelerate="0.5" smil:decelerate="0.5" pres:node-type="on-click" pres:preset-class="motion-path" pres:preset-id="ooo-motionpath-diagonal-up-right">
+ <anim:animateMotion smil:dur="2" smil:fill="hold" svg:path="M 0 0 L 0.25 -0.3331"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold" smil:accelerate="0.5" smil:decelerate="0.5" pres:node-type="on-click" pres:preset-class="motion-path" pres:preset-id="ooo-motionpath-down">
+ <anim:animateMotion smil:dur="2" smil:fill="hold" svg:path="M 0 0 L 0 0.3331"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold" smil:accelerate="0.5" smil:decelerate="0.5" pres:node-type="on-click" pres:preset-class="motion-path" pres:preset-id="ooo-motionpath-funnel">
+ <anim:animateMotion smil:dur="2" smil:fill="hold" svg:path="M 0 0 C -0.001 0.03331 0.06 0.06262 0.137 0.06396 C 0.198 0.06662 0.248 0.05063 0.249 0.03065 C 0.249 0.01066 0.2 -0.00799 0.138 -0.00933 C 0.107 -0.00933 0.079 -0.00666 0.059 0 C 0.03 0.00933 0.013 0.02398 0.013 0.0413 C 0.013 0.05063 0.018 0.05996 0.027 0.06795 C 0.048 0.08527 0.089 0.09727 0.136 0.0986 C 0.191 0.10126 0.236 0.08661 0.236 0.06929 C 0.237 0.05063 0.192 0.03464 0.137 0.03198 C 0.109 0.03198 0.084 0.03464 0.065 0.03997 C 0.04 0.0493 0.024 0.06396 0.024 0.07861 C 0.024 0.08661 0.029 0.0946 0.037 0.1026 C 0.056 0.11725 0.092 0.12924 0.135 0.13058 C 0.185 0.13191 0.225 0.11858 0.225 0.1026 C 0.226 0.08661 0.186 0.07195 0.136 0.07062 C 0.111 0.06929 0.088 0.07195 0.071 0.07728 C 0.048 0.08527 0.035 0.09727 0.035 0.11192 C 0.035 0.11858 0.039 0.12658 0.046 0.13324 C 0.063 0.14656 0.096 0.15722 0.134 0.15856 C 0.179 0.15856 0.215 0.1479 0.215 0.13324 C 0.215 0.11858 0.18 0.10526 0.135 0.10393 C 0.113 0.10393 0.092 0.10659 0.077 0.11059 C 0.056 0.11725 0.044 0.12924 0.043 0.14124 C 0.043 0.1479 0.048 0.15456 0.054 0.15989 C 0.069 0.17321 0.099 0.18254 0.133 0.18254 C 0.173 0.18387 0.206 0.17455 0.206 0.16122 C 0.207 0.1479 0.174 0.13591 0.134 0.13457 C 0.114 0.13457 0.095 0.13591 0.082 0.14124 C 0.063 0.14656 0.052 0.15722 0.052 0.16788 C 0.052 0.17455 0.055 0.17988 0.061 0.1852 C 0.075 0.1972 0.101 0.20519 0.132 0.20652 C 0.169 0.20652 0.198 0.19853 0.198 0.18654 C 0.199 0.17455 0.17 0.16389 0.133 0.16255 C 0.115 0.16255 0.099 0.16389 0.087 0.16788 C 0.07 0.17321 0.06 0.18254 0.06 0.1932 C 0.06 0.19853 0.063 0.20253 0.068 0.20786 C 0.08 0.21851 0.104 0.22518 0.132 0.22651 C 0.165 0.22784 0.191 0.21985 0.191 0.20786 C 0.191 0.19853 0.166 0.18787 0.133 0.18787 C 0.116 0.18654 0.101 0.1892 0.09 0.19187 C 0.075 0.1972 0.066 0.20519 0.066 0.21452 C 0.066 0.21985 0.069 0.22384 0.074 0.22784 C 0.085 0.23717 0.107 0.24383 0.131 0.24516 C 0.161 0.2465 0.185 0.2385 0.185 0.22917 C 0.185 0.21851 0.161 0.21052 0.132 0.20919 C 0.118 0.20919 0.104 0.21052 0.094 0.21452 C 0.08 0.21851 0.072 0.22518 0.072 0.2345 C 0.072 0.2385 0.075 0.2425 0.079 0.2465 C 0.089 0.25449 0.108 0.26115 0.131 0.26115 C 0.157 0.26248 0.179 0.25582 0.179 0.2465 C 0.179 0.2385 0.158 0.23051 0.131 0.23051 C 0.119 0.22917 0.106 0.23051 0.097 0.23317 C 0.085 0.2385 0.078 0.24516 0.078 0.25183 C 0.078 0.25582 0.08 0.25982 0.084 0.26248 C 0.093 0.27048 0.11 0.27581 0.131 0.27714 C 0.155 0.27714 0.174 0.27048 0.174 0.26382 C 0.174 0.25582 0.155 0.24783 0.131 0.24783 C 0.119 0.24783 0.108 0.24916 0.101 0.25183 C 0.089 0.25449 0.083 0.26115 0.083 0.26781 C 0.083 0.27048 0.085 0.27448 0.088 0.27714 C 0.096 0.28514 0.112 0.28913 0.13 0.29046 C 0.152 0.29046 0.169 0.28514 0.169 0.27847 C 0.169 0.27048 0.152 0.26515 0.131 0.26382 C 0.12 0.26382 0.11 0.26515 0.103 0.26781 C 0.093 0.27048 0.087 0.27581 0.087 0.28247 C 0.087 0.28514 0.089 0.2878 0.092 0.29046"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold" smil:accelerate="0.5" smil:decelerate="0.5" pres:node-type="on-click" pres:preset-class="motion-path" pres:preset-id="ooo-motionpath-heartbeat">
+ <anim:animateMotion smil:dur="2" smil:fill="hold" svg:path="M 0 0 L 0.017 0 C 0.025 0 0.034 -0.01865 0.042 -0.02132 C 0.048 -0.02132 0.059 -0.004 0.064 -0.004 C 0.071 -0.004 0.078 -0.00933 0.091 -0.00933 L 0.1 -0.21585 L 0.11 0.03331 L 0.122 0 L 0.132 -0.00933 L 0.156 -0.00133 C 0.167 -0.00533 0.176 -0.02265 0.187 -0.02931 C 0.191 -0.03065 0.2 -0.03198 0.206 -0.02931 C 0.212 -0.02665 0.217 -0.00799 0.219 -0.00666 C 0.222 -0.00133 0.229 -0.00666 0.233 -0.004 L 0.239 0 L 0.25 0"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold" smil:accelerate="0.5" smil:decelerate="0.5" pres:node-type="on-click" pres:preset-class="motion-path" pres:preset-id="ooo-motionpath-left">
+ <anim:animateMotion smil:dur="2" smil:fill="hold" svg:path="M 0 0 L -0.25 0"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold" smil:accelerate="0.5" smil:decelerate="0.5" pres:node-type="on-click" pres:preset-class="motion-path" pres:preset-id="ooo-motionpath-right">
+ <anim:animateMotion smil:dur="2" smil:fill="hold" svg:path="M 0 0 L 0.25 0"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold" smil:accelerate="0.5" smil:decelerate="0.5" pres:node-type="on-click" pres:preset-class="motion-path" pres:preset-id="ooo-motionpath-s-curve-1">
+ <anim:animateMotion smil:dur="2" smil:fill="hold" svg:path="M 0 0 C 0 -0.04663 0.028 -0.08261 0.062 -0.08261 C 0.097 -0.08261 0.125 -0.04663 0.125 0 C 0.125 0.04663 0.153 0.08261 0.188 0.08261 C 0.222 0.08261 0.25 0.04663 0.25 0"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold" smil:accelerate="0.5" smil:decelerate="0.5" pres:node-type="on-click" pres:preset-class="motion-path" pres:preset-id="ooo-motionpath-s-curve-2">
+ <anim:animateMotion smil:dur="2" smil:fill="hold" svg:path="M 0 0 C 0 0.04663 0.028 0.08261 0.062 0.08261 C 0.097 0.08261 0.125 0.04663 0.125 0 C 0.125 -0.04663 0.153 -0.08261 0.188 -0.08261 C 0.222 -0.08261 0.25 -0.04663 0.25 0"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold" smil:accelerate="0.5" smil:decelerate="0.5" pres:node-type="on-click" pres:preset-class="motion-path" pres:preset-id="ooo-motionpath-sine-wave">
+ <anim:animateMotion smil:dur="2" smil:fill="hold" svg:path="M 0 0 C 0.003 -0.02532 0.007 -0.0493 0.015 -0.0493 C 0.024 -0.0493 0.027 -0.02532 0.03 0 C 0.034 0.02798 0.037 0.05596 0.047 0.05596 C 0.056 0.05596 0.059 0.02798 0.063 0 C 0.065 -0.02532 0.069 -0.0493 0.078 -0.0493 C 0.086 -0.0493 0.09 -0.02532 0.093 0 C 0.096 0.02798 0.1 0.05596 0.109 0.05596 C 0.118 0.05596 0.125 0 0.125 0 C 0.128 -0.02532 0.131 -0.0493 0.14 -0.0493 C 0.149 -0.0493 0.152 -0.02532 0.155 0 C 0.159 0.02798 0.162 0.05596 0.172 0.05596 C 0.181 0.05596 0.184 0.02798 0.187 0 C 0.191 -0.02532 0.194 -0.0493 0.203 -0.0493 C 0.211 -0.0493 0.215 -0.02532 0.218 0 C 0.221 0.02798 0.225 0.05596 0.234 0.05596 C 0.243 0.05596 0.246 0.02798 0.25 0"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold" smil:accelerate="0.5" smil:decelerate="0.5" pres:node-type="on-click" pres:preset-class="motion-path" pres:preset-id="ooo-motionpath-spiral-left">
+ <anim:animateMotion smil:dur="2" smil:fill="hold" svg:path="M 0 0 C 0.004 -0.08927 -0.046 -0.16655 -0.113 -0.17188 C -0.177 -0.17854 -0.237 -0.11858 -0.241 -0.03198 C -0.246 0.04797 -0.204 0.12258 -0.144 0.12791 C -0.089 0.13191 -0.037 0.08261 -0.033 0.00799 C -0.029 -0.05996 -0.064 -0.12391 -0.115 -0.12924 C -0.162 -0.13324 -0.206 -0.09194 -0.209 -0.02931 C -0.212 0.02665 -0.184 0.08128 -0.142 0.08394 C -0.104 0.08794 -0.068 0.05596 -0.065 0.00533 C -0.063 -0.03997 -0.084 -0.08394 -0.117 -0.08661 C -0.146 -0.08927 -0.175 -0.06529 -0.177 -0.02665 C -0.179 0.00666 -0.164 0.03864 -0.14 0.0413 C -0.12 0.04397 -0.099 0.02931 -0.098 0.00266 C -0.096 -0.01865 -0.104 -0.0413 -0.119 -0.04397 C -0.131 -0.04397 -0.143 -0.03864 -0.145 -0.02398 C -0.146 -0.01466 -0.144 -0.00533 -0.138 -0.00133 C -0.135 0 -0.133 0 -0.13 -0.00133"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold" smil:accelerate="0.5" smil:decelerate="0.5" pres:node-type="on-click" pres:preset-class="motion-path" pres:preset-id="ooo-motionpath-spiral-right">
+ <anim:animateMotion smil:dur="2" smil:fill="hold" svg:path="M 0 0 C -0.004 -0.08927 0.046 -0.16655 0.113 -0.17188 C 0.177 -0.17854 0.237 -0.11858 0.241 -0.03198 C 0.246 0.04797 0.204 0.12258 0.144 0.12791 C 0.089 0.13191 0.037 0.08261 0.033 0.00799 C 0.029 -0.05996 0.064 -0.12391 0.115 -0.12924 C 0.162 -0.13324 0.206 -0.09194 0.209 -0.02931 C 0.212 0.02665 0.184 0.08128 0.142 0.08394 C 0.104 0.08794 0.068 0.05596 0.065 0.00533 C 0.063 -0.03997 0.084 -0.08394 0.117 -0.08661 C 0.146 -0.08927 0.175 -0.06529 0.177 -0.02665 C 0.179 0.00666 0.164 0.03864 0.14 0.0413 C 0.12 0.04397 0.099 0.02931 0.098 0.00266 C 0.096 -0.01865 0.104 -0.0413 0.119 -0.04397 C 0.131 -0.04397 0.143 -0.03864 0.145 -0.02398 C 0.146 -0.01466 0.144 -0.00533 0.138 -0.00133 C 0.135 0 0.133 0 0.13 -0.00133"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold" smil:accelerate="0.5" smil:decelerate="0.5" pres:node-type="on-click" pres:preset-class="motion-path" pres:preset-id="ooo-motionpath-spring">
+ <anim:animateMotion smil:dur="2" smil:fill="hold" svg:path="M 0 0 C -0.066 0.00799 -0.115 0.02798 -0.115 0.04397 C -0.115 0.05863 -0.067 0.06929 -0.003 0.06929 C 0.061 0.06929 0.115 0.05863 0.115 0.04397 C 0.115 0.02798 0.059 0.02398 -0.005 0.03464 C -0.068 0.04663 -0.115 0.06662 -0.115 0.08128 C -0.115 0.09593 -0.066 0.10793 -0.003 0.10793 C 0.061 0.10793 0.115 0.09593 0.115 0.08128 C 0.115 0.06662 0.059 0.06262 -0.004 0.07328 C -0.068 0.08394 -0.115 0.10393 -0.115 0.11858 C -0.115 0.13457 -0.066 0.14656 -0.002 0.14656 C 0.061 0.14656 0.115 0.13457 0.115 0.11858 C 0.115 0.10526 0.059 0.10126 -0.004 0.11059 C -0.067 0.12125 -0.115 0.14257 -0.115 0.15722 C -0.115 0.17188 -0.065 0.18387 -0.002 0.18387 C 0.063 0.18387 0.115 0.17188 0.115 0.15722 C 0.115 0.14257 0.06 0.13857 -0.003 0.14923 C -0.066 0.15989 -0.115 0.17988 -0.115 0.19453 C -0.115 0.21052 -0.065 0.22118 -0.001 0.22118 C 0.063 0.22118 0.115 0.20919 0.115 0.19453 C 0.115 0.17988 0.06 0.17588 -0.003 0.18654 C -0.066 0.1972 -0.115 0.21851 -0.115 0.23184 C -0.115 0.2465 -0.064 0.25849 -0.001 0.25849 C 0.063 0.25849 0.115 0.2465 0.115 0.23184 C 0.115 0.21851 0.061 0.21452 -0.003 0.22384 C -0.066 0.2345 -0.115 0.25582 -0.115 0.27048 C -0.115 0.2838 -0.064 0.29713 0 0.29713 C 0.064 0.29713 0.115 0.28514 0.115 0.27048 C 0.115 0.25582 0.061 0.25183 -0.002 0.26248 C -0.065 0.27314 -0.116 0.29313 -0.115 0.30779 C -0.114 0.32244 -0.064 0.3331 0 0.3331 C 0.064 0.3331 0.115 0.32111 0.115 0.30645 C 0.115 0.29313 0.063 0.28913 0 0.30112"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold" smil:accelerate="0.5" smil:decelerate="0.5" pres:node-type="on-click" pres:preset-class="motion-path" pres:preset-id="ooo-motionpath-stairs-down">
+ <anim:animateMotion smil:dur="2" smil:fill="hold" svg:path="M 0 0 l 0.036 0 l 0 0.04797 l 0.036 0 l 0 0.04797 l 0.036 0 l 0 0.04797 l 0.036 0 l 0 0.04797 l 0.036 0 l 0 0.04797 l 0.036 0 l 0 0.04797 l 0.036 0 l 0 0.04797"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold" smil:accelerate="0.5" smil:decelerate="0.5" pres:node-type="on-click" pres:preset-class="motion-path" pres:preset-id="ooo-motionpath-turn-down">
+ <anim:animateMotion smil:dur="2" smil:fill="hold" svg:path="M 0 0 L 0.125 0 C 0.181 0 0.25 0.09194 0.25 0.16655 L 0.25 0.3331"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold" smil:accelerate="0.5" smil:decelerate="0.5" pres:node-type="on-click" pres:preset-class="motion-path" pres:preset-id="ooo-motionpath-turn-down-right">
+ <anim:animateMotion smil:dur="2" smil:fill="hold" svg:path="M 0 0 L 0 0.16655 C 0 0.24117 0.069 0.3331 0.125 0.3331 L 0.25 0.3331"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold" smil:accelerate="0.5" smil:decelerate="0.5" pres:node-type="on-click" pres:preset-class="motion-path" pres:preset-id="ooo-motionpath-turn-up">
+ <anim:animateMotion smil:dur="2" smil:fill="hold" svg:path="M 0 0 L 0.125 0 C 0.181 0 0.25 -0.09194 0.25 -0.16655 L 0.25 -0.3331"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold" smil:accelerate="0.5" smil:decelerate="0.5" pres:node-type="on-click" pres:preset-class="motion-path" pres:preset-id="ooo-motionpath-turn-up-right">
+ <anim:animateMotion smil:dur="2" smil:fill="hold" svg:path="M 0 0 L 0 -0.16655 C 0 -0.24117 0.069 -0.3331 0.125 -0.3331 L 0.25 -0.3331"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold" smil:accelerate="0.5" smil:decelerate="0.5" pres:node-type="on-click" pres:preset-class="motion-path" pres:preset-id="ooo-motionpath-up">
+ <anim:animateMotion smil:dur="2" smil:fill="hold" svg:path="M 0 0 L 0 -0.3331"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold" smil:accelerate="0.5" smil:decelerate="0.5" pres:node-type="on-click" pres:preset-class="motion-path" pres:preset-id="ooo-motionpath-wave">
+ <anim:animateMotion smil:dur="2" smil:fill="hold" svg:path="M 0 0 C 0.002 0.08394 0.009 0.1439 0.016 0.1439 C 0.023 0.1439 0.029 0.08394 0.031 0 C 0.034 0.08394 0.04 0.1439 0.047 0.1439 C 0.054 0.1439 0.06 0.08394 0.062 0 C 0.065 0.08394 0.071 0.1439 0.078 0.1439 C 0.085 0.1439 0.092 0.08394 0.094 0 C 0.096 0.08394 0.102 0.1439 0.11 0.1439 C 0.116 0.1439 0.123 0.08394 0.125 0 C 0.127 0.08394 0.134 0.1439 0.141 0.1439 C 0.148 0.1439 0.154 0.08394 0.156 0 C 0.159 0.08394 0.165 0.1439 0.172 0.1439 C 0.179 0.1439 0.185 0.08394 0.188 0 C 0.19 0.08394 0.196 0.1439 0.203 0.1439 C 0.21 0.1439 0.217 0.08394 0.219 0 C 0.221 0.08394 0.227 0.1439 0.235 0.1439 C 0.242 0.1439 0.248 0.08394 0.25 0"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold" smil:accelerate="0.5" smil:decelerate="0.5" pres:node-type="on-click" pres:preset-class="motion-path" pres:preset-id="ooo-motionpath-zigzag">
+ <anim:animateMotion smil:dur="2" smil:fill="hold" svg:path="M 0 0 L 0.016 0.13191 L 0.031 0 L 0.047 0.13191 L 0.063 0 L 0.078 0.13191 L 0.094 0 L 0.109 0.13191 L 0.125 0 L 0.141 0.13191 L 0.156 0 L 0.172 0.13191 L 0.187 0 L 0.203 0.13191 L 0.219 0 L 0.234 0.13191 L 0.25 0"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold" smil:accelerate="0.5" smil:decelerate="0.5" pres:node-type="on-click" pres:preset-class="motion-path" pres:preset-id="ooo-motionpath-bean">
+ <anim:animateMotion smil:dur="2" smil:fill="hold" svg:path="M 0 0 C 0.002 -0.004 0.012 -0.0453 0.037 -0.04264 C 0.075 -0.03864 0.09 -0.00933 0.125 -0.03864 C 0.147 -0.05596 0.173 -0.09993 0.192 -0.0986 C 0.235 -0.09727 0.244 -0.05196 0.244 -0.01066 C 0.245 0.04797 0.189 0.09727 0.121 0.1026 C 0.052 0.10659 -0.005 0.04397 0 0 Z"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold" smil:accelerate="0.5" smil:decelerate="0.5" pres:node-type="on-click" pres:preset-class="motion-path" pres:preset-id="ooo-motionpath-buzz-saw">
+ <anim:animateMotion smil:dur="2" smil:fill="hold" svg:path="M 0 0 C -0.022 -0.02265 -0.033 -0.06129 -0.027 -0.09993 C -0.024 -0.11325 -0.02 -0.12658 -0.014 -0.13724 C -0.01 -0.10659 0.004 -0.07861 0.025 -0.06129 C 0.025 -0.0986 0.041 -0.13457 0.068 -0.15056 C 0.077 -0.15722 0.087 -0.15989 0.097 -0.16122 C 0.082 -0.13857 0.074 -0.10659 0.077 -0.07328 C 0.099 -0.09727 0.13 -0.1026 0.157 -0.08527 C 0.166 -0.07994 0.175 -0.07062 0.181 -0.06129 C 0.158 -0.06396 0.134 -0.05196 0.117 -0.02798 C 0.144 -0.01999 0.167 0.00799 0.174 0.04663 C 0.176 0.05996 0.176 0.07328 0.174 0.08661 C 0.161 0.06129 0.139 0.04397 0.115 0.0413 C 0.127 0.07461 0.124 0.11592 0.106 0.14656 C 0.099 0.15722 0.091 0.16655 0.082 0.17188 C 0.089 0.14257 0.085 0.10926 0.072 0.08261 C 0.06 0.11592 0.034 0.13857 0.004 0.13857 C -0.007 0.13857 -0.017 0.13591 -0.026 0.13058 C -0.004 0.11992 0.013 0.0946 0.021 0.06396 C -0.007 0.07195 -0.036 0.05996 -0.055 0.02931 C -0.062 0.01732 -0.066 0.00533 -0.069 -0.00799 C -0.049 0.00933 -0.023 0.01199 0 0 Z"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold" smil:accelerate="0.5" smil:decelerate="0.5" pres:node-type="on-click" pres:preset-class="motion-path" pres:preset-id="ooo-motionpath-curved-square">
+ <anim:animateMotion smil:dur="2" smil:fill="hold" svg:path="M 0 0 C 0 -0.04264 0.026 -0.07728 0.058 -0.07728 L 0.192 -0.07728 C 0.224 -0.07728 0.25 -0.04264 0.25 0 L 0.25 0.17588 C 0.25 0.21851 0.224 0.25449 0.192 0.25449 L 0.058 0.25449 C 0.026 0.25449 0 0.21851 0 0.17588 Z"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold" smil:accelerate="0.5" smil:decelerate="0.5" pres:node-type="on-click" pres:preset-class="motion-path" pres:preset-id="ooo-motionpath-curved-x">
+ <anim:animateMotion smil:dur="2" smil:fill="hold" svg:path="M 0 0 C 0.006 0.00799 0.011 0.01466 0.015 0.02265 C 0.02 0.01466 0.024 0.00799 0.03 0 C 0.065 -0.04663 0.107 -0.06662 0.124 -0.0453 C 0.14 -0.02265 0.125 0.03331 0.09 0.07994 C 0.084 0.08661 0.079 0.09327 0.073 0.09993 C 0.079 0.10526 0.084 0.11192 0.09 0.11992 C 0.125 0.16655 0.14 0.22251 0.124 0.24383 C 0.107 0.26648 0.065 0.2465 0.03 0.19986 C 0.024 0.19187 0.02 0.1852 0.015 0.17721 C 0.011 0.1852 0.006 0.19187 0 0.19986 C -0.035 0.2465 -0.077 0.26648 -0.094 0.24383 C -0.11 0.22251 -0.095 0.16655 -0.06 0.11992 C -0.054 0.11192 -0.049 0.10526 -0.043 0.09993 C -0.049 0.09327 -0.054 0.08661 -0.06 0.07994 C -0.095 0.03331 -0.11 -0.02265 -0.094 -0.0453 C -0.077 -0.06662 -0.035 -0.04663 0 0 Z"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold" smil:accelerate="0.5" smil:decelerate="0.5" pres:node-type="on-click" pres:preset-class="motion-path" pres:preset-id="ooo-motionpath-curvy-star">
+ <anim:animateMotion smil:dur="2" smil:fill="hold" svg:path="M 0 0 C 0.072 0.07728 0.1 0.20253 0.077 0.31711 C -0.015 0.31045 -0.093 0.23051 -0.125 0.12125 C -0.047 0.0533 0.051 0.05729 0.125 0.12125 C 0.092 0.23717 0.011 0.31045 -0.077 0.31711 C -0.101 0.1972 -0.068 0.07461 0 0 Z"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold" smil:accelerate="0.5" smil:decelerate="0.5" pres:node-type="on-click" pres:preset-class="motion-path" pres:preset-id="ooo-motionpath-figure-8-four">
+ <anim:animateMotion smil:dur="2" smil:fill="hold" svg:path="M 0 0 C 0.017 0 0.031 0.01865 0.031 0.0413 C 0.031 0.06529 0.017 0.08394 0 0.08394 C -0.017 0.08394 -0.031 0.1026 -0.031 0.12525 C -0.031 0.1479 -0.017 0.16655 0 0.16655 C 0.017 0.16655 0.031 0.1852 0.031 0.20786 C 0.031 0.23051 0.017 0.24916 0 0.24916 C -0.017 0.24916 -0.031 0.26781 -0.031 0.2918 C -0.031 0.31445 -0.017 0.3331 0 0.3331 C 0.017 0.3331 0.031 0.31445 0.031 0.2918 C 0.031 0.26781 0.017 0.24916 0 0.24916 C -0.017 0.24916 -0.031 0.23051 -0.031 0.20786 C -0.031 0.1852 -0.017 0.16655 0 0.16655 C 0.017 0.16655 0.031 0.1479 0.031 0.12525 C 0.031 0.1026 0.017 0.08394 0 0.08394 C -0.017 0.08394 -0.031 0.06529 -0.031 0.0413 C -0.031 0.01865 -0.017 0 0 0 Z"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold" smil:accelerate="0.5" smil:decelerate="0.5" pres:node-type="on-click" pres:preset-class="motion-path" pres:preset-id="ooo-motionpath-horizontal-figure-8">
+ <anim:animateMotion smil:dur="2" smil:fill="hold" svg:path="M 0 0 C 0 0.04397 0.027 0.07994 0.06 0.07994 C 0.099 0.07994 0.113 0.03997 0.119 0.01599 L 0.125 -0.01599 C 0.131 -0.03997 0.146 -0.07994 0.19 -0.07994 C 0.218 -0.07994 0.25 -0.04397 0.25 0 C 0.25 0.04397 0.218 0.07994 0.19 0.07994 C 0.146 0.07994 0.131 0.03997 0.125 0.01599 L 0.119 -0.01599 C 0.113 -0.03997 0.099 -0.07994 0.06 -0.07994 C 0.027 -0.07994 0 -0.04397 0 0 Z"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold" smil:accelerate="0.5" smil:decelerate="0.5" pres:node-type="on-click" pres:preset-class="motion-path" pres:preset-id="ooo-motionpath-inverted-square">
+ <anim:animateMotion smil:dur="2" smil:fill="hold" svg:path="M 0 0 C 0.004 -0.00533 0.01 -0.00799 0.015 -0.00799 C 0.022 -0.00799 0.029 -0.004 0.033 0.00266 C 0.05 0.02931 0.063 0.08794 0.063 0.15722 C 0.063 0.15722 0.063 0.15856 0.063 0.15856 C 0.063 0.15856 0.063 0.15989 0.063 0.15989 C 0.063 0.22917 0.05 0.28913 0.033 0.31578 C 0.029 0.32111 0.022 0.32511 0.015 0.32511 C 0.01 0.32511 0.004 0.32244 0 0.31711 C -0.004 0.31178 -0.006 0.30512 -0.006 0.29713 C -0.006 0.2878 -0.003 0.27981 0.002 0.27448 C 0.022 0.25049 0.066 0.23317 0.118 0.23317 C 0.118 0.23317 0.119 0.23317 0.119 0.23317 C 0.119 0.23317 0.12 0.23317 0.12 0.23317 C 0.172 0.23317 0.217 0.25049 0.237 0.27448 C 0.241 0.27981 0.244 0.2878 0.244 0.29713 C 0.244 0.30512 0.242 0.31178 0.238 0.31711 C 0.234 0.32244 0.229 0.32511 0.223 0.32511 C 0.216 0.32511 0.21 0.32111 0.206 0.31578 C 0.188 0.28913 0.175 0.22917 0.175 0.15989 C 0.175 0.15989 0.175 0.15856 0.175 0.15856 C 0.175 0.15856 0.175 0.15722 0.175 0.15722 C 0.175 0.08794 0.188 0.02931 0.206 0.00133 C 0.21 -0.004 0.216 -0.00799 0.223 -0.00799 C 0.229 -0.00799 0.234 -0.00533 0.238 0 C 0.242 0.00533 0.244 0.01332 0.244 0.01999 C 0.244 0.02931 0.241 0.03731 0.237 0.04397 C 0.217 0.06662 0.172 0.08394 0.12 0.08394 C 0.12 0.08394 0.12 0.08394 0.119 0.08394 C 0.119 0.08394 0.118 0.08394 0.118 0.08394 C 0.066 0.08394 0.022 0.06662 0.002 0.04397 C -0.003 0.03731 -0.006 0.02931 -0.006 0.01999 C -0.006 0.01332 -0.004 0.00533 0 0 Z"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold" smil:accelerate="0.5" smil:decelerate="0.5" pres:node-type="on-click" pres:preset-class="motion-path" pres:preset-id="ooo-motionpath-inverted-triangle">
+ <anim:animateMotion smil:dur="2" smil:fill="hold" svg:path="M 0 0 C 0.015 0.03198 0.037 0.06529 0.055 0.07861 C 0.082 0.09993 0.108 0.10793 0.113 0.09727 C 0.117 0.08661 0.099 0.05996 0.072 0.03864 C 0.054 0.02532 0.021 0.01599 -0.008 0.01466 C -0.036 0.01599 -0.07 0.02532 -0.088 0.03864 C -0.115 0.05996 -0.133 0.08661 -0.128 0.09727 C -0.123 0.10793 -0.097 0.09993 -0.071 0.07861 C -0.053 0.06529 -0.03 0.03198 -0.016 0 C -0.001 -0.03331 0.009 -0.07728 0.009 -0.10526 C 0.009 -0.1479 0.002 -0.18121 -0.008 -0.18121 C -0.017 -0.18121 -0.025 -0.1479 -0.025 -0.10526 C -0.025 -0.07728 -0.014 -0.03331 0 0 Z"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold" smil:accelerate="0.5" smil:decelerate="0.5" pres:node-type="on-click" pres:preset-class="motion-path" pres:preset-id="ooo-motionpath-loop-de-loop">
+ <anim:animateMotion smil:dur="2" smil:fill="hold" svg:path="M 0 0 C 0.023 0.00133 0.042 0.01199 0.052 0.02798 L 0.075 0.06529 C 0.08 0.07328 0.088 0.07728 0.098 0.07728 C 0.112 0.07728 0.124 0.06662 0.125 0.05063 C 0.124 0.03731 0.112 0.02532 0.098 0.02532 C 0.088 0.02532 0.08 0.03065 0.075 0.03731 L 0.052 0.07461 C 0.042 0.0906 0.023 0.10126 0 0.1026 C -0.023 0.10126 -0.042 0.0906 -0.052 0.07461 L -0.075 0.03731 C -0.08 0.03065 -0.088 0.02532 -0.098 0.02532 C -0.112 0.02532 -0.124 0.03731 -0.125 0.05063 C -0.124 0.06662 -0.112 0.07728 -0.098 0.07728 C -0.088 0.07728 -0.08 0.07328 -0.075 0.06529 L -0.052 0.02798 C -0.042 0.01199 -0.023 0.00133 0 0 Z"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold" smil:accelerate="0.5" smil:decelerate="0.5" pres:node-type="on-click" pres:preset-class="motion-path" pres:preset-id="ooo-motionpath-neutron">
+ <anim:animateMotion smil:dur="2" smil:fill="hold" svg:path="M 0 0 C 0.007 -0.01332 0.014 -0.02798 0.021 -0.04663 C 0.04 -0.09993 0.045 -0.15189 0.031 -0.15989 C 0.017 -0.16922 -0.01 -0.13191 -0.029 -0.07861 C -0.039 -0.05063 -0.045 -0.02398 -0.047 -0.004 C -0.05 0.01199 -0.051 0.02798 -0.051 0.04663 C -0.051 0.10659 -0.038 0.15589 -0.023 0.15589 C -0.008 0.15589 0.005 0.10659 0.005 0.04663 C 0.005 0.01865 0.002 -0.00799 -0.003 -0.02665 C -0.005 -0.04264 -0.01 -0.05996 -0.016 -0.07728 C -0.036 -0.13191 -0.063 -0.16922 -0.077 -0.15989 C -0.091 -0.15056 -0.086 -0.09993 -0.066 -0.0453 C -0.058 -0.01999 -0.047 0.00133 -0.036 0.01599 C -0.028 0.02931 -0.019 0.0413 -0.007 0.0533 C 0.029 0.09194 0.065 0.10926 0.075 0.09327 C 0.084 0.07728 0.064 0.03331 0.028 -0.004 C 0.013 -0.01999 -0.003 -0.03198 -0.016 -0.03997 C -0.028 -0.04797 -0.043 -0.05463 -0.059 -0.05863 C -0.103 -0.07195 -0.141 -0.06795 -0.144 -0.04663 C -0.148 -0.02665 -0.115 0 -0.071 0.01332 C -0.051 0.01865 -0.032 0.02132 -0.017 0.01999 C -0.004 0.01999 0.01 0.01732 0.025 0.01332 C 0.069 0 0.102 -0.02798 0.098 -0.04797 C 0.095 -0.06795 0.057 -0.07328 0.013 -0.05996 C -0.008 -0.0533 -0.027 -0.04397 -0.04 -0.03331 C -0.051 -0.02532 -0.062 -0.01599 -0.074 -0.004 C -0.109 0.03464 -0.13 0.07728 -0.12 0.09327 C -0.111 0.10926 -0.074 0.09194 -0.039 0.05463 C -0.022 0.03598 -0.008 0.01732 0 0 Z"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold" smil:accelerate="0.5" smil:decelerate="0.5" pres:node-type="on-click" pres:preset-class="motion-path" pres:preset-id="ooo-motionpath-peanut">
+ <anim:animateMotion smil:dur="2" smil:fill="hold" svg:path="M 0 0 C 0.038 0 0.069 0.0413 0.069 0.09194 C 0.069 0.12525 0.056 0.15456 0.037 0.17188 C 0.037 0.17188 0.036 0.17188 0.036 0.17188 C 0.029 0.17854 0.025 0.1892 0.025 0.20119 C 0.025 0.21185 0.029 0.22118 0.034 0.22784 C 0.042 0.2385 0.047 0.25449 0.047 0.27048 C 0.047 0.30512 0.026 0.3331 0 0.3331 C -0.026 0.3331 -0.047 0.30512 -0.047 0.27048 C -0.047 0.25449 -0.042 0.2385 -0.034 0.22784 C -0.029 0.22118 -0.026 0.21185 -0.026 0.20119 C -0.026 0.1892 -0.03 0.17854 -0.036 0.17188 C -0.036 0.17188 -0.037 0.17188 -0.037 0.17188 C -0.057 0.15456 -0.07 0.12525 -0.07 0.09194 C -0.07 0.0413 -0.039 0 0 0 C 0 0 0 0 0 0 Z"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold" smil:accelerate="0.5" smil:decelerate="0.5" pres:node-type="on-click" pres:preset-class="motion-path" pres:preset-id="ooo-motionpath-clover">
+ <anim:animateMotion smil:dur="2" smil:fill="hold" svg:path="M 0 0 C -0.118 -0.15722 0.132 -0.15722 0.011 0 C 0.132 -0.15722 0.132 0.17588 0.011 0.01466 C 0.132 0.17588 -0.118 0.17588 0 0.01466 C -0.118 0.17588 -0.118 -0.15722 0 0 Z"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold" smil:accelerate="0.5" smil:decelerate="0.5" pres:node-type="on-click" pres:preset-class="motion-path" pres:preset-id="ooo-motionpath-pointy-star">
+ <anim:animateMotion smil:dur="2" smil:fill="hold" svg:path="M 0 0 C 0.069 0 0.124 -0.07461 0.124 -0.16655 C 0.124 -0.07461 0.179 -0.00133 0.248 -0.00133 C 0.179 -0.00133 0.125 0.07461 0.125 0.16655 C 0.125 0.07461 0.069 0 0 0 Z"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold" smil:accelerate="0.5" smil:decelerate="0.5" pres:node-type="on-click" pres:preset-class="motion-path" pres:preset-id="ooo-motionpath-swoosh">
+ <anim:animateMotion smil:dur="2" smil:fill="hold" svg:path="M 0 0 C 0 0 0.017 -0.08661 0.017 -0.08661 C 0.034 -0.15722 0.061 -0.1852 0.1 -0.1852 C 0.12 -0.1852 0.138 -0.17455 0.152 -0.15722 C 0.162 -0.14523 0.174 -0.13857 0.187 -0.13857 C 0.212 -0.13857 0.233 -0.16255 0.241 -0.1972 C 0.241 -0.1972 0.25 -0.2385 0.25 -0.2385 C 0.25 -0.2385 0.232 -0.15056 0.232 -0.15056 C 0.215 -0.08128 0.188 -0.0533 0.15 -0.0533 C 0.13 -0.0533 0.111 -0.06396 0.096 -0.08261 C 0.087 -0.09327 0.075 -0.09993 0.063 -0.09993 C 0.038 -0.09993 0.017 -0.07595 0.009 -0.0413 C 0.009 -0.0413 0 0 0 0 Z"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold" smil:accelerate="0.5" smil:decelerate="0.5" pres:node-type="on-click" pres:preset-class="motion-path" pres:preset-id="ooo-motionpath-vertical-figure-8">
+ <anim:animateMotion smil:dur="2" smil:fill="hold" svg:path="M 0 0 C 0.033 0 0.06 0.03598 0.06 0.07994 C 0.06 0.13191 0.03 0.15056 0.012 0.15856 L -0.012 0.16655 C -0.03 0.17455 -0.06 0.19453 -0.06 0.25316 C -0.06 0.29046 -0.033 0.3331 0 0.3331 C 0.033 0.3331 0.06 0.29046 0.06 0.25316 C 0.06 0.19453 0.03 0.17455 0.012 0.16655 L -0.012 0.15856 C -0.03 0.15056 -0.06 0.13191 -0.06 0.07994 C -0.06 0.03598 -0.033 0 0 0 Z"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold" pres:node-type="on-click" pres:preset-class="entrance" pres:preset-id="ooo-media-start">
+ <anim:command smil:begin="0" smil:dur="0.001" smil:fill="hold" anim:command="play"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold" pres:node-type="on-click" pres:preset-class="entrance" pres:preset-id="ooo-media-stop">
+ <anim:command smil:begin="0" smil:dur="0.001" smil:fill="hold" anim:command="stop"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+ <anim:par smil:begin="indefinite" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold">
+ <anim:par smil:begin="0" smil:fill="hold" pres:node-type="on-click" pres:preset-class="entrance" pres:preset-id="ooo-media-toggle-pause">
+ <anim:command smil:begin="0" smil:dur="0.001" smil:fill="hold" anim:command="toggle-pause"/>
+ </anim:par>
+ </anim:par>
+ </anim:par>
+</anim:seq>
diff --git a/test/user-template/user/config/soffice.cfg/simpress/layoutlist.xml b/test/user-template/user/config/soffice.cfg/simpress/layoutlist.xml
new file mode 100644
index 0000000000..c458b11507
--- /dev/null
+++ b/test/user-template/user/config/soffice.cfg/simpress/layoutlist.xml
@@ -0,0 +1,86 @@
+<?xml version="1.0"?>
+<!-- Configurable definitions of Impress slide layouts.
+
+ Currently the layout type name needs to match a set of predefined strings.
+ Per entry, you can declare up to one Title object, and up to four
+ Outline objects. All values are relative to Impress' 'layout
+ rect', which is roughly 90% of the available slide area.
+-->
+<layout-list>
+ <layout type="AUTOLAYOUT_TITLE_CONTENT">
+ <presobj kind="PRESOBJ_TITLE" relative-height="1" relative-width="1" relative-posX="0" relative-posY="0"/>
+ <presobj kind="PRESOBJ_OUTLINE1" relative-height="1" relative-width="1" relative-posX="0" relative-posY="0"/>
+ </layout>
+ <layout type="AUTOLAYOUT_TITLE_2CONTENT">
+ <presobj kind="PRESOBJ_TITLE" relative-height="1" relative-width="1" relative-posX="0" relative-posY="0"/>
+ <presobj kind="PRESOBJ_OUTLINE1" relative-height="1" relative-width="0.488" relative-posX="0" relative-posY="0"/>
+ <presobj kind="PRESOBJ_OUTLINE2" relative-height="1" relative-width="0.488" relative-posX="1.05" relative-posY="0"/>
+ </layout>
+ <layout type="AUTOLAYOUT_TITLE_CONTENT_OVER_CONTENT">
+ <presobj kind="PRESOBJ_TITLE" relative-height="1" relative-width="1" relative-posX="0" relative-posY="0"/>
+ <presobj kind="PRESOBJ_OUTLINE1" relative-height="0.477" relative-width="1" relative-posX="0" relative-posY="0"/>
+ <presobj kind="PRESOBJ_OUTLINE2" relative-height="0.477" relative-width="1" relative-posX="0" relative-posY="1.095"/>
+ </layout>
+ <layout type="AUTOLAYOUT_TITLE_CONTENT_2CONTENT">
+ <presobj kind="PRESOBJ_TITLE" relative-height="1" relative-width="1" relative-posX="0" relative-posY="0"/>
+ <presobj kind="PRESOBJ_OUTLINE1" relative-height="1" relative-width="0.488" relative-posX="0" relative-posY="0"/>
+ <presobj kind="PRESOBJ_OUTLINE2" relative-height="0.477" relative-width="0.488" relative-posX="1.05" relative-posY="0"/>
+ <presobj kind="PRESOBJ_OUTLINE3" relative-height="0.477" relative-width="0.488" relative-posX="1.05" relative-posY="1.095"/>
+ </layout>
+ <layout type="AUTOLAYOUT_TITLE_4CONTENT">
+ <presobj kind="PRESOBJ_TITLE" relative-height="1" relative-width="1" relative-posX="0" relative-posY="0"/>
+ <presobj kind="PRESOBJ_OUTLINE1" relative-height="0.477" relative-width="0.488" relative-posX="0" relative-posY="0"/>
+ <presobj kind="PRESOBJ_OUTLINE2" relative-height="0.477" relative-width="0.488" relative-posX="1.05" relative-posY="0"/>
+ <presobj kind="PRESOBJ_OUTLINE3" relative-height="0.477" relative-width="0.488" relative-posX="1.05" relative-posY="1.095"/>
+ <presobj kind="PRESOBJ_OUTLINE4" relative-height="0.477" relative-width="0.488" relative-posX="0" relative-posY="1.095"/>
+ </layout>
+ <layout type="AUTOLAYOUT_ONLY_TEXT">
+ <presobj kind="PRESOBJ_OUTLINE1" relative-height="4.6354" relative-width="1" relative-posX="0" relative-posY="0"/>
+ </layout>
+ <layout type="AUTOLAYOUT_TITLE_ONLY">
+ <presobj kind="PRESOBJ_TITLE" relative-height="1" relative-width="1" relative-posX="0" relative-posY="0"/>
+ </layout>
+ <layout type="AUTOLAYOUT_TITLE_6CONTENT">
+ <presobj kind="PRESOBJ_TITLE" relative-height="1" relative-width="1" relative-posX="0" relative-posY="0"/>
+ <presobj kind="PRESOBJ_OUTLINE1" relative-height="0.477" relative-width="0.322" relative-posX="0" relative-posY="0"/>
+ <presobj kind="PRESOBJ_OUTLINE2" relative-height="0.477" relative-width="0.322" relative-posX="1.05" relative-posY="0"/>
+ <presobj kind="PRESOBJ_OUTLINE3" relative-height="0.477" relative-width="0.322" relative-posX="2.10" relative-posY="0"/>
+ <presobj kind="PRESOBJ_OUTLINE4" relative-height="0.477" relative-width="0.322" relative-posX="2.10" relative-posY="1.095"/>
+ <presobj kind="PRESOBJ_OUTLINE5" relative-height="0.477" relative-width="0.322" relative-posX="1.05" relative-posY="1.095"/>
+ <presobj kind="PRESOBJ_OUTLINE6" relative-height="0.477" relative-width="0.322" relative-posX="0" relative-posY="1.095"/>
+ </layout>
+ <layout type="AUTOLAYOUT_START">
+ <presobj kind="PRESOBJ_TITLE" relative-height="1" relative-width="1" relative-posX="0" relative-posY="0"/>
+ <presobj kind="PRESOBJ_OUTLINE1" relative-height="1" relative-width="1" relative-posX="0" relative-posY="0"/>
+ </layout>
+ <layout type="AUTOLAYOUT_TITLE_2CONTENT_CONTENT">
+ <presobj kind="PRESOBJ_TITLE" relative-height="1" relative-width="1" relative-posX="0" relative-posY="0"/>
+ <presobj kind="PRESOBJ_OUTLINE1" relative-height="0.477" relative-width="0.488" relative-posX="0" relative-posY="0"/>
+ <presobj kind="PRESOBJ_OUTLINE2" relative-height="0.477" relative-width="0.488" relative-posX="0" relative-posY="1.095"/>
+ <presobj kind="PRESOBJ_OUTLINE3" relative-height="1" relative-width="0.488" relative-posX="1.05" relative-posY="0"/>
+ </layout>
+ <layout type="AUTOLAYOUT_TITLE_2CONTENT_OVER_CONTENT">
+ <presobj kind="PRESOBJ_TITLE" relative-height="1" relative-width="1" relative-posX="0" relative-posY="0"/>
+ <presobj kind="PRESOBJ_OUTLINE1" relative-height="0.477" relative-width="0.488" relative-posX="0" relative-posY="0"/>
+ <presobj kind="PRESOBJ_OUTLINE2" relative-height="0.477" relative-width="0.488" relative-posX="1.05" relative-posY="0"/>
+ <presobj kind="PRESOBJ_OUTLINE3" relative-height="0.477" relative-width="1" relative-posX="0" relative-posY="1.095"/>
+ </layout>
+ <layout type="AUTOLAYOUT_VTITLE_VCONTENT">
+ <presobj kind="PRESOBJ_TITLE" relative-height="4.6354" relative-width="0.139167" relative-posX="6.1856" relative-posY="0"/>
+ <presobj kind="PRESOBJ_OUTLINE1" relative-height="1.3347" relative-width="0.777778" relative-posX="0" relative-posY="-0.25078974"/>
+ </layout>
+ <layout type="AUTOLAYOUT_VTITLE_VCONTENT_OVER_VCONTENT">
+ <presobj kind="PRESOBJ_TITLE" relative-height="4.6354" relative-width="0.139167" relative-posX="6.1856" relative-posY="0"/>
+ <presobj kind="PRESOBJ_OUTLINE1" relative-height="0.6272578" relative-width="0.777778" relative-posX="0" relative-posY="-0.53363874"/>
+ <presobj kind="PRESOBJ_OUTLINE2" relative-height="0.6272578" relative-width="0.777778" relative-posX="0" relative-posY="0.5939791"/>
+ </layout>
+ <layout type="AUTOLAYOUT_TITLE_VCONTENT">
+ <presobj kind="PRESOBJ_TITLE" relative-height="1" relative-width="1" relative-posX="0" relative-posY="0"/>
+ <presobj kind="PRESOBJ_OUTLINE1" relative-height="1" relative-width="1" relative-posX="0" relative-posY="0"/>
+ </layout>
+ <layout type="AUTOLAYOUT_TITLE_2VTEXT">
+ <presobj kind="PRESOBJ_TITLE" relative-height="1" relative-width="1" relative-posX="0" relative-posY="0"/>
+ <presobj kind="PRESOBJ_OUTLINE1" relative-height="1" relative-width="0.488" relative-posX="0" relative-posY="0"/>
+ <presobj kind="PRESOBJ_OUTLINE2" relative-height="1" relative-width="0.488" relative-posX="1.05" relative-posY="0"/>
+ </layout>
+</layout-list>
diff --git a/test/user-template/user/config/soffice.cfg/simpress/objectlist.xml b/test/user-template/user/config/soffice.cfg/simpress/objectlist.xml
new file mode 100644
index 0000000000..40ecec3502
--- /dev/null
+++ b/test/user-template/user/config/soffice.cfg/simpress/objectlist.xml
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ * 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/.
+ *
+-->
+<object-list>
+ <object type="PRESOBJ_DATETIME">
+ <object-prop pagekind="PK_STANDARD" relative-height="0.069" relative-width="0.233" relative-posX="0.05" relative-posY="0.911"/>
+ <object-prop pagekind="PK_HANDOUT" relative-height="0.05" relative-width="0.434" relative-posX="0.434" relative-posY="0"/>
+ <object-prop pagekind="PK_NOTES" relative-height="0.05" relative-width="0.434" relative-posX="0.434" relative-posY="0"/>
+ </object>
+ <object type="PRESOBJ_FOOTER">
+ <object-prop pagekind="PK_STANDARD" relative-height="0.069" relative-width="0.317" relative-posX="0.342" relative-posY="0.911"/>
+ <object-prop pagekind="PK_HANDOUT" relative-height="0.05" relative-width="0.434" relative-posX="0" relative-posY="0.05"/>
+ <object-prop pagekind="PK_NOTES" relative-height="0.05" relative-width="0.434" relative-posX="0" relative-posY="0.05"/>
+ </object>
+ <object type="PRESOBJ_SLIDENUMBER">
+ <object-prop pagekind="PK_STANDARD" relative-height="0.069" relative-width="0.233" relative-posX="0.717" relative-posY="0.911"/>
+ <object-prop pagekind="PK_HANDOUT" relative-height="0.05" relative-width="0.434" relative-posX="0.434" relative-posY="0.05"/>
+ <object-prop pagekind="PK_NOTES" relative-height="0.05" relative-width="0.434" relative-posX="0.434" relative-posY="0.05"/>
+ </object>
+ <object type="PRESOBJ_HEADER">
+ <object-prop pagekind="PK_STANDARD" relative-height="0.069" relative-width="0.317" relative-posX="0.717" relative-posY="0.911"/>
+ <object-prop pagekind="PK_HANDOUT" relative-height="0.05" relative-width="0.434" relative-posX="0" relative-posY="0"/>
+ <object-prop pagekind="PK_NOTES" relative-height="0.05" relative-width="0.434" relative-posX="0" relative-posY="0"/>
+ </object>
+ <object type="PRESOBJ_TITLE">
+ <object-prop pagekind="PK_STANDARD" relative-height="0.167" relative-width="0.9" relative-posX="0.05" relative-posY="0.0399"/>
+ <object-prop pagekind="PK_NOTES" relative-height="0.375" relative-width="1" relative-posX="0" relative-posY="0.076"/>
+ </object>
+ <object type="PRESOBJ_OUTLINE">
+ <object-prop pagekind="PK_STANDARD" relative-height="0.58" relative-width="0.9" relative-posX="0.05" relative-posY="0.234"/>
+ </object>
+ <object type="PRESOBJ_NOTES">
+ <object-prop pagekind="PK_NOTES" relative-height="0.45" relative-width="0.8" relative-posX="0.1" relative-posY="0.475"/>
+ </object>
+</object-list> \ No newline at end of file
diff --git a/test/user-template/user/config/soffice.cfg/simpress/transitions-ogl.xml b/test/user-template/user/config/soffice.cfg/simpress/transitions-ogl.xml
new file mode 100644
index 0000000000..ca1e3661c1
--- /dev/null
+++ b/test/user-template/user/config/soffice.cfg/simpress/transitions-ogl.xml
@@ -0,0 +1,48 @@
+<?xml version="1.0"?>
+<anim:seq xmlns:office="urn:oasis:names:tc:openoffice:xmlns:office:1.0" xmlns:style="urn:oasis:names:tc:openoffice:xmlns:style:1.0" xmlns:text="urn:oasis:names:tc:openoffice:xmlns:text:1.0" xmlns:table="urn:oasis:names:tc:openoffice:xmlns:table:1.0" xmlns:draw="urn:oasis:names:tc:openoffice:xmlns:drawing:1.0" xmlns:fo="http://www.w3.org/1999/XSL/Format" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:meta="urn:oasis:names:tc:openoffice:xmlns:meta:1.0" xmlns:number="urn:oasis:names:tc:openoffice:xmlns:datastyle:1.0" xmlns:pres="urn:oasis:names:tc:openoffice:xmlns:presentation:1.0" xmlns:svg="http://www.w3.org/2000/svg" xmlns:chart="urn:oasis:names:tc:openoffice:xmlns:chart:1.0" xmlns:dr3d="urn:oasis:names:tc:openoffice:xmlns:dr3d:1.0" xmlns:math="http://www.w3.org/1998/Math/MathML" xmlns:form="urn:oasis:names:tc:openoffice:xmlns:form:1.0" xmlns:script="urn:oasis:names:tc:openoffice:xmlns:script:1.0" xmlns:ooo="http://openoffice.org/2004/office" xmlns:ooow="http://openoffice.org/2004/writer" xmlns:oooc="http://openoffice.org/2004/calc" xmlns:dom="http://www.w3.org/2001/xml-events" xmlns:smil="http://www.w3.org/2001/SMIL20" xmlns:anim="urn:oasis:names:tc:openoffice:xmlns:animation:1.0" pres:node-type="main-sequence">
+ <anim:par pres:preset-id="tile-flip">
+ <anim:transitionFilter smil:type="miscShapeWipe" smil:subtype="across"/>
+ </anim:par>
+ <anim:par pres:preset-id="outside-cube">
+ <anim:transitionFilter smil:type="miscShapeWipe" smil:subtype="cornersOut"/>
+ </anim:par>
+ <anim:par pres:preset-id="revolving-circles">
+ <anim:transitionFilter smil:type="miscShapeWipe" smil:subtype="circle"/>
+ </anim:par>
+ <anim:par pres:preset-id="turning-helix">
+ <anim:transitionFilter smil:type="miscShapeWipe" smil:subtype="fanOutHorizontal"/>
+ </anim:par>
+ <anim:par pres:preset-id="inside-cube">
+ <anim:transitionFilter smil:type="miscShapeWipe" smil:subtype="cornersIn"/>
+ </anim:par>
+ <anim:par pres:preset-id="fall">
+ <anim:transitionFilter smil:type="miscShapeWipe" smil:subtype="leftToRight"/>
+ </anim:par>
+ <anim:par pres:preset-id="turn-around">
+ <anim:transitionFilter smil:type="miscShapeWipe" smil:subtype="topToBottom"/>
+ </anim:par>
+ <anim:par pres:preset-id="iris">
+ <anim:transitionFilter smil:type="miscShapeWipe" smil:subtype="topLeft"/>
+ </anim:par>
+ <anim:par pres:preset-id="turn-down">
+ <anim:transitionFilter smil:type="miscShapeWipe" smil:subtype="topRight"/>
+ </anim:par>
+ <anim:par pres:preset-id="rochade">
+ <anim:transitionFilter smil:type="miscShapeWipe" smil:subtype="bottomRight"/>
+ </anim:par>
+ <anim:par pres:preset-id="venetian3dv">
+ <anim:transitionFilter smil:type="miscShapeWipe" smil:subtype="bottomLeft"/>
+ </anim:par>
+ <anim:par pres:preset-id="venetian3dh">
+ <anim:transitionFilter smil:type="miscShapeWipe" smil:subtype="topCenter"/>
+ </anim:par>
+ <anim:par pres:preset-id="static">
+ <anim:transitionFilter smil:type="miscShapeWipe" smil:subtype="rightCenter"/>
+ </anim:par>
+ <anim:par pres:preset-id="finedissolve">
+ <anim:transitionFilter smil:type="miscShapeWipe" smil:subtype="bottomCenter"/>
+ </anim:par>
+ <anim:par pres:preset-id="zoom-rotate-in">
+ <anim:transitionFilter smil:type="zoom" smil:subtype="rotateIn"/>
+ </anim:par>
+ </anim:seq>
diff --git a/test/user-template/user/config/soffice.cfg/simpress/transitions.xml b/test/user-template/user/config/soffice.cfg/simpress/transitions.xml
new file mode 100644
index 0000000000..556eb6f504
--- /dev/null
+++ b/test/user-template/user/config/soffice.cfg/simpress/transitions.xml
@@ -0,0 +1,225 @@
+<?xml version="1.0"?>
+<anim:seq xmlns:office="urn:oasis:names:tc:openoffice:xmlns:office:1.0" xmlns:style="urn:oasis:names:tc:openoffice:xmlns:style:1.0" xmlns:text="urn:oasis:names:tc:openoffice:xmlns:text:1.0" xmlns:table="urn:oasis:names:tc:openoffice:xmlns:table:1.0" xmlns:draw="urn:oasis:names:tc:openoffice:xmlns:drawing:1.0" xmlns:fo="http://www.w3.org/1999/XSL/Format" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:meta="urn:oasis:names:tc:openoffice:xmlns:meta:1.0" xmlns:number="urn:oasis:names:tc:openoffice:xmlns:datastyle:1.0" xmlns:pres="urn:oasis:names:tc:openoffice:xmlns:presentation:1.0" xmlns:svg="http://www.w3.org/2000/svg" xmlns:chart="urn:oasis:names:tc:openoffice:xmlns:chart:1.0" xmlns:dr3d="urn:oasis:names:tc:openoffice:xmlns:dr3d:1.0" xmlns:math="http://www.w3.org/1998/Math/MathML" xmlns:form="urn:oasis:names:tc:openoffice:xmlns:form:1.0" xmlns:script="urn:oasis:names:tc:openoffice:xmlns:script:1.0" xmlns:ooo="http://openoffice.org/2004/office" xmlns:ooow="http://openoffice.org/2004/writer" xmlns:oooc="http://openoffice.org/2004/calc" xmlns:dom="http://www.w3.org/2001/xml-events" xmlns:smil="http://www.w3.org/2001/SMIL20" xmlns:anim="urn:oasis:names:tc:openoffice:xmlns:animation:1.0" pres:node-type="main-sequence">
+ <anim:par pres:preset-id="wipe-up">
+ <anim:transitionFilter smil:type="barWipe" smil:subtype="topToBottom" smil:direction="reverse"/>
+ </anim:par>
+ <anim:par pres:preset-id="wipe-right">
+ <anim:transitionFilter smil:type="barWipe" smil:subtype="leftToRight"/>
+ </anim:par>
+ <anim:par pres:preset-id="wipe-left">
+ <anim:transitionFilter smil:type="barWipe" smil:subtype="leftToRight" smil:direction="reverse"/>
+ </anim:par>
+ <anim:par pres:preset-id="wipe-down">
+ <anim:transitionFilter smil:type="barWipe" smil:subtype="topToBottom"/>
+ </anim:par>
+ <anim:par pres:preset-id="wheel-clockwise-1-spoke">
+ <anim:transitionFilter smil:type="pinWheelWipe" smil:subtype="oneBlade"/>
+ </anim:par>
+ <anim:par pres:preset-id="wheel-clockwise-2-spokes">
+ <anim:transitionFilter smil:type="pinWheelWipe" smil:subtype="twoBladeVertical"/>
+ </anim:par>
+ <anim:par pres:preset-id="wheel-clockwise-3-spokes">
+ <anim:transitionFilter smil:type="pinWheelWipe" smil:subtype="threeBlade"/>
+ </anim:par>
+ <anim:par pres:preset-id="wheel-clockwise-4-spokes">
+ <anim:transitionFilter smil:type="pinWheelWipe" smil:subtype="fourBlade"/>
+ </anim:par>
+ <anim:par pres:preset-id="wheel-clockwise-8-spokes">
+ <anim:transitionFilter smil:type="pinWheelWipe" smil:subtype="eightBlade"/>
+ </anim:par>
+ <anim:par pres:preset-id="uncover-down">
+ <anim:transitionFilter smil:type="slideWipe" smil:subtype="fromTop" smil:direction="reverse"/>
+ </anim:par>
+ <anim:par pres:preset-id="uncover-left">
+ <anim:transitionFilter smil:type="slideWipe" smil:subtype="fromRight" smil:direction="reverse"/>
+ </anim:par>
+ <anim:par pres:preset-id="uncover-right">
+ <anim:transitionFilter smil:type="slideWipe" smil:subtype="fromLeft" smil:direction="reverse"/>
+ </anim:par>
+ <anim:par pres:preset-id="uncover-up">
+ <anim:transitionFilter smil:type="slideWipe" smil:subtype="fromBottom" smil:direction="reverse"/>
+ </anim:par>
+ <anim:par pres:preset-id="uncover-left-down">
+ <anim:transitionFilter smil:type="slideWipe" smil:subtype="fromTopRight" smil:direction="reverse"/>
+ </anim:par>
+ <anim:par pres:preset-id="uncover-left-up">
+ <anim:transitionFilter smil:type="slideWipe" smil:subtype="fromBottomRight" smil:direction="reverse"/>
+ </anim:par>
+ <anim:par pres:preset-id="uncover-right-down">
+ <anim:transitionFilter smil:type="slideWipe" smil:subtype="fromTopLeft" smil:direction="reverse"/>
+ </anim:par>
+ <anim:par pres:preset-id="uncover-right-up">
+ <anim:transitionFilter smil:type="slideWipe" smil:subtype="fromBottomLeft" smil:direction="reverse"/>
+ </anim:par>
+<!-- <anim:par pres:preset-id="barn-inVertical"> -->
+<!-- <anim:transitionFilter smil:type="barnDoorWipe" smil:subtype="vertical"/> -->
+<!-- </anim:par> -->
+<!-- <anim:par pres:preset-id="barn-outVertical"> -->
+<!-- <anim:transitionFilter smil:type="barnDoorWipe" smil:subtype="vertical" smil:direction="reverse"/> -->
+<!-- </anim:par> -->
+<!-- <anim:par pres:preset-id="barn-inHorizontal"> -->
+<!-- <anim:transitionFilter smil:type="barnDoorWipe" smil:subtype="horizontal"/> -->
+<!-- </anim:par> -->
+<!-- <anim:par pres:preset-id="barn-outHorizontal"> -->
+<!-- <anim:transitionFilter smil:type="barnDoorWipe" smil:subtype="horizontal" smil:direction="reverse"/> -->
+<!-- </anim:par> -->
+ <anim:par pres:preset-id="random-bars-vertical">
+ <anim:transitionFilter smil:type="randomBarWipe" smil:subtype="vertical"/>},
+ </anim:par>
+ <anim:par pres:preset-id="random-bars-horizontal">
+ <anim:transitionFilter smil:type="randomBarWipe" smil:subtype="horizontal"/>
+ </anim:par>
+ <anim:par pres:preset-id="checkerboard-down">
+ <anim:transitionFilter smil:type="checkerBoardWipe" smil:subtype="down"/>},
+ </anim:par>
+ <anim:par pres:preset-id="checkerboard-across">
+ <anim:transitionFilter smil:type="checkerBoardWipe" smil:subtype="across"/>
+ </anim:par>
+ <anim:par pres:preset-id="shape-plus">
+ <anim:transitionFilter smil:type="fourBoxWipe" smil:subtype="cornersOut"/>
+ </anim:par>
+<!-- <anim:par pres:preset-id="plus-in"> -->
+<!-- <anim:transitionFilter smil:type="fourBoxWipe" smil:subtype="cornersIn"/> -->
+<!-- </anim:par> -->
+ <anim:par pres:preset-id="shape-diamond">
+ <anim:transitionFilter smil:type="irisWipe" smil:subtype="diamond"/>
+ </anim:par>
+<!-- <anim:par pres:preset-id="diamond-in"> -->
+<!-- <anim:transitionFilter smil:type="irisWipe" smil:subtype="diamond" smil:direction="reverse"/> -->
+<!-- </anim:par> -->
+ <anim:par pres:preset-id="shape-circle">
+ <anim:transitionFilter smil:type="ellipseWipe" smil:subtype="circle"/>
+ </anim:par>
+<!-- <anim:par pres:preset-id="circle-in"> -->
+<!-- <anim:transitionFilter smil:type="ellipseWipe" smil:subtype="circle" smil:direction="reverse"/> -->
+<!-- </anim:par> -->
+ <anim:par pres:preset-id="box-out">
+ <anim:transitionFilter smil:type="irisWipe" smil:subtype="rectangle"/>
+ </anim:par>
+ <anim:par pres:preset-id="box-in">
+ <anim:transitionFilter smil:type="irisWipe" smil:subtype="rectangle" smil:direction="reverse"/>
+ </anim:par>
+ <anim:par pres:preset-id="wedge">
+ <anim:transitionFilter smil:type="fanWipe" smil:subtype="centerTop"/>
+ </anim:par>
+ <anim:par pres:preset-id="venetian-blinds-vertical">
+ <anim:transitionFilter smil:type="blindsWipe" smil:subtype="vertical"/>
+ </anim:par>
+ <anim:par pres:preset-id="venetian-blinds-horizontal">
+ <anim:transitionFilter smil:type="blindsWipe" smil:subtype="horizontal"/>
+ </anim:par>
+ <anim:par pres:preset-id="fade-through-black">
+ <anim:transitionFilter smil:type="fade" smil:subtype="fadeOverColor" smil:fadeColor="#000000"/>
+ </anim:par>
+ <anim:par pres:preset-id="cut-through-black">
+ <anim:transitionFilter smil:type="barWipe" smil:subtype="fadeOverColor" smil:fadeColor="#000000"/>
+ </anim:par>
+ <anim:par pres:preset-id="cover-down">
+ <anim:transitionFilter smil:type="slideWipe" smil:subtype="fromTop"/>
+ </anim:par>
+ <anim:par pres:preset-id="cover-left">
+ <anim:transitionFilter smil:type="slideWipe" smil:subtype="fromRight"/>
+ </anim:par>
+ <anim:par pres:preset-id="cover-right">
+ <anim:transitionFilter smil:type="slideWipe" smil:subtype="fromLeft"/>
+ </anim:par>
+ <anim:par pres:preset-id="cover-up">
+ <anim:transitionFilter smil:type="slideWipe" smil:subtype="fromBottom"/>
+ </anim:par>
+ <anim:par pres:preset-id="cover-left-down">
+ <anim:transitionFilter smil:type="slideWipe" smil:subtype="fromTopRight"/>
+ </anim:par>
+ <anim:par pres:preset-id="cover-left-up">
+ <anim:transitionFilter smil:type="slideWipe" smil:subtype="fromBottomRight"/>
+ </anim:par>
+ <anim:par pres:preset-id="cover-right-down">
+ <anim:transitionFilter smil:type="slideWipe" smil:subtype="fromTopLeft"/>
+ </anim:par>
+ <anim:par pres:preset-id="cover-right-up">
+ <anim:transitionFilter smil:type="slideWipe" smil:subtype="fromBottomLeft"/>
+ </anim:par>
+ <anim:par pres:preset-id="dissolve">
+ <anim:transitionFilter smil:type="dissolve" smil:subtype="default"/>
+ </anim:par>
+ <anim:par pres:preset-id="random-transition">
+ <anim:transitionFilter smil:type="random"/>
+ </anim:par>
+ <!--anim:par pres:preset-id="zoom-rotate-in">
+ <anim:transitionFilter smil:type="zoom" smil:subtype="rotateIn"/>
+ </anim:par-->
+ <anim:par pres:preset-id="clock-wipe-twelve">
+ <anim:transitionFilter smil:type="clockWipe" smil:subtype="clockwiseTwelve"/>
+ </anim:par>
+ <anim:par pres:preset-id="reverse-clock-wipe-twelve">
+ <anim:transitionFilter smil:type="clockWipe" smil:subtype="clockwiseTwelve" smil:direction="reverse"/>
+ </anim:par>
+ <anim:par pres:preset-id="spiral-wipe-top-left-clockwise">
+ <anim:transitionFilter smil:type="spiralWipe" smil:subtype="topLeftClockwise"/>
+ </anim:par>
+ <anim:par pres:preset-id="spiral-wipe-top-right-counter-clockwise">
+ <anim:transitionFilter smil:type="spiralWipe" smil:subtype="topRightCounterClockwise"/>
+ </anim:par>
+ <anim:par pres:preset-id="spiral-wipe-out-to-bottom-right-clockwise">
+ <anim:transitionFilter smil:type="spiralWipe" smil:subtype="bottomRightCounterClockwise" smil:direction="reverse"/>
+ </anim:par>
+ <anim:par pres:preset-id="spiral-wipe-out-to-bottom-left-counter-clockwise">
+ <anim:transitionFilter smil:type="spiralWipe" smil:subtype="bottomLeftClockwise" smil:direction="reverse"/>
+ </anim:par>
+ <anim:par pres:preset-id="snake-wipe-top-left-vertical">
+ <anim:transitionFilter smil:type="snakeWipe" smil:subtype="topLeftVertical"/>
+ </anim:par>
+ <anim:par pres:preset-id="snake-wipe-top-left-horizontal">
+ <anim:transitionFilter smil:type="snakeWipe" smil:subtype="topLeftHorizontal"/>
+ </anim:par>
+ <anim:par pres:preset-id="snake-wipe-bottom-right-vertical">
+ <anim:transitionFilter smil:type="snakeWipe" smil:subtype="topLeftVertical" smil:direction="reverse"/>
+ </anim:par>
+ <anim:par pres:preset-id="snake-wipe-bottom-right-horizontal">
+ <anim:transitionFilter smil:type="snakeWipe" smil:subtype="topLeftHorizontal" smil:direction="reverse"/>
+ </anim:par>
+ <anim:par pres:preset-id="comb-horizontal">
+ <anim:transitionFilter smil:type="pushWipe" smil:subtype="combHorizontal"/>
+ </anim:par>
+ <anim:par pres:preset-id="comb-vertical">
+ <anim:transitionFilter smil:type="pushWipe" smil:subtype="combVertical"/>
+ </anim:par>
+ <anim:par pres:preset-id="fade-smoothly">
+ <anim:transitionFilter smil:type="fade" smil:subtype="crossfade"/>
+ </anim:par>
+ <anim:par pres:preset-id="push-down">
+ <anim:transitionFilter smil:type="pushWipe" smil:subtype="fromTop"/>
+ </anim:par>
+ <anim:par pres:preset-id="push-left">
+ <anim:transitionFilter smil:type="pushWipe" smil:subtype="fromRight"/>
+ </anim:par>
+ <anim:par pres:preset-id="push-right">
+ <anim:transitionFilter smil:type="pushWipe" smil:subtype="fromLeft"/>
+ </anim:par>
+ <anim:par pres:preset-id="push-up">
+ <anim:transitionFilter smil:type="pushWipe" smil:subtype="fromBottom"/>
+ </anim:par>
+ <anim:par pres:preset-id="split-horizontal-in">
+ <anim:transitionFilter smil:type="barnDoorWipe" smil:subtype="horizontal" smil:direction="reverse"/>
+ </anim:par>
+ <anim:par pres:preset-id="split-horizontal-out">
+ <anim:transitionFilter smil:type="barnDoorWipe" smil:subtype="horizontal"/>
+ </anim:par>
+ <anim:par pres:preset-id="split-vertical-in">
+ <anim:transitionFilter smil:type="barnDoorWipe" smil:subtype="vertical" smil:direction="reverse"/>
+ </anim:par>
+ <anim:par pres:preset-id="split-vertical-out">
+ <anim:transitionFilter smil:type="barnDoorWipe" smil:subtype="vertical"/>
+ </anim:par>
+ <anim:par pres:preset-id="diagonal-squares-left-down">
+ <anim:transitionFilter smil:type="waterfallWipe" smil:subtype="horizontalRight"/>
+ </anim:par>
+ <anim:par pres:preset-id="diagonal-squares-left-up">
+ <anim:transitionFilter smil:type="waterfallWipe" smil:subtype="horizontalLeft" smil:direction="reverse"/>
+ </anim:par>
+ <anim:par pres:preset-id="diagonal-squares-right-down">
+ <anim:transitionFilter smil:type="waterfallWipe" smil:subtype="horizontalLeft"/>
+ </anim:par>
+ <anim:par pres:preset-id="diagonal-squares-right-up">
+ <anim:transitionFilter smil:type="waterfallWipe" smil:subtype="horizontalRight" smil:direction="reverse"/>
+ </anim:par>
+ </anim:seq>
diff --git a/test/user-template/user/database/biblio.odb b/test/user-template/user/database/biblio.odb
new file mode 100644
index 0000000000..199fd6f5f4
--- /dev/null
+++ b/test/user-template/user/database/biblio.odb
Binary files differ
diff --git a/test/user-template/user/database/biblio/biblio.dbf b/test/user-template/user/database/biblio/biblio.dbf
new file mode 100644
index 0000000000..4161cea25c
--- /dev/null
+++ b/test/user-template/user/database/biblio/biblio.dbf
Binary files differ
diff --git a/test/user-template/user/database/biblio/biblio.dbt b/test/user-template/user/database/biblio/biblio.dbt
new file mode 100644
index 0000000000..e17daea26b
--- /dev/null
+++ b/test/user-template/user/database/biblio/biblio.dbt
Binary files differ
diff --git a/test/user-template/user/wordbook/en-GB.dic b/test/user-template/user/wordbook/en-GB.dic
new file mode 100644
index 0000000000..6f59453710
--- /dev/null
+++ b/test/user-template/user/wordbook/en-GB.dic
@@ -0,0 +1,46 @@
+OOoUserDict1
+lang: en-GB
+type: positive
+---
+Applet
+Applets
+AutoAbstract
+AutoComplete
+AutoFill
+AutoMail
+AutoPilots
+AutoSpell
+AutoUpdate
+Bitmap
+Clientsided
+ClipArt
+ClipArts
+Combobox
+Euro
+FontManager
+Fontwork
+Frameset
+Framesets
+GIFs
+HelpAgent
+HighEnd
+Homepage
+Http
+Hyperlink
+Hyperlinks
+ImageMaps
+Imagemap
+Intranet
+PlugIns
+Plugin
+PreFinal
+Serversided
+ServicePack
+TabPage
+deinstall
+deinstalled
+deinstalling
+deinstalls
+userspace
+endian
+endianness
diff --git a/test/user-template/user/wordbook/en-US.dic b/test/user-template/user/wordbook/en-US.dic
new file mode 100644
index 0000000000..4aa77f9c96
--- /dev/null
+++ b/test/user-template/user/wordbook/en-US.dic
@@ -0,0 +1,46 @@
+OOoUserDict1
+lang: en-US
+type: positive
+---
+Applet
+Applets
+AutoAbstract
+AutoComplete
+AutoFill
+AutoMail
+AutoPilots
+AutoSpell
+AutoUpdate
+Bitmap
+Clientsided
+ClipArt
+ClipArts
+Combobox
+Euro
+FontManager
+Fontwork
+Frameset
+Framesets
+GIFs
+HelpAgent
+HighEnd
+Homepage
+Http
+Hyperlink
+Hyperlinks
+ImageMaps
+Imagemap
+Intranet
+PlugIns
+Plugin
+PreFinal
+Serversided
+ServicePack
+TabPage
+deinstall
+deinstalled
+deinstalling
+deinstalls
+userspace
+endian
+endianness
diff --git a/test/user-template/user/wordbook/sl.dic b/test/user-template/user/wordbook/sl.dic
new file mode 100644
index 0000000000..4c2100a99a
--- /dev/null
+++ b/test/user-template/user/wordbook/sl.dic
@@ -0,0 +1,24 @@
+OOoUserDict1
+lang: sl
+type: positive
+---
+avtopiloti
+hiperpovezav
+hiperpovezava
+hiperpovezavam
+hiperpovezavama
+hiperpovezavami
+hiperpovezave
+hiperpovezavi
+hiperpovezavo
+intranet
+samooblikovanj
+samooblikovanja
+samooblikovanje
+samooblikovanju
+samopopravka
+samopopravki
+samopopravkom
+samopopravkoma
+samopopravkov
+samopopravku
diff --git a/test/user-template/user/wordbook/technical.dic b/test/user-template/user/wordbook/technical.dic
new file mode 100644
index 0000000000..383c6689c3
--- /dev/null
+++ b/test/user-template/user/wordbook/technical.dic
@@ -0,0 +1,230 @@
+OOoUserDict1
+lang: <none>
+type: positive
+---
+Accenture
+Acer
+Acrobat
+Add-in
+Adobe
+Advanced
+AMD
+Android
+AppArmor
+AppConnect=
+Apple
+AppWizard=
+AppXaminer=
+AppXNavigator=
+AppXRay=
+Argus=
+Asus
+AutoVue=
+Badger
+Base=
+Base24=
+Bing
+BorderManager
+Breezy
+CADView=
+Calc=
+Canon
+Canonical
+Capgemini
+Carefx
+Chrome
+Cisco=
+Clickstream=
+Cognos=
+Connect2OracleSelf=
+ConsoleOne
+ConText=
+COREid=
+Corporation
+Dapper
+dBase
+Debian
+debootstrap
+Dell
+Devices
+DocLink
+Docuflex=
+Documaker=
+Document
+dpkg
+Drake
+Draw=
+Edgy
+eDirectory
+Edubuntu
+Eft
+eGuide
+Electronics
+Etch
+Ethernet
+Evolution
+Exadata=
+Facebook
+Fawn
+Feisty
+Firebird
+Firefox
+FLAC
+Flash
+Foundation
+Foxconn
+FreeBSD
+Fujitsu
+gcc
+gcj
+Gibbon
+GIF
+gij
+GNOME
+GNU
+Google
+GPS
+GroupWise
+Gutsy
+Hardy
+Hedgehog
+Heron
+Hewlett-Packard
+Hi-Fi
+Hitachi
+Hoary
+HP
+HTML
+Ibex
+IBM
+iChain
+Identi.ca
+iFolder
+iManager
+Impress=
+Intel
+Intrepid
+iPrint
+Jackalope
+Jaunty
+JavaScript
+JPEG
+Karmic
+KDE
+Kerberos
+Koala
+Kubuntu
+Launchpad
+LDAP
+Lenny
+Lenovo
+LibreOffice=
+Linux
+Lucid
+Lynx
+Malone
+ManageWise
+MasterCard
+Math=
+Maverick
+Meerkat
+Micro
+Microsoft=
+MicroStrategy=
+Mono
+Motorola
+Mozilla
+MySQL
+NCSA
+NEC
+NetBSD
+NetIdentity
+NetMail
+NetStorage
+NetWare
+NNTP
+Nokia
+Novell
+NRadius
+ODBC
+Ogg
+OnDemand
+OpenBSD
+OpenDocument=
+OpenOffice.org=
+openSUSE
+OpenText=
+OpenWorld=
+OpenZorg=
+Opera
+Optronics
+Oracle=
+Panasonic
+PayPal
+PeopleSoft=
+Plug-in
+PNG
+PolyServe
+POP3
+PostgreSQL
+PPPoE
+Quanta
+Rosetta
+RosettaNet=
+rpm
+Samba
+Samsung
+SAP
+Sarge
+Satmetrix=
+SecretStore
+SecureLogin
+Sharp
+Shockwave
+Sid
+Skype
+SLED
+SLES
+SMTP
+Sony
+Soyuz
+Spamassassin
+SPI
+Squeeze
+StarOffice
+StorageTek=
+Sun=
+SunHSI=
+SunSAI=
+SUSE
+TeliaSonera
+The
+Thunderbird
+Toshiba
+TrueType
+Twitter
+Ubuntu
+uname
+URL
+Visa
+VoIP=
+Vorbis
+VRML
+Warthog
+Warty
+Wheezy
+Wi-Fi
+WiMAX
+Windows
+Woody
+WorkPlace
+Writer=
+WYSIWYG
+Xen
+Ximian
+Xtensible
+XTier
+Xubuntu
+Yahoo
+YouTube
+ZENworks