diff options
-rw-r--r-- | sfx2/source/view/frame.cxx | 5 | ||||
-rw-r--r-- | sw/inc/cmdid.h | 2 | ||||
-rw-r--r-- | sw/qa/uibase/shells/shells.cxx | 63 | ||||
-rw-r--r-- | sw/sdi/_textsh.sdi | 6 | ||||
-rw-r--r-- | sw/sdi/swriter.sdi | 18 | ||||
-rw-r--r-- | sw/source/uibase/shells/textfld.cxx | 73 |
6 files changed, 166 insertions, 1 deletions
diff --git a/sfx2/source/view/frame.cxx b/sfx2/source/view/frame.cxx index eda62d4a29e9..f65d958e3fc4 100644 --- a/sfx2/source/view/frame.cxx +++ b/sfx2/source/view/frame.cxx @@ -58,7 +58,10 @@ using namespace ::com::sun::star::util; using namespace ::com::sun::star::frame; using namespace ::com::sun::star::container; -SfxPoolItem* SfxUnoAnyItem::CreateDefault() { SAL_WARN( "sfx", "No SfxUnoAnyItem factory available"); return nullptr; } +SfxPoolItem* SfxUnoAnyItem::CreateDefault() +{ + return new SfxUnoAnyItem(0, uno::Any()); +} SfxPoolItem* SfxUnoFrameItem::CreateDefault() { diff --git a/sw/inc/cmdid.h b/sw/inc/cmdid.h index c0d31883c3e0..838ccde78c83 100644 --- a/sw/inc/cmdid.h +++ b/sw/inc/cmdid.h @@ -310,6 +310,8 @@ class SwUINumRuleItem; #define FN_PROTECT_FIELDS (FN_INSERT2 + 26) #define FN_PROTECT_BOOKMARKS (FN_INSERT2 + 27) +#define FN_UPDATE_TEXT_FORMFIELDS (FN_INSERT2 + 28) + // clipboard table content #define FN_PASTE_NESTED_TABLE (FN_INSERT2 + 30) /* instead of the cell-by-cell copy between source and target tables */ #define FN_TABLE_PASTE_ROW_BEFORE (FN_INSERT2 + 31) /* paste table as new table rows */ diff --git a/sw/qa/uibase/shells/shells.cxx b/sw/qa/uibase/shells/shells.cxx index 4361920b3e87..01be5fda10b3 100644 --- a/sw/qa/uibase/shells/shells.cxx +++ b/sw/qa/uibase/shells/shells.cxx @@ -26,6 +26,7 @@ #include <comphelper/propertyvalue.hxx> #include <unotools/ucbstreamhelper.hxx> #include <xmloff/odffields.hxx> +#include <comphelper/string.hxx> #include <IDocumentContentOperations.hxx> #include <cmdid.h> @@ -35,6 +36,7 @@ #include <IDocumentDrawModelAccess.hxx> #include <drawdoc.hxx> #include <docsh.hxx> +#include <ndtxt.hxx> /// Covers sw/source/uibase/shells/ fixes. class SwUibaseShellsTest : public SwModelTestBase @@ -314,6 +316,67 @@ CPPUNIT_TEST_FIXTURE(SwUibaseShellsTest, testInsertTextFormField) CPPUNIT_ASSERT_EQUAL(OUString("aaa\nbbb"), aActualResult); } +CPPUNIT_TEST_FIXTURE(SwUibaseShellsTest, testUpdateFieldmarks) +{ + // Given a document with 2 fieldmarks: + createSwDoc(); + { + uno::Sequence<css::beans::PropertyValue> aArgs = { + comphelper::makePropertyValue("FieldType", uno::Any(OUString(ODF_UNHANDLED))), + comphelper::makePropertyValue("FieldCommand", + uno::Any(OUString("ADDIN ZOTERO_ITEM old command 1"))), + comphelper::makePropertyValue("FieldResult", uno::Any(OUString("old result 1"))), + }; + dispatchCommand(mxComponent, ".uno:TextFormField", aArgs); + } + { + uno::Sequence<css::beans::PropertyValue> aArgs = { + comphelper::makePropertyValue("FieldType", uno::Any(OUString(ODF_UNHANDLED))), + comphelper::makePropertyValue("FieldCommand", + uno::Any(OUString("ADDIN ZOTERO_ITEM old command 2"))), + comphelper::makePropertyValue("FieldResult", uno::Any(OUString("old result 2"))), + }; + dispatchCommand(mxComponent, ".uno:TextFormField", aArgs); + } + + // When updating those fieldmarks: + uno::Sequence<css::beans::PropertyValue> aField1{ + comphelper::makePropertyValue("FieldType", uno::Any(OUString(ODF_UNHANDLED))), + comphelper::makePropertyValue("FieldCommand", + uno::Any(OUString("ADDIN ZOTERO_ITEM new command 1"))), + comphelper::makePropertyValue("FieldResult", uno::Any(OUString("new result 1"))), + }; + uno::Sequence<css::beans::PropertyValue> aField2{ + comphelper::makePropertyValue("FieldType", uno::Any(OUString(ODF_UNHANDLED))), + comphelper::makePropertyValue("FieldCommand", + uno::Any(OUString("ADDIN ZOTERO_ITEM new command 2"))), + comphelper::makePropertyValue("FieldResult", uno::Any(OUString("new result 2"))), + }; + uno::Sequence<uno::Sequence<css::beans::PropertyValue>> aFields = { aField1, aField2 }; + uno::Sequence<css::beans::PropertyValue> aArgs = { + comphelper::makePropertyValue("FieldType", uno::Any(OUString(ODF_UNHANDLED))), + comphelper::makePropertyValue("FieldCommandPrefix", + uno::Any(OUString("ADDIN ZOTERO_ITEM"))), + comphelper::makePropertyValue("Fields", uno::Any(aFields)), + }; + dispatchCommand(mxComponent, ".uno:TextFormFields", aArgs); + + // Then make sure that the document text contains the new field results: + SwDoc* pDoc = getSwDoc(); + SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell(); + pWrtShell->SttEndDoc(/*bStt=*/true); + SwCursor* pCursor = pWrtShell->GetCursor(); + OUString aActual = pCursor->Start()->GetNode().GetTextNode()->GetText(); + static sal_Unicode const aForbidden[] + = { CH_TXT_ATR_FIELDSTART, CH_TXT_ATR_FIELDSEP, CH_TXT_ATR_FIELDEND, 0 }; + aActual = comphelper::string::removeAny(aActual, aForbidden); + // Without the accompanying fix in place, this test would have failed with: + // - Expected: new result 1new result 2 + // - Actual : old result 1old result 2 + // i.e. the fieldmarks were not updated. + CPPUNIT_ASSERT_EQUAL(OUString("new result 1new result 2"), aActual); +} + CPPUNIT_PLUGIN_IMPLEMENT(); /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/sdi/_textsh.sdi b/sw/sdi/_textsh.sdi index 6830a248a24b..312462f5b474 100644 --- a/sw/sdi/_textsh.sdi +++ b/sw/sdi/_textsh.sdi @@ -1778,6 +1778,12 @@ interface BaseText StateMethod = StateField ; ] + FN_UPDATE_TEXT_FORMFIELDS + [ + ExecMethod = ExecField ; + StateMethod = StateField ; + ] + FN_PROTECT_FIELDS [ ExecMethod = Execute ; diff --git a/sw/sdi/swriter.sdi b/sw/sdi/swriter.sdi index 738f42a9c6ab..60ca3faa4437 100644 --- a/sw/sdi/swriter.sdi +++ b/sw/sdi/swriter.sdi @@ -8255,6 +8255,24 @@ SfxVoidItem TextFormField FN_INSERT_TEXT_FORMFIELD GroupId = SfxGroupId::Controls; ] +SfxVoidItem TextFormFields FN_UPDATE_TEXT_FORMFIELDS +(SfxStringItem FieldType FN_PARAM_1, SfxStringItem FieldCommandPrefix FN_PARAM_2, SfxUnoAnyItem Fields FN_PARAM_3) +[ + AutoUpdate = TRUE, + FastCall = FALSE, + ReadOnlyDoc = FALSE, + Toggle = FALSE, + Container = FALSE, + RecordAbsolute = FALSE, + RecordPerSet; + + + AccelConfig = TRUE, + MenuConfig = TRUE, + ToolBoxConfig = TRUE, + GroupId = SfxGroupId::Controls; +] + SfxVoidItem CheckBoxFormField FN_INSERT_CHECKBOX_FORMFIELD [ diff --git a/sw/source/uibase/shells/textfld.cxx b/sw/source/uibase/shells/textfld.cxx index 762705c90b66..90a620b1959f 100644 --- a/sw/source/uibase/shells/textfld.cxx +++ b/sw/source/uibase/shells/textfld.cxx @@ -17,6 +17,7 @@ * the License at http://www.apache.org/licenses/LICENSE-2.0 . */ +#include <com/sun/star/beans/PropertyValues.hpp> #include <AnnotationWin.hxx> #include <comphelper/lok.hxx> #include <hintids.hxx> @@ -60,6 +61,7 @@ #include <IDocumentUndoRedo.hxx> #include <svl/zforlist.hxx> #include <svl/zformat.hxx> +#include <comphelper/sequenceashashmap.hxx> #include <IMark.hxx> #include <officecfg/Office/Compatibility.hxx> #include <ndtxt.hxx> @@ -833,6 +835,77 @@ FIELD_INSERT: rSh.GetView().GetViewFrame()->GetBindings().Invalidate( SID_UNDO ); } break; + case FN_UPDATE_TEXT_FORMFIELDS: + { + OUString aFieldType; + const SfxStringItem* pFieldType = rReq.GetArg<SfxStringItem>(FN_PARAM_1); + if (pFieldType) + { + aFieldType = pFieldType->GetValue(); + } + OUString aFieldCommandPrefix; + const SfxStringItem* pFieldCommandPrefix = rReq.GetArg<SfxStringItem>(FN_PARAM_2); + if (pFieldCommandPrefix) + { + aFieldCommandPrefix = pFieldCommandPrefix->GetValue(); + } + uno::Sequence<beans::PropertyValues> aFields; + const SfxUnoAnyItem* pFields = rReq.GetArg<SfxUnoAnyItem>(FN_PARAM_3); + if (pFields) + { + pFields->GetValue() >>= aFields; + } + + rSh.GetDoc()->GetIDocumentUndoRedo().StartUndo(SwUndoId::INSERT_FORM_FIELD, nullptr); + rSh.StartAction(); + + IDocumentMarkAccess* pMarkAccess = rSh.GetDoc()->getIDocumentMarkAccess(); + sal_Int32 nFieldIndex = 0; + for (auto it = pMarkAccess->getFieldmarksBegin(); it != pMarkAccess->getFieldmarksEnd(); ++it) + { + auto pFieldmark = dynamic_cast<sw::mark::IFieldmark*>(*it); + assert(pFieldmark); + if (pFieldmark->GetFieldname() != aFieldType) + { + continue; + } + + auto itParam = pFieldmark->GetParameters()->find(ODF_CODE_PARAM); + if (itParam == pFieldmark->GetParameters()->end()) + { + continue; + } + + OUString aCommand; + itParam->second >>= aCommand; + if (!aCommand.startsWith(aFieldCommandPrefix)) + { + continue; + } + + if (aFields.getLength() <= nFieldIndex) + { + continue; + } + + comphelper::SequenceAsHashMap aMap(aFields[nFieldIndex++]); + itParam->second = aMap["FieldCommand"]; + SwPaM aPaM(pFieldmark->GetMarkPos(), pFieldmark->GetOtherMarkPos()); + aPaM.Normalize(); + // Skip field start & separator. + aPaM.GetPoint()->AdjustContent(2); + // Skip field end. + aPaM.GetMark()->AdjustContent(-1); + rSh.GetDoc()->getIDocumentContentOperations().DeleteAndJoin(aPaM); + OUString aFieldResult; + aMap["FieldResult"] >>= aFieldResult; + SwTranslateHelper::PasteHTMLToPaM(rSh, &aPaM, aFieldResult.toUtf8(), true); + } + + rSh.EndAction(); + rSh.GetDoc()->GetIDocumentUndoRedo().EndUndo(SwUndoId::INSERT_FORM_FIELD, nullptr); + } + break; default: OSL_FAIL("wrong dispatcher"); return; |