sw/inc/fldbas.hxx                   |    1 +
 sw/qa/uibase/fldui/fldui.cxx        |   27 +++++++++++++++++++++++++++
 sw/sdi/swriter.sdi                  |    2 +-
 sw/source/core/fields/fldbas.cxx    |   31 +++++++++++++++++++++++++++++++
 sw/source/uibase/fldui/fldmgr.cxx   |   35 +++++++++++++++++++++++++++++++++++
 sw/source/uibase/shells/textfld.cxx |    5 +++++
 6 files changed, 100 insertions(+), 1 deletion(-)

New commits:
commit eb67d771af370465cb194ba6cfbda138ece9bb25
Author:     Miklos Vajna <[email protected]>
AuthorDate: Wed Dec 21 14:51:08 2022 +0100
Commit:     Miklos Vajna <[email protected]>
CommitDate: Thu Jan 5 07:10:49 2023 +0000

    sw, field insert: handle the Content param for refmarks and accept HTML 
there
    
    Creating a bookmark just to refer to it is a bit hacky, refmarks are the
    proper solution to that.
    
    But while .uno:InsertBookmark allows specifying custom HTML for the
    content of the created bookmark, there is no matching UNO command that
    would do the same for refmarks.
    
    Fix the problem by extending .uno:InsertField:
    
    - add a TypeName parameter, so TypeName=SetRef can be used in macros,
      which is more readable than Type=12
    
    - handle the previously ignored Content parameter when creating a
      refmark and accept HTML there to allow rich formatting
    
    Note that unlike bookmarks, refmarks are text attributes in a text node,
    so in case multi-paragraph HTML would be provided, the created refmark
    will only cover the content till the end of the first paragraph. Also
    not that unlike fieldmarks and bookmarks, a refmark can only represent a
    reference, not a bibliography, we'll need sections for that.
    
    (cherry picked from commit 16075474819696f920979969474aa8300f4af530)
    
    Conflicts:
            sw/source/uibase/shells/textfld.cxx
    
    Change-Id: I4d95f0a6e5618f1b611f7431e9189a63ee75d349
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/144941
    Tested-by: Jenkins CollaboraOffice <[email protected]>
    Reviewed-by: Justin Luth <[email protected]>
    Reviewed-by: Miklos Vajna <[email protected]>

diff --git a/sw/inc/fldbas.hxx b/sw/inc/fldbas.hxx
index 0251ba1f9a23..37e3d871ca0e 100644
--- a/sw/inc/fldbas.hxx
+++ b/sw/inc/fldbas.hxx
@@ -234,6 +234,7 @@ enum SwDateTimeSubType {
 
 /// General tools.
 OUString  FormatNumber(sal_uInt32 nNum, SvxNumType nFormat, LanguageType nLang 
= LANGUAGE_NONE);
+SwFieldTypesEnum SwFieldTypeFromString(std::u16string_view rString);
 
 /** Instances of SwFields and those derived from it occur 0 to n times.
  For each class there is one instance of the associated type class.
diff --git a/sw/qa/uibase/fldui/fldui.cxx b/sw/qa/uibase/fldui/fldui.cxx
index b3785f5ee072..b9a69936bd50 100644
--- a/sw/qa/uibase/fldui/fldui.cxx
+++ b/sw/qa/uibase/fldui/fldui.cxx
@@ -19,6 +19,7 @@
 #include <wrtsh.hxx>
 #include <fldmgr.hxx>
 #include <authfld.hxx>
+#include <ndtxt.hxx>
 
 using namespace com::sun::star;
 
@@ -91,6 +92,32 @@ CPPUNIT_TEST_FIXTURE(Test, testBiblioPageNumberUpdate)
     // i.e. the second biblio field's URL was not updated.
     CPPUNIT_ASSERT_EQUAL(aNewUrl, pEntry->GetAuthorField(AUTH_FIELD_URL));
 }
+
+CPPUNIT_TEST_FIXTURE(Test, testInsertRefmark)
+{
+    // Given an empty document:
+    SwDoc* pDoc = createSwDoc();
+
+    // When inserting a refmark with text:
+    uno::Sequence<css::beans::PropertyValue> aArgs = {
+        comphelper::makePropertyValue("TypeName", 
uno::Any(OUString("SetRef"))),
+        comphelper::makePropertyValue(
+            "Name", uno::Any(OUString("ZOTERO_ITEM CSL_CITATION {} 
RNDpyJknp173F"))),
+        comphelper::makePropertyValue("Content", 
uno::Any(OUString("aaa<b>bbb</b>ccc"))),
+    };
+    dispatchCommand(mxComponent, ".uno:InsertField", aArgs);
+
+    // Then make sure that we create a refmark that covers that text:
+    SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell();
+    SwTextNode* pTextNode = pWrtShell->GetCursor()->GetNode().GetTextNode();
+    std::vector<SwTextAttr*> aAttrs = pTextNode->GetTextAttrsAt(0, 
RES_TXTATR_REFMARK);
+    // Without the accompanying fix in place, this test would have failed with:
+    // - Expected: 1
+    // - Actual  : 0
+    // i.e. no refmark was created, only the hard to read Type=12 created a 
refmark.
+    CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), aAttrs.size());
+    CPPUNIT_ASSERT_EQUAL(OUString("aaabbbccc"), pTextNode->GetText());
+}
 }
 
 CPPUNIT_PLUGIN_IMPLEMENT();
diff --git a/sw/sdi/swriter.sdi b/sw/sdi/swriter.sdi
index bc58977788a4..11ecc7c465e1 100644
--- a/sw/sdi/swriter.sdi
+++ b/sw/sdi/swriter.sdi
@@ -2855,7 +2855,7 @@ SfxVoidItem InsertEnvelope FN_ENVELOP
 ]
 
 SfxVoidItem InsertField FN_INSERT_FIELD
-(SfxUInt16Item Type FN_PARAM_FIELD_TYPE,SfxUInt16Item SubType 
FN_PARAM_FIELD_SUBTYPE,SfxStringItem Name FN_INSERT_FIELD,SfxStringItem Content 
FN_PARAM_FIELD_CONTENT,SfxUInt32Item Format FN_PARAM_FIELD_FORMAT,SfxStringItem 
Separator FN_PARAM_3)
+(SfxUInt16Item Type FN_PARAM_FIELD_TYPE,SfxUInt16Item SubType 
FN_PARAM_FIELD_SUBTYPE,SfxStringItem Name FN_INSERT_FIELD,SfxStringItem Content 
FN_PARAM_FIELD_CONTENT,SfxUInt32Item Format FN_PARAM_FIELD_FORMAT,SfxStringItem 
Separator FN_PARAM_3, SfxStringItem TypeName FN_PARAM_4)
 [
     AutoUpdate = FALSE,
     FastCall = FALSE,
diff --git a/sw/source/core/fields/fldbas.cxx b/sw/source/core/fields/fldbas.cxx
index ae5a8751ff05..206fc635ea0c 100644
--- a/sw/source/core/fields/fldbas.cxx
+++ b/sw/source/core/fields/fldbas.cxx
@@ -520,6 +520,37 @@ OUString FormatNumber(sal_uInt32 nNum, SvxNumType nFormat, 
LanguageType nLang)
         return aNumber.GetNumStr(nNum, LanguageTag::convertToLocale(nLang));
 }
 
+SwFieldTypesEnum SwFieldTypeFromString(std::u16string_view rString)
+{
+    if (rString == u"Date")
+        return SwFieldTypesEnum::Date;
+    if (rString == u"Time")
+        return SwFieldTypesEnum::Time;
+    if (rString == u"Filename")
+        return SwFieldTypesEnum::Filename;
+    if (rString == u"DatabaseName")
+        return SwFieldTypesEnum::DatabaseName;
+    if (rString == u"Chapter")
+        return SwFieldTypesEnum::Chapter;
+    if (rString == u"PageNumber")
+        return SwFieldTypesEnum::PageNumber;
+    if (rString == u"DocumentStatistics")
+        return SwFieldTypesEnum::DocumentStatistics;
+    if (rString == u"Author")
+        return SwFieldTypesEnum::Author;
+    if (rString == u"Set")
+        return SwFieldTypesEnum::Set;
+    if (rString == u"Get")
+        return SwFieldTypesEnum::Get;
+    if (rString == u"Formel")
+        return SwFieldTypesEnum::Formel;
+    if (rString == u"HiddenText")
+        return SwFieldTypesEnum::HiddenText;
+    if (rString == u"SetRef")
+        return SwFieldTypesEnum::SetRef;
+    return SwFieldTypesEnum::Unknown;
+}
+
 SwValueFieldType::SwValueFieldType(SwDoc *const pDoc, SwFieldIds const 
nWhichId)
     : SwFieldType(nWhichId)
     , m_pDoc(pDoc)
diff --git a/sw/source/uibase/fldui/fldmgr.cxx 
b/sw/source/uibase/fldui/fldmgr.cxx
index 90fdaad22a1d..bddc1904df77 100644
--- a/sw/source/uibase/fldui/fldmgr.cxx
+++ b/sw/source/uibase/fldui/fldmgr.cxx
@@ -71,6 +71,8 @@
 #include <viewopt.hxx>
 #include <txmsrt.hxx>
 #include <unotools/useroptions.hxx>
+#include <IDocumentContentOperations.hxx>
+#include <translatehelper.hxx>
 
 using namespace com::sun::star::uno;
 using namespace com::sun::star::container;
@@ -1070,7 +1072,40 @@ bool SwFieldMgr::InsertField(
         {
             if( !rData.m_sPar1.isEmpty() && CanInsertRefMark( rData.m_sPar1 ) )
             {
+                const OUString& rRefmarkText = rData.m_sPar2;
+                SwPaM* pCursorPos = pCurShell->GetCursor();
+                pCurShell->StartAction();
+                if (!rRefmarkText.isEmpty())
+                {
+                    // Split node to remember where the start position is.
+                    bool bSuccess = 
pCurShell->GetDoc()->getIDocumentContentOperations().SplitNode(
+                            *pCursorPos->GetPoint(), /*bChkTableStart=*/false);
+                    if (bSuccess)
+                    {
+                        SwPaM aRefmarkPam(*pCursorPos->GetPoint());
+                        aRefmarkPam.Move(fnMoveBackward, GoInContent);
+
+                        // Paste HTML content.
+                        SwTranslateHelper::PasteHTMLToPaM(
+                                *pCurShell, pCursorPos, rRefmarkText.toUtf8(), 
/*bSetSelection=*/true);
+
+                        // Undo the above SplitNode().
+                        aRefmarkPam.SetMark();
+                        aRefmarkPam.Move(fnMoveForward, GoInContent);
+                        
pCurShell->GetDoc()->getIDocumentContentOperations().DeleteAndJoin(
+                                aRefmarkPam);
+                        *aRefmarkPam.GetMark() = *pCursorPos->GetPoint();
+                        *pCursorPos = aRefmarkPam;
+                    }
+                }
+
                 pCurShell->SetAttrItem( SwFormatRefMark( rData.m_sPar1 ) );
+
+                if (!rRefmarkText.isEmpty())
+                {
+                    pCursorPos->DeleteMark();
+                }
+                pCurShell->EndAction();
                 return true;
             }
             return false;
diff --git a/sw/source/uibase/shells/textfld.cxx 
b/sw/source/uibase/shells/textfld.cxx
index 8aa66ef09ddc..620ceff0fb14 100644
--- a/sw/source/uibase/shells/textfld.cxx
+++ b/sw/source/uibase/shells/textfld.cxx
@@ -268,6 +268,11 @@ void SwTextShell::ExecField(SfxRequest &rReq)
                 if( SfxItemState::SET == pArgs->GetItemState( 
FN_PARAM_FIELD_TYPE,
                                                             false, &pItem ))
                     nType = static_cast<SwFieldTypesEnum>(static_cast<const 
SfxUInt16Item *>(pItem)->GetValue());
+                else if (pArgs->GetItemState(FN_PARAM_4, false, &pItem) == 
SfxItemState::SET)
+                {
+                    const OUString& rTypeName = static_cast<const 
SfxStringItem *>(pItem)->GetValue();
+                    nType = SwFieldTypeFromString(rTypeName);
+                }
                 if( SfxItemState::SET == pArgs->GetItemState( 
FN_PARAM_FIELD_SUBTYPE,
                                                             false, &pItem ))
                     nSubType = static_cast<const SfxUInt16Item 
*>(pItem)->GetValue();

Reply via email to