[Libreoffice-commits] core.git: Branch 'feature/cib_contract3753' - sw/inc sw/source writerfilter/source
Michael Stahl (via logerrit)
logerrit at kemper.freedesktop.org
Mon Nov 2 15:32:01 UTC 2020
sw/inc/IDocumentMarkAccess.hxx | 8 +
sw/inc/unomap.hxx | 3
sw/source/core/doc/docbm.cxx | 7
sw/source/core/inc/MarkManager.hxx | 2
sw/source/core/inc/unobookmark.hxx | 46 +++++-
sw/source/core/unocore/unobkm.cxx | 166 ++++++++++++++++++++--
sw/source/core/unocore/unofield.cxx | 7
sw/source/core/unocore/unomap.cxx | 11 +
sw/source/core/unocore/unomap1.cxx | 6
writerfilter/source/dmapper/DomainMapper_Impl.cxx | 24 ++-
writerfilter/source/dmapper/DomainMapper_Impl.hxx | 2
11 files changed, 260 insertions(+), 22 deletions(-)
New commits:
commit cbd0bb273d8ca464b98703fd03dc5887d8436170
Author: Michael Stahl <Michael.Stahl at cib.de>
AuthorDate: Fri Oct 30 20:30:40 2020 +0100
Commit: Michael Stahl <Michael.Stahl at cib.de>
CommitDate: Mon Nov 2 16:23:24 2020 +0100
sw: return SwXFieldmark in SwXFieldEnumeration
* Implement text::XTextField in SwXFieldmark
* That requires overriding XTextContent, just forward to SwXBookmark
* Also override XServiceInfo implementation in SwXFieldmark
* Add a PropertySetInfo for SwXFieldmark, which doesn't support "Hidden"
or "Condition" properties of SwXBookmark
* in SwXFieldmark::setFieldType(), only allow sensible new types
* fix DomainMapper_Impl assumptions that if it implements XTextField
it can't be a fieldmark, which caused CppunitTest_sw_ooxmlexport10
testTdf92157 to fail with a SAXException caused by some disposed
SwXTextCursor
Change-Id: I1ae2e9cb99ea784040874517e4d1af7e59d24405
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/105083
Tested-by: Jenkins
Reviewed-by: Michael Stahl <michael.stahl at cib.de>
(cherry picked from commit dd24e21bb4f183048a738314934fc3f02ec093f1)
diff --git a/sw/inc/IDocumentMarkAccess.hxx b/sw/inc/IDocumentMarkAccess.hxx
index a076a6dada66..8aff936b6aa3 100644
--- a/sw/inc/IDocumentMarkAccess.hxx
+++ b/sw/inc/IDocumentMarkAccess.hxx
@@ -309,6 +309,14 @@ class IDocumentMarkAccess
// Fieldmarks
+ /** returns a STL-like random access iterator to the begin of the sequence of fieldmarks.
+ */
+ virtual const_iterator_t getFieldmarksBegin() const =0;
+
+ /** returns a STL-like random access iterator to the end of the sequence of fieldmarks.
+ */
+ virtual const_iterator_t getFieldmarksEnd() const =0;
+
/// get Fieldmark for CH_TXT_ATR_FIELDSTART/CH_TXT_ATR_FIELDEND at rPos
virtual ::sw::mark::IFieldmark* getFieldmarkAt(const SwPosition& rPos) const =0;
virtual ::sw::mark::IFieldmark* getFieldmarkFor(const SwPosition& pos) const =0;
diff --git a/sw/inc/unomap.hxx b/sw/inc/unomap.hxx
index caee6bc5c209..1cd22609f02e 100644
--- a/sw/inc/unomap.hxx
+++ b/sw/inc/unomap.hxx
@@ -125,7 +125,8 @@ struct SfxItemPropertyMapEntry;
#define PROPERTY_MAP_ACCESSIBILITY_TEXT_ATTRIBUTE 99
#define PROPERTY_MAP_TABLE_STYLE 100
#define PROPERTY_MAP_CELL_STYLE 101
-#define PROPERTY_MAP_END 102
+#define PROPERTY_MAP_FIELDMARK 102
+#define PROPERTY_MAP_END 103
//S&E
#define WID_WORDS 0
diff --git a/sw/source/core/doc/docbm.cxx b/sw/source/core/doc/docbm.cxx
index a9eed445a21c..de9d216af112 100644
--- a/sw/source/core/doc/docbm.cxx
+++ b/sw/source/core/doc/docbm.cxx
@@ -1287,6 +1287,13 @@ namespace sw { namespace mark
sal_Int32 MarkManager::getBookmarksCount() const
{ return m_vBookmarks.size(); }
+ IDocumentMarkAccess::const_iterator_t MarkManager::getFieldmarksBegin() const
+ { return m_vFieldmarks.begin(); }
+
+ IDocumentMarkAccess::const_iterator_t MarkManager::getFieldmarksEnd() const
+ { return m_vFieldmarks.end(); }
+
+
// finds the first that is starting after
IDocumentMarkAccess::const_iterator_t MarkManager::findFirstBookmarkStartsAfter(const SwPosition& rPos) const
{
diff --git a/sw/source/core/inc/MarkManager.hxx b/sw/source/core/inc/MarkManager.hxx
index edf8121836b6..8509ea210131 100644
--- a/sw/source/core/inc/MarkManager.hxx
+++ b/sw/source/core/inc/MarkManager.hxx
@@ -85,6 +85,8 @@ namespace sw {
virtual const_iterator_t findFirstBookmarkStartsAfter(const SwPosition& rPos) const override;
// Fieldmarks
+ virtual const_iterator_t getFieldmarksBegin() const override;
+ virtual const_iterator_t getFieldmarksEnd() const override;
virtual ::sw::mark::IFieldmark* getFieldmarkAt(const SwPosition& rPos) const override;
virtual ::sw::mark::IFieldmark* getFieldmarkFor(const SwPosition& rPos) const override;
virtual ::sw::mark::IFieldmark* getFieldmarkBefore(const SwPosition& rPos) const override;
diff --git a/sw/source/core/inc/unobookmark.hxx b/sw/source/core/inc/unobookmark.hxx
index 20b984742b73..5354621154cc 100644
--- a/sw/source/core/inc/unobookmark.hxx
+++ b/sw/source/core/inc/unobookmark.hxx
@@ -25,6 +25,7 @@
#include <com/sun/star/beans/XPropertySet.hpp>
#include <com/sun/star/container/XNamed.hpp>
#include <com/sun/star/text/XTextContent.hpp>
+#include <com/sun/star/text/XTextField.hpp>
#include <com/sun/star/text/XFormField.hpp>
#include <cppuhelper/implbase.hxx>
@@ -70,6 +71,8 @@ protected:
IDocumentMarkAccess* GetIDocumentMarkAccess();
+ SwDoc * GetDoc();
+
void registerInMark( SwXBookmark& rXMark, ::sw::mark::IMark* const pMarkBase );
virtual ~SwXBookmark() override;
@@ -177,7 +180,9 @@ class SwXFieldmarkParameters
};
typedef cppu::ImplInheritanceHelper< SwXBookmark,
- css::text::XFormField > SwXFieldmark_Base;
+ css::text::XFormField,
+ css::text::XTextField
+ > SwXFieldmark_Base;
class SwXFieldmark final
: public SwXFieldmark_Base
@@ -185,6 +190,11 @@ class SwXFieldmark final
::sw::mark::ICheckboxFieldmark* getCheckboxFieldmark();
bool const isReplacementObject;
+ css::uno::Reference<css::text::XTextRange>
+ GetCommand(::sw::mark::IFieldmark const& rMark);
+ css::uno::Reference<css::text::XTextRange>
+ GetResult(::sw::mark::IFieldmark const& rMark);
+
SwXFieldmark(bool isReplacementObject, SwDoc* pDoc);
public:
@@ -194,15 +204,41 @@ public:
virtual void attachToRange(
const css::uno::Reference<css::text::XTextRange > & xTextRange) override;
- virtual OUString SAL_CALL getFieldType() override;
- virtual void SAL_CALL setFieldType(const OUString& description ) override;
- virtual css::uno::Reference< css::container::XNameContainer > SAL_CALL getParameters( ) override;
+
+ // XServiceInfo
+ virtual OUString SAL_CALL getImplementationName() override;
+ virtual css::uno::Sequence<OUString> SAL_CALL
+ getSupportedServiceNames() override;
+
+ // XPropertySet
+ virtual css::uno::Reference<css::beans::XPropertySetInfo> SAL_CALL
+ getPropertySetInfo() override;
virtual void SAL_CALL setPropertyValue(
const OUString& rPropertyName,
const css::uno::Any& rValue) override;
-
virtual css::uno::Any SAL_CALL getPropertyValue(
const OUString& rPropertyName) override;
+
+ // XComponent
+ virtual void SAL_CALL dispose() override;
+ virtual void SAL_CALL addEventListener(
+ const css::uno::Reference<css::lang::XEventListener> & xListener) override;
+ virtual void SAL_CALL removeEventListener(
+ const css::uno::Reference<css::lang::XEventListener> & xListener) override;
+
+ // XTextContent
+ virtual void SAL_CALL attach(
+ const css::uno::Reference<css::text::XTextRange> & xTextRange) override;
+ virtual css::uno::Reference<css::text::XTextRange> SAL_CALL getAnchor() override;
+
+ // XTextField
+ virtual OUString SAL_CALL getPresentation(sal_Bool bShowCommand) override;
+
+ // XFormField
+ virtual OUString SAL_CALL getFieldType() override;
+ virtual void SAL_CALL setFieldType(const OUString& description) override;
+ virtual css::uno::Reference<css::container::XNameContainer> SAL_CALL getParameters() override;
+
};
#endif // INCLUDED_SW_SOURCE_CORE_INC_UNOBOOKMARK_HXX
diff --git a/sw/source/core/unocore/unobkm.cxx b/sw/source/core/unocore/unobkm.cxx
index ddeaccf1966b..a7848b6cc9d6 100644
--- a/sw/source/core/unocore/unobkm.cxx
+++ b/sw/source/core/unocore/unobkm.cxx
@@ -141,6 +141,11 @@ IDocumentMarkAccess* SwXBookmark::GetIDocumentMarkAccess()
return m_pImpl->m_pDoc->getIDocumentMarkAccess();
}
+SwDoc * SwXBookmark::GetDoc()
+{
+ return m_pImpl->m_pDoc;
+}
+
SwXBookmark::SwXBookmark(SwDoc *const pDoc)
: m_pImpl( new SwXBookmark::Impl(pDoc) )
{
@@ -521,11 +526,6 @@ SwXBookmark::removeVetoableChangeListener(
OSL_FAIL("SwXBookmark::removeVetoableChangeListener(): not implemented");
}
-SwXFieldmark::SwXFieldmark(bool _isReplacementObject, SwDoc* pDc)
- : SwXFieldmark_Base(pDc)
- , isReplacementObject(_isReplacementObject)
-{ }
-
void SwXFieldmarkParameters::insertByName(const OUString& aName, const uno::Any& aElement)
{
SolarMutexGuard aGuard;
@@ -600,6 +600,36 @@ IFieldmark::parameter_map_t* SwXFieldmarkParameters::getCoreParameters()
return m_pFieldmark->GetParameters();
}
+SwXFieldmark::SwXFieldmark(bool const isReplacementObject_, SwDoc *const pDoc)
+ : SwXFieldmark_Base(pDoc)
+ , isReplacementObject(isReplacementObject_)
+{
+}
+
+OUString SAL_CALL
+SwXFieldmark::getImplementationName()
+{
+ return "SwXFieldmark";
+}
+
+uno::Sequence<OUString> SAL_CALL
+SwXFieldmark::getSupportedServiceNames()
+{
+ // is const, no lock needed
+ if (isReplacementObject)
+ {
+ return {"com.sun.star.text.TextContent",
+ "com.sun.star.text.Bookmark",
+ "com.sun.star.text.FormFieldmark"};
+ }
+ else
+ {
+ return {"com.sun.star.text.TextContent",
+ "com.sun.star.text.Bookmark",
+ "com.sun.star.text.Fieldmark"};
+ }
+}
+
void SwXFieldmark::attachToRange( const uno::Reference < text::XTextRange >& xTextRange )
{
@@ -634,8 +664,17 @@ void SwXFieldmark::setFieldType(const OUString & fieldType)
}
}
- // We did not generate a new fieldmark, so set the type ID
- pBkm->SetFieldname(fieldType);
+ if ((!isReplacementObject && (fieldType == ODF_UNHANDLED
+ || fieldType == ODF_FORMDATE
+ || fieldType == ODF_FORMTEXT))
+ || (isReplacementObject && (fieldType == ODF_FORMCHECKBOX
+ || fieldType == ODF_FORMDROPDOWN)))
+ {
+ pBkm->SetFieldname(fieldType);
+ return;
+ }
+
+ throw uno::RuntimeException("changing to that type isn't implemented");
}
}
@@ -676,7 +715,7 @@ SwXFieldmark::CreateXFieldmark(SwDoc & rDoc, ::sw::mark::IMark *const pMark,
else
pXBkmk = new SwXFieldmark(isReplacementObject, &rDoc);
- xMark.set(pXBkmk);
+ xMark.set(static_cast<::cppu::OWeakObject*>(pXBkmk), uno::UNO_QUERY); // work around ambiguous base
pXBkmk->registerInMark(*pXBkmk, pMarkBase);
}
return xMark;
@@ -713,8 +752,7 @@ SwXFieldmark::setPropertyValue(const OUString& PropertyName,
pCheckboxFm->SetChecked( bChecked );
}
- else
- SwXFieldmark_Base::setPropertyValue( PropertyName, rValue );
+ // this doesn't support any SwXBookmark property
}
// support 'hidden' "Checked" property ( note: this property is just for convenience to support
@@ -731,7 +769,113 @@ uno::Any SAL_CALL SwXFieldmark::getPropertyValue(const OUString& rPropertyName)
return uno::makeAny( pCheckboxFm->IsChecked() );
}
- return SwXFieldmark_Base::getPropertyValue( rPropertyName );
+ return uno::Any(); // this doesn't support any SwXBookmark property
+}
+
+uno::Reference<beans::XPropertySetInfo> SAL_CALL
+SwXFieldmark::getPropertySetInfo()
+{
+ SolarMutexGuard g;
+
+ static uno::Reference<beans::XPropertySetInfo> const xRef(
+ aSwMapProvider.GetPropertySet(PROPERTY_MAP_FIELDMARK)
+ ->getPropertySetInfo() );
+ return xRef;
+}
+
+// XComponent
+void SAL_CALL SwXFieldmark::dispose()
+{
+ return SwXBookmark::dispose();
+}
+void SAL_CALL SwXFieldmark::addEventListener(
+ uno::Reference<lang::XEventListener> const& xListener)
+{
+ return SwXBookmark::addEventListener(xListener);
+}
+void SAL_CALL SwXFieldmark::removeEventListener(
+ uno::Reference<lang::XEventListener> const& xListener)
+{
+ return SwXBookmark::removeEventListener(xListener);
+}
+
+// XTextContent
+void SAL_CALL SwXFieldmark::attach(
+ uno::Reference<text::XTextRange> const& xTextRange)
+{
+ return SwXBookmark::attach(xTextRange);
+}
+
+uno::Reference<text::XTextRange> SAL_CALL SwXFieldmark::getAnchor()
+{
+ return SwXBookmark::getAnchor();
+}
+
+uno::Reference<text::XTextRange>
+SwXFieldmark::GetCommand(IFieldmark const& rMark)
+{
+ SwPosition const sepPos(sw::mark::FindFieldSep(rMark));
+ SwPosition start(rMark.GetMarkStart());
+ ++start.nContent;
+ return SwXTextRange::CreateXTextRange(*GetDoc(), start, &sepPos);
+}
+
+uno::Reference<text::XTextRange>
+SwXFieldmark::GetResult(IFieldmark const& rMark)
+{
+ SwPosition sepPos(sw::mark::FindFieldSep(rMark));
+ ++sepPos.nContent;
+ SwPosition const& rEnd(rMark.GetMarkEnd());
+ return SwXTextRange::CreateXTextRange(*GetDoc(), sepPos, &rEnd);
+}
+
+// XTextField
+OUString SAL_CALL
+SwXFieldmark::getPresentation(sal_Bool const bShowCommand)
+{
+ SolarMutexGuard g;
+
+ IFieldmark const*const pMark(dynamic_cast<IFieldmark*>(GetBookmark()));
+ if (!pMark)
+ {
+ throw lang::DisposedException();
+ }
+
+ if (bShowCommand)
+ {
+ if (isReplacementObject)
+ {
+ return OUString();
+ }
+ else
+ { // also for ODF_FORMDATE, which shouldn't be a fieldmark...
+ uno::Reference<text::XTextRange> const xCommand(GetCommand(*pMark));
+ return xCommand->getString();
+ }
+ }
+ else
+ {
+ OUString const type(getFieldType());
+ if (type == ODF_FORMCHECKBOX)
+ {
+ ::sw::mark::ICheckboxFieldmark const*const pCheckboxFm(
+ dynamic_cast<ICheckboxFieldmark const*>(pMark));
+ assert(pCheckboxFm);
+ return pCheckboxFm->IsChecked()
+ ? OUString(u"\u2612")
+ : OUString(u"\u2610");
+ }
+ else if (type == ODF_FORMDROPDOWN)
+ {
+ return sw::mark::ExpandFieldmark(const_cast<IFieldmark *>(pMark));
+ }
+ else
+ {
+ assert(!isReplacementObject);
+ uno::Reference<text::XTextRange> const xResult(GetResult(*pMark));
+ return xResult->getString();
+ }
+ }
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/core/unocore/unofield.cxx b/sw/source/core/unocore/unofield.cxx
index b5b7f4e1a88e..a3a0a010ff6d 100644
--- a/sw/source/core/unocore/unofield.cxx
+++ b/sw/source/core/unocore/unofield.cxx
@@ -26,6 +26,7 @@
#include <unofield.hxx>
#include <unofieldcoll.hxx>
+#include <unobookmark.hxx>
#include <swtypes.hxx>
#include <cmdid.h>
#include <doc.hxx>
@@ -3039,6 +3040,12 @@ SwXFieldEnumeration::SwXFieldEnumeration(SwDoc & rDoc)
{
m_pImpl->m_Items.push_back( rMetaField );
}
+ // also add fieldmarks
+ IDocumentMarkAccess& rMarksAccess(*rDoc.getIDocumentMarkAccess());
+ for (auto iter = rMarksAccess.getFieldmarksBegin(); iter != rMarksAccess.getFieldmarksEnd(); ++iter)
+ {
+ m_pImpl->m_Items.emplace_back(SwXFieldmark::CreateXFieldmark(rDoc, *iter), uno::UNO_QUERY);
+ }
}
SwXFieldEnumeration::~SwXFieldEnumeration()
diff --git a/sw/source/core/unocore/unomap.cxx b/sw/source/core/unocore/unomap.cxx
index 05695e8585b2..36053d46f136 100644
--- a/sw/source/core/unocore/unomap.cxx
+++ b/sw/source/core/unocore/unomap.cxx
@@ -604,6 +604,17 @@ const SfxItemPropertyMapEntry* SwUnoPropertyMapProvider::GetPropertyMapEntries(s
m_aMapEntriesArr[nPropertyId] = GetBookmarkPropertyMap();
}
break;
+ case PROPERTY_MAP_FIELDMARK:
+ {
+ static SfxItemPropertyMapEntry const aFieldmarkMap_Impl[] =
+ {
+ // FIXME: is this supposed to actually exist as UNO property, or is it supposed to be in the "parameters" of the field?
+ { u"Checked", 0, cppu::UnoType<bool>::get(), PROPERTY_NONE, 0},
+ { u"", 0, css::uno::Type(), 0, 0 }
+ };
+ m_aMapEntriesArr[nPropertyId] = aFieldmarkMap_Impl;
+ }
+ break;
case PROPERTY_MAP_PARAGRAPH_EXTENSIONS:
{
m_aMapEntriesArr[nPropertyId] = GetParagraphExtensionsPropertyMap();
diff --git a/sw/source/core/unocore/unomap1.cxx b/sw/source/core/unocore/unomap1.cxx
index 7796adb8e798..8d6c33589eb2 100644
--- a/sw/source/core/unocore/unomap1.cxx
+++ b/sw/source/core/unocore/unomap1.cxx
@@ -1247,6 +1247,12 @@ const SfxItemPropertySet* SwUnoPropertyMapProvider::GetPropertySet( sal_uInt16
m_aPropertySetArr[nPropertyId] = &aPROPERTY_MAP_BOOKMARK;
}
break;
+ case PROPERTY_MAP_FIELDMARK:
+ {
+ static SfxItemPropertySet aPROPERTY_MAP_FIELDMARK(pEntries);
+ m_aPropertySetArr[nPropertyId] = &aPROPERTY_MAP_FIELDMARK;
+ }
+ break;
case PROPERTY_MAP_PARAGRAPH_EXTENSIONS:
{
static SfxItemPropertySet aPROPERTY_MAP_PARAGRAPH_EXTENSIONS(pEntries);
diff --git a/writerfilter/source/dmapper/DomainMapper_Impl.cxx b/writerfilter/source/dmapper/DomainMapper_Impl.cxx
index c5dae0441317..4f29b26bb9de 100644
--- a/writerfilter/source/dmapper/DomainMapper_Impl.cxx
+++ b/writerfilter/source/dmapper/DomainMapper_Impl.cxx
@@ -3569,6 +3569,20 @@ FieldContext::~FieldContext()
{
}
+void FieldContext::SetTextField(uno::Reference<text::XTextField> const& xTextField)
+{
+#ifndef NDEBUG
+ if (xTextField.is())
+ {
+ uno::Reference<lang::XServiceInfo> const xServiceInfo(xTextField, uno::UNO_QUERY);
+ assert(xServiceInfo.is());
+ // those must be set by SetFormField()
+ assert(!xServiceInfo->supportsService("com.sun.star.text.Fieldmark")
+ && !xServiceInfo->supportsService("com.sun.star.text.FormFieldmark"));
+ }
+#endif
+ m_xTextField = xTextField;
+}
void FieldContext::AppendCommand(const OUString& rPart)
{
@@ -4975,8 +4989,7 @@ void DomainMapper_Impl::CloseFieldCommand()
case FIELD_FORMDROPDOWN :
case FIELD_FORMTEXT :
{
- uno::Reference< text::XTextField > xTextField( xFieldInterface, uno::UNO_QUERY );
- if ( !xTextField.is() )
+ if (bCreateEnhancedField)
{
FFDataHandler::Pointer_t
pFFDataHandler(pContext->getFFDataHandler());
@@ -5454,6 +5467,11 @@ void DomainMapper_Impl::CloseFieldCommand()
uno::makeAny( lcl_ParseNumberingType(pContext->GetCommand()) ));
break;
}
+
+ if (!bCreateEnhancedField)
+ {
+ pContext->SetTextField( uno::Reference<text::XTextField>(xFieldInterface, uno::UNO_QUERY) );
+ }
}
else
{
@@ -5487,8 +5505,6 @@ void DomainMapper_Impl::CloseFieldCommand()
else
m_bParaHadField = false;
}
- //set the text field if there is any
- pContext->SetTextField( uno::Reference< text::XTextField >( xFieldInterface, uno::UNO_QUERY ) );
}
catch( const uno::Exception& )
{
diff --git a/writerfilter/source/dmapper/DomainMapper_Impl.hxx b/writerfilter/source/dmapper/DomainMapper_Impl.hxx
index 2f264c4c9c19..655c631da899 100644
--- a/writerfilter/source/dmapper/DomainMapper_Impl.hxx
+++ b/writerfilter/source/dmapper/DomainMapper_Impl.hxx
@@ -196,7 +196,7 @@ public:
const css::uno::Reference<css::beans::XPropertySet>& GetCustomField() const { return m_xCustomField; }
void SetCustomField(css::uno::Reference<css::beans::XPropertySet> const& xCustomField) { m_xCustomField = xCustomField; }
const css::uno::Reference<css::text::XTextField>& GetTextField() const { return m_xTextField;}
- void SetTextField(css::uno::Reference<css::text::XTextField> const& xTextField) { m_xTextField = xTextField;}
+ void SetTextField(css::uno::Reference<css::text::XTextField> const& xTextField);
const css::uno::Reference<css::text::XFormField>& GetFormField() const { return m_xFormField;}
void SetFormField(css::uno::Reference<css::text::XFormField> const& xFormField) { m_xFormField = xFormField;}
More information about the Libreoffice-commits
mailing list