summaryrefslogtreecommitdiff
path: root/sw
diff options
context:
space:
mode:
authorAttila Szűcs <attila.szucs@collabora.com>2024-07-11 11:24:28 +0200
committerMiklos Vajna <vmiklos@collabora.com>2024-07-17 10:52:38 +0200
commit84d63cfccf7af8f2b3b689ab0e622f8b408eb470 (patch)
tree55c561e5d09759e2045b897f29f5ee18042898f3 /sw
parentddcc9515bc4313b580fad6474b603266ef2b9c15 (diff)
Sw: extract/transform document structure 2
inserting a ContentControl, now generate a unique ID for it... search the lowest possible non used (non negative) number added a GetType() function for SwXContentControl that get it from SwContentControl, and used it for extract and transform. Added some support for all other types.. some are not really usable yet. Fixed a problem when setting checkbox check, did not changed its content. If content is set to “”. It now set as placeholder, and reset its content to the initial placeholder value, like: “Choose an item” or “Click here to enter text” (work for checkbox, and picture CntentControl.) Change-Id: I0fc696f73734bdfb9ac5b8fdc6891168b8d4ed5a Reviewed-on: https://gerrit.libreoffice.org/c/core/+/170600 Tested-by: Jenkins Reviewed-by: Miklos Vajna <vmiklos@collabora.com>
Diffstat (limited to 'sw')
-rw-r--r--sw/inc/unoprnms.hxx1
-rw-r--r--sw/source/core/unocore/unocontentcontrol.cxx13
-rw-r--r--sw/source/uibase/shells/textsh1.cxx116
-rw-r--r--sw/source/uibase/uno/loktxdoc.cxx82
-rw-r--r--sw/source/uibase/wrtsh/wrtsh1.cxx22
5 files changed, 205 insertions, 29 deletions
diff --git a/sw/inc/unoprnms.hxx b/sw/inc/unoprnms.hxx
index 836294a98a3f..7ed25b929247 100644
--- a/sw/inc/unoprnms.hxx
+++ b/sw/inc/unoprnms.hxx
@@ -938,6 +938,7 @@ inline constexpr OUString UNO_NAME_MULTILINE = u"MultiLine"_ustr;
inline constexpr OUString UNO_NAME_DATE_STRING = u"DateString"_ustr;
inline constexpr OUString UNO_NAME_PARA_ID = u"ParaId"_ustr;
inline constexpr OUString UNO_NAME_PARA_ID_PARENT = u"ParaIdParent"_ustr;
+inline constexpr OUString UNO_NAME_CONTENT_CONTROL_TYPE = u"ContentControlType"_ustr;
#endif
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/core/unocore/unocontentcontrol.cxx b/sw/source/core/unocore/unocontentcontrol.cxx
index 0660183a681d..e9c7563a59fa 100644
--- a/sw/source/core/unocore/unocontentcontrol.cxx
+++ b/sw/source/core/unocore/unocontentcontrol.cxx
@@ -177,6 +177,7 @@ public:
sal_uInt32 m_nTabIndex;
OUString m_aLock;
OUString m_aMultiLine;
+ SwContentControlType m_iType;
Impl(SwXContentControl& rThis, SwDoc& rDoc, SwContentControl* pContentControl,
css::uno::Reference<SwXText> xParentText, std::unique_ptr<const TextRangeList_t> pPortions)
@@ -196,6 +197,7 @@ public:
, m_bDropDown(false)
, m_nId(0)
, m_nTabIndex(0)
+ , m_iType(SwContentControlType::RICH_TEXT)
{
if (m_pContentControl)
{
@@ -1330,6 +1332,17 @@ uno::Any SAL_CALL SwXContentControl::getPropertyValue(const OUString& rPropertyN
aRet <<= m_pImpl->m_pContentControl->GetMultiLine();
}
}
+ else if (rPropertyName == UNO_NAME_CONTENT_CONTROL_TYPE)
+ {
+ if (m_pImpl->m_bIsDescriptor)
+ {
+ aRet <<= static_cast<sal_Int32>(m_pImpl->m_iType);
+ }
+ else
+ {
+ aRet <<= static_cast<sal_Int32>(m_pImpl->m_pContentControl->GetType());
+ }
+ }
else
{
throw beans::UnknownPropertyException();
diff --git a/sw/source/uibase/shells/textsh1.cxx b/sw/source/uibase/shells/textsh1.cxx
index a169f0490263..3ceb282ff704 100644
--- a/sw/source/uibase/shells/textsh1.cxx
+++ b/sw/source/uibase/shells/textsh1.cxx
@@ -129,6 +129,7 @@
#include <flyfrm.hxx>
#include <unoprnms.hxx>
#include <boost/property_tree/json_parser.hpp>
+#include <formatcontentcontrol.hxx>
using namespace ::com::sun::star;
using namespace com::sun::star::beans;
@@ -2246,11 +2247,14 @@ void SwTextShell::Execute(SfxRequest &rReq)
// get the loaded content controls
uno::Reference<text::XContentControlsSupplier> xCCSupplier(
GetView().GetDocShell()->GetModel(), uno::UNO_QUERY);
+ if (!xCCSupplier.is())
+ break;
+
uno::Reference<container::XIndexAccess> xContentControls
= xCCSupplier->getContentControls();
int iCCcount = xContentControls->getCount();
- enum class ContentDataType
+ enum class ContentFilterType
{
ERROR = -1,
INDEX,
@@ -2272,18 +2276,18 @@ void SwTextShell::Execute(SfxRequest &rReq)
{
std::string aTextEnd = aItem2.first.substr(15);
std::string aValue = "";
- ContentDataType iKeyId = ContentDataType::ERROR;
+ ContentFilterType iKeyId = ContentFilterType::ERROR;
// Find how the content control is identified: ByIndex, ByAlias...
for (size_t i = 0; i < aIdTexts.size(); i++)
{
if (aTextEnd.starts_with(aIdTexts[i]))
{
- iKeyId = static_cast<ContentDataType>(i);
+ iKeyId = static_cast<ContentFilterType>(i);
aValue = aTextEnd.substr(aIdTexts[i].length());
break;
}
}
- if (iKeyId != ContentDataType::ERROR)
+ if (iKeyId != ContentFilterType::ERROR)
{
// Check all the content controls, if they match
for (int i = 0; i < iCCcount; ++i)
@@ -2293,17 +2297,19 @@ void SwTextShell::Execute(SfxRequest &rReq)
uno::Reference<beans::XPropertySet> xContentControlProps(
xContentControl, uno::UNO_QUERY);
+ if (!xContentControlProps.is())
+ continue;
// Compare the loaded and the actual idetifier
switch (iKeyId)
{
- case ContentDataType::INDEX:
+ case ContentFilterType::INDEX:
{
if (stoi(aValue) != i)
continue;
}
break;
- case ContentDataType::ID:
+ case ContentFilterType::ID:
{
sal_Int32 iID = -1;
xContentControlProps->getPropertyValue(UNO_NAME_ID)
@@ -2312,7 +2318,7 @@ void SwTextShell::Execute(SfxRequest &rReq)
continue;
}
break;
- case ContentDataType::ALIAS:
+ case ContentFilterType::ALIAS:
{
OUString aAlias;
xContentControlProps->getPropertyValue(UNO_NAME_ALIAS)
@@ -2322,7 +2328,7 @@ void SwTextShell::Execute(SfxRequest &rReq)
continue;
}
break;
- case ContentDataType::TAG:
+ case ContentFilterType::TAG:
{
OUString aTag;
xContentControlProps->getPropertyValue(UNO_NAME_TAG)
@@ -2337,16 +2343,91 @@ void SwTextShell::Execute(SfxRequest &rReq)
}
// We have a match, this content control need to be transformed
- // Set all the values (of the content control) what nes needed
+ // Set all the values (of the content control) what is needed
for (const auto& aItem3 : aItem2.second)
{
if (aItem3.first == "content")
{
+ std::string aContent
+ = aItem3.second.get_value<std::string>();
+
uno::Reference<text::XText> xContentControlText(
xContentControl, uno::UNO_QUERY);
- xContentControlText->setString(OStringToOUString(
- aItem3.second.get_value<std::string>(),
- RTL_TEXTENCODING_UTF8));
+ if (!xContentControlText.is())
+ continue;
+
+ xContentControlText->setString(
+ OStringToOUString(aContent, RTL_TEXTENCODING_UTF8));
+
+ sal_Int32 iType = 0;
+ xContentControlProps->getPropertyValue(
+ UNO_NAME_CONTENT_CONTROL_TYPE)
+ >>= iType;
+ SwContentControlType aType
+ = static_cast<SwContentControlType>(iType);
+
+ // if we set the content of a checkbox, then we
+ // also set the checked state based on the content
+ if (aType == SwContentControlType::CHECKBOX)
+ {
+ OUString aCheckedContent;
+ xContentControlProps->getPropertyValue(
+ UNO_NAME_CHECKED_STATE)
+ >>= aCheckedContent;
+ bool bChecked = false;
+ if (aCheckedContent
+ == OStringToOUString(
+ aItem3.second.get_value<std::string>(),
+ RTL_TEXTENCODING_UTF8))
+ bChecked = true;
+ xContentControlProps->setPropertyValue(
+ UNO_NAME_CHECKED, uno::Any(bChecked));
+ }
+ else if (aType == SwContentControlType::PLAIN_TEXT
+ || aType == SwContentControlType::RICH_TEXT
+ || aType == SwContentControlType::DATE
+ || aType == SwContentControlType::COMBO_BOX
+ || aType
+ == SwContentControlType::DROP_DOWN_LIST)
+ {
+ // Set the placeholder
+ bool bPlaceHolder = aContent == "" ? true : false;
+ xContentControlProps->setPropertyValue(
+ UNO_NAME_SHOWING_PLACE_HOLDER,
+ uno::Any(bPlaceHolder));
+ if (bPlaceHolder)
+ {
+ OUString aPlaceHolderText;
+ switch (aType)
+ {
+ case SwContentControlType::PLAIN_TEXT:
+ case SwContentControlType::RICH_TEXT:
+ {
+ aPlaceHolderText = SwResId(
+ STR_CONTENT_CONTROL_PLACEHOLDER);
+ }
+ break;
+ case SwContentControlType::COMBO_BOX:
+ case SwContentControlType::DROP_DOWN_LIST:
+ {
+ aPlaceHolderText = SwResId(
+ STR_DROPDOWN_CONTENT_CONTROL_PLACEHOLDER);
+ }
+ break;
+ case SwContentControlType::DATE:
+ {
+ aPlaceHolderText = SwResId(
+ STR_DATE_CONTENT_CONTROL_PLACEHOLDER);
+ }
+ break;
+ default: // do nothing for picture and checkbox
+ break;
+ }
+ if (!aPlaceHolderText.isEmpty())
+ xContentControlText->setString(
+ aPlaceHolderText);
+ }
+ }
}
else if (aItem3.first == "checked")
{
@@ -2357,6 +2438,17 @@ void SwTextShell::Execute(SfxRequest &rReq)
xContentControlProps->setPropertyValue(
UNO_NAME_CHECKED,
uno::Any(bChecked));
+
+ OUString aCheckContent;
+ xContentControlProps->getPropertyValue(
+ bChecked ? UNO_NAME_CHECKED_STATE
+ : UNO_NAME_UNCHECKED_STATE)
+ >>= aCheckContent;
+ uno::Reference<text::XText> xContentControlText(
+ xContentControl, uno::UNO_QUERY);
+ if (!xContentControlText.is())
+ continue;
+ xContentControlText->setString(aCheckContent);
}
else if (aItem3.first == "alias")
{
diff --git a/sw/source/uibase/uno/loktxdoc.cxx b/sw/source/uibase/uno/loktxdoc.cxx
index f2ae84f339d3..ff592be587c4 100644
--- a/sw/source/uibase/uno/loktxdoc.cxx
+++ b/sw/source/uibase/uno/loktxdoc.cxx
@@ -387,11 +387,20 @@ void GetField(tools::JsonWriter& rJsonWriter, SwDocShell* pDocShell,
///
/// Parameters:
///
-/// todo later (filtering options)
+/// - filter: To filter what document structure types to extract
+/// now, only contentcontrol is supported.
void GetDocStructure(tools::JsonWriter& rJsonWriter, SwDocShell* /*pDocShell*/,
- const std::map<OUString, OUString>& /*rArguments*/,
+ const std::map<OUString, OUString>& rArguments,
uno::Reference<container::XIndexAccess>& xContentControls)
{
+ auto it = rArguments.find(u"filter"_ustr);
+ if (it != rArguments.end())
+ {
+ // If filter is present but we are filtering not to contentcontrols
+ if (!it->second.equals(u"contentcontrol"_ustr))
+ return;
+ }
+
int iCCcount = xContentControls->getCount();
auto commentsNode = rJsonWriter.startNode("DocStructure");
@@ -419,6 +428,10 @@ void GetDocStructure(tools::JsonWriter& rJsonWriter, SwDocShell* /*pDocShell*/,
xContentControlProps->getPropertyValue(UNO_NAME_ALIAS) >>= aAlias;
rJsonWriter.put("alias", aAlias);
+ sal_Int32 iType(0);
+ xContentControlProps->getPropertyValue(UNO_NAME_CONTENT_CONTROL_TYPE) >>= iType;
+ SwContentControlType aType = static_cast<SwContentControlType>(iType);
+
bool bShowingPlaceHolder = false;
xContentControlProps->getPropertyValue(UNO_NAME_SHOWING_PLACE_HOLDER)
>>= bShowingPlaceHolder;
@@ -429,23 +442,58 @@ void GetDocStructure(tools::JsonWriter& rJsonWriter, SwDocShell* /*pDocShell*/,
}
rJsonWriter.put("content", aContent);
- bool bPlainText = false;
- xContentControlProps->getPropertyValue(UNO_NAME_PLAIN_TEXT) >>= bPlainText;
- bool bChBox = false;
- xContentControlProps->getPropertyValue(UNO_NAME_CHECKBOX) >>= bChBox;
- // "type" value derives from the UNO bool property name.
- if (bPlainText)
- {
- rJsonWriter.put("type", "plain-text");
- }
- else if (bChBox)
+ switch (aType)
{
- rJsonWriter.put("type", "checkbox");
- bool bchecked = false;
- xContentControlProps->getPropertyValue(UNO_NAME_CHECKED) >>= bchecked;
- rJsonWriter.put(UNO_NAME_CHECKED, OUString::boolean(bchecked));
+ case SwContentControlType::RICH_TEXT:
+ {
+ rJsonWriter.put("type", "rich-text");
+ }
+ break;
+ case SwContentControlType::CHECKBOX:
+ {
+ rJsonWriter.put("type", "checkbox");
+ bool bchecked = false;
+ xContentControlProps->getPropertyValue(UNO_NAME_CHECKED) >>= bchecked;
+ rJsonWriter.put(UNO_NAME_CHECKED, OUString::boolean(bchecked));
+ }
+ break;
+ case SwContentControlType::DROP_DOWN_LIST:
+ {
+ rJsonWriter.put("type", "drop-down-list");
+ // we could list its elements if we want
+ }
+ break;
+ case SwContentControlType::PICTURE:
+ {
+ rJsonWriter.put("type", "picture");
+ }
+ break;
+ case SwContentControlType::DATE:
+ {
+ rJsonWriter.put("type", "date");
+ OUString aDateFormat;
+ xContentControlProps->getPropertyValue(UNO_NAME_DATE_FORMAT) >>= aDateFormat;
+ rJsonWriter.put(UNO_NAME_DATE_FORMAT, aDateFormat);
+ OUString aDateLanguage;
+ xContentControlProps->getPropertyValue(UNO_NAME_DATE_LANGUAGE) >>= aDateLanguage;
+ rJsonWriter.put(UNO_NAME_DATE_LANGUAGE, aDateLanguage);
+ }
+ break;
+ case SwContentControlType::PLAIN_TEXT:
+ {
+ rJsonWriter.put("type", "plain-text");
+ }
+ break;
+ case SwContentControlType::COMBO_BOX:
+ {
+ rJsonWriter.put("type", "combo-box");
+ // we could list its elements if we want
+ }
+ break;
+ default:
+ //it should never happen
+ rJsonWriter.put("type", "no type?");
}
- // TODO more types: picture, date, combobox, dropdown...
}
}
diff --git a/sw/source/uibase/wrtsh/wrtsh1.cxx b/sw/source/uibase/wrtsh/wrtsh1.cxx
index c6848b5ead50..65d725c6872a 100644
--- a/sw/source/uibase/wrtsh/wrtsh1.cxx
+++ b/sw/source/uibase/wrtsh/wrtsh1.cxx
@@ -1075,6 +1075,28 @@ void SwWrtShell::InsertContentControl(SwContentControlType eType)
}
auto pContentControl = std::make_shared<SwContentControl>(nullptr);
+
+ // Search for a non used ID for the new ContentControl, to make it unique
+ SwContentControlManager& pManager = GetDoc()->GetContentControlManager();
+ size_t nCCCount = pManager.GetCount();
+ std::vector<bool> aIdMap(nCCCount);
+ aIdMap.resize(nCCCount, false);
+ size_t nIdToCheck;
+ for (nIdToCheck = 0; nIdToCheck < nCCCount; nIdToCheck++)
+ {
+ sal_Int32 nID
+ = pManager.UnsortedGet(nIdToCheck)->GetContentControl().GetContentControl()->GetId();
+ if (nID >= 0 && nID < static_cast<sal_Int32>(nCCCount))
+ {
+ aIdMap[nID] = true;
+ }
+ }
+ // Find the first ID that was not used
+ nIdToCheck = 0;
+ while (nIdToCheck < nCCCount && aIdMap[nIdToCheck])
+ nIdToCheck++;
+ pContentControl->SetId(nIdToCheck);
+
OUString aPlaceholder;
switch (eType)
{