summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--desktop/source/lib/init.cxx17
-rw-r--r--include/LibreOfficeKit/LibreOfficeKit.h3
-rw-r--r--include/LibreOfficeKit/LibreOfficeKit.hxx4
-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
8 files changed, 221 insertions, 37 deletions
diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx
index 2769c47bf9b0..48b771c9f7f3 100644
--- a/desktop/source/lib/init.cxx
+++ b/desktop/source/lib/init.cxx
@@ -2588,7 +2588,8 @@ static void lo_setOption(LibreOfficeKit* pThis, const char* pOption, const char*
static void lo_dumpState(LibreOfficeKit* pThis, const char* pOptions, char** pState);
-static char* lo_extractDocumentStructureRequest(LibreOfficeKit* pThis, const char* pFilePath);
+static char* lo_extractDocumentStructureRequest(LibreOfficeKit* pThis, const char* pFilePath,
+ const char* pFilter);
LibLibreOffice_Impl::LibLibreOffice_Impl()
: m_pOfficeClass( gOfficeClass.lock() )
@@ -3147,7 +3148,8 @@ static char* lo_extractRequest(LibreOfficeKit* /*pThis*/, const char* pFilePath)
return strdup("{ }");
}
-static char* lo_extractDocumentStructureRequest(LibreOfficeKit* /*pThis*/, const char* pFilePath)
+static char* lo_extractDocumentStructureRequest(LibreOfficeKit* /*pThis*/, const char* pFilePath,
+ const char* pFilter)
{
uno::Reference<frame::XDesktop2> xComponentLoader = frame::Desktop::create(xContext);
uno::Reference< css::lang::XComponent > xComp;
@@ -3194,9 +3196,14 @@ static char* lo_extractDocumentStructureRequest(LibreOfficeKit* /*pThis*/, const
{
tools::JsonWriter aJson;
{
- pDoc->getCommandValues(aJson, ".uno:ExtractDocumentStructure");
- //auto aNode = aJson.startNode("Controls");
- //extractLinks(xLTS->getLinks(), false, aJson);
+ OString aCommand = ".uno:ExtractDocumentStructure"_ostr;
+ if (pFilter && pFilter[0])
+ {
+ aCommand
+ = OString::Concat(aCommand) + "?filter="_ostr + pFilter;
+ }
+
+ pDoc->getCommandValues(aJson, aCommand);
}
return convertOString(aJson.finishAndGetAsOString());
}
diff --git a/include/LibreOfficeKit/LibreOfficeKit.h b/include/LibreOfficeKit/LibreOfficeKit.h
index 168e1203123e..da1ddbe13d7f 100644
--- a/include/LibreOfficeKit/LibreOfficeKit.h
+++ b/include/LibreOfficeKit/LibreOfficeKit.h
@@ -149,7 +149,8 @@ struct _LibreOfficeKitClass
/** @see lok::Office::extractDocumentStructureRequest.
*/
- char* (*extractDocumentStructureRequest) (LibreOfficeKit* pThis, const char* pFilePath);
+ char* (*extractDocumentStructureRequest)(LibreOfficeKit* pThis, const char* pFilePath,
+ const char* pFilter);
};
#define LIBREOFFICEKIT_DOCUMENT_HAS(pDoc,member) LIBREOFFICEKIT_HAS_MEMBER(LibreOfficeKitDocumentClass,member,(pDoc)->pClass->nSize)
diff --git a/include/LibreOfficeKit/LibreOfficeKit.hxx b/include/LibreOfficeKit/LibreOfficeKit.hxx
index 9ce39d9e7d34..3f165c3e5363 100644
--- a/include/LibreOfficeKit/LibreOfficeKit.hxx
+++ b/include/LibreOfficeKit/LibreOfficeKit.hxx
@@ -1259,9 +1259,9 @@ public:
return mpThis->pClass->setForkedChild(mpThis, bIsChild);
}
- char* extractDocumentStructureRequest(const char* pFilePath)
+ char* extractDocumentStructureRequest(const char* pFilePath, const char* pFilter)
{
- return mpThis->pClass->extractDocumentStructureRequest(mpThis, pFilePath);
+ return mpThis->pClass->extractDocumentStructureRequest(mpThis, pFilePath, pFilter);
}
};
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)
{