summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sfx2/source/view/frame.cxx5
-rw-r--r--sw/inc/cmdid.h2
-rw-r--r--sw/qa/uibase/shells/shells.cxx63
-rw-r--r--sw/sdi/_textsh.sdi6
-rw-r--r--sw/sdi/swriter.sdi18
-rw-r--r--sw/source/uibase/shells/textfld.cxx73
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;