diff options
-rw-r--r-- | oovbaapi/UnoApi_oovbaapi.mk | 3 | ||||
-rw-r--r-- | oovbaapi/ooo/vba/word/WdContentControlType.idl | 25 | ||||
-rw-r--r-- | oovbaapi/ooo/vba/word/XContentControl.idl | 103 | ||||
-rw-r--r-- | oovbaapi/ooo/vba/word/XContentControls.idl | 23 | ||||
-rw-r--r-- | oovbaapi/ooo/vba/word/XDocument.idl | 3 | ||||
-rw-r--r-- | sw/Library_vbaswobj.mk | 2 | ||||
-rw-r--r-- | sw/qa/core/data/docm/testModernVBA.docm | bin | 0 -> 31069 bytes | |||
-rw-r--r-- | sw/qa/core/macros-test.cxx | 4 | ||||
-rw-r--r-- | sw/source/ui/vba/vbacontentcontrol.cxx | 754 | ||||
-rw-r--r-- | sw/source/ui/vba/vbacontentcontrol.hxx | 142 | ||||
-rw-r--r-- | sw/source/ui/vba/vbacontentcontrols.cxx | 264 | ||||
-rw-r--r-- | sw/source/ui/vba/vbacontentcontrols.hxx | 44 | ||||
-rw-r--r-- | sw/source/ui/vba/vbadocument.cxx | 27 | ||||
-rw-r--r-- | sw/source/ui/vba/vbadocument.hxx | 3 |
14 files changed, 1397 insertions, 0 deletions
diff --git a/oovbaapi/UnoApi_oovbaapi.mk b/oovbaapi/UnoApi_oovbaapi.mk index 331cf4937e32..063700762e46 100644 --- a/oovbaapi/UnoApi_oovbaapi.mk +++ b/oovbaapi/UnoApi_oovbaapi.mk @@ -833,6 +833,7 @@ $(eval $(call gb_UnoApi_add_idlfiles,oovbaapi,ooo/vba/word,\ WdFarEastLineBreakLevel \ WdFieldKind \ WdFieldShading \ + WdContentControlType \ WdFieldType \ WdFindMatch \ WdFindWrap \ @@ -1057,6 +1058,8 @@ $(eval $(call gb_UnoApi_add_idlfiles,oovbaapi,ooo/vba/word,\ XFields \ XFind \ XFont \ + XContentControl \ + XContentControls \ XFormField \ XFormFields \ XFrame \ diff --git a/oovbaapi/ooo/vba/word/WdContentControlType.idl b/oovbaapi/ooo/vba/word/WdContentControlType.idl new file mode 100644 index 000000000000..d93159a07b66 --- /dev/null +++ b/oovbaapi/ooo/vba/word/WdContentControlType.idl @@ -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/. + */ + +module ooo { module vba { module word { + constants WdContentControlType { + const long wdContentControlRichText = 0; + const long wdContentControlText = 1; + const long wdContentControlPicture = 2; + const long wdContentControlComboBox = 3; + const long wdContentControlDropdownList = 4; + const long wdContentControlBuildingBlockGallery = 5; + const long wdContentControlDate = 6; + const long wdContentControlGroup = 7; + const long wdContentControlCheckbox = 8; + const long wdContentControlRepeatingSection = 9; + }; +}; }; }; + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/oovbaapi/ooo/vba/word/XContentControl.idl b/oovbaapi/ooo/vba/word/XContentControl.idl new file mode 100644 index 000000000000..e53846022786 --- /dev/null +++ b/oovbaapi/ooo/vba/word/XContentControl.idl @@ -0,0 +1,103 @@ +/* -*- 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/. + */ + +module ooo { module vba { module word { + +interface XRange; +interface XContentControlListEntries; +interface XContentControl +{ + interface ooo::vba::XHelperInterface; + + /// returns or sets whether users can add/remove sections from the specified repeating section + /// content control by using the user interface. + /// Use only with repeating section content controls. + [attribute] boolean AllowInsertDeleteSection; + /// returns or sets the appearance of the content control. + /// (wdContentControlBoundingBox/wdContentControlHidden/wdContentControlTags) + [attribute] long Appearance; + /// returns or sets a String that represents the category for a building block content control. + [attribute] string BuildingBlockCategory; + /// returns or sets a WdBuildingBlockTypes constant that represents the type of building block + /// for a building block content control. + [attribute] long BuildingBlockType; + /// returns or sets a Boolean that represents a check box's current state (checked/unchecked). + [attribute] boolean Checked; + /// returns or sets the color of the content control. + [attribute] long Color; + /// returns or sets a WdCalendarType constant that represents the calendar type. + [attribute] long DateCalendarType; + /// returns or sets a String that represents the format in which dates are displayed. + [attribute] string DateDisplayFormat; + /// returns a WdLanguageID that represents the language format for the date displayed. + [attribute, readonly] long DateDisplayLocale; + /// returns or sets a WdContentControlDateStorageFormat that represents the format for storage + /// and retrieval of dates when a date content control is bound to the XML data store. + [attribute] long DateStorageFormat; + /// returns or sets a Variant that represents the name of the character style to use to format text in a text content control. + //[attribute] string DefaultTextStyle; + /// returns a ContentControlListEntries collection that represents the items + /// in a drop-down list content control or in a combo box content control. + [attribute, readonly] any DropdownListEntries; + /// returns a String that represents the identification for a content control. + [attribute, readonly] string ID; + /// returns the level of the content control—whether the content control surrounds text, paragraphs, table cells, or table rows; or if it is inline. + /// (wdContentControlLevelCell/wdContentControlLevelInline/wdContentControlLevelParagraph/wdContentControlLevelRow) + [attribute, readonly] long Level; + /// returns or sets whether the user can delete a content control from the active document. + [attribute] boolean LockContentControl; + /// returns or sets whether the user can edit the contents of a content control. + [attribute] boolean LockContents; + /// returns or sets whether a text content control allows multiple lines of text. + [attribute] boolean MultiLine; + /// returns a ContentControl that represents the parent content control for a content control that is nested inside a rich-text control or group control. + //[attribute, readonly] XContentControl ParentContentControl; + /// returns a BuildingBlock object that represents the placeholder text for a content control. + [attribute, readonly] /*WRONG - should be XBuildingBlock*/ string PlaceholderText; + /// returns a Range that represents the contents of the content control in the active document. + [attribute, readonly] XRange Range; + /// returns the collection of repeating section items in the specified repeating section content control. + //[attribute, readonly] RepeatingSectionItems; + /// returns or sets the name of the repeating section items used in the context menu associated + /// with the specified repeating section content control. + [attribute] string RepeatingSectionItemTitle; + /// returns whether the placeholder text for the content control is displayed. + [attribute, readonly] boolean ShowingPlaceholderText; + /// returns or sets a String that represents a value to identify a content control. + [attribute] string Tag; + /// returns or sets whether to remove a content control from the active document + /// when the user edits the contents of the control. + [attribute] boolean Temporary; + /// returns or sets a String that represents the title for a content control. + [attribute] string Title; + /// returns or sets a WdContentControlType that represents the type for a content control. + [attribute] long Type; + /// returns an XMLMapping object that represents the mapping of a content control to XML data in the data store of a document. + //[attribute, readonly] XMLMapping; + + /// Copies the content control from the active document to the Clipboard. + void Copy(); + /// Removes the content control from the active document and moves it to the Clipboard. + void Cut(); + /// Deletes the specified content control and the contents of the content control. + void Delete( [in] /*optional*/ any bDeleteContents ); + /// Sets the symbol used to represent the checked state of a check box content control. + void SetCheckedSymbol( [in] long Character, [in] /*optional*/ any sFont ); + /// Sets the symbol used to represent the unchecked state of a check box content control. + void SetUnCheckedSymbol( [in] long Character, [in] /*optional*/ any sFont ); + /// Sets the placeholder text that displays until a user enters their own text. + void SetPlaceholderText( [in] /*optional*/ any BuildingBlock, [in] /*optional*/ any Range, [in] /*optional*/ any sFont ); + /// Removes a group content control. Its children are no longer nested and can be freely edited. + void Ungroup(); + +}; + +}; }; }; + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/oovbaapi/ooo/vba/word/XContentControls.idl b/oovbaapi/ooo/vba/word/XContentControls.idl new file mode 100644 index 000000000000..49facea70b40 --- /dev/null +++ b/oovbaapi/ooo/vba/word/XContentControls.idl @@ -0,0 +1,23 @@ +/* -*- 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/. + */ + +module ooo { module vba { module word { + +interface XContentControl; +interface XContentControls +{ + interface ::ooo::vba::XCollection; + + /// Returns a ContentControl object that represents a new WdContentControlType added at a range + //XContentControl Add( [in] /*optional*/ any Type, [in] /*optional*/ any Range ) raises ( com::sun::star::script::BasicErrorException ); +}; + +}; }; }; + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/oovbaapi/ooo/vba/word/XDocument.idl b/oovbaapi/ooo/vba/word/XDocument.idl index 0f7b5f994aa1..354cac11b2ed 100644 --- a/oovbaapi/ooo/vba/word/XDocument.idl +++ b/oovbaapi/ooo/vba/word/XDocument.idl @@ -37,6 +37,9 @@ interface XDocument any BuiltInDocumentProperties( [in] any Index ); any CustomDocumentProperties( [in] any Index ); any Bookmarks( [in] any Index ); + any ContentControls( [in] any Index ); + any SelectContentControlsByTag( [in] any Index ); + any SelectContentControlsByTitle( [in] any Index ); any Variables( [in] any Index ); any Paragraphs( [in] any Index ); any Styles( [in] any Index ) raises (com::sun::star::script::BasicErrorException); diff --git a/sw/Library_vbaswobj.mk b/sw/Library_vbaswobj.mk index 1b0ca044d565..e6b45b4e2f37 100644 --- a/sw/Library_vbaswobj.mk +++ b/sw/Library_vbaswobj.mk @@ -72,6 +72,8 @@ $(eval $(call gb_Library_add_exception_objects,vbaswobj,\ sw/source/ui/vba/vbacells \ sw/source/ui/vba/vbacolumn \ sw/source/ui/vba/vbacolumns \ + sw/source/ui/vba/vbacontentcontrol \ + sw/source/ui/vba/vbacontentcontrols \ sw/source/ui/vba/vbaformfield \ sw/source/ui/vba/vbaformfields \ sw/source/ui/vba/vbaformfieldcheckbox \ diff --git a/sw/qa/core/data/docm/testModernVBA.docm b/sw/qa/core/data/docm/testModernVBA.docm Binary files differnew file mode 100644 index 000000000000..faa85768884b --- /dev/null +++ b/sw/qa/core/data/docm/testModernVBA.docm diff --git a/sw/qa/core/macros-test.cxx b/sw/qa/core/macros-test.cxx index a4030b08937e..df562126cc27 100644 --- a/sw/qa/core/macros-test.cxx +++ b/sw/qa/core/macros-test.cxx @@ -91,6 +91,10 @@ void SwMacrosTest::testVba() OUString("vnd.sun.Star.script:Project.ThisDocument.testAll?language=Basic&location=document") }, { + OUString("testModernVBA.docm"), + OUString("vnd.sun.Star.script:Project.ThisDocument.testAll?language=Basic&location=document") + }, + { OUString("testFind.docm"), OUString("vnd.sun.Star.script:Project.Module1.testAll?language=Basic&location=document") }, diff --git a/sw/source/ui/vba/vbacontentcontrol.cxx b/sw/source/ui/vba/vbacontentcontrol.cxx new file mode 100644 index 000000000000..3d51d8bd4448 --- /dev/null +++ b/sw/source/ui/vba/vbacontentcontrol.cxx @@ -0,0 +1,754 @@ +/* -*- 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 <ooo/vba/word/WdColor.hpp> +#include <ooo/vba/word/WdCalendarType.hpp> +#include <ooo/vba/word/WdContentControlType.hpp> +#include <ooo/vba/word/WdLanguageID.hpp> + +#include <sal/log.hxx> + +#include <ndtxt.hxx> + +#include "vbacontentcontrol.hxx" +//#include "vbacontentcontroldropdownlistentries.hxx" + +using namespace ::ooo::vba; +using namespace ::com::sun::star; + +/** + * Content controls are the modern version of FormFields, providing inline functionality similar + * to that of ActiveX form controls. Individual content controls may contain contents + * such as dates, lists, or paragraphs of formatted text. + * + * Not all functions are applicable to each type of control, so use getType verification liberally. + */ +SwVbaContentControl::SwVbaContentControl(const uno::Reference<XHelperInterface>& rParent, + const uno::Reference<uno::XComponentContext>& rContext, + const uno::Reference<text::XTextDocument>& xTextDocument, + SwTextContentControl& rContentControl) + : SwVbaContentControl_BASE(rParent, rContext) + , mxTextDocument(xTextDocument) + , m_rCC(rContentControl) +{ +} + +SwVbaContentControl::~SwVbaContentControl() {} + +sal_Bool SwVbaContentControl::getAllowInsertDeleteSection() +{ + SAL_INFO("sw.vba", "SwVbaContentControl::getAllowInsertDeleteSection stub"); + return false; +} + +void SwVbaContentControl::setAllowInsertDeleteSection(sal_Bool /*bSet*/) +{ + SAL_INFO("sw.vba", "SwVbaContentControl::setAllowInsertDeleteSection stub"); +} + +sal_Int32 SwVbaContentControl::getAppearance() +{ + SAL_INFO("sw.vba", "SwVbaContentControl::getAppearance stub"); + // wdContentControlBoundingBox / wdContentControlHidden / wdContentControlTags + return 0; +} + +void SwVbaContentControl::setAppearance(sal_Int32 nSet) +{ + SAL_INFO("sw.vba", "SwVbaContentControl::setAppearance[" << nSet << "] stub"); +} + +OUString SwVbaContentControl::getBuildingBlockCategory() +{ + SAL_INFO("sw.vba", "SwVbaContentControl::getBuildingBlockCategory stub"); + return OUString(); +} + +void SwVbaContentControl::setBuildingBlockCategory(const OUString& sSet) +{ + SAL_INFO("sw.vba", "SwVbaContentControl::setBuildingBlockCategory[" << sSet << "] stub"); +} + +sal_Int32 SwVbaContentControl::getBuildingBlockType() +{ + SAL_INFO("sw.vba", "SwVbaContentControl::getBuildingBlockType stub"); + // returns a WdBuildingBlockTypes that represents the type of building block + return 0; +} + +void SwVbaContentControl::setBuildingBlockType(sal_Int32 nSet) +{ + SAL_INFO("sw.vba", "SwVbaContentControl::setBuildingBlockType[" << nSet << "] stub"); +} + +sal_Bool SwVbaContentControl::getChecked() +{ + const std::shared_ptr<SwContentControl>& pCC = m_rCC.GetContentControl().GetContentControl(); + return pCC->GetCheckbox() && pCC->GetChecked(); +} + +void SwVbaContentControl::setChecked(sal_Bool bSet) +{ + std::shared_ptr<SwContentControl> pCC = m_rCC.GetContentControl().GetContentControl(); + if (pCC->GetCheckbox() && pCC->GetChecked() != static_cast<bool>(bSet)) + { + pCC->SetChecked(bSet); + //pCC->Invalidate(); + } +} + +sal_Int32 SwVbaContentControl::getColor() +{ + const std::shared_ptr<SwContentControl>& pCC = m_rCC.GetContentControl().GetContentControl(); + //This is just an assumed implementation - I have no testing environment to confirm. + OUString sColor = pCC->GetColor(); + if (sColor == "wdColorAutomatic") + return word::WdColor::wdColorAutomatic; + if (sColor == "wdColorBlack") + return word::WdColor::wdColorBlack; + if (sColor == "wdColorBlue") + return word::WdColor::wdColorBlue; + if (sColor == "wdColorBlueGray") + return word::WdColor::wdColorBlueGray; + if (sColor == "wdColorBrightGreen") + return word::WdColor::wdColorBrightGreen; + if (sColor == "wdColorBrown") + return word::WdColor::wdColorBrown; + if (sColor == "wdColorDarkBlue") + return word::WdColor::wdColorDarkBlue; + if (sColor == "wdColorDarkGreen") + return word::WdColor::wdColorDarkGreen; + if (sColor == "wdColorDarkRed") + return word::WdColor::wdColorDarkRed; + if (sColor == "wdColorDarkTeal") + return word::WdColor::wdColorDarkTeal; + if (sColor == "wdColorDarkYellow") + return word::WdColor::wdColorDarkYellow; + if (sColor == "wdColorGold") + return word::WdColor::wdColorGold; + if (sColor == "wdColorGray05") + return word::WdColor::wdColorGray05; + if (sColor == "wdColorGray10") + return word::WdColor::wdColorGray10; + if (sColor == "wdColorGray125") + return word::WdColor::wdColorGray125; + if (sColor == "wdColorGray15") + return word::WdColor::wdColorGray15; + if (sColor == "wdColorGray20") + return word::WdColor::wdColorGray20; + if (sColor == "wdColorGray25") + return word::WdColor::wdColorGray25; + if (sColor == "wdColorGray30") + return word::WdColor::wdColorGray30; + if (sColor == "wdColorGray35") + return word::WdColor::wdColorGray35; + if (sColor == "wdColorGray375") + return word::WdColor::wdColorGray375; + if (sColor == "wdColorGray40") + return word::WdColor::wdColorGray40; + if (sColor == "wdColorGray45") + return word::WdColor::wdColorGray45; + if (sColor == "wdColorGray50") + return word::WdColor::wdColorGray50; + if (sColor == "wdColorGray55") + return word::WdColor::wdColorGray55; + if (sColor == "wdColorGray60") + return word::WdColor::wdColorGray60; + if (sColor == "wdColorGray625") + return word::WdColor::wdColorGray625; + if (sColor == "wdColorGray65") + return word::WdColor::wdColorGray65; + if (sColor == "wdColorGray70") + return word::WdColor::wdColorGray70; + if (sColor == "wdColorGray75") + return word::WdColor::wdColorGray75; + if (sColor == "wdColorGray80") + return word::WdColor::wdColorGray80; + if (sColor == "wdColorGray85") + return word::WdColor::wdColorGray85; + if (sColor == "wdColorGray875") + return word::WdColor::wdColorGray875; + if (sColor == "wdColorGray90") + return word::WdColor::wdColorGray90; + if (sColor == "wdColorGray95") + return word::WdColor::wdColorGray95; + if (sColor == "wdColorGreen") + return word::WdColor::wdColorGreen; + if (sColor == "wdColorIndigo") + return word::WdColor::wdColorIndigo; + if (sColor == "wdColorLavender") + return word::WdColor::wdColorLavender; + if (sColor == "wdColorLightBlue") + return word::WdColor::wdColorLightBlue; + if (sColor == "wdColorLightGreen") + return word::WdColor::wdColorLightGreen; + if (sColor == "wdColorLightOrange") + return word::WdColor::wdColorLightOrange; + if (sColor == "wdColorLightTurquoise") + return word::WdColor::wdColorLightTurquoise; + if (sColor == "wdColorLightYellow") + return word::WdColor::wdColorLightYellow; + if (sColor == "wdColorLime") + return word::WdColor::wdColorLime; + if (sColor == "wdColorOliveGreen") + return word::WdColor::wdColorOliveGreen; + if (sColor == "wdColorOrange") + return word::WdColor::wdColorOrange; + if (sColor == "wdColorPaleBlue") + return word::WdColor::wdColorPaleBlue; + if (sColor == "wdColorPink") + return word::WdColor::wdColorPink; + if (sColor == "wdColorPlum") + return word::WdColor::wdColorPlum; + if (sColor == "wdColorRed") + return word::WdColor::wdColorRed; + if (sColor == "wdColorRose") + return word::WdColor::wdColorRose; + if (sColor == "wdColorSeaGreen") + return word::WdColor::wdColorSeaGreen; + if (sColor == "wdColorSkyBlue") + return word::WdColor::wdColorSkyBlue; + if (sColor == "wdColorTan") + return word::WdColor::wdColorTan; + if (sColor == "wdColorTeal") + return word::WdColor::wdColorTeal; + if (sColor == "wdColorTurquoise") + return word::WdColor::wdColorTurquoise; + if (sColor == "wdColorViolet") + return word::WdColor::wdColorViolet; + if (sColor == "wdColorWhite") + return word::WdColor::wdColorWhite; + if (sColor == "wdColorYellow") + return word::WdColor::wdColorYellow; + + return word::WdColor::wdColorBlack; +} + +void SwVbaContentControl::setColor(sal_Int32 nWdColor) +{ + std::shared_ptr<SwContentControl> pCC = m_rCC.GetContentControl().GetContentControl(); + + switch (nWdColor) + { + case word::WdColor::wdColorAqua: + pCC->SetColor("wdColorAqua"); + break; + case word::WdColor::wdColorAutomatic: + pCC->SetColor("wdColorAutomatic"); + break; + case word::WdColor::wdColorBlack: + pCC->SetColor("wdColorBlack"); + break; + case word::WdColor::wdColorBlue: + pCC->SetColor("wdColorBlue"); + break; + case word::WdColor::wdColorBlueGray: + pCC->SetColor("wdColorBlueGray"); + break; + case word::WdColor::wdColorBrightGreen: + pCC->SetColor("wdColorBrightGreen"); + break; + case word::WdColor::wdColorBrown: + pCC->SetColor("wdColorBrown"); + break; + case word::WdColor::wdColorDarkBlue: + pCC->SetColor("wdColorDarkBlue"); + break; + case word::WdColor::wdColorDarkGreen: + pCC->SetColor("wdColorDarkGreen"); + break; + case word::WdColor::wdColorDarkRed: + pCC->SetColor("wdColorDarkRed"); + break; + case word::WdColor::wdColorDarkTeal: + pCC->SetColor("wdColorDarkTeal"); + break; + case word::WdColor::wdColorDarkYellow: + pCC->SetColor("wdColorDarkYellow"); + break; + case word::WdColor::wdColorGold: + pCC->SetColor("wdColorGold"); + break; + case word::WdColor::wdColorGray05: + pCC->SetColor("wdColorGray05"); + break; + case word::WdColor::wdColorGray10: + pCC->SetColor("wdColorGray10"); + break; + case word::WdColor::wdColorGray125: + pCC->SetColor("wdColorGray125"); + break; + case word::WdColor::wdColorGray15: + pCC->SetColor("wdColorGray15"); + break; + case word::WdColor::wdColorGray20: + pCC->SetColor("wdColorGray20"); + break; + case word::WdColor::wdColorGray25: + pCC->SetColor("wdColorGray25"); + break; + case word::WdColor::wdColorGray30: + pCC->SetColor("wdColorGray30"); + break; + case word::WdColor::wdColorGray35: + pCC->SetColor("wdColorGray35"); + break; + case word::WdColor::wdColorGray375: + pCC->SetColor("wdColorGray375"); + break; + case word::WdColor::wdColorGray40: + pCC->SetColor("wdColorGray40"); + break; + case word::WdColor::wdColorGray45: + pCC->SetColor("wdColorGray45"); + break; + case word::WdColor::wdColorGray50: + pCC->SetColor("wdColorGray50"); + break; + case word::WdColor::wdColorGray55: + pCC->SetColor("wdColorGray55"); + break; + case word::WdColor::wdColorGray60: + pCC->SetColor("wdColorGray60"); + break; + case word::WdColor::wdColorGray625: + pCC->SetColor("wdColorGray625"); + break; + case word::WdColor::wdColorGray65: + pCC->SetColor("wdColorGray65"); + break; + case word::WdColor::wdColorGray70: + pCC->SetColor("wdColorGray70"); + break; + case word::WdColor::wdColorGray75: + pCC->SetColor("wdColorGray75"); + break; + case word::WdColor::wdColorGray80: + pCC->SetColor("wdColorGray80"); + break; + case word::WdColor::wdColorGray85: + pCC->SetColor("wdColorGray85"); + break; + case word::WdColor::wdColorGray875: + pCC->SetColor("wdColorGray875"); + break; + case word::WdColor::wdColorGray90: + pCC->SetColor("wdColorGray90"); + break; + case word::WdColor::wdColorGray95: + pCC->SetColor("wdColorGray95"); + break; + case word::WdColor::wdColorGreen: + pCC->SetColor("wdColorGreen"); + break; + case word::WdColor::wdColorIndigo: + pCC->SetColor("wdColorIndigo"); + break; + case word::WdColor::wdColorLavender: + pCC->SetColor("wdColorLavender"); + break; + case word::WdColor::wdColorLightBlue: + pCC->SetColor("wdColorLightBlue"); + break; + case word::WdColor::wdColorLightGreen: + pCC->SetColor("wdColorLightGreen"); + break; + case word::WdColor::wdColorLightOrange: + pCC->SetColor("wdColorLightOrange"); + break; + case word::WdColor::wdColorLightTurquoise: + pCC->SetColor("wdColorLightTurquoise"); + break; + case word::WdColor::wdColorLightYellow: + pCC->SetColor("wdColorLightYellow"); + break; + case word::WdColor::wdColorLime: + pCC->SetColor("wdColorLime"); + break; + case word::WdColor::wdColorOliveGreen: + pCC->SetColor("wdColorOliveGreen"); + break; + case word::WdColor::wdColorOrange: + pCC->SetColor("wdColorOrange"); + break; + case word::WdColor::wdColorPaleBlue: + pCC->SetColor("wdColorPaleBlue"); + break; + case word::WdColor::wdColorPink: + pCC->SetColor("wdColorPink"); + break; + case word::WdColor::wdColorPlum: + pCC->SetColor("wdColorPlum"); + break; + case word::WdColor::wdColorRed: + pCC->SetColor("wdColorRed"); + break; + case word::WdColor::wdColorRose: + pCC->SetColor("wdColorRose"); + break; + case word::WdColor::wdColorSeaGreen: + pCC->SetColor("wdColorSeaGreen"); + break; + case word::WdColor::wdColorSkyBlue: + pCC->SetColor("wdColorSkyBlue"); + break; + case word::WdColor::wdColorTan: + pCC->SetColor("wdColorTan"); + break; + case word::WdColor::wdColorTeal: + pCC->SetColor("wdColorTeal"); + break; + case word::WdColor::wdColorTurquoise: + pCC->SetColor("wdColorTurquoise"); + break; + case word::WdColor::wdColorViolet: + pCC->SetColor("wdColorViolet"); + break; + case word::WdColor::wdColorWhite: + pCC->SetColor("wdColorWhite"); + break; + default:; + } +} + +sal_Int32 SwVbaContentControl::getDateCalendarType() +{ + SAL_INFO("sw.vba", "SwVbaContentControl::getDateCalendarType stub"); + // returns a WdCalendarTypes that represents the type of building block + return word::WdCalendarType::wdCalendarWestern; +} + +void SwVbaContentControl::setDateCalendarType(sal_Int32 nSet) +{ + SAL_INFO("sw.vba", "SwVbaContentControl::setDateCalendarType[" << nSet << "] stub"); +} + +OUString SwVbaContentControl::getDateDisplayFormat() +{ + const std::shared_ptr<SwContentControl>& pCC = m_rCC.GetContentControl().GetContentControl(); + return pCC->GetDateFormat(); +} + +void SwVbaContentControl::setDateDisplayFormat(const OUString& sSet) +{ + std::shared_ptr<SwContentControl> pCC = m_rCC.GetContentControl().GetContentControl(); + pCC->SetDateFormat(sSet); +} + +sal_Int32 SwVbaContentControl::getDateStorageFormat() +{ + SAL_INFO("sw.vba", "SwVbaContentControl::getDateStorageFormat stub"); + // returns a WdContentControlDateStorageFormat when bound to the XML data store. + return 0; +} + +void SwVbaContentControl::setDateStorageFormat(sal_Int32 nSet) +{ + SAL_INFO("sw.vba", "SwVbaContentControl::setDateStorageFormat[" << nSet << "] stub"); +} + +sal_Int32 SwVbaContentControl::getDateDisplayLocale() +{ + SAL_INFO("sw.vba", "SwVbaContentControl::getDateDisplayLocale stub"); + // returns a WdLanguageID that represents the language format for a date content control. + return word::WdLanguageID::wdEnglishUS; +} + +uno::Any SwVbaContentControl::getDropdownListEntries() +{ + std::shared_ptr<SwContentControl> pCC = m_rCC.GetContentControl().GetContentControl(); + //if (!pCC->GetDropDown() && !pCC->GetComboBox()) + // return uno::Any(); + //return uno::Any(uno::Reference<XCollection>( + // new SwVbaContentControlDropDownListEntries(this, mxContext, m_rCC))); + return uno::Any(); +} + +OUString SwVbaContentControl::getID() +{ + //const std::shared_ptr<SwContentControl>& pCC = m_rCC.GetContentControl().GetContentControl(); + //return OUString::number(static_cast<sal_uInt32>(pCC->GetId())); + return OUString(); +} + +sal_Int32 SwVbaContentControl::getLevel() +{ + SAL_INFO("sw.vba", "SwVbaContentControl::getLevel stub"); + // returns a WdContentControlLevel + return 0; +} + +sal_Bool SwVbaContentControl::getLockContentControl() +{ + SAL_INFO("sw.vba", "SwVbaContentControl::getLockContentControl stub"); + // returns whether the user can delete a content control from the active document. + return true; +} + +void SwVbaContentControl::setLockContentControl(sal_Bool /*bSet*/) +{ + SAL_INFO("sw.vba", "SwVbaContentControl::setLockContentControl stub"); +} + +sal_Bool SwVbaContentControl::getLockContents() +{ + // Pseudo-implementation - the need for locking in a form would be very rare. + // LO uses this for internal purposes. Only expose it to VBA when safe. + const std::shared_ptr<SwContentControl>& pCC = m_rCC.GetContentControl().GetContentControl(); + // Checkbox/DropDown/Picture are normally locked - but not in this sense. Report as unlocked. + if (pCC->GetType() == SwContentControlType::CHECKBOX + || pCC->GetType() == SwContentControlType::DROP_DOWN_LIST + || pCC->GetType() == SwContentControlType::PICTURE) + { + return false; + } + + return pCC->GetReadWrite(); +} + +void SwVbaContentControl::setLockContents(sal_Bool bSet) +{ + std::shared_ptr<SwContentControl> pCC = m_rCC.GetContentControl().GetContentControl(); + // Checkbox/DropDown/Picture are normally locked in LO implementation - don't unlock them. + if (pCC->GetType() == SwContentControlType::CHECKBOX + || pCC->GetType() == SwContentControlType::DROP_DOWN_LIST + || pCC->GetType() == SwContentControlType::PICTURE) + { + return; + } + pCC->SetReadWrite(bSet); +} + +sal_Bool SwVbaContentControl::getMultiLine() +{ + SAL_INFO("sw.vba", "SwVbaContentControl::getMultiLine stub"); + return false; +} + +void SwVbaContentControl::setMultiLine(sal_Bool /*bSet*/) +{ + SAL_INFO("sw.vba", "SwVbaContentControl::setMultiLine stub"); +} + +OUString SwVbaContentControl::getPlaceholderText() +{ + // return pCC->GetPlaceholderDocPart(); // This is not correct. Much more complex than this... + SAL_INFO("sw.vba", "SwVbaContentControl::getPlaceholderText stub"); + return OUString(); +} + +sal_Bool SwVbaContentControl::getShowingPlaceholderText() +{ + const std::shared_ptr<SwContentControl>& pCC = m_rCC.GetContentControl().GetContentControl(); + return pCC->GetShowingPlaceHolder(); +} + +uno::Reference<word::XRange> SwVbaContentControl::getRange() +{ + SAL_INFO("sw.vba", "SwVbaContentControl::getRange stub"); + return uno::Reference<word::XRange>(); +} + +OUString SwVbaContentControl::getRepeatingSectionItemTitle() +{ + SAL_INFO("sw.vba", "SwVbaContentControl::getRepeatingSectionItemTitle stub"); + return OUString(); +} + +void SwVbaContentControl::setRepeatingSectionItemTitle(const OUString& rSet) +{ + SAL_INFO("sw.vba", "SwVbaContentControl::setRepeatingSectionItemTitle[" << rSet << "] stub"); +} + +OUString SwVbaContentControl::getTag() +{ + const std::shared_ptr<SwContentControl>& pCC = m_rCC.GetContentControl().GetContentControl(); + return pCC->GetTag(); +} + +void SwVbaContentControl::setTag(const OUString& rSet) +{ + std::shared_ptr<SwContentControl> pCC = m_rCC.GetContentControl().GetContentControl(); + return pCC->SetTag(rSet); +} + +sal_Bool SwVbaContentControl::getTemporary() +{ + SAL_INFO("sw.vba", "SwVbaContentControl::getTemporary stub"); + // Is content control removed when user edits (one time use)? Not implemented in LO. + return false; +} + +void SwVbaContentControl::setTemporary(sal_Bool /*bSet*/) +{ + SAL_INFO("sw.vba", "SwVbaContentControl::setTemporary stub"); +} + +OUString SwVbaContentControl::getTitle() +{ + const std::shared_ptr<SwContentControl>& pCC = m_rCC.GetContentControl().GetContentControl(); + return pCC->GetAlias(); +} + +void SwVbaContentControl::setTitle(const OUString& rSet) +{ + std::shared_ptr<SwContentControl> pCC = m_rCC.GetContentControl().GetContentControl(); + return pCC->SetAlias(rSet); +} + +sal_Int32 SwVbaContentControl::getType() +{ + const std::shared_ptr<SwContentControl>& pCC = m_rCC.GetContentControl().GetContentControl(); + SwContentControlType eType = pCC->GetType(); + sal_Int32 eVbaType = word::WdContentControlType::wdContentControlRichText; + + switch (eType) + { + case SwContentControlType::CHECKBOX: + eVbaType = word::WdContentControlType::wdContentControlCheckbox; + break; + case SwContentControlType::DROP_DOWN_LIST: + eVbaType = word::WdContentControlType::wdContentControlDropdownList; + break; + case SwContentControlType::PICTURE: + eVbaType = word::WdContentControlType::wdContentControlPicture; + break; + case SwContentControlType::DATE: + eVbaType = word::WdContentControlType::wdContentControlDate; + break; + case SwContentControlType::PLAIN_TEXT: + eVbaType = word::WdContentControlType::wdContentControlText; + break; + case SwContentControlType::COMBO_BOX: + eVbaType = word::WdContentControlType::wdContentControlComboBox; + break; + case SwContentControlType::RICH_TEXT: + default:; + } + return eVbaType; +} + +void SwVbaContentControl::setType(sal_Int32 nSet) +{ + SAL_INFO("sw.vba", "SwVbaContentControl::setType[" << nSet << "] stub"); + // std::shared_ptr<SwContentControl> pCC = m_rCC.GetContentControl().GetContentControl(); + // SwContentControlType eType = SwContentControlType::RICH_TEXT; + // switch(nSet) + // { + // case word::WdContentControlType::wdContentControlCheckbox: + // eType = SwContentControlType::CHECKBOX; + // break; + // case word::WdContentControlType::wdContentControlDropdownList: + // eType = SwContentControlType::DROP_DOWN_LIST; + // break; + // case word::WdContentControlType::wdContentControlPicture: + // eType = SwContentControlType::PICTURE; + // break; + // case word::WdContentControlType::wdContentControlDate: + // eType = SwContentControlType::DATE; + // break; + // case word::WdContentControlType::wdContentControlText: + // eType = SwContentControlType::PLAIN_TEXT; + // break; + // case word::WdContentControlType::wdContentControlComboBox: + // eType = SwContentControlType::COMBO_BOX; + // break; + // case word::WdContentControlType::wdContentControlRichText: + // default:; + // } + // pCC->SetType(eType); +} + +void SwVbaContentControl::Copy() +{ + SAL_INFO("sw.vba", "SwVbaContentControl::Copy[" << getID() << "] stub"); +} + +void SwVbaContentControl::Cut() +{ + SAL_INFO("sw.vba", + "SwVbaContentControl::Cut[" << getID() << "], but missing sending to clipboard"); + + Delete(uno::Any(false)); +} + +void SwVbaContentControl::Delete(const uno::Any& DeleteContents) +{ + bool bDeleteContents = false; + DeleteContents >>= bDeleteContents; + SAL_INFO("sw.vba", "SwVbaContentControl::Delete[" << DeleteContents << "] stub"); + //m_rCC.ChgTextNode(nullptr); // works, but crashes on UI touch - probably requires invalidation +} + +void SwVbaContentControl::SetCheckedSymbol(sal_Int32 Character, const uno::Any& Font) +{ + SAL_INFO_IF(Font.hasValue(), "sw.vba", "SetCheckedSymbol Font[" << Font << "] stub"); + if (Character < 31 || Character > SAL_MAX_UINT16) + return; // unsupported character. Would such a thing exist in VBA? + + std::shared_ptr<SwContentControl> pCC = m_rCC.GetContentControl().GetContentControl(); + pCC->SetCheckedState(OUString(static_cast<sal_Unicode>(Character))); + //if (getChecked()) + // pCC->Invalidate(); +} + +void SwVbaContentControl::SetUnCheckedSymbol(sal_Int32 Character, const uno::Any& Font) +{ + SAL_INFO_IF(Font.hasValue(), "sw.vba", "SetUnCheckedSymbol Font[" << Font << "] stub"); + if (Character < 31 || Character > SAL_MAX_UINT16) + return; // unsupported character. Would such a thing exist in VBA? + + std::shared_ptr<SwContentControl> pCC = m_rCC.GetContentControl().GetContentControl(); + pCC->SetUncheckedState(OUString(static_cast<sal_Unicode>(Character))); + //if (!getChecked()) + // pCC->Invalidate(); +} + +void SwVbaContentControl::SetPlaceholderText(const uno::Any& BuildingBlock, const uno::Any& Range, + const uno::Any& Text) +{ + SAL_INFO("sw.vba", "SwVbaContentControl::SetPlaceholderText stub"); + std::shared_ptr<SwContentControl> pCC = m_rCC.GetContentControl().GetContentControl(); + if (BuildingBlock.hasValue()) + { + // Set placeholder text to the building block - whatever that is. + } + else if (Range.hasValue()) + { + // Set placeholder text to the contents of the Range, however you do that. + } + else if (Text.hasValue()) + { + // Set placeholder text to the provided string + } + else + { + // Remove placeholder text. + pCC->SetPlaceholderDocPart(""); + } + //if (getShowingPlaceholderText()) + //{ + // if (!pCC->GetCheckbox()) + // pCC->Invalidate(); + // // Ensure that invalidation doesn't turn off showing placeholder as true + // pCC->SetShowingPlaceHolder(true); + //} +} + +void SwVbaContentControl::Ungroup() { SAL_INFO("sw.vba", "SwVbaContentControl::UnGroup stub"); } + +OUString SwVbaContentControl::getServiceImplName() { return "SwVbaContentControl"; } + +uno::Sequence<OUString> SwVbaContentControl::getServiceNames() +{ + static uno::Sequence<OUString> const aServiceNames{ "ooo.vba.word.ContentControl" }; + return aServiceNames; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/ui/vba/vbacontentcontrol.hxx b/sw/source/ui/vba/vbacontentcontrol.hxx new file mode 100644 index 000000000000..e5fa927e36fa --- /dev/null +++ b/sw/source/ui/vba/vbacontentcontrol.hxx @@ -0,0 +1,142 @@ +/* -*- 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 <com/sun/star/text/XTextDocument.hpp> +#include <ooo/vba/word/XContentControl.hpp> + +#include <vbahelper/vbahelperinterface.hxx> + +#include <textcontentcontrol.hxx> + +typedef InheritedHelperInterfaceWeakImpl<ooo::vba::word::XContentControl> SwVbaContentControl_BASE; + +class SwVbaContentControl : public SwVbaContentControl_BASE +{ +private: + css::uno::Reference<css::text::XTextDocument> mxTextDocument; + SwTextContentControl& m_rCC; + +public: + /// @throws css::uno::RuntimeException + SwVbaContentControl(const css::uno::Reference<ooo::vba::XHelperInterface>& rParent, + const css::uno::Reference<css::uno::XComponentContext>& rContext, + const css::uno::Reference<css::text::XTextDocument>& xTextDocument, + SwTextContentControl& rContentControl); + ~SwVbaContentControl() override; + + // XContentControl Properties + sal_Bool SAL_CALL getAllowInsertDeleteSection() override; + void SAL_CALL setAllowInsertDeleteSection(sal_Bool bSet) override; + + sal_Int32 SAL_CALL getAppearance() override; + void SAL_CALL setAppearance(sal_Int32 nSet) override; + + OUString SAL_CALL getBuildingBlockCategory() override; + void SAL_CALL setBuildingBlockCategory(const OUString& sSet) override; + + sal_Int32 SAL_CALL getBuildingBlockType() override; + void SAL_CALL setBuildingBlockType(sal_Int32 nSet) override; + + sal_Bool SAL_CALL getChecked() override; + void SAL_CALL setChecked(sal_Bool bSet) override; + + // returns or sets a WdColor (@since after 2010 I assume) + sal_Int32 SAL_CALL getColor() override; + void SAL_CALL setColor(sal_Int32 nSet) override; + + sal_Int32 SAL_CALL getDateCalendarType() override; + void SAL_CALL setDateCalendarType(sal_Int32 nSet) override; + + OUString SAL_CALL getDateDisplayFormat() override; + void SAL_CALL setDateDisplayFormat(const OUString& sSet) override; + + sal_Int32 SAL_CALL getDateDisplayLocale() override; + + sal_Int32 SAL_CALL getDateStorageFormat() override; + void SAL_CALL setDateStorageFormat(sal_Int32 nSet) override; + + css::uno::Any SAL_CALL getDropdownListEntries() override; + + // This is an integer used as a unique indentifier string + OUString SAL_CALL getID() override; + + sal_Int32 SAL_CALL getLevel() override; + + // returns or sets if the user can delete the control + sal_Bool SAL_CALL getLockContentControl() override; + void SAL_CALL setLockContentControl(sal_Bool bSet) override; + + // returns or sets if the user can edit the contents (i.e. read-only flag) + sal_Bool SAL_CALL getLockContents() override; + void SAL_CALL setLockContents(sal_Bool bSet) override; + + sal_Bool SAL_CALL getMultiLine() override; + void SAL_CALL setMultiLine(sal_Bool bSet) override; + + // WRONG- THIS SHOULD RETURN XBUILDINGBLOCK + OUString SAL_CALL getPlaceholderText() override; + + sal_Bool SAL_CALL getShowingPlaceholderText() override; + + OUString SAL_CALL getRepeatingSectionItemTitle() override; + void SAL_CALL setRepeatingSectionItemTitle(const OUString& rSet) override; + + css::uno::Reference<ooo::vba::word::XRange> SAL_CALL getRange() override; + + OUString SAL_CALL getTag() override; + void SAL_CALL setTag(const OUString& rSet) override; + + // returns or sets if the control is removed after accepting user change (i.e. control -> text) + sal_Bool SAL_CALL getTemporary() override; + void SAL_CALL setTemporary(sal_Bool bSet) override; + + OUString SAL_CALL getTitle() override; + void SAL_CALL setTitle(const OUString& rSet) override; + + // returns or sets a WdContentControlType that represents the type for a content control. + sal_Int32 SAL_CALL getType() override; + void SAL_CALL setType(sal_Int32 nSet) override; + + // XContentControl Methods + + // Copies the content control from the active document to the Clipboard. + // Retreive from the clipboard using the Paste method of the Selection object + // or of the Range object, or use the Paste function from within Microsoft Word. + void SAL_CALL Copy() override; + + // Removes the control from the active document and moves it to the Clipboard. + void SAL_CALL Cut() override; + + // Specifies whether to delete the contents of the content control. The default value is False. + // True removes both the content control and its contents. + // False removes the control but leaves the contents of the content control in the document. + void SAL_CALL Delete(const css::uno::Any& bDeleteContents) override; + + // Set the Unicode character used to display the checked state. + void SAL_CALL SetCheckedSymbol(sal_Int32 Character, const css::uno::Any& sFont) override; + + // Set the Unicode character used to display the unchecked state. + void SAL_CALL SetUnCheckedSymbol(sal_Int32 Character, const css::uno::Any& sFont) override; + + // Sets the placeholder text that displays until a user enters their own text. + // Only one of the parameters is used when specifying placeholder text. + // If more than one parameter is provided, use the text specified in the first parameter. + // If all parameters are omitted, the placeholder text is blank. + void SAL_CALL SetPlaceholderText(const css::uno::Any& BuildingBlock, const css::uno::Any& Range, + const css::uno::Any& sText) override; + + void SAL_CALL Ungroup() override; + + // XHelperInterface + OUString getServiceImplName() override; + css::uno::Sequence<OUString> getServiceNames() override; +}; + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/ui/vba/vbacontentcontrols.cxx b/sw/source/ui/vba/vbacontentcontrols.cxx new file mode 100644 index 000000000000..549541cb7c61 --- /dev/null +++ b/sw/source/ui/vba/vbacontentcontrols.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 <comphelper/sequence.hxx> +#include <sal/log.hxx> + +#include <doc.hxx> +#include <docsh.hxx> +#include <textcontentcontrol.hxx> + +#include "vbacontentcontrol.hxx" +#include "vbacontentcontrols.hxx" +#include "wordvbahelper.hxx" + +using namespace ::ooo::vba; +using namespace ::com::sun::star; + +// Helper function to access the content controls +// @param rIndex +// [in] negative indexes indicate the need to search by name, otherwise get by index, +// using SAL_MAX_INT32 to indicate the need to just get the total count. +// [out] rIndex indicates the found index, or the total number of content controls +static SwTextContentControl* +lcl_getContentControl(std::u16string_view sName, std::u16string_view sTag, + std::u16string_view sTitle, sal_Int32& rIndex, + const uno::Reference<text::XTextDocument>& xTextDocument, + uno::Sequence<OUString>* pElementNames = nullptr) +{ + SwDoc* pDoc = word::getDocShell(xTextDocument)->GetDoc(); + if (!pDoc) + return nullptr; + + assert(sTag.empty() || sTitle.empty()); // only one grouping at a time is allowed + + SwTextContentControl* pControl = nullptr; + std::vector<OUString> vElementNames; + SwContentControlManager& rManager = pDoc->GetContentControlManager(); + size_t i = static_cast<size_t>(rIndex); + const size_t nLen = rManager.GetCount(); + if (!pElementNames && rIndex > 0 && sName.empty() && sTag.empty() && sTitle.empty()) + { + // This is the normal get-by-index/getCount mode - no need for fancy filtering. + if (i < nLen) + pControl = rManager.Get(i); + else + rIndex = nLen; + } + else + { + // loop through everything collecting names, filtering by Tag/Title + sal_Int32 nCounter = 0; + for (i = 0; i < nLen; ++i) + { + pControl = rManager.Get(i); + if (!sTag.empty() + && sTag != pControl->GetContentControl().GetContentControl()->GetTag()) + continue; + if (!sTitle.empty() + && sTitle != pControl->GetContentControl().GetContentControl()->GetAlias()) + continue; + + //OUString sID = OUString::number(static_cast<sal_uInt32>( + // pControl->GetContentControl().GetContentControl()->GetId())); + //if (!sName.empty() && sName != sID) + // continue; + + //if (pElementNames) + // vElementNames.push_back(sID); + + if (rIndex == nCounter /*|| !sName.empty()*/) + break; + + pControl = nullptr; + ++nCounter; + } + rIndex = nCounter; + } + if (pElementNames) + *pElementNames = comphelper::containerToSequence(vElementNames); + return pControl; +} + +namespace +{ +class ContentControlsEnumWrapper : public EnumerationHelper_BASE +{ + uno::Reference<container::XIndexAccess> mxIndexAccess; + sal_Int32 nIndex; + +public: + explicit ContentControlsEnumWrapper(uno::Reference<container::XIndexAccess> xIndexAccess) + : mxIndexAccess(std::move(xIndexAccess)) + , nIndex(0) + { + } + + sal_Bool SAL_CALL hasMoreElements() override { return (nIndex < mxIndexAccess->getCount()); } + + uno::Any SAL_CALL nextElement() override + { + if (nIndex < mxIndexAccess->getCount()) + { + return mxIndexAccess->getByIndex(nIndex++); + } + throw container::NoSuchElementException(); + } +}; + +class ContentControlCollectionHelper + : public ::cppu::WeakImplHelper<container::XNameAccess, container::XIndexAccess, + container::XEnumerationAccess> +{ +private: + uno::Reference<XHelperInterface> mxParent; + uno::Reference<uno::XComponentContext> mxContext; + uno::Reference<text::XTextDocument> mxTextDocument; + const OUString m_sTag; + const OUString m_sTitle; + SwTextContentControl* m_pCache; + +public: + /// @throws css::uno::RuntimeException + ContentControlCollectionHelper(uno::Reference<ov::XHelperInterface> xParent, + uno::Reference<uno::XComponentContext> xContext, + uno::Reference<text::XTextDocument> xTextDocument, + const OUString& rTag, const OUString& rTitle) + + : mxParent(std::move(xParent)) + , mxContext(std::move(xContext)) + , mxTextDocument(std::move(xTextDocument)) + , m_sTag(rTag) + , m_sTitle(rTitle) + , m_pCache(nullptr) + { + } + + // XIndexAccess + sal_Int32 SAL_CALL getCount() override + { + sal_Int32 nCount = SAL_MAX_INT32; + lcl_getContentControl(u"", m_sTag, m_sTitle, nCount, mxTextDocument); + return nCount == SAL_MAX_INT32 || nCount < 0 ? 0 : nCount; + } + + uno::Any SAL_CALL getByIndex(sal_Int32 Index) override + { + m_pCache = lcl_getContentControl(u"", m_sTag, m_sTitle, Index, mxTextDocument); + if (!m_pCache) + throw lang::IndexOutOfBoundsException(); + + return uno::Any(uno::Reference<word::XContentControl>( + new SwVbaContentControl(mxParent, mxContext, mxTextDocument, *m_pCache))); + } + + // XNameAccess + uno::Sequence<OUString> SAL_CALL getElementNames() override + { + sal_Int32 nCount = SAL_MAX_INT32; + uno::Sequence<OUString> aSeq; + lcl_getContentControl(u"", m_sTag, m_sTitle, nCount, mxTextDocument, &aSeq); + return aSeq; + } + + uno::Any SAL_CALL getByName(const OUString& aName) override + { + if (!hasByName(aName)) + throw container::NoSuchElementException(); + + return uno::Any(uno::Reference<word::XContentControl>( + new SwVbaContentControl(mxParent, mxContext, mxTextDocument, *m_pCache))); + } + + sal_Bool SAL_CALL hasByName(const OUString& aName) override + { + sal_Int32 nCount = -1; + m_pCache = lcl_getContentControl(aName, m_sTag, m_sTitle, nCount, mxTextDocument); + return m_pCache != nullptr; + } + + // XElementAccess + uno::Type SAL_CALL getElementType() override + { + return cppu::UnoType<word::XContentControl>::get(); + } + + sal_Bool SAL_CALL hasElements() override { return getCount() != 0; } + + // XEnumerationAccess + uno::Reference<container::XEnumeration> SAL_CALL createEnumeration() override + { + return new ContentControlsEnumWrapper(this); + } +}; +} + +/** + * Content Controls can be accessed and filtered in many different ways. + * Surprisingly however, there is no clear, descriptive "by name" access. + * Instead, each content control (probably) has a unique _signed-integer_ identifier, + * which can be passed to Item() as a float or _unsigned-integer_ string + * (to differentiate it from getByIndex). + * + * Index access can be filtered by Tag, Title, Range, and XML link. + * TODO: add filtering for Range, SelectLinkedControls, SelectUnlinkedControls + */ +SwVbaContentControls::SwVbaContentControls(const uno::Reference<XHelperInterface>& xParent, + const uno::Reference<uno::XComponentContext>& xContext, + const uno::Reference<text::XTextDocument>& xTextDocument, + const OUString& rTag, const OUString& rTitle) + : SwVbaContentControls_BASE( + xParent, xContext, + uno::Reference<container::XIndexAccess>( + new ContentControlCollectionHelper(xParent, xContext, xTextDocument, rTag, rTitle))) + , m_sTag(rTag) + , m_sTitle(rTitle) +{ +} + +// uno::Reference<ooo::vba::word::XContentControl> SwVbaContentControls::Add(const uno::Any& Range, +// sal_Int32 Type) +// { +// sw::mark::IFieldmark* pFieldmark = nullptr; +// switch (Type) +// { +// case ooo::vba::word::WdFieldType::wdFieldFormCheckBox: +// break; +// case ooo::vba::word::WdFieldType::wdFieldFormDropDown: +// break; +// case ooo::vba::word::WdFieldType::wdFieldFormTextInput: +// default:; +// } +// +// return uno::Reference<ooo::vba::word::XContentControl>( +// new SwVbaContentControl(mxParent, mxContext, m_xTextDocument, *pFieldmark)); +// } + +// XEnumerationAccess +uno::Type SwVbaContentControls::getElementType() +{ + return cppu::UnoType<word::XContentControl>::get(); +} + +uno::Reference<container::XEnumeration> SwVbaContentControls::createEnumeration() +{ + return new ContentControlsEnumWrapper(m_xIndexAccess); +} + +uno::Any SwVbaContentControls::createCollectionObject(const uno::Any& aSource) { return aSource; } + +OUString SwVbaContentControls::getServiceImplName() { return "SwVbaContentControls"; } + +uno::Sequence<OUString> SwVbaContentControls::getServiceNames() +{ + static uno::Sequence<OUString> const sNames{ "ooo.vba.word.ContentControls" }; + return sNames; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/ui/vba/vbacontentcontrols.hxx b/sw/source/ui/vba/vbacontentcontrols.hxx new file mode 100644 index 000000000000..a31ca589788a --- /dev/null +++ b/sw/source/ui/vba/vbacontentcontrols.hxx @@ -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/. + */ +#pragma once + +#include <com/sun/star/text/XTextDocument.hpp> +#include <ooo/vba/word/XContentControls.hpp> + +#include <vbahelper/vbacollectionimpl.hxx> + +typedef CollTestImplHelper<ooo::vba::word::XContentControls> SwVbaContentControls_BASE; + +class SwVbaContentControls : public SwVbaContentControls_BASE +{ +private: + OUString m_sTag; + OUString m_sTitle; + +public: + /// @throws css::uno::RuntimeException + SwVbaContentControls(const css::uno::Reference<ov::XHelperInterface>& xParent, + const css::uno::Reference<css::uno::XComponentContext>& xContext, + const css::uno::Reference<css::text::XTextDocument>& xTextDocument, + const OUString& rTag, const OUString& rTitle); + + // XContentControls + //css::uno::Reference<ooo::vba::word::XContentControl> SAL_CALL Add(const css::uno::Any& Type, const css::uno::Any& Range) override; + + // XEnumerationAccess + css::uno::Type SAL_CALL getElementType() override; + css::uno::Reference<css::container::XEnumeration> SAL_CALL createEnumeration() override; + + // SwVbaContentControls_BASE + css::uno::Any createCollectionObject(const css::uno::Any& aSource) override; + OUString getServiceImplName() override; + css::uno::Sequence<OUString> getServiceNames() override; +}; + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/ui/vba/vbadocument.cxx b/sw/source/ui/vba/vbadocument.cxx index 6dcbdbf5c0b4..f08974ef06e0 100644 --- a/sw/source/ui/vba/vbadocument.cxx +++ b/sw/source/ui/vba/vbadocument.cxx @@ -21,6 +21,7 @@ #include <sal/log.hxx> #include "vbafilterpropsfromformat.hxx" +#include "vbacontentcontrols.hxx" #include "vbadocument.hxx" #include "vbaformfields.hxx" #include "vbarange.hxx" @@ -217,6 +218,32 @@ SwVbaDocument::Bookmarks( const uno::Any& rIndex ) return xBookmarksVba->Item( rIndex, uno::Any() ); } +uno::Any SAL_CALL SwVbaDocument::ContentControls(const uno::Any& index) +{ + uno::Reference<XCollection> xContentControls( + new SwVbaContentControls(this, mxContext, mxTextDocument, "", "")); + if (index.hasValue()) + return xContentControls->Item(index, uno::Any()); + + return uno::Any(xContentControls); +} + +uno::Any SAL_CALL SwVbaDocument::SelectContentControlsByTag(const uno::Any& index) +{ + OUString sTag; + index >>= sTag; + return uno::Any(uno::Reference<XCollection>( + new SwVbaContentControls(this, mxContext, mxTextDocument, sTag, ""))); +} + +uno::Any SAL_CALL SwVbaDocument::SelectContentControlsByTitle(const uno::Any& index) +{ + OUString sTitle; + index >>= sTitle; + return uno::Any(uno::Reference<XCollection>( + new SwVbaContentControls(this, mxContext, mxTextDocument, "", sTitle))); +} + uno::Any SAL_CALL SwVbaDocument::Variables( const uno::Any& rIndex ) { diff --git a/sw/source/ui/vba/vbadocument.hxx b/sw/source/ui/vba/vbadocument.hxx index f1352e44f625..31ca3751686a 100644 --- a/sw/source/ui/vba/vbadocument.hxx +++ b/sw/source/ui/vba/vbadocument.hxx @@ -55,6 +55,9 @@ public: virtual css::uno::Any SAL_CALL BuiltInDocumentProperties( const css::uno::Any& index ) override; virtual css::uno::Any SAL_CALL CustomDocumentProperties( const css::uno::Any& index ) override; virtual css::uno::Any SAL_CALL Bookmarks( const css::uno::Any& rIndex ) override; + css::uno::Any SAL_CALL ContentControls(const css::uno::Any& index) override; + css::uno::Any SAL_CALL SelectContentControlsByTag(const css::uno::Any& index) override; + css::uno::Any SAL_CALL SelectContentControlsByTitle(const css::uno::Any& index) override; virtual css::uno::Any SAL_CALL Variables( const css::uno::Any& rIndex ) override; virtual css::uno::Any SAL_CALL getAttachedTemplate() override; virtual void SAL_CALL setAttachedTemplate( const css::uno::Any& _attachedtemplate ) override; |