[Libreoffice-commits] core.git: sw/inc sw/source writerfilter/source

Libreoffice Gerrit user logerrit at kemper.freedesktop.org
Sat Mar 9 14:41:16 UTC 2019


 sw/inc/IDocumentMarkAccess.hxx                    |    2 
 sw/source/core/crsr/bookmrk.cxx                   |   33 ++++++++++++++
 sw/source/core/doc/docbm.cxx                      |   50 ++++++++++++++++++++--
 sw/source/core/inc/MarkManager.hxx                |    1 
 sw/source/core/inc/bookmrk.hxx                    |   12 +++++
 sw/source/core/inc/unobookmark.hxx                |    2 
 sw/source/core/text/itrform2.cxx                  |    4 -
 sw/source/core/unocore/unobkm.cxx                 |   23 +++++++++-
 writerfilter/source/dmapper/FormControlHelper.cxx |   17 ++++++-
 9 files changed, 133 insertions(+), 11 deletions(-)

New commits:
commit f66a83c95c21b4311918a64bb85016857b49f4d4
Author:     Tamás Zolnai <tamas.zolnai at collabora.com>
AuthorDate: Sat Mar 9 14:44:50 2019 +0100
Commit:     Tamás Zolnai <tamas.zolnai at collabora.com>
CommitDate: Sat Mar 9 15:40:56 2019 +0100

    MSForms: Introduce a new IFieldMark for drop-down form field
    
    * It was weird anyway that a drop-down form field was represented
    as an CheckboxFieldmark.
    * It will be useful for later commits, to have a separate field type
    for drop-down field.
    * Needed to fix-up the API a bit because it was designed to specify
    the field type after initialization. I solved it in a way to not break
    the API behavior. Hopefully it's not very slow.
    
    Change-Id: I3103e6b1c36289b27b62ab9ca7dfeebc14901c8a
    Reviewed-on: https://gerrit.libreoffice.org/68960
    Tested-by: Jenkins
    Reviewed-by: Tamás Zolnai <tamas.zolnai at collabora.com>

diff --git a/sw/inc/IDocumentMarkAccess.hxx b/sw/inc/IDocumentMarkAccess.hxx
index 823326e2b8ac..cbd523c012b1 100644
--- a/sw/inc/IDocumentMarkAccess.hxx
+++ b/sw/inc/IDocumentMarkAccess.hxx
@@ -47,6 +47,7 @@ class IDocumentMarkAccess
             ANNOTATIONMARK,
             TEXT_FIELDMARK,
             CHECKBOX_FIELDMARK,
+            DROPDOWN_FIELDMARK,
             NAVIGATOR_REMINDER
         };
 
@@ -255,6 +256,7 @@ class IDocumentMarkAccess
         virtual std::vector< ::sw::mark::IFieldmark* > getDropDownsFor(const SwPaM &rPaM) const=0;
 
         virtual void deleteFieldmarkAt(const SwPosition& rPos) = 0;
+        virtual ::sw::mark::IFieldmark* changeNonTextFieldmarkType(::sw::mark::IFieldmark* pFieldmark, const OUString& rNewType) = 0;
 
         // Annotation Marks
         virtual const_iterator_t getAnnotationMarksBegin() const = 0;
diff --git a/sw/source/core/crsr/bookmrk.cxx b/sw/source/core/crsr/bookmrk.cxx
index 92bb4c67d786..4bb6d6780295 100644
--- a/sw/source/core/crsr/bookmrk.cxx
+++ b/sw/source/core/crsr/bookmrk.cxx
@@ -478,6 +478,39 @@ namespace sw { namespace mark
             pResult->second >>= bResult;
         return bResult;
     }
+
+    DropDownFieldmark::DropDownFieldmark(const SwPaM& rPaM)
+        : Fieldmark(rPaM)
+    {
+    }
+
+    DropDownFieldmark::~DropDownFieldmark()
+    {
+    }
+
+    void DropDownFieldmark::InitDoc(SwDoc* const io_pDoc, sw::mark::InsertMode const eMode)
+    {
+        if (eMode == sw::mark::InsertMode::New)
+        {
+            lcl_SetFieldMarks(this, io_pDoc, CH_TXT_ATR_FIELDSTART, CH_TXT_ATR_FORMELEMENT);
+
+            // For some reason the end mark is moved from 1 by the Insert:
+            // we don't want this for checkboxes
+            SwPosition aNewEndPos = GetMarkEnd();
+            aNewEndPos.nContent--;
+            SetMarkEndPos( aNewEndPos );
+        }
+        else
+        {
+            lcl_AssertFieldMarksSet(this, CH_TXT_ATR_FIELDSTART, CH_TXT_ATR_FORMELEMENT);
+        }
+    }
+
+    void DropDownFieldmark::ReleaseDoc(SwDoc* const pDoc)
+    {
+        lcl_RemoveFieldMarks(this, pDoc,
+                CH_TXT_ATR_FIELDSTART, CH_TXT_ATR_FORMELEMENT);
+    }
 }}
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/core/doc/docbm.cxx b/sw/source/core/doc/docbm.cxx
index e06908f3438a..d34508e1b254 100644
--- a/sw/source/core/doc/docbm.cxx
+++ b/sw/source/core/doc/docbm.cxx
@@ -338,6 +338,8 @@ IDocumentMarkAccess::MarkType IDocumentMarkAccess::GetType(const IMark& rBkmk)
         return MarkType::TEXT_FIELDMARK;
     else if(*pMarkTypeInfo == typeid(CheckboxFieldmark))
         return MarkType::CHECKBOX_FIELDMARK;
+    else if(*pMarkTypeInfo == typeid(DropDownFieldmark))
+        return MarkType::DROPDOWN_FIELDMARK;
     else if(*pMarkTypeInfo == typeid(NavigatorReminder))
         return MarkType::NAVIGATOR_REMINDER;
     else
@@ -414,6 +416,9 @@ namespace sw { namespace mark
             case IDocumentMarkAccess::MarkType::CHECKBOX_FIELDMARK:
                 pMark = std::shared_ptr<IMark>(new CheckboxFieldmark(rPaM));
                 break;
+            case IDocumentMarkAccess::MarkType::DROPDOWN_FIELDMARK:
+                pMark = std::shared_ptr<IMark>(new DropDownFieldmark(rPaM));
+                break;
             case IDocumentMarkAccess::MarkType::NAVIGATOR_REMINDER:
                 pMark = std::shared_ptr<IMark>(new NavigatorReminder(rPaM));
                 break;
@@ -462,6 +467,7 @@ namespace sw { namespace mark
                 break;
             case IDocumentMarkAccess::MarkType::TEXT_FIELDMARK:
             case IDocumentMarkAccess::MarkType::CHECKBOX_FIELDMARK:
+            case IDocumentMarkAccess::MarkType::DROPDOWN_FIELDMARK:
                 lcl_InsertMarkSorted(m_vFieldmarks, pMark);
                 break;
             case IDocumentMarkAccess::MarkType::ANNOTATIONMARK:
@@ -522,9 +528,20 @@ namespace sw { namespace mark
         bool bEnableSetModified = m_pDoc->getIDocumentState().IsEnableSetModified();
         m_pDoc->getIDocumentState().SetEnableSetModified(false);
 
-        sw::mark::IMark* pMark = makeMark( rPaM, rName,
-                IDocumentMarkAccess::MarkType::CHECKBOX_FIELDMARK,
-                sw::mark::InsertMode::New);
+        sw::mark::IMark* pMark = nullptr;
+        if(rType == ODF_FORMCHECKBOX)
+        {
+            pMark = makeMark( rPaM, rName,
+                    IDocumentMarkAccess::MarkType::CHECKBOX_FIELDMARK,
+                    sw::mark::InsertMode::New);
+        }
+        else if(rType == ODF_FORMDROPDOWN)
+        {
+            pMark = makeMark( rPaM, rName,
+                    IDocumentMarkAccess::MarkType::DROPDOWN_FIELDMARK,
+                    sw::mark::InsertMode::New);
+        }
+
         sw::mark::IFieldmark* pFieldMark = dynamic_cast<sw::mark::IFieldmark*>( pMark );
         if (pFieldMark)
             pFieldMark->SetFieldname( rType );
@@ -934,6 +951,7 @@ namespace sw { namespace mark
 
             case IDocumentMarkAccess::MarkType::TEXT_FIELDMARK:
             case IDocumentMarkAccess::MarkType::CHECKBOX_FIELDMARK:
+            case IDocumentMarkAccess::MarkType::DROPDOWN_FIELDMARK:
                 {
                     IDocumentMarkAccess::iterator_t ppFieldmark = lcl_FindMark(m_vFieldmarks, *ppMark);
                     if ( ppFieldmark != m_vFieldmarks.end() )
@@ -1077,6 +1095,32 @@ namespace sw { namespace mark
         deleteMark(lcl_FindMark(m_vAllMarks, *pFieldmark));
     }
 
+    ::sw::mark::IFieldmark* MarkManager::changeNonTextFieldmarkType(::sw::mark::IFieldmark* pFieldmark, const OUString& rNewType)
+    {
+        bool bActualChange = false;
+        if(rNewType == ODF_FORMDROPDOWN)
+        {
+            if (dynamic_cast<::sw::mark::CheckboxFieldmark*>(pFieldmark))
+                bActualChange = true;
+        }
+        else if(rNewType == ODF_FORMCHECKBOX)
+        {
+            if (dynamic_cast<::sw::mark::DropDownFieldmark*>(pFieldmark))
+                bActualChange = true;
+        }
+
+        if (!bActualChange)
+            return nullptr;
+
+        // Store attributes needed to create the new fieldmark
+        OUString sName = pFieldmark->GetName();
+        SwPaM aPaM(pFieldmark->GetMarkPos());
+
+        // Remove the old fieldmark and create a new one with the new type
+        deleteFieldmarkAt(*aPaM.GetPoint());
+        return makeNoTextFieldBookmark(aPaM, sName, rNewType);
+    }
+
 
     IFieldmark* MarkManager::getDropDownFor(const SwPosition& rPos) const
     {
diff --git a/sw/source/core/inc/MarkManager.hxx b/sw/source/core/inc/MarkManager.hxx
index cbae235520e8..71ad5c913d6c 100644
--- a/sw/source/core/inc/MarkManager.hxx
+++ b/sw/source/core/inc/MarkManager.hxx
@@ -86,6 +86,7 @@ namespace sw {
             virtual std::vector< ::sw::mark::IFieldmark* > getDropDownsFor(const SwPaM &rPaM) const override;
 
             virtual void deleteFieldmarkAt(const SwPosition& rPos) override;
+            virtual ::sw::mark::IFieldmark* changeNonTextFieldmarkType(::sw::mark::IFieldmark* pFieldmark, const OUString& rNewType) override;
 
             void dumpAsXml(xmlTextWriterPtr pWriter) const;
 
diff --git a/sw/source/core/inc/bookmrk.hxx b/sw/source/core/inc/bookmrk.hxx
index 9bf1c9d7679c..3bde575ab399 100644
--- a/sw/source/core/inc/bookmrk.hxx
+++ b/sw/source/core/inc/bookmrk.hxx
@@ -245,6 +245,7 @@ namespace sw {
             virtual void ReleaseDoc(SwDoc* const pDoc) override;
         };
 
+        /// Fieldmark representing a checkbox form field.
         class CheckboxFieldmark
             : virtual public ICheckboxFieldmark
             , public Fieldmark
@@ -256,6 +257,17 @@ namespace sw {
             bool IsChecked() const override;
             void SetChecked(bool checked) override;
         };
+
+        /// Fieldmark representing a drop-down form field.
+        class DropDownFieldmark
+            : public Fieldmark
+        {
+        public:
+            DropDownFieldmark(const SwPaM& rPaM);
+            virtual ~DropDownFieldmark() override;
+            virtual void InitDoc(SwDoc* const io_pDoc, sw::mark::InsertMode eMode) override;
+            virtual void ReleaseDoc(SwDoc* const pDoc) override;
+        };
     }
 }
 #endif
diff --git a/sw/source/core/inc/unobookmark.hxx b/sw/source/core/inc/unobookmark.hxx
index 95763c1b0a09..5c38402ba17c 100644
--- a/sw/source/core/inc/unobookmark.hxx
+++ b/sw/source/core/inc/unobookmark.hxx
@@ -68,6 +68,8 @@ protected:
 
     const ::sw::mark::IMark* GetBookmark() const;
 
+    IDocumentMarkAccess* GetIDocumentMarkAccess();
+
     void registerInMark( SwXBookmark& rXMark, ::sw::mark::IMark* const pMarkBase );
 
     virtual ~SwXBookmark() override;
diff --git a/sw/source/core/text/itrform2.cxx b/sw/source/core/text/itrform2.cxx
index 631373f98d99..2697f3022639 100644
--- a/sw/source/core/text/itrform2.cxx
+++ b/sw/source/core/text/itrform2.cxx
@@ -917,10 +917,6 @@ SwTextPortion *SwTextFormatter::WhichTextPor( SwTextFormatInfo &rInf ) const
                     {
                         pPor = new SwFieldMarkPortion();
                     }
-                    else
-                    {
-                        assert( false );        // unknown type...
-                    }
                 }
             }
             if( !pPor )
diff --git a/sw/source/core/unocore/unobkm.cxx b/sw/source/core/unocore/unobkm.cxx
index 753263a2aa6f..0a53c27c4516 100644
--- a/sw/source/core/unocore/unobkm.cxx
+++ b/sw/source/core/unocore/unobkm.cxx
@@ -134,6 +134,11 @@ const ::sw::mark::IMark* SwXBookmark::GetBookmark() const
     return m_pImpl->m_pRegisteredBookmark;
 }
 
+IDocumentMarkAccess* SwXBookmark::GetIDocumentMarkAccess()
+{
+    return m_pImpl->m_pDoc->getIDocumentMarkAccess();
+}
+
 SwXBookmark::SwXBookmark(SwDoc *const pDoc)
     : m_pImpl( new SwXBookmark::Impl(pDoc) )
 {
@@ -620,7 +625,21 @@ void SwXFieldmark::setFieldType(const OUString & fieldType)
         dynamic_cast<const IFieldmark*>(GetBookmark()));
     if(!pBkm)
         throw uno::RuntimeException();
-    pBkm->SetFieldname(fieldType);
+    if(fieldType != getFieldType())
+    {
+        if(fieldType == ODF_FORMDROPDOWN || fieldType == ODF_FORMCHECKBOX)
+        {
+            ::sw::mark::IFieldmark* pNewFieldmark = GetIDocumentMarkAccess()->changeNonTextFieldmarkType(pBkm, fieldType);
+            if (pNewFieldmark)
+            {
+                registerInMark(*this, pNewFieldmark);
+                return;
+            }
+        }
+
+        // We did not generate a new fieldmark, so set the type ID
+        pBkm->SetFieldname(fieldType);
+    }
 }
 
 uno::Reference<container::XNameContainer> SwXFieldmark::getParameters()
@@ -654,6 +673,8 @@ SwXFieldmark::CreateXFieldmark(SwDoc & rDoc, ::sw::mark::IMark *const pMark,
             pXBkmk = new SwXFieldmark(false, &rDoc);
         else if (dynamic_cast< ::sw::mark::CheckboxFieldmark* >(pMark))
             pXBkmk = new SwXFieldmark(true, &rDoc);
+        else if (dynamic_cast< ::sw::mark::DropDownFieldmark* >(pMark))
+            pXBkmk = new SwXFieldmark(true, &rDoc);
         else
             pXBkmk = new SwXFieldmark(isReplacementObject, &rDoc);
 
diff --git a/writerfilter/source/dmapper/FormControlHelper.cxx b/writerfilter/source/dmapper/FormControlHelper.cxx
index 3088a4a27361..98e7bb0ba319 100644
--- a/writerfilter/source/dmapper/FormControlHelper.cxx
+++ b/writerfilter/source/dmapper/FormControlHelper.cxx
@@ -202,6 +202,20 @@ bool FormControlHelper::createCheckbox(uno::Reference<text::XTextRange> const& x
 
 void FormControlHelper::processField(uno::Reference<text::XFormField> const& xFormField)
 {
+    // Set field type first before adding parameters.
+    if (m_pImpl->m_eFieldId == FIELD_FORMTEXT )
+    {
+        xFormField->setFieldType(ODF_FORMTEXT);
+    }
+    else if (m_pImpl->m_eFieldId == FIELD_FORMCHECKBOX )
+    {
+        xFormField->setFieldType(ODF_FORMCHECKBOX);
+    }
+    else if (m_pImpl->m_eFieldId == FIELD_FORMDROPDOWN )
+    {
+        xFormField->setFieldType(ODF_FORMDROPDOWN);
+    }
+
     uno::Reference<container::XNameContainer> xNameCont = xFormField->getParameters();
     uno::Reference<container::XNamed> xNamed( xFormField, uno::UNO_QUERY );
     if ( m_pFFData && xNamed.is() && xNameCont.is() )
@@ -223,7 +237,6 @@ void FormControlHelper::processField(uno::Reference<text::XFormField> const& xFo
 
         if (m_pImpl->m_eFieldId == FIELD_FORMTEXT )
         {
-            xFormField->setFieldType(ODF_FORMTEXT);
             sTmp = m_pFFData->getName();
             try
             {
@@ -255,7 +268,6 @@ void FormControlHelper::processField(uno::Reference<text::XFormField> const& xFo
         }
         else if (m_pImpl->m_eFieldId == FIELD_FORMCHECKBOX )
         {
-            xFormField->setFieldType(ODF_FORMCHECKBOX);
             uno::Reference<beans::XPropertySet> xPropSet(xFormField, uno::UNO_QUERY);
             uno::Any aAny;
             aAny <<= m_pFFData->getCheckboxChecked();
@@ -264,7 +276,6 @@ void FormControlHelper::processField(uno::Reference<text::XFormField> const& xFo
         }
         else if (m_pImpl->m_eFieldId == FIELD_FORMDROPDOWN )
         {
-            xFormField->setFieldType(ODF_FORMDROPDOWN);
             const FFDataHandler::DropDownEntries_t& rEntries = m_pFFData->getDropDownEntries();
             if (!rEntries.empty())
             {


More information about the Libreoffice-commits mailing list