sw/inc/cmdid.h | 1 sw/sdi/_textsh.sdi | 4 sw/sdi/swriter.sdi | 17 ++++ sw/source/uibase/shells/textsh1.cxx | 151 ++++++++++++++++++++++++++++++++++++ 4 files changed, 173 insertions(+)
New commits: commit 913e26de02067d49cdbe2746f9e3c3c9bed63236 Author: Attila Szűcs <[email protected]> AuthorDate: Mon Jul 1 08:48:43 2024 +0200 Commit: Miklos Vajna <[email protected]> CommitDate: Tue Jul 16 09:24:45 2024 +0200 SW: transform document structure Added a new UNO command: .uno:TransformDocumentStructure it need a sring parameter conaining a JSON strucure, that list what to change (transform), like this: { "Transforms": { "ContentControls.ByIndex.0": { "content": "new value for the first content control" }, "ContentControls.ByTag.name": { "content": "John Smith" } } } this is just a 1. version it can only set text of a plain-text content control, or the state of a checkbox, or the alias (i may will be removed .. we have to decide later about all setable propertyes of contentc controls, what to let transform) Change-Id: I1772d979a7eb43961d62896f3c393482ed7dfa89 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/170538 Reviewed-by: Miklos Vajna <[email protected]> Tested-by: Jenkins diff --git a/sw/inc/cmdid.h b/sw/inc/cmdid.h index c99e8da6d3f7..bd36f0bdd3b3 100644 --- a/sw/inc/cmdid.h +++ b/sw/inc/cmdid.h @@ -151,6 +151,7 @@ class SwUINumRuleItem; #define FN_REDLINE_REJECT_ALL (FN_EDIT2 + 44) /* Redlining Reject All*/ #define FN_REDLINE_ACCEPT_TONEXT (FN_EDIT2 + 45) /* Redlining Accept and jump to next*/ #define FN_REDLINE_REJECT_TONEXT (FN_EDIT2 + 46) /* Redlining Reject and jump to next*/ +#define FN_TRANSFORM_DOCUMENT_STRUCTURE (FN_EDIT2 + 47) /* overwrite text of content control, and more*/ // Region: View #define FN_DRAW_WRAP_DLG TypedWhichId<SfxInt16Item>(FN_VIEW + 3) /* Draw wrapping dlg */ diff --git a/sw/sdi/_textsh.sdi b/sw/sdi/_textsh.sdi index fa5809bd29c0..4d982bf76d8f 100644 --- a/sw/sdi/_textsh.sdi +++ b/sw/sdi/_textsh.sdi @@ -336,6 +336,10 @@ interface BaseText ExecMethod = ExecInsert ; StateMethod = GetState ; ] + FN_TRANSFORM_DOCUMENT_STRUCTURE + [ + ExecMethod = Execute ; + ] FN_INSERT_COLUMN_BREAK // status(final|play) [ ExecMethod = ExecInsert ; diff --git a/sw/sdi/swriter.sdi b/sw/sdi/swriter.sdi index ed49dc200ed9..ccbfb29dfb75 100644 --- a/sw/sdi/swriter.sdi +++ b/sw/sdi/swriter.sdi @@ -3338,6 +3338,23 @@ SfxVoidItem ContentControlProperties FN_CONTENT_CONTROL_PROPERTIES GroupId = SfxGroupId::Insert; ] +SfxVoidItem TransformDocumentStructure FN_TRANSFORM_DOCUMENT_STRUCTURE +(SfxStringItem DataJson FN_PARAM_1) +[ + AutoUpdate = FALSE, + FastCall = FALSE, + ReadOnlyDoc = FALSE, + Toggle = FALSE, + Container = FALSE, + RecordAbsolute = FALSE, + RecordPerSet; + + AccelConfig = TRUE, + MenuConfig = TRUE, + ToolBoxConfig = TRUE, + GroupId = SfxGroupId::Edit; +] + SfxVoidItem InsertMultiIndex FN_INSERT_MULTI_TOX () [ diff --git a/sw/source/uibase/shells/textsh1.cxx b/sw/source/uibase/shells/textsh1.cxx index 9b0d76746541..a169f0490263 100644 --- a/sw/source/uibase/shells/textsh1.cxx +++ b/sw/source/uibase/shells/textsh1.cxx @@ -23,6 +23,7 @@ #include <com/sun/star/i18n/WordType.hpp> #include <com/sun/star/linguistic2/XThesaurus.hpp> +#include <com/sun/star/text/XContentControlsSupplier.hpp> #include <hintids.hxx> #include <cmdid.h> @@ -126,6 +127,8 @@ #include <fmtrfmrk.hxx> #include <cntfrm.hxx> #include <flyfrm.hxx> +#include <unoprnms.hxx> +#include <boost/property_tree/json_parser.hpp> using namespace ::com::sun::star; using namespace com::sun::star::beans; @@ -2224,6 +2227,154 @@ void SwTextShell::Execute(SfxRequest &rReq) rWrtSh.SetInsMode( bOldIns ); } break; + case FN_TRANSFORM_DOCUMENT_STRUCTURE: + { + // get the parameter, what to transform + OUString aDataJson; + const SfxStringItem* pDataJson = rReq.GetArg<SfxStringItem>(FN_PARAM_1); + if (pDataJson) + { + aDataJson = pDataJson->GetValue(); + } + + // parse the JSON got prom parameter + boost::property_tree::ptree aTree; + std::stringstream aStream( + (std::string(OUStringToOString(aDataJson, RTL_TEXTENCODING_UTF8)))); + boost::property_tree::read_json(aStream, aTree); + + // get the loaded content controls + uno::Reference<text::XContentControlsSupplier> xCCSupplier( + GetView().GetDocShell()->GetModel(), uno::UNO_QUERY); + uno::Reference<container::XIndexAccess> xContentControls + = xCCSupplier->getContentControls(); + int iCCcount = xContentControls->getCount(); + + enum class ContentDataType + { + ERROR = -1, + INDEX, + TAG, + ALIAS, + ID + }; + std::vector<std::string> aIdTexts = { ".ByIndex.", ".ByTag.", ".ByAlias.", ".ById." }; + + // Iterate trough the JSON data loaded into a tree structure + for (const auto& aItem : aTree) + { + if (aItem.first == "Transforms") + { + // Handle all transformations + for (const auto& aItem2 : aItem.second) + { + if (aItem2.first.starts_with("ContentControls")) + { + std::string aTextEnd = aItem2.first.substr(15); + std::string aValue = ""; + ContentDataType iKeyId = ContentDataType::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); + aValue = aTextEnd.substr(aIdTexts[i].length()); + break; + } + } + if (iKeyId != ContentDataType::ERROR) + { + // Check all the content controls, if they match + for (int i = 0; i < iCCcount; ++i) + { + uno::Reference<text::XTextContent> xContentControl; + xContentControls->getByIndex(i) >>= xContentControl; + + uno::Reference<beans::XPropertySet> xContentControlProps( + xContentControl, uno::UNO_QUERY); + + // Compare the loaded and the actual idetifier + switch (iKeyId) + { + case ContentDataType::INDEX: + { + if (stoi(aValue) != i) + continue; + } + break; + case ContentDataType::ID: + { + sal_Int32 iID = -1; + xContentControlProps->getPropertyValue(UNO_NAME_ID) + >>= iID; + if (stoi(aValue) != iID) + continue; + } + break; + case ContentDataType::ALIAS: + { + OUString aAlias; + xContentControlProps->getPropertyValue(UNO_NAME_ALIAS) + >>= aAlias; + if (OStringToOUString(aValue, RTL_TEXTENCODING_UTF8) + != aAlias) + continue; + } + break; + case ContentDataType::TAG: + { + OUString aTag; + xContentControlProps->getPropertyValue(UNO_NAME_TAG) + >>= aTag; + if (OStringToOUString(aValue, RTL_TEXTENCODING_UTF8) + != aTag) + continue; + } + break; + default: + continue; + } + + // We have a match, this content control need to be transformed + // Set all the values (of the content control) what nes needed + for (const auto& aItem3 : aItem2.second) + { + if (aItem3.first == "content") + { + uno::Reference<text::XText> xContentControlText( + xContentControl, uno::UNO_QUERY); + xContentControlText->setString(OStringToOUString( + aItem3.second.get_value<std::string>(), + RTL_TEXTENCODING_UTF8)); + } + else if (aItem3.first == "checked") + { + bool bChecked + = (aItem3.second.get_value<std::string>() == "true") + ? true + : false; + xContentControlProps->setPropertyValue( + UNO_NAME_CHECKED, + uno::Any(bChecked)); + } + else if (aItem3.first == "alias") + { + xContentControlProps->setPropertyValue( + UNO_NAME_ALIAS, + uno::Any(OStringToOUString( + aItem3.second.get_value<std::string>(), + RTL_TEXTENCODING_UTF8))); + } + } + } + } + } + } + } + } + } + break; default: OSL_ENSURE(false, "wrong dispatcher"); return;
