summaryrefslogtreecommitdiffstats
path: root/sw/source/core/unocore
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-15 05:54:39 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-15 05:54:39 +0000
commit267c6f2ac71f92999e969232431ba04678e7437e (patch)
tree358c9467650e1d0a1d7227a21dac2e3d08b622b2 /sw/source/core/unocore
parentInitial commit. (diff)
downloadlibreoffice-267c6f2ac71f92999e969232431ba04678e7437e.tar.xz
libreoffice-267c6f2ac71f92999e969232431ba04678e7437e.zip
Adding upstream version 4:24.2.0.upstream/4%24.2.0
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'sw/source/core/unocore')
-rw-r--r--sw/source/core/unocore/SwXTextDefaults.cxx235
-rw-r--r--sw/source/core/unocore/TextCursorHelper.cxx25
-rw-r--r--sw/source/core/unocore/XMLRangeHelper.cxx387
-rw-r--r--sw/source/core/unocore/XMLRangeHelper.hxx68
-rw-r--r--sw/source/core/unocore/swunohelper.cxx337
-rw-r--r--sw/source/core/unocore/unobkm.cxx863
-rw-r--r--sw/source/core/unocore/unochart.cxx2695
-rw-r--r--sw/source/core/unocore/unocoll.cxx1871
-rw-r--r--sw/source/core/unocore/unocontentcontrol.cxx1458
-rw-r--r--sw/source/core/unocore/unocrsr.cxx216
-rw-r--r--sw/source/core/unocore/unocrsrhelper.cxx1587
-rw-r--r--sw/source/core/unocore/unodraw.cxx2876
-rw-r--r--sw/source/core/unocore/unoevent.cxx233
-rw-r--r--sw/source/core/unocore/unofield.cxx3024
-rw-r--r--sw/source/core/unocore/unoflatpara.cxx581
-rw-r--r--sw/source/core/unocore/unoframe.cxx3691
-rw-r--r--sw/source/core/unocore/unoftn.cxx538
-rw-r--r--sw/source/core/unocore/unoidx.cxx3086
-rw-r--r--sw/source/core/unocore/unolinebreak.cxx283
-rw-r--r--sw/source/core/unocore/unomap.cxx1558
-rw-r--r--sw/source/core/unocore/unomap1.cxx1737
-rw-r--r--sw/source/core/unocore/unomapproperties.hxx584
-rw-r--r--sw/source/core/unocore/unoobj.cxx3123
-rw-r--r--sw/source/core/unocore/unoobj2.cxx1860
-rw-r--r--sw/source/core/unocore/unoparagraph.cxx1457
-rw-r--r--sw/source/core/unocore/unoport.cxx871
-rw-r--r--sw/source/core/unocore/unoportenum.cxx1526
-rw-r--r--sw/source/core/unocore/unoredline.cxx581
-rw-r--r--sw/source/core/unocore/unoredlines.cxx162
-rw-r--r--sw/source/core/unocore/unorefmk.cxx1475
-rw-r--r--sw/source/core/unocore/unosect.cxx1730
-rw-r--r--sw/source/core/unocore/unosett.cxx2126
-rw-r--r--sw/source/core/unocore/unosrch.cxx603
-rw-r--r--sw/source/core/unocore/unostyle.cxx5614
-rw-r--r--sw/source/core/unocore/unotbl.cxx4116
-rw-r--r--sw/source/core/unocore/unotext.cxx2706
-rw-r--r--sw/source/core/unocore/unotextmarkup.cxx514
37 files changed, 56397 insertions, 0 deletions
diff --git a/sw/source/core/unocore/SwXTextDefaults.cxx b/sw/source/core/unocore/SwXTextDefaults.cxx
new file mode 100644
index 0000000000..a74808141d
--- /dev/null
+++ b/sw/source/core/unocore/SwXTextDefaults.cxx
@@ -0,0 +1,235 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <com/sun/star/beans/PropertyAttribute.hpp>
+
+#include <vcl/svapp.hxx>
+#include <osl/diagnose.h>
+#include <svl/itemprop.hxx>
+
+#include <SwXTextDefaults.hxx>
+#include <SwStyleNameMapper.hxx>
+#include <fchrfmt.hxx>
+#include <charfmt.hxx>
+#include <cppuhelper/supportsservice.hxx>
+#include <docstyle.hxx>
+#include <doc.hxx>
+#include <docsh.hxx>
+#include <unomap.hxx>
+#include <unomid.h>
+#include <paratr.hxx>
+#include <unocrsrhelper.hxx>
+#include <hintids.hxx>
+#include <fmtpdsc.hxx>
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::lang;
+
+SwXTextDefaults::SwXTextDefaults ( SwDoc * pNewDoc ) :
+ m_pPropSet( aSwMapProvider.GetPropertySet( PROPERTY_MAP_TEXT_DEFAULT ) ),
+ m_pDoc ( pNewDoc )
+{
+}
+
+SwXTextDefaults::~SwXTextDefaults ()
+{
+}
+
+uno::Reference< XPropertySetInfo > SAL_CALL SwXTextDefaults::getPropertySetInfo( )
+{
+ static uno::Reference < XPropertySetInfo > xRef = m_pPropSet->getPropertySetInfo();
+ return xRef;
+}
+
+void SAL_CALL SwXTextDefaults::setPropertyValue( const OUString& rPropertyName, const Any& aValue )
+{
+ SolarMutexGuard aGuard;
+ if (!m_pDoc)
+ throw RuntimeException();
+ const SfxItemPropertyMapEntry *pMap = m_pPropSet->getPropertyMap().getByName( rPropertyName );
+ if (!pMap)
+ throw UnknownPropertyException( "Unknown property: " + rPropertyName, getXWeak() );
+ if ( pMap->nFlags & PropertyAttribute::READONLY)
+ throw PropertyVetoException ( "Property is read-only: " + rPropertyName, getXWeak() );
+
+ const SfxPoolItem& rItem = m_pDoc->GetDefault(pMap->nWID);
+ if (RES_PAGEDESC == pMap->nWID && MID_PAGEDESC_PAGEDESCNAME == pMap->nMemberId)
+ {
+ SfxItemSetFixed<RES_PAGEDESC, RES_PAGEDESC> aSet( m_pDoc->GetAttrPool() );
+ aSet.Put(rItem);
+ SwUnoCursorHelper::SetPageDesc( aValue, *m_pDoc, aSet );
+ m_pDoc->SetDefault(aSet.Get(RES_PAGEDESC));
+ }
+ else if ((RES_PARATR_DROP == pMap->nWID && MID_DROPCAP_CHAR_STYLE_NAME == pMap->nMemberId) ||
+ (RES_TXTATR_CHARFMT == pMap->nWID))
+ {
+ OUString uStyle;
+ if(!(aValue >>= uStyle))
+ throw lang::IllegalArgumentException();
+
+ OUString sStyle;
+ SwStyleNameMapper::FillUIName(uStyle, sStyle, SwGetPoolIdFromName::ChrFmt );
+ SwDocStyleSheet* pStyle =
+ static_cast<SwDocStyleSheet*>(m_pDoc->GetDocShell()->GetStyleSheetPool()->Find(sStyle, SfxStyleFamily::Char));
+ std::unique_ptr<SwFormatDrop> pDrop;
+ std::unique_ptr<SwFormatCharFormat> pCharFormat;
+ if(!pStyle)
+ throw lang::IllegalArgumentException();
+
+ rtl::Reference< SwDocStyleSheet > xStyle( new SwDocStyleSheet( *pStyle ) );
+ if (xStyle->GetCharFormat() == m_pDoc->GetDfltCharFormat())
+ return; // don't SetCharFormat with formats from mpDfltCharFormat
+
+ if (RES_PARATR_DROP == pMap->nWID)
+ {
+ pDrop.reset(static_cast<SwFormatDrop*>(rItem.Clone())); // because rItem is const...
+ pDrop->SetCharFormat(xStyle->GetCharFormat());
+ m_pDoc->SetDefault(*pDrop);
+ }
+ else // RES_TXTATR_CHARFMT == pMap->nWID
+ {
+ pCharFormat.reset(static_cast<SwFormatCharFormat*>(rItem.Clone())); // because rItem is const...
+ pCharFormat->SetCharFormat(xStyle->GetCharFormat());
+ m_pDoc->SetDefault(*pCharFormat);
+ }
+ }
+ else
+ {
+ std::unique_ptr<SfxPoolItem> pNewItem(rItem.Clone());
+ pNewItem->PutValue( aValue, pMap->nMemberId);
+ m_pDoc->SetDefault(*pNewItem);
+ }
+}
+
+Any SAL_CALL SwXTextDefaults::getPropertyValue( const OUString& rPropertyName )
+{
+ SolarMutexGuard aGuard;
+ if (!m_pDoc)
+ throw RuntimeException();
+ const SfxItemPropertyMapEntry *pMap = m_pPropSet->getPropertyMap().getByName( rPropertyName );
+ if (!pMap)
+ throw UnknownPropertyException( "Unknown property: " + rPropertyName, getXWeak() );
+ Any aRet;
+ const SfxPoolItem& rItem = m_pDoc->GetDefault(pMap->nWID);
+ rItem.QueryValue( aRet, pMap->nMemberId );
+ return aRet;
+}
+
+void SAL_CALL SwXTextDefaults::addPropertyChangeListener( const OUString& /*rPropertyName*/, const uno::Reference< XPropertyChangeListener >& /*xListener*/ )
+{
+ OSL_FAIL ( "not implemented" );
+}
+
+void SAL_CALL SwXTextDefaults::removePropertyChangeListener( const OUString& /*rPropertyName*/, const uno::Reference< XPropertyChangeListener >& /*xListener*/ )
+{
+ OSL_FAIL ( "not implemented" );
+}
+
+void SAL_CALL SwXTextDefaults::addVetoableChangeListener( const OUString& /*rPropertyName*/, const uno::Reference< XVetoableChangeListener >& /*xListener*/ )
+{
+ OSL_FAIL ( "not implemented" );
+}
+
+void SAL_CALL SwXTextDefaults::removeVetoableChangeListener( const OUString& /*rPropertyName*/, const uno::Reference< XVetoableChangeListener >& /*xListener*/ )
+{
+ OSL_FAIL ( "not implemented" );
+}
+
+// XPropertyState
+PropertyState SAL_CALL SwXTextDefaults::getPropertyState( const OUString& rPropertyName )
+{
+ SolarMutexGuard aGuard;
+ PropertyState eRet = PropertyState_DIRECT_VALUE;
+ if (!m_pDoc)
+ throw RuntimeException();
+ const SfxItemPropertyMapEntry *pMap = m_pPropSet->getPropertyMap().getByName( rPropertyName );
+ if (!pMap)
+ throw UnknownPropertyException( "Unknown property: " + rPropertyName, getXWeak() );
+
+ const SfxPoolItem& rItem = m_pDoc->GetDefault(pMap->nWID);
+ if (IsStaticDefaultItem ( &rItem ) )
+ eRet = PropertyState_DEFAULT_VALUE;
+ return eRet;
+}
+
+Sequence< PropertyState > SAL_CALL SwXTextDefaults::getPropertyStates( const Sequence< OUString >& rPropertyNames )
+{
+ const sal_Int32 nCount = rPropertyNames.getLength();
+ Sequence < PropertyState > aRet ( nCount );
+
+ std::transform(rPropertyNames.begin(), rPropertyNames.end(), aRet.getArray(),
+ [this](const OUString& rName) -> PropertyState { return getPropertyState(rName); });
+
+ return aRet;
+}
+
+void SAL_CALL SwXTextDefaults::setPropertyToDefault( const OUString& rPropertyName )
+{
+ if (!m_pDoc)
+ throw RuntimeException();
+ const SfxItemPropertyMapEntry *pMap = m_pPropSet->getPropertyMap().getByName( rPropertyName );
+ if (!pMap)
+ throw UnknownPropertyException( "Unknown property: " + rPropertyName, getXWeak() );
+ if ( pMap->nFlags & PropertyAttribute::READONLY)
+ throw RuntimeException( "setPropertyToDefault: property is read-only: " + rPropertyName, getXWeak() );
+ SfxItemPool& rSet (m_pDoc->GetAttrPool());
+ rSet.ResetPoolDefaultItem ( pMap->nWID );
+}
+
+Any SAL_CALL SwXTextDefaults::getPropertyDefault( const OUString& rPropertyName )
+{
+ if (!m_pDoc)
+ throw RuntimeException();
+ const SfxItemPropertyMapEntry *pMap = m_pPropSet->getPropertyMap().getByName( rPropertyName );
+ if (!pMap)
+ throw UnknownPropertyException( "Unknown property: " + rPropertyName, getXWeak() );
+ Any aRet;
+ SfxItemPool& rSet (m_pDoc->GetAttrPool());
+ SfxPoolItem const*const pItem = rSet.GetPoolDefaultItem(pMap->nWID);
+ if (pItem)
+ {
+ pItem->QueryValue( aRet, pMap->nMemberId );
+ }
+ return aRet;
+}
+
+OUString SAL_CALL SwXTextDefaults::getImplementationName( )
+{
+ return "SwXTextDefaults";
+}
+
+sal_Bool SAL_CALL SwXTextDefaults::supportsService( const OUString& rServiceName )
+{
+ return cppu::supportsService(this, rServiceName);
+}
+
+uno::Sequence< OUString > SAL_CALL SwXTextDefaults::getSupportedServiceNames( )
+{
+ return { "com.sun.star.text.Defaults",
+ "com.sun.star.style.CharacterProperties",
+ "com.sun.star.style.CharacterPropertiesAsian",
+ "com.sun.star.style.CharacterPropertiesComplex",
+ "com.sun.star.style.ParagraphProperties",
+ "com.sun.star.style.ParagraphPropertiesAsian",
+ "com.sun.star.style.ParagraphPropertiesComplex" };
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/core/unocore/TextCursorHelper.cxx b/sw/source/core/unocore/TextCursorHelper.cxx
new file mode 100644
index 0000000000..fad4ebe0ab
--- /dev/null
+++ b/sw/source/core/unocore/TextCursorHelper.cxx
@@ -0,0 +1,25 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <TextCursorHelper.hxx>
+#include <comphelper/servicehelper.hxx>
+
+OTextCursorHelper::~OTextCursorHelper() {}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/core/unocore/XMLRangeHelper.cxx b/sw/source/core/unocore/XMLRangeHelper.cxx
new file mode 100644
index 0000000000..6464543d51
--- /dev/null
+++ b/sw/source/core/unocore/XMLRangeHelper.cxx
@@ -0,0 +1,387 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include "XMLRangeHelper.hxx"
+#include <rtl/character.hxx>
+#include <rtl/ustrbuf.hxx>
+#include <o3tl/string_view.hxx>
+#include <algorithm>
+
+namespace
+{
+/** unary function that escapes backslashes and single quotes in a sal_Unicode
+ array (which you can get from an OUString with getStr()) and puts the result
+ into the OUStringBuffer given in the CTOR
+ */
+class lcl_Escape
+{
+public:
+ explicit lcl_Escape( OUStringBuffer & aResultBuffer ) : m_aResultBuffer( aResultBuffer ) {}
+ void operator() ( sal_Unicode aChar )
+ {
+ static const sal_Unicode s_aQuote( '\'' );
+ static const sal_Unicode s_aBackslash( '\\' );
+
+ if( aChar == s_aQuote ||
+ aChar == s_aBackslash )
+ m_aResultBuffer.append( s_aBackslash );
+ m_aResultBuffer.append( aChar );
+ }
+
+private:
+ OUStringBuffer & m_aResultBuffer;
+};
+
+/** unary function that removes backslash escapes in a sal_Unicode array (which
+ you can get from an OUString with getStr()) and puts the result into the
+ OUStringBuffer given in the CTOR
+ */
+class lcl_UnEscape
+{
+public:
+ explicit lcl_UnEscape( OUStringBuffer & aResultBuffer ) : m_aResultBuffer( aResultBuffer ) {}
+ void operator() ( sal_Unicode aChar )
+ {
+ static const sal_Unicode s_aBackslash( '\\' );
+
+ if( aChar != s_aBackslash )
+ m_aResultBuffer.append( aChar );
+ }
+
+private:
+ OUStringBuffer & m_aResultBuffer;
+};
+
+void lcl_getXMLStringForCell( const /*::chart::*/XMLRangeHelper::Cell & rCell, OUStringBuffer * output )
+{
+ assert(output != nullptr);
+
+ if( rCell.empty())
+ return;
+
+ sal_Int32 nCol = rCell.nColumn;
+ output->append( '.' );
+ if( ! rCell.bRelativeColumn )
+ output->append( '$' );
+
+ // get A, B, C, ..., AA, AB, ... representation of column number
+ if( nCol < 26 )
+ output->append( static_cast<sal_Unicode>('A' + nCol) );
+ else if( nCol < 702 )
+ {
+ output->append( static_cast<sal_Unicode>('A' + nCol / 26 - 1 ));
+ output->append( static_cast<sal_Unicode>('A' + nCol % 26) );
+ }
+ else // works for nCol <= 18,278
+ {
+ output->append( static_cast<sal_Unicode>('A' + nCol / 702 - 1 ));
+ output->append( static_cast<sal_Unicode>('A' + (nCol % 702) / 26 ));
+ output->append( static_cast<sal_Unicode>('A' + nCol % 26) );
+ }
+
+ // write row number as number
+ if( ! rCell.bRelativeRow )
+ output->append( '$' );
+ output->append( rCell.nRow + sal_Int32(1) );
+}
+
+void lcl_getSingleCellAddressFromXMLString(
+ std::u16string_view rXMLString,
+ sal_Int32 nStartPos, sal_Int32 nEndPos,
+ /*::chart::*/XMLRangeHelper::Cell & rOutCell )
+{
+ // expect "\$?[a-zA-Z]+\$?[1-9][0-9]*"
+ static const sal_Unicode aDollar( '$' );
+ static const sal_Unicode aLetterA( 'A' );
+
+ OUString aCellStr = OUString(rXMLString.substr( nStartPos, nEndPos - nStartPos + 1 )).toAsciiUpperCase();
+ const sal_Unicode* pStrArray = aCellStr.getStr();
+ sal_Int32 nLength = aCellStr.getLength();
+ sal_Int32 i = nLength - 1, nColumn = 0;
+
+ // parse number for row
+ while( rtl::isAsciiDigit( pStrArray[ i ] ) && i >= 0 )
+ i--;
+ rOutCell.nRow = (o3tl::toInt32(aCellStr.subView( i + 1 ))) - 1;
+ // a dollar in XML means absolute (whereas in UI it means relative)
+ if( pStrArray[ i ] == aDollar )
+ {
+ i--;
+ rOutCell.bRelativeRow = false;
+ }
+ else
+ rOutCell.bRelativeRow = true;
+
+ // parse rest for column
+ sal_Int32 nPower = 1;
+ while( rtl::isAsciiAlpha( pStrArray[ i ] ))
+ {
+ nColumn += (pStrArray[ i ] - aLetterA + 1) * nPower;
+ i--;
+ nPower *= 26;
+ }
+ rOutCell.nColumn = nColumn - 1;
+
+ rOutCell.bRelativeColumn = true;
+ if( i >= 0 &&
+ pStrArray[ i ] == aDollar )
+ rOutCell.bRelativeColumn = false;
+ rOutCell.bIsEmpty = false;
+}
+
+bool lcl_getCellAddressFromXMLString(
+ const OUString& rXMLString,
+ sal_Int32 nStartPos, sal_Int32 nEndPos,
+ /*::chart::*/XMLRangeHelper::Cell & rOutCell,
+ OUString& rOutTableName )
+{
+ static const sal_Unicode aDot( '.' );
+ static const sal_Unicode aQuote( '\'' );
+ static const sal_Unicode aBackslash( '\\' );
+
+ sal_Int32 nNextDelimiterPos = nStartPos;
+
+ sal_Int32 nDelimiterPos = nStartPos;
+ bool bInQuotation = false;
+ // parse table name
+ while( nDelimiterPos < nEndPos &&
+ ( bInQuotation || rXMLString[ nDelimiterPos ] != aDot ))
+ {
+ // skip escaped characters (with backslash)
+ if( rXMLString[ nDelimiterPos ] == aBackslash )
+ ++nDelimiterPos;
+ // toggle quotation mode when finding single quotes
+ else if( rXMLString[ nDelimiterPos ] == aQuote )
+ bInQuotation = ! bInQuotation;
+
+ ++nDelimiterPos;
+ }
+
+ if( nDelimiterPos == -1 ||
+ nDelimiterPos >= nEndPos )
+ {
+ return false;
+ }
+ if( nDelimiterPos > nStartPos )
+ {
+ // there is a table name before the address
+
+ OUStringBuffer aTableNameBuffer;
+ const sal_Unicode * pTableName = rXMLString.getStr();
+
+ // remove escapes from table name
+ std::for_each( pTableName + nStartPos,
+ pTableName + nDelimiterPos,
+ lcl_UnEscape( aTableNameBuffer ));
+
+ // unquote quoted table name
+ const sal_Unicode * pBuf = aTableNameBuffer.getStr();
+ if( pBuf[ 0 ] == aQuote &&
+ pBuf[ aTableNameBuffer.getLength() - 1 ] == aQuote )
+ {
+ OUString aName = aTableNameBuffer.makeStringAndClear();
+ rOutTableName = aName.copy( 1, aName.getLength() - 2 );
+ }
+ else
+ rOutTableName = aTableNameBuffer.makeStringAndClear();
+ }
+
+ for( sal_Int32 i = 0;
+ nNextDelimiterPos < nEndPos;
+ nDelimiterPos = nNextDelimiterPos, i++ )
+ {
+ nNextDelimiterPos = rXMLString.indexOf( aDot, nDelimiterPos + 1 );
+ if( nNextDelimiterPos == -1 ||
+ nNextDelimiterPos > nEndPos )
+ nNextDelimiterPos = nEndPos + 1;
+
+ if( i==0 )
+ // only take first cell
+ lcl_getSingleCellAddressFromXMLString(
+ rXMLString, nDelimiterPos + 1, nNextDelimiterPos - 1, rOutCell );
+ }
+
+ return true;
+}
+
+bool lcl_getCellRangeAddressFromXMLString(
+ const OUString& rXMLString,
+ sal_Int32 nStartPos, sal_Int32 nEndPos,
+ /*::chart::*/XMLRangeHelper::CellRange & rOutRange )
+{
+ bool bResult = true;
+ static const sal_Unicode aColon( ':' );
+ static const sal_Unicode aQuote( '\'' );
+ static const sal_Unicode aBackslash( '\\' );
+
+ sal_Int32 nDelimiterPos = nStartPos;
+ bool bInQuotation = false;
+ // parse table name
+ while( nDelimiterPos < nEndPos &&
+ ( bInQuotation || rXMLString[ nDelimiterPos ] != aColon ))
+ {
+ // skip escaped characters (with backslash)
+ if( rXMLString[ nDelimiterPos ] == aBackslash )
+ ++nDelimiterPos;
+ // toggle quotation mode when finding single quotes
+ else if( rXMLString[ nDelimiterPos ] == aQuote )
+ bInQuotation = ! bInQuotation;
+
+ ++nDelimiterPos;
+ }
+
+ if( nDelimiterPos == nEndPos )
+ {
+ // only one cell
+ bResult = lcl_getCellAddressFromXMLString( rXMLString, nStartPos, nEndPos,
+ rOutRange.aUpperLeft,
+ rOutRange.aTableName );
+ }
+ else
+ {
+ // range (separated by a colon)
+ bResult = lcl_getCellAddressFromXMLString( rXMLString, nStartPos, nDelimiterPos - 1,
+ rOutRange.aUpperLeft,
+ rOutRange.aTableName );
+ OUString sTableSecondName;
+ if( bResult )
+ {
+ bResult = lcl_getCellAddressFromXMLString( rXMLString, nDelimiterPos + 1, nEndPos,
+ rOutRange.aLowerRight,
+ sTableSecondName );
+ }
+ if( bResult &&
+ !sTableSecondName.isEmpty() &&
+ sTableSecondName != rOutRange.aTableName )
+ bResult = false;
+ }
+
+ return bResult;
+}
+
+} // anonymous namespace
+
+namespace XMLRangeHelper
+{
+
+CellRange getCellRangeFromXMLString( const OUString & rXMLString )
+{
+ static const sal_Unicode aSpace( ' ' );
+ static const sal_Unicode aQuote( '\'' );
+ static const sal_Unicode aDollar( '$' );
+ static const sal_Unicode aBackslash( '\\' );
+
+ sal_Int32 nStartPos = 0;
+ sal_Int32 nEndPos = nStartPos;
+ const sal_Int32 nLength = rXMLString.getLength();
+
+ // reset
+ CellRange aResult;
+
+ // iterate over different ranges
+ for( sal_Int32 i = 0;
+ nEndPos < nLength;
+ nStartPos = ++nEndPos, i++ )
+ {
+ // find start point of next range
+
+ // ignore leading '$'
+ if( rXMLString[ nEndPos ] == aDollar)
+ nEndPos++;
+
+ bool bInQuotation = false;
+ // parse range
+ while( nEndPos < nLength &&
+ ( bInQuotation || rXMLString[ nEndPos ] != aSpace ))
+ {
+ // skip escaped characters (with backslash)
+ if( rXMLString[ nEndPos ] == aBackslash )
+ ++nEndPos;
+ // toggle quotation mode when finding single quotes
+ else if( rXMLString[ nEndPos ] == aQuote )
+ bInQuotation = ! bInQuotation;
+
+ ++nEndPos;
+ }
+
+ if( ! lcl_getCellRangeAddressFromXMLString(
+ rXMLString,
+ nStartPos, nEndPos - 1,
+ aResult ))
+ {
+ // if an error occurred, bail out
+ return CellRange();
+ }
+ }
+
+ return aResult;
+}
+
+OUString getXMLStringFromCellRange( const CellRange & rRange )
+{
+ static const sal_Unicode aSpace( ' ' );
+ static const sal_Unicode aQuote( '\'' );
+
+ OUStringBuffer aBuffer;
+
+ if( !rRange.aTableName.isEmpty())
+ {
+ bool bNeedsEscaping = ( rRange.aTableName.indexOf( aQuote ) > -1 );
+ bool bNeedsQuoting = bNeedsEscaping || ( rRange.aTableName.indexOf( aSpace ) > -1 );
+
+ // quote table name if it contains spaces or quotes
+ if( bNeedsQuoting )
+ {
+ // leading quote
+ aBuffer.append( aQuote );
+
+ // escape existing quotes
+ if( bNeedsEscaping )
+ {
+ const sal_Unicode * pTableNameBeg = rRange.aTableName.getStr();
+
+ // append the quoted string at the buffer
+ std::for_each( pTableNameBeg,
+ pTableNameBeg + rRange.aTableName.getLength(),
+ lcl_Escape( aBuffer ) );
+ }
+ else
+ aBuffer.append( rRange.aTableName );
+
+ // final quote
+ aBuffer.append( aQuote );
+ }
+ else
+ aBuffer.append( rRange.aTableName );
+ }
+ lcl_getXMLStringForCell( rRange.aUpperLeft, &aBuffer );
+
+ if( ! rRange.aLowerRight.empty())
+ {
+ // we have a range (not a single cell)
+ aBuffer.append( ':' );
+ lcl_getXMLStringForCell( rRange.aLowerRight, &aBuffer );
+ }
+
+ return aBuffer.makeStringAndClear();
+}
+
+} // namespace XMLRangeHelper
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/core/unocore/XMLRangeHelper.hxx b/sw/source/core/unocore/XMLRangeHelper.hxx
new file mode 100644
index 0000000000..51966860fb
--- /dev/null
+++ b/sw/source/core/unocore/XMLRangeHelper.hxx
@@ -0,0 +1,68 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+//!!
+//!! This file is an exact copy of the same file in chart2 project
+//!!
+
+#ifndef INCLUDED_SW_SOURCE_CORE_UNOCORE_XMLRANGEHELPER_HXX
+#define INCLUDED_SW_SOURCE_CORE_UNOCORE_XMLRANGEHELPER_HXX
+
+#include <sal/types.h>
+#include <rtl/ustring.hxx>
+
+namespace XMLRangeHelper
+{
+
+struct Cell
+{
+ sal_Int32 nColumn;
+ sal_Int32 nRow;
+ bool bRelativeColumn;
+ bool bRelativeRow;
+ bool bIsEmpty;
+
+ Cell() :
+ nColumn(0),
+ nRow(0),
+ bRelativeColumn(false),
+ bRelativeRow(false),
+ bIsEmpty(true)
+ {}
+
+ bool empty() const { return bIsEmpty; }
+};
+
+struct CellRange
+{
+ Cell aUpperLeft;
+ Cell aLowerRight;
+ OUString aTableName;
+};
+
+CellRange getCellRangeFromXMLString( const OUString & rXMLString );
+
+OUString getXMLStringFromCellRange( const CellRange & rRange );
+
+} // namespace XMLRangeHelper
+
+// INCLUDED_SW_SOURCE_CORE_UNOCORE_XMLRANGEHELPER_HXX
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/core/unocore/swunohelper.cxx b/sw/source/core/unocore/swunohelper.cxx
new file mode 100644
index 0000000000..0aab2a681a
--- /dev/null
+++ b/sw/source/core/unocore/swunohelper.cxx
@@ -0,0 +1,337 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <com/sun/star/uno/Sequence.h>
+#include <com/sun/star/uno/Exception.hpp>
+#include <com/sun/star/ucb/UniversalContentBroker.hpp>
+#include <com/sun/star/ucb/XContentIdentifier.hpp>
+#include <com/sun/star/ucb/XCommandEnvironment.hpp>
+#include <com/sun/star/ucb/TransferInfo.hpp>
+#include <com/sun/star/ucb/NameClash.hpp>
+#include <com/sun/star/sdbc/XResultSet.hpp>
+#include <com/sun/star/sdbc/XRow.hpp>
+#include <comphelper/processfactory.hxx>
+#include <comphelper/extract.hxx>
+#include <o3tl/any.hxx>
+#include <tools/urlobj.hxx>
+#include <tools/datetime.hxx>
+#include <comphelper/diagnose_ex.hxx>
+#include <rtl/ustring.hxx>
+#include <osl/diagnose.h>
+#include <ucbhelper/contentidentifier.hxx>
+#include <ucbhelper/content.hxx>
+#include <swunohelper.hxx>
+#include <svx/xdef.hxx>
+#include <svx/xfillit0.hxx>
+#include <editeng/memberids.h>
+#include <svl/itemset.hxx>
+
+using namespace com::sun::star;
+
+namespace SWUnoHelper
+{
+
+sal_Int32 GetEnumAsInt32( const css::uno::Any& rVal )
+{
+ sal_Int32 nReturn = 0;
+ if (! ::cppu::enum2int(nReturn,rVal) )
+ OSL_FAIL( "can't get EnumAsInt32" );
+ return nReturn;
+}
+
+// methods for UCB actions
+bool UCB_DeleteFile( const OUString& rURL )
+{
+ bool bRemoved;
+ try
+ {
+ ucbhelper::Content aTempContent( rURL,
+ css::uno::Reference< css::ucb::XCommandEnvironment >(),
+ comphelper::getProcessComponentContext() );
+ aTempContent.executeCommand("delete", css::uno::Any( true ) );
+ bRemoved = true;
+ }
+ catch( css::uno::Exception& )
+ {
+ bRemoved = false;
+ TOOLS_WARN_EXCEPTION( "sw", "Exception from executeCommand( delete )" );
+ }
+ return bRemoved;
+}
+
+bool UCB_MoveFile( const OUString& rURL, std::u16string_view rNewURL )
+{
+ bool bCopyCompleted = true;
+ try
+ {
+ INetURLObject aURL( rNewURL );
+ const OUString sName(aURL.GetLastName());
+ aURL.removeSegment();
+ const OUString sMainURL( aURL.GetMainURL(INetURLObject::DecodeMechanism::NONE) );
+
+ ucbhelper::Content aTempContent( sMainURL,
+ css::uno::Reference< css::ucb::XCommandEnvironment >(),
+ comphelper::getProcessComponentContext() );
+
+ css::ucb::TransferInfo aInfo;
+ aInfo.NameClash = css::ucb::NameClash::ERROR;
+ aInfo.NewTitle = sName;
+ aInfo.SourceURL = rURL;
+ aInfo.MoveData = true;
+ aTempContent.executeCommand( "transfer", uno::Any(aInfo) );
+ }
+ catch( css::uno::Exception& )
+ {
+ TOOLS_WARN_EXCEPTION( "sw", "Exception from executeCommand( transfer )" );
+ bCopyCompleted = false;
+ }
+ return bCopyCompleted;
+}
+
+bool UCB_IsCaseSensitiveFileName( std::u16string_view rURL )
+{
+ bool bCaseSensitive;
+ try
+ {
+ INetURLObject aTempObj( rURL );
+ aTempObj.SetBase( aTempObj.GetBase().toAsciiLowerCase() );
+ css::uno::Reference< css::ucb::XContentIdentifier > xRef1 = new
+ ucbhelper::ContentIdentifier( aTempObj.GetMainURL( INetURLObject::DecodeMechanism::NONE ));
+
+ aTempObj.SetBase(aTempObj.GetBase().toAsciiUpperCase());
+ css::uno::Reference< css::ucb::XContentIdentifier > xRef2 = new
+ ucbhelper::ContentIdentifier( aTempObj.GetMainURL( INetURLObject::DecodeMechanism::NONE ));
+
+ css::uno::Reference< css::ucb::XUniversalContentBroker > xUcb =
+ css::ucb::UniversalContentBroker::create(comphelper::getProcessComponentContext());
+
+ sal_Int32 nCompare = xUcb->compareContentIds( xRef1, xRef2 );
+ bCaseSensitive = 0 != nCompare;
+ }
+ catch( css::uno::Exception& )
+ {
+ bCaseSensitive = false;
+ TOOLS_WARN_EXCEPTION( "sw", "compareContentIds()" );
+ }
+ return bCaseSensitive;
+}
+
+bool UCB_IsReadOnlyFileName( const OUString& rURL )
+{
+ bool bIsReadOnly = false;
+ try
+ {
+ ucbhelper::Content aCnt( rURL, css::uno::Reference< css::ucb::XCommandEnvironment >(), comphelper::getProcessComponentContext() );
+ css::uno::Any aAny = aCnt.getPropertyValue("IsReadOnly");
+ if(aAny.hasValue())
+ bIsReadOnly = *o3tl::doAccess<bool>(aAny);
+ }
+ catch( css::uno::Exception& )
+ {
+ bIsReadOnly = false;
+ }
+ return bIsReadOnly;
+}
+
+bool UCB_IsFile( const OUString& rURL )
+{
+ bool bExists = false;
+ try
+ {
+ ::ucbhelper::Content aContent( rURL, css::uno::Reference< css::ucb::XCommandEnvironment >(), comphelper::getProcessComponentContext() );
+ bExists = aContent.isDocument();
+ }
+ catch (css::uno::Exception &)
+ {
+ }
+ return bExists;
+}
+
+bool UCB_IsDirectory( const OUString& rURL )
+{
+ bool bExists = false;
+ try
+ {
+ ::ucbhelper::Content aContent( rURL, css::uno::Reference< css::ucb::XCommandEnvironment >(), comphelper::getProcessComponentContext() );
+ bExists = aContent.isFolder();
+ }
+ catch (css::uno::Exception &)
+ {
+ }
+ return bExists;
+}
+
+ // get a list of files from the folder of the URL
+ // options: pExtension = 0 -> all, else this specific extension
+ // pDateTime != 0 -> returns also the modified date/time of
+ // the files in a std::vector<OUString> -->
+ // !! objects must be deleted from the caller!!
+bool UCB_GetFileListOfFolder( const OUString& rURL,
+ std::vector<OUString>& rList,
+ const OUString* pExtension,
+ std::vector< ::DateTime >* pDateTimeList )
+{
+ bool bOk = false;
+ try
+ {
+ ucbhelper::Content aCnt( rURL, css::uno::Reference< css::ucb::XCommandEnvironment >(), comphelper::getProcessComponentContext() );
+ css::uno::Reference< css::sdbc::XResultSet > xResultSet;
+
+ const sal_Int32 nSeqSize = pDateTimeList ? 2 : 1;
+ css::uno::Sequence < OUString > aProps( nSeqSize );
+ OUString* pProps = aProps.getArray();
+ pProps[ 0 ] = "Title";
+ if( pDateTimeList )
+ pProps[ 1 ] = "DateModified";
+
+ try
+ {
+ xResultSet = aCnt.createCursor( aProps, ::ucbhelper::INCLUDE_DOCUMENTS_ONLY );
+ }
+ catch( css::uno::Exception& )
+ {
+ OSL_FAIL( "create cursor failed!" );
+ }
+
+ if( xResultSet.is() )
+ {
+ css::uno::Reference< css::sdbc::XRow > xRow( xResultSet, css::uno::UNO_QUERY );
+ const sal_Int32 nExtLen = pExtension ? pExtension->getLength() : 0;
+ try
+ {
+ if( xResultSet->first() )
+ {
+ do {
+ const OUString sTitle( xRow->getString( 1 ) );
+ if( !nExtLen ||
+ ( sTitle.getLength() > nExtLen &&
+ sTitle.endsWith( *pExtension )) )
+ {
+ rList.push_back( sTitle );
+
+ if( pDateTimeList )
+ {
+ css::util::DateTime aStamp = xRow->getTimestamp(2);
+ ::DateTime aDateTime(
+ ::Date( aStamp.Day,
+ aStamp.Month,
+ aStamp.Year ),
+ ::tools::Time( aStamp.Hours,
+ aStamp.Minutes,
+ aStamp.Seconds,
+ aStamp.NanoSeconds ));
+ pDateTimeList->push_back( aDateTime );
+ }
+ }
+
+ } while( xResultSet->next() );
+ }
+ bOk = true;
+ }
+ catch( css::uno::Exception& )
+ {
+ TOOLS_WARN_EXCEPTION( "sw", "" );
+ }
+ }
+ }
+ catch( css::uno::Exception& )
+ {
+ TOOLS_WARN_EXCEPTION( "sw", "" );
+ bOk = false;
+ }
+ return bOk;
+}
+
+bool needToMapFillItemsToSvxBrushItemTypes(const SfxItemSet& rSet,
+ sal_uInt16 const nMID)
+{
+ const XFillStyleItem* pXFillStyleItem(rSet.GetItem<XFillStyleItem>(XATTR_FILLSTYLE, false));
+
+ if(!pXFillStyleItem)
+ {
+ return false;
+ }
+
+ // here different FillStyles can be excluded for export; it will depend on the
+ // quality these fallbacks can reach. That again is done in getSvxBrushItemFromSourceSet,
+ // take a look there how the superset of DrawObject FillStyles is mapped to SvxBrushItem.
+ const drawing::FillStyle eFill = pXFillStyleItem->GetValue();
+ switch (eFill)
+ {
+ case drawing::FillStyle_NONE:
+ // claim that BackColor and BackTransparent are available so that
+ // fo:background="transparent" attribute is exported to override
+ // the parent style in case it is != NONE
+ switch (nMID)
+ {
+ case MID_BACK_COLOR:
+ case MID_BACK_COLOR_R_G_B:
+ case MID_GRAPHIC_TRANSPARENT: // this is *BackTransparent
+ return true;
+ default:
+ return false;
+ }
+ break;
+ case drawing::FillStyle_SOLID:
+ case drawing::FillStyle_GRADIENT: // gradient and hatch don't exist in
+ case drawing::FillStyle_HATCH: // SvxBrushItem so average color is emulated
+ switch (nMID)
+ {
+ case MID_BACK_COLOR:
+ case MID_GRAPHIC_TRANSPARENT: // this is *BackTransparent
+ // Gradient/Hatch always have emulated color
+ return (drawing::FillStyle_SOLID != eFill)
+ || SfxItemState::SET == rSet.GetItemState(XATTR_FILLCOLOR)
+ || SfxItemState::SET == rSet.GetItemState(XATTR_FILLTRANSPARENCE)
+ || SfxItemState::SET == rSet.GetItemState(XATTR_FILLFLOATTRANSPARENCE);
+ case MID_BACK_COLOR_R_G_B:
+ // Gradient/Hatch always have emulated color
+ return (drawing::FillStyle_SOLID != eFill)
+ || SfxItemState::SET == rSet.GetItemState(XATTR_FILLCOLOR);
+ case MID_BACK_COLOR_TRANSPARENCY:
+ return SfxItemState::SET == rSet.GetItemState(XATTR_FILLTRANSPARENCE)
+ || SfxItemState::SET == rSet.GetItemState(XATTR_FILLFLOATTRANSPARENCE);
+ }
+ break;
+ case drawing::FillStyle_BITMAP:
+ switch (nMID)
+ {
+ case MID_GRAPHIC:
+ return SfxItemState::SET == rSet.GetItemState(XATTR_FILLBITMAP);
+ case MID_GRAPHIC_POSITION:
+ return SfxItemState::SET == rSet.GetItemState(XATTR_FILLBMP_STRETCH)
+ || SfxItemState::SET == rSet.GetItemState(XATTR_FILLBMP_TILE)
+ || SfxItemState::SET == rSet.GetItemState(XATTR_FILLBMP_POS);
+ case MID_GRAPHIC_TRANSPARENT:
+ case MID_GRAPHIC_TRANSPARENCY:
+ return SfxItemState::SET == rSet.GetItemState(XATTR_FILLTRANSPARENCE)
+ || SfxItemState::SET == rSet.GetItemState(XATTR_FILLFLOATTRANSPARENCE);
+ }
+ break;
+ default:
+ assert(false);
+ }
+
+
+ return false;
+}
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/core/unocore/unobkm.cxx b/sw/source/core/unocore/unobkm.cxx
new file mode 100644
index 0000000000..81818a13d0
--- /dev/null
+++ b/sw/source/core/unocore/unobkm.cxx
@@ -0,0 +1,863 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <unobookmark.hxx>
+
+#include <comphelper/interfacecontainer4.hxx>
+#include <comphelper/sequence.hxx>
+#include <comphelper/servicehelper.hxx>
+#include <cppuhelper/supportsservice.hxx>
+#include <svl/itemprop.hxx>
+#include <svl/listener.hxx>
+#include <vcl/svapp.hxx>
+#include <xmloff/odffields.hxx>
+
+#include <TextCursorHelper.hxx>
+#include <unotextrange.hxx>
+#include <unomap.hxx>
+#include <unoprnms.hxx>
+#include <IMark.hxx>
+#include <crossrefbookmark.hxx>
+#include <doc.hxx>
+#include <docsh.hxx>
+
+using namespace ::sw::mark;
+using namespace ::com::sun::star;
+
+class SwXBookmark::Impl
+ : public SvtListener
+{
+public:
+ unotools::WeakReference<SwXBookmark> m_wThis;
+ std::mutex m_Mutex; // just for OInterfaceContainerHelper3
+ ::comphelper::OInterfaceContainerHelper4<css::lang::XEventListener> m_EventListeners;
+ SwDoc* m_pDoc;
+ ::sw::mark::IMark* m_pRegisteredBookmark;
+ OUString m_sMarkName;
+ bool m_bHidden;
+ OUString m_HideCondition;
+
+ Impl( SwDoc *const pDoc )
+ : m_pDoc(pDoc)
+ , m_pRegisteredBookmark(nullptr)
+ , m_bHidden(false)
+ {
+ // DO NOT registerInMark here! (because SetXBookmark would delete rThis)
+ }
+
+ void registerInMark(SwXBookmark & rThis, ::sw::mark::IMark *const pBkmk);
+protected:
+ virtual void Notify(const SfxHint&) override;
+
+};
+
+void SwXBookmark::Impl::Notify(const SfxHint& rHint)
+{
+ if(rHint.GetId() == SfxHintId::Dying)
+ {
+ m_pRegisteredBookmark = nullptr;
+ m_pDoc = nullptr;
+ uno::Reference<uno::XInterface> const xThis(m_wThis);
+ if (!xThis.is())
+ { // fdo#72695: if UNO object is already dead, don't revive it with event
+ return;
+ }
+ lang::EventObject const ev(xThis);
+ std::unique_lock aGuard(m_Mutex);
+ m_EventListeners.disposeAndClear(aGuard, ev);
+ }
+}
+
+void SwXBookmark::Impl::registerInMark(SwXBookmark& rThis,
+ ::sw::mark::IMark* const pBkmk)
+{
+ const rtl::Reference<SwXBookmark> xBookmark(&rThis);
+ if (pBkmk)
+ {
+ EndListeningAll();
+ StartListening(pBkmk->GetNotifier());
+ ::sw::mark::MarkBase *const pMarkBase(dynamic_cast< ::sw::mark::MarkBase * >(pBkmk));
+ OSL_ENSURE(pMarkBase, "registerInMark: no MarkBase?");
+ if (pMarkBase)
+ {
+ pMarkBase->SetXBookmark(xBookmark);
+ }
+ assert(m_pDoc == nullptr || m_pDoc == &pBkmk->GetMarkPos().GetDoc());
+ m_pDoc = &pBkmk->GetMarkPos().GetDoc();
+ }
+ else if (m_pRegisteredBookmark)
+ {
+ m_sMarkName = m_pRegisteredBookmark->GetName();
+
+ // the following applies only to bookmarks (not to fieldmarks)
+ IBookmark* pBookmark = dynamic_cast<IBookmark*>(m_pRegisteredBookmark);
+ if (pBookmark)
+ {
+ m_bHidden = pBookmark->IsHidden();
+ m_HideCondition = pBookmark->GetHideCondition();
+ }
+ EndListeningAll();
+ }
+ m_pRegisteredBookmark = pBkmk;
+ // need a permanent Reference to initialize m_wThis
+ m_wThis = xBookmark.get();
+}
+
+void SwXBookmark::registerInMark(SwXBookmark & rThis,
+ ::sw::mark::IMark *const pBkmk)
+{
+ m_pImpl->registerInMark( rThis, pBkmk );
+}
+
+::sw::mark::IMark* SwXBookmark::GetBookmark() const
+{
+ return m_pImpl->m_pRegisteredBookmark;
+}
+
+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) )
+{
+}
+
+SwXBookmark::SwXBookmark()
+ : m_pImpl( new SwXBookmark::Impl(nullptr) )
+{
+}
+
+SwXBookmark::~SwXBookmark()
+{
+}
+
+rtl::Reference<SwXBookmark> SwXBookmark::CreateXBookmark(
+ SwDoc & rDoc,
+ ::sw::mark::IMark *const pBookmark)
+{
+ // #i105557#: do not iterate over the registered clients: race condition
+ ::sw::mark::MarkBase *const pMarkBase(dynamic_cast< ::sw::mark::MarkBase * >(pBookmark));
+ OSL_ENSURE(!pBookmark || pMarkBase, "CreateXBookmark: no MarkBase?");
+ rtl::Reference<SwXBookmark> xBookmark;
+ if (pMarkBase)
+ {
+ xBookmark = pMarkBase->GetXBookmark();
+ }
+ if (!xBookmark.is())
+ {
+ OSL_ENSURE(!pBookmark ||
+ dynamic_cast< ::sw::mark::IBookmark* >(pBookmark) ||
+ IDocumentMarkAccess::GetType(*pBookmark) == IDocumentMarkAccess::MarkType::ANNOTATIONMARK,
+ "<SwXBookmark::GetObject(..)>"
+ "SwXBookmark requested for non-bookmark mark and non-annotation mark.");
+ SwXBookmark *const pXBookmark =
+ pBookmark ? new SwXBookmark(&rDoc) : new SwXBookmark;
+ xBookmark.set(pXBookmark);
+ pXBookmark->m_pImpl->registerInMark(*pXBookmark, pMarkBase);
+ }
+ return xBookmark;
+}
+
+::sw::mark::IMark const* SwXBookmark::GetBookmarkInDoc(SwDoc const*const pDoc,
+ const uno::Reference<uno::XInterface> & xUT)
+{
+ SwXBookmark *const pXBkm = dynamic_cast<SwXBookmark*>(xUT.get());
+ if (pXBkm && (pDoc == pXBkm->m_pImpl->m_pDoc))
+ {
+ return pXBkm->m_pImpl->m_pRegisteredBookmark;
+ }
+ return nullptr;
+}
+
+void SwXBookmark::attachToRangeEx(
+ const uno::Reference< text::XTextRange > & xTextRange,
+ IDocumentMarkAccess::MarkType eType,
+ bool const isFieldmarkSeparatorAtStart)
+{
+ if (m_pImpl->m_pRegisteredBookmark)
+ {
+ throw uno::RuntimeException();
+ }
+
+ SwXTextRange* pRange = dynamic_cast<SwXTextRange*>(xTextRange.get());
+ OTextCursorHelper* pCursor = dynamic_cast<OTextCursorHelper*>(xTextRange.get());
+
+ SwDoc *const pDoc =
+ pRange ? &pRange->GetDoc() : (pCursor ? pCursor->GetDoc() : nullptr);
+ if (!pDoc)
+ {
+ throw lang::IllegalArgumentException();
+ }
+
+ m_pImpl->m_pDoc = pDoc;
+ SwUnoInternalPaM aPam(*m_pImpl->m_pDoc);
+ ::sw::XTextRangeToSwPaM(aPam, xTextRange);
+ UnoActionContext aCont(m_pImpl->m_pDoc);
+ if (m_pImpl->m_sMarkName.isEmpty())
+ {
+ m_pImpl->m_sMarkName = "Bookmark";
+ }
+ if ((eType == IDocumentMarkAccess::MarkType::BOOKMARK) &&
+ ::sw::mark::CrossRefNumItemBookmark::IsLegalName(m_pImpl->m_sMarkName))
+ {
+ eType = IDocumentMarkAccess::MarkType::CROSSREF_NUMITEM_BOOKMARK;
+ }
+ else if ((eType == IDocumentMarkAccess::MarkType::BOOKMARK) &&
+ ::sw::mark::CrossRefHeadingBookmark::IsLegalName(m_pImpl->m_sMarkName) &&
+ IDocumentMarkAccess::IsLegalPaMForCrossRefHeadingBookmark( aPam ) )
+ {
+ eType = IDocumentMarkAccess::MarkType::CROSSREF_HEADING_BOOKMARK;
+ }
+ m_pImpl->registerInMark(*this,
+ m_pImpl->m_pDoc->getIDocumentMarkAccess()->makeMark(
+ aPam, m_pImpl->m_sMarkName, eType, ::sw::mark::InsertMode::New,
+ // note: aPam will be moved fwd by inserting start char, so sep
+ // will be directly following start
+ isFieldmarkSeparatorAtStart ? aPam.Start() : nullptr));
+ // #i81002#
+ // Check, if bookmark has been created.
+ // E.g., the creation of a cross-reference bookmark is suppress,
+ // if the PaM isn't a valid one for cross-reference bookmarks.
+ if (!m_pImpl->m_pRegisteredBookmark)
+ {
+ OSL_FAIL("<SwXBookmark::attachToRange(..)>"
+ " - could not create Mark.");
+ throw lang::IllegalArgumentException();
+ }
+}
+
+void SwXBookmark::attachToRange( const uno::Reference< text::XTextRange > & xTextRange )
+{
+ attachToRangeEx(xTextRange, IDocumentMarkAccess::MarkType::BOOKMARK);
+}
+
+void SAL_CALL SwXBookmark::attach( const uno::Reference< text::XTextRange > & xTextRange )
+{
+ SolarMutexGuard aGuard;
+ attachToRange( xTextRange );
+}
+
+uno::Reference< text::XTextRange > SAL_CALL SwXBookmark::getAnchor()
+{
+ SolarMutexGuard aGuard;
+
+ if (!m_pImpl->m_pRegisteredBookmark)
+ {
+ throw uno::RuntimeException();
+ }
+ return SwXTextRange::CreateXTextRange(
+ *m_pImpl->m_pDoc,
+ m_pImpl->m_pRegisteredBookmark->GetMarkPos(),
+ (m_pImpl->m_pRegisteredBookmark->IsExpanded())
+ ? &m_pImpl->m_pRegisteredBookmark->GetOtherMarkPos() : nullptr);
+}
+
+void SAL_CALL SwXBookmark::dispose()
+{
+ SolarMutexGuard aGuard;
+ if (m_pImpl->m_pRegisteredBookmark)
+ {
+ m_pImpl->m_pDoc->getIDocumentMarkAccess()->deleteMark( m_pImpl->m_pRegisteredBookmark );
+ }
+}
+
+void SAL_CALL SwXBookmark::addEventListener(
+ const uno::Reference< lang::XEventListener > & xListener)
+{
+ // no need to lock here as m_pImpl is const and container threadsafe
+ std::unique_lock aGuard(m_pImpl->m_Mutex);
+ m_pImpl->m_EventListeners.addInterface(aGuard, xListener);
+}
+
+void SAL_CALL SwXBookmark::removeEventListener(
+ const uno::Reference< lang::XEventListener > & xListener)
+{
+ // no need to lock here as m_pImpl is const and container threadsafe
+ std::unique_lock aGuard(m_pImpl->m_Mutex);
+ m_pImpl->m_EventListeners.removeInterface(aGuard, xListener);
+}
+
+OUString SAL_CALL SwXBookmark::getName()
+{
+ SolarMutexGuard aGuard;
+
+ return (m_pImpl->m_pRegisteredBookmark)
+ ? m_pImpl->m_pRegisteredBookmark->GetName()
+ : m_pImpl->m_sMarkName;
+}
+
+void SAL_CALL SwXBookmark::setName(const OUString& rName)
+{
+ SolarMutexGuard aGuard;
+
+ if (!m_pImpl->m_pRegisteredBookmark)
+ {
+ m_pImpl->m_sMarkName = rName;
+ }
+ if (!m_pImpl->m_pRegisteredBookmark || (getName() == rName))
+ {
+ return;
+ }
+ IDocumentMarkAccess *const pMarkAccess =
+ m_pImpl->m_pDoc->getIDocumentMarkAccess();
+ if(pMarkAccess->findMark(rName) != pMarkAccess->getAllMarksEnd())
+ {
+ throw uno::RuntimeException("setName(): name already in use",
+ getXWeak());
+ }
+
+ SwPaM aPam(m_pImpl->m_pRegisteredBookmark->GetMarkPos());
+ if (m_pImpl->m_pRegisteredBookmark->IsExpanded())
+ {
+ aPam.SetMark();
+ *aPam.GetMark() = m_pImpl->m_pRegisteredBookmark->GetOtherMarkPos();
+ }
+
+ pMarkAccess->renameMark(m_pImpl->m_pRegisteredBookmark, rName);
+}
+
+OUString SAL_CALL
+SwXBookmark::getImplementationName()
+{
+ return "SwXBookmark";
+}
+
+sal_Bool SAL_CALL SwXBookmark::supportsService(const OUString& rServiceName)
+{
+ return cppu::supportsService(this, rServiceName);
+}
+
+uno::Sequence< OUString > SAL_CALL
+SwXBookmark::getSupportedServiceNames()
+{
+ return {
+ "com.sun.star.text.TextContent",
+ "com.sun.star.text.Bookmark",
+ "com.sun.star.document.LinkTarget"
+ };
+}
+
+// MetadatableMixin
+::sfx2::Metadatable* SwXBookmark::GetCoreObject()
+{
+ return dynamic_cast< ::sfx2::Metadatable* >(m_pImpl->m_pRegisteredBookmark);
+}
+
+uno::Reference<frame::XModel> SwXBookmark::GetModel()
+{
+ if (m_pImpl->m_pDoc)
+ {
+ SwDocShell const * const pShell( m_pImpl->m_pDoc->GetDocShell() );
+ return pShell ? pShell->GetModel() : nullptr;
+ }
+ return nullptr;
+}
+
+uno::Reference< beans::XPropertySetInfo > SAL_CALL
+SwXBookmark::getPropertySetInfo()
+{
+ SolarMutexGuard g;
+
+ static uno::Reference< beans::XPropertySetInfo > xRef(
+ aSwMapProvider.GetPropertySet(PROPERTY_MAP_BOOKMARK)
+ ->getPropertySetInfo() );
+ return xRef;
+}
+
+void SAL_CALL
+SwXBookmark::setPropertyValue(const OUString& PropertyName,
+ const uno::Any& rValue)
+{
+ SolarMutexGuard g;
+
+ if (PropertyName == UNO_NAME_BOOKMARK_HIDDEN)
+ {
+ bool bNewValue = false;
+ if (!(rValue >>= bNewValue))
+ throw lang::IllegalArgumentException("Property BookmarkHidden requires value of type boolean", nullptr, 0);
+
+ IBookmark* pBookmark = dynamic_cast<IBookmark*>(m_pImpl->m_pRegisteredBookmark);
+ if (pBookmark)
+ {
+ pBookmark->Hide(bNewValue);
+ }
+ else
+ {
+ m_pImpl->m_bHidden = bNewValue;
+ }
+ return;
+ }
+ else if (PropertyName == UNO_NAME_BOOKMARK_CONDITION)
+ {
+ OUString newValue;
+ if (!(rValue >>= newValue))
+ throw lang::IllegalArgumentException("Property BookmarkCondition requires value of type string", nullptr, 0);
+
+ IBookmark* pBookmark = dynamic_cast<IBookmark*>(m_pImpl->m_pRegisteredBookmark);
+ if (pBookmark)
+ {
+ pBookmark->SetHideCondition(newValue);
+ }
+ else
+ {
+ m_pImpl->m_HideCondition = newValue;
+ }
+ return;
+ }
+
+ // nothing to set here
+ throw lang::IllegalArgumentException("Property is read-only: "
+ + PropertyName, getXWeak(), 0 );
+}
+
+uno::Any SAL_CALL SwXBookmark::getPropertyValue(const OUString& rPropertyName)
+{
+ SolarMutexGuard g;
+
+ uno::Any aRet;
+ if (! ::sw::GetDefaultTextContentValue(aRet, rPropertyName))
+ {
+ if(rPropertyName == UNO_LINK_DISPLAY_NAME)
+ {
+ aRet <<= getName();
+ }
+ else if (rPropertyName == UNO_NAME_BOOKMARK_HIDDEN)
+ {
+ IBookmark* pBookmark = dynamic_cast<IBookmark*>(m_pImpl->m_pRegisteredBookmark);
+ if (pBookmark)
+ {
+ aRet <<= pBookmark->IsHidden();
+ }
+ else
+ {
+ aRet <<= m_pImpl->m_bHidden;
+ }
+ }
+ else if (rPropertyName == UNO_NAME_BOOKMARK_CONDITION)
+ {
+ IBookmark* pBookmark = dynamic_cast<IBookmark*>(m_pImpl->m_pRegisteredBookmark);
+ if (pBookmark)
+ {
+ aRet <<= pBookmark->GetHideCondition();
+ }
+ else
+ {
+ aRet <<= m_pImpl->m_HideCondition;
+ }
+ }
+ }
+ return aRet;
+}
+
+void SAL_CALL
+SwXBookmark::addPropertyChangeListener(
+ const OUString& /*rPropertyName*/,
+ const uno::Reference< beans::XPropertyChangeListener >& /*xListener*/)
+{
+ OSL_FAIL("SwXBookmark::addPropertyChangeListener(): not implemented");
+}
+
+void SAL_CALL
+SwXBookmark::removePropertyChangeListener(
+ const OUString& /*rPropertyName*/,
+ const uno::Reference< beans::XPropertyChangeListener >& /*xListener*/)
+{
+ OSL_FAIL("SwXBookmark::removePropertyChangeListener(): not implemented");
+}
+
+void SAL_CALL
+SwXBookmark::addVetoableChangeListener(
+ const OUString& /*rPropertyName*/,
+ const uno::Reference< beans::XVetoableChangeListener >& /*xListener*/)
+{
+ OSL_FAIL("SwXBookmark::addVetoableChangeListener(): not implemented");
+}
+
+void SAL_CALL
+SwXBookmark::removeVetoableChangeListener(
+ const OUString& /*rPropertyName*/,
+ const uno::Reference< beans::XVetoableChangeListener >& /*xListener*/)
+{
+ OSL_FAIL("SwXBookmark::removeVetoableChangeListener(): not implemented");
+}
+
+
+void SwXFieldmarkParameters::insertByName(const OUString& aName, const uno::Any& aElement)
+{
+ SolarMutexGuard aGuard;
+ IFieldmark::parameter_map_t* pParameters = getCoreParameters();
+ if(pParameters->find(aName) != pParameters->end())
+ throw container::ElementExistException();
+ (*pParameters)[aName] = aElement;
+}
+
+void SwXFieldmarkParameters::removeByName(const OUString& aName)
+{
+ SolarMutexGuard aGuard;
+ if(!getCoreParameters()->erase(aName))
+ throw container::NoSuchElementException();
+}
+
+void SwXFieldmarkParameters::replaceByName(const OUString& aName, const uno::Any& aElement)
+{
+ SolarMutexGuard aGuard;
+ IFieldmark::parameter_map_t* pParameters = getCoreParameters();
+ IFieldmark::parameter_map_t::iterator pEntry = pParameters->find(aName);
+ if(pEntry == pParameters->end())
+ throw container::NoSuchElementException();
+ pEntry->second = aElement;
+}
+
+uno::Any SwXFieldmarkParameters::getByName(const OUString& aName)
+{
+ SolarMutexGuard aGuard;
+ IFieldmark::parameter_map_t* pParameters = getCoreParameters();
+ IFieldmark::parameter_map_t::iterator pEntry = pParameters->find(aName);
+ if(pEntry == pParameters->end())
+ throw container::NoSuchElementException();
+ return pEntry->second;
+}
+
+uno::Sequence<OUString> SwXFieldmarkParameters::getElementNames()
+{
+ SolarMutexGuard aGuard;
+ IFieldmark::parameter_map_t* pParameters = getCoreParameters();
+ return comphelper::mapKeysToSequence(*pParameters);
+}
+
+sal_Bool SwXFieldmarkParameters::hasByName(const OUString& aName)
+{
+ SolarMutexGuard aGuard;
+ IFieldmark::parameter_map_t* pParameters = getCoreParameters();
+ return (pParameters->find(aName) != pParameters->end());
+}
+
+uno::Type SwXFieldmarkParameters::getElementType()
+{
+ return ::cppu::UnoType<void>::get();
+}
+
+sal_Bool SwXFieldmarkParameters::hasElements()
+{
+ SolarMutexGuard aGuard;
+ return !getCoreParameters()->empty();
+}
+
+void SwXFieldmarkParameters::Notify(const SfxHint& rHint)
+{
+ if(rHint.GetId() == SfxHintId::Dying)
+ m_pFieldmark = nullptr;
+}
+
+IFieldmark::parameter_map_t* SwXFieldmarkParameters::getCoreParameters()
+{
+ if(!m_pFieldmark)
+ throw uno::RuntimeException();
+ return m_pFieldmark->GetParameters();
+}
+
+SwXFieldmark::SwXFieldmark(bool const isReplacementObject, SwDoc *const pDoc)
+ : SwXFieldmark_Base(pDoc)
+ , m_bReplacementObject(isReplacementObject)
+{
+}
+
+OUString SAL_CALL
+SwXFieldmark::getImplementationName()
+{
+ return "SwXFieldmark";
+}
+
+uno::Sequence<OUString> SAL_CALL
+SwXFieldmark::getSupportedServiceNames()
+{
+ // is const, no lock needed
+ if (m_bReplacementObject)
+ {
+ 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 )
+{
+
+ attachToRangeEx( xTextRange,
+ (m_bReplacementObject ? IDocumentMarkAccess::MarkType::CHECKBOX_FIELDMARK : IDocumentMarkAccess::MarkType::TEXT_FIELDMARK),
+ m_isFieldmarkSeparatorAtStart);
+}
+
+OUString SwXFieldmark::getFieldType()
+{
+ SolarMutexGuard aGuard;
+ const IFieldmark *pBkm = dynamic_cast<const IFieldmark*>(GetBookmark());
+ if(!pBkm)
+ throw uno::RuntimeException();
+ return pBkm->GetFieldname();
+}
+
+void SwXFieldmark::setFieldType(const OUString & fieldType)
+{
+ SolarMutexGuard aGuard;
+ IFieldmark *pBkm = dynamic_cast<IFieldmark*>(GetBookmark());
+ if(!pBkm)
+ throw uno::RuntimeException();
+
+ OUString const oldFieldType(getFieldType());
+ if (fieldType == oldFieldType)
+ return;
+
+ // note: this must not change between point-fieldmarks and range-fieldmarks
+ if(fieldType == ODF_FORMDROPDOWN || fieldType == ODF_FORMCHECKBOX || fieldType == ODF_FORMDATE)
+ {
+ ::sw::mark::IFieldmark* pNewFieldmark = GetIDocumentMarkAccess()->changeFormFieldmarkType(pBkm, fieldType);
+ if (pNewFieldmark)
+ {
+ registerInMark(*this, pNewFieldmark);
+ return;
+ }
+ }
+
+ if ((!m_bReplacementObject && (fieldType == ODF_UNHANDLED
+ || fieldType == ODF_FORMDATE
+ || fieldType == ODF_FORMTEXT))
+ || (m_bReplacementObject && (fieldType == ODF_FORMCHECKBOX
+ || fieldType == ODF_FORMDROPDOWN)))
+ {
+ pBkm->SetFieldname(fieldType);
+ return;
+ }
+
+ throw uno::RuntimeException("changing to that type isn't implemented");
+}
+
+uno::Reference<container::XNameContainer> SwXFieldmark::getParameters()
+{
+ SolarMutexGuard aGuard;
+ IFieldmark *pBkm = dynamic_cast<IFieldmark*>(GetBookmark());
+ if(!pBkm)
+ throw uno::RuntimeException();
+ return uno::Reference<container::XNameContainer>(new SwXFieldmarkParameters(pBkm));
+}
+
+rtl::Reference<SwXBookmark>
+SwXFieldmark::CreateXFieldmark(SwDoc & rDoc, ::sw::mark::IMark *const pMark,
+ bool const isReplacementObject)
+{
+ // #i105557#: do not iterate over the registered clients: race condition
+ ::sw::mark::MarkBase *const pMarkBase(
+ dynamic_cast< ::sw::mark::MarkBase * >(pMark));
+ assert(!pMark || pMarkBase);
+ rtl::Reference<SwXBookmark> xMark;
+ if (pMarkBase)
+ {
+ xMark = pMarkBase->GetXBookmark();
+ }
+ if (!xMark.is())
+ {
+ // FIXME: These belong in XTextFieldsSupplier
+ rtl::Reference<SwXFieldmark> pXBkmk;
+ if (dynamic_cast< ::sw::mark::TextFieldmark* >(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 if (dynamic_cast< ::sw::mark::DateFieldmark* >(pMark))
+ pXBkmk = new SwXFieldmark(false, &rDoc);
+ else
+ pXBkmk = new SwXFieldmark(isReplacementObject, &rDoc);
+
+ xMark = pXBkmk.get();
+ pXBkmk->registerInMark(*pXBkmk, pMarkBase);
+ }
+ return xMark;
+}
+
+::sw::mark::ICheckboxFieldmark*
+SwXFieldmark::getCheckboxFieldmark()
+{
+ ::sw::mark::ICheckboxFieldmark* pCheckboxFm = nullptr;
+ if ( getFieldType() == ODF_FORMCHECKBOX )
+ {
+ pCheckboxFm = dynamic_cast< ::sw::mark::ICheckboxFieldmark* >( GetBookmark());
+ assert( GetBookmark() == nullptr || pCheckboxFm != nullptr );
+ // unclear to me whether GetBookmark() can be null here
+ }
+ return pCheckboxFm;
+
+}
+
+// support 'hidden' "Checked" property ( note: this property is just for convenience to support
+// docx import filter thus not published via PropertySet info )
+
+void SAL_CALL
+SwXFieldmark::setPropertyValue(const OUString& PropertyName,
+ const uno::Any& rValue)
+{
+ SolarMutexGuard g;
+ if ( PropertyName == "Checked" )
+ {
+ ::sw::mark::ICheckboxFieldmark* pCheckboxFm = getCheckboxFieldmark();
+ bool bChecked( false );
+ if ( !(pCheckboxFm && ( rValue >>= bChecked )) )
+ throw uno::RuntimeException();
+
+ pCheckboxFm->SetChecked( bChecked );
+ }
+ else if (PropertyName == "PrivateSeparatorAtStart")
+ {
+ bool isFieldmarkSeparatorAtStart{};
+ if (rValue >>= isFieldmarkSeparatorAtStart)
+ {
+ m_isFieldmarkSeparatorAtStart = isFieldmarkSeparatorAtStart;
+ }
+ }
+ // this doesn't support any SwXBookmark property
+}
+
+// support 'hidden' "Checked" property ( note: this property is just for convenience to support
+// docx import filter thus not published via PropertySet info )
+
+uno::Any SAL_CALL SwXFieldmark::getPropertyValue(const OUString& rPropertyName)
+{
+ SolarMutexGuard g;
+ if ( rPropertyName == "Checked" )
+ {
+ ::sw::mark::ICheckboxFieldmark* pCheckboxFm = getCheckboxFieldmark();
+ if ( !pCheckboxFm )
+ throw uno::RuntimeException();
+
+ return uno::Any( pCheckboxFm->IsChecked() );
+ }
+ 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();
+}
+
+rtl::Reference<SwXTextRange>
+SwXFieldmark::GetCommand(IFieldmark const& rMark)
+{
+ SwPosition const sepPos(sw::mark::FindFieldSep(rMark));
+ SwPosition start(rMark.GetMarkStart());
+ start.AdjustContent(1);
+ return SwXTextRange::CreateXTextRange(*GetDoc(), start, &sepPos);
+}
+
+rtl::Reference<SwXTextRange>
+SwXFieldmark::GetResult(IFieldmark const& rMark)
+{
+ SwPosition sepPos(sw::mark::FindFieldSep(rMark));
+ sepPos.AdjustContent(1);
+ 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 (m_bReplacementObject)
+ {
+ 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 || type == ODF_FORMDROPDOWN)
+ {
+ return sw::mark::ExpandFieldmark(const_cast<IFieldmark *>(pMark));
+ }
+ else
+ {
+ assert(!m_bReplacementObject);
+ 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/unochart.cxx b/sw/source/core/unocore/unochart.cxx
new file mode 100644
index 0000000000..db97093a31
--- /dev/null
+++ b/sw/source/core/unocore/unochart.cxx
@@ -0,0 +1,2695 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <algorithm>
+#include <string_view>
+
+#include <com/sun/star/chart/ChartDataRowSource.hpp>
+#include <com/sun/star/chart2/data/LabelOrigin.hpp>
+#include <com/sun/star/embed/XEmbeddedObject.hpp>
+#include <com/sun/star/frame/XModel.hpp>
+#include <comphelper/diagnose_ex.hxx>
+#include <cppuhelper/supportsservice.hxx>
+#include <o3tl/deleter.hxx>
+#include <o3tl/string_view.hxx>
+#include <mutex>
+#include <vcl/svapp.hxx>
+
+#include "XMLRangeHelper.hxx"
+#include <unochart.hxx>
+#include <swtable.hxx>
+#include <unoprnms.hxx>
+#include <unomap.hxx>
+#include <unocrsr.hxx>
+#include <unotbl.hxx>
+#include <doc.hxx>
+#include <IDocumentChartDataProviderAccess.hxx>
+#include <frmfmt.hxx>
+#include <ndole.hxx>
+#include <swtypes.hxx>
+#include <strings.hrc>
+#include <comphelper/servicehelper.hxx>
+#include <comphelper/string.hxx>
+#include <svl/itemprop.hxx>
+
+using namespace ::com::sun::star;
+
+void SwChartHelper::DoUpdateAllCharts( SwDoc* pDoc )
+{
+ if (!pDoc)
+ return;
+
+ SwOLENode *pONd;
+ SwStartNode *pStNd;
+ SwNodeIndex aIdx( *pDoc->GetNodes().GetEndOfAutotext().StartOfSectionNode(), 1 );
+ while( nullptr != (pStNd = aIdx.GetNode().GetStartNode()) )
+ {
+ ++aIdx;
+ if (nullptr != ( pONd = aIdx.GetNode().GetOLENode() ) &&
+ pONd->GetOLEObj().GetObject().IsChart() )
+ {
+ // Load the object and set modified
+
+ uno::Reference < embed::XEmbeddedObject > xIP = pONd->GetOLEObj().GetOleRef();
+ if ( svt::EmbeddedObjectRef::TryRunningState( xIP ) )
+ {
+ try
+ {
+ uno::Reference< util::XModifiable > xModif( xIP->getComponent(), uno::UNO_QUERY_THROW );
+ xModif->setModified( true );
+ }
+ catch ( uno::Exception& )
+ {
+ }
+
+ }
+ }
+ aIdx.Assign( *pStNd->EndOfSectionNode(), + 1 );
+ }
+}
+
+SwChartLockController_Helper::SwChartLockController_Helper( SwDoc *pDocument ) :
+ m_pDoc( pDocument )
+ , m_aUnlockTimer( "sw::SwChartLockController_Helper aUnlockTimer" )
+ , m_bIsLocked( false )
+{
+ m_aUnlockTimer.SetTimeout( 1500 );
+ m_aUnlockTimer.SetInvokeHandler( LINK( this, SwChartLockController_Helper, DoUnlockAllCharts ));
+}
+
+SwChartLockController_Helper::~SwChartLockController_Helper()
+{
+ if (m_pDoc) // still connected?
+ suppress_fun_call_w_exception(Disconnect());
+}
+
+void SwChartLockController_Helper::StartOrContinueLocking()
+{
+ if (!m_bIsLocked)
+ LockAllCharts();
+ m_aUnlockTimer.Start(); // start or continue time of locking
+}
+
+void SwChartLockController_Helper::Disconnect()
+{
+ m_aUnlockTimer.Stop();
+ UnlockAllCharts();
+ m_pDoc = nullptr;
+}
+
+void SwChartLockController_Helper::LockUnlockAllCharts( bool bLock )
+{
+ if (!m_pDoc)
+ return;
+
+ uno::Reference< frame::XModel > xRes;
+ SwOLENode *pONd;
+ SwStartNode *pStNd;
+ SwNodeIndex aIdx( *m_pDoc->GetNodes().GetEndOfAutotext().StartOfSectionNode(), 1 );
+ while( nullptr != (pStNd = aIdx.GetNode().GetStartNode()) )
+ {
+ ++aIdx;
+ if (nullptr != ( pONd = aIdx.GetNode().GetOLENode() ) &&
+ !pONd->GetChartTableName().isEmpty() /* is chart object? */)
+ {
+ uno::Reference < embed::XEmbeddedObject > xIP = pONd->GetOLEObj().GetOleRef();
+ if ( svt::EmbeddedObjectRef::TryRunningState( xIP ) )
+ {
+ xRes.set( xIP->getComponent(), uno::UNO_QUERY );
+ if (xRes.is())
+ {
+ if (bLock)
+ xRes->lockControllers();
+ else
+ xRes->unlockControllers();
+ }
+ }
+ }
+ aIdx.Assign( *pStNd->EndOfSectionNode(), + 1 );
+ }
+
+ m_bIsLocked = bLock;
+}
+
+IMPL_LINK_NOARG( SwChartLockController_Helper, DoUnlockAllCharts, Timer *, void )
+{
+ UnlockAllCharts();
+}
+
+static std::mutex & GetChartMutex()
+{
+ static std::mutex aMutex;
+ return aMutex;
+}
+
+static void LaunchModifiedEvent(
+ ::comphelper::OInterfaceContainerHelper4<util::XModifyListener> &rICH,
+ const uno::Reference< uno::XInterface > &rxI )
+{
+ lang::EventObject aEvtObj( rxI );
+ std::unique_lock aGuard(GetChartMutex());
+ rICH.notifyEach( aGuard, &util::XModifyListener::modified, aEvtObj );
+}
+
+/**
+ * rCellRangeName needs to be of one of the following formats:
+ * - e.g. "A2:E5" or
+ * - e.g. "Table1.A2:E5"
+ */
+bool FillRangeDescriptor(
+ SwRangeDescriptor &rDesc,
+ std::u16string_view rCellRangeName )
+{
+ sal_Int32 nToken = std::u16string_view::npos == rCellRangeName.find('.') ? 0 : 1;
+ std::u16string_view aCellRangeNoTableName( o3tl::getToken(rCellRangeName, nToken, '.' ) );
+ OUString aTLName( o3tl::getToken(aCellRangeNoTableName, 0, ':') ); // name of top left cell
+ OUString aBRName( o3tl::getToken(aCellRangeNoTableName, 1, ':') ); // name of bottom right cell
+ if(aTLName.isEmpty() || aBRName.isEmpty())
+ return false;
+
+ rDesc.nTop = rDesc.nLeft = rDesc.nBottom = rDesc.nRight = -1;
+ SwXTextTable::GetCellPosition( aTLName, rDesc.nLeft, rDesc.nTop );
+ SwXTextTable::GetCellPosition( aBRName, rDesc.nRight, rDesc.nBottom );
+ rDesc.Normalize();
+ OSL_ENSURE( rDesc.nTop != -1 &&
+ rDesc.nLeft != -1 &&
+ rDesc.nBottom != -1 &&
+ rDesc.nRight != -1,
+ "failed to get range descriptor" );
+ OSL_ENSURE( rDesc.nTop <= rDesc.nBottom && rDesc.nLeft <= rDesc.nRight,
+ "invalid range descriptor");
+ return true;
+}
+
+static OUString GetCellRangeName( const SwFrameFormat &rTableFormat, SwUnoCursor &rTableCursor )
+{
+ OUString aRes;
+
+ //!! see also SwXTextTableCursor::getRangeName
+
+ SwUnoTableCursor* pUnoTableCursor = dynamic_cast<SwUnoTableCursor*>(&rTableCursor);
+ if (!pUnoTableCursor)
+ return OUString();
+
+ // tdf#132714 empty outdated selection cache to avoid crashing in ActualizeSelection()
+ size_t nCount = pUnoTableCursor->GetSelectedBoxesCount();
+ while (nCount--)
+ pUnoTableCursor->DeleteBox(nCount);
+
+ pUnoTableCursor->MakeBoxSels();
+
+ const SwStartNode* pStart;
+ const SwTableBox* pStartBox = nullptr;
+ const SwTableBox* pEndBox = nullptr;
+
+ pStart = pUnoTableCursor->GetPoint()->GetNode().FindTableBoxStartNode();
+ if (pStart)
+ {
+ const SwTable* pTable = SwTable::FindTable( &rTableFormat );
+ pEndBox = pTable->GetTableBox( pStart->GetIndex());
+ aRes = pEndBox->GetName();
+
+ if(pUnoTableCursor->HasMark())
+ {
+ pStart = pUnoTableCursor->GetMark()->GetNode().FindTableBoxStartNode();
+ pStartBox = pTable->GetTableBox( pStart->GetIndex());
+ }
+ OSL_ENSURE( pStartBox, "start box not found" );
+ OSL_ENSURE( pEndBox, "end box not found" );
+
+ // need to switch start and end?
+ if (*pUnoTableCursor->GetPoint() < *pUnoTableCursor->GetMark())
+ {
+ const SwTableBox* pTmpBox = pStartBox;
+ pStartBox = pEndBox;
+ pEndBox = pTmpBox;
+ }
+
+ if (!pStartBox)
+ return aRes;
+
+ aRes = pStartBox->GetName() + ":";
+ if (pEndBox)
+ aRes += pEndBox->GetName();
+ else
+ aRes += pStartBox->GetName();
+ }
+
+ return aRes;
+}
+
+static OUString GetRangeRepFromTableAndCells( std::u16string_view rTableName,
+ std::u16string_view rStartCell, std::u16string_view rEndCell,
+ bool bForceEndCellName )
+{
+ OSL_ENSURE( !rTableName.empty(), "table name missing" );
+ OSL_ENSURE( !rStartCell.empty(), "cell name missing" );
+ OUString aRes = OUString::Concat(rTableName) + "." + rStartCell;
+
+ if (!rEndCell.empty())
+ {
+ aRes += OUString::Concat(":") + rEndCell;
+ }
+ else if (bForceEndCellName)
+ {
+ aRes += OUString::Concat(":") + rStartCell;
+ }
+
+ return aRes;
+}
+
+static bool GetTableAndCellsFromRangeRep(
+ std::u16string_view rRangeRepresentation,
+ OUString &rTableName,
+ OUString &rStartCell,
+ OUString &rEndCell,
+ bool bSortStartEndCells = true )
+{
+ // parse range representation for table name and cell/range names
+ // accepted format sth like: "Table1.A2:C5" , "Table2.A2.1:B3.2"
+ OUString aTableName; // table name
+ OUString aStartCell; // name of top left cell
+ OUString aEndCell; // name of bottom right cell
+ size_t nIdx = rRangeRepresentation.find( '.' );
+ if (nIdx != std::u16string_view::npos)
+ {
+ aTableName = rRangeRepresentation.substr( 0, nIdx );
+ std::u16string_view aRange = rRangeRepresentation.substr( nIdx + 1 ); // cell range
+ size_t nPos = aRange.find( ':' );
+ if (nPos != std::u16string_view::npos) // a cell-range like "Table1.A2:D4"
+ {
+ aStartCell = aRange.substr( 0, nPos );
+ aEndCell = aRange.substr( nPos + 1 );
+
+ // need to switch start and end cell ?
+ // (does not check for normalization here)
+ if (bSortStartEndCells && 1 == sw_CompareCellsByColFirst( aStartCell, aEndCell ))
+ {
+ OUString aTmp( aStartCell );
+ aStartCell = aEndCell;
+ aEndCell = aTmp;
+ }
+ }
+ else // a single cell like in "Table1.B3"
+ {
+ aStartCell = aEndCell = aRange;
+ }
+ }
+
+ bool bSuccess = !aTableName.isEmpty() &&
+ !aStartCell.isEmpty() && !aEndCell.isEmpty();
+ if (bSuccess)
+ {
+ rTableName = aTableName;
+ rStartCell = aStartCell;
+ rEndCell = aEndCell;
+ }
+ return bSuccess;
+}
+
+static void GetTableByName( const SwDoc &rDoc, std::u16string_view rTableName,
+ SwFrameFormat **ppTableFormat, SwTable **ppTable)
+{
+ SwFrameFormat *pTableFormat = nullptr;
+
+ // find frame format of table
+ //! see SwXTextTables::getByName
+ const size_t nCount = rDoc.GetTableFrameFormatCount(true);
+ for (size_t i = 0; i < nCount && !pTableFormat; ++i)
+ {
+ SwFrameFormat& rTableFormat = rDoc.GetTableFrameFormat(i, true);
+ if(rTableName == rTableFormat.GetName())
+ pTableFormat = &rTableFormat;
+ }
+
+ if (ppTableFormat)
+ *ppTableFormat = pTableFormat;
+
+ if (ppTable)
+ *ppTable = pTableFormat ? SwTable::FindTable( pTableFormat ) : nullptr;
+}
+
+static void GetFormatAndCreateCursorFromRangeRep(
+ const SwDoc *pDoc,
+ std::u16string_view rRangeRepresentation, // must be a single range (i.e. so called sub-range)
+ SwFrameFormat **ppTableFormat, // will be set to the table format of the table used in the range representation
+ std::shared_ptr<SwUnoCursor>& rpUnoCursor ) // will be set to cursor spanning the cell range (cursor will be created!)
+{
+ OUString aTableName; // table name
+ OUString aStartCell; // name of top left cell
+ OUString aEndCell; // name of bottom right cell
+ bool bNamesFound = GetTableAndCellsFromRangeRep( rRangeRepresentation,
+ aTableName, aStartCell, aEndCell );
+
+ if (!bNamesFound)
+ {
+ if (ppTableFormat)
+ *ppTableFormat = nullptr;
+ rpUnoCursor.reset();
+ }
+ else
+ {
+ SwFrameFormat *pTableFormat = nullptr;
+
+ // is the correct table format already provided?
+ if (*ppTableFormat != nullptr && (*ppTableFormat)->GetName() == aTableName)
+ pTableFormat = *ppTableFormat;
+ else
+ GetTableByName( *pDoc, aTableName, &pTableFormat, nullptr );
+
+ *ppTableFormat = pTableFormat;
+
+ rpUnoCursor.reset(); // default result in case of failure
+
+ SwTable *pTable = pTableFormat ? SwTable::FindTable( pTableFormat ) : nullptr;
+ // create new SwUnoCursor spanning the specified range
+ //! see also SwXTextTable::GetRangeByName
+ // #i80314#
+ // perform validation check. Thus, pass <true> as 2nd parameter to <SwTable::GetTableBox(..)>
+ const SwTableBox* pTLBox =
+ pTable ? pTable->GetTableBox( aStartCell, true ) : nullptr;
+ if(pTLBox)
+ {
+ const SwStartNode* pSttNd = pTLBox->GetSttNd();
+ SwPosition aPos(*pSttNd);
+
+ // set cursor to top left box of range
+ auto pUnoCursor = pTableFormat->GetDoc()->CreateUnoCursor(aPos, true);
+ pUnoCursor->Move( fnMoveForward, GoInNode );
+ pUnoCursor->SetRemainInSection( false );
+
+ // #i80314#
+ // perform validation check. Thus, pass <true> as 2nd parameter to <SwTable::GetTableBox(..)>
+ const SwTableBox* pBRBox = pTable->GetTableBox( aEndCell, true );
+ if(pBRBox)
+ {
+ pUnoCursor->SetMark();
+ pUnoCursor->GetPoint()->Assign( *pBRBox->GetSttNd() );
+ pUnoCursor->Move( fnMoveForward, GoInNode );
+ SwUnoTableCursor& rCursor =
+ dynamic_cast<SwUnoTableCursor&>(*pUnoCursor);
+ // HACK: remove pending actions for old style tables
+ UnoActionRemoveContext aRemoveContext(rCursor);
+ rCursor.MakeBoxSels();
+ rpUnoCursor = pUnoCursor;
+ }
+ }
+ }
+}
+
+static bool GetSubranges( std::u16string_view rRangeRepresentation,
+ uno::Sequence< OUString > &rSubRanges, bool bNormalize )
+{
+ bool bRes = true;
+ const sal_Int32 nLen = comphelper::string::getTokenCount(rRangeRepresentation, ';');
+ uno::Sequence< OUString > aRanges( nLen );
+
+ sal_Int32 nCnt = 0;
+ if (nLen != 0)
+ {
+ OUString *pRanges = aRanges.getArray();
+ OUString aFirstTable;
+ sal_Int32 nPos = 0;
+ for( sal_Int32 i = 0; i < nLen && bRes; ++i )
+ {
+ const OUString aRange( o3tl::getToken(rRangeRepresentation, 0, ';', nPos ) );
+ if (!aRange.isEmpty())
+ {
+ pRanges[nCnt] = aRange;
+
+ OUString aTableName, aStartCell, aEndCell;
+ if (!GetTableAndCellsFromRangeRep( aRange,
+ aTableName, aStartCell, aEndCell ))
+ bRes = false;
+
+ if (bNormalize)
+ {
+ sw_NormalizeRange( aStartCell, aEndCell );
+ pRanges[nCnt] = GetRangeRepFromTableAndCells( aTableName,
+ aStartCell, aEndCell, true );
+ }
+
+ // make sure to use only a single table
+ if (nCnt == 0)
+ aFirstTable = aTableName;
+ else
+ if (aFirstTable != aTableName) bRes = false;
+
+ ++nCnt;
+ }
+ }
+ }
+ aRanges.realloc( nCnt );
+
+ rSubRanges = aRanges;
+ return bRes;
+}
+
+static void SortSubranges( uno::Sequence< OUString > &rSubRanges, bool bCmpByColumn )
+{
+ sal_Int32 nLen = rSubRanges.getLength();
+ OUString *pSubRanges = rSubRanges.getArray();
+
+ OUString aSmallestTableName;
+ OUString aSmallestStartCell;
+ OUString aSmallestEndCell;
+
+ for (sal_Int32 i = 0; i < nLen; ++i)
+ {
+ sal_Int32 nIdxOfSmallest = i;
+ GetTableAndCellsFromRangeRep( pSubRanges[nIdxOfSmallest],
+ aSmallestTableName, aSmallestStartCell, aSmallestEndCell );
+ if (aSmallestEndCell.isEmpty())
+ aSmallestEndCell = aSmallestStartCell;
+
+ for (sal_Int32 k = i+1; k < nLen; ++k)
+ {
+ // get cell names for sub range
+ OUString aTableName;
+ OUString aStartCell;
+ OUString aEndCell;
+ GetTableAndCellsFromRangeRep( pSubRanges[k],
+ aTableName, aStartCell, aEndCell );
+ if (aEndCell.isEmpty())
+ aEndCell = aStartCell;
+
+ // compare cell ranges ( is the new one smaller? )
+ if (-1 == sw_CompareCellRanges( aStartCell, aEndCell,
+ aSmallestStartCell, aSmallestEndCell, bCmpByColumn ))
+ {
+ nIdxOfSmallest = k;
+ aSmallestTableName = aTableName;
+ aSmallestStartCell = aStartCell;
+ aSmallestEndCell = aEndCell;
+ }
+ }
+
+ // move smallest element to the start of the not sorted area
+ const OUString aTmp( pSubRanges[ nIdxOfSmallest ] );
+ pSubRanges[ nIdxOfSmallest ] = pSubRanges[ i ];
+ pSubRanges[ i ] = aTmp;
+ }
+}
+
+SwChartDataProvider::SwChartDataProvider( const SwDoc& rSwDoc ) :
+ m_pDoc( &rSwDoc )
+{
+ m_bDisposed = false;
+}
+
+SwChartDataProvider::~SwChartDataProvider()
+{
+}
+
+uno::Reference< chart2::data::XDataSource > SwChartDataProvider::Impl_createDataSource(
+ const uno::Sequence< beans::PropertyValue >& rArguments, bool bTestOnly )
+{
+ SolarMutexGuard aGuard;
+ if (m_bDisposed)
+ throw lang::DisposedException();
+
+ uno::Reference< chart2::data::XDataSource > xRes;
+
+ if (!m_pDoc)
+ throw uno::RuntimeException("Not connected to a document.");
+
+ // get arguments
+ OUString aRangeRepresentation;
+ uno::Sequence< sal_Int32 > aSequenceMapping;
+ bool bFirstIsLabel = false;
+ bool bDtaSrcIsColumns = true; // true : DataSource will be sequence of columns
+ // false: DataSource will be sequence of rows
+
+ OUString aChartOleObjectName; //work around wrong writer ranges ( see Issue 58464 )
+ sal_Int32 nArgs = rArguments.getLength();
+ OSL_ENSURE( nArgs != 0, "no properties provided" );
+ if (nArgs == 0)
+ return xRes;
+ for (const beans::PropertyValue& rArg : rArguments)
+ {
+ if ( rArg.Name == "DataRowSource" )
+ {
+ chart::ChartDataRowSource eSource;
+ if (!(rArg.Value >>= eSource))
+ {
+ sal_Int32 nTmp = 0;
+ if (!(rArg.Value >>= nTmp))
+ throw lang::IllegalArgumentException();
+ eSource = static_cast< chart::ChartDataRowSource >( nTmp );
+ }
+ bDtaSrcIsColumns = eSource == chart::ChartDataRowSource_COLUMNS;
+ }
+ else if ( rArg.Name == "FirstCellAsLabel" )
+ {
+ if (!(rArg.Value >>= bFirstIsLabel))
+ throw lang::IllegalArgumentException();
+ }
+ else if ( rArg.Name == "CellRangeRepresentation" )
+ {
+ if (!(rArg.Value >>= aRangeRepresentation))
+ throw lang::IllegalArgumentException();
+ }
+ else if ( rArg.Name == "SequenceMapping" )
+ {
+ if (!(rArg.Value >>= aSequenceMapping))
+ throw lang::IllegalArgumentException();
+ }
+ else if ( rArg.Name == "ChartOleObjectName" )
+ {
+ if (!(rArg.Value >>= aChartOleObjectName))
+ throw lang::IllegalArgumentException();
+ }
+ }
+
+ uno::Sequence< OUString > aSubRanges;
+ // get sub-ranges and check that they all are from the very same table
+ bool bOk = GetSubranges( aRangeRepresentation, aSubRanges, true );
+
+ if (!bOk && m_pDoc && !aChartOleObjectName.isEmpty() )
+ {
+ //try to correct the range here
+ //work around wrong writer ranges ( see Issue 58464 )
+ OUString aChartTableName;
+
+ const SwNodes& rNodes = m_pDoc->GetNodes();
+ for( SwNodeOffset nN = rNodes.Count(); nN--; )
+ {
+ SwNode* pNode = rNodes[nN];
+ if( !pNode )
+ continue;
+ const SwOLENode* pOleNode = pNode->GetOLENode();
+ if( !pOleNode )
+ continue;
+ const SwOLEObj& rOObj = pOleNode->GetOLEObj();
+ if( aChartOleObjectName == rOObj.GetCurrentPersistName() )
+ {
+ aChartTableName = pOleNode->GetChartTableName();
+ break;
+ }
+ }
+
+ if( !aChartTableName.isEmpty() )
+ {
+ //the wrong range is still shifted one row down
+ //thus the first row is missing and an invalid row at the end is added.
+ //Therefore we need to shift the range one row up
+ SwRangeDescriptor aDesc;
+ if (aRangeRepresentation.isEmpty())
+ return xRes; // we can't handle this thus returning an empty references
+
+ aRangeRepresentation = aRangeRepresentation.copy( 1 ); // get rid of '.' to have only the cell range left
+ FillRangeDescriptor( aDesc, aRangeRepresentation );
+ aDesc.Normalize();
+
+ if (aDesc.nTop <= 0) // no chance to shift the range one row up?
+ return xRes; // we can't handle this thus returning an empty references
+
+ aDesc.nTop -= 1;
+ aDesc.nBottom -= 1;
+
+ OUString aNewStartCell( sw_GetCellName( aDesc.nLeft, aDesc.nTop ) );
+ OUString aNewEndCell( sw_GetCellName( aDesc.nRight, aDesc.nBottom ) );
+ aRangeRepresentation = GetRangeRepFromTableAndCells(
+ aChartTableName, aNewStartCell, aNewEndCell, true );
+ bOk = GetSubranges( aRangeRepresentation, aSubRanges, true );
+ }
+ }
+ if (!bOk) // different tables used, or incorrect range specifiers
+ throw lang::IllegalArgumentException();
+
+ SortSubranges( aSubRanges, bDtaSrcIsColumns );
+
+ // get table format for that single table from above
+ SwFrameFormat *pTableFormat = nullptr; // pointer to table format
+ std::shared_ptr<SwUnoCursor> pUnoCursor; // here required to check if the cells in the range do actually exist
+ if (aSubRanges.hasElements())
+ GetFormatAndCreateCursorFromRangeRep( m_pDoc, aSubRanges[0], &pTableFormat, pUnoCursor );
+
+ if (!pTableFormat || !pUnoCursor)
+ throw lang::IllegalArgumentException();
+
+ SwTable* pTable = SwTable::FindTable(pTableFormat);
+ if (pTable->IsTableComplex())
+ return xRes; // we can't handle this thus returning an empty references
+
+ // get a character map in the size of the table to mark
+ // all the ranges to use in
+ sal_Int32 nRows = pTable->GetTabLines().size();
+ sal_Int32 nCols = 0;
+ // As per tdf#149718 one should know that some cells can be merged together.
+ // Therefore, the number of columns (boxes in each row) are not necessarily
+ // equal. Here, we calculate the maximum number of columns in all rows.
+ for (sal_Int32 i = 0; i < nRows; ++i)
+ nCols = std::max(nCols, static_cast<sal_Int32>(pTable->GetTabLines()[i]->GetTabBoxes().size()));
+
+ std::vector<std::vector<char>> aMap(nRows);
+ for (sal_Int32 i = 0; i < nRows; ++i)
+ aMap[i].resize(nCols);
+
+ // iterate over subranges and mark used cells in above map
+ //!! by proceeding this way we automatically get rid of
+ //!! multiple listed or overlapping cell ranges which should
+ //!! just be ignored silently
+ for (const OUString& rSubRange : std::as_const(aSubRanges))
+ {
+ OUString aTableName, aStartCell, aEndCell;
+ bool bOk2 = GetTableAndCellsFromRangeRep(
+ rSubRange, aTableName, aStartCell, aEndCell );
+ OSL_ENSURE(bOk2, "failed to get table and start/end cells");
+
+ sal_Int32 nStartRow, nStartCol, nEndRow, nEndCol;
+ SwXTextTable::GetCellPosition(aStartCell, nStartCol, nStartRow);
+ SwXTextTable::GetCellPosition(aEndCell, nEndCol, nEndRow);
+ OSL_ENSURE( nStartRow <= nEndRow && nStartCol <= nEndCol,
+ "cell range not normalized");
+
+ // test if the ranges span more than the available cells
+ if( nStartRow < 0 || nEndRow >= nRows ||
+ nStartCol < 0 || nEndCol >= nCols )
+ {
+ throw lang::IllegalArgumentException();
+ }
+ for (sal_Int32 k1 = nStartRow; k1 <= nEndRow; ++k1)
+ {
+ for (sal_Int32 k2 = nStartCol; k2 <= nEndCol; ++k2)
+ aMap[k1][k2] = 'x';
+ }
+ }
+
+ // find label and data sequences to use
+
+ sal_Int32 oi; // outer index (slower changing index)
+ sal_Int32 ii; // inner index (faster changing index)
+ sal_Int32 oiEnd = bDtaSrcIsColumns ? nCols : nRows;
+ sal_Int32 iiEnd = bDtaSrcIsColumns ? nRows : nCols;
+ std::vector<sal_Int32> aLabelIdx(oiEnd);
+ std::vector<sal_Int32> aDataStartIdx(oiEnd);
+ std::vector<sal_Int32> aDataLen(oiEnd);
+ for (oi = 0; oi < oiEnd; ++oi)
+ {
+ aLabelIdx[oi] = -1;
+ aDataStartIdx[oi] = -1;
+ aDataLen[oi] = 0;
+ }
+
+ for (oi = 0; oi < oiEnd; ++oi)
+ {
+ ii = 0;
+ while (ii < iiEnd)
+ {
+ char &rChar = bDtaSrcIsColumns ? aMap[ii][oi] : aMap[oi][ii];
+
+ // label should be used but is not yet found?
+ if (rChar == 'x' && bFirstIsLabel && aLabelIdx[oi] == -1)
+ {
+ aLabelIdx[oi] = ii;
+ rChar = 'L'; // setting a different char for labels here
+ // makes the test for the data sequence below
+ // easier
+ }
+
+ // find data sequence
+ if (rChar == 'x' && aDataStartIdx[oi] == -1)
+ {
+ aDataStartIdx[oi] = ii;
+
+ // get length of data sequence
+ sal_Int32 nL = 0;
+ while (ii< iiEnd && 'x' == (bDtaSrcIsColumns ? aMap[ii][oi] : aMap[oi][ii]))
+ {
+ ++nL; ++ii;
+ }
+ aDataLen[oi] = nL;
+
+ // check that there is no other separate sequence of data
+ // to be found because that is not supported
+ while (ii < iiEnd)
+ {
+ if ('x' == (bDtaSrcIsColumns ? aMap[ii][oi] : aMap[oi][ii]))
+ throw lang::IllegalArgumentException();
+ ++ii;
+ }
+ }
+ else
+ ++ii;
+ }
+ }
+
+ // make some other consistency checks while calculating
+ // the number of XLabeledDataSequence to build:
+ // - labels should always be used or not at all
+ // - the data sequences should have equal non-zero length
+ sal_Int32 nNumLDS = 0;
+ if (oiEnd > 0)
+ {
+ for (oi = 0; oi < oiEnd; ++oi)
+ {
+ // row/col used at all?
+ if (aDataStartIdx[oi] != -1 &&
+ (!bFirstIsLabel || aLabelIdx[oi] != -1))
+ {
+ ++nNumLDS;
+ }
+ }
+ }
+ if (nNumLDS == 0)
+ throw lang::IllegalArgumentException();
+
+ // now we should have all necessary data to build a proper DataSource
+ // thus if we came this far there should be no further problem
+ if (bTestOnly)
+ return xRes; // have createDataSourcePossible return true
+
+ // create data source from found label and data sequences
+ uno::Sequence<uno::Reference<chart2::data::XDataSequence>> aLabelSeqs(nNumLDS);
+ uno::Reference<chart2::data::XDataSequence>* pLabelSeqs = aLabelSeqs.getArray();
+ uno::Sequence<uno::Reference<chart2::data::XDataSequence>> aDataSeqs(nNumLDS);
+ uno::Reference<chart2::data::XDataSequence>* pDataSeqs = aDataSeqs.getArray();
+ sal_Int32 nSeqsIdx = 0;
+ for (oi = 0; oi < oiEnd; ++oi)
+ {
+ // row/col not used? (see if-statement above where nNumLDS was counted)
+ if (!(aDataStartIdx[oi] != -1 &&
+ (!bFirstIsLabel || aLabelIdx[oi] != -1)))
+ continue;
+
+ // get cell ranges for label and data
+
+ SwRangeDescriptor aLabelDesc;
+ SwRangeDescriptor aDataDesc;
+ if (bDtaSrcIsColumns) // use columns
+ {
+ aLabelDesc.nTop = aLabelIdx[oi];
+ aLabelDesc.nLeft = oi;
+ aLabelDesc.nBottom = aLabelDesc.nTop;
+ aLabelDesc.nRight = oi;
+
+ aDataDesc.nTop = aDataStartIdx[oi];
+ aDataDesc.nLeft = oi;
+ aDataDesc.nBottom = aDataDesc.nTop + aDataLen[oi] - 1;
+ aDataDesc.nRight = oi;
+ }
+ else // use rows
+ {
+ aLabelDesc.nTop = oi;
+ aLabelDesc.nLeft = aLabelIdx[oi];
+ aLabelDesc.nBottom = oi;
+ aLabelDesc.nRight = aLabelDesc.nLeft;
+
+ aDataDesc.nTop = oi;
+ aDataDesc.nLeft = aDataStartIdx[oi];
+ aDataDesc.nBottom = oi;
+ aDataDesc.nRight = aDataDesc.nLeft + aDataLen[oi] - 1;
+ }
+ const OUString aBaseName = pTableFormat->GetName() + ".";
+
+ OUString aLabelRange;
+ if (aLabelIdx[oi] != -1)
+ {
+ aLabelRange = aBaseName
+ + sw_GetCellName( aLabelDesc.nLeft, aLabelDesc.nTop )
+ + ":" + sw_GetCellName( aLabelDesc.nRight, aLabelDesc.nBottom );
+ }
+
+ OUString aDataRange = aBaseName
+ + sw_GetCellName( aDataDesc.nLeft, aDataDesc.nTop )
+ + ":" + sw_GetCellName( aDataDesc.nRight, aDataDesc.nBottom );
+
+ // get cursors spanning the cell ranges for label and data
+ std::shared_ptr<SwUnoCursor> pLabelUnoCursor;
+ std::shared_ptr<SwUnoCursor> pDataUnoCursor;
+ GetFormatAndCreateCursorFromRangeRep(m_pDoc, aLabelRange, &pTableFormat, pLabelUnoCursor);
+ GetFormatAndCreateCursorFromRangeRep(m_pDoc, aDataRange, &pTableFormat, pDataUnoCursor);
+
+ // create XDataSequence's from cursors
+ if (pLabelUnoCursor)
+ pLabelSeqs[nSeqsIdx] = new SwChartDataSequence(*this, *pTableFormat, pLabelUnoCursor);
+ OSL_ENSURE(pDataUnoCursor, "pointer to data sequence missing");
+ if (pDataUnoCursor)
+ pDataSeqs[nSeqsIdx] = new SwChartDataSequence(*this, *pTableFormat, pDataUnoCursor);
+ if (pLabelUnoCursor || pDataUnoCursor)
+ ++nSeqsIdx;
+ }
+ OSL_ENSURE(nSeqsIdx == nNumLDS, "mismatch between sequence size and num,ber of entries");
+
+ // build data source from data and label sequences
+ uno::Sequence<uno::Reference<chart2::data::XLabeledDataSequence>> aLDS(nNumLDS);
+ uno::Reference<chart2::data::XLabeledDataSequence>* pLDS = aLDS.getArray();
+ for (sal_Int32 i = 0; i < nNumLDS; ++i)
+ {
+ rtl::Reference<SwChartLabeledDataSequence> pLabeledDtaSeq = new SwChartLabeledDataSequence;
+ pLabeledDtaSeq->setLabel(pLabelSeqs[i]);
+ pLabeledDtaSeq->setValues(pDataSeqs[i]);
+ pLDS[i] = pLabeledDtaSeq;
+ }
+
+ // apply 'SequenceMapping' if it was provided
+ if (aSequenceMapping.hasElements())
+ {
+ uno::Sequence<uno::Reference<chart2::data::XLabeledDataSequence>> aOld_LDS(aLDS);
+ uno::Reference<chart2::data::XLabeledDataSequence>* pOld_LDS = aOld_LDS.getArray();
+
+ sal_Int32 nNewCnt = 0;
+ for (sal_Int32 nIdx : std::as_const(aSequenceMapping))
+ {
+ // check that index to be used is valid
+ // and has not yet been used
+ if (0 <= nIdx && nIdx < nNumLDS && pOld_LDS[nIdx].is())
+ {
+ pLDS[nNewCnt++] = pOld_LDS[nIdx];
+
+ // mark index as being used already (avoids duplicate entries)
+ pOld_LDS[nIdx].clear();
+ }
+ }
+ // add not yet used 'old' sequences to new one
+ for (sal_Int32 i = 0; i < nNumLDS; ++i)
+ {
+ if (pOld_LDS[i].is())
+ pLDS[nNewCnt++] = pOld_LDS[i];
+ }
+ OSL_ENSURE(nNewCnt == nNumLDS, "unexpected size of resulting sequence");
+ }
+
+ xRes = new SwChartDataSource(aLDS);
+ return xRes;
+}
+
+sal_Bool SAL_CALL SwChartDataProvider::createDataSourcePossible(
+ const uno::Sequence< beans::PropertyValue >& rArguments )
+{
+ SolarMutexGuard aGuard;
+
+ bool bPossible = true;
+ try
+ {
+ Impl_createDataSource( rArguments, true );
+ }
+ catch (lang::IllegalArgumentException &)
+ {
+ bPossible = false;
+ }
+
+ return bPossible;
+}
+
+uno::Reference< chart2::data::XDataSource > SAL_CALL SwChartDataProvider::createDataSource(
+ const uno::Sequence< beans::PropertyValue >& rArguments )
+{
+ SolarMutexGuard aGuard;
+ return Impl_createDataSource( rArguments );
+}
+
+/**
+ * Fix for #i79009
+ * we need to return a property that has the same value as the property
+ * 'CellRangeRepresentation' but for all rows which are increased by one.
+ * E.g. Table1.A1:D5 -> Table1,A2:D6
+ * Since the problem is only for old charts which did not support multiple
+ * we do not need to provide that property/string if the 'CellRangeRepresentation'
+ * contains multiple ranges.
+ */
+OUString SwChartDataProvider::GetBrokenCellRangeForExport(
+ std::u16string_view rCellRangeRepresentation )
+{
+ // check that we do not have multiple ranges
+ if (std::u16string_view::npos == rCellRangeRepresentation.find( ';' ))
+ {
+ // get current cell and table names
+ OUString aTableName, aStartCell, aEndCell;
+ GetTableAndCellsFromRangeRep( rCellRangeRepresentation,
+ aTableName, aStartCell, aEndCell, false );
+ sal_Int32 nStartCol = -1, nStartRow = -1, nEndCol = -1, nEndRow = -1;
+ SwXTextTable::GetCellPosition( aStartCell, nStartCol, nStartRow );
+ SwXTextTable::GetCellPosition( aEndCell, nEndCol, nEndRow );
+
+ // get new cell names
+ ++nStartRow;
+ ++nEndRow;
+ aStartCell = sw_GetCellName( nStartCol, nStartRow );
+ aEndCell = sw_GetCellName( nEndCol, nEndRow );
+
+ return GetRangeRepFromTableAndCells( aTableName,
+ aStartCell, aEndCell, false );
+ }
+
+ return OUString();
+}
+
+uno::Sequence< beans::PropertyValue > SAL_CALL SwChartDataProvider::detectArguments(
+ const uno::Reference< chart2::data::XDataSource >& xDataSource )
+{
+ SolarMutexGuard aGuard;
+ if (m_bDisposed)
+ throw lang::DisposedException();
+
+ uno::Sequence< beans::PropertyValue > aResult;
+ if (!xDataSource.is())
+ return aResult;
+
+ const uno::Sequence< uno::Reference< chart2::data::XLabeledDataSequence > > aDS_LDS( xDataSource->getDataSequences() );
+ const uno::Reference< chart2::data::XLabeledDataSequence > *pDS_LDS = aDS_LDS.getConstArray();
+ sal_Int32 nNumDS_LDS = aDS_LDS.getLength();
+
+ if (nNumDS_LDS == 0)
+ {
+ OSL_FAIL( "XLabeledDataSequence in data source contains 0 entries" );
+ return aResult;
+ }
+
+ SwFrameFormat *pTableFormat = nullptr;
+ SwTable *pTable = nullptr;
+ OUString aTableName;
+ sal_Int32 nTableRows = 0;
+ sal_Int32 nTableCols = 0;
+
+ // data used to build 'CellRangeRepresentation' from later on
+ std::vector< std::vector< char > > aMap;
+
+ uno::Sequence< sal_Int32 > aSequenceMapping( nNumDS_LDS );
+ sal_Int32 *pSequenceMapping = aSequenceMapping.getArray();
+
+ OUString aCellRanges;
+ sal_Int16 nDtaSrcIsColumns = -1;// -1: don't know yet, 0: false, 1: true -2: neither
+ sal_Int32 nLabelSeqLen = -1; // used to see if labels are always used or not and have
+ // the expected size of 1 (i.e. if FirstCellAsLabel can
+ // be determined)
+ // -1: don't know yet, 0: not used, 1: always a single labe cell, ...
+ // -2: neither/failed
+ for (sal_Int32 nDS1 = 0; nDS1 < nNumDS_LDS; ++nDS1)
+ {
+ uno::Reference< chart2::data::XLabeledDataSequence > xLabeledDataSequence( pDS_LDS[nDS1] );
+ if( !xLabeledDataSequence.is() )
+ {
+ OSL_FAIL("got NULL for XLabeledDataSequence from Data source");
+ continue;
+ }
+ const uno::Reference< chart2::data::XDataSequence > xCurLabel = xLabeledDataSequence->getLabel();
+ const uno::Reference< chart2::data::XDataSequence > xCurValues = xLabeledDataSequence->getValues();
+
+ // get sequence lengths for label and values.
+ // (0 length is Ok)
+ sal_Int32 nCurLabelSeqLen = -1;
+ sal_Int32 nCurValuesSeqLen = -1;
+ if (xCurLabel.is())
+ nCurLabelSeqLen = xCurLabel->getData().getLength();
+ if (xCurValues.is())
+ nCurValuesSeqLen = xCurValues->getData().getLength();
+
+ // check for consistent use of 'first cell as label'
+ if (nLabelSeqLen == -1) // set initial value to compare with below further on
+ nLabelSeqLen = nCurLabelSeqLen;
+ if (nLabelSeqLen != nCurLabelSeqLen)
+ nLabelSeqLen = -2; // failed / no consistent use of label cells
+
+ // get table and cell names for label and values data sequences
+ // (start and end cell will be sorted, i.e. start cell <= end cell)
+ OUString aLabelTableName, aLabelStartCell, aLabelEndCell;
+ OUString aValuesTableName, aValuesStartCell, aValuesEndCell;
+ OUString aLabelRange, aValuesRange;
+ if (xCurLabel.is())
+ aLabelRange = xCurLabel->getSourceRangeRepresentation();
+ if (xCurValues.is())
+ aValuesRange = xCurValues->getSourceRangeRepresentation();
+ if ((!aLabelRange.isEmpty() && !GetTableAndCellsFromRangeRep( aLabelRange,
+ aLabelTableName, aLabelStartCell, aLabelEndCell )) ||
+ !GetTableAndCellsFromRangeRep( aValuesRange,
+ aValuesTableName, aValuesStartCell, aValuesEndCell ))
+ {
+ return aResult; // failed -> return empty property sequence
+ }
+
+ // make sure all sequences use the same table
+ if (aTableName.isEmpty())
+ aTableName = aValuesTableName; // get initial value to compare with
+ if (aTableName.isEmpty() ||
+ aTableName != aValuesTableName ||
+ (!aLabelTableName.isEmpty() && aTableName != aLabelTableName))
+ {
+ return aResult; // failed -> return empty property sequence
+ }
+
+ // try to get 'DataRowSource' value (ROWS or COLUMNS) from inspecting
+ // first and last cell used in both sequences
+
+ sal_Int32 nFirstCol = -1, nFirstRow = -1, nLastCol = -1, nLastRow = -1;
+ const OUString aCell( !aLabelStartCell.isEmpty() ? aLabelStartCell : aValuesStartCell );
+ OSL_ENSURE( !aCell.isEmpty() , "start cell missing?" );
+ SwXTextTable::GetCellPosition( aCell, nFirstCol, nFirstRow);
+ SwXTextTable::GetCellPosition( aValuesEndCell, nLastCol, nLastRow);
+
+ sal_Int16 nDirection = -1; // -1: not yet set, 0: columns, 1: rows, -2: failed
+ if (nFirstCol == nLastCol && nFirstRow == nLastRow) // a single cell...
+ {
+ OSL_ENSURE( nCurLabelSeqLen == 0 && nCurValuesSeqLen == 1,
+ "trying to determine 'DataRowSource': something's fishy... should have been a single cell");
+ nDirection = 0; // default direction for a single cell should be 'columns'
+ }
+ else // more than one cell is available (in values and label together!)
+ {
+ if (nFirstCol == nLastCol && nFirstRow != nLastRow)
+ nDirection = 1;
+ else if (nFirstCol != nLastCol && nFirstRow == nLastRow)
+ nDirection = 0;
+ else
+ {
+ OSL_FAIL( "trying to determine 'DataRowSource': unexpected case found" );
+ nDirection = -2;
+ }
+ }
+ // check for consistent direction of data source
+ if (nDtaSrcIsColumns == -1) // set initial value to compare with below
+ nDtaSrcIsColumns = nDirection;
+ if (nDtaSrcIsColumns != nDirection)
+ {
+ nDtaSrcIsColumns = -2; // failed
+ }
+
+ if (nDtaSrcIsColumns == 0 || nDtaSrcIsColumns == 1)
+ {
+ // build data to obtain 'SequenceMapping' later on
+
+ OSL_ENSURE( nDtaSrcIsColumns == 0 || /* rows */
+ nDtaSrcIsColumns == 1, /* columns */
+ "unexpected value for 'nDtaSrcIsColumns'" );
+ pSequenceMapping[nDS1] = nDtaSrcIsColumns ? nFirstCol : nFirstRow;
+
+ // build data used to determine 'CellRangeRepresentation' later on
+
+ GetTableByName( *m_pDoc, aTableName, &pTableFormat, &pTable );
+ if (!pTable || pTable->IsTableComplex())
+ return aResult; // failed -> return empty property sequence
+ nTableRows = pTable->GetTabLines().size();
+ nTableCols = pTable->GetTabLines().front()->GetTabBoxes().size();
+ aMap.resize( nTableRows );
+ for (sal_Int32 i = 0; i < nTableRows; ++i)
+ aMap[i].resize( nTableCols );
+
+ if (!aLabelStartCell.isEmpty() && !aLabelEndCell.isEmpty())
+ {
+ sal_Int32 nStartCol = -1, nStartRow = -1, nEndCol = -1, nEndRow = -1;
+ SwXTextTable::GetCellPosition( aLabelStartCell, nStartCol, nStartRow );
+ SwXTextTable::GetCellPosition( aLabelEndCell, nEndCol, nEndRow );
+ if (nStartRow < 0 || nEndRow >= nTableRows ||
+ nStartCol < 0 || nEndCol >= nTableCols)
+ {
+ return aResult; // failed -> return empty property sequence
+ }
+ for (sal_Int32 i = nStartRow; i <= nEndRow; ++i)
+ {
+ for (sal_Int32 k = nStartCol; k <= nEndCol; ++k)
+ {
+ char &rChar = aMap[i][k];
+ if (rChar == '\0') // check for overlapping values and/or labels
+ rChar = 'L';
+ else
+ return aResult; // failed -> return empty property sequence
+ }
+ }
+ }
+ if (!aValuesStartCell.isEmpty() && !aValuesEndCell.isEmpty())
+ {
+ sal_Int32 nStartCol = -1, nStartRow = -1, nEndCol = -1, nEndRow = -1;
+ SwXTextTable::GetCellPosition( aValuesStartCell, nStartCol, nStartRow );
+ SwXTextTable::GetCellPosition( aValuesEndCell, nEndCol, nEndRow );
+ if (nStartRow < 0 || nEndRow >= nTableRows ||
+ nStartCol < 0 || nEndCol >= nTableCols)
+ {
+ return aResult; // failed -> return empty property sequence
+ }
+ for (sal_Int32 i = nStartRow; i <= nEndRow; ++i)
+ {
+ for (sal_Int32 k = nStartCol; k <= nEndCol; ++k)
+ {
+ char &rChar = aMap[i][k];
+ if (rChar == '\0') // check for overlapping values and/or labels
+ rChar = 'x';
+ else
+ return aResult; // failed -> return empty property sequence
+ }
+ }
+ }
+ }
+
+#if OSL_DEBUG_LEVEL > 0
+ // do some extra sanity checking that the length of the sequences
+ // matches their range representation
+ {
+ sal_Int32 nStartRow = -1, nStartCol = -1, nEndRow = -1, nEndCol = -1;
+ if (xCurLabel.is())
+ {
+ SwXTextTable::GetCellPosition( aLabelStartCell, nStartCol, nStartRow);
+ SwXTextTable::GetCellPosition( aLabelEndCell, nEndCol, nEndRow);
+ OSL_ENSURE( (nStartCol == nEndCol && (nEndRow - nStartRow + 1) == xCurLabel->getData().getLength()) ||
+ (nStartRow == nEndRow && (nEndCol - nStartCol + 1) == xCurLabel->getData().getLength()),
+ "label sequence length does not match range representation!" );
+ }
+ if (xCurValues.is())
+ {
+ SwXTextTable::GetCellPosition( aValuesStartCell, nStartCol, nStartRow);
+ SwXTextTable::GetCellPosition( aValuesEndCell, nEndCol, nEndRow);
+ OSL_ENSURE( (nStartCol == nEndCol && (nEndRow - nStartRow + 1) == xCurValues->getData().getLength()) ||
+ (nStartRow == nEndRow && (nEndCol - nStartCol + 1) == xCurValues->getData().getLength()),
+ "value sequence length does not match range representation!" );
+ }
+ }
+#endif
+ } // for
+
+ // build value for 'CellRangeRepresentation'
+
+ const OUString aCellRangeBase = aTableName + ".";
+ OUString aCurRange;
+ for (sal_Int32 i = 0; i < nTableRows; ++i)
+ {
+ for (sal_Int32 k = 0; k < nTableCols; ++k)
+ {
+ if (aMap[i][k] != '\0') // top-left cell of a sub-range found
+ {
+ // find rectangular sub-range to use
+ sal_Int32 nRowIndex1 = i; // row index
+ sal_Int32 nColIndex1 = k; // column index
+ sal_Int32 nRowSubLen = 0;
+ sal_Int32 nColSubLen = 0;
+ while (nRowIndex1 < nTableRows && aMap[nRowIndex1++][k] != '\0')
+ ++nRowSubLen;
+ // be aware of shifted sequences!
+ // (according to the checks done prior the length should be ok)
+ while (nColIndex1 < nTableCols && aMap[i][nColIndex1] != '\0'
+ && aMap[i + nRowSubLen-1][nColIndex1] != '\0')
+ {
+ ++nColIndex1;
+ ++nColSubLen;
+ }
+ OUString aStartCell( sw_GetCellName( k, i ) );
+ OUString aEndCell( sw_GetCellName( k + nColSubLen - 1, i + nRowSubLen - 1) );
+ aCurRange = aCellRangeBase + aStartCell + ":" + aEndCell;
+ if (!aCellRanges.isEmpty())
+ aCellRanges += ";";
+ aCellRanges += aCurRange;
+
+ // clear already found sub-range from map
+ for (sal_Int32 nRowIndex2 = 0; nRowIndex2 < nRowSubLen; ++nRowIndex2)
+ for (sal_Int32 nColumnIndex2 = 0; nColumnIndex2 < nColSubLen; ++nColumnIndex2)
+ aMap[i + nRowIndex2][k + nColumnIndex2] = '\0';
+ }
+ }
+ }
+ // to be nice to the user we now sort the cell ranges according to
+ // rows or columns depending on the direction used in the data source
+ uno::Sequence< OUString > aSortedRanges;
+ GetSubranges( aCellRanges, aSortedRanges, false /*sub ranges should already be normalized*/ );
+ SortSubranges( aSortedRanges, (nDtaSrcIsColumns == 1) );
+ OUString aSortedCellRanges;
+ for (const OUString& rSortedRange : std::as_const(aSortedRanges))
+ {
+ if (!aSortedCellRanges.isEmpty())
+ aSortedCellRanges += ";";
+ aSortedCellRanges += rSortedRange;
+ }
+
+ // build value for 'SequenceMapping'
+
+ uno::Sequence< sal_Int32 > aSortedMapping( aSequenceMapping );
+ auto [begin, end] = asNonConstRange(aSortedMapping);
+ std::sort(begin, end);
+ bool bNeedSequenceMapping = false;
+ for (sal_Int32 i = 0; i < aSequenceMapping.getLength(); ++i)
+ {
+ auto it = std::find( std::cbegin(aSortedMapping), std::cend(aSortedMapping),
+ aSequenceMapping[i] );
+ pSequenceMapping[i] = std::distance(std::cbegin(aSortedMapping), it);
+
+ if (i != std::as_const(aSequenceMapping)[i])
+ bNeedSequenceMapping = true;
+ }
+
+ // check if 'SequenceMapping' is actually not required...
+ // (don't write unnecessary properties to the XML file)
+ if (!bNeedSequenceMapping)
+ aSequenceMapping.realloc(0);
+
+ // build resulting properties
+
+ OSL_ENSURE(nLabelSeqLen >= 0 || nLabelSeqLen == -2 /*not used*/,
+ "unexpected value for 'nLabelSeqLen'" );
+ bool bFirstCellIsLabel = false; // default value if 'nLabelSeqLen' could not properly determined
+ if (nLabelSeqLen > 0) // == 0 means no label sequence in use
+ bFirstCellIsLabel = true;
+
+ OSL_ENSURE( !aSortedCellRanges.isEmpty(), "CellRangeRepresentation missing" );
+ const OUString aBrokenCellRangeForExport( GetBrokenCellRangeForExport( aSortedCellRanges ) );
+
+ aResult.realloc(5);
+ auto pResult = aResult.getArray();
+ sal_Int32 nProps = 0;
+ pResult[nProps ].Name = "FirstCellAsLabel";
+ pResult[nProps++].Value <<= bFirstCellIsLabel;
+ pResult[nProps ].Name = "CellRangeRepresentation";
+ pResult[nProps++].Value <<= aSortedCellRanges;
+ if (!aBrokenCellRangeForExport.isEmpty())
+ {
+ pResult[nProps ].Name = "BrokenCellRangeForExport";
+ pResult[nProps++].Value <<= aBrokenCellRangeForExport;
+ }
+ if (nDtaSrcIsColumns == 0 || nDtaSrcIsColumns == 1)
+ {
+ chart::ChartDataRowSource eDataRowSource = (nDtaSrcIsColumns == 1) ?
+ chart::ChartDataRowSource_COLUMNS : chart::ChartDataRowSource_ROWS;
+ pResult[nProps ].Name = "DataRowSource";
+ pResult[nProps++].Value <<= eDataRowSource;
+
+ if (aSequenceMapping.hasElements())
+ {
+ pResult[nProps ].Name = "SequenceMapping";
+ pResult[nProps++].Value <<= aSequenceMapping;
+ }
+ }
+ aResult.realloc( nProps );
+
+ return aResult;
+}
+
+uno::Reference< chart2::data::XDataSequence > SwChartDataProvider::Impl_createDataSequenceByRangeRepresentation(
+ std::u16string_view rRangeRepresentation, bool bTestOnly )
+{
+ if (m_bDisposed)
+ throw lang::DisposedException();
+
+ SwFrameFormat *pTableFormat = nullptr; // pointer to table format
+ std::shared_ptr<SwUnoCursor> pUnoCursor; // pointer to new created cursor spanning the cell range
+ GetFormatAndCreateCursorFromRangeRep( m_pDoc, rRangeRepresentation,
+ &pTableFormat, pUnoCursor );
+ if (!pTableFormat || !pUnoCursor)
+ throw lang::IllegalArgumentException();
+
+ // check that cursors point and mark are in a single row or column.
+ OUString aCellRange( GetCellRangeName( *pTableFormat, *pUnoCursor ) );
+ SwRangeDescriptor aDesc;
+ FillRangeDescriptor( aDesc, aCellRange );
+ if (aDesc.nTop != aDesc.nBottom && aDesc.nLeft != aDesc.nRight)
+ throw lang::IllegalArgumentException();
+
+ OSL_ENSURE( pTableFormat && pUnoCursor, "table format or cursor missing" );
+ uno::Reference< chart2::data::XDataSequence > xDataSeq;
+ if (!bTestOnly)
+ xDataSeq = new SwChartDataSequence( *this, *pTableFormat, pUnoCursor );
+
+ return xDataSeq;
+}
+
+sal_Bool SAL_CALL SwChartDataProvider::createDataSequenceByRangeRepresentationPossible(
+ const OUString& rRangeRepresentation )
+{
+ SolarMutexGuard aGuard;
+
+ bool bPossible = true;
+ try
+ {
+ Impl_createDataSequenceByRangeRepresentation( rRangeRepresentation, true );
+ }
+ catch (lang::IllegalArgumentException &)
+ {
+ bPossible = false;
+ }
+
+ return bPossible;
+}
+
+uno::Reference< chart2::data::XDataSequence > SAL_CALL SwChartDataProvider::createDataSequenceByRangeRepresentation(
+ const OUString& rRangeRepresentation )
+{
+ SolarMutexGuard aGuard;
+ return Impl_createDataSequenceByRangeRepresentation( rRangeRepresentation );
+}
+
+uno::Reference< sheet::XRangeSelection > SAL_CALL SwChartDataProvider::getRangeSelection( )
+{
+ // note: it is no error to return nothing here
+ return uno::Reference< sheet::XRangeSelection >();
+}
+
+uno::Reference<css::chart2::data::XDataSequence> SAL_CALL
+ SwChartDataProvider::createDataSequenceByValueArray(
+ const OUString& /*aRole*/, const OUString& /*aRangeRepresentation*/,
+ const OUString& /*aRoleQualifier*/ )
+{
+ return uno::Reference<css::chart2::data::XDataSequence>();
+}
+
+void SAL_CALL SwChartDataProvider::dispose( )
+{
+ bool bMustDispose( false );
+ {
+ std::unique_lock aGuard( GetChartMutex() );
+ bMustDispose = !m_bDisposed;
+ if (!m_bDisposed)
+ m_bDisposed = true;
+ }
+ if (!bMustDispose)
+ return;
+
+ // dispose all data-sequences
+ for (const auto& rEntry : m_aDataSequences)
+ {
+ DisposeAllDataSequences( rEntry.first );
+ }
+ // release all references to data-sequences
+ m_aDataSequences.clear();
+
+ // require listeners to release references to this object
+ lang::EventObject aEvtObj( static_cast< chart2::data::XDataProvider * >(this) );
+ std::unique_lock aGuard( GetChartMutex() );
+ m_aEventListeners.disposeAndClear( aGuard, aEvtObj );
+}
+
+void SAL_CALL SwChartDataProvider::addEventListener(
+ const uno::Reference< lang::XEventListener >& rxListener )
+{
+ std::unique_lock aGuard( GetChartMutex() );
+ if (!m_bDisposed && rxListener.is())
+ m_aEventListeners.addInterface( aGuard, rxListener );
+}
+
+void SAL_CALL SwChartDataProvider::removeEventListener(
+ const uno::Reference< lang::XEventListener >& rxListener )
+{
+ std::unique_lock aGuard( GetChartMutex() );
+ if (!m_bDisposed && rxListener.is())
+ m_aEventListeners.removeInterface( aGuard, rxListener );
+}
+
+OUString SAL_CALL SwChartDataProvider::getImplementationName( )
+{
+ return "SwChartDataProvider";
+}
+
+sal_Bool SAL_CALL SwChartDataProvider::supportsService(const OUString& rServiceName )
+{
+ return cppu::supportsService(this, rServiceName);
+}
+
+uno::Sequence< OUString > SAL_CALL SwChartDataProvider::getSupportedServiceNames( )
+{
+ return { "com.sun.star.chart2.data.DataProvider"};
+}
+
+void SwChartDataProvider::AddDataSequence( const SwTable &rTable, rtl::Reference< SwChartDataSequence > const &rxDataSequence )
+{
+ Vec_DataSequenceRef_t& rVec = m_aDataSequences[ &rTable ];
+ assert(std::find_if(rVec.begin(), rVec.end(),
+ [&rxDataSequence](const unotools::WeakReference < SwChartDataSequence >& i)
+ {
+ return i.get() == rxDataSequence;
+ }) == rVec.end() && "duplicate insert");
+ rVec.push_back( rxDataSequence );
+}
+
+void SwChartDataProvider::RemoveDataSequence( const SwTable &rTable, rtl::Reference< SwChartDataSequence > const &rxDataSequence )
+{
+ Vec_DataSequenceRef_t& rVec = m_aDataSequences[ &rTable ];
+ std::erase_if(rVec,
+ [&rxDataSequence](const unotools::WeakReference < SwChartDataSequence >& i)
+ {
+ return i.get() == rxDataSequence;
+ });
+}
+
+void SwChartDataProvider::InvalidateTable( const SwTable *pTable, bool bImmediate )
+{
+ OSL_ENSURE( pTable, "table pointer is NULL" );
+ if (!pTable)
+ return;
+
+ if (!m_bDisposed)
+ pTable->GetFrameFormat()->GetDoc()->getIDocumentChartDataProviderAccess().GetChartControllerHelper().StartOrContinueLocking();
+
+ const Vec_DataSequenceRef_t &rVec = m_aDataSequences[ pTable ];
+ for (const unotools::WeakReference<SwChartDataSequence>& rItem : rVec)
+ {
+ rtl::Reference< SwChartDataSequence > xRef(rItem);
+ if (xRef.is())
+ {
+ // mark the sequence as 'dirty' and notify listeners
+ xRef->setModified( true );
+ }
+ }
+
+ // tdf#122995 added Immediate-mode to allow non-timer-delayed Chart invalidation
+ if (bImmediate && !m_bDisposed)
+ pTable->GetFrameFormat()->GetDoc()->getIDocumentChartDataProviderAccess().GetChartControllerHelper().Disconnect();
+}
+
+void SwChartDataProvider::DeleteBox( const SwTable *pTable, const SwTableBox &rBox )
+{
+ OSL_ENSURE( pTable, "table pointer is NULL" );
+ if (!pTable)
+ return;
+
+ if (!m_bDisposed)
+ pTable->GetFrameFormat()->GetDoc()->getIDocumentChartDataProviderAccess().GetChartControllerHelper().StartOrContinueLocking();
+
+ Vec_DataSequenceRef_t &rVec = m_aDataSequences[ pTable ];
+
+ // iterate over all data-sequences for that table...
+ auto aIt( rVec.begin() );
+ while (aIt != rVec.end())
+ {
+ bool bNowEmpty = false;
+ bool bSeqDisposed = false;
+
+ // check if weak reference is still valid...
+ rtl::Reference< SwChartDataSequence > pDataSeq(*aIt);
+ if (pDataSeq.is())
+ {
+ // then delete that table box (check if implementation cursor needs to be adjusted)
+ try
+ {
+ bNowEmpty = pDataSeq->DeleteBox( rBox );
+ }
+ catch (const lang::DisposedException&)
+ {
+ bNowEmpty = true;
+ bSeqDisposed = true;
+ }
+ }
+
+ if (bNowEmpty)
+ {
+ aIt = rVec.erase( aIt );
+ if (pDataSeq && !bSeqDisposed)
+ pDataSeq->dispose(); // the current way to tell chart that sth. got removed
+ }
+ else
+ ++aIt;
+ }
+}
+
+void SwChartDataProvider::DisposeAllDataSequences( const SwTable *pTable )
+{
+ OSL_ENSURE( pTable, "table pointer is NULL" );
+ if (!pTable)
+ return;
+
+ if (!m_bDisposed)
+ pTable->GetFrameFormat()->GetDoc()->getIDocumentChartDataProviderAccess().GetChartControllerHelper().StartOrContinueLocking();
+
+ //! make a copy of the STL container!
+ //! This is necessary since calling 'dispose' will implicitly remove an element
+ //! of the original container, and thus any iterator in the original container
+ //! would become invalid.
+ const Vec_DataSequenceRef_t aVec( m_aDataSequences[ pTable ] );
+
+ for (const unotools::WeakReference<SwChartDataSequence>& rItem : aVec)
+ {
+ rtl::Reference< SwChartDataSequence > xRef(rItem);
+ if (xRef.is())
+ {
+ xRef->dispose();
+ }
+ }
+}
+
+/**
+ * SwChartDataProvider::AddRowCols tries to notify charts of added columns
+ * or rows and extends the value sequence respectively (if possible).
+ * If those can be added to the end of existing value data-sequences those
+ * sequences get modified accordingly and will send a modification
+ * notification (calling 'setModified
+ *
+ * Since this function is a work-around for non existent Writer core functionality
+ * (no arbitrary multi-selection in tables that can be used to define a
+ * data-sequence) this function will be somewhat unreliable.
+ * For example we will only try to adapt value sequences. For this we assume
+ * that a sequence of length 1 is a label sequence and those with length >= 2
+ * we presume to be value sequences. Also new cells can only be added in the
+ * direction the value sequence is already pointing (rows / cols) and at the
+ * start or end of the values data-sequence.
+ * Nothing needs to be done if the new cells are in between the table cursors
+ * point and mark since data-sequence are considered to consist of all cells
+ * between those.
+ * New rows/cols need to be added already to the table before calling
+ * this function.
+ */
+void SwChartDataProvider::AddRowCols(
+ const SwTable &rTable,
+ const SwSelBoxes& rBoxes,
+ sal_uInt16 nLines, bool bBehind )
+{
+ if (rTable.IsTableComplex())
+ return;
+
+ const size_t nBoxes = rBoxes.size();
+ if (nBoxes < 1 || nLines < 1)
+ return;
+
+ SwTableBox* pFirstBox = rBoxes[0];
+ SwTableBox* pLastBox = rBoxes.back();
+
+ if (!(pFirstBox && pLastBox))
+ return;
+
+ sal_Int32 nFirstCol = -1, nFirstRow = -1, nLastCol = -1, nLastRow = -1;
+ SwXTextTable::GetCellPosition( pFirstBox->GetName(), nFirstCol, nFirstRow );
+ SwXTextTable::GetCellPosition( pLastBox->GetName(), nLastCol, nLastRow );
+
+ bool bAddCols = false; // default; also to be used if nBoxes == 1 :-/
+ if (nFirstCol == nLastCol && nFirstRow != nLastRow)
+ bAddCols = true;
+ if (nFirstCol != nLastCol && nFirstRow != nLastRow)
+ return;
+
+ //get range of indices in col/rows for new cells
+ sal_Int32 nFirstNewCol = nFirstCol;
+ sal_Int32 nFirstNewRow = bBehind ? nFirstRow + 1 : nFirstRow - nLines;
+ if (bAddCols)
+ {
+ OSL_ENSURE( nFirstCol == nLastCol, "column indices seem broken" );
+ nFirstNewCol = bBehind ? nFirstCol + 1 : nFirstCol - nLines;
+ nFirstNewRow = nFirstRow;
+ }
+
+ // iterate over all data-sequences for the table
+ const Vec_DataSequenceRef_t &rVec = m_aDataSequences[ &rTable ];
+ for (const unotools::WeakReference<SwChartDataSequence>& rItem : rVec)
+ {
+ rtl::Reference< SwChartDataSequence > pDataSeq(rItem);
+ if (pDataSeq.is())
+ {
+ const sal_Int32 nLen = pDataSeq->getTextualData().getLength();
+ if (nLen > 1) // value data-sequence ?
+ {
+ SwRangeDescriptor aDesc;
+ pDataSeq->FillRangeDesc( aDesc );
+
+ chart::ChartDataRowSource eDRSource = chart::ChartDataRowSource_COLUMNS;
+ if (aDesc.nTop == aDesc.nBottom && aDesc.nLeft != aDesc.nRight)
+ eDRSource = chart::ChartDataRowSource_ROWS;
+
+ if (!bAddCols && eDRSource == chart::ChartDataRowSource_COLUMNS)
+ {
+ // add rows: extend affected columns by newly added row cells
+ pDataSeq->ExtendTo( true, nFirstNewRow, nLines );
+ }
+ else if (bAddCols && eDRSource == chart::ChartDataRowSource_ROWS)
+ {
+ // add cols: extend affected rows by newly added column cells
+ pDataSeq->ExtendTo( false, nFirstNewCol, nLines );
+ }
+ }
+ }
+ }
+}
+
+// XRangeXMLConversion
+OUString SAL_CALL SwChartDataProvider::convertRangeToXML( const OUString& rRangeRepresentation )
+{
+ SolarMutexGuard aGuard;
+ if (m_bDisposed)
+ throw lang::DisposedException();
+
+ if (rRangeRepresentation.isEmpty())
+ return OUString();
+
+ OUStringBuffer aRes;
+
+ // multiple ranges are delimited by a ';' like in
+ // "Table1.A1:A4;Table1.C2:C5" the same table must be used in all ranges!
+ SwTable* pFirstFoundTable = nullptr; // to check that only one table will be used
+ sal_Int32 nPos = 0;
+ do {
+ const OUString aRange( rRangeRepresentation.getToken(0, ';', nPos) );
+ SwFrameFormat *pTableFormat = nullptr; // pointer to table format
+ std::shared_ptr<SwUnoCursor> pCursor;
+ GetFormatAndCreateCursorFromRangeRep( m_pDoc, aRange, &pTableFormat, pCursor );
+ if (!pTableFormat)
+ throw lang::IllegalArgumentException();
+ SwTable* pTable = SwTable::FindTable( pTableFormat );
+ if (pTable->IsTableComplex())
+ throw uno::RuntimeException("Table too complex.");
+
+ // check that there is only one table used in all ranges
+ if (!pFirstFoundTable)
+ pFirstFoundTable = pTable;
+ if (pTable != pFirstFoundTable)
+ throw lang::IllegalArgumentException();
+
+ OUString aTableName;
+ OUString aStartCell;
+ OUString aEndCell;
+ if (!GetTableAndCellsFromRangeRep( aRange, aTableName, aStartCell, aEndCell ))
+ throw lang::IllegalArgumentException();
+
+ sal_Int32 nCol, nRow;
+ SwXTextTable::GetCellPosition( aStartCell, nCol, nRow );
+ if (nCol < 0 || nRow < 0)
+ throw uno::RuntimeException("Cell not found.");
+
+ //!! following objects/functions are implemented in XMLRangeHelper.?xx
+ //!! which is a copy of the respective file from chart2 !!
+ XMLRangeHelper::CellRange aCellRange;
+ aCellRange.aTableName = aTableName;
+ aCellRange.aUpperLeft.nColumn = nCol;
+ aCellRange.aUpperLeft.nRow = nRow;
+ aCellRange.aUpperLeft.bIsEmpty = false;
+ if (aStartCell != aEndCell && !aEndCell.isEmpty())
+ {
+ SwXTextTable::GetCellPosition( aEndCell, nCol, nRow );
+ if (nCol < 0 || nRow < 0)
+ throw uno::RuntimeException("Cell not found.");
+
+ aCellRange.aLowerRight.nColumn = nCol;
+ aCellRange.aLowerRight.nRow = nRow;
+ aCellRange.aLowerRight.bIsEmpty = false;
+ }
+ OUString aTmp( XMLRangeHelper::getXMLStringFromCellRange( aCellRange ) );
+ if (!aRes.isEmpty()) // in case of multiple ranges add delimiter
+ aRes.append(" ");
+ aRes.append(aTmp);
+ }
+ while (nPos>0);
+
+ return aRes.makeStringAndClear();
+}
+
+OUString SAL_CALL SwChartDataProvider::convertRangeFromXML( const OUString& rXMLRange )
+{
+ SolarMutexGuard aGuard;
+ if (m_bDisposed)
+ throw lang::DisposedException();
+
+ if (rXMLRange.isEmpty())
+ return OUString();
+
+ OUStringBuffer aRes;
+
+ // multiple ranges are delimited by a ' ' like in
+ // "Table1.$A$1:.$A$4 Table1.$C$2:.$C$5" the same table must be used in all ranges!
+ OUString aFirstFoundTable; // to check that only one table will be used
+ sal_Int32 nPos = 0;
+ do
+ {
+ OUString aRange( rXMLRange.getToken(0, ' ', nPos) );
+
+ //!! following objects and function are implemented in XMLRangeHelper.?xx
+ //!! which is a copy of the respective file from chart2 !!
+ XMLRangeHelper::CellRange aCellRange( XMLRangeHelper::getCellRangeFromXMLString( aRange ));
+
+ // check that there is only one table used in all ranges
+ if (aFirstFoundTable.isEmpty())
+ aFirstFoundTable = aCellRange.aTableName;
+ if (aCellRange.aTableName != aFirstFoundTable)
+ throw lang::IllegalArgumentException();
+
+ OUString aTmp = aCellRange.aTableName + "." +
+ sw_GetCellName( aCellRange.aUpperLeft.nColumn,
+ aCellRange.aUpperLeft.nRow );
+ // does cell range consist of more than a single cell?
+ if (!aCellRange.aLowerRight.bIsEmpty)
+ {
+ aTmp += ":" + sw_GetCellName( aCellRange.aLowerRight.nColumn,
+ aCellRange.aLowerRight.nRow );
+ }
+
+ if (!aRes.isEmpty()) // in case of multiple ranges add delimiter
+ aRes.append(";");
+ aRes.append(aTmp);
+ }
+ while (nPos>0);
+
+ return aRes.makeStringAndClear();
+}
+
+SwChartDataSource::SwChartDataSource(
+ const uno::Sequence< uno::Reference< chart2::data::XLabeledDataSequence > > &rLDS ) :
+ m_aLDS( rLDS )
+{
+}
+
+SwChartDataSource::~SwChartDataSource()
+{
+}
+
+uno::Sequence< uno::Reference< chart2::data::XLabeledDataSequence > > SAL_CALL SwChartDataSource::getDataSequences( )
+{
+ SolarMutexGuard aGuard;
+ return m_aLDS;
+}
+
+OUString SAL_CALL SwChartDataSource::getImplementationName( )
+{
+ return "SwChartDataSource";
+}
+
+sal_Bool SAL_CALL SwChartDataSource::supportsService(const OUString& rServiceName )
+{
+ return cppu::supportsService(this, rServiceName);
+}
+
+uno::Sequence< OUString > SAL_CALL SwChartDataSource::getSupportedServiceNames( )
+{
+ return { "com.sun.star.chart2.data.DataSource" };
+}
+
+SwChartDataSequence::SwChartDataSequence(
+ SwChartDataProvider& rProvider,
+ SwFrameFormat& rTableFormat,
+ const std::shared_ptr<SwUnoCursor>& pTableCursor ) :
+ m_pFormat(&rTableFormat),
+ m_aRowLabelText( SwResId( STR_CHART2_ROW_LABEL_TEXT ) ),
+ m_aColLabelText( SwResId( STR_CHART2_COL_LABEL_TEXT ) ),
+ m_xDataProvider( &rProvider ),
+ m_pTableCursor( pTableCursor ),
+ m_pPropSet( aSwMapProvider.GetPropertySet( PROPERTY_MAP_CHART2_DATA_SEQUENCE ) )
+{
+ StartListening(rTableFormat.GetNotifier());
+ m_bDisposed = false;
+
+ acquire();
+ try
+ {
+ const SwTable* pTable = SwTable::FindTable( &rTableFormat );
+ if (pTable)
+ {
+ m_xDataProvider->AddDataSequence( *pTable, this );
+ m_xDataProvider->addEventListener( static_cast< lang::XEventListener * >(this) );
+ }
+ else {
+ OSL_FAIL( "table missing" );
+ }
+ }
+ catch (uno::RuntimeException &)
+ {
+ // TODO: shouldn't there be a call to release() here?
+ throw;
+ }
+ catch (uno::Exception &)
+ {
+ }
+ release();
+
+#if OSL_DEBUG_LEVEL > 0
+ // check if it can properly convert into a SwUnoTableCursor
+ // which is required for some functions
+ SwUnoTableCursor* pUnoTableCursor = dynamic_cast<SwUnoTableCursor*>(&(*m_pTableCursor));
+ OSL_ENSURE(pUnoTableCursor, "SwChartDataSequence: cursor not SwUnoTableCursor");
+#endif
+}
+
+SwChartDataSequence::SwChartDataSequence( const SwChartDataSequence &rObj ) :
+ SwChartDataSequenceBaseClass(rObj),
+ SvtListener(),
+ m_pFormat( rObj.m_pFormat ),
+ m_aRole( rObj.m_aRole ),
+ m_aRowLabelText( SwResId(STR_CHART2_ROW_LABEL_TEXT) ),
+ m_aColLabelText( SwResId(STR_CHART2_COL_LABEL_TEXT) ),
+ m_xDataProvider( rObj.m_xDataProvider ),
+ m_pTableCursor( rObj.m_pTableCursor ),
+ m_pPropSet( rObj.m_pPropSet )
+{
+ if(m_pFormat)
+ StartListening(m_pFormat->GetNotifier());
+ m_bDisposed = false;
+
+ acquire();
+ try
+ {
+ const SwTable* pTable = SwTable::FindTable( GetFrameFormat() );
+ if (pTable)
+ {
+ m_xDataProvider->AddDataSequence( *pTable, this );
+ m_xDataProvider->addEventListener( static_cast< lang::XEventListener * >(this) );
+ }
+ else {
+ OSL_FAIL( "table missing" );
+ }
+ }
+ catch (uno::RuntimeException &)
+ {
+ // TODO: shouldn't there be a call to release() here?
+ throw;
+ }
+ catch (uno::Exception &)
+ {
+ }
+ release();
+
+#if OSL_DEBUG_LEVEL > 0
+ // check if it can properly convert into a SwUnoTableCursor
+ // which is required for some functions
+ SwUnoTableCursor* pUnoTableCursor = dynamic_cast<SwUnoTableCursor*>(&(*m_pTableCursor));
+ OSL_ENSURE(pUnoTableCursor, "SwChartDataSequence: cursor not SwUnoTableCursor");
+#endif
+}
+
+SwChartDataSequence::~SwChartDataSequence()
+{
+}
+
+OUString SAL_CALL SwChartDataSequence::getSourceRangeRepresentation( )
+{
+ SolarMutexGuard aGuard;
+ if (m_bDisposed)
+ throw lang::DisposedException();
+
+ OUString aRes;
+ SwFrameFormat* pTableFormat = GetFrameFormat();
+ if (pTableFormat)
+ {
+ const OUString aCellRange( GetCellRangeName( *pTableFormat, *m_pTableCursor ) );
+ OSL_ENSURE( !aCellRange.isEmpty(), "failed to get cell range" );
+ aRes = pTableFormat->GetName() + "." + aCellRange;
+ }
+ return aRes;
+}
+
+uno::Sequence< OUString > SAL_CALL SwChartDataSequence::generateLabel(
+ chart2::data::LabelOrigin eLabelOrigin )
+{
+ SolarMutexGuard aGuard;
+ if (m_bDisposed)
+ throw lang::DisposedException();
+
+ uno::Sequence< OUString > aLabels;
+
+ {
+ SwRangeDescriptor aDesc;
+ bool bOk = false;
+ SwFrameFormat* pTableFormat = GetFrameFormat();
+ if (!pTableFormat)
+ throw uno::RuntimeException("No table format found.");
+ SwTable* pTable = SwTable::FindTable( pTableFormat );
+ if (!pTable)
+ throw uno::RuntimeException("No table found.");
+ if (pTable->IsTableComplex())
+ throw uno::RuntimeException("Table too complex.");
+
+ const OUString aCellRange( GetCellRangeName( *pTableFormat, *m_pTableCursor ) );
+ OSL_ENSURE( !aCellRange.isEmpty(), "failed to get cell range" );
+ bOk = FillRangeDescriptor( aDesc, aCellRange );
+ OSL_ENSURE( bOk, "failed to get SwRangeDescriptor" );
+
+ if (bOk)
+ {
+ aDesc.Normalize();
+ sal_Int32 nColSpan = aDesc.nRight - aDesc.nLeft + 1;
+ sal_Int32 nRowSpan = aDesc.nBottom - aDesc.nTop + 1;
+ OSL_ENSURE( nColSpan == 1 || nRowSpan == 1,
+ "unexpected range of selected cells" );
+
+ OUString aText; // label text to be returned
+ bool bReturnEmptyText = false;
+ bool bUseCol = true;
+ if (eLabelOrigin == chart2::data::LabelOrigin_COLUMN)
+ bUseCol = true;
+ else if (eLabelOrigin == chart2::data::LabelOrigin_ROW)
+ bUseCol = false;
+ else if (eLabelOrigin == chart2::data::LabelOrigin_SHORT_SIDE)
+ {
+ bUseCol = nColSpan < nRowSpan;
+ bReturnEmptyText = nColSpan == nRowSpan;
+ }
+ else if (eLabelOrigin == chart2::data::LabelOrigin_LONG_SIDE)
+ {
+ bUseCol = nColSpan > nRowSpan;
+ bReturnEmptyText = nColSpan == nRowSpan;
+ }
+ else {
+ OSL_FAIL( "unexpected case" );
+ }
+
+ // build label sequence
+
+ sal_Int32 nSeqLen = bUseCol ? nColSpan : nRowSpan;
+ aLabels.realloc( nSeqLen );
+ OUString *pLabels = aLabels.getArray();
+ for (sal_Int32 i = 0; i < nSeqLen; ++i)
+ {
+ if (!bReturnEmptyText)
+ {
+ aText = bUseCol ? m_aColLabelText : m_aRowLabelText;
+ sal_Int32 nCol = aDesc.nLeft;
+ sal_Int32 nRow = aDesc.nTop;
+ if (bUseCol)
+ nCol = nCol + i;
+ else
+ nRow = nRow + i;
+ OUString aCellName( sw_GetCellName( nCol, nRow ) );
+
+ sal_Int32 nLen = aCellName.getLength();
+ if (nLen)
+ {
+ const sal_Unicode *pBuf = aCellName.getStr();
+ const sal_Unicode *pEnd = pBuf + nLen;
+ while (pBuf < pEnd && ('0' > *pBuf || *pBuf > '9'))
+ ++pBuf;
+ // start of number found?
+ if (pBuf < pEnd && ('0' <= *pBuf && *pBuf <= '9'))
+ {
+ OUString aRplc;
+ std::u16string_view aNew;
+ if (bUseCol)
+ {
+ aRplc = "%COLUMNLETTER";
+ aNew = aCellName.subView(0, pBuf - aCellName.getStr());
+ }
+ else
+ {
+ aRplc = "%ROWNUMBER";
+ aNew = std::u16string_view(pBuf, (aCellName.getStr() + nLen) - pBuf);
+ }
+ aText = aText.replaceFirst( aRplc, aNew );
+ }
+ }
+ }
+ pLabels[i] = aText;
+ }
+ }
+ }
+
+ return aLabels;
+}
+
+::sal_Int32 SAL_CALL SwChartDataSequence::getNumberFormatKeyByIndex(
+ ::sal_Int32 /*nIndex*/ )
+{
+ return 0;
+}
+
+std::vector< css::uno::Reference< css::table::XCell > > SwChartDataSequence::GetCells()
+{
+ if (m_bDisposed)
+ throw lang::DisposedException();
+ auto pTableFormat(GetFrameFormat());
+ if(!pTableFormat)
+ return std::vector< css::uno::Reference< css::table::XCell > >();
+ auto pTable(SwTable::FindTable(pTableFormat));
+ if(pTable->IsTableComplex())
+ return std::vector< css::uno::Reference< css::table::XCell > >();
+ SwRangeDescriptor aDesc;
+ if(!FillRangeDescriptor(aDesc, GetCellRangeName(*pTableFormat, *m_pTableCursor)))
+ return std::vector< css::uno::Reference< css::table::XCell > >();
+ return SwXCellRange::CreateXCellRange(m_pTableCursor, *pTableFormat, aDesc)->GetCells();
+}
+
+uno::Sequence< OUString > SAL_CALL SwChartDataSequence::getTextualData()
+{
+ SolarMutexGuard aGuard;
+ auto vCells(GetCells());
+ uno::Sequence< OUString > vTextData(vCells.size());
+ std::transform(vCells.begin(),
+ vCells.end(),
+ vTextData.getArray(),
+ [] (decltype(vCells)::value_type& xCell)
+ { return static_cast<SwXCell*>(xCell.get())->getString(); });
+ return vTextData;
+}
+
+uno::Sequence< uno::Any > SAL_CALL SwChartDataSequence::getData()
+{
+ SolarMutexGuard aGuard;
+ try
+ {
+ auto vCells(GetCells());
+ uno::Sequence< uno::Any > vAnyData(vCells.size());
+ std::transform(vCells.begin(),
+ vCells.end(),
+ vAnyData.getArray(),
+ [] (decltype(vCells)::value_type& xCell)
+ { return static_cast<SwXCell*>(xCell.get())->GetAny(); });
+ return vAnyData;
+ }
+ catch (const lang::DisposedException&)
+ {
+ TOOLS_WARN_EXCEPTION( "sw", "unexpected exception caught" );
+ }
+ return uno::Sequence< uno::Any >{};
+}
+
+uno::Sequence< double > SAL_CALL SwChartDataSequence::getNumericalData()
+{
+ SolarMutexGuard aGuard;
+ auto vCells(GetCells());
+ uno::Sequence< double > vNumData(vCells.size());
+ std::transform(vCells.begin(),
+ vCells.end(),
+ vNumData.getArray(),
+ [] (decltype(vCells)::value_type& xCell)
+ { return static_cast<SwXCell*>(xCell.get())->GetForcedNumericalValue(); });
+ return vNumData;
+}
+
+uno::Reference< util::XCloneable > SAL_CALL SwChartDataSequence::createClone( )
+{
+ SolarMutexGuard aGuard;
+ if (m_bDisposed)
+ throw lang::DisposedException();
+ return new SwChartDataSequence( *this );
+}
+
+uno::Reference< beans::XPropertySetInfo > SAL_CALL SwChartDataSequence::getPropertySetInfo( )
+{
+ SolarMutexGuard aGuard;
+ if (m_bDisposed)
+ throw lang::DisposedException();
+
+ static uno::Reference< beans::XPropertySetInfo > xRes = m_pPropSet->getPropertySetInfo();
+ return xRes;
+}
+
+void SAL_CALL SwChartDataSequence::setPropertyValue(
+ const OUString& rPropertyName,
+ const uno::Any& rValue )
+{
+ SolarMutexGuard aGuard;
+ if (m_bDisposed)
+ throw lang::DisposedException();
+
+ if (rPropertyName != UNO_NAME_ROLE)
+ throw beans::UnknownPropertyException(rPropertyName);
+
+ if ( !(rValue >>= m_aRole) )
+ throw lang::IllegalArgumentException();
+}
+
+uno::Any SAL_CALL SwChartDataSequence::getPropertyValue(
+ const OUString& rPropertyName )
+{
+ SolarMutexGuard aGuard;
+ if (m_bDisposed)
+ throw lang::DisposedException();
+
+ if (!(rPropertyName == UNO_NAME_ROLE))
+ throw beans::UnknownPropertyException(rPropertyName);
+
+ return uno::Any(m_aRole);
+}
+
+void SAL_CALL SwChartDataSequence::addPropertyChangeListener(
+ const OUString& /*rPropertyName*/,
+ const uno::Reference< beans::XPropertyChangeListener >& /*xListener*/ )
+{
+ OSL_FAIL( "not implemented" );
+}
+
+void SAL_CALL SwChartDataSequence::removePropertyChangeListener(
+ const OUString& /*rPropertyName*/,
+ const uno::Reference< beans::XPropertyChangeListener >& /*xListener*/ )
+{
+ OSL_FAIL( "not implemented" );
+}
+
+void SAL_CALL SwChartDataSequence::addVetoableChangeListener(
+ const OUString& /*rPropertyName*/,
+ const uno::Reference< beans::XVetoableChangeListener >& /*xListener*/ )
+{
+ OSL_FAIL( "not implemented" );
+}
+
+void SAL_CALL SwChartDataSequence::removeVetoableChangeListener(
+ const OUString& /*rPropertyName*/,
+ const uno::Reference< beans::XVetoableChangeListener >& /*xListener*/ )
+{
+ OSL_FAIL( "not implemented" );
+}
+
+OUString SAL_CALL SwChartDataSequence::getImplementationName( )
+{
+ return "SwChartDataSequence";
+}
+
+sal_Bool SAL_CALL SwChartDataSequence::supportsService(const OUString& rServiceName )
+{
+ return cppu::supportsService(this, rServiceName);
+}
+
+uno::Sequence< OUString > SAL_CALL SwChartDataSequence::getSupportedServiceNames( )
+{
+ return { "com.sun.star.chart2.data.DataSequence" };
+}
+
+void SwChartDataSequence::Notify( const SfxHint& rHint)
+{
+ if(rHint.GetId() == SfxHintId::Dying)
+ m_pFormat = nullptr;
+ if(!m_pFormat || !m_pTableCursor)
+ {
+ m_pFormat = nullptr;
+ m_pTableCursor.reset(nullptr);
+ dispose();
+ }
+ else if (rHint.GetId() == SfxHintId::SwLegacyModify)
+ {
+ setModified( true );
+ }
+}
+
+sal_Bool SAL_CALL SwChartDataSequence::isModified( )
+{
+ SolarMutexGuard aGuard;
+ if (m_bDisposed)
+ throw lang::DisposedException();
+
+ return true;
+}
+
+void SAL_CALL SwChartDataSequence::setModified(
+ sal_Bool bModified )
+{
+ SolarMutexGuard aGuard;
+ if (m_bDisposed)
+ throw lang::DisposedException();
+
+ if (bModified)
+ LaunchModifiedEvent( m_aModifyListeners, static_cast< XModifyBroadcaster * >(this) );
+}
+
+void SAL_CALL SwChartDataSequence::addModifyListener(
+ const uno::Reference< util::XModifyListener >& rxListener )
+{
+ std::unique_lock aGuard( GetChartMutex() );
+ if (!m_bDisposed && rxListener.is())
+ m_aModifyListeners.addInterface( aGuard, rxListener );
+}
+
+void SAL_CALL SwChartDataSequence::removeModifyListener(
+ const uno::Reference< util::XModifyListener >& rxListener )
+{
+ std::unique_lock aGuard( GetChartMutex() );
+ if (!m_bDisposed && rxListener.is())
+ m_aModifyListeners.removeInterface( aGuard, rxListener );
+}
+
+void SAL_CALL SwChartDataSequence::disposing( const lang::EventObject& rSource )
+{
+ if (m_bDisposed)
+ throw lang::DisposedException();
+ if (rSource.Source == cppu::getXWeak(m_xDataProvider.get()))
+ {
+ m_xDataProvider.clear();
+ }
+}
+
+void SAL_CALL SwChartDataSequence::dispose( )
+{
+ bool bMustDispose( false );
+ {
+ std::unique_lock aGuard( GetChartMutex() );
+ bMustDispose = !m_bDisposed;
+ if (!m_bDisposed)
+ m_bDisposed = true;
+ }
+ if (!bMustDispose)
+ return;
+
+ m_bDisposed = true;
+ if (m_xDataProvider.is())
+ {
+ const SwTable* pTable = SwTable::FindTable( GetFrameFormat() );
+ if (pTable)
+ {
+ m_xDataProvider->RemoveDataSequence( *pTable, this );
+ }
+ else {
+ OSL_FAIL( "table missing" );
+ }
+
+ //#i119653# The bug is crashed for an exception thrown by
+ //SwCharDataSequence::setModified() because
+ //the SwCharDataSequence object has been disposed.
+
+ //Actually, the former design of SwClient will disconnect itself
+ //from the notification list in its destructor.
+
+ //But the SwCharDataSequence won't be destructed but disposed in code
+ //(the data member SwChartDataSequence::bDisposed will be set to
+ //TRUE), the relationship between client and modification is not
+ //released.
+
+ //So any notification from modify object will lead to said
+ //exception threw out. Recorrect the logic of code in
+ //SwChartDataSequence::Dispose(), release the relationship
+ //here...
+ if (m_pFormat && m_pFormat->HasWriterListeners())
+ {
+ EndListeningAll();
+ m_pFormat = nullptr;
+ m_pTableCursor.reset(nullptr);
+ }
+ }
+
+ // require listeners to release references to this object
+ lang::EventObject aEvtObj( static_cast< chart2::data::XDataSequence * >(this) );
+ std::unique_lock aGuard( GetChartMutex() );
+ m_aModifyListeners.disposeAndClear( aGuard, aEvtObj );
+ m_aEvtListeners.disposeAndClear( aGuard, aEvtObj );
+}
+
+void SAL_CALL SwChartDataSequence::addEventListener(
+ const uno::Reference< lang::XEventListener >& rxListener )
+{
+ std::unique_lock aGuard( GetChartMutex() );
+ if (!m_bDisposed && rxListener.is())
+ m_aEvtListeners.addInterface( aGuard, rxListener );
+}
+
+void SAL_CALL SwChartDataSequence::removeEventListener(
+ const uno::Reference< lang::XEventListener >& rxListener )
+{
+ std::unique_lock aGuard( GetChartMutex() );
+ if (!m_bDisposed && rxListener.is())
+ m_aEvtListeners.removeInterface( aGuard, rxListener );
+}
+
+bool SwChartDataSequence::DeleteBox( const SwTableBox &rBox )
+{
+ if (m_bDisposed)
+ throw lang::DisposedException();
+
+ // to be set if the last box of the data-sequence was removed here
+ bool bNowEmpty = false;
+
+ // if the implementation cursor gets affected (i.e. the box where it is located
+ // in gets removed) we need to move it before that... (otherwise it does not need to change)
+
+ const SwStartNode* pPointStartNode = m_pTableCursor->GetPoint()->GetNode().FindTableBoxStartNode();
+ const SwStartNode* pMarkStartNode = m_pTableCursor->GetMark()->GetNode().FindTableBoxStartNode();
+
+ if (!m_pTableCursor->HasMark() || (pPointStartNode == rBox.GetSttNd() && pMarkStartNode == rBox.GetSttNd()))
+ {
+ bNowEmpty = true;
+ }
+ else if (pPointStartNode == rBox.GetSttNd() || pMarkStartNode == rBox.GetSttNd())
+ {
+ sal_Int32 nPointRow = -1, nPointCol = -1;
+ sal_Int32 nMarkRow = -1, nMarkCol = -1;
+ const SwTable* pTable = SwTable::FindTable( GetFrameFormat() );
+ OUString aPointCellName( pTable->GetTableBox( pPointStartNode->GetIndex() )->GetName() );
+ OUString aMarkCellName( pTable->GetTableBox( pMarkStartNode->GetIndex() )->GetName() );
+
+ SwXTextTable::GetCellPosition( aPointCellName, nPointCol, nPointRow );
+ SwXTextTable::GetCellPosition( aMarkCellName, nMarkCol, nMarkRow );
+ OSL_ENSURE( nPointRow >= 0 && nPointCol >= 0, "invalid row and col" );
+ OSL_ENSURE( nMarkRow >= 0 && nMarkCol >= 0, "invalid row and col" );
+
+ // move vertical or horizontal?
+ OSL_ENSURE( nPointRow == nMarkRow || nPointCol == nMarkCol,
+ "row/col indices not matching" );
+ OSL_ENSURE( nPointRow != nMarkRow || nPointCol != nMarkCol,
+ "point and mark are identical" );
+ bool bMoveVertical = (nPointCol == nMarkCol);
+ bool bMoveHorizontal = (nPointRow == nMarkRow);
+
+ // get movement direction
+ bool bMoveLeft = false; // move left or right?
+ bool bMoveUp = false; // move up or down?
+ if (bMoveVertical)
+ {
+ if (pPointStartNode == rBox.GetSttNd()) // move point?
+ bMoveUp = nPointRow > nMarkRow;
+ else // move mark
+ bMoveUp = nMarkRow > nPointRow;
+ }
+ else if (bMoveHorizontal)
+ {
+ if (pPointStartNode == rBox.GetSttNd()) // move point?
+ bMoveLeft = nPointCol > nMarkCol;
+ else // move mark
+ bMoveLeft = nMarkCol > nPointCol;
+ }
+ else {
+ OSL_FAIL( "neither vertical nor horizontal movement" );
+ }
+
+ // get new box (position) to use...
+ sal_Int32 nRow = (pPointStartNode == rBox.GetSttNd()) ? nPointRow : nMarkRow;
+ sal_Int32 nCol = (pPointStartNode == rBox.GetSttNd()) ? nPointCol : nMarkCol;
+ if (bMoveVertical)
+ nRow += bMoveUp ? -1 : +1;
+ if (bMoveHorizontal)
+ nCol += bMoveLeft ? -1 : +1;
+ const OUString aNewCellName = sw_GetCellName( nCol, nRow );
+ SwTableBox* pNewBox = const_cast<SwTableBox*>(pTable->GetTableBox( aNewCellName ));
+
+ if (pNewBox) // set new position (cell range) to use
+ {
+ // This is how you get the first content node of a row:
+ // First get a SwNodeIndex pointing to the node after SwStartNode of the box...
+ SwNodeIndex aIdx( *pNewBox->GetSttNd(), +1 );
+ // This can be a SwContentNode, but might also be a table or section node,
+ // therefore call GoNext
+ SwContentNode *pCNd = aIdx.GetNode().GetContentNode();
+ if (!pCNd)
+ pCNd = GetFrameFormat()->GetDoc()->GetNodes().GoNext( &aIdx );
+ // and then one can e.g. create a SwPosition:
+ SwPosition aNewPos( *pCNd ); // new position to be used with cursor
+
+ // if the mark is to be changed, make sure there is one
+ if (pMarkStartNode == rBox.GetSttNd() && !m_pTableCursor->HasMark())
+ m_pTableCursor->SetMark();
+
+ // set cursor to new position
+ SwPosition *pPos = (pPointStartNode == rBox.GetSttNd()) ?
+ m_pTableCursor->GetPoint() : m_pTableCursor->GetMark();
+ if (pPos)
+ {
+ *pPos = aNewPos;
+ }
+ else {
+ OSL_FAIL( "neither point nor mark available for change" );
+ }
+ }
+ else {
+ OSL_FAIL( "failed to get position" );
+ }
+ }
+
+ return bNowEmpty;
+}
+
+void SwChartDataSequence::FillRangeDesc( SwRangeDescriptor &rRangeDesc ) const
+{
+ SwFrameFormat* pTableFormat = GetFrameFormat();
+ if(pTableFormat)
+ {
+ SwTable* pTable = SwTable::FindTable( pTableFormat );
+ if(!pTable->IsTableComplex())
+ {
+ FillRangeDescriptor( rRangeDesc, GetCellRangeName( *pTableFormat, *m_pTableCursor ) );
+ }
+ }
+}
+
+/**
+ * Extends the data-sequence by new cells added at the end of the direction
+ * the data-sequence points to.
+ * If the cells are already within the range of the sequence nothing needs
+ * to be done.
+ * If the cells are beyond the end of the sequence (are not adjacent to the
+ * current last cell) nothing can be done. Only if the cells are adjacent to
+ * the last cell they can be added.
+ *
+ * @returns true if the data-sequence was changed.
+ * @param bExtendCols - specifies if columns or rows are to be extended
+ * @param nFirstNew - index of first new row/col to be included in data-sequence
+ * @param nLastNew - index of last new row/col to be included in data-sequence
+ */
+void SwChartDataSequence::ExtendTo( bool bExtendCol,
+ sal_Int32 nFirstNew, sal_Int32 nCount )
+{
+ SwUnoTableCursor* pUnoTableCursor = dynamic_cast<SwUnoTableCursor*>(&(*m_pTableCursor));
+ if (!pUnoTableCursor)
+ return;
+
+ const SwStartNode *pStartNd = nullptr;
+ const SwTableBox *pStartBox = nullptr;
+ const SwTableBox *pEndBox = nullptr;
+
+ const SwTable* pTable = SwTable::FindTable( GetFrameFormat() );
+ OSL_ENSURE( !pTable->IsTableComplex(), "table too complex" );
+ if (nCount < 1 || nFirstNew < 0 || pTable->IsTableComplex())
+ return;
+
+ // get range descriptor (cell range) for current data-sequence
+
+ pStartNd = pUnoTableCursor->GetPoint()->GetNode().FindTableBoxStartNode();
+ pEndBox = pTable->GetTableBox( pStartNd->GetIndex() );
+ const OUString aEndBox( pEndBox->GetName() );
+
+ pStartNd = pUnoTableCursor->GetMark()->GetNode().FindTableBoxStartNode();
+ pStartBox = pTable->GetTableBox( pStartNd->GetIndex() );
+ const OUString aStartBox( pStartBox->GetName() );
+
+ SwRangeDescriptor aDesc;
+ // note that cell range here takes the newly added rows/cols already into account
+ OUString sDescrip = aStartBox + ":" + aEndBox;
+ FillRangeDescriptor( aDesc, sDescrip );
+
+ bool bChanged = false;
+ OUString aNewStartCell;
+ OUString aNewEndCell;
+ if (bExtendCol && aDesc.nBottom + 1 == nFirstNew)
+ {
+ // new column cells adjacent to the bottom of the
+ // current data-sequence to be added...
+ OSL_ENSURE( aDesc.nLeft == aDesc.nRight, "data-sequence is not a column" );
+ aNewStartCell = sw_GetCellName(aDesc.nLeft, aDesc.nTop);
+ aNewEndCell = sw_GetCellName(aDesc.nRight, aDesc.nBottom + nCount);
+ bChanged = true;
+ }
+ else if (bExtendCol && aDesc.nTop - nCount == nFirstNew)
+ {
+ // new column cells adjacent to the top of the
+ // current data-sequence to be added...
+ OSL_ENSURE( aDesc.nLeft == aDesc.nRight, "data-sequence is not a column" );
+ aNewStartCell = sw_GetCellName(aDesc.nLeft, aDesc.nTop - nCount);
+ aNewEndCell = sw_GetCellName(aDesc.nRight, aDesc.nBottom);
+ bChanged = true;
+ }
+ else if (!bExtendCol && aDesc.nRight + 1 == nFirstNew)
+ {
+ // new row cells adjacent to the right of the
+ // current data-sequence to be added...
+ OSL_ENSURE( aDesc.nTop == aDesc.nBottom, "data-sequence is not a row" );
+ aNewStartCell = sw_GetCellName(aDesc.nLeft, aDesc.nTop);
+ aNewEndCell = sw_GetCellName(aDesc.nRight + nCount, aDesc.nBottom);
+ bChanged = true;
+ }
+ else if (!bExtendCol && aDesc.nLeft - nCount == nFirstNew)
+ {
+ // new row cells adjacent to the left of the
+ // current data-sequence to be added...
+ OSL_ENSURE( aDesc.nTop == aDesc.nBottom, "data-sequence is not a row" );
+ aNewStartCell = sw_GetCellName(aDesc.nLeft - nCount, aDesc.nTop);
+ aNewEndCell = sw_GetCellName(aDesc.nRight, aDesc.nBottom);
+ bChanged = true;
+ }
+
+ if (bChanged)
+ {
+ // move table cursor to new start and end of data-sequence
+ const SwTableBox *pNewStartBox = pTable->GetTableBox( aNewStartCell );
+ const SwTableBox *pNewEndBox = pTable->GetTableBox( aNewEndCell );
+ pUnoTableCursor->SetMark();
+ pUnoTableCursor->GetPoint()->Assign( *pNewEndBox->GetSttNd() );
+ pUnoTableCursor->GetMark()->Assign( *pNewStartBox->GetSttNd() );
+ pUnoTableCursor->Move( fnMoveForward, GoInNode );
+ pUnoTableCursor->MakeBoxSels();
+ }
+}
+
+SwChartLabeledDataSequence::SwChartLabeledDataSequence()
+{
+ m_bDisposed = false;
+}
+
+SwChartLabeledDataSequence::~SwChartLabeledDataSequence()
+{
+}
+
+uno::Reference< chart2::data::XDataSequence > SAL_CALL SwChartLabeledDataSequence::getValues( )
+{
+ SolarMutexGuard aGuard;
+ if (m_bDisposed)
+ throw lang::DisposedException();
+ return m_xData;
+}
+
+void SwChartLabeledDataSequence::SetDataSequence(
+ uno::Reference< chart2::data::XDataSequence >& rxDest,
+ const uno::Reference< chart2::data::XDataSequence >& rxSource)
+{
+ uno::Reference< util::XModifyListener > xML(this);
+ uno::Reference< lang::XEventListener > xEL(this);
+
+ // stop listening to old data-sequence
+ uno::Reference< util::XModifyBroadcaster > xMB( rxDest, uno::UNO_QUERY );
+ if (xMB.is())
+ xMB->removeModifyListener( xML );
+ uno::Reference< lang::XComponent > xC( rxDest, uno::UNO_QUERY );
+ if (xC.is())
+ xC->removeEventListener( xEL );
+
+ rxDest = rxSource;
+
+ // start listening to new data-sequence
+ xC.set( rxDest, uno::UNO_QUERY );
+ if (xC.is())
+ xC->addEventListener( xEL );
+ xMB.set( rxDest, uno::UNO_QUERY );
+ if (xMB.is())
+ xMB->addModifyListener( xML );
+}
+
+void SAL_CALL SwChartLabeledDataSequence::setValues(
+ const uno::Reference< chart2::data::XDataSequence >& rxSequence )
+{
+ SolarMutexGuard aGuard;
+ if (m_bDisposed)
+ throw lang::DisposedException();
+
+ if (m_xData != rxSequence)
+ {
+ SetDataSequence( m_xData, rxSequence );
+ // inform listeners of changes
+ LaunchModifiedEvent( m_aModifyListeners, static_cast< XModifyBroadcaster * >(this) );
+ }
+}
+
+uno::Reference< chart2::data::XDataSequence > SAL_CALL SwChartLabeledDataSequence::getLabel( )
+{
+ SolarMutexGuard aGuard;
+ if (m_bDisposed)
+ throw lang::DisposedException();
+ return m_xLabels;
+}
+
+void SAL_CALL SwChartLabeledDataSequence::setLabel(
+ const uno::Reference< chart2::data::XDataSequence >& rxSequence )
+{
+ SolarMutexGuard aGuard;
+ if (m_bDisposed)
+ throw lang::DisposedException();
+
+ if (m_xLabels != rxSequence)
+ {
+ SetDataSequence( m_xLabels, rxSequence );
+ // inform listeners of changes
+ LaunchModifiedEvent( m_aModifyListeners, static_cast< XModifyBroadcaster * >(this) );
+ }
+}
+
+uno::Reference< util::XCloneable > SAL_CALL SwChartLabeledDataSequence::createClone( )
+{
+ SolarMutexGuard aGuard;
+ if (m_bDisposed)
+ throw lang::DisposedException();
+
+ uno::Reference< util::XCloneable > xDataCloneable( m_xData, uno::UNO_QUERY );
+ uno::Reference< util::XCloneable > xLabelsCloneable( m_xLabels, uno::UNO_QUERY );
+ rtl::Reference<SwChartLabeledDataSequence > pRes = new SwChartLabeledDataSequence();
+ if (xDataCloneable.is())
+ {
+ uno::Reference< chart2::data::XDataSequence > xDataClone( xDataCloneable->createClone(), uno::UNO_QUERY );
+ pRes->setValues( xDataClone );
+ }
+
+ if (xLabelsCloneable.is())
+ {
+ uno::Reference< chart2::data::XDataSequence > xLabelsClone( xLabelsCloneable->createClone(), uno::UNO_QUERY );
+ pRes->setLabel( xLabelsClone );
+ }
+ return pRes;
+}
+
+OUString SAL_CALL SwChartLabeledDataSequence::getImplementationName( )
+{
+ return "SwChartLabeledDataSequence";
+}
+
+sal_Bool SAL_CALL SwChartLabeledDataSequence::supportsService(
+ const OUString& rServiceName )
+{
+ return cppu::supportsService(this, rServiceName);
+}
+
+uno::Sequence< OUString > SAL_CALL SwChartLabeledDataSequence::getSupportedServiceNames( )
+{
+ return { "com.sun.star.chart2.data.LabeledDataSequence" };
+}
+
+void SAL_CALL SwChartLabeledDataSequence::disposing(
+ const lang::EventObject& rSource )
+{
+ std::unique_lock aGuard( GetChartMutex() );
+ uno::Reference< uno::XInterface > xRef( rSource.Source );
+ if (xRef == m_xData)
+ m_xData.clear();
+ if (xRef == m_xLabels)
+ m_xLabels.clear();
+ if (!m_xData.is() && !m_xLabels.is())
+ {
+ aGuard.unlock();
+ dispose();
+ }
+}
+
+void SAL_CALL SwChartLabeledDataSequence::modified(
+ const lang::EventObject& rEvent )
+{
+ if (rEvent.Source == m_xData || rEvent.Source == m_xLabels)
+ {
+ LaunchModifiedEvent( m_aModifyListeners, static_cast< XModifyBroadcaster * >(this) );
+ }
+}
+
+void SAL_CALL SwChartLabeledDataSequence::addModifyListener(
+ const uno::Reference< util::XModifyListener >& rxListener )
+{
+ std::unique_lock aGuard( GetChartMutex() );
+ if (!m_bDisposed && rxListener.is())
+ m_aModifyListeners.addInterface( aGuard, rxListener );
+}
+
+void SAL_CALL SwChartLabeledDataSequence::removeModifyListener(
+ const uno::Reference< util::XModifyListener >& rxListener )
+{
+ std::unique_lock aGuard( GetChartMutex() );
+ if (!m_bDisposed && rxListener.is())
+ m_aModifyListeners.removeInterface( aGuard, rxListener );
+}
+
+void SAL_CALL SwChartLabeledDataSequence::dispose( )
+{
+ bool bMustDispose( false );
+ {
+ std::unique_lock aGuard( GetChartMutex() );
+ bMustDispose = !m_bDisposed;
+ if (!m_bDisposed)
+ m_bDisposed = true;
+ }
+ if (bMustDispose)
+ {
+ m_bDisposed = true;
+
+ // require listeners to release references to this object
+ lang::EventObject aEvtObj( static_cast< chart2::data::XLabeledDataSequence * >(this) );
+ std::unique_lock aGuard( GetChartMutex() );
+ m_aModifyListeners.disposeAndClear( aGuard, aEvtObj );
+ m_aEventListeners.disposeAndClear( aGuard, aEvtObj );
+ }
+}
+
+void SAL_CALL SwChartLabeledDataSequence::addEventListener(
+ const uno::Reference< lang::XEventListener >& rxListener )
+{
+ std::unique_lock aGuard( GetChartMutex() );
+ if (!m_bDisposed && rxListener.is())
+ m_aEventListeners.addInterface( aGuard, rxListener );
+}
+
+void SAL_CALL SwChartLabeledDataSequence::removeEventListener(
+ const uno::Reference< lang::XEventListener >& rxListener )
+{
+ std::unique_lock aGuard( GetChartMutex() );
+ if (!m_bDisposed && rxListener.is())
+ m_aEventListeners.removeInterface( aGuard, rxListener );
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/core/unocore/unocoll.cxx b/sw/source/core/unocore/unocoll.cxx
new file mode 100644
index 0000000000..d0f3332421
--- /dev/null
+++ b/sw/source/core/unocore/unocoll.cxx
@@ -0,0 +1,1871 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <config_features.h>
+
+#include <hintids.hxx>
+#include <doc.hxx>
+#include <IDocumentChartDataProviderAccess.hxx>
+#include <IDocumentFieldsAccess.hxx>
+#include <docary.hxx>
+#include <unocoll.hxx>
+#include <unosett.hxx>
+#include <section.hxx>
+#include <IMark.hxx>
+#include <ftnidx.hxx>
+#include <fmtftn.hxx>
+#include <txtftn.hxx>
+#include <com/sun/star/text/XTextTable.hpp>
+#include <o3tl/safeint.hxx>
+#include <o3tl/string_view.hxx>
+#include <svtools/unoimap.hxx>
+#include <svtools/unoevent.hxx>
+#include <svx/SvxXTextColumns.hxx>
+#include <unotbl.hxx>
+#include <unostyle.hxx>
+#include <unofield.hxx>
+#include <unoidx.hxx>
+#include <unoframe.hxx>
+#include <textboxhelper.hxx>
+#include <unofootnote.hxx>
+#include <unolinebreak.hxx>
+#include <unoport.hxx>
+#include <vcl/svapp.hxx>
+#include <fmtcntnt.hxx>
+#include <authfld.hxx>
+#include <SwXTextDefaults.hxx>
+#include <unochart.hxx>
+#include <comphelper/sequence.hxx>
+#include <cppuhelper/supportsservice.hxx>
+#include <unosection.hxx>
+#include <unoparagraph.hxx>
+#include <unobookmark.hxx>
+#include <unorefmark.hxx>
+#include <unometa.hxx>
+#include <unocontentcontrol.hxx>
+#include <docsh.hxx>
+#include <hints.hxx>
+#include <frameformats.hxx>
+#include <com/sun/star/document/XCodeNameQuery.hpp>
+#include <com/sun/star/drawing/XDrawPageSupplier.hpp>
+#include <com/sun/star/form/XFormsSupplier.hpp>
+#include <com/sun/star/script/ModuleInfo.hpp>
+#include <com/sun/star/script/ModuleType.hpp>
+#include <com/sun/star/script/vba/XVBAModuleInfo.hpp>
+#include <com/sun/star/lang/IndexOutOfBoundsException.hpp>
+#include <vbahelper/vbaaccesshelper.hxx>
+#include <basic/basmgr.hxx>
+#include <comphelper/processfactory.hxx>
+#include <cppuhelper/implbase.hxx>
+#include <sfx2/event.hxx>
+#include <sal/log.hxx>
+#include <tools/debug.hxx>
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::document;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::text;
+using namespace ::com::sun::star::container;
+using namespace ::com::sun::star::lang;
+
+#if HAVE_FEATURE_SCRIPTING
+
+namespace {
+
+class SwVbaCodeNameProvider : public ::cppu::WeakImplHelper< document::XCodeNameQuery >
+{
+ SwDocShell* mpDocShell;
+ OUString msThisDocumentCodeName;
+public:
+ explicit SwVbaCodeNameProvider( SwDocShell* pDocShell ) : mpDocShell( pDocShell ) {}
+ // XCodeNameQuery
+
+ OUString SAL_CALL getCodeNameForContainer( const uno::Reference< uno::XInterface >& /*xIf*/ ) override
+ {
+ // #FIXME not implemented...
+ return OUString();
+ }
+
+ OUString SAL_CALL getCodeNameForObject( const uno::Reference< uno::XInterface >& xIf ) override
+ {
+ // Initialise the code name
+ if ( msThisDocumentCodeName.isEmpty() )
+ {
+ try
+ {
+ uno::Reference< beans::XPropertySet > xProps( mpDocShell->GetModel(), uno::UNO_QUERY_THROW );
+ uno::Reference< container::XNameAccess > xLibContainer( xProps->getPropertyValue("BasicLibraries"), uno::UNO_QUERY_THROW );
+ OUString sProjectName( "Standard");
+ if ( !mpDocShell->GetBasicManager()->GetName().isEmpty() )
+ {
+ sProjectName = mpDocShell->GetBasicManager()->GetName();
+ }
+ uno::Reference< container::XNameAccess > xLib( xLibContainer->getByName( sProjectName ), uno::UNO_QUERY_THROW );
+ const uno::Sequence< OUString > sModuleNames = xLib->getElementNames();
+ uno::Reference< script::vba::XVBAModuleInfo > xVBAModuleInfo( xLib, uno::UNO_QUERY );
+
+ auto pModuleName = std::find_if(sModuleNames.begin(), sModuleNames.end(), [&xVBAModuleInfo](const OUString& rName) {
+ return xVBAModuleInfo->hasModuleInfo(rName)
+ && xVBAModuleInfo->getModuleInfo(rName).ModuleType == script::ModuleType::DOCUMENT; });
+ if (pModuleName != sModuleNames.end())
+ msThisDocumentCodeName = *pModuleName;
+ }
+ catch( uno::Exception& )
+ {
+ }
+ }
+ OUString sCodeName;
+ if ( mpDocShell )
+ {
+ // need to find the page ( and index ) for this control
+ uno::Reference< drawing::XDrawPageSupplier > xSupplier( mpDocShell->GetModel(), uno::UNO_QUERY_THROW );
+ uno::Reference< container::XIndexAccess > xIndex( xSupplier->getDrawPage(), uno::UNO_QUERY_THROW );
+
+ try
+ {
+ uno::Reference< form::XFormsSupplier > xFormSupplier( xIndex, uno::UNO_QUERY_THROW );
+ uno::Reference< container::XIndexAccess > xFormIndex( xFormSupplier->getForms(), uno::UNO_QUERY_THROW );
+ // get the www-standard container
+ uno::Reference< container::XIndexAccess > xFormControls( xFormIndex->getByIndex(0), uno::UNO_QUERY_THROW );
+ sal_Int32 nCntrls = xFormControls->getCount();
+ for( sal_Int32 cIndex = 0; cIndex < nCntrls; ++cIndex )
+ {
+ uno::Reference< uno::XInterface > xControl( xFormControls->getByIndex( cIndex ), uno::UNO_QUERY_THROW );
+ bool bMatched = ( xControl == xIf );
+ if ( bMatched )
+ {
+ sCodeName = msThisDocumentCodeName;
+ break;
+ }
+ }
+ }
+ catch( uno::Exception& )
+ {
+ }
+ }
+ // #TODO Probably should throw here ( if !bMatched )
+ return sCodeName;
+ }
+};
+
+}
+
+typedef std::unordered_map< OUString, OUString > StringHashMap;
+
+namespace {
+
+class SwVbaProjectNameProvider : public ::cppu::WeakImplHelper< container::XNameContainer >
+{
+ StringHashMap mTemplateToProject;
+public:
+ SwVbaProjectNameProvider()
+ {
+ }
+ virtual sal_Bool SAL_CALL hasByName( const OUString& aName ) override
+ {
+ return ( mTemplateToProject.find( aName ) != mTemplateToProject.end() );
+ }
+ virtual css::uno::Any SAL_CALL getByName( const OUString& aName ) override
+ {
+ if ( !hasByName( aName ) )
+ throw container::NoSuchElementException();
+ return uno::Any( mTemplateToProject.find( aName )->second );
+ }
+ virtual css::uno::Sequence< OUString > SAL_CALL getElementNames( ) override
+ {
+ return comphelper::mapKeysToSequence( mTemplateToProject );
+ }
+
+ virtual void SAL_CALL insertByName( const OUString& aName, const uno::Any& aElement ) override
+ {
+
+ OUString sProjectName;
+ aElement >>= sProjectName;
+ SAL_INFO("sw.uno", "Template cache inserting template name " << aName
+ << " with project " << sProjectName);
+ mTemplateToProject[ aName ] = sProjectName;
+ }
+
+ virtual void SAL_CALL removeByName( const OUString& Name ) override
+ {
+ if ( !hasByName( Name ) )
+ throw container::NoSuchElementException();
+ mTemplateToProject.erase( Name );
+ }
+ virtual void SAL_CALL replaceByName( const OUString& aName, const uno::Any& aElement ) override
+ {
+ if ( !hasByName( aName ) )
+ throw container::NoSuchElementException();
+ insertByName( aName, aElement ); // insert will overwrite
+ }
+ // XElemenAccess
+ virtual css::uno::Type SAL_CALL getElementType( ) override
+ {
+ return ::cppu::UnoType<OUString>::get();
+ }
+ virtual sal_Bool SAL_CALL hasElements( ) override
+ {
+
+ return ( !mTemplateToProject.empty() );
+ }
+
+};
+
+class SwVbaObjectForCodeNameProvider : public ::cppu::WeakImplHelper< container::XNameAccess >
+{
+ SwDocShell* mpDocShell;
+public:
+ explicit SwVbaObjectForCodeNameProvider( SwDocShell* pDocShell ) : mpDocShell( pDocShell )
+ {
+ // #FIXME #TODO is the code name for ThisDocument read anywhere?
+ }
+
+ virtual sal_Bool SAL_CALL hasByName( const OUString& aName ) override
+ {
+ // #FIXME #TODO we really need to be checking against the codename for
+ // ThisDocument
+ if ( aName == "ThisDocument" )
+ return true;
+ return false;
+ }
+
+ css::uno::Any SAL_CALL getByName( const OUString& aName ) override
+ {
+ if ( !hasByName( aName ) )
+ throw container::NoSuchElementException();
+ uno::Sequence< uno::Any > aArgs{ uno::Any(uno::Reference< uno::XInterface >()),
+ uno::Any(mpDocShell->GetModel()) };
+ uno::Reference< uno::XInterface > xDocObj = ooo::vba::createVBAUnoAPIServiceWithArgs( mpDocShell, "ooo.vba.word.Document" , aArgs );
+ SAL_INFO("sw.uno",
+ "Creating Object ( ooo.vba.word.Document ) 0x" << xDocObj.get());
+ return uno::Any( xDocObj );
+ }
+ virtual css::uno::Sequence< OUString > SAL_CALL getElementNames( ) override
+ {
+ uno::Sequence< OUString > aNames;
+ return aNames;
+ }
+ // XElemenAccess
+ virtual css::uno::Type SAL_CALL getElementType( ) override { return uno::Type(); }
+ virtual sal_Bool SAL_CALL hasElements( ) override { return true; }
+
+};
+
+}
+
+#endif
+
+namespace {
+
+struct ProvNamesId_Type
+{
+ const char * pName;
+ SwServiceType nType;
+};
+
+}
+
+// note: this thing is indexed as an array, so do not insert/remove entries!
+const ProvNamesId_Type aProvNamesId[] =
+{
+ { "com.sun.star.text.TextTable", SwServiceType::TypeTextTable },
+ { "com.sun.star.text.TextFrame", SwServiceType::TypeTextFrame },
+ { "com.sun.star.text.GraphicObject", SwServiceType::TypeGraphic },
+ { "com.sun.star.text.TextEmbeddedObject", SwServiceType::TypeOLE },
+ { "com.sun.star.text.Bookmark", SwServiceType::TypeBookmark },
+ { "com.sun.star.text.Footnote", SwServiceType::TypeFootnote },
+ { "com.sun.star.text.Endnote", SwServiceType::TypeEndnote },
+ { "com.sun.star.text.DocumentIndexMark", SwServiceType::TypeIndexMark },
+ { "com.sun.star.text.DocumentIndex", SwServiceType::TypeIndex },
+ { "com.sun.star.text.ReferenceMark", SwServiceType::ReferenceMark },
+ { "com.sun.star.style.CharacterStyle", SwServiceType::StyleCharacter },
+ { "com.sun.star.style.ParagraphStyle", SwServiceType::StyleParagraph },
+ { "com.sun.star.style.FrameStyle", SwServiceType::StyleFrame },
+ { "com.sun.star.style.PageStyle", SwServiceType::StylePage },
+ { "com.sun.star.style.NumberingStyle", SwServiceType::StyleNumbering },
+ { "com.sun.star.text.ContentIndexMark", SwServiceType::ContentIndexMark },
+ { "com.sun.star.text.ContentIndex", SwServiceType::ContentIndex },
+ { "com.sun.star.text.UserIndexMark", SwServiceType::UserIndexMark },
+ { "com.sun.star.text.UserIndex", SwServiceType::UserIndex },
+ { "com.sun.star.text.TextSection", SwServiceType::TextSection },
+ { "com.sun.star.text.TextField.DateTime", SwServiceType::FieldTypeDateTime },
+ { "com.sun.star.text.TextField.User", SwServiceType::FieldTypeUser },
+ { "com.sun.star.text.TextField.SetExpression", SwServiceType::FieldTypeSetExp },
+ { "com.sun.star.text.TextField.GetExpression", SwServiceType::FieldTypeGetExp },
+ { "com.sun.star.text.TextField.FileName", SwServiceType::FieldTypeFileName },
+ { "com.sun.star.text.TextField.PageNumber", SwServiceType::FieldTypePageNum },
+ { "com.sun.star.text.TextField.Author", SwServiceType::FieldTypeAuthor },
+ { "com.sun.star.text.TextField.Chapter", SwServiceType::FieldTypeChapter },
+ { "", SwServiceType::FieldTypeDummy0 },
+ { "com.sun.star.text.TextField.GetReference", SwServiceType::FieldTypeGetReference },
+ { "com.sun.star.text.TextField.ConditionalText", SwServiceType::FieldTypeConditionedText },
+ { "com.sun.star.text.TextField.Annotation", SwServiceType::FieldTypeAnnotation },
+ { "com.sun.star.text.TextField.Input", SwServiceType::FieldTypeInput },
+ { "com.sun.star.text.TextField.Macro", SwServiceType::FieldTypeMacro },
+ { "com.sun.star.text.TextField.DDE", SwServiceType::FieldTypeDDE },
+ { "com.sun.star.text.TextField.HiddenParagraph", SwServiceType::FieldTypeHiddenPara },
+ { "" /*com.sun.star.text.TextField.DocumentInfo"*/, SwServiceType::FieldTypeDocInfo },
+ { "com.sun.star.text.TextField.TemplateName", SwServiceType::FieldTypeTemplateName },
+ { "com.sun.star.text.TextField.ExtendedUser", SwServiceType::FieldTypeUserExt },
+ { "com.sun.star.text.TextField.ReferencePageSet", SwServiceType::FieldTypeRefPageSet },
+ { "com.sun.star.text.TextField.ReferencePageGet", SwServiceType::FieldTypeRefPageGet },
+ { "com.sun.star.text.TextField.JumpEdit", SwServiceType::FieldTypeJumpEdit },
+ { "com.sun.star.text.TextField.Script", SwServiceType::FieldTypeScript },
+ { "com.sun.star.text.TextField.DatabaseNextSet", SwServiceType::FieldTypeDatabaseNextSet },
+ { "com.sun.star.text.TextField.DatabaseNumberOfSet", SwServiceType::FieldTypeDatabaseNumSet },
+ { "com.sun.star.text.TextField.DatabaseSetNumber", SwServiceType::FieldTypeDatabaseSetNum },
+ { "com.sun.star.text.TextField.Database", SwServiceType::FieldTypeDatabase },
+ { "com.sun.star.text.TextField.DatabaseName", SwServiceType::FieldTypeDatabaseName },
+ { "com.sun.star.text.TextField.TableFormula", SwServiceType::FieldTypeTableFormula },
+ { "com.sun.star.text.TextField.PageCount", SwServiceType::FieldTypePageCount },
+ { "com.sun.star.text.TextField.ParagraphCount", SwServiceType::FieldTypeParagraphCount },
+ { "com.sun.star.text.TextField.WordCount", SwServiceType::FieldTypeWordCount },
+ { "com.sun.star.text.TextField.CharacterCount", SwServiceType::FieldTypeCharacterCount },
+ { "com.sun.star.text.TextField.TableCount", SwServiceType::FieldTypeTableCount },
+ { "com.sun.star.text.TextField.GraphicObjectCount", SwServiceType::FieldTypeGraphicObjectCount },
+ { "com.sun.star.text.TextField.EmbeddedObjectCount", SwServiceType::FieldTypeEmbeddedObjectCount },
+ { "com.sun.star.text.TextField.DocInfo.ChangeAuthor", SwServiceType::FieldTypeDocInfoChangeAuthor },
+ { "com.sun.star.text.TextField.DocInfo.ChangeDateTime", SwServiceType::FieldTypeDocInfoChangeDateTime },
+ { "com.sun.star.text.TextField.DocInfo.EditTime", SwServiceType::FieldTypeDocInfoEditTime },
+ { "com.sun.star.text.TextField.DocInfo.Description", SwServiceType::FieldTypeDocInfoDescription },
+ { "com.sun.star.text.TextField.DocInfo.CreateAuthor", SwServiceType::FieldTypeDocInfoCreateAuthor },
+ { "com.sun.star.text.TextField.DocInfo.CreateDateTime", SwServiceType::FieldTypeDocInfoCreateDateTime },
+ { "", SwServiceType::FieldTypeDummy0 },
+ { "", SwServiceType::FieldTypeDummy1 },
+ { "", SwServiceType::FieldTypeDummy2 },
+ { "", SwServiceType::FieldTypeDummy3 },
+ { "com.sun.star.text.TextField.DocInfo.Custom", SwServiceType::FieldTypeDocInfoCustom },
+ { "com.sun.star.text.TextField.DocInfo.PrintAuthor", SwServiceType::FieldTypeDocInfoPrintAuthor },
+ { "com.sun.star.text.TextField.DocInfo.PrintDateTime", SwServiceType::FieldTypeDocInfoPrintDateTime },
+ { "com.sun.star.text.TextField.DocInfo.KeyWords", SwServiceType::FieldTypeDocInfoKeywords },
+ { "com.sun.star.text.TextField.DocInfo.Subject", SwServiceType::FieldTypeDocInfoSubject },
+ { "com.sun.star.text.TextField.DocInfo.Title", SwServiceType::FieldTypeDocInfoTitle },
+ { "com.sun.star.text.TextField.DocInfo.Revision", SwServiceType::FieldTypeDocInfoRevision },
+ { "com.sun.star.text.TextField.Bibliography", SwServiceType::FieldTypeBibliography },
+ { "com.sun.star.text.TextField.CombinedCharacters", SwServiceType::FieldTypeCombinedCharacters },
+ { "com.sun.star.text.TextField.DropDown", SwServiceType::FieldTypeDropdown },
+ { "com.sun.star.text.textfield.MetadataField", SwServiceType::FieldTypeMetafield },
+ { "", SwServiceType::FieldTypeDummy4 },
+ { "", SwServiceType::FieldTypeDummy5 },
+ { "", SwServiceType::FieldTypeDummy6 },
+ { "", SwServiceType::FieldTypeDummy7 },
+ { "com.sun.star.text.FieldMaster.User", SwServiceType::FieldMasterUser },
+ { "com.sun.star.text.FieldMaster.DDE", SwServiceType::FieldMasterDDE },
+ { "com.sun.star.text.FieldMaster.SetExpression", SwServiceType::FieldMasterSetExp },
+ { "com.sun.star.text.FieldMaster.Database", SwServiceType::FieldMasterDatabase },
+ { "com.sun.star.text.FieldMaster.Bibliography", SwServiceType::FieldMasterBibliography },
+ { "", SwServiceType::FieldMasterDummy2 },
+ { "", SwServiceType::FieldMasterDummy3 },
+ { "", SwServiceType::FieldMasterDummy4 },
+ { "", SwServiceType::FieldMasterDummy5 },
+ { "com.sun.star.text.IllustrationsIndex", SwServiceType::IndexIllustrations },
+ { "com.sun.star.text.ObjectIndex", SwServiceType::IndexObjects },
+ { "com.sun.star.text.TableIndex", SwServiceType::IndexTables },
+ { "com.sun.star.text.Bibliography", SwServiceType::IndexBibliography },
+ { "com.sun.star.text.Paragraph", SwServiceType::Paragraph },
+ { "com.sun.star.text.TextField.InputUser", SwServiceType::FieldTypeInputUser },
+ { "com.sun.star.text.TextField.HiddenText", SwServiceType::FieldTypeHiddenText },
+ { "com.sun.star.style.ConditionalParagraphStyle", SwServiceType::StyleConditionalParagraph },
+ { "com.sun.star.text.NumberingRules", SwServiceType::NumberingRules },
+ { "com.sun.star.text.TextColumns", SwServiceType::TextColumns },
+ { "com.sun.star.text.IndexHeaderSection", SwServiceType::IndexHeaderSection },
+ { "com.sun.star.text.Defaults", SwServiceType::Defaults },
+ { "com.sun.star.image.ImageMapRectangleObject", SwServiceType::IMapRectangle },
+ { "com.sun.star.image.ImageMapCircleObject", SwServiceType::IMapCircle },
+ { "com.sun.star.image.ImageMapPolygonObject", SwServiceType::IMapPolygon },
+ { "com.sun.star.text.TextGraphicObject", SwServiceType::TypeTextGraphic },
+ { "com.sun.star.chart2.data.DataProvider", SwServiceType::Chart2DataProvider },
+ { "com.sun.star.text.Fieldmark", SwServiceType::TypeFieldMark },
+ { "com.sun.star.text.FormFieldmark", SwServiceType::TypeFormFieldMark },
+ { "com.sun.star.text.InContentMetadata", SwServiceType::TypeMeta },
+ { "ooo.vba.VBAObjectModuleObjectProvider", SwServiceType::VbaObjectProvider },
+ { "ooo.vba.VBACodeNameProvider", SwServiceType::VbaCodeNameProvider },
+ { "ooo.vba.VBAProjectNameProvider", SwServiceType::VbaProjectNameProvider },
+ { "ooo.vba.VBAGlobals", SwServiceType::VbaGlobals },
+
+ // case-correct versions of the service names (see #i67811)
+ { CSS_TEXT_TEXTFIELD_DATE_TIME, SwServiceType::FieldTypeDateTime },
+ { CSS_TEXT_TEXTFIELD_USER, SwServiceType::FieldTypeUser },
+ { CSS_TEXT_TEXTFIELD_SET_EXPRESSION, SwServiceType::FieldTypeSetExp },
+ { CSS_TEXT_TEXTFIELD_GET_EXPRESSION, SwServiceType::FieldTypeGetExp },
+ { CSS_TEXT_TEXTFIELD_FILE_NAME, SwServiceType::FieldTypeFileName },
+ { CSS_TEXT_TEXTFIELD_PAGE_NUMBER, SwServiceType::FieldTypePageNum },
+ { CSS_TEXT_TEXTFIELD_AUTHOR, SwServiceType::FieldTypeAuthor },
+ { CSS_TEXT_TEXTFIELD_CHAPTER, SwServiceType::FieldTypeChapter },
+ { CSS_TEXT_TEXTFIELD_GET_REFERENCE, SwServiceType::FieldTypeGetReference },
+ { CSS_TEXT_TEXTFIELD_CONDITIONAL_TEXT, SwServiceType::FieldTypeConditionedText },
+ { CSS_TEXT_TEXTFIELD_ANNOTATION, SwServiceType::FieldTypeAnnotation },
+ { CSS_TEXT_TEXTFIELD_INPUT, SwServiceType::FieldTypeInput },
+ { CSS_TEXT_TEXTFIELD_MACRO, SwServiceType::FieldTypeMacro },
+ { CSS_TEXT_TEXTFIELD_DDE, SwServiceType::FieldTypeDDE },
+ { CSS_TEXT_TEXTFIELD_HIDDEN_PARAGRAPH, SwServiceType::FieldTypeHiddenPara },
+ { CSS_TEXT_TEXTFIELD_TEMPLATE_NAME, SwServiceType::FieldTypeTemplateName },
+ { CSS_TEXT_TEXTFIELD_EXTENDED_USER, SwServiceType::FieldTypeUserExt },
+ { CSS_TEXT_TEXTFIELD_REFERENCE_PAGE_SET, SwServiceType::FieldTypeRefPageSet },
+ { CSS_TEXT_TEXTFIELD_REFERENCE_PAGE_GET, SwServiceType::FieldTypeRefPageGet },
+ { CSS_TEXT_TEXTFIELD_JUMP_EDIT, SwServiceType::FieldTypeJumpEdit },
+ { CSS_TEXT_TEXTFIELD_SCRIPT, SwServiceType::FieldTypeScript },
+ { CSS_TEXT_TEXTFIELD_DATABASE_NEXT_SET, SwServiceType::FieldTypeDatabaseNextSet },
+ { CSS_TEXT_TEXTFIELD_DATABASE_NUMBER_OF_SET, SwServiceType::FieldTypeDatabaseNumSet },
+ { CSS_TEXT_TEXTFIELD_DATABASE_SET_NUMBER, SwServiceType::FieldTypeDatabaseSetNum },
+ { CSS_TEXT_TEXTFIELD_DATABASE, SwServiceType::FieldTypeDatabase },
+ { CSS_TEXT_TEXTFIELD_DATABASE_NAME, SwServiceType::FieldTypeDatabaseName },
+ { CSS_TEXT_TEXTFIELD_TABLE_FORMULA, SwServiceType::FieldTypeTableFormula },
+ { CSS_TEXT_TEXTFIELD_PAGE_COUNT, SwServiceType::FieldTypePageCount },
+ { CSS_TEXT_TEXTFIELD_PARAGRAPH_COUNT, SwServiceType::FieldTypeParagraphCount },
+ { CSS_TEXT_TEXTFIELD_WORD_COUNT, SwServiceType::FieldTypeWordCount },
+ { CSS_TEXT_TEXTFIELD_CHARACTER_COUNT, SwServiceType::FieldTypeCharacterCount },
+ { CSS_TEXT_TEXTFIELD_TABLE_COUNT, SwServiceType::FieldTypeTableCount },
+ { CSS_TEXT_TEXTFIELD_GRAPHIC_OBJECT_COUNT, SwServiceType::FieldTypeGraphicObjectCount },
+ { CSS_TEXT_TEXTFIELD_EMBEDDED_OBJECT_COUNT, SwServiceType::FieldTypeEmbeddedObjectCount },
+ { CSS_TEXT_TEXTFIELD_DOCINFO_CHANGE_AUTHOR, SwServiceType::FieldTypeDocInfoChangeAuthor },
+ { CSS_TEXT_TEXTFIELD_DOCINFO_CHANGE_DATE_TIME, SwServiceType::FieldTypeDocInfoChangeDateTime },
+ { CSS_TEXT_TEXTFIELD_DOCINFO_EDIT_TIME, SwServiceType::FieldTypeDocInfoEditTime },
+ { CSS_TEXT_TEXTFIELD_DOCINFO_DESCRIPTION, SwServiceType::FieldTypeDocInfoDescription },
+ { CSS_TEXT_TEXTFIELD_DOCINFO_CREATE_AUTHOR, SwServiceType::FieldTypeDocInfoCreateAuthor },
+ { CSS_TEXT_TEXTFIELD_DOCINFO_CREATE_DATE_TIME, SwServiceType::FieldTypeDocInfoCreateDateTime },
+ { CSS_TEXT_TEXTFIELD_DOCINFO_PRINT_AUTHOR, SwServiceType::FieldTypeDocInfoPrintAuthor },
+ { CSS_TEXT_TEXTFIELD_DOCINFO_PRINT_DATE_TIME, SwServiceType::FieldTypeDocInfoPrintDateTime },
+ { CSS_TEXT_TEXTFIELD_DOCINFO_KEY_WORDS, SwServiceType::FieldTypeDocInfoKeywords },
+ { CSS_TEXT_TEXTFIELD_DOCINFO_SUBJECT, SwServiceType::FieldTypeDocInfoSubject },
+ { CSS_TEXT_TEXTFIELD_DOCINFO_TITLE, SwServiceType::FieldTypeDocInfoTitle },
+ { CSS_TEXT_TEXTFIELD_DOCINFO_REVISION, SwServiceType::FieldTypeDocInfoRevision },
+ { CSS_TEXT_TEXTFIELD_DOCINFO_CUSTOM, SwServiceType::FieldTypeDocInfoCustom },
+ { CSS_TEXT_TEXTFIELD_BIBLIOGRAPHY, SwServiceType::FieldTypeBibliography },
+ { CSS_TEXT_TEXTFIELD_COMBINED_CHARACTERS, SwServiceType::FieldTypeCombinedCharacters },
+ { CSS_TEXT_TEXTFIELD_DROP_DOWN, SwServiceType::FieldTypeDropdown },
+ { CSS_TEXT_TEXTFIELD_INPUT_USER, SwServiceType::FieldTypeInputUser },
+ { CSS_TEXT_TEXTFIELD_HIDDEN_TEXT, SwServiceType::FieldTypeHiddenText },
+ { CSS_TEXT_FIELDMASTER_USER, SwServiceType::FieldMasterUser },
+ { CSS_TEXT_FIELDMASTER_DDE, SwServiceType::FieldMasterDDE },
+ { CSS_TEXT_FIELDMASTER_SET_EXPRESSION, SwServiceType::FieldMasterSetExp },
+ { CSS_TEXT_FIELDMASTER_DATABASE, SwServiceType::FieldMasterDatabase },
+ { CSS_TEXT_FIELDMASTER_BIBLIOGRAPHY, SwServiceType::FieldMasterBibliography },
+ { "com.sun.star.style.TableStyle", SwServiceType::StyleTable },
+ { "com.sun.star.style.CellStyle", SwServiceType::StyleCell },
+ { "com.sun.star.text.LineBreak", SwServiceType::LineBreak },
+ { "com.sun.star.text.ContentControl", SwServiceType::ContentControl }
+};
+
+const SvEventDescription* sw_GetSupportedMacroItems()
+{
+ static const SvEventDescription aMacroDescriptionsImpl[] =
+ {
+ { SvMacroItemId::OnMouseOver, "OnMouseOver" },
+ { SvMacroItemId::OnMouseOut, "OnMouseOut" },
+ { SvMacroItemId::NONE, nullptr }
+ };
+
+ return aMacroDescriptionsImpl;
+}
+
+OUString SwXServiceProvider::GetProviderName(SwServiceType nObjectType)
+{
+ OUString sRet;
+ const sal_uInt16 nEntries = SAL_N_ELEMENTS(aProvNamesId);
+ if(static_cast<sal_uInt16>(nObjectType) < nEntries)
+ sRet = OUString::createFromAscii(aProvNamesId[static_cast<sal_uInt16>(nObjectType)].pName);
+ return sRet;
+}
+
+uno::Sequence<OUString> SwXServiceProvider::GetAllServiceNames()
+{
+ const sal_uInt16 nEntries = SAL_N_ELEMENTS(aProvNamesId);
+ uno::Sequence<OUString> aRet(nEntries);
+ OUString* pArray = aRet.getArray();
+ sal_uInt16 n = 0;
+ for(const ProvNamesId_Type & i : aProvNamesId)
+ {
+ OUString sProv(OUString::createFromAscii(i.pName));
+ if(!sProv.isEmpty())
+ {
+ pArray[n] = sProv;
+ n++;
+ }
+ }
+ aRet.realloc(n);
+ return aRet;
+
+}
+
+SwServiceType SwXServiceProvider::GetProviderType(std::u16string_view rServiceName)
+{
+ for(const ProvNamesId_Type & i : aProvNamesId)
+ {
+ if (o3tl::equalsAscii(rServiceName, i.pName))
+ return i.nType;
+ }
+ return SwServiceType::Invalid;
+}
+
+uno::Reference<uno::XInterface>
+SwXServiceProvider::MakeInstance(SwServiceType nObjectType, SwDoc & rDoc)
+{
+ SolarMutexGuard aGuard;
+ uno::Reference< uno::XInterface > xRet;
+ switch(nObjectType)
+ {
+ case SwServiceType::TypeTextTable:
+ {
+ xRet = getXWeak(SwXTextTable::CreateXTextTable(nullptr).get());
+ }
+ break;
+ case SwServiceType::TypeTextFrame:
+ {
+ xRet = getXWeak(SwXTextFrame::CreateXTextFrame(rDoc, nullptr).get());
+ }
+ break;
+ case SwServiceType::TypeGraphic :
+ case SwServiceType::TypeTextGraphic /* #i47503# */ :
+ {
+ xRet = getXWeak(SwXTextGraphicObject::CreateXTextGraphicObject(rDoc, nullptr).get());
+
+ }
+ break;
+ case SwServiceType::TypeOLE :
+ {
+ xRet = getXWeak(SwXTextEmbeddedObject::CreateXTextEmbeddedObject(rDoc, nullptr).get());
+ }
+ break;
+ case SwServiceType::TypeBookmark :
+ {
+ xRet = getXWeak(SwXBookmark::CreateXBookmark(rDoc, nullptr).get());
+ }
+ break;
+ case SwServiceType::TypeFieldMark :
+ {
+ xRet = getXWeak(SwXFieldmark::CreateXFieldmark(rDoc, nullptr).get());
+ }
+ break;
+ case SwServiceType::TypeFormFieldMark :
+ {
+ xRet = getXWeak(SwXFieldmark::CreateXFieldmark(rDoc, nullptr, true).get());
+ }
+ break;
+ case SwServiceType::VbaObjectProvider :
+#if HAVE_FEATURE_SCRIPTING
+ {
+ xRet = getXWeak(new SwVbaObjectForCodeNameProvider(rDoc.GetDocShell()));
+ }
+#endif
+ break;
+ case SwServiceType::VbaCodeNameProvider :
+#if HAVE_FEATURE_SCRIPTING
+ {
+ if (rDoc.GetDocShell() && ooo::vba::isAlienWordDoc(*rDoc.GetDocShell()))
+ {
+ xRet = getXWeak(new SwVbaCodeNameProvider(rDoc.GetDocShell()));
+ }
+ }
+#endif
+ break;
+ case SwServiceType::VbaProjectNameProvider :
+#if HAVE_FEATURE_SCRIPTING
+ {
+ uno::Reference< container::XNameContainer > xProjProv = rDoc.GetVBATemplateToProjectCache();
+ if (!xProjProv.is() && rDoc.GetDocShell()
+ && ooo::vba::isAlienWordDoc(*rDoc.GetDocShell()))
+ {
+ xProjProv = new SwVbaProjectNameProvider;
+ rDoc.SetVBATemplateToProjectCache(xProjProv);
+ }
+ xRet = xProjProv;
+ }
+#endif
+ break;
+ case SwServiceType::VbaGlobals :
+#if HAVE_FEATURE_SCRIPTING
+ {
+ uno::Any aGlobs;
+ BasicManager *pBasicMan = rDoc.GetDocShell()->GetBasicManager();
+ if (pBasicMan && !pBasicMan->GetGlobalUNOConstant("VBAGlobals", aGlobs))
+ {
+ uno::Sequence< uno::Any > aArgs{ uno::Any(rDoc.GetDocShell()->GetModel()) };
+ aGlobs <<= ::comphelper::getProcessServiceFactory()->createInstanceWithArguments( "ooo.vba.word.Globals", aArgs );
+ pBasicMan->SetGlobalUNOConstant( "VBAGlobals", aGlobs );
+ }
+ aGlobs >>= xRet;
+ }
+#endif
+ break;
+
+ case SwServiceType::TypeFootnote :
+ xRet = getXWeak(SwXFootnote::CreateXFootnote(rDoc, nullptr).get());
+ break;
+ case SwServiceType::TypeEndnote :
+ xRet = getXWeak(SwXFootnote::CreateXFootnote(rDoc, nullptr, true).get());
+ break;
+ case SwServiceType::ContentIndexMark :
+ case SwServiceType::UserIndexMark :
+ case SwServiceType::TypeIndexMark:
+ {
+ TOXTypes eType = TOX_INDEX;
+ if(SwServiceType::ContentIndexMark== nObjectType)
+ eType = TOX_CONTENT;
+ else if(SwServiceType::UserIndexMark == nObjectType)
+ eType = TOX_USER;
+ xRet = getXWeak(SwXDocumentIndexMark::CreateXDocumentIndexMark(rDoc, nullptr, eType).get());
+ }
+ break;
+ case SwServiceType::ContentIndex :
+ case SwServiceType::UserIndex :
+ case SwServiceType::TypeIndex :
+ case SwServiceType::IndexIllustrations:
+ case SwServiceType::IndexObjects :
+ case SwServiceType::IndexTables:
+ case SwServiceType::IndexBibliography :
+ {
+ TOXTypes eType = TOX_INDEX;
+ if(SwServiceType::ContentIndex == nObjectType)
+ eType = TOX_CONTENT;
+ else if(SwServiceType::UserIndex == nObjectType)
+ eType = TOX_USER;
+ else if(SwServiceType::IndexIllustrations == nObjectType)
+ {
+ eType = TOX_ILLUSTRATIONS;
+ }
+ else if(SwServiceType::IndexObjects == nObjectType)
+ {
+ eType = TOX_OBJECTS;
+ }
+ else if(SwServiceType::IndexBibliography == nObjectType)
+ {
+ eType = TOX_AUTHORITIES;
+ }
+ else if(SwServiceType::IndexTables == nObjectType)
+ {
+ eType = TOX_TABLES;
+ }
+ xRet = getXWeak(SwXDocumentIndex::CreateXDocumentIndex(rDoc, nullptr, eType).get());
+ }
+ break;
+ case SwServiceType::IndexHeaderSection :
+ case SwServiceType::TextSection :
+ xRet = getXWeak(SwXTextSection::CreateXTextSection(nullptr,
+ (SwServiceType::IndexHeaderSection == nObjectType)).get());
+
+ break;
+ case SwServiceType::ReferenceMark :
+ xRet = getXWeak(SwXReferenceMark::CreateXReferenceMark(rDoc, nullptr).get());
+ break;
+ case SwServiceType::StyleCharacter:
+ case SwServiceType::StyleParagraph:
+ case SwServiceType::StyleConditionalParagraph:
+ case SwServiceType::StyleFrame:
+ case SwServiceType::StylePage:
+ case SwServiceType::StyleNumbering:
+ case SwServiceType::StyleTable:
+ case SwServiceType::StyleCell:
+ {
+ SfxStyleFamily eFamily = SfxStyleFamily::Char;
+ switch(nObjectType)
+ {
+ case SwServiceType::StyleParagraph:
+ eFamily = SfxStyleFamily::Para;
+ break;
+ case SwServiceType::StyleConditionalParagraph:
+ eFamily = SfxStyleFamily::Para;
+ xRet = SwXStyleFamilies::CreateStyleCondParagraph(rDoc);
+ break;
+ case SwServiceType::StyleFrame:
+ eFamily = SfxStyleFamily::Frame;
+ break;
+ case SwServiceType::StylePage:
+ eFamily = SfxStyleFamily::Page;
+ break;
+ case SwServiceType::StyleNumbering:
+ eFamily = SfxStyleFamily::Pseudo;
+ break;
+ case SwServiceType::StyleTable:
+ eFamily = SfxStyleFamily::Table;
+ break;
+ case SwServiceType::StyleCell:
+ eFamily = SfxStyleFamily::Cell;
+ break;
+ default: break;
+ }
+ if(!xRet.is())
+ xRet = SwXStyleFamilies::CreateStyle(eFamily, rDoc);
+ }
+ break;
+ case SwServiceType::FieldTypeDateTime:
+ case SwServiceType::FieldTypeUser:
+ case SwServiceType::FieldTypeSetExp:
+ case SwServiceType::FieldTypeGetExp:
+ case SwServiceType::FieldTypeFileName:
+ case SwServiceType::FieldTypePageNum:
+ case SwServiceType::FieldTypeAuthor:
+ case SwServiceType::FieldTypeChapter:
+ case SwServiceType::FieldTypeGetReference:
+ case SwServiceType::FieldTypeConditionedText:
+ case SwServiceType::FieldTypeInput:
+ case SwServiceType::FieldTypeMacro:
+ case SwServiceType::FieldTypeDDE:
+ case SwServiceType::FieldTypeHiddenPara:
+ case SwServiceType::FieldTypeDocInfo:
+ case SwServiceType::FieldTypeTemplateName:
+ case SwServiceType::FieldTypeUserExt:
+ case SwServiceType::FieldTypeRefPageSet:
+ case SwServiceType::FieldTypeRefPageGet:
+ case SwServiceType::FieldTypeJumpEdit:
+ case SwServiceType::FieldTypeScript:
+ case SwServiceType::FieldTypeDatabaseNextSet:
+ case SwServiceType::FieldTypeDatabaseNumSet:
+ case SwServiceType::FieldTypeDatabaseSetNum:
+ case SwServiceType::FieldTypeDatabase:
+ case SwServiceType::FieldTypeDatabaseName:
+ case SwServiceType::FieldTypePageCount:
+ case SwServiceType::FieldTypeParagraphCount:
+ case SwServiceType::FieldTypeWordCount:
+ case SwServiceType::FieldTypeCharacterCount:
+ case SwServiceType::FieldTypeTableCount:
+ case SwServiceType::FieldTypeGraphicObjectCount:
+ case SwServiceType::FieldTypeEmbeddedObjectCount:
+ case SwServiceType::FieldTypeDocInfoChangeAuthor:
+ case SwServiceType::FieldTypeDocInfoChangeDateTime:
+ case SwServiceType::FieldTypeDocInfoEditTime:
+ case SwServiceType::FieldTypeDocInfoDescription:
+ case SwServiceType::FieldTypeDocInfoCreateAuthor:
+ case SwServiceType::FieldTypeDocInfoCreateDateTime:
+ case SwServiceType::FieldTypeDocInfoCustom:
+ case SwServiceType::FieldTypeDocInfoPrintAuthor:
+ case SwServiceType::FieldTypeDocInfoPrintDateTime:
+ case SwServiceType::FieldTypeDocInfoKeywords:
+ case SwServiceType::FieldTypeDocInfoSubject:
+ case SwServiceType::FieldTypeDocInfoTitle:
+ case SwServiceType::FieldTypeDocInfoRevision:
+ case SwServiceType::FieldTypeBibliography:
+ case SwServiceType::FieldTypeInputUser:
+ case SwServiceType::FieldTypeHiddenText:
+ case SwServiceType::FieldTypeCombinedCharacters:
+ case SwServiceType::FieldTypeDropdown:
+ case SwServiceType::FieldTypeTableFormula:
+ // NOTE: the sw.SwXAutoTextEntry unoapi test depends on pDoc = 0
+ xRet = getXWeak(SwXTextField::CreateXTextField(nullptr, nullptr, nObjectType).get());
+ break;
+ case SwServiceType::FieldTypeAnnotation:
+ xRet = getXWeak(SwXTextField::CreateXTextField(&rDoc, nullptr, nObjectType).get());
+ break;
+ case SwServiceType::FieldMasterUser:
+ case SwServiceType::FieldMasterDDE:
+ case SwServiceType::FieldMasterSetExp :
+ case SwServiceType::FieldMasterDatabase:
+ {
+ SwFieldIds nResId = SwFieldIds::Unknown;
+ switch(nObjectType)
+ {
+ case SwServiceType::FieldMasterUser: nResId = SwFieldIds::User; break;
+ case SwServiceType::FieldMasterDDE: nResId = SwFieldIds::Dde; break;
+ case SwServiceType::FieldMasterSetExp : nResId = SwFieldIds::SetExp; break;
+ case SwServiceType::FieldMasterDatabase: nResId = SwFieldIds::Database; break;
+ default: break;
+ }
+ xRet = getXWeak(SwXFieldMaster::CreateXFieldMaster(&rDoc, nullptr, nResId).get());
+ }
+ break;
+ case SwServiceType::FieldMasterBibliography:
+ {
+ SwFieldType* pType = rDoc.getIDocumentFieldsAccess().GetFieldType(SwFieldIds::TableOfAuthorities, OUString(), true);
+ if(!pType)
+ {
+ SwAuthorityFieldType aType(&rDoc);
+ pType = rDoc.getIDocumentFieldsAccess().InsertFieldType(aType);
+ }
+ xRet = getXWeak(SwXFieldMaster::CreateXFieldMaster(&rDoc, pType).get());
+ }
+ break;
+ case SwServiceType::Paragraph:
+ xRet = getXWeak(SwXParagraph::CreateXParagraph(rDoc, nullptr, nullptr).get());
+ break;
+ case SwServiceType::NumberingRules:
+ xRet = getXWeak(new SwXNumberingRules(rDoc));
+ break;
+ case SwServiceType::TextColumns:
+ xRet = SvxXTextColumns_createInstance();
+ break;
+ case SwServiceType::Defaults:
+ xRet = getXWeak(new SwXTextDefaults(&rDoc));
+ break;
+ case SwServiceType::IMapRectangle:
+ xRet = SvUnoImageMapRectangleObject_createInstance( sw_GetSupportedMacroItems() );
+ break;
+ case SwServiceType::IMapCircle:
+ xRet = SvUnoImageMapCircleObject_createInstance( sw_GetSupportedMacroItems() );
+ break;
+ case SwServiceType::IMapPolygon:
+ xRet = SvUnoImageMapPolygonObject_createInstance( sw_GetSupportedMacroItems() );
+ break;
+ case SwServiceType::Chart2DataProvider:
+ // #i64497# If a chart is in a temporary document during clipboard
+ // paste, there should be no data provider, so that own data is used
+ // This should not happen during copy/paste, as this will unlink
+ // charts using table data.
+ if (rDoc.GetDocShell()->GetCreateMode() != SfxObjectCreateMode::EMBEDDED)
+ xRet = getXWeak(rDoc.getIDocumentChartDataProviderAccess().GetChartDataProvider( true /* create - if not yet available */ ));
+ else
+ SAL_WARN("sw.uno",
+ "not creating chart data provider for embedded object");
+
+ break;
+ case SwServiceType::TypeMeta:
+ xRet = getXWeak(SwXMeta::CreateXMeta(rDoc, false).get());
+ break;
+ case SwServiceType::FieldTypeMetafield:
+ xRet = getXWeak(SwXMeta::CreateXMeta(rDoc, true).get());
+ break;
+ case SwServiceType::LineBreak:
+ xRet = getXWeak(SwXLineBreak::CreateXLineBreak(nullptr).get());
+ break;
+ case SwServiceType::ContentControl:
+ xRet = getXWeak(SwXContentControl::CreateXContentControl(rDoc).get());
+ break;
+ default:
+ throw uno::RuntimeException();
+ }
+ return xRet;
+}
+
+//SMART_UNO_IMPLEMENTATION( SwXTextTables, UsrObject );
+SwXTextTables::SwXTextTables(SwDoc* pDc) :
+ SwUnoCollection(pDc)
+{
+
+}
+
+SwXTextTables::~SwXTextTables()
+{
+
+}
+
+sal_Int32 SwXTextTables::getCount()
+{
+ SolarMutexGuard aGuard;
+ sal_Int32 nRet = 0;
+ if(IsValid())
+ nRet = static_cast<sal_Int32>(GetDoc().GetTableFrameFormatCount(true));
+ return nRet;
+}
+
+uno::Any SAL_CALL SwXTextTables::getByIndex(sal_Int32 nInputIndex)
+{
+ SolarMutexGuard aGuard;
+
+ if (nInputIndex < 0)
+ throw IndexOutOfBoundsException();
+
+ size_t nIndex = static_cast<size_t>(nInputIndex);
+ for(SwTableFormat* pFormat: *GetDoc().GetTableFrameFormats())
+ {
+ if(!pFormat->IsUsed())
+ continue;
+ if(nIndex)
+ --nIndex;
+ else
+ {
+ uno::Reference<XTextTable> xTable = SwXTextTables::GetObject(*pFormat);
+ uno::Any aRet;
+ aRet <<= xTable;
+ return aRet;
+ }
+ }
+ throw IndexOutOfBoundsException();
+}
+
+uno::Any SwXTextTables::getByName(const OUString& rItemName)
+{
+ SolarMutexGuard aGuard;
+ uno::Any aRet;
+
+ const size_t nCount = GetDoc().GetTableFrameFormatCount(true);
+ uno::Reference< XTextTable > xTable;
+ for( size_t i = 0; i < nCount; ++i)
+ {
+ SwFrameFormat& rFormat = GetDoc().GetTableFrameFormat(i, true);
+ if (rItemName == rFormat.GetName())
+ {
+ xTable = SwXTextTables::GetObject(rFormat);
+ aRet <<= xTable;
+ break;
+ }
+ }
+ if(!xTable.is())
+ throw NoSuchElementException();
+
+ return aRet;
+}
+
+uno::Sequence< OUString > SwXTextTables::getElementNames()
+{
+ SolarMutexGuard aGuard;
+ const size_t nCount = GetDoc().GetTableFrameFormatCount(true);
+ uno::Sequence<OUString> aSeq(static_cast<sal_Int32>(nCount));
+ if(nCount)
+ {
+ OUString* pArray = aSeq.getArray();
+ for( size_t i = 0; i < nCount; ++i)
+ {
+ SwFrameFormat& rFormat = GetDoc().GetTableFrameFormat(i, true);
+
+ pArray[i] = rFormat.GetName();
+ }
+ }
+ return aSeq;
+}
+
+sal_Bool SwXTextTables::hasByName(const OUString& rName)
+{
+ SolarMutexGuard aGuard;
+ bool bRet= false;
+
+ const size_t nCount = GetDoc().GetTableFrameFormatCount(true);
+ for( size_t i = 0; i < nCount; ++i)
+ {
+ SwFrameFormat& rFormat = GetDoc().GetTableFrameFormat(i, true);
+ if (rName == rFormat.GetName())
+ {
+ bRet = true;
+ break;
+ }
+ }
+ return bRet;
+}
+
+uno::Type SAL_CALL
+ SwXTextTables::getElementType( )
+{
+ return cppu::UnoType<XTextTable>::get();
+}
+
+sal_Bool SwXTextTables::hasElements()
+{
+ SolarMutexGuard aGuard;
+ return 0 != GetDoc().GetTableFrameFormatCount(true);
+}
+
+OUString SwXTextTables::getImplementationName()
+{
+ return "SwXTextTables";
+}
+
+sal_Bool SwXTextTables::supportsService(const OUString& rServiceName)
+{
+ return cppu::supportsService(this, rServiceName);
+}
+
+uno::Sequence< OUString > SwXTextTables::getSupportedServiceNames()
+{
+ return { "com.sun.star.text.TextTables" };
+}
+
+uno::Reference<text::XTextTable> SwXTextTables::GetObject(SwFrameFormat& rFormat)
+{
+ return SwXTextTable::CreateXTextTable(& rFormat);
+}
+
+namespace
+{
+ template<FlyCntType T> struct UnoFrameWrap_traits {};
+
+ template<>
+ struct UnoFrameWrap_traits<FLYCNTTYPE_FRM>
+ {
+ static uno::Any wrapFrame(SwFrameFormat & rFrameFormat)
+ {
+ uno::Reference<text::XTextFrame> const xRet(
+ SwXTextFrame::CreateXTextFrame(*rFrameFormat.GetDoc(), &rFrameFormat));
+ return uno::Any(xRet);
+ }
+ static bool filter(const SwNode* const pNode) { return !pNode->IsNoTextNode(); };
+ };
+
+ template<>
+ struct UnoFrameWrap_traits<FLYCNTTYPE_GRF>
+ {
+ static uno::Any wrapFrame(SwFrameFormat & rFrameFormat)
+ {
+ uno::Reference<text::XTextContent> const xRet(
+ SwXTextGraphicObject::CreateXTextGraphicObject(*rFrameFormat.GetDoc(), &rFrameFormat));
+ return uno::Any(xRet);
+ }
+ static bool filter(const SwNode* const pNode) { return pNode->IsGrfNode(); };
+ };
+
+ template<>
+ struct UnoFrameWrap_traits<FLYCNTTYPE_OLE>
+ {
+ static uno::Any wrapFrame(SwFrameFormat & rFrameFormat)
+ {
+ uno::Reference<text::XTextContent> const xRet(
+ SwXTextEmbeddedObject::CreateXTextEmbeddedObject(*rFrameFormat.GetDoc(), &rFrameFormat));
+ return uno::Any(xRet);
+ }
+ static bool filter(const SwNode* const pNode) { return pNode->IsOLENode(); };
+ };
+
+ template<FlyCntType T>
+ uno::Any lcl_UnoWrapFrame(SwFrameFormat* pFormat)
+ {
+ return UnoFrameWrap_traits<T>::wrapFrame(*pFormat);
+ }
+
+ // runtime adapter for lcl_UnoWrapFrame
+ /// @throws uno::RuntimeException
+ uno::Any lcl_UnoWrapFrame(SwFrameFormat* pFormat, FlyCntType eType)
+ {
+ switch(eType)
+ {
+ case FLYCNTTYPE_FRM:
+ return lcl_UnoWrapFrame<FLYCNTTYPE_FRM>(pFormat);
+ case FLYCNTTYPE_GRF:
+ return lcl_UnoWrapFrame<FLYCNTTYPE_GRF>(pFormat);
+ case FLYCNTTYPE_OLE:
+ return lcl_UnoWrapFrame<FLYCNTTYPE_OLE>(pFormat);
+ default:
+ throw uno::RuntimeException();
+ }
+ }
+
+ template<FlyCntType T>
+ class SwXFrameEnumeration
+ : public SwSimpleEnumeration_Base
+ {
+ private:
+ std::vector< Any > m_aFrames;
+ protected:
+ virtual ~SwXFrameEnumeration() override {};
+ public:
+ SwXFrameEnumeration(const SwDoc& rDoc);
+
+ //XEnumeration
+ virtual sal_Bool SAL_CALL hasMoreElements() override;
+ virtual Any SAL_CALL nextElement() override;
+
+ //XServiceInfo
+ virtual OUString SAL_CALL getImplementationName() override;
+ virtual sal_Bool SAL_CALL supportsService(const OUString& ServiceName) override;
+ virtual Sequence< OUString > SAL_CALL getSupportedServiceNames() override;
+ };
+}
+
+template<FlyCntType T>
+SwXFrameEnumeration<T>::SwXFrameEnumeration(const SwDoc& rDoc)
+{
+ SolarMutexGuard aGuard;
+ for(sw::SpzFrameFormat* pFormat: *rDoc.GetSpzFrameFormats())
+ {
+ // #i104937#
+ if(pFormat->Which() != RES_FLYFRMFMT || SwTextBoxHelper::isTextBox(pFormat, RES_FLYFRMFMT))
+ continue;
+ const SwNodeIndex* pIdx = pFormat->GetContent().GetContentIdx();
+ if(!pIdx || !pIdx->GetNodes().IsDocNodes())
+ continue;
+ const SwNode* pNd = rDoc.GetNodes()[ pIdx->GetIndex() + 1 ];
+ if(UnoFrameWrap_traits<T>::filter(pNd))
+ m_aFrames.push_back(lcl_UnoWrapFrame<T>(pFormat));
+ }
+}
+
+template<FlyCntType T>
+sal_Bool SwXFrameEnumeration<T>::hasMoreElements()
+{
+ SolarMutexGuard aGuard;
+ return !m_aFrames.empty();
+}
+
+template<FlyCntType T>
+Any SwXFrameEnumeration<T>::nextElement()
+{
+ SolarMutexGuard aGuard;
+ if(m_aFrames.empty())
+ throw NoSuchElementException();
+
+ Any aResult = m_aFrames.back();
+ m_aFrames.pop_back();
+ return aResult;
+}
+
+template<FlyCntType T>
+OUString SwXFrameEnumeration<T>::getImplementationName()
+{
+ return "SwXFrameEnumeration";
+}
+
+template<FlyCntType T>
+sal_Bool SwXFrameEnumeration<T>::supportsService(const OUString& ServiceName)
+{
+ return cppu::supportsService(this, ServiceName);
+}
+
+template<FlyCntType T>
+Sequence< OUString > SwXFrameEnumeration<T>::getSupportedServiceNames()
+{
+ return { OUString("com.sun.star.container.XEnumeration") };
+}
+
+OUString SwXFrames::getImplementationName()
+{
+ return "SwXFrames";
+}
+
+sal_Bool SwXFrames::supportsService(const OUString& rServiceName)
+{
+ return cppu::supportsService(this, rServiceName);
+}
+
+Sequence<OUString> SwXFrames::getSupportedServiceNames()
+{
+ return { OUString("com.sun.star.text.TextFrames") };
+}
+
+SwXFrames::SwXFrames(SwDoc* _pDoc, FlyCntType eSet) :
+ SwUnoCollection(_pDoc),
+ m_eType(eSet)
+{}
+
+SwXFrames::~SwXFrames()
+{}
+
+uno::Reference<container::XEnumeration> SwXFrames::createEnumeration()
+{
+ SolarMutexGuard aGuard;
+ switch(m_eType)
+ {
+ case FLYCNTTYPE_FRM:
+ return uno::Reference< container::XEnumeration >(
+ new SwXFrameEnumeration<FLYCNTTYPE_FRM>(GetDoc()));
+ case FLYCNTTYPE_GRF:
+ return uno::Reference< container::XEnumeration >(
+ new SwXFrameEnumeration<FLYCNTTYPE_GRF>(GetDoc()));
+ case FLYCNTTYPE_OLE:
+ return uno::Reference< container::XEnumeration >(
+ new SwXFrameEnumeration<FLYCNTTYPE_OLE>(GetDoc()));
+ default:
+ throw uno::RuntimeException();
+ }
+}
+
+sal_Int32 SwXFrames::getCount()
+{
+ SolarMutexGuard aGuard;
+ // Ignore TextBoxes for TextFrames.
+ return static_cast<sal_Int32>(GetDoc().GetFlyCount(m_eType, /*bIgnoreTextBoxes=*/m_eType == FLYCNTTYPE_FRM));
+}
+
+uno::Any SwXFrames::getByIndex(sal_Int32 nIndex)
+{
+ SolarMutexGuard aGuard;
+ if(nIndex < 0)
+ throw IndexOutOfBoundsException();
+ // Ignore TextBoxes for TextFrames.
+ SwFrameFormat* pFormat = GetDoc().GetFlyNum(static_cast<size_t>(nIndex), m_eType, /*bIgnoreTextBoxes=*/m_eType == FLYCNTTYPE_FRM);
+ if(!pFormat)
+ throw IndexOutOfBoundsException();
+ return lcl_UnoWrapFrame(pFormat, m_eType);
+}
+
+uno::Any SwXFrames::getByName(const OUString& rName)
+{
+ SolarMutexGuard aGuard;
+ const SwFrameFormat* pFormat;
+ switch(m_eType)
+ {
+ case FLYCNTTYPE_GRF:
+ pFormat = GetDoc().FindFlyByName(rName, SwNodeType::Grf);
+ break;
+ case FLYCNTTYPE_OLE:
+ pFormat = GetDoc().FindFlyByName(rName, SwNodeType::Ole);
+ break;
+ default:
+ pFormat = GetDoc().FindFlyByName(rName, SwNodeType::Text);
+ break;
+ }
+ if(!pFormat)
+ throw NoSuchElementException();
+ return lcl_UnoWrapFrame(const_cast<SwFrameFormat*>(pFormat), m_eType);
+}
+
+uno::Sequence<OUString> SwXFrames::getElementNames()
+{
+ SolarMutexGuard aGuard;
+ const Reference<XEnumeration> xEnum = createEnumeration();
+ std::vector<OUString> vNames;
+ while(xEnum->hasMoreElements())
+ {
+ Reference<container::XNamed> xNamed;
+ xEnum->nextElement() >>= xNamed;
+ if(xNamed.is())
+ vNames.push_back(xNamed->getName());
+ }
+ return ::comphelper::containerToSequence(vNames);
+}
+
+sal_Bool SwXFrames::hasByName(const OUString& rName)
+{
+ SolarMutexGuard aGuard;
+ switch(m_eType)
+ {
+ case FLYCNTTYPE_GRF:
+ return GetDoc().FindFlyByName(rName, SwNodeType::Grf) != nullptr;
+ case FLYCNTTYPE_OLE:
+ return GetDoc().FindFlyByName(rName, SwNodeType::Ole) != nullptr;
+ default:
+ return GetDoc().FindFlyByName(rName, SwNodeType::Text) != nullptr;
+ }
+}
+
+uno::Type SAL_CALL SwXFrames::getElementType()
+{
+ SolarMutexGuard aGuard;
+ switch(m_eType)
+ {
+ case FLYCNTTYPE_FRM:
+ return cppu::UnoType<XTextFrame>::get();
+ case FLYCNTTYPE_GRF:
+ return cppu::UnoType<XTextContent>::get();
+ case FLYCNTTYPE_OLE:
+ return cppu::UnoType<XEmbeddedObjectSupplier>::get();
+ default:
+ return uno::Type();
+ }
+}
+
+sal_Bool SwXFrames::hasElements()
+{
+ SolarMutexGuard aGuard;
+ return GetDoc().GetFlyCount(m_eType) > 0;
+}
+
+
+OUString SwXTextFrames::getImplementationName()
+{
+ return "SwXTextFrames";
+}
+
+sal_Bool SwXTextFrames::supportsService(const OUString& rServiceName)
+{
+ return cppu::supportsService(this, rServiceName);
+}
+
+Sequence< OUString > SwXTextFrames::getSupportedServiceNames()
+{
+ return { "com.sun.star.text.TextFrames" };
+}
+
+SwXTextFrames::SwXTextFrames(SwDoc* _pDoc) :
+ SwXFrames(_pDoc, FLYCNTTYPE_FRM)
+{
+}
+
+SwXTextFrames::~SwXTextFrames()
+{
+}
+
+OUString SwXTextGraphicObjects::getImplementationName()
+{
+ return "SwXTextGraphicObjects";
+}
+
+sal_Bool SwXTextGraphicObjects::supportsService(const OUString& rServiceName)
+{
+ return cppu::supportsService(this, rServiceName);
+}
+
+Sequence< OUString > SwXTextGraphicObjects::getSupportedServiceNames()
+{
+ return { "com.sun.star.text.TextGraphicObjects" };
+}
+
+SwXTextGraphicObjects::SwXTextGraphicObjects(SwDoc* _pDoc) :
+ SwXFrames(_pDoc, FLYCNTTYPE_GRF)
+{
+}
+
+SwXTextGraphicObjects::~SwXTextGraphicObjects()
+{
+}
+
+OUString SwXTextEmbeddedObjects::getImplementationName()
+{
+ return "SwXTextEmbeddedObjects";
+}
+
+sal_Bool SwXTextEmbeddedObjects::supportsService(const OUString& rServiceName)
+{
+ return cppu::supportsService(this, rServiceName);
+}
+
+Sequence< OUString > SwXTextEmbeddedObjects::getSupportedServiceNames()
+{
+ return { "com.sun.star.text.TextEmbeddedObjects" };
+}
+
+SwXTextEmbeddedObjects::SwXTextEmbeddedObjects(SwDoc* _pDoc) :
+ SwXFrames(_pDoc, FLYCNTTYPE_OLE)
+{
+}
+
+SwXTextEmbeddedObjects::~SwXTextEmbeddedObjects()
+{
+}
+
+OUString SwXTextSections::getImplementationName()
+{
+ return "SwXTextSections";
+}
+
+sal_Bool SwXTextSections::supportsService(const OUString& rServiceName)
+{
+ return cppu::supportsService(this, rServiceName);
+}
+
+Sequence< OUString > SwXTextSections::getSupportedServiceNames()
+{
+ return { "com.sun.star.text.TextSections" };
+}
+
+SwXTextSections::SwXTextSections(SwDoc* _pDoc) :
+ SwUnoCollection(_pDoc)
+{
+}
+
+SwXTextSections::~SwXTextSections()
+{
+}
+
+sal_Int32 SwXTextSections::getCount()
+{
+ SolarMutexGuard aGuard;
+ const SwSectionFormats& rSectFormats = GetDoc().GetSections();
+ size_t nCount = rSectFormats.size();
+ for(size_t i = nCount; i; --i)
+ {
+ if( !rSectFormats[i - 1]->IsInNodesArr())
+ nCount--;
+ }
+ return nCount;
+}
+
+uno::Any SwXTextSections::getByIndex(sal_Int32 nIndex)
+{
+ if (nIndex < 0)
+ throw IndexOutOfBoundsException();
+ size_t nIndex2 = nIndex;
+ SolarMutexGuard aGuard;
+
+ const SwSectionFormats& rSectFormats = GetDoc().GetSections();
+ const size_t nCount = rSectFormats.size();
+ for(size_t i = 0; i < nCount; ++i)
+ {
+ if( !rSectFormats[i]->IsInNodesArr())
+ nIndex2++;
+ else if (nIndex2 == i)
+ return Any(GetObject(*rSectFormats[i]));
+ }
+ throw IndexOutOfBoundsException();
+}
+
+uno::Any SwXTextSections::getByName(const OUString& rName)
+{
+ SolarMutexGuard aGuard;
+ uno::Any aRet;
+
+ SwSectionFormats& rFormats = GetDoc().GetSections();
+ uno::Reference< XTextSection > xSect;
+ for(size_t i = 0; i < rFormats.size(); ++i)
+ {
+ SwSectionFormat* pFormat = rFormats[i];
+ if (pFormat->IsInNodesArr()
+ && (rName == pFormat->GetSection()->GetSectionName()))
+ {
+ xSect = GetObject(*pFormat);
+ aRet <<= xSect;
+ break;
+ }
+ }
+ if(!xSect.is())
+ throw NoSuchElementException();
+
+ return aRet;
+}
+
+uno::Sequence< OUString > SwXTextSections::getElementNames()
+{
+ SolarMutexGuard aGuard;
+ SwSectionFormats& rSectFormats = GetDoc().GetSections();
+ size_t nCount = rSectFormats.size();
+ for(size_t i = nCount; i; --i)
+ {
+ if( !rSectFormats[i - 1]->IsInNodesArr())
+ nCount--;
+ }
+
+ uno::Sequence<OUString> aSeq(nCount);
+ if(nCount)
+ {
+ OUString* pArray = aSeq.getArray();
+ size_t nIndex = 0;
+ for( size_t i = 0; i < nCount; ++i, ++nIndex)
+ {
+ const SwSectionFormat* pFormat = rSectFormats[nIndex];
+ while(!pFormat->IsInNodesArr())
+ {
+ pFormat = rSectFormats[++nIndex];
+ }
+ pArray[i] = pFormat->GetSection()->GetSectionName();
+ }
+ }
+ return aSeq;
+}
+
+sal_Bool SwXTextSections::hasByName(const OUString& rName)
+{
+ SolarMutexGuard aGuard;
+ bool bRet = false;
+ if(IsValid())
+ {
+ SwSectionFormats& rFormats = GetDoc().GetSections();
+ for(size_t i = 0; i < rFormats.size(); ++i)
+ {
+ const SwSectionFormat* pFormat = rFormats[i];
+ if (rName == pFormat->GetSection()->GetSectionName())
+ {
+ bRet = true;
+ break;
+ }
+ }
+ }
+ else
+ {
+ // special handling for dbg_ methods
+ if( !rName.startsWith("dbg_"))
+ throw uno::RuntimeException();
+ }
+ return bRet;
+}
+
+uno::Type SAL_CALL SwXTextSections::getElementType()
+{
+ return cppu::UnoType<XTextSection>::get();
+}
+
+sal_Bool SwXTextSections::hasElements()
+{
+ SolarMutexGuard aGuard;
+ size_t nCount = 0;
+
+ SwSectionFormats& rFormats = GetDoc().GetSections();
+ nCount = rFormats.size();
+
+ return nCount > 0;
+}
+
+uno::Reference< XTextSection > SwXTextSections::GetObject( SwSectionFormat& rFormat )
+{
+ return SwXTextSection::CreateXTextSection(&rFormat);
+}
+
+OUString SwXBookmarks::getImplementationName()
+{
+ return "SwXBookmarks";
+}
+
+sal_Bool SwXBookmarks::supportsService(const OUString& rServiceName)
+{
+ return cppu::supportsService(this, rServiceName);
+}
+
+Sequence< OUString > SwXBookmarks::getSupportedServiceNames()
+{
+ return { "com.sun.star.text.Bookmarks" };
+}
+
+SwXBookmarks::SwXBookmarks(SwDoc* _pDoc) :
+ SwUnoCollection(_pDoc)
+{ }
+
+SwXBookmarks::~SwXBookmarks()
+{ }
+
+sal_Int32 SwXBookmarks::getCount()
+{
+ SolarMutexGuard aGuard;
+
+ sal_Int32 count(0);
+ IDocumentMarkAccess* const pMarkAccess = GetDoc().getIDocumentMarkAccess();
+ for (IDocumentMarkAccess::const_iterator_t ppMark =
+ pMarkAccess->getBookmarksBegin();
+ ppMark != pMarkAccess->getBookmarksEnd(); ++ppMark)
+ {
+ if (IDocumentMarkAccess::MarkType::BOOKMARK ==
+ IDocumentMarkAccess::GetType(**ppMark))
+ {
+ ++count; // only count real bookmarks
+ }
+ }
+ return count;
+}
+
+uno::Any SwXBookmarks::getByIndex(sal_Int32 nIndex)
+{
+ SolarMutexGuard aGuard;
+ auto& rDoc = GetDoc();
+ IDocumentMarkAccess* const pMarkAccess = rDoc.getIDocumentMarkAccess();
+ if(nIndex < 0 || nIndex >= pMarkAccess->getBookmarksCount())
+ throw IndexOutOfBoundsException();
+
+ sal_Int32 count(0);
+ for (IDocumentMarkAccess::const_iterator_t ppMark =
+ pMarkAccess->getBookmarksBegin();
+ ppMark != pMarkAccess->getBookmarksEnd(); ++ppMark)
+ {
+ if (IDocumentMarkAccess::MarkType::BOOKMARK ==
+ IDocumentMarkAccess::GetType(**ppMark))
+ {
+ if (count == nIndex)
+ {
+ uno::Any aRet;
+ const uno::Reference< text::XTextContent > xRef =
+ SwXBookmark::CreateXBookmark(rDoc, *ppMark);
+ aRet <<= xRef;
+ return aRet;
+ }
+ ++count; // only count real bookmarks
+ }
+ }
+ throw IndexOutOfBoundsException();
+}
+
+uno::Any SwXBookmarks::getByName(const OUString& rName)
+{
+ SolarMutexGuard aGuard;
+
+ auto& rDoc = GetDoc();
+ IDocumentMarkAccess* const pMarkAccess = rDoc.getIDocumentMarkAccess();
+ IDocumentMarkAccess::const_iterator_t ppBkmk = pMarkAccess->findBookmark(rName);
+ if(ppBkmk == pMarkAccess->getBookmarksEnd())
+ throw NoSuchElementException();
+
+ uno::Any aRet;
+ const uno::Reference< text::XTextContent > xRef =
+ SwXBookmark::CreateXBookmark(rDoc, *ppBkmk);
+ aRet <<= xRef;
+ return aRet;
+}
+
+uno::Sequence< OUString > SwXBookmarks::getElementNames()
+{
+ SolarMutexGuard aGuard;
+
+ std::vector< OUString > ret;
+ IDocumentMarkAccess* const pMarkAccess = GetDoc().getIDocumentMarkAccess();
+ for (IDocumentMarkAccess::const_iterator_t ppMark =
+ pMarkAccess->getBookmarksBegin();
+ ppMark != pMarkAccess->getBookmarksEnd(); ++ppMark)
+ {
+ if (IDocumentMarkAccess::MarkType::BOOKMARK ==
+ IDocumentMarkAccess::GetType(**ppMark))
+ {
+ ret.push_back((*ppMark)->GetName()); // only add real bookmarks
+ }
+ }
+ return comphelper::containerToSequence(ret);
+}
+
+sal_Bool SwXBookmarks::hasByName(const OUString& rName)
+{
+ SolarMutexGuard aGuard;
+
+ IDocumentMarkAccess* const pMarkAccess = GetDoc().getIDocumentMarkAccess();
+ return pMarkAccess->findBookmark(rName) != pMarkAccess->getBookmarksEnd();
+}
+
+uno::Type SAL_CALL SwXBookmarks::getElementType()
+{
+ return cppu::UnoType<XTextContent>::get();
+}
+
+sal_Bool SwXBookmarks::hasElements()
+{
+ SolarMutexGuard aGuard;
+
+ IDocumentMarkAccess* const pMarkAccess = GetDoc().getIDocumentMarkAccess();
+ for (IDocumentMarkAccess::const_iterator_t ppMark =
+ pMarkAccess->getBookmarksBegin();
+ ppMark != pMarkAccess->getBookmarksEnd(); ++ppMark)
+ {
+ if (IDocumentMarkAccess::MarkType::BOOKMARK ==
+ IDocumentMarkAccess::GetType(**ppMark))
+ {
+ return true;
+ }
+ }
+ return false;
+}
+
+SwXNumberingRulesCollection::SwXNumberingRulesCollection( SwDoc* _pDoc ) :
+ SwUnoCollection(_pDoc)
+{
+}
+
+SwXNumberingRulesCollection::~SwXNumberingRulesCollection()
+{
+}
+
+sal_Int32 SwXNumberingRulesCollection::getCount()
+{
+ SolarMutexGuard aGuard;
+ return GetDoc().GetNumRuleTable().size();
+}
+
+uno::Any SwXNumberingRulesCollection::getByIndex(sal_Int32 nIndex)
+{
+ if (nIndex < 0)
+ throw IndexOutOfBoundsException();
+
+ SolarMutexGuard aGuard;
+
+ if (SwDoc& rDoc = GetDoc(); o3tl::make_unsigned(nIndex) < rDoc.GetNumRuleTable().size())
+ {
+ uno::Reference<XIndexReplace> xRef(
+ new SwXNumberingRules(*rDoc.GetNumRuleTable()[nIndex], &rDoc));
+ return uno::Any(xRef);
+ }
+
+ throw IndexOutOfBoundsException();
+}
+
+uno::Type SAL_CALL SwXNumberingRulesCollection::getElementType()
+{
+ return cppu::UnoType<XIndexReplace>::get();
+}
+
+sal_Bool SwXNumberingRulesCollection::hasElements()
+{
+ SolarMutexGuard aGuard;
+ return !GetDoc().GetNumRuleTable().empty();
+}
+
+OUString SwXFootnotes::getImplementationName()
+{
+ return "SwXFootnotes";
+}
+
+sal_Bool SwXFootnotes::supportsService(const OUString& rServiceName)
+{
+ return cppu::supportsService(this, rServiceName);
+}
+
+Sequence< OUString > SwXFootnotes::getSupportedServiceNames()
+{
+ return { "com.sun.star.text.Footnotes" };
+}
+
+SwXFootnotes::SwXFootnotes(bool bEnd, SwDoc* _pDoc)
+ : SwUnoCollection(_pDoc)
+ , m_bEndnote(bEnd)
+{
+}
+
+SwXFootnotes::~SwXFootnotes()
+{
+}
+
+sal_Int32 SwXFootnotes::getCount()
+{
+ SolarMutexGuard aGuard;
+ sal_Int32 nCount = 0;
+ auto& rIdxs = GetDoc().GetFootnoteIdxs();
+ const size_t nFootnoteCnt = rIdxs.size();
+ SwTextFootnote* pTextFootnote;
+ for( size_t n = 0; n < nFootnoteCnt; ++n )
+ {
+ pTextFootnote = rIdxs[n];
+ const SwFormatFootnote& rFootnote = pTextFootnote->GetFootnote();
+ if ( rFootnote.IsEndNote() != m_bEndnote )
+ continue;
+ nCount++;
+ }
+ return nCount;
+}
+
+uno::Any SwXFootnotes::getByIndex(sal_Int32 nIndex)
+{
+ SolarMutexGuard aGuard;
+ uno::Any aRet;
+ sal_Int32 nCount = 0;
+
+ auto& rDoc = GetDoc();
+ auto& rIdxs = rDoc.GetFootnoteIdxs();
+ const size_t nFootnoteCnt = rIdxs.size();
+ SwTextFootnote* pTextFootnote;
+ uno::Reference< XFootnote > xRef;
+ for( size_t n = 0; n < nFootnoteCnt; ++n )
+ {
+ pTextFootnote = rIdxs[n];
+ const SwFormatFootnote& rFootnote = pTextFootnote->GetFootnote();
+ if ( rFootnote.IsEndNote() != m_bEndnote )
+ continue;
+
+ if(nCount == nIndex)
+ {
+ xRef = SwXFootnote::CreateXFootnote(rDoc,
+ &const_cast<SwFormatFootnote&>(rFootnote));
+ aRet <<= xRef;
+ break;
+ }
+ nCount++;
+ }
+ if(!xRef.is())
+ throw IndexOutOfBoundsException();
+
+ return aRet;
+}
+
+uno::Type SAL_CALL SwXFootnotes::getElementType()
+{
+ return cppu::UnoType<XFootnote>::get();
+}
+
+sal_Bool SwXFootnotes::hasElements()
+{
+ SolarMutexGuard aGuard;
+ return !GetDoc().GetFootnoteIdxs().empty();
+}
+
+Reference<XFootnote> SwXFootnotes::GetObject( SwDoc& rDoc, const SwFormatFootnote& rFormat )
+{
+ return SwXFootnote::CreateXFootnote(rDoc, &const_cast<SwFormatFootnote&>(rFormat));
+}
+
+OUString SwXReferenceMarks::getImplementationName()
+{
+ return "SwXReferenceMarks";
+}
+
+sal_Bool SwXReferenceMarks::supportsService(const OUString& rServiceName)
+{
+ return cppu::supportsService(this, rServiceName);
+}
+
+Sequence< OUString > SwXReferenceMarks::getSupportedServiceNames()
+{
+ return { "com.sun.star.text.ReferenceMarks" };
+}
+
+SwXReferenceMarks::SwXReferenceMarks(SwDoc* _pDoc) :
+ SwUnoCollection(_pDoc)
+{
+}
+
+SwXReferenceMarks::~SwXReferenceMarks()
+{
+}
+
+sal_Int32 SwXReferenceMarks::getCount()
+{
+ SolarMutexGuard aGuard;
+ return GetDoc().GetRefMarks();
+}
+
+uno::Any SwXReferenceMarks::getByIndex(sal_Int32 nIndex)
+{
+ SolarMutexGuard aGuard;
+ uno::Any aRet;
+ uno::Reference< XTextContent > xRef;
+ if(0 <= nIndex && nIndex < SAL_MAX_UINT16)
+ {
+ auto& rDoc = GetDoc();
+ SwFormatRefMark *const pMark = const_cast<SwFormatRefMark*>(
+ rDoc.GetRefMark(o3tl::narrowing<sal_uInt16>(nIndex)));
+ if(pMark)
+ {
+ xRef = SwXReferenceMark::CreateXReferenceMark(rDoc, pMark);
+ aRet <<= xRef;
+ }
+ }
+ if(!xRef.is())
+ throw IndexOutOfBoundsException();
+ return aRet;
+}
+
+uno::Any SwXReferenceMarks::getByName(const OUString& rName)
+{
+ SolarMutexGuard aGuard;
+ uno::Any aRet;
+
+ auto& rDoc = GetDoc();
+ SwFormatRefMark *const pMark =
+ const_cast<SwFormatRefMark*>(rDoc.GetRefMark(rName));
+ if(!pMark)
+ throw NoSuchElementException();
+
+ uno::Reference<XTextContent> const xRef =
+ SwXReferenceMark::CreateXReferenceMark(rDoc, pMark);
+ aRet <<= xRef;
+
+ return aRet;
+}
+
+uno::Sequence< OUString > SwXReferenceMarks::getElementNames()
+{
+ SolarMutexGuard aGuard;
+ uno::Sequence<OUString> aRet;
+
+ std::vector<OUString> aStrings;
+ const sal_uInt16 nCount = GetDoc().GetRefMarks(&aStrings);
+ aRet.realloc(nCount);
+ OUString* pNames = aRet.getArray();
+ for(sal_uInt16 i = 0; i < nCount; i++)
+ pNames[i] = aStrings[i];
+
+ return aRet;
+}
+
+sal_Bool SwXReferenceMarks::hasByName(const OUString& rName)
+{
+ SolarMutexGuard aGuard;
+ return nullptr != GetDoc().GetRefMark( rName);
+}
+
+uno::Type SAL_CALL SwXReferenceMarks::getElementType()
+{
+ return cppu::UnoType<XTextContent>::get();
+}
+
+sal_Bool SwXReferenceMarks::hasElements()
+{
+ SolarMutexGuard aGuard;
+ return 0 != GetDoc().GetRefMarks();
+}
+
+SwDoc& SwUnoCollection::GetDoc() const
+{
+ DBG_TESTSOLARMUTEX();
+ if (!m_pDoc)
+ throw uno::RuntimeException();
+ return *m_pDoc;
+}
+
+void SwUnoCollection::Invalidate()
+{
+ SolarMutexGuard aGuard;
+ m_pDoc = nullptr;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/core/unocore/unocontentcontrol.cxx b/sw/source/core/unocore/unocontentcontrol.cxx
new file mode 100644
index 0000000000..5d54d60e9b
--- /dev/null
+++ b/sw/source/core/unocore/unocontentcontrol.cxx
@@ -0,0 +1,1458 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <unocontentcontrol.hxx>
+
+#include <mutex>
+
+#include <com/sun/star/text/XWordCursor.hpp>
+#include <com/sun/star/lang/IndexOutOfBoundsException.hpp>
+
+#include <comphelper/interfacecontainer4.hxx>
+#include <cppuhelper/supportsservice.hxx>
+
+#include <formatcontentcontrol.hxx>
+#include <ndtxt.hxx>
+#include <textcontentcontrol.hxx>
+#include <unotext.hxx>
+#include <unotextcursor.hxx>
+#include <unotextrange.hxx>
+#include <doc.hxx>
+#include <unoport.hxx>
+#include <unomap.hxx>
+#include <unoprnms.hxx>
+#include <utility>
+
+using namespace com::sun::star;
+
+namespace
+{
+/// UNO API wrapper around the text inside an SwXContentControl.
+class SwXContentControlText : public cppu::OWeakObject, public SwXText
+{
+private:
+ SwXContentControl& m_rContentControl;
+
+ void PrepareForAttach(uno::Reference<text::XTextRange>& xRange, const SwPaM& rPam) override;
+
+protected:
+ const SwStartNode* GetStartNode() const override;
+
+public:
+ SwXContentControlText(SwDoc& rDoc, SwXContentControl& rContentControl);
+
+ /// SwXText::Invalidate() is protected.
+ using SwXText::Invalidate;
+
+ // XInterface
+ void SAL_CALL acquire() noexcept override { cppu::OWeakObject::acquire(); }
+ void SAL_CALL release() noexcept override { cppu::OWeakObject::release(); }
+
+ // XTypeProvider
+ uno::Sequence<sal_Int8> SAL_CALL getImplementationId() override;
+
+ // XText
+ virtual rtl::Reference<SwXTextCursor> createXTextCursor() override;
+ virtual rtl::Reference<SwXTextCursor> createXTextCursorByRange(
+ const ::css::uno::Reference<::css::text::XTextRange>& aTextPosition) override;
+};
+}
+
+SwXContentControlText::SwXContentControlText(SwDoc& rDoc, SwXContentControl& rContentControl)
+ : SwXText(&rDoc, CursorType::ContentControl)
+ , m_rContentControl(rContentControl)
+{
+}
+
+const SwStartNode* SwXContentControlText::GetStartNode() const
+{
+ SwXText* pParent = m_rContentControl.GetParentText().get();
+ return pParent ? pParent->GetStartNode() : nullptr;
+}
+
+void SwXContentControlText::PrepareForAttach(uno::Reference<text::XTextRange>& xRange,
+ const SwPaM& rPam)
+{
+ // Create a new cursor to prevent modifying SwXTextRange.
+ xRange = static_cast<text::XWordCursor*>(
+ new SwXTextCursor(*GetDoc(), &m_rContentControl, CursorType::ContentControl,
+ *rPam.GetPoint(), (rPam.HasMark()) ? rPam.GetMark() : nullptr));
+}
+
+rtl::Reference<SwXTextCursor> SwXContentControlText::createXTextCursor()
+{
+ rtl::Reference<SwXTextCursor> xRet;
+ if (IsValid())
+ {
+ SwTextNode* pTextNode;
+ sal_Int32 nContentControlStart;
+ sal_Int32 nContentControlEnd;
+ bool bSuccess = m_rContentControl.SetContentRange(pTextNode, nContentControlStart,
+ nContentControlEnd);
+ if (bSuccess)
+ {
+ SwPosition aPos(*pTextNode, nContentControlStart);
+ xRet = new SwXTextCursor(*GetDoc(), &m_rContentControl, CursorType::ContentControl,
+ aPos);
+ }
+ }
+ return xRet;
+}
+
+uno::Sequence<sal_Int8> SAL_CALL SwXContentControlText::getImplementationId()
+{
+ return css::uno::Sequence<sal_Int8>();
+}
+
+// XText
+
+rtl::Reference<SwXTextCursor> SwXContentControlText::createXTextCursorByRange(
+ const uno::Reference<text::XTextRange>& xTextPosition)
+{
+ const rtl::Reference<SwXTextCursor> xCursor(createXTextCursor());
+ xCursor->gotoRange(xTextPosition, false);
+ return xCursor;
+}
+
+/**
+ * The inner part SwXContentControl, which is deleted with a locked SolarMutex.
+ *
+ * The content control has a cached list of text portions for its contents. This list is created by
+ * SwXTextPortionEnumeration. The content control listens at the SwTextNode and throws away the
+ * cache when the text node changes.
+ */
+class SwXContentControl::Impl : public SvtListener
+{
+public:
+ unotools::WeakReference<SwXContentControl> m_wThis;
+ // Just for OInterfaceContainerHelper4.
+ std::mutex m_Mutex;
+ ::comphelper::OInterfaceContainerHelper4<css::lang::XEventListener> m_EventListeners;
+ std::unique_ptr<const TextRangeList_t> m_pTextPortions;
+ // 3 possible states: not attached, attached, disposed
+ bool m_bIsDisposed;
+ bool m_bIsDescriptor;
+ css::uno::Reference<SwXText> m_xParentText;
+ rtl::Reference<SwXContentControlText> m_xText;
+ SwContentControl* m_pContentControl;
+ bool m_bShowingPlaceHolder;
+ bool m_bCheckbox;
+ bool m_bChecked;
+ OUString m_aCheckedState;
+ OUString m_aUncheckedState;
+ std::vector<SwContentControlListItem> m_aListItems;
+ bool m_bPicture;
+ bool m_bDate;
+ OUString m_aDateFormat;
+ OUString m_aDateLanguage;
+ OUString m_aCurrentDate;
+ bool m_bPlainText;
+ bool m_bComboBox;
+ bool m_bDropDown;
+ OUString m_aPlaceholderDocPart;
+ OUString m_aDataBindingPrefixMappings;
+ OUString m_aDataBindingXpath;
+ OUString m_aDataBindingStoreItemID;
+ OUString m_aColor;
+ OUString m_aAppearance;
+ OUString m_aAlias;
+ OUString m_aTag;
+ sal_Int32 m_nId;
+ sal_uInt32 m_nTabIndex;
+ OUString m_aLock;
+ OUString m_aMultiLine;
+
+ Impl(SwXContentControl& rThis, SwDoc& rDoc, SwContentControl* pContentControl,
+ css::uno::Reference<SwXText> xParentText, std::unique_ptr<const TextRangeList_t> pPortions)
+ : m_pTextPortions(std::move(pPortions))
+ , m_bIsDisposed(false)
+ , m_bIsDescriptor(pContentControl == nullptr)
+ , m_xParentText(std::move(xParentText))
+ , m_xText(new SwXContentControlText(rDoc, rThis))
+ , m_pContentControl(pContentControl)
+ , m_bShowingPlaceHolder(false)
+ , m_bCheckbox(false)
+ , m_bChecked(false)
+ , m_bPicture(false)
+ , m_bDate(false)
+ , m_bPlainText(false)
+ , m_bComboBox(false)
+ , m_bDropDown(false)
+ , m_nId(0)
+ , m_nTabIndex(0)
+ {
+ if (m_pContentControl)
+ {
+ StartListening(m_pContentControl->GetNotifier());
+ }
+ }
+
+ const SwContentControl* GetContentControl() const;
+
+protected:
+ void Notify(const SfxHint& rHint) override;
+};
+
+const SwContentControl* SwXContentControl::Impl::GetContentControl() const
+{
+ return m_pContentControl;
+}
+
+// sw::BroadcastingModify
+void SwXContentControl::Impl::Notify(const SfxHint& rHint)
+{
+ // throw away cache (SwTextNode changed)
+ m_pTextPortions.reset();
+
+ if (rHint.GetId() != SfxHintId::Dying && rHint.GetId() != SfxHintId::Deinitializing)
+ return;
+
+ m_bIsDisposed = true;
+ m_pContentControl = nullptr;
+ m_xText->Invalidate();
+ uno::Reference<uno::XInterface> xThis(m_wThis);
+ if (!xThis.is())
+ {
+ // If UNO object is already dead, don't refer to it in an event.
+ return;
+ }
+ lang::EventObject aEvent(xThis);
+ std::unique_lock aGuard(m_Mutex);
+ m_EventListeners.disposeAndClear(aGuard, aEvent);
+}
+
+const css::uno::Reference<SwXText>& SwXContentControl::GetParentText() const
+{
+ return m_pImpl->m_xParentText;
+}
+
+SwXContentControl::SwXContentControl(SwDoc* pDoc, SwContentControl* pContentControl,
+ const css::uno::Reference<SwXText>& xParentText,
+ std::unique_ptr<const TextRangeList_t> pPortions)
+ : m_pImpl(new SwXContentControl::Impl(*this, *pDoc, pContentControl, xParentText,
+ std::move(pPortions)))
+{
+}
+
+SwXContentControl::SwXContentControl(SwDoc* pDoc)
+ : m_pImpl(new SwXContentControl::Impl(*this, *pDoc, nullptr, nullptr, nullptr))
+{
+}
+
+SwXContentControl::~SwXContentControl() {}
+
+rtl::Reference<SwXContentControl> SwXContentControl::CreateXContentControl(SwDoc& rDoc)
+{
+ rtl::Reference<SwXContentControl> xContentControl(new SwXContentControl(&rDoc));
+ xContentControl->m_pImpl->m_wThis = xContentControl.get();
+ return xContentControl;
+}
+
+rtl::Reference<SwXContentControl>
+SwXContentControl::CreateXContentControl(SwContentControl& rContentControl,
+ const css::uno::Reference<SwXText>& xParent,
+ std::unique_ptr<const TextRangeList_t>&& pPortions)
+{
+ // re-use existing SwXContentControl
+ rtl::Reference<SwXContentControl> xContentControl(rContentControl.GetXContentControl());
+ if (xContentControl.is())
+ {
+ if (pPortions)
+ {
+ // The content control must always be created with the complete content. If
+ // SwXTextPortionEnumeration is created for a selection, it must be checked that the
+ // content control is contained in the selection.
+ xContentControl->m_pImpl->m_pTextPortions = std::move(pPortions);
+ if (xContentControl->m_pImpl->m_xParentText.get() != xParent.get())
+ {
+ SAL_WARN("sw.uno", "SwXContentControl with different parent");
+ xContentControl->m_pImpl->m_xParentText = xParent;
+ }
+ }
+ return xContentControl;
+ }
+
+ // Create new SwXContentControl.
+ SwTextNode* pTextNode = rContentControl.GetTextNode();
+ if (!pTextNode)
+ {
+ SAL_WARN("sw.uno", "CreateXContentControl: no text node");
+ return nullptr;
+ }
+ css::uno::Reference<SwXText> xParentText(xParent);
+ if (!xParentText.is())
+ {
+ SwTextContentControl* pTextAttr = rContentControl.GetTextAttr();
+ if (!pTextAttr)
+ {
+ SAL_WARN("sw.uno", "CreateXContentControl: no text attr");
+ return nullptr;
+ }
+ SwPosition aPos(*pTextNode, pTextAttr->GetStart());
+ xParentText = sw::CreateParentXText(pTextNode->GetDoc(), aPos);
+ }
+ if (!xParentText.is())
+ {
+ return nullptr;
+ }
+ xContentControl = new SwXContentControl(&pTextNode->GetDoc(), &rContentControl, xParentText,
+ std::move(pPortions));
+ rContentControl.SetXContentControl(xContentControl);
+ xContentControl->m_pImpl->m_wThis = xContentControl.get();
+ return xContentControl;
+}
+
+bool SwXContentControl::SetContentRange(SwTextNode*& rpNode, sal_Int32& rStart,
+ sal_Int32& rEnd) const
+{
+ const SwContentControl* pContentControl = m_pImpl->GetContentControl();
+ if (pContentControl)
+ {
+ const SwTextContentControl* pTextAttr = pContentControl->GetTextAttr();
+ if (pTextAttr)
+ {
+ rpNode = pContentControl->GetTextNode();
+ if (rpNode)
+ {
+ // rStart points at the first position within the content control.
+ rStart = pTextAttr->GetStart() + 1;
+ // rEnd points at the last position within the content control.
+ rEnd = *pTextAttr->End() - 1;
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
+// XServiceInfo
+OUString SAL_CALL SwXContentControl::getImplementationName() { return "SwXContentControl"; }
+
+sal_Bool SAL_CALL SwXContentControl::supportsService(const OUString& rServiceName)
+{
+ return cppu::supportsService(this, rServiceName);
+}
+
+uno::Sequence<OUString> SAL_CALL SwXContentControl::getSupportedServiceNames()
+{
+ return { "com.sun.star.text.TextContent", "com.sun.star.text.ContentControl" };
+}
+
+// XComponent
+void SAL_CALL
+SwXContentControl::addEventListener(const uno::Reference<lang::XEventListener>& xListener)
+{
+ std::unique_lock aGuard(m_pImpl->m_Mutex);
+ m_pImpl->m_EventListeners.addInterface(aGuard, xListener);
+}
+
+void SAL_CALL
+SwXContentControl::removeEventListener(const uno::Reference<lang::XEventListener>& xListener)
+{
+ std::unique_lock aGuard(m_pImpl->m_Mutex);
+ m_pImpl->m_EventListeners.removeInterface(aGuard, xListener);
+}
+
+void SAL_CALL SwXContentControl::dispose()
+{
+ SolarMutexGuard g;
+
+ if (m_pImpl->m_bIsDescriptor)
+ {
+ m_pImpl->m_pTextPortions.reset();
+ lang::EventObject aEvent(getXWeak());
+ std::unique_lock aGuard(m_pImpl->m_Mutex);
+ m_pImpl->m_EventListeners.disposeAndClear(aGuard, aEvent);
+ m_pImpl->m_bIsDisposed = true;
+ m_pImpl->m_xText->Invalidate();
+ }
+ else if (!m_pImpl->m_bIsDisposed)
+ {
+ SwTextNode* pTextNode;
+ sal_Int32 nContentControlStart;
+ sal_Int32 nContentControlEnd;
+ bool bSuccess = SetContentRange(pTextNode, nContentControlStart, nContentControlEnd);
+ if (!bSuccess)
+ {
+ SAL_WARN("sw.core", "SwXContentControl::dispose: no pam");
+ }
+ else
+ {
+ // -1 because of CH_TXTATR
+ SwPaM aPam(*pTextNode, nContentControlStart - 1, *pTextNode, nContentControlEnd);
+ SwDoc& rDoc(pTextNode->GetDoc());
+ rDoc.getIDocumentContentOperations().DeleteAndJoin(aPam);
+
+ // removal should call Modify and do the dispose
+ assert(m_pImpl->m_bIsDisposed);
+ }
+ }
+}
+
+void SwXContentControl::AttachImpl(const uno::Reference<text::XTextRange>& xTextRange,
+ sal_uInt16 nWhich)
+{
+ SolarMutexGuard aGuard;
+
+ if (m_pImpl->m_bIsDisposed)
+ {
+ throw lang::DisposedException();
+ }
+ if (!m_pImpl->m_bIsDescriptor)
+ {
+ throw uno::RuntimeException("SwXContentControl::AttachImpl(): already attached",
+ getXWeak());
+ }
+
+ SwXTextRange* pRange = dynamic_cast<SwXTextRange*>(xTextRange.get());
+ OTextCursorHelper* pCursor
+ = pRange ? nullptr : dynamic_cast<OTextCursorHelper*>(xTextRange.get());
+ if (!pRange && !pCursor)
+ {
+ throw lang::IllegalArgumentException(
+ "SwXContentControl::AttachImpl(): argument not supported type", getXWeak(), 0);
+ }
+
+ SwDoc* pDoc = pRange ? &pRange->GetDoc() : pCursor->GetDoc();
+ if (!pDoc)
+ {
+ throw lang::IllegalArgumentException(
+ "SwXContentControl::AttachImpl(): argument has no SwDoc", getXWeak(), 0);
+ }
+
+ SwUnoInternalPaM aPam(*pDoc);
+ ::sw::XTextRangeToSwPaM(aPam, xTextRange);
+
+ UnoActionContext aContext(pDoc);
+
+ auto pTextCursor = dynamic_cast<SwXTextCursor*>(pCursor);
+ bool bForceExpandHints = pTextCursor && pTextCursor->IsAtEndOfContentControl();
+ SetAttrMode nInsertFlags = bForceExpandHints
+ ? (SetAttrMode::FORCEHINTEXPAND | SetAttrMode::DONTEXPAND)
+ : SetAttrMode::DONTEXPAND;
+
+ auto pContentControl = std::make_shared<SwContentControl>(nullptr);
+
+ pContentControl->SetShowingPlaceHolder(m_pImpl->m_bShowingPlaceHolder);
+ pContentControl->SetCheckbox(m_pImpl->m_bCheckbox);
+ pContentControl->SetChecked(m_pImpl->m_bChecked);
+ pContentControl->SetCheckedState(m_pImpl->m_aCheckedState);
+ pContentControl->SetUncheckedState(m_pImpl->m_aUncheckedState);
+ pContentControl->SetListItems(m_pImpl->m_aListItems);
+ pContentControl->SetPicture(m_pImpl->m_bPicture);
+ pContentControl->SetDate(m_pImpl->m_bDate);
+ pContentControl->SetDateFormat(m_pImpl->m_aDateFormat);
+ pContentControl->SetDateLanguage(m_pImpl->m_aDateLanguage);
+ pContentControl->SetCurrentDate(m_pImpl->m_aCurrentDate);
+ pContentControl->SetPlainText(m_pImpl->m_bPlainText);
+ pContentControl->SetComboBox(m_pImpl->m_bComboBox);
+ pContentControl->SetDropDown(m_pImpl->m_bDropDown);
+ pContentControl->SetPlaceholderDocPart(m_pImpl->m_aPlaceholderDocPart);
+ pContentControl->SetDataBindingPrefixMappings(m_pImpl->m_aDataBindingPrefixMappings);
+ pContentControl->SetDataBindingXpath(m_pImpl->m_aDataBindingXpath);
+ pContentControl->SetDataBindingStoreItemID(m_pImpl->m_aDataBindingStoreItemID);
+ pContentControl->SetColor(m_pImpl->m_aColor);
+ pContentControl->SetAppearance(m_pImpl->m_aAppearance);
+ pContentControl->SetAlias(m_pImpl->m_aAlias);
+ pContentControl->SetTag(m_pImpl->m_aTag);
+ pContentControl->SetId(m_pImpl->m_nId);
+ pContentControl->SetTabIndex(m_pImpl->m_nTabIndex);
+ pContentControl->SetLock(m_pImpl->m_aLock);
+ pContentControl->SetMultiLine(m_pImpl->m_aMultiLine);
+
+ SwFormatContentControl aContentControl(pContentControl, nWhich);
+ bool bSuccess
+ = pDoc->getIDocumentContentOperations().InsertPoolItem(aPam, aContentControl, nInsertFlags);
+ SwTextAttr* pTextAttr = pContentControl->GetTextAttr();
+ if (!bSuccess)
+ {
+ throw lang::IllegalArgumentException(
+ "SwXContentControl::AttachImpl(): cannot create content control: invalid range",
+ getXWeak(), 1);
+ }
+ if (!pTextAttr)
+ {
+ SAL_WARN("sw.core", "content control inserted, but has no text attribute?");
+ throw uno::RuntimeException(
+ "SwXContentControl::AttachImpl(): cannot create content control", getXWeak());
+ }
+
+ m_pImpl->EndListeningAll();
+ m_pImpl->m_pContentControl = pContentControl.get();
+ m_pImpl->StartListening(pContentControl->GetNotifier());
+ pContentControl->SetXContentControl(this);
+
+ m_pImpl->m_xParentText = sw::CreateParentXText(*pDoc, *aPam.GetPoint());
+
+ m_pImpl->m_bIsDescriptor = false;
+}
+
+// XTextContent
+void SAL_CALL SwXContentControl::attach(const uno::Reference<text::XTextRange>& xTextRange)
+{
+ return SwXContentControl::AttachImpl(xTextRange, RES_TXTATR_CONTENTCONTROL);
+}
+
+uno::Reference<text::XTextRange> SAL_CALL SwXContentControl::getAnchor()
+{
+ SolarMutexGuard g;
+
+ if (m_pImpl->m_bIsDisposed)
+ {
+ throw lang::DisposedException();
+ }
+ if (m_pImpl->m_bIsDescriptor)
+ {
+ throw uno::RuntimeException("SwXContentControl::getAnchor(): not inserted", getXWeak());
+ }
+
+ SwTextNode* pTextNode;
+ sal_Int32 nContentControlStart;
+ sal_Int32 nContentControlEnd;
+ bool bSuccess = SetContentRange(pTextNode, nContentControlStart, nContentControlEnd);
+ if (!bSuccess)
+ {
+ SAL_WARN("sw.core", "no pam");
+ throw lang::DisposedException("SwXContentControl::getAnchor(): not attached", getXWeak());
+ }
+
+ SwPosition aStart(*pTextNode, nContentControlStart - 1); // -1 due to CH_TXTATR
+ SwPosition aEnd(*pTextNode, nContentControlEnd);
+ return SwXTextRange::CreateXTextRange(pTextNode->GetDoc(), aStart, &aEnd);
+}
+
+// XTextRange
+uno::Reference<text::XText> SAL_CALL SwXContentControl::getText() { return this; }
+
+uno::Reference<text::XTextRange> SAL_CALL SwXContentControl::getStart()
+{
+ SolarMutexGuard g;
+ return m_pImpl->m_xText->getStart();
+}
+
+uno::Reference<text::XTextRange> SAL_CALL SwXContentControl::getEnd()
+{
+ SolarMutexGuard g;
+ return m_pImpl->m_xText->getEnd();
+}
+
+OUString SAL_CALL SwXContentControl::getString()
+{
+ SolarMutexGuard g;
+ return m_pImpl->m_xText->getString();
+}
+
+void SAL_CALL SwXContentControl::setString(const OUString& rString)
+{
+ SolarMutexGuard g;
+ return m_pImpl->m_xText->setString(rString);
+}
+
+// XSimpleText
+uno::Reference<text::XTextCursor> SAL_CALL SwXContentControl::createTextCursor()
+{
+ SolarMutexGuard g;
+ return m_pImpl->m_xText->createTextCursor();
+}
+
+uno::Reference<text::XTextCursor> SAL_CALL
+SwXContentControl::createTextCursorByRange(const uno::Reference<text::XTextRange>& xTextPosition)
+{
+ SolarMutexGuard g;
+ return m_pImpl->m_xText->createTextCursorByRange(xTextPosition);
+}
+
+void SAL_CALL SwXContentControl::insertString(const uno::Reference<text::XTextRange>& xRange,
+ const OUString& rString, sal_Bool bAbsorb)
+{
+ SolarMutexGuard g;
+ return m_pImpl->m_xText->insertString(xRange, rString, bAbsorb);
+}
+
+void SAL_CALL SwXContentControl::insertControlCharacter(
+ const uno::Reference<text::XTextRange>& xRange, sal_Int16 nControlCharacter, sal_Bool bAbsorb)
+{
+ SolarMutexGuard g;
+ return m_pImpl->m_xText->insertControlCharacter(xRange, nControlCharacter, bAbsorb);
+}
+
+// XText
+void SAL_CALL SwXContentControl::insertTextContent(
+ const uno::Reference<text::XTextRange>& xRange,
+ const uno::Reference<text::XTextContent>& xContent, sal_Bool bAbsorb)
+{
+ SolarMutexGuard g;
+ return m_pImpl->m_xText->insertTextContent(xRange, xContent, bAbsorb);
+}
+
+void SAL_CALL
+SwXContentControl::removeTextContent(const uno::Reference<text::XTextContent>& xContent)
+{
+ SolarMutexGuard g;
+ return m_pImpl->m_xText->removeTextContent(xContent);
+}
+
+// XPropertySet
+uno::Reference<beans::XPropertySetInfo> SAL_CALL SwXContentControl::getPropertySetInfo()
+{
+ SolarMutexGuard aGuard;
+
+ static uno::Reference<beans::XPropertySetInfo> xRet
+ = aSwMapProvider.GetPropertySet(PROPERTY_MAP_CONTENTCONTROL)->getPropertySetInfo();
+ return xRet;
+}
+
+void SAL_CALL SwXContentControl::setPropertyValue(const OUString& rPropertyName,
+ const css::uno::Any& rValue)
+{
+ SolarMutexGuard aGuard;
+
+ if (rPropertyName == UNO_NAME_SHOWING_PLACE_HOLDER)
+ {
+ bool bValue;
+ if (rValue >>= bValue)
+ {
+ if (m_pImpl->m_bIsDescriptor)
+ {
+ m_pImpl->m_bShowingPlaceHolder = bValue;
+ }
+ else
+ {
+ m_pImpl->m_pContentControl->SetShowingPlaceHolder(bValue);
+ }
+ }
+ }
+ else if (rPropertyName == UNO_NAME_CHECKBOX)
+ {
+ bool bValue;
+ if (rValue >>= bValue)
+ {
+ if (m_pImpl->m_bIsDescriptor)
+ {
+ m_pImpl->m_bCheckbox = bValue;
+ }
+ else
+ {
+ m_pImpl->m_pContentControl->SetCheckbox(bValue);
+ }
+ }
+ }
+ else if (rPropertyName == UNO_NAME_CHECKED)
+ {
+ bool bValue;
+ if (rValue >>= bValue)
+ {
+ if (m_pImpl->m_bIsDescriptor)
+ {
+ m_pImpl->m_bChecked = bValue;
+ }
+ else
+ {
+ m_pImpl->m_pContentControl->SetChecked(bValue);
+ }
+ }
+ }
+ else if (rPropertyName == UNO_NAME_CHECKED_STATE)
+ {
+ OUString aValue;
+ if (rValue >>= aValue)
+ {
+ if (m_pImpl->m_bIsDescriptor)
+ {
+ m_pImpl->m_aCheckedState = aValue;
+ }
+ else
+ {
+ m_pImpl->m_pContentControl->SetCheckedState(aValue);
+ }
+ }
+ }
+ else if (rPropertyName == UNO_NAME_UNCHECKED_STATE)
+ {
+ OUString aValue;
+ if (rValue >>= aValue)
+ {
+ if (m_pImpl->m_bIsDescriptor)
+ {
+ m_pImpl->m_aUncheckedState = aValue;
+ }
+ else
+ {
+ m_pImpl->m_pContentControl->SetUncheckedState(aValue);
+ }
+ }
+ }
+ else if (rPropertyName == UNO_NAME_LIST_ITEMS)
+ {
+ std::vector<SwContentControlListItem> aItems
+ = SwContentControlListItem::ItemsFromAny(rValue);
+ if (m_pImpl->m_bIsDescriptor)
+ {
+ m_pImpl->m_aListItems = aItems;
+
+ if (!m_pImpl->m_bComboBox && !m_pImpl->m_bDropDown)
+ {
+ m_pImpl->m_bDropDown = true;
+ }
+ }
+ else
+ {
+ m_pImpl->m_pContentControl->SetListItems(aItems);
+
+ if (!m_pImpl->m_pContentControl->GetComboBox()
+ && !m_pImpl->m_pContentControl->GetDropDown())
+ {
+ m_pImpl->m_pContentControl->SetDropDown(true);
+ }
+ }
+ }
+ else if (rPropertyName == UNO_NAME_PICTURE)
+ {
+ bool bValue;
+ if (rValue >>= bValue)
+ {
+ if (m_pImpl->m_bIsDescriptor)
+ {
+ m_pImpl->m_bPicture = bValue;
+ }
+ else
+ {
+ m_pImpl->m_pContentControl->SetPicture(bValue);
+ }
+ }
+ }
+ else if (rPropertyName == UNO_NAME_DATE)
+ {
+ bool bValue;
+ if (rValue >>= bValue)
+ {
+ if (m_pImpl->m_bIsDescriptor)
+ {
+ m_pImpl->m_bDate = bValue;
+ }
+ else
+ {
+ m_pImpl->m_pContentControl->SetDate(bValue);
+ }
+ }
+ }
+ else if (rPropertyName == UNO_NAME_DATE_FORMAT)
+ {
+ OUString aValue;
+ if (rValue >>= aValue)
+ {
+ if (m_pImpl->m_bIsDescriptor)
+ {
+ m_pImpl->m_aDateFormat = aValue;
+ }
+ else
+ {
+ m_pImpl->m_pContentControl->SetDateFormat(aValue);
+ }
+ }
+ }
+ else if (rPropertyName == UNO_NAME_DATE_LANGUAGE)
+ {
+ OUString aValue;
+ if (rValue >>= aValue)
+ {
+ if (m_pImpl->m_bIsDescriptor)
+ {
+ m_pImpl->m_aDateLanguage = aValue;
+ }
+ else
+ {
+ m_pImpl->m_pContentControl->SetDateLanguage(aValue);
+ }
+ }
+ }
+ else if (rPropertyName == UNO_NAME_CURRENT_DATE)
+ {
+ OUString aValue;
+ if (rValue >>= aValue)
+ {
+ if (m_pImpl->m_bIsDescriptor)
+ {
+ m_pImpl->m_aCurrentDate = aValue;
+ }
+ else
+ {
+ m_pImpl->m_pContentControl->SetCurrentDate(aValue);
+ }
+ }
+ }
+ else if (rPropertyName == UNO_NAME_PLAIN_TEXT)
+ {
+ bool bValue;
+ if (rValue >>= bValue)
+ {
+ if (m_pImpl->m_bIsDescriptor)
+ {
+ m_pImpl->m_bPlainText = bValue;
+ }
+ else
+ {
+ m_pImpl->m_pContentControl->SetPlainText(bValue);
+ }
+ }
+ }
+ else if (rPropertyName == UNO_NAME_COMBO_BOX)
+ {
+ bool bValue;
+ if (rValue >>= bValue)
+ {
+ if (m_pImpl->m_bIsDescriptor)
+ {
+ m_pImpl->m_bComboBox = bValue;
+ }
+ else
+ {
+ m_pImpl->m_pContentControl->SetComboBox(bValue);
+ }
+ }
+ }
+ else if (rPropertyName == UNO_NAME_DROP_DOWN)
+ {
+ bool bValue;
+ if (rValue >>= bValue)
+ {
+ if (m_pImpl->m_bIsDescriptor)
+ {
+ m_pImpl->m_bDropDown = bValue;
+ }
+ else
+ {
+ m_pImpl->m_pContentControl->SetDropDown(bValue);
+ }
+ }
+ }
+ else if (rPropertyName == UNO_NAME_PLACEHOLDER_DOC_PART)
+ {
+ OUString aValue;
+ if (rValue >>= aValue)
+ {
+ if (m_pImpl->m_bIsDescriptor)
+ {
+ m_pImpl->m_aPlaceholderDocPart = aValue;
+ }
+ else
+ {
+ m_pImpl->m_pContentControl->SetPlaceholderDocPart(aValue);
+ }
+ }
+ }
+ else if (rPropertyName == UNO_NAME_DATA_BINDING_PREFIX_MAPPINGS)
+ {
+ OUString aValue;
+ if (rValue >>= aValue)
+ {
+ if (m_pImpl->m_bIsDescriptor)
+ {
+ m_pImpl->m_aDataBindingPrefixMappings = aValue;
+ }
+ else
+ {
+ m_pImpl->m_pContentControl->SetDataBindingPrefixMappings(aValue);
+ }
+ }
+ }
+ else if (rPropertyName == UNO_NAME_DATA_BINDING_XPATH)
+ {
+ OUString aValue;
+ if (rValue >>= aValue)
+ {
+ if (m_pImpl->m_bIsDescriptor)
+ {
+ m_pImpl->m_aDataBindingXpath = aValue;
+ }
+ else
+ {
+ m_pImpl->m_pContentControl->SetDataBindingXpath(aValue);
+ }
+ }
+ }
+ else if (rPropertyName == UNO_NAME_DATA_BINDING_STORE_ITEM_ID)
+ {
+ OUString aValue;
+ if (rValue >>= aValue)
+ {
+ if (m_pImpl->m_bIsDescriptor)
+ {
+ m_pImpl->m_aDataBindingStoreItemID = aValue;
+ }
+ else
+ {
+ m_pImpl->m_pContentControl->SetDataBindingStoreItemID(aValue);
+ }
+ }
+ }
+ else if (rPropertyName == UNO_NAME_COLOR)
+ {
+ OUString aValue;
+ if (rValue >>= aValue)
+ {
+ if (m_pImpl->m_bIsDescriptor)
+ {
+ m_pImpl->m_aColor = aValue;
+ }
+ else
+ {
+ m_pImpl->m_pContentControl->SetColor(aValue);
+ }
+ }
+ }
+ else if (rPropertyName == UNO_NAME_APPEARANCE)
+ {
+ OUString aValue;
+ if (rValue >>= aValue)
+ {
+ if (m_pImpl->m_bIsDescriptor)
+ {
+ m_pImpl->m_aAppearance = aValue;
+ }
+ else
+ {
+ m_pImpl->m_pContentControl->SetAppearance(aValue);
+ }
+ }
+ }
+ else if (rPropertyName == UNO_NAME_ALIAS)
+ {
+ OUString aValue;
+ if (rValue >>= aValue)
+ {
+ if (m_pImpl->m_bIsDescriptor)
+ {
+ m_pImpl->m_aAlias = aValue;
+ }
+ else
+ {
+ m_pImpl->m_pContentControl->SetAlias(aValue);
+ }
+ }
+ }
+ else if (rPropertyName == UNO_NAME_TAG)
+ {
+ OUString aValue;
+ if (rValue >>= aValue)
+ {
+ if (m_pImpl->m_bIsDescriptor)
+ {
+ m_pImpl->m_aTag = aValue;
+ }
+ else
+ {
+ m_pImpl->m_pContentControl->SetTag(aValue);
+ }
+ }
+ }
+ else if (rPropertyName == UNO_NAME_ID)
+ {
+ sal_Int32 nValue = 0;
+ if (rValue >>= nValue)
+ {
+ if (m_pImpl->m_bIsDescriptor)
+ {
+ m_pImpl->m_nId = nValue;
+ }
+ else
+ {
+ m_pImpl->m_pContentControl->SetId(nValue);
+ }
+ }
+ }
+ else if (rPropertyName == UNO_NAME_TAB_INDEX)
+ {
+ sal_uInt32 nValue = 0;
+ if (rValue >>= nValue)
+ {
+ if (m_pImpl->m_bIsDescriptor)
+ {
+ m_pImpl->m_nTabIndex = nValue;
+ }
+ else
+ {
+ m_pImpl->m_pContentControl->SetTabIndex(nValue);
+ }
+ }
+ }
+ else if (rPropertyName == UNO_NAME_LOCK)
+ {
+ OUString aValue;
+ if (rValue >>= aValue)
+ {
+ if (m_pImpl->m_bIsDescriptor)
+ {
+ m_pImpl->m_aLock = aValue;
+ }
+ else
+ {
+ m_pImpl->m_pContentControl->SetLock(aValue);
+ }
+ }
+ }
+ else if (rPropertyName == UNO_NAME_MULTILINE)
+ {
+ OUString aValue;
+ if (rValue >>= aValue)
+ {
+ if (m_pImpl->m_bIsDescriptor)
+ {
+ m_pImpl->m_aMultiLine = aValue;
+ }
+ else
+ {
+ m_pImpl->m_pContentControl->SetMultiLine(aValue);
+ }
+ }
+ }
+ else
+ {
+ throw beans::UnknownPropertyException();
+ }
+}
+
+uno::Any SAL_CALL SwXContentControl::getPropertyValue(const OUString& rPropertyName)
+{
+ SolarMutexGuard aGuard;
+
+ uno::Any aRet;
+ if (rPropertyName == UNO_NAME_SHOWING_PLACE_HOLDER)
+ {
+ if (m_pImpl->m_bIsDescriptor)
+ {
+ aRet <<= m_pImpl->m_bShowingPlaceHolder;
+ }
+ else
+ {
+ aRet <<= m_pImpl->m_pContentControl->GetShowingPlaceHolder();
+ }
+ }
+ else if (rPropertyName == UNO_NAME_CHECKBOX)
+ {
+ if (m_pImpl->m_bIsDescriptor)
+ {
+ aRet <<= m_pImpl->m_bCheckbox;
+ }
+ else
+ {
+ aRet <<= m_pImpl->m_pContentControl->GetCheckbox();
+ }
+ }
+ else if (rPropertyName == UNO_NAME_CHECKED)
+ {
+ if (m_pImpl->m_bIsDescriptor)
+ {
+ aRet <<= m_pImpl->m_bChecked;
+ }
+ else
+ {
+ aRet <<= m_pImpl->m_pContentControl->GetChecked();
+ }
+ }
+ else if (rPropertyName == UNO_NAME_CHECKED_STATE)
+ {
+ if (m_pImpl->m_bIsDescriptor)
+ {
+ aRet <<= m_pImpl->m_aCheckedState;
+ }
+ else
+ {
+ aRet <<= m_pImpl->m_pContentControl->GetCheckedState();
+ }
+ }
+ else if (rPropertyName == UNO_NAME_UNCHECKED_STATE)
+ {
+ if (m_pImpl->m_bIsDescriptor)
+ {
+ aRet <<= m_pImpl->m_aUncheckedState;
+ }
+ else
+ {
+ aRet <<= m_pImpl->m_pContentControl->GetUncheckedState();
+ }
+ }
+ else if (rPropertyName == UNO_NAME_LIST_ITEMS)
+ {
+ std::vector<SwContentControlListItem> aItems;
+ if (m_pImpl->m_bIsDescriptor)
+ {
+ aItems = m_pImpl->m_aListItems;
+ }
+ else
+ {
+ aItems = m_pImpl->m_pContentControl->GetListItems();
+ }
+ SwContentControlListItem::ItemsToAny(aItems, aRet);
+ }
+ else if (rPropertyName == UNO_NAME_PICTURE)
+ {
+ if (m_pImpl->m_bIsDescriptor)
+ {
+ aRet <<= m_pImpl->m_bPicture;
+ }
+ else
+ {
+ aRet <<= m_pImpl->m_pContentControl->GetPicture();
+ }
+ }
+ else if (rPropertyName == UNO_NAME_DATE)
+ {
+ if (m_pImpl->m_bIsDescriptor)
+ {
+ aRet <<= m_pImpl->m_bDate;
+ }
+ else
+ {
+ aRet <<= m_pImpl->m_pContentControl->GetDate();
+ }
+ }
+ else if (rPropertyName == UNO_NAME_DATE_FORMAT)
+ {
+ if (m_pImpl->m_bIsDescriptor)
+ {
+ aRet <<= m_pImpl->m_aDateFormat;
+ }
+ else
+ {
+ aRet <<= m_pImpl->m_pContentControl->GetDateFormat();
+ }
+ }
+ else if (rPropertyName == UNO_NAME_DATE_LANGUAGE)
+ {
+ if (m_pImpl->m_bIsDescriptor)
+ {
+ aRet <<= m_pImpl->m_aDateLanguage;
+ }
+ else
+ {
+ aRet <<= m_pImpl->m_pContentControl->GetDateLanguage();
+ }
+ }
+ else if (rPropertyName == UNO_NAME_CURRENT_DATE)
+ {
+ if (m_pImpl->m_bIsDescriptor)
+ {
+ aRet <<= m_pImpl->m_aCurrentDate;
+ }
+ else
+ {
+ aRet <<= m_pImpl->m_pContentControl->GetCurrentDate();
+ }
+ }
+ else if (rPropertyName == UNO_NAME_PLAIN_TEXT)
+ {
+ if (m_pImpl->m_bIsDescriptor)
+ {
+ aRet <<= m_pImpl->m_bPlainText;
+ }
+ else
+ {
+ aRet <<= m_pImpl->m_pContentControl->GetPlainText();
+ }
+ }
+ else if (rPropertyName == UNO_NAME_COMBO_BOX)
+ {
+ if (m_pImpl->m_bIsDescriptor)
+ {
+ aRet <<= m_pImpl->m_bComboBox;
+ }
+ else
+ {
+ aRet <<= m_pImpl->m_pContentControl->GetComboBox();
+ }
+ }
+ else if (rPropertyName == UNO_NAME_DROP_DOWN)
+ {
+ if (m_pImpl->m_bIsDescriptor)
+ {
+ aRet <<= m_pImpl->m_bDropDown;
+ }
+ else
+ {
+ aRet <<= m_pImpl->m_pContentControl->GetDropDown();
+ }
+ }
+ else if (rPropertyName == UNO_NAME_PLACEHOLDER_DOC_PART)
+ {
+ if (m_pImpl->m_bIsDescriptor)
+ {
+ aRet <<= m_pImpl->m_aPlaceholderDocPart;
+ }
+ else
+ {
+ aRet <<= m_pImpl->m_pContentControl->GetCurrentDate();
+ }
+ }
+ else if (rPropertyName == UNO_NAME_DATA_BINDING_PREFIX_MAPPINGS)
+ {
+ if (m_pImpl->m_bIsDescriptor)
+ {
+ aRet <<= m_pImpl->m_aDataBindingPrefixMappings;
+ }
+ else
+ {
+ aRet <<= m_pImpl->m_pContentControl->GetDataBindingPrefixMappings();
+ }
+ }
+ else if (rPropertyName == UNO_NAME_DATA_BINDING_XPATH)
+ {
+ if (m_pImpl->m_bIsDescriptor)
+ {
+ aRet <<= m_pImpl->m_aDataBindingXpath;
+ }
+ else
+ {
+ aRet <<= m_pImpl->m_pContentControl->GetDataBindingXpath();
+ }
+ }
+ else if (rPropertyName == UNO_NAME_DATA_BINDING_STORE_ITEM_ID)
+ {
+ if (m_pImpl->m_bIsDescriptor)
+ {
+ aRet <<= m_pImpl->m_aDataBindingStoreItemID;
+ }
+ else
+ {
+ aRet <<= m_pImpl->m_pContentControl->GetDataBindingStoreItemID();
+ }
+ }
+ else if (rPropertyName == UNO_NAME_COLOR)
+ {
+ if (m_pImpl->m_bIsDescriptor)
+ {
+ aRet <<= m_pImpl->m_aColor;
+ }
+ else
+ {
+ aRet <<= m_pImpl->m_pContentControl->GetColor();
+ }
+ }
+ else if (rPropertyName == UNO_NAME_APPEARANCE)
+ {
+ if (m_pImpl->m_bIsDescriptor)
+ {
+ aRet <<= m_pImpl->m_aAppearance;
+ }
+ else
+ {
+ aRet <<= m_pImpl->m_pContentControl->GetAppearance();
+ }
+ }
+ else if (rPropertyName == UNO_NAME_ALIAS)
+ {
+ if (m_pImpl->m_bIsDescriptor)
+ {
+ aRet <<= m_pImpl->m_aAlias;
+ }
+ else
+ {
+ aRet <<= m_pImpl->m_pContentControl->GetAlias();
+ }
+ }
+ else if (rPropertyName == UNO_NAME_TAG)
+ {
+ if (m_pImpl->m_bIsDescriptor)
+ {
+ aRet <<= m_pImpl->m_aTag;
+ }
+ else
+ {
+ aRet <<= m_pImpl->m_pContentControl->GetTag();
+ }
+ }
+ else if (rPropertyName == UNO_NAME_DATE_STRING)
+ {
+ if (!m_pImpl->m_bIsDescriptor)
+ {
+ aRet <<= m_pImpl->m_pContentControl->GetDateString();
+ }
+ }
+ else if (rPropertyName == UNO_NAME_ID)
+ {
+ if (m_pImpl->m_bIsDescriptor)
+ {
+ aRet <<= m_pImpl->m_nId;
+ }
+ else
+ {
+ aRet <<= m_pImpl->m_pContentControl->GetId();
+ }
+ }
+ else if (rPropertyName == UNO_NAME_TAB_INDEX)
+ {
+ if (m_pImpl->m_bIsDescriptor)
+ {
+ aRet <<= m_pImpl->m_nTabIndex;
+ }
+ else
+ {
+ aRet <<= m_pImpl->m_pContentControl->GetTabIndex();
+ }
+ }
+ else if (rPropertyName == UNO_NAME_LOCK)
+ {
+ if (m_pImpl->m_bIsDescriptor)
+ {
+ aRet <<= m_pImpl->m_aLock;
+ }
+ else
+ {
+ aRet <<= m_pImpl->m_pContentControl->GetLock();
+ }
+ }
+ else if (rPropertyName == UNO_NAME_MULTILINE)
+ {
+ if (m_pImpl->m_bIsDescriptor)
+ {
+ aRet <<= m_pImpl->m_aMultiLine;
+ }
+ else
+ {
+ aRet <<= m_pImpl->m_pContentControl->GetMultiLine();
+ }
+ }
+ else
+ {
+ throw beans::UnknownPropertyException();
+ }
+
+ return aRet;
+}
+
+void SAL_CALL SwXContentControl::addPropertyChangeListener(
+ const OUString& /*rPropertyName*/,
+ const uno::Reference<beans::XPropertyChangeListener>& /*xListener*/)
+{
+ SAL_WARN("sw.uno", "SwXContentControl::addPropertyChangeListener: not implemented");
+}
+
+void SAL_CALL SwXContentControl::removePropertyChangeListener(
+ const OUString& /*rPropertyName*/,
+ const uno::Reference<beans::XPropertyChangeListener>& /*xListener*/)
+{
+ SAL_WARN("sw.uno", "SwXContentControl::removePropertyChangeListener: not implemented");
+}
+
+void SAL_CALL SwXContentControl::addVetoableChangeListener(
+ const OUString& /*rPropertyName*/,
+ const uno::Reference<beans::XVetoableChangeListener>& /*xListener*/)
+{
+ SAL_WARN("sw.uno", "SwXContentControl::addVetoableChangeListener: not implemented");
+}
+
+void SAL_CALL SwXContentControl::removeVetoableChangeListener(
+ const OUString& /*rPropertyName*/,
+ const uno::Reference<beans::XVetoableChangeListener>& /*xListener*/)
+{
+ SAL_WARN("sw.uno", "SwXContentControl::removeVetoableChangeListener: not implemented");
+}
+
+// XElementAccess
+uno::Type SAL_CALL SwXContentControl::getElementType()
+{
+ return cppu::UnoType<text::XTextRange>::get();
+}
+
+sal_Bool SAL_CALL SwXContentControl::hasElements()
+{
+ SolarMutexGuard g;
+ return m_pImpl->m_pContentControl != nullptr;
+}
+
+// XEnumerationAccess
+uno::Reference<container::XEnumeration> SAL_CALL SwXContentControl::createEnumeration()
+{
+ SolarMutexGuard g;
+
+ if (m_pImpl->m_bIsDisposed)
+ {
+ throw lang::DisposedException();
+ }
+ if (m_pImpl->m_bIsDescriptor)
+ {
+ throw uno::RuntimeException("createEnumeration(): not inserted", getXWeak());
+ }
+
+ SwTextNode* pTextNode;
+ sal_Int32 nContentControlStart;
+ sal_Int32 nContentControlEnd;
+ bool bSuccess = SetContentRange(pTextNode, nContentControlStart, nContentControlEnd);
+ if (!bSuccess)
+ {
+ SAL_WARN("sw.core", "no pam");
+ throw lang::DisposedException();
+ }
+
+ SwPaM aPam(*pTextNode, nContentControlStart);
+
+ if (!m_pImpl->m_pTextPortions)
+ {
+ return new SwXTextPortionEnumeration(aPam, GetParentText(), nContentControlStart,
+ nContentControlEnd);
+ }
+ else
+ {
+ return new SwXTextPortionEnumeration(aPam, std::deque(*m_pImpl->m_pTextPortions));
+ }
+}
+
+SwXContentControls::SwXContentControls(SwDoc* pDoc)
+ : SwUnoCollection(pDoc)
+{
+}
+
+SwXContentControls::~SwXContentControls() {}
+
+sal_Int32 SwXContentControls::getCount()
+{
+ SolarMutexGuard aGuard;
+
+ return GetDoc().GetContentControlManager().GetCount();
+}
+
+uno::Any SwXContentControls::getByIndex(sal_Int32 nIndex)
+{
+ SolarMutexGuard aGuard;
+
+ SwContentControlManager& rManager = GetDoc().GetContentControlManager();
+ if (nIndex < 0 || o3tl::make_unsigned(nIndex) >= rManager.GetCount())
+ {
+ throw lang::IndexOutOfBoundsException();
+ }
+
+ SwTextContentControl* pTextContentControl = rManager.Get(nIndex);
+ const SwFormatContentControl& rFormatContentControl = pTextContentControl->GetContentControl();
+ rtl::Reference<SwXContentControl> xContentControl
+ = SwXContentControl::CreateXContentControl(*rFormatContentControl.GetContentControl());
+ uno::Any aRet;
+ aRet <<= uno::Reference<text::XTextContent>(xContentControl);
+ return aRet;
+}
+
+uno::Type SwXContentControls::getElementType() { return cppu::UnoType<text::XTextContent>::get(); }
+
+sal_Bool SwXContentControls::hasElements()
+{
+ SolarMutexGuard aGuard;
+
+ return !GetDoc().GetContentControlManager().IsEmpty();
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/core/unocore/unocrsr.cxx b/sw/source/core/unocore/unocrsr.cxx
new file mode 100644
index 0000000000..6c10066732
--- /dev/null
+++ b/sw/source/core/unocore/unocrsr.cxx
@@ -0,0 +1,216 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <unocrsr.hxx>
+#include <doc.hxx>
+#include <IDocumentLayoutAccess.hxx>
+#include <swtable.hxx>
+#include <rootfrm.hxx>
+
+sw::UnoCursorHint::~UnoCursorHint() {}
+
+SwUnoCursor::SwUnoCursor( const SwPosition &rPos )
+ : SwCursor( rPos, nullptr )
+ , m_bRemainInSection(true)
+ , m_bSkipOverHiddenSections(false)
+ , m_bSkipOverProtectSections(false)
+{}
+
+SwUnoCursor::~SwUnoCursor()
+{
+ SwDoc& rDoc = GetDoc();
+ if( !rDoc.IsInDtor() )
+ {
+ assert(!m_aNotifier.HasListeners());
+ }
+
+ // delete the whole ring
+ while( GetNext() != this )
+ {
+ Ring* pNxt = GetNextInRing();
+ // coverity[deref_arg] - the delete moves a new entry into GetNext()
+ pNxt->MoveTo(nullptr); // remove from chain
+ delete pNxt; // and delete
+ }
+ // coverity[deref_arg] - GetNext() is not a use after free at this point
+}
+
+bool SwUnoCursor::IsReadOnlyAvailable() const
+{
+ return true;
+}
+
+const SwContentFrame*
+SwUnoCursor::DoSetBidiLevelLeftRight( bool &, bool, bool )
+{
+ return nullptr; // not for uno cursor
+}
+
+void SwUnoCursor::DoSetBidiLevelUpDown()
+{
+ // not for uno cursor
+}
+
+bool SwUnoCursor::IsSelOvr( SwCursorSelOverFlags eFlags )
+{
+ if (m_bRemainInSection)
+ {
+ SwDoc& rDoc = GetDoc();
+ SwNodeIndex aOldIdx( *rDoc.GetNodes()[ GetSavePos()->nNode ] );
+ SwPosition& rPtPos = *GetPoint();
+ SwStartNode *pOldSttNd = aOldIdx.GetNode().StartOfSectionNode(),
+ *pNewSttNd = rPtPos.GetNode().StartOfSectionNode();
+ if( pOldSttNd != pNewSttNd )
+ {
+ bool bMoveDown = GetSavePos()->nNode < rPtPos.GetNodeIndex();
+ bool bValidPos = false;
+
+ // search the correct surrounded start node - which the index
+ // can't leave.
+ while( pOldSttNd->IsSectionNode() )
+ pOldSttNd = pOldSttNd->StartOfSectionNode();
+
+ // is the new index inside this surrounded section?
+ if( rPtPos.GetNode() > *pOldSttNd &&
+ rPtPos.GetNode() < *pOldSttNd->EndOfSectionNode() )
+ {
+ // check if it a valid move inside this section
+ // (only over SwSection's !)
+ const SwStartNode* pInvalidNode;
+ do {
+ pInvalidNode = nullptr;
+ pNewSttNd = rPtPos.GetNode().StartOfSectionNode();
+
+ const SwStartNode *pSttNd = pNewSttNd, *pEndNd = pOldSttNd;
+ if( pSttNd->EndOfSectionIndex() >
+ pEndNd->EndOfSectionIndex() )
+ {
+ pEndNd = pNewSttNd;
+ pSttNd = pOldSttNd;
+ }
+
+ while( pSttNd->GetIndex() > pEndNd->GetIndex() )
+ {
+ if( !pSttNd->IsSectionNode() )
+ pInvalidNode = pSttNd;
+ pSttNd = pSttNd->StartOfSectionNode();
+ }
+ if( pInvalidNode )
+ {
+ if( bMoveDown )
+ {
+ rPtPos.Assign( *pInvalidNode->EndOfSectionNode(), 1 );
+
+ if( !rPtPos.GetNode().IsContentNode() &&
+ ( !rDoc.GetNodes().GoNextSection( &rPtPos ) ||
+ rPtPos.GetNode() > *pOldSttNd->EndOfSectionNode() ) )
+ break;
+ }
+ else
+ {
+ rPtPos.Assign( *pInvalidNode, -1 );
+
+ if( !rPtPos.GetNode().IsContentNode() &&
+ ( !SwNodes::GoPrevSection( &rPtPos ) ||
+ rPtPos.GetNode() < *pOldSttNd ) )
+ break;
+ }
+ }
+ else
+ bValidPos = true;
+ } while ( pInvalidNode );
+ }
+
+ if( bValidPos )
+ {
+ SwContentNode* pCNd = GetPointContentNode();
+ GetPoint()->SetContent( (pCNd && !bMoveDown) ? pCNd->Len() : 0);
+ }
+ else
+ {
+ rPtPos.Assign( GetSavePos()->nNode );
+ GetPoint()->SetContent( GetSavePos()->nContent );
+ return true;
+ }
+ }
+ }
+ return SwCursor::IsSelOvr( eFlags );
+}
+
+SwUnoTableCursor::SwUnoTableCursor(const SwPosition& rPos)
+ : SwCursor(rPos, nullptr)
+ , SwUnoCursor(rPos)
+ , SwTableCursor(rPos)
+ , m_aTableSel(rPos, nullptr)
+{
+ SetRemainInSection(false);
+}
+
+SwUnoTableCursor::~SwUnoTableCursor()
+{
+ while (m_aTableSel.GetNext() != &m_aTableSel)
+ delete m_aTableSel.GetNext();
+}
+
+bool SwUnoTableCursor::IsSelOvr( SwCursorSelOverFlags eFlags )
+{
+ bool bRet = SwUnoCursor::IsSelOvr( eFlags );
+ if( !bRet )
+ {
+ const SwTableNode* pTNd = GetPoint()->GetNode().FindTableNode();
+ bRet = !(pTNd == GetDoc().GetNodes()[ GetSavePos()->nNode ]->
+ FindTableNode() && (!HasMark() ||
+ pTNd == GetMark()->GetNode().FindTableNode() ));
+ }
+ return bRet;
+}
+
+void SwUnoTableCursor::MakeBoxSels()
+{
+ const SwContentNode* pCNd;
+ bool bMakeTableCursors = true;
+ if( GetPoint()->GetNodeIndex() && GetMark()->GetNodeIndex() &&
+ nullptr != ( pCNd = GetPointContentNode() ) && pCNd->getLayoutFrame( pCNd->GetDoc().getIDocumentLayoutAccess().GetCurrentLayout() ) &&
+ nullptr != ( pCNd = GetMarkContentNode() ) && pCNd->getLayoutFrame( pCNd->GetDoc().getIDocumentLayoutAccess().GetCurrentLayout() ) )
+ bMakeTableCursors = GetDoc().getIDocumentLayoutAccess().GetCurrentLayout()->MakeTableCursors( *this );
+
+ if ( !bMakeTableCursors )
+ {
+ SwSelBoxes const& rTmpBoxes = GetSelectedBoxes();
+ while (!rTmpBoxes.empty())
+ {
+ DeleteBox(0);
+ }
+ }
+
+ if( IsChgd() )
+ {
+ SwTableCursor::MakeBoxSels( &m_aTableSel );
+ if (!GetSelectedBoxesCount())
+ {
+ const SwTableBox* pBox;
+ const SwNode* pBoxNd = GetPoint()->GetNode().FindTableBoxStartNode();
+ const SwTableNode* pTableNd = pBoxNd ? pBoxNd->FindTableNode() : nullptr;
+ if( pTableNd && nullptr != ( pBox = pTableNd->GetTable().GetTableBox( pBoxNd->GetIndex() )) )
+ InsertBox( *pBox );
+ }
+ }
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/core/unocore/unocrsrhelper.cxx b/sw/source/core/unocore/unocrsrhelper.cxx
new file mode 100644
index 0000000000..70a724814c
--- /dev/null
+++ b/sw/source/core/unocore/unocrsrhelper.cxx
@@ -0,0 +1,1587 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <unocrsrhelper.hxx>
+
+#include <map>
+#include <algorithm>
+#include <memory>
+
+#include <com/sun/star/beans/NamedValue.hpp>
+#include <com/sun/star/beans/PropertyAttribute.hpp>
+#include <com/sun/star/beans/PropertyState.hpp>
+#include <com/sun/star/embed/ElementModes.hpp>
+#include <com/sun/star/embed/XStorage.hpp>
+#include <com/sun/star/io/IOException.hpp>
+#include <com/sun/star/text/XTextSection.hpp>
+#include <com/sun/star/lang/XSingleServiceFactory.hpp>
+
+#include <svx/unoshape.hxx>
+
+#include <cmdid.h>
+#include <hintids.hxx>
+#include <unotextrange.hxx>
+#include <unodraw.hxx>
+#include <unofootnote.hxx>
+#include <unobookmark.hxx>
+#include <unomap.hxx>
+#include <unorefmark.hxx>
+#include <unoidx.hxx>
+#include <unofield.hxx>
+#include <unotbl.hxx>
+#include <unosett.hxx>
+#include <unoframe.hxx>
+#include <unocrsr.hxx>
+#include <doc.hxx>
+#include <IDocumentUndoRedo.hxx>
+#include <IDocumentRedlineAccess.hxx>
+#include <IDocumentLayoutAccess.hxx>
+#include <fmtftn.hxx>
+#include <charfmt.hxx>
+#include <pagedesc.hxx>
+#include <docstyle.hxx>
+#include <ndtxt.hxx>
+#include <docsh.hxx>
+#include <section.hxx>
+#include <shellio.hxx>
+#include <edimp.hxx>
+#include <swundo.hxx>
+#include <cntfrm.hxx>
+#include <pagefrm.hxx>
+#include <svl/eitem.hxx>
+#include <svl/lngmisc.hxx>
+#include <swtable.hxx>
+#include <tox.hxx>
+#include <doctxm.hxx>
+#include <fchrfmt.hxx>
+#include <editeng/editids.hrc>
+#include <editeng/flstitem.hxx>
+#include <editeng/prntitem.hxx>
+#include <vcl/metric.hxx>
+#include <svtools/ctrltool.hxx>
+#include <sfx2/docfilt.hxx>
+#include <sfx2/docfile.hxx>
+#include <sfx2/fcontnr.hxx>
+#include <svl/stritem.hxx>
+#include <SwStyleNameMapper.hxx>
+#include <redline.hxx>
+#include <numrule.hxx>
+#include <comphelper/storagehelper.hxx>
+#include <unotools/mediadescriptor.hxx>
+#include <comphelper/sequenceashashmap.hxx>
+#include <SwNodeNum.hxx>
+#include <fmtmeta.hxx>
+#include <txtfld.hxx>
+#include <unoparagraph.hxx>
+#include <poolfmt.hxx>
+#include <paratr.hxx>
+#include <sal/log.hxx>
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::text;
+using namespace ::com::sun::star::table;
+using namespace ::com::sun::star::container;
+using namespace ::com::sun::star::lang;
+
+namespace SwUnoCursorHelper
+{
+
+static SwPaM* lcl_createPamCopy(const SwPaM& rPam)
+{
+ SwPaM *const pRet = new SwPaM(*rPam.GetPoint());
+ ::sw::DeepCopyPaM(rPam, *pRet);
+ return pRet;
+}
+
+void GetSelectableFromAny(uno::Reference<uno::XInterface> const& xIfc,
+ SwDoc & rTargetDoc,
+ SwPaM *& o_rpPaM, std::pair<OUString, FlyCntType> & o_rFrame,
+ OUString & o_rTableName, SwUnoTableCursor const*& o_rpTableCursor,
+ ::sw::mark::IMark const*& o_rpMark,
+ std::vector<SdrObject *> & o_rSdrObjects)
+{
+ uno::Reference<drawing::XShapes> const xShapes(xIfc, UNO_QUERY);
+ if (xShapes.is())
+ {
+ sal_Int32 nShapes(xShapes->getCount());
+ for (sal_Int32 i = 0; i < nShapes; ++i)
+ {
+ uno::Reference<lang::XUnoTunnel> xShape;
+ xShapes->getByIndex(i) >>= xShape;
+ if (xShape.is())
+ {
+ SvxShape *const pSvxShape(
+ comphelper::getFromUnoTunnel<SvxShape>(xShape));
+ if (pSvxShape)
+ {
+ SdrObject *const pSdrObject = pSvxShape->GetSdrObject();
+ if (pSdrObject)
+ { // hmm... needs view to verify it's in right doc...
+ o_rSdrObjects.push_back(pSdrObject);
+ }
+ }
+ }
+ }
+ return;
+ }
+
+ uno::Reference<lang::XUnoTunnel> const xTunnel(xIfc, UNO_QUERY);
+
+ SwXShape *const pShape(comphelper::getFromUnoTunnel<SwXShape>(xTunnel));
+ if (pShape)
+ {
+ if (SvxShape * pSvxShape = pShape->GetSvxShape())
+ {
+ SdrObject *const pSdrObject = pSvxShape->GetSdrObject();
+ if (pSdrObject)
+ { // hmm... needs view to verify it's in right doc...
+ o_rSdrObjects.push_back(pSdrObject);
+ }
+ }
+ return;
+ }
+
+ OTextCursorHelper *const pCursor(
+ dynamic_cast<OTextCursorHelper*>(xIfc.get()));
+ if (pCursor)
+ {
+ if (pCursor->GetDoc() == &rTargetDoc)
+ {
+ o_rpPaM = lcl_createPamCopy(*pCursor->GetPaM());
+ }
+ return;
+ }
+
+ SwXTextRanges* const pRanges = dynamic_cast<SwXTextRanges*>(xIfc.get());
+ if (pRanges)
+ {
+ SwUnoCursor const* pUnoCursor = pRanges->GetCursor();
+ if (pUnoCursor && &pUnoCursor->GetDoc() == &rTargetDoc)
+ {
+ o_rpPaM = lcl_createPamCopy(*pUnoCursor);
+ }
+ return;
+ }
+
+ // check these before Range to prevent misinterpretation of text frames
+ // and cells also implement XTextRange
+ SwXFrame *const pFrame = dynamic_cast<SwXFrame*>(xIfc.get());
+ if (pFrame)
+ {
+ const SwFrameFormat *const pFrameFormat(pFrame->GetFrameFormat());
+ if (pFrameFormat && pFrameFormat->GetDoc() == &rTargetDoc)
+ {
+ o_rFrame = std::make_pair(pFrameFormat->GetName(), pFrame->GetFlyCntType());
+ }
+ return;
+ }
+
+ SwXTextTable *const pTextTable = dynamic_cast<SwXTextTable*>(xIfc.get());
+ if (pTextTable)
+ {
+ SwFrameFormat *const pFrameFormat(pTextTable->GetFrameFormat());
+ if (pFrameFormat && pFrameFormat->GetDoc() == &rTargetDoc)
+ {
+ o_rTableName = pFrameFormat->GetName();
+ }
+ return;
+ }
+
+ SwXCell *const pCell = dynamic_cast<SwXCell*>(xIfc.get());
+ if (pCell)
+ {
+ SwFrameFormat *const pFrameFormat(pCell->GetFrameFormat());
+ if (pFrameFormat && pFrameFormat->GetDoc() == &rTargetDoc)
+ {
+ SwTableBox * pBox = pCell->GetTableBox();
+ SwTable *const pTable = SwTable::FindTable(pFrameFormat);
+ // ??? what's the benefit of setting pBox in this convoluted way?
+ pBox = pCell->FindBox(pTable, pBox);
+ if (pBox)
+ {
+ SwPaM aPam(*pBox->GetSttNd());
+ aPam.Move(fnMoveForward, GoInNode);
+ o_rpPaM = lcl_createPamCopy(aPam);
+ }
+ }
+ return;
+ }
+
+ uno::Reference<text::XTextRange> const xTextRange(xTunnel, UNO_QUERY);
+ if (xTextRange.is())
+ {
+ SwUnoInternalPaM aPam(rTargetDoc);
+ if (::sw::XTextRangeToSwPaM(aPam, xTextRange))
+ {
+ o_rpPaM = lcl_createPamCopy(aPam);
+ }
+ return;
+ }
+
+ SwXCellRange *const pCellRange = dynamic_cast<SwXCellRange*>(xIfc.get());
+ if (pCellRange)
+ {
+ SwUnoCursor const*const pUnoCursor(pCellRange->GetTableCursor());
+ if (pUnoCursor && &pUnoCursor->GetDoc() == &rTargetDoc)
+ {
+ // probably can't copy it to o_rpPaM for this since it's
+ // a SwTableCursor
+ o_rpTableCursor = dynamic_cast<SwUnoTableCursor const*>(pUnoCursor);
+ }
+ return;
+ }
+
+ ::sw::mark::IMark const*const pMark =
+ SwXBookmark::GetBookmarkInDoc(& rTargetDoc, xIfc);
+ if (pMark)
+ {
+ o_rpMark = pMark;
+ return;
+ }
+}
+
+uno::Reference<text::XTextContent>
+GetNestedTextContent(SwTextNode const & rTextNode, sal_Int32 const nIndex,
+ bool const bParent)
+{
+ // these should be unambiguous because of the dummy character
+ auto const eMode( bParent
+ ? ::sw::GetTextAttrMode::Parent : ::sw::GetTextAttrMode::Expand );
+ SwTextAttr *const pMetaTextAttr =
+ rTextNode.GetTextAttrAt(nIndex, RES_TXTATR_META, eMode);
+ SwTextAttr *const pMetaFieldTextAttr =
+ rTextNode.GetTextAttrAt(nIndex, RES_TXTATR_METAFIELD, eMode);
+ // which is innermost?
+ SwTextAttr *const pTextAttr = pMetaTextAttr
+ ? (pMetaFieldTextAttr
+ ? ((pMetaFieldTextAttr->GetStart() >
+ pMetaTextAttr->GetStart())
+ ? pMetaFieldTextAttr : pMetaTextAttr)
+ : pMetaTextAttr)
+ : pMetaFieldTextAttr;
+ uno::Reference<XTextContent> xRet;
+ if (pTextAttr)
+ {
+ ::sw::Meta *const pMeta(
+ static_cast<SwFormatMeta &>(pTextAttr->GetAttr()).GetMeta());
+ assert(pMeta);
+ xRet.set(pMeta->MakeUnoObject(), uno::UNO_QUERY);
+ }
+ return xRet;
+}
+
+static uno::Any GetParaListAutoFormat(SwTextNode const& rNode)
+{
+ SwFormatAutoFormat const*const pFormat(
+ rNode.GetSwAttrSet().GetItem<SwFormatAutoFormat>(RES_PARATR_LIST_AUTOFMT, false));
+ if (!pFormat)
+ {
+ return uno::Any();
+ }
+ const auto pSet(pFormat->GetStyleHandle());
+ if (!pSet)
+ return {};
+ SfxItemPropertySet const& rPropSet(*aSwMapProvider.GetPropertySet(PROPERTY_MAP_CHAR_AUTO_STYLE));
+ SfxItemPropertyMap const& rMap(rPropSet.getPropertyMap());
+ std::vector<beans::NamedValue> props;
+ // have to iterate the map, not the item set?
+ for (auto const pEntry : rMap.getPropertyEntries())
+ {
+ if (rPropSet.getPropertyState(*pEntry, *pSet) == PropertyState_DIRECT_VALUE)
+ {
+ Any value;
+ rPropSet.getPropertyValue(*pEntry, *pSet, value);
+ props.emplace_back(pEntry->aName, value);
+ }
+ }
+ return uno::Any(comphelper::containerToSequence(props));
+}
+
+// Read the special properties of the cursor
+bool getCursorPropertyValue(const SfxItemPropertyMapEntry& rEntry
+ , SwPaM& rPam
+ , Any *pAny
+ , PropertyState& eState
+ , const SwTextNode* pNode )
+{
+ PropertyState eNewState = PropertyState_DIRECT_VALUE;
+ bool bDone = true;
+ switch(rEntry.nWID)
+ {
+ case FN_UNO_PARA_CONT_PREV_SUBTREE:
+ if (pAny)
+ {
+ const SwTextNode * pTmpNode = pNode;
+
+ if (!pTmpNode)
+ pTmpNode = rPam.GetPointNode().GetTextNode();
+
+ bool bRet = false;
+
+ if ( pTmpNode &&
+ pTmpNode->GetNum() &&
+ pTmpNode->GetNum()->IsContinueingPreviousSubTree() )
+ {
+ bRet = true;
+ }
+
+ *pAny <<= bRet;
+ }
+ break;
+ case FN_UNO_PARA_NUM_STRING:
+ if (pAny)
+ {
+ const SwTextNode * pTmpNode = pNode;
+
+ if (!pTmpNode)
+ pTmpNode = rPam.GetPointNode().GetTextNode();
+
+ OUString sRet;
+ if ( pTmpNode && pTmpNode->GetNum() )
+ {
+ sRet = pTmpNode->GetNumString();
+ }
+
+ *pAny <<= sRet;
+ }
+ break;
+ case RES_PARATR_OUTLINELEVEL:
+ if (pAny)
+ {
+ const SwTextNode * pTmpNode = pNode;
+
+ if (!pTmpNode)
+ pTmpNode = rPam.GetPointNode().GetTextNode();
+
+ sal_Int16 nRet = -1;
+ if ( pTmpNode )
+ nRet = sal::static_int_cast< sal_Int16 >( pTmpNode->GetAttrOutlineLevel() );
+
+ *pAny <<= nRet;
+ }
+ break;
+ case FN_UNO_PARA_CONDITIONAL_STYLE_NAME:
+ case FN_UNO_PARA_STYLE :
+ {
+ SwFormatColl* pFormat = nullptr;
+ if(pNode)
+ pFormat = FN_UNO_PARA_CONDITIONAL_STYLE_NAME == rEntry.nWID
+ ? pNode->GetFormatColl() : &pNode->GetAnyFormatColl();
+ else
+ {
+ pFormat = SwUnoCursorHelper::GetCurTextFormatColl(rPam,
+ FN_UNO_PARA_CONDITIONAL_STYLE_NAME == rEntry.nWID);
+ }
+ if(pFormat)
+ {
+ if( pAny )
+ {
+ OUString sVal;
+ SwStyleNameMapper::FillProgName(pFormat->GetName(), sVal, SwGetPoolIdFromName::TxtColl );
+ *pAny <<= sVal;
+ }
+ }
+ else
+ eNewState = PropertyState_AMBIGUOUS_VALUE;
+ }
+ break;
+ case FN_UNO_PAGE_STYLE :
+ {
+ OUString sVal;
+ GetCurPageStyle(rPam, sVal);
+ if( pAny )
+ *pAny <<= sVal;
+ if(sVal.isEmpty())
+ eNewState = PropertyState_AMBIGUOUS_VALUE;
+ }
+ break;
+ case FN_UNO_NUM_START_VALUE :
+ if( pAny )
+ {
+ sal_Int16 nValue = IsNodeNumStart(rPam, eNewState);
+ *pAny <<= nValue;
+ }
+ break;
+ case FN_UNO_NUM_LEVEL :
+ case FN_UNO_IS_NUMBER :
+ // #i91601#
+ case FN_UNO_LIST_ID:
+ case FN_NUMBER_NEWSTART:
+ case FN_UNO_PARA_NUM_AUTO_FORMAT:
+ {
+ if (!pAny)
+ {
+ break;
+ }
+ // a multi selection is not considered
+ const SwTextNode* pTextNd = rPam.GetPointNode().GetTextNode();
+ if ( pTextNd && pTextNd->IsInList() )
+ {
+ switch (rEntry.nWID)
+ {
+ case FN_UNO_NUM_LEVEL:
+ {
+ *pAny <<= static_cast<sal_Int16>(pTextNd->GetActualListLevel());
+ break;
+ }
+ case FN_UNO_IS_NUMBER:
+ {
+ *pAny <<= pTextNd->IsCountedInList();
+ break;
+ }
+ // #i91601#
+ case FN_UNO_LIST_ID:
+ {
+ *pAny <<= pTextNd->GetListId();
+ break;
+ }
+ case FN_NUMBER_NEWSTART:
+ {
+ *pAny <<= pTextNd->IsListRestart();
+ break;
+ }
+ case FN_UNO_PARA_NUM_AUTO_FORMAT:
+ {
+ *pAny = GetParaListAutoFormat(*pTextNd);
+ break;
+ }
+ default:
+ assert(false);
+ }
+ }
+ else
+ {
+ eNewState = PropertyState_DEFAULT_VALUE;
+
+ // #i30838# set default values for default properties
+ switch (rEntry.nWID)
+ {
+ case FN_UNO_NUM_LEVEL:
+ {
+ *pAny <<= static_cast<sal_Int16>( 0 );
+ break;
+ }
+ case FN_UNO_IS_NUMBER:
+ {
+ *pAny <<= false;
+ break;
+ }
+ // #i91601#
+ case FN_UNO_LIST_ID:
+ {
+ *pAny <<= OUString();
+ break;
+ }
+ case FN_NUMBER_NEWSTART:
+ {
+ *pAny <<= false;
+ break;
+ }
+ case FN_UNO_PARA_NUM_AUTO_FORMAT:
+ {
+ break; // void
+ }
+ default:
+ assert(false);
+ }
+ }
+ //PROPERTY_MAYBEVOID!
+ }
+ break;
+ case FN_UNO_NUM_RULES :
+ if( pAny )
+ getNumberingProperty(rPam, eNewState, pAny);
+ else
+ {
+ if( !SwDoc::GetNumRuleAtPos( *rPam.GetPoint() ) )
+ eNewState = PropertyState_DEFAULT_VALUE;
+ }
+ break;
+ case FN_UNO_DOCUMENT_INDEX_MARK:
+ {
+ std::vector<SwTextAttr *> marks;
+ if (rPam.GetPointNode().IsTextNode())
+ {
+ marks = rPam.GetPointNode().GetTextNode()->GetTextAttrsAt(
+ rPam.GetPoint()->GetContentIndex(), RES_TXTATR_TOXMARK);
+ }
+ if (!marks.empty())
+ {
+ if( pAny )
+ { // hmm... can only return 1 here
+ SwTOXMark & rMark =
+ static_cast<SwTOXMark &>((*marks.begin())->GetAttr());
+ const uno::Reference< text::XDocumentIndexMark > xRef =
+ SwXDocumentIndexMark::CreateXDocumentIndexMark(
+ rPam.GetDoc(), &rMark);
+ (*pAny) <<= xRef;
+ }
+ }
+ else
+ //also here - indistinguishable
+ eNewState = PropertyState_DEFAULT_VALUE;
+ }
+ break;
+ case FN_UNO_DOCUMENT_INDEX:
+ {
+ SwTOXBase* pBase = SwDoc::GetCurTOX(
+ *rPam.Start() );
+ if( pBase )
+ {
+ if( pAny )
+ {
+ const uno::Reference< text::XDocumentIndex > xRef =
+ SwXDocumentIndex::CreateXDocumentIndex(rPam.GetDoc(),
+ static_cast<SwTOXBaseSection *>(pBase));
+ (*pAny) <<= xRef;
+ }
+ }
+ else
+ eNewState = PropertyState_DEFAULT_VALUE;
+ }
+ break;
+ case FN_UNO_TEXT_FIELD:
+ {
+ const SwPosition *pPos = rPam.Start();
+ const SwTextNode *pTextNd =
+ rPam.GetDoc().GetNodes()[pPos->GetNodeIndex()]->GetTextNode();
+ const SwTextAttr* pTextAttr = pTextNd
+ ? pTextNd->GetFieldTextAttrAt(pPos->GetContentIndex(), ::sw::GetTextAttrMode::Default)
+ : nullptr;
+ if ( pTextAttr != nullptr )
+ {
+ if( pAny )
+ {
+ uno::Reference<text::XTextField> const xField(
+ SwXTextField::CreateXTextField(&rPam.GetDoc(),
+ &pTextAttr->GetFormatField()));
+ *pAny <<= xField;
+ }
+ }
+ else
+ eNewState = PropertyState_DEFAULT_VALUE;
+ }
+ break;
+ case FN_UNO_TEXT_TABLE:
+ case FN_UNO_CELL:
+ {
+ SwStartNode* pSttNode = rPam.GetPointNode().StartOfSectionNode();
+ SwStartNodeType eType = pSttNode->GetStartNodeType();
+ if(SwTableBoxStartNode == eType)
+ {
+ if( pAny )
+ {
+ const SwTableNode* pTableNode = pSttNode->FindTableNode();
+ SwFrameFormat* pTableFormat = pTableNode->GetTable().GetFrameFormat();
+ //SwTable& rTable = static_cast<SwTableNode*>(pSttNode)->GetTable();
+ if(FN_UNO_TEXT_TABLE == rEntry.nWID)
+ {
+ uno::Reference< XTextTable > xTable = SwXTextTables::GetObject(*pTableFormat);
+ *pAny <<= xTable;
+ }
+ else
+ {
+ SwTableBox* pBox = pSttNode->GetTableBox();
+ uno::Reference< XCell > xCell = SwXCell::CreateXCell(pTableFormat, pBox);
+ *pAny <<= xCell;
+ }
+ }
+ }
+ else
+ eNewState = PropertyState_DEFAULT_VALUE;
+ }
+ break;
+ case FN_UNO_TEXT_FRAME:
+ {
+ SwStartNode* pSttNode = rPam.GetPointNode().StartOfSectionNode();
+ SwStartNodeType eType = pSttNode->GetStartNodeType();
+
+ SwFrameFormat* pFormat;
+ if(eType == SwFlyStartNode && nullptr != (pFormat = pSttNode->GetFlyFormat()))
+ {
+ // Create a wrapper only for text frames, not for graphic or OLE nodes.
+ if (pAny && !rPam.GetPointNode().IsNoTextNode())
+ {
+ uno::Reference<XTextFrame> const xFrame(
+ SwXTextFrame::CreateXTextFrame(*pFormat->GetDoc(), pFormat));
+ (*pAny) <<= xFrame;
+ }
+ }
+ else
+ eNewState = PropertyState_DEFAULT_VALUE;
+ }
+ break;
+ case FN_UNO_TEXT_SECTION:
+ {
+ SwSection* pSect = SwDoc::GetCurrSection(*rPam.GetPoint());
+ if(pSect)
+ {
+ if( pAny )
+ {
+ uno::Reference< XTextSection > xSect = SwXTextSections::GetObject( *pSect->GetFormat() );
+ *pAny <<= xSect;
+ }
+ }
+ else
+ eNewState = PropertyState_DEFAULT_VALUE;
+ }
+ break;
+ case FN_UNO_TEXT_PARAGRAPH:
+ {
+ SwTextNode* pTextNode = rPam.GetPoint()->GetNode().GetTextNode();
+ if (pTextNode)
+ {
+ if (pAny)
+ {
+ uno::Reference<text::XTextContent> xParagraph = SwXParagraph::CreateXParagraph(pTextNode->GetDoc(), pTextNode, nullptr);
+ *pAny <<= xParagraph;
+ }
+ }
+ else
+ eNewState = PropertyState_DEFAULT_VALUE;
+ }
+ break;
+ case FN_UNO_SORTED_TEXT_ID:
+ {
+ if( pAny )
+ {
+ sal_Int32 nIndex = -1;
+ SwTextNode* pTextNode = rPam.GetPoint()->GetNode().GetTextNode();
+ if ( pTextNode )
+ nIndex = pTextNode->GetIndex().get();
+ *pAny <<= nIndex;
+ }
+ }
+ break;
+ case FN_UNO_ENDNOTE:
+ case FN_UNO_FOOTNOTE:
+ {
+ SwTextAttr *const pTextAttr = rPam.GetPointNode().IsTextNode() ?
+ rPam.GetPointNode().GetTextNode()->GetTextAttrForCharAt(
+ rPam.GetPoint()->GetContentIndex(), RES_TXTATR_FTN) : nullptr;
+ if(pTextAttr)
+ {
+ const SwFormatFootnote& rFootnote = pTextAttr->GetFootnote();
+ if(rFootnote.IsEndNote() == (FN_UNO_ENDNOTE == rEntry.nWID))
+ {
+ if( pAny )
+ {
+ const uno::Reference< text::XFootnote > xFootnote =
+ SwXFootnote::CreateXFootnote(rPam.GetDoc(),
+ &const_cast<SwFormatFootnote&>(rFootnote));
+ *pAny <<= xFootnote;
+ }
+ }
+ else
+ eNewState = PropertyState_DEFAULT_VALUE;
+ }
+ else
+ eNewState = PropertyState_DEFAULT_VALUE;
+ }
+ break;
+ case FN_UNO_REFERENCE_MARK:
+ {
+ std::vector<SwTextAttr *> marks;
+ if (rPam.GetPointNode().IsTextNode())
+ {
+ marks = rPam.GetPointNode().GetTextNode()->GetTextAttrsAt(
+ rPam.GetPoint()->GetContentIndex(), RES_TXTATR_REFMARK);
+ }
+ if (!marks.empty())
+ {
+ if( pAny )
+ { // hmm... can only return 1 here
+ const SwFormatRefMark& rRef = (*marks.begin())->GetRefMark();
+ uno::Reference<XTextContent> const xRef =
+ SwXReferenceMark::CreateXReferenceMark(rPam.GetDoc(),
+ const_cast<SwFormatRefMark*>(&rRef));
+ *pAny <<= xRef;
+ }
+ }
+ else
+ eNewState = PropertyState_DEFAULT_VALUE;
+ }
+ break;
+ case FN_UNO_NESTED_TEXT_CONTENT:
+ {
+ uno::Reference<XTextContent> const xRet(rPam.GetPointNode().IsTextNode()
+ ? GetNestedTextContent(*rPam.GetPointNode().GetTextNode(),
+ rPam.GetPoint()->GetContentIndex(), false)
+ : nullptr);
+ if (xRet.is())
+ {
+ if (pAny)
+ {
+ (*pAny) <<= xRet;
+ }
+ }
+ else
+ {
+ eNewState = PropertyState_DEFAULT_VALUE;
+ }
+ }
+ break;
+ case FN_UNO_CHARFMT_SEQUENCE:
+ {
+
+ SwTextNode *const pTextNode = rPam.GetPointNode().GetTextNode();
+ if (&rPam.GetPointNode() == &rPam.GetMarkNode()
+ && pTextNode && pTextNode->GetpSwpHints())
+ {
+ sal_Int32 nPaMStart = rPam.Start()->GetContentIndex();
+ sal_Int32 nPaMEnd = rPam.End()->GetContentIndex();
+ Sequence< OUString> aCharStyles;
+ SwpHints* pHints = pTextNode->GetpSwpHints();
+ for( size_t nAttr = 0; nAttr < pHints->Count(); ++nAttr )
+ {
+ SwTextAttr* pAttr = pHints->Get( nAttr );
+ if(pAttr->Which() != RES_TXTATR_CHARFMT)
+ continue;
+ const sal_Int32 nAttrStart = pAttr->GetStart();
+ const sal_Int32 nAttrEnd = *pAttr->GetEnd();
+ //check if the attribute touches the selection
+ if( ( nAttrEnd > nPaMStart && nAttrStart < nPaMEnd ) ||
+ ( !nAttrStart && !nAttrEnd && !nPaMStart && !nPaMEnd ) )
+ {
+ //check for overlapping
+ if(nAttrStart > nPaMStart ||
+ nAttrEnd < nPaMEnd)
+ {
+ aCharStyles.realloc(0);
+ break;
+ }
+ else
+ {
+ //now the attribute should start before or at the selection
+ //and it should end at the end of the selection or behind
+ OSL_ENSURE(nAttrStart <= nPaMStart && nAttrEnd >=nPaMEnd,
+ "attribute overlaps or is outside");
+ //now the name of the style has to be added to the sequence
+ aCharStyles.realloc(aCharStyles.getLength() + 1);
+ OSL_ENSURE(pAttr->GetCharFormat().GetCharFormat(), "no character format set");
+ aCharStyles.getArray()[aCharStyles.getLength() - 1] =
+ SwStyleNameMapper::GetProgName(
+ pAttr->GetCharFormat().GetCharFormat()->GetName(), SwGetPoolIdFromName::ChrFmt);
+ }
+ }
+
+ }
+ eNewState =
+ aCharStyles.hasElements() ?
+ PropertyState_DIRECT_VALUE : PropertyState_DEFAULT_VALUE;
+ if(pAny)
+ (*pAny) <<= aCharStyles;
+ }
+ else
+ eNewState = PropertyState_DEFAULT_VALUE;
+ }
+ break;
+ case RES_TXTATR_CHARFMT:
+ // no break here!
+ default: bDone = false;
+ }
+ if( bDone )
+ eState = eNewState;
+ return bDone;
+};
+
+sal_Int16 IsNodeNumStart(SwPaM const & rPam, PropertyState& eState)
+{
+ const SwTextNode* pTextNd = rPam.GetPointNode().GetTextNode();
+ // correction: check, if restart value is set at the text node and use
+ // new method <SwTextNode::GetAttrListRestartValue()> to retrieve the value
+ if ( pTextNd && pTextNd->GetNumRule() && pTextNd->IsListRestart() &&
+ pTextNd->HasAttrListRestartValue() )
+ {
+ eState = PropertyState_DIRECT_VALUE;
+ sal_Int16 nTmp = sal::static_int_cast< sal_Int16 >(pTextNd->GetAttrListRestartValue());
+ return nTmp;
+ }
+ eState = PropertyState_DEFAULT_VALUE;
+ return -1;
+}
+
+void setNumberingProperty(const Any& rValue, SwPaM& rPam)
+{
+ uno::Reference<XIndexReplace> xIndexReplace;
+ if(rValue >>= xIndexReplace)
+ {
+ auto pSwNum = dynamic_cast<SwXNumberingRules*>(xIndexReplace.get());
+ if(pSwNum)
+ {
+ SwDoc& rDoc = rPam.GetDoc();
+ if(pSwNum->GetNumRule())
+ {
+ SwNumRule aRule(*pSwNum->GetNumRule());
+ const OUString* pNewCharStyles = pSwNum->GetNewCharStyleNames();
+ const OUString* pBulletFontNames = pSwNum->GetBulletFontNames();
+ for(sal_uInt16 i = 0; i < MAXLEVEL; i++)
+ {
+ SwNumFormat aFormat(aRule.Get( i ));
+ if (!pNewCharStyles[i].isEmpty() &&
+ !SwXNumberingRules::isInvalidStyle(pNewCharStyles[i]) &&
+ (!aFormat.GetCharFormat() || pNewCharStyles[i] != aFormat.GetCharFormat()->GetName()))
+ {
+ if (pNewCharStyles[i].isEmpty())
+ {
+ // FIXME
+ // Is something missing/wrong here?
+ // if condition is always false due to outer check!
+ aFormat.SetCharFormat(nullptr);
+ }
+ else
+ {
+
+ // get CharStyle and set the rule
+ const size_t nChCount = rDoc.GetCharFormats()->size();
+ SwCharFormat* pCharFormat = nullptr;
+ for(size_t nCharFormat = 0; nCharFormat < nChCount; ++nCharFormat)
+ {
+ SwCharFormat& rChFormat = *((*(rDoc.GetCharFormats()))[nCharFormat]);
+ if(rChFormat.GetName() == pNewCharStyles[i])
+ {
+ pCharFormat = &rChFormat;
+ break;
+ }
+ }
+
+ if(!pCharFormat)
+ {
+ SfxStyleSheetBasePool* pPool = rDoc.GetDocShell()->GetStyleSheetPool();
+ SfxStyleSheetBase* pBase;
+ pBase = pPool->Find(pNewCharStyles[i], SfxStyleFamily::Char);
+ // shall it really be created?
+ if(!pBase)
+ pBase = &pPool->Make(pNewCharStyles[i], SfxStyleFamily::Page);
+ pCharFormat = static_cast<SwDocStyleSheet*>(pBase)->GetCharFormat();
+ }
+ if(pCharFormat)
+ aFormat.SetCharFormat(pCharFormat);
+ }
+ }
+ //Now again for fonts
+ if(
+ !pBulletFontNames[i].isEmpty() &&
+ !SwXNumberingRules::isInvalidStyle(pBulletFontNames[i]) &&
+ (!aFormat.GetBulletFont() || aFormat.GetBulletFont()->GetFamilyName() != pBulletFontNames[i])
+ )
+ {
+ const SvxFontListItem* pFontListItem =
+ static_cast<const SvxFontListItem* >(rDoc.GetDocShell()
+ ->GetItem( SID_ATTR_CHAR_FONTLIST ));
+ const FontList* pList = pFontListItem->GetFontList();
+
+ vcl::Font aFont(pList->Get(
+ pBulletFontNames[i],WEIGHT_NORMAL, ITALIC_NONE));
+ aFormat.SetBulletFont(&aFont);
+ }
+ aRule.Set( i, aFormat );
+ }
+ UnoActionContext aAction(&rDoc);
+
+ if( rPam.GetNext() != &rPam ) // Multiple selection?
+ {
+ rDoc.GetIDocumentUndoRedo().StartUndo( SwUndoId::START, nullptr );
+ SwPamRanges aRangeArr( rPam );
+ SwPaM aPam( *rPam.GetPoint() );
+ for ( size_t n = 0; n < aRangeArr.Count(); ++n )
+ {
+ // no start of a new list
+ rDoc.SetNumRule( aRangeArr.SetPam( n, aPam ), aRule, false );
+ }
+ rDoc.GetIDocumentUndoRedo().EndUndo( SwUndoId::END, nullptr );
+ }
+ else
+ {
+ // no start of a new list
+ rDoc.SetNumRule( rPam, aRule, false );
+ }
+
+ }
+ else if(!pSwNum->GetCreatedNumRuleName().isEmpty())
+ {
+ UnoActionContext aAction( &rDoc );
+ SwNumRule* pRule = rDoc.FindNumRulePtr( pSwNum->GetCreatedNumRuleName() );
+ if ( !pRule )
+ throw RuntimeException();
+ // no start of a new list
+ rDoc.SetNumRule( rPam, *pRule, false );
+ }
+ else
+ {
+ // #i103817#
+ // outline numbering
+ UnoActionContext aAction(&rDoc);
+ SwNumRule* pRule = rDoc.GetOutlineNumRule();
+ if(!pRule)
+ throw RuntimeException();
+ rDoc.SetNumRule( rPam, *pRule, false );
+ }
+ }
+ }
+ else if ( rValue.getValueType() == cppu::UnoType<void>::get() )
+ {
+ rPam.GetDoc().DelNumRules(rPam);
+ }
+}
+
+void getNumberingProperty(SwPaM& rPam, PropertyState& eState, Any * pAny )
+{
+ const SwNumRule* pNumRule = SwDoc::GetNumRuleAtPos( *rPam.GetPoint() );
+ if(pNumRule)
+ {
+ uno::Reference< XIndexReplace > xNum = new SwXNumberingRules(*pNumRule);
+ if ( pAny )
+ *pAny <<= xNum;
+ eState = PropertyState_DIRECT_VALUE;
+ }
+ else
+ eState = PropertyState_DEFAULT_VALUE;
+}
+
+void GetCurPageStyle(SwPaM const & rPaM, OUString &rString)
+{
+ if (!rPaM.GetPointContentNode())
+ return; // TODO: is there an easy way to get it for tables/sections?
+ SwRootFrame* pLayout = rPaM.GetDoc().getIDocumentLayoutAccess().GetCurrentLayout();
+ // Consider the position inside the content node, since the node may span over multiple pages
+ // with different page styles.
+ SwContentFrame* pFrame = rPaM.GetPointContentNode()->getLayoutFrame(pLayout, rPaM.GetPoint());
+ if(pFrame)
+ {
+ const SwPageFrame* pPage = pFrame->FindPageFrame();
+ if(pPage)
+ {
+ SwStyleNameMapper::FillProgName(pPage->GetPageDesc()->GetName(),
+ rString, SwGetPoolIdFromName::PageDesc);
+ }
+ }
+}
+
+// reset special properties of the cursor
+void resetCursorPropertyValue(const SfxItemPropertyMapEntry& rEntry, SwPaM& rPam)
+{
+ SwDoc& rDoc = rPam.GetDoc();
+ switch(rEntry.nWID)
+ {
+ case FN_UNO_PARA_STYLE :
+ break;
+ case FN_UNO_PAGE_STYLE :
+ break;
+ case FN_UNO_NUM_START_VALUE :
+ {
+ UnoActionContext aAction(&rDoc);
+
+ if( rPam.GetNext() != &rPam ) // Multiple selection?
+ {
+ rDoc.GetIDocumentUndoRedo().StartUndo( SwUndoId::START, nullptr );
+ SwPamRanges aRangeArr( rPam );
+ SwPaM aPam( *rPam.GetPoint() );
+ for( size_t n = 0; n < aRangeArr.Count(); ++n )
+ rDoc.SetNodeNumStart( *aRangeArr.SetPam( n, aPam ).GetPoint(), 1 );
+ rDoc.GetIDocumentUndoRedo().EndUndo( SwUndoId::END, nullptr );
+ }
+ else
+ rDoc.SetNodeNumStart( *rPam.GetPoint(), 0 );
+ }
+
+ break;
+ case FN_UNO_NUM_LEVEL :
+ break;
+ case FN_UNO_NUM_RULES:
+ break;
+ case FN_UNO_CHARFMT_SEQUENCE:
+ {
+ rDoc.ResetAttrs(rPam, true, { RES_TXTATR_CHARFMT });
+ }
+ break;
+ }
+}
+
+void InsertFile(SwUnoCursor* pUnoCursor, const OUString& rURL,
+ const uno::Sequence< beans::PropertyValue >& rOptions)
+{
+ if (SwTextNode const*const pTextNode = pUnoCursor->GetPoint()->GetNode().GetTextNode())
+ {
+ // TODO: check meta field here too in case it ever grows a 2nd char
+ if (pTextNode->GetTextAttrAt(pUnoCursor->GetPoint()->GetContentIndex(),
+ RES_TXTATR_INPUTFIELD, ::sw::GetTextAttrMode::Parent))
+ {
+ throw uno::RuntimeException("cannot insert file inside input field");
+ }
+
+ if (pTextNode->GetTextAttrAt(pUnoCursor->GetPoint()->GetContentIndex(),
+ RES_TXTATR_CONTENTCONTROL, ::sw::GetTextAttrMode::Parent))
+ {
+ throw uno::RuntimeException("cannot insert file inside content controls");
+ }
+ }
+
+ std::unique_ptr<SfxMedium> pMed;
+ SwDoc& rDoc = pUnoCursor->GetDoc();
+ SwDocShell* pDocSh = rDoc.GetDocShell();
+ utl::MediaDescriptor aMediaDescriptor( rOptions );
+ OUString sFileName = rURL;
+ OUString sFilterName, sFilterOptions, sPassword, sBaseURL;
+ uno::Reference < io::XStream > xStream;
+ uno::Reference < io::XInputStream > xInputStream;
+
+ if( sFileName.isEmpty() )
+ aMediaDescriptor[utl::MediaDescriptor::PROP_URL] >>= sFileName;
+ if( sFileName.isEmpty() )
+ aMediaDescriptor[utl::MediaDescriptor::PROP_FILENAME] >>= sFileName;
+ aMediaDescriptor[utl::MediaDescriptor::PROP_INPUTSTREAM] >>= xInputStream;
+ aMediaDescriptor[utl::MediaDescriptor::PROP_STREAM] >>= xStream;
+ aMediaDescriptor[utl::MediaDescriptor::PROP_INPUTSTREAM] >>= xInputStream;
+ aMediaDescriptor[utl::MediaDescriptor::PROP_FILTERNAME] >>= sFilterName;
+ aMediaDescriptor[utl::MediaDescriptor::PROP_FILTEROPTIONS] >>= sFilterOptions;
+ aMediaDescriptor[utl::MediaDescriptor::PROP_PASSWORD] >>= sPassword;
+ aMediaDescriptor[utl::MediaDescriptor::PROP_DOCUMENTBASEURL ] >>= sBaseURL;
+ if ( !xInputStream.is() && xStream.is() )
+ xInputStream = xStream->getInputStream();
+
+ if(!pDocSh || (sFileName.isEmpty() && !xInputStream.is()))
+ return;
+
+ SfxObjectFactory& rFact = pDocSh->GetFactory();
+ std::shared_ptr<const SfxFilter> pFilter = rFact.GetFilterContainer()->GetFilter4FilterName( sFilterName );
+ uno::Reference < embed::XStorage > xReadStorage;
+ if( xInputStream.is() )
+ {
+ uno::Sequence< uno::Any > aArgs{ uno::Any(xInputStream),
+ uno::Any(embed::ElementModes::READ) };
+ try
+ {
+ xReadStorage.set( ::comphelper::OStorageHelper::GetStorageFactory()->createInstanceWithArguments( aArgs ),
+ uno::UNO_QUERY );
+ }
+ catch( const io::IOException&) {}
+ }
+ if ( !pFilter )
+ {
+ if( xInputStream.is() && !xReadStorage.is())
+ {
+ pMed.reset(new SfxMedium);
+ pMed->setStreamToLoadFrom(xInputStream, true );
+ }
+ else
+ pMed.reset(xReadStorage.is() ?
+ new SfxMedium(xReadStorage, sBaseURL ) :
+ new SfxMedium(sFileName, StreamMode::READ ));
+ if( !sBaseURL.isEmpty() )
+ pMed->GetItemSet().Put( SfxStringItem( SID_DOC_BASEURL, sBaseURL ) );
+
+ SfxFilterMatcher aMatcher( rFact.GetFilterContainer()->GetName() );
+ ErrCode nErr = aMatcher.GuessFilter(*pMed, pFilter, SfxFilterFlags::NONE);
+ if ( nErr || !pFilter)
+ return;
+ pMed->SetFilter( pFilter );
+ }
+ else
+ {
+ if( xInputStream.is() && !xReadStorage.is())
+ {
+ pMed.reset(new SfxMedium);
+ pMed->setStreamToLoadFrom(xInputStream, true );
+ pMed->SetFilter( pFilter );
+ }
+ else
+ {
+ if( xReadStorage.is() )
+ {
+ pMed.reset(new SfxMedium(xReadStorage, sBaseURL ));
+ pMed->SetFilter( pFilter );
+ }
+ else
+ pMed.reset(new SfxMedium(sFileName, StreamMode::READ, pFilter, nullptr));
+ }
+ if(!sFilterOptions.isEmpty())
+ pMed->GetItemSet().Put( SfxStringItem( SID_FILE_FILTEROPTIONS, sFilterOptions ) );
+ if(!sBaseURL.isEmpty())
+ pMed->GetItemSet().Put( SfxStringItem( SID_DOC_BASEURL, sBaseURL ) );
+ }
+
+ // this sourcecode is not responsible for the lifetime of the shell, SfxObjectShellLock should not be used
+ SfxObjectShellRef aRef( pDocSh );
+
+ pMed->Download(); // if necessary: start the download
+ if( !(aRef.is() && 1 < aRef->GetRefCount()) ) // Ref still valid?
+ return;
+
+ SwReaderPtr pRdr;
+ SfxItemSet& rSet = pMed->GetItemSet();
+ rSet.Put(SfxBoolItem(FN_API_CALL, true));
+ if(!sPassword.isEmpty())
+ rSet.Put(SfxStringItem(SID_PASSWORD, sPassword));
+ Reader *pRead = pDocSh->StartConvertFrom( *pMed, pRdr, nullptr, pUnoCursor);
+ if( !pRead )
+ return;
+
+ UnoActionContext aContext(&rDoc);
+
+ if(pUnoCursor->HasMark())
+ rDoc.getIDocumentContentOperations().DeleteAndJoin(*pUnoCursor);
+
+ SwNodeIndex aSave( pUnoCursor->GetPoint()->GetNode(), -1 );
+ sal_Int32 nContent = pUnoCursor->GetPoint()->GetContentIndex();
+
+ ErrCodeMsg nErrno = pRdr->Read( *pRead ); // and paste the document
+
+ if(!nErrno)
+ {
+ ++aSave;
+ pUnoCursor->SetMark();
+ pUnoCursor->GetMark()->Assign( aSave );
+
+ SwContentNode* pCntNode = aSave.GetNode().GetContentNode();
+ if( !pCntNode )
+ nContent = 0;
+ pUnoCursor->GetMark()->SetContent( nContent );
+ }
+}
+
+// insert text and scan for CR characters in order to insert
+// paragraph breaks at those positions by calling SplitNode
+bool DocInsertStringSplitCR(
+ SwDoc &rDoc,
+ const SwPaM &rNewCursor,
+ std::u16string_view rText,
+ const bool bForceExpandHints )
+{
+ bool bOK = true;
+
+ for (size_t i = 0; i < rText.size(); ++i)
+ {
+ sal_Unicode const ch(rText[i]);
+ if (linguistic::IsControlChar(ch)
+ && ch != '\r' && ch != '\n' && ch != '\t')
+ {
+ SAL_WARN("sw.uno", "DocInsertStringSplitCR: refusing to insert control character " << int(ch));
+ return false;
+ }
+ }
+
+ const SwInsertFlags nInsertFlags =
+ bForceExpandHints
+ ? ( SwInsertFlags::FORCEHINTEXPAND | SwInsertFlags::EMPTYEXPAND)
+ : SwInsertFlags::EMPTYEXPAND;
+
+ // grouping done in InsertString is intended for typing, not API calls
+ ::sw::GroupUndoGuard const undoGuard(rDoc.GetIDocumentUndoRedo());
+ SwTextNode* const pTextNd =
+ rNewCursor.GetPoint()->GetNode().GetTextNode();
+ if (!pTextNd)
+ {
+ SAL_INFO("sw.uno", "DocInsertStringSplitCR: need a text node");
+ return false;
+ }
+ OUString aText;
+ sal_Int32 nStartIdx = 0;
+ const sal_Int32 nMaxLength = COMPLETE_STRING - pTextNd->GetText().getLength();
+
+ size_t nIdx = rText.find( '\r', nStartIdx );
+ if( ( nIdx == std::u16string_view::npos && nMaxLength < sal_Int32(rText.size()) ) ||
+ ( nIdx != std::u16string_view::npos && nMaxLength < sal_Int32(nIdx) ) )
+ {
+ nIdx = nMaxLength;
+ }
+ while (nIdx != std::u16string_view::npos )
+ {
+ OSL_ENSURE( sal_Int32(nIdx) - nStartIdx >= 0, "index negative!" );
+ aText = rText.substr( nStartIdx, nIdx - nStartIdx );
+ if (!aText.isEmpty() &&
+ !rDoc.getIDocumentContentOperations().InsertString( rNewCursor, aText, nInsertFlags ))
+ {
+ OSL_FAIL( "Doc->Insert(Str) failed." );
+ bOK = false;
+ }
+ if (!rDoc.getIDocumentContentOperations().SplitNode( *rNewCursor.GetPoint(), false ) )
+ {
+ OSL_FAIL( "SplitNode failed" );
+ bOK = false;
+ }
+ nStartIdx = nIdx + 1;
+ nIdx = rText.find( '\r', nStartIdx );
+ }
+ aText = rText.substr( nStartIdx );
+ if (!aText.isEmpty() &&
+ !rDoc.getIDocumentContentOperations().InsertString( rNewCursor, aText, nInsertFlags ))
+ {
+ OSL_FAIL( "Doc->Insert(Str) failed." );
+ bOK = false;
+ }
+
+ return bOK;
+}
+
+void makeRedline( SwPaM const & rPaM,
+ std::u16string_view rRedlineType,
+ const uno::Sequence< beans::PropertyValue >& rRedlineProperties )
+{
+ IDocumentRedlineAccess& rRedlineAccess = rPaM.GetDoc().getIDocumentRedlineAccess();
+
+ RedlineType eType;
+ if ( rRedlineType == u"Insert" )
+ eType = RedlineType::Insert;
+ else if ( rRedlineType == u"Delete" )
+ eType = RedlineType::Delete;
+ else if ( rRedlineType == u"Format" )
+ eType = RedlineType::Format;
+ else if ( rRedlineType == u"TextTable" )
+ eType = RedlineType::Table;
+ else if ( rRedlineType == u"ParagraphFormat" )
+ eType = RedlineType::ParagraphFormat;
+ else
+ throw lang::IllegalArgumentException();
+
+ //todo: what about REDLINE_FMTCOLL?
+ std::size_t nAuthor = 0;
+ OUString sAuthor;
+ OUString sComment;
+ ::util::DateTime aStamp;
+ uno::Sequence< beans::PropertyValue > aRevertProperties;
+ sal_uInt32 nMovedID = 0;
+ bool bFoundComment = false;
+ bool bFoundStamp = false;
+ bool bFoundRevertProperties = false;
+ for (const css::beans::PropertyValue & rProp : rRedlineProperties )
+ {
+ if (rProp.Name == "RedlineAuthor")
+ {
+ if( rProp.Value >>= sAuthor )
+ nAuthor = rRedlineAccess.InsertRedlineAuthor(sAuthor);
+ }
+ else if (rProp.Name == "RedlineComment")
+ bFoundComment = rProp.Value >>= sComment;
+ else if (rProp.Name == "RedlineDateTime")
+ bFoundStamp = rProp.Value >>= aStamp;
+ else if (rProp.Name == "RedlineRevertProperties")
+ bFoundRevertProperties = rProp.Value >>= aRevertProperties;
+ else if (rProp.Name == "RedlineMoved")
+ rProp.Value >>= nMovedID;
+ }
+
+ SwRedlineData aRedlineData( eType, nAuthor );
+ if( bFoundComment )
+ aRedlineData.SetComment( sComment );
+ if( bFoundStamp )
+ aRedlineData.SetTimeStamp( DateTime( aStamp));
+
+ std::unique_ptr<SwRedlineExtraData_FormatColl> xRedlineExtraData;
+
+ // Read the 'Redline Revert Properties' from the parameters
+ // Check if the value exists
+ if ( bFoundRevertProperties )
+ {
+ int nMap = 0;
+ // Make sure that paragraph format gets its own map, otherwise e.g. fill attributes are not preserved.
+ if (eType == RedlineType::ParagraphFormat)
+ {
+ nMap = PROPERTY_MAP_PARAGRAPH;
+ if (!aRevertProperties.hasElements())
+ {
+ // to reject the paragraph style change, use standard style
+ xRedlineExtraData.reset(new SwRedlineExtraData_FormatColl( "", RES_POOLCOLL_STANDARD, nullptr ));
+ }
+ }
+ else
+ nMap = PROPERTY_MAP_TEXTPORTION_EXTENSIONS;
+ SfxItemPropertySet const& rPropSet = *aSwMapProvider.GetPropertySet(nMap);
+
+ // Check if there are any properties
+ if (aRevertProperties.hasElements())
+ {
+ SwDoc& rDoc = rPaM.GetDoc();
+
+ // Build set of attributes we want to fetch
+ WhichRangesContainer aWhichPairs;
+ std::vector<SfxItemPropertyMapEntry const*> aEntries;
+ std::vector<uno::Any> aValues;
+ aEntries.reserve(aRevertProperties.getLength());
+ sal_uInt16 nStyleId = USHRT_MAX;
+ sal_uInt16 nNumId = USHRT_MAX;
+ for (const auto& rRevertProperty : std::as_const(aRevertProperties))
+ {
+ const OUString &rPropertyName = rRevertProperty.Name;
+ SfxItemPropertyMapEntry const* pEntry = rPropSet.getPropertyMap().getByName(rPropertyName);
+
+ if (!pEntry)
+ {
+ // unknown property
+ break;
+ }
+ else if (pEntry->nFlags & beans::PropertyAttribute::READONLY)
+ {
+ break;
+ }
+ else if (rPropertyName == "NumberingRules")
+ {
+ aWhichPairs = aWhichPairs.MergeRange(RES_PARATR_NUMRULE, RES_PARATR_NUMRULE);
+ nNumId = aEntries.size();
+ }
+ else
+ {
+ aWhichPairs = aWhichPairs.MergeRange(pEntry->nWID, pEntry->nWID);
+ if (rPropertyName == "ParaStyleName")
+ nStyleId = aEntries.size();
+ }
+ aEntries.push_back(pEntry);
+ aValues.push_back(rRevertProperty.Value);
+ }
+
+ if (!aWhichPairs.empty())
+ {
+ sal_uInt16 nStylePoolId = USHRT_MAX;
+ OUString sParaStyleName, sUIStyle;
+ SfxItemSet aItemSet(rDoc.GetAttrPool(), std::move(aWhichPairs));
+
+ for (size_t i = 0; i < aEntries.size(); ++i)
+ {
+ const uno::Any &rValue = aValues[i];
+ if (i == nNumId)
+ {
+ uno::Reference<container::XNamed> xNumberingRules;
+ rValue >>= xNumberingRules;
+ if (xNumberingRules.is())
+ {
+ aItemSet.Put( SwNumRuleItem( xNumberingRules->getName() ));
+ // keep it during export
+ SwNumRule* pRule = rDoc.FindNumRulePtr(
+ xNumberingRules->getName());
+ if (pRule)
+ pRule->SetUsedByRedline(true);
+ }
+ }
+ else
+ {
+ SfxItemPropertyMapEntry const*const pEntry = aEntries[i];
+ rPropSet.setPropertyValue(*pEntry, rValue, aItemSet);
+ if (i == nStyleId)
+ rValue >>= sParaStyleName;
+ }
+ }
+
+ if (eType == RedlineType::ParagraphFormat && sParaStyleName.isEmpty())
+ nStylePoolId = RES_POOLCOLL_STANDARD;
+
+ // tdf#149747 Get UI style name from programmatic style name
+ SwStyleNameMapper::FillUIName(sParaStyleName, sUIStyle,
+ SwGetPoolIdFromName::TxtColl);
+ xRedlineExtraData.reset(new SwRedlineExtraData_FormatColl(
+ sUIStyle.isEmpty() ? sParaStyleName : sUIStyle, nStylePoolId, &aItemSet));
+ }
+ else if (eType == RedlineType::ParagraphFormat)
+ xRedlineExtraData.reset(new SwRedlineExtraData_FormatColl( "", RES_POOLCOLL_STANDARD, nullptr ));
+ }
+ }
+
+ SwRangeRedline* pRedline = new SwRangeRedline( aRedlineData, rPaM );
+
+ // set IsMoved bit of the redline to show and handle moved text
+ if ( nMovedID > 0 )
+ {
+ pRedline->SetMoved( nMovedID );
+ rRedlineAccess.GetRedlineTable().setMovedIDIfNeeded(nMovedID);
+ }
+
+ RedlineFlags nPrevMode = rRedlineAccess.GetRedlineFlags( );
+ // xRedlineExtraData is copied here
+ pRedline->SetExtraData( xRedlineExtraData.get() );
+
+ rRedlineAccess.SetRedlineFlags_intern(RedlineFlags::On);
+ auto const result(rRedlineAccess.AppendRedline(pRedline, false));
+ rRedlineAccess.SetRedlineFlags_intern( nPrevMode );
+ if (IDocumentRedlineAccess::AppendResult::IGNORED == result)
+ throw lang::IllegalArgumentException();
+}
+
+void makeTableRowRedline( SwTableLine& rTableLine,
+ std::u16string_view rRedlineType,
+ const uno::Sequence< beans::PropertyValue >& rRedlineProperties )
+{
+ SwDoc* pDoc = rTableLine.GetFrameFormat()->GetDoc();
+ IDocumentRedlineAccess* pRedlineAccess = &pDoc->getIDocumentRedlineAccess();
+
+ RedlineType eType;
+ if ( rRedlineType == u"TableRowInsert" )
+ {
+ eType = RedlineType::TableRowInsert;
+ }
+ else if ( rRedlineType == u"TableRowDelete" )
+ {
+ eType = RedlineType::TableRowDelete;
+ }
+ else
+ {
+ throw lang::IllegalArgumentException();
+ }
+
+ // set table row property "HasTextChangesOnly" to false
+ // to handle tracked deletion or insertion of the table row on the UI
+ const SvxPrintItem *pHasTextChangesOnlyProp =
+ rTableLine.GetFrameFormat()->GetAttrSet().GetItem<SvxPrintItem>(RES_PRINT);
+ if ( !pHasTextChangesOnlyProp || pHasTextChangesOnlyProp->GetValue() )
+ {
+ SvxPrintItem aSetTracking(RES_PRINT, false);
+ SwNodeIndex aInsPos( *(rTableLine.GetTabBoxes()[0]->GetSttNd()), 1 );
+ // as a workaround for the rows without text content,
+ // add a redline with invisible text CH_TXT_TRACKED_DUMMY_CHAR
+ if ( rTableLine.IsEmpty() )
+ {
+ SwPaM aPaM(aInsPos);
+ pDoc->getIDocumentContentOperations().InsertString( aPaM,
+ OUStringChar(CH_TXT_TRACKED_DUMMY_CHAR) );
+ aPaM.SetMark();
+ aPaM.GetMark()->SetContent(0);
+ makeRedline(aPaM, RedlineType::TableRowInsert == eType
+ ? u"Insert"
+ : u"Delete", rRedlineProperties);
+ }
+ SwCursor aCursor( SwPosition(aInsPos), nullptr );
+ pDoc->SetRowNotTracked( aCursor, aSetTracking );
+ }
+
+ comphelper::SequenceAsHashMap aPropMap( rRedlineProperties );
+ std::size_t nAuthor = 0;
+ OUString sAuthor;
+ if( aPropMap.getValue("RedlineAuthor") >>= sAuthor )
+ nAuthor = pRedlineAccess->InsertRedlineAuthor(sAuthor);
+
+ OUString sComment;
+ SwRedlineData aRedlineData( eType, nAuthor );
+ if( aPropMap.getValue("RedlineComment") >>= sComment )
+ aRedlineData.SetComment( sComment );
+
+ ::util::DateTime aStamp;
+ if( aPropMap.getValue("RedlineDateTime") >>= aStamp )
+ {
+ aRedlineData.SetTimeStamp(
+ DateTime( Date( aStamp.Day, aStamp.Month, aStamp.Year ), tools::Time( aStamp.Hours, aStamp.Minutes, aStamp.Seconds ) ) );
+ }
+
+ SwTableRowRedline* pRedline = new SwTableRowRedline( aRedlineData, rTableLine );
+ RedlineFlags nPrevMode = pRedlineAccess->GetRedlineFlags( );
+ pRedline->SetExtraData( nullptr );
+
+ pRedlineAccess->SetRedlineFlags_intern(RedlineFlags::On);
+ bool bRet = pRedlineAccess->AppendTableRowRedline( pRedline );
+ pRedlineAccess->SetRedlineFlags_intern( nPrevMode );
+ if( !bRet )
+ throw lang::IllegalArgumentException();
+}
+
+void makeTableCellRedline( SwTableBox& rTableBox,
+ std::u16string_view rRedlineType,
+ const uno::Sequence< beans::PropertyValue >& rRedlineProperties )
+{
+ SwDoc* pDoc = rTableBox.GetFrameFormat()->GetDoc();
+ IDocumentRedlineAccess* pRedlineAccess = &pDoc->getIDocumentRedlineAccess();
+
+ RedlineType eType;
+ if ( rRedlineType == u"TableCellInsert" )
+ {
+ eType = RedlineType::TableCellInsert;
+ }
+ else if ( rRedlineType == u"TableCellDelete" )
+ {
+ eType = RedlineType::TableCellDelete;
+ }
+ else
+ {
+ throw lang::IllegalArgumentException();
+ }
+
+ // set table row property "HasTextChangesOnly" to false
+ // to handle tracked deletion or insertion of the table row on the UI
+ const SvxPrintItem *pHasTextChangesOnlyProp =
+ rTableBox.GetFrameFormat()->GetAttrSet().GetItem<SvxPrintItem>(RES_PRINT);
+ if ( !pHasTextChangesOnlyProp || pHasTextChangesOnlyProp->GetValue() )
+ {
+ SvxPrintItem aSetTracking(RES_PRINT, false);
+ SwNodeIndex aInsPos( *rTableBox.GetSttNd(), 1 );
+ // as a workaround for the cells without text content,
+ // add a redline with invisible text CH_TXT_TRACKED_DUMMY_CHAR
+ if ( rTableBox.IsEmpty() )
+ {
+ SwPaM aPaM(aInsPos);
+ pDoc->getIDocumentContentOperations().InsertString( aPaM,
+ OUStringChar(CH_TXT_TRACKED_DUMMY_CHAR) );
+ aPaM.SetMark();
+ aPaM.GetMark()->SetContent(0);
+ makeRedline(aPaM, RedlineType::TableCellInsert == eType
+ ? u"Insert"
+ : u"Delete", rRedlineProperties);
+ }
+ SwCursor aCursor( SwPosition(aInsPos), nullptr );
+ pDoc->SetBoxAttr( aCursor, aSetTracking );
+ }
+
+ comphelper::SequenceAsHashMap aPropMap( rRedlineProperties );
+ std::size_t nAuthor = 0;
+ OUString sAuthor;
+ if( aPropMap.getValue("RedlineAuthor") >>= sAuthor )
+ nAuthor = pRedlineAccess->InsertRedlineAuthor(sAuthor);
+
+ OUString sComment;
+ SwRedlineData aRedlineData( eType, nAuthor );
+ if( aPropMap.getValue("RedlineComment") >>= sComment )
+ aRedlineData.SetComment( sComment );
+
+ ::util::DateTime aStamp;
+ if( aPropMap.getValue("RedlineDateTime") >>= aStamp )
+ {
+ aRedlineData.SetTimeStamp(
+ DateTime( Date( aStamp.Day, aStamp.Month, aStamp.Year ), tools::Time( aStamp.Hours, aStamp.Minutes, aStamp.Seconds ) ) );
+ }
+
+ SwTableCellRedline* pRedline = new SwTableCellRedline( aRedlineData, rTableBox );
+ RedlineFlags nPrevMode = pRedlineAccess->GetRedlineFlags( );
+ pRedline->SetExtraData( nullptr );
+
+ pRedlineAccess->SetRedlineFlags_intern(RedlineFlags::On);
+ bool bRet = pRedlineAccess->AppendTableCellRedline( pRedline );
+ pRedlineAccess->SetRedlineFlags_intern( nPrevMode );
+ if( !bRet )
+ throw lang::IllegalArgumentException();
+}
+
+void SwAnyMapHelper::SetValue( sal_uInt16 nWhichId, sal_uInt16 nMemberId, const uno::Any& rAny )
+{
+ sal_uInt32 nKey = (nWhichId << 16) + nMemberId;
+ m_Map[nKey] = rAny;
+}
+
+bool SwAnyMapHelper::FillValue( sal_uInt16 nWhichId, sal_uInt16 nMemberId, const uno::Any*& pAny )
+{
+ bool bRet = false;
+ sal_uInt32 nKey = (nWhichId << 16) + nMemberId;
+ auto aIt = m_Map.find( nKey );
+ if (aIt != m_Map.end())
+ {
+ pAny = & aIt->second;
+ bRet = true;
+ }
+ return bRet;
+}
+
+}//namespace SwUnoCursorHelper
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/core/unocore/unodraw.cxx b/sw/source/core/unocore/unodraw.cxx
new file mode 100644
index 0000000000..5bb5621d95
--- /dev/null
+++ b/sw/source/core/unocore/unodraw.cxx
@@ -0,0 +1,2876 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <sal/config.h>
+
+#include <initializer_list>
+#include <memory>
+#include <string_view>
+
+#include <sal/log.hxx>
+
+#include <cmdid.h>
+#include <unomid.h>
+
+#include <drawdoc.hxx>
+#include <unodraw.hxx>
+#include <unoframe.hxx>
+#include <unoparagraph.hxx>
+#include <unotextrange.hxx>
+#include <svx/svditer.hxx>
+#include <swunohelper.hxx>
+#include <textboxhelper.hxx>
+#include <doc.hxx>
+#include <IDocumentUndoRedo.hxx>
+#include <IDocumentDrawModelAccess.hxx>
+#include <IDocumentLayoutAccess.hxx>
+#include <fmtcntnt.hxx>
+#include <fmtflcnt.hxx>
+#include <txatbase.hxx>
+#include <docsh.hxx>
+#include <unomap.hxx>
+#include <unoport.hxx>
+#include <TextCursorHelper.hxx>
+#include <dflyobj.hxx>
+#include <ndtxt.hxx>
+#include <svx/svdview.hxx>
+#include <svx/unoshape.hxx>
+#include <dcontact.hxx>
+#include <fmtornt.hxx>
+#include <fmtsrnd.hxx>
+#include <fmtfollowtextflow.hxx>
+#include <rootfrm.hxx>
+#include <editeng/lrspitem.hxx>
+#include <editeng/ulspitem.hxx>
+#include <o3tl/any.hxx>
+#include <o3tl/safeint.hxx>
+#include <crstate.hxx>
+#include <comphelper/extract.hxx>
+#include <comphelper/profilezone.hxx>
+#include <comphelper/sequence.hxx>
+#include <cppuhelper/supportsservice.hxx>
+#include <svx/scene3d.hxx>
+#include <tools/UnitConversion.hxx>
+#include <com/sun/star/beans/PropertyAttribute.hpp>
+#include <com/sun/star/drawing/XDrawPageSupplier.hpp>
+#include <com/sun/star/frame/XModel.hpp>
+#include <fmtwrapinfluenceonobjpos.hxx>
+#include <com/sun/star/text/TextContentAnchorType.hpp>
+#include <basegfx/matrix/b2dhommatrixtools.hxx>
+#include <com/sun/star/drawing/PointSequence.hpp>
+#include <com/sun/star/lang/IllegalArgumentException.hpp>
+#include <com/sun/star/lang/IndexOutOfBoundsException.hpp>
+#include <docmodel/uno/UnoTheme.hxx>
+
+using namespace ::com::sun::star;
+
+class SwShapeDescriptor_Impl
+{
+ bool m_isInReading;
+ std::unique_ptr<SwFormatHoriOrient> m_pHOrient;
+ std::unique_ptr<SwFormatVertOrient> m_pVOrient;
+ std::unique_ptr<SwFormatAnchor> m_pAnchor;
+ std::unique_ptr<SwFormatSurround> m_pSurround;
+ std::unique_ptr<SvxULSpaceItem> m_pULSpace;
+ std::unique_ptr<SvxLRSpaceItem> m_pLRSpace;
+ bool m_bOpaque;
+ uno::Reference< text::XTextRange > m_xTextRange;
+ // #i26791#
+ std::unique_ptr<SwFormatFollowTextFlow> m_pFollowTextFlow;
+ // #i28701#
+ std::unique_ptr<SwFormatWrapInfluenceOnObjPos> m_pWrapInfluenceOnObjPos;
+ // #i28749#
+ sal_Int16 mnPositionLayoutDir;
+
+ SwShapeDescriptor_Impl(const SwShapeDescriptor_Impl&) = delete;
+ SwShapeDescriptor_Impl& operator=(const SwShapeDescriptor_Impl&) = delete;
+
+public:
+ SwShapeDescriptor_Impl(SwDoc const*const pDoc)
+ : m_isInReading(pDoc && pDoc->IsInReading())
+ // #i32349# - no defaults, in order to determine on
+ // adding a shape, if positioning attributes are set or not.
+ , m_bOpaque(false)
+ // #i26791#
+ , m_pFollowTextFlow( new SwFormatFollowTextFlow(false) )
+ // #i28701# #i35017#
+ , m_pWrapInfluenceOnObjPos( new SwFormatWrapInfluenceOnObjPos(
+ text::WrapInfluenceOnPosition::ONCE_CONCURRENT) )
+ // #i28749#
+ , mnPositionLayoutDir(text::PositionLayoutDir::PositionInLayoutDirOfAnchor)
+ {}
+
+ SwFormatAnchor* GetAnchor(bool bCreate = false)
+ {
+ if (bCreate && !m_pAnchor)
+ {
+ m_pAnchor.reset(new SwFormatAnchor(RndStdIds::FLY_AS_CHAR));
+ }
+ return m_pAnchor.get();
+ }
+ SwFormatHoriOrient* GetHOrient(bool bCreate = false)
+ {
+ if (bCreate && !m_pHOrient)
+ {
+ // #i26791#
+ m_pHOrient.reset(new SwFormatHoriOrient(0, text::HoriOrientation::NONE, text::RelOrientation::FRAME));
+ }
+ return m_pHOrient.get();
+ }
+ SwFormatVertOrient* GetVOrient(bool bCreate = false)
+ {
+ if (bCreate && !m_pVOrient)
+ {
+ if (m_isInReading && // tdf#113938 extensions might rely on old default
+ (!GetAnchor(true) || m_pAnchor->GetAnchorId() == RndStdIds::FLY_AS_CHAR))
+ { // for as-char, NONE ("from-top") is not a good default
+ m_pVOrient.reset(new SwFormatVertOrient(0, text::VertOrientation::TOP, text::RelOrientation::FRAME));
+ }
+ else
+ { // #i26791#
+ m_pVOrient.reset(new SwFormatVertOrient(0, text::VertOrientation::NONE, text::RelOrientation::FRAME));
+ }
+ }
+ return m_pVOrient.get();
+ }
+
+ SwFormatSurround* GetSurround(bool bCreate = false)
+ {
+ if (bCreate && !m_pSurround)
+ {
+ m_pSurround.reset(new SwFormatSurround());
+ }
+ return m_pSurround.get();
+ }
+ SvxLRSpaceItem* GetLRSpace(bool bCreate = false)
+ {
+ if (bCreate && !m_pLRSpace)
+ {
+ m_pLRSpace.reset(new SvxLRSpaceItem(RES_LR_SPACE));
+ }
+ return m_pLRSpace.get();
+ }
+ SvxULSpaceItem* GetULSpace(bool bCreate = false)
+ {
+ if (bCreate && !m_pULSpace)
+ {
+ m_pULSpace.reset(new SvxULSpaceItem(RES_UL_SPACE));
+ }
+ return m_pULSpace.get();
+ }
+ uno::Reference< text::XTextRange > & GetTextRange()
+ {
+ return m_xTextRange;
+ }
+ bool IsOpaque() const
+ {
+ return m_bOpaque;
+ }
+ const bool& GetOpaque() const
+ {
+ return m_bOpaque;
+ }
+ void RemoveHOrient() { m_pHOrient.reset(); }
+ void RemoveVOrient() { m_pVOrient.reset(); }
+ void RemoveAnchor() { m_pAnchor.reset(); }
+ void RemoveSurround() { m_pSurround.reset(); }
+ void RemoveULSpace() { m_pULSpace.reset(); }
+ void RemoveLRSpace() { m_pLRSpace.reset(); }
+ void SetOpaque(bool bSet){m_bOpaque = bSet;}
+
+ // #i26791#
+ SwFormatFollowTextFlow* GetFollowTextFlow( bool _bCreate = false )
+ {
+ if (_bCreate && !m_pFollowTextFlow)
+ {
+ m_pFollowTextFlow.reset(new SwFormatFollowTextFlow(false));
+ }
+ return m_pFollowTextFlow.get();
+ }
+ void RemoveFollowTextFlow()
+ {
+ m_pFollowTextFlow.reset();
+ }
+
+ // #i28749#
+ sal_Int16 GetPositionLayoutDir() const
+ {
+ return mnPositionLayoutDir;
+ }
+ void SetPositionLayoutDir( sal_Int16 _nPositionLayoutDir )
+ {
+ switch ( _nPositionLayoutDir )
+ {
+ case text::PositionLayoutDir::PositionInHoriL2R:
+ case text::PositionLayoutDir::PositionInLayoutDirOfAnchor:
+ {
+ mnPositionLayoutDir = _nPositionLayoutDir;
+ }
+ break;
+ default:
+ {
+ OSL_FAIL( "<SwShapeDescriptor_Impl::SetPositionLayoutDir(..)> - invalid attribute value." );
+ }
+ }
+ }
+
+ // #i28701#
+ SwFormatWrapInfluenceOnObjPos* GetWrapInfluenceOnObjPos(
+ const bool _bCreate = false )
+ {
+ if (_bCreate && !m_pWrapInfluenceOnObjPos)
+ {
+ m_pWrapInfluenceOnObjPos.reset(new SwFormatWrapInfluenceOnObjPos(
+ // #i35017#
+ text::WrapInfluenceOnPosition::ONCE_CONCURRENT));
+ }
+ return m_pWrapInfluenceOnObjPos.get();
+ }
+ void RemoveWrapInfluenceOnObjPos()
+ {
+ m_pWrapInfluenceOnObjPos.reset();
+ }
+};
+
+SwFmDrawPage::SwFmDrawPage( SwDoc* pDoc, SdrPage* pPage )
+ : SwFmDrawPage_Base(pPage)
+ , m_pDoc(pDoc)
+ , m_pPageView(nullptr)
+ , m_pPropertySet(aSwMapProvider.GetPropertySet(PROPERTY_MAP_TEXT_PAGE))
+{
+}
+
+SwFmDrawPage::~SwFmDrawPage() noexcept
+{
+ while (!m_vShapes.empty())
+ m_vShapes.back()->dispose();
+ RemovePageView();
+}
+
+const SdrMarkList& SwFmDrawPage::PreGroup(const uno::Reference< drawing::XShapes > & xShapes)
+{
+ SelectObjectsInView( xShapes, GetPageView() );
+ const SdrMarkList& rMarkList = mpView->GetMarkedObjectList();
+ return rMarkList;
+}
+
+void SwFmDrawPage::PreUnGroup(const uno::Reference< drawing::XShapeGroup >& rShapeGroup)
+{
+ SelectObjectInView( rShapeGroup, GetPageView() );
+}
+
+SdrPageView* SwFmDrawPage::GetPageView()
+{
+ if(!m_pPageView)
+ m_pPageView = mpView->ShowSdrPage( mpPage );
+ return m_pPageView;
+}
+
+void SwFmDrawPage::RemovePageView()
+{
+ if(m_pPageView && mpView)
+ mpView->HideSdrPage();
+ m_pPageView = nullptr;
+}
+
+uno::Reference<drawing::XShape> SwFmDrawPage::GetShape(SdrObject* pObj)
+{
+ if(!pObj)
+ return nullptr;
+ SwFrameFormat* pFormat = ::FindFrameFormat( pObj );
+ // TODO see comment at
+ // <https://gerrit.libreoffice.org/c/core/+/78734/4#message-5ee4e724a8073c5c475f07da0b5d79bc34e61de5>
+ // "make page bookkeep the SwXShapes" [-loplugin:crosscast]:
+ SwFmDrawPage* pPage = dynamic_cast<SwFmDrawPage*>(pFormat);
+ if(!pPage || pPage->m_vShapes.empty())
+ return uno::Reference<drawing::XShape>(pObj->getUnoShape(), uno::UNO_QUERY);
+ for(const auto & pShape : pPage->m_vShapes)
+ {
+ SvxShape* pSvxShape = pShape->GetSvxShape();
+ if (pSvxShape && pSvxShape->GetSdrObject() == pObj)
+ return pShape;
+ }
+ return nullptr;
+}
+
+uno::Reference<drawing::XShapeGroup> SwFmDrawPage::GetShapeGroup(SdrObject* pObj)
+{
+ return uno::Reference<drawing::XShapeGroup>(GetShape(pObj), uno::UNO_QUERY);
+}
+
+uno::Reference< drawing::XShape > SwFmDrawPage::CreateShape( SdrObject *pObj ) const
+{
+ uno::Reference< drawing::XShape > xRet;
+ if(dynamic_cast<const SwVirtFlyDrawObj*>( pObj) != nullptr || pObj->GetObjInventor() == SdrInventor::Swg)
+ {
+ SwFlyDrawContact* pFlyContact = static_cast<SwFlyDrawContact*>(pObj->GetUserCall());
+ if(pFlyContact)
+ {
+ SwFrameFormat* pFlyFormat = pFlyContact->GetFormat();
+ SwDoc* pDoc = pFlyFormat->GetDoc();
+ const SwNodeIndex* pIdx;
+ if( RES_FLYFRMFMT == pFlyFormat->Which()
+ && nullptr != ( pIdx = pFlyFormat->GetContent().GetContentIdx() )
+ && pIdx->GetNodes().IsDocNodes()
+ )
+ {
+ const SwNode* pNd = pDoc->GetNodes()[ pIdx->GetIndex() + 1 ];
+ if(!pNd->IsNoTextNode())
+ {
+ xRet.set(cppu::getXWeak(SwXTextFrame::CreateXTextFrame(*pDoc, pFlyFormat).get()),
+ uno::UNO_QUERY);
+ }
+ else if( pNd->IsGrfNode() )
+ {
+ xRet.set(cppu::getXWeak(SwXTextGraphicObject::CreateXTextGraphicObject(
+ *pDoc, pFlyFormat).get()), uno::UNO_QUERY);
+ }
+ else if( pNd->IsOLENode() )
+ {
+ xRet.set(cppu::getXWeak(SwXTextEmbeddedObject::CreateXTextEmbeddedObject(
+ *pDoc, pFlyFormat).get()), uno::UNO_QUERY);
+ }
+ }
+ else
+ {
+ OSL_FAIL( "<SwFmDrawPage::CreateShape(..)> - could not retrieve type. Thus, no shape created." );
+ return xRet;
+ }
+ }
+ }
+ else
+ {
+ // own block - temporary object has to be destroyed before
+ // the delegator is set #81670#
+ {
+ xRet = SvxDrawPage::CreateShape( pObj );
+ }
+ uno::Reference< XUnoTunnel > xShapeTunnel(xRet, uno::UNO_QUERY);
+ //don't create an SwXShape if it already exists
+ rtl::Reference<SwXShape> pShape = comphelper::getFromUnoTunnel<SwXShape>(xShapeTunnel);
+ if(!pShape)
+ {
+ xShapeTunnel = nullptr;
+ uno::Reference< uno::XInterface > xCreate(xRet, uno::UNO_QUERY);
+ xRet = nullptr;
+ if ( pObj->IsGroupObject() && (!pObj->Is3DObj() || DynCastE3dScene(pObj)) )
+ pShape = new SwXGroupShape(xCreate, nullptr);
+ else
+ pShape = new SwXShape(xCreate, nullptr);
+ xRet = pShape;
+ }
+ const_cast<std::vector<rtl::Reference<SwXShape>>*>(&m_vShapes)->push_back(pShape);
+ pShape->m_pPage = this;
+ }
+ return xRet;
+}
+
+uno::Reference<beans::XPropertySetInfo> SwFmDrawPage::getPropertySetInfo()
+{
+ static uno::Reference<beans::XPropertySetInfo> xRet = m_pPropertySet->getPropertySetInfo();
+ return xRet;
+}
+
+void SwFmDrawPage::setPropertyValue(const OUString& rPropertyName, const uno::Any& aValue)
+{
+ SolarMutexGuard aGuard;
+ const SfxItemPropertyMapEntry* pEntry = m_pPropertySet->getPropertyMap().getByName(rPropertyName);
+
+ switch (pEntry ? pEntry->nWID : -1)
+ {
+ case WID_PAGE_THEME:
+ {
+ SdrPage* pPage = GetSdrPage();
+ css::uno::Reference<css::util::XTheme> xTheme;
+ if (aValue >>= xTheme)
+ {
+ auto& rUnoTheme = dynamic_cast<UnoTheme&>(*xTheme);
+ pPage->getSdrModelFromSdrPage().setTheme(rUnoTheme.getTheme());
+ }
+ }
+ break;
+ case WID_PAGE_BOTTOM:
+ case WID_PAGE_LEFT:
+ case WID_PAGE_RIGHT:
+ case WID_PAGE_TOP:
+ case WID_PAGE_WIDTH:
+ case WID_PAGE_HEIGHT:
+ case WID_PAGE_NUMBER:
+ case WID_PAGE_ORIENT:
+ case WID_PAGE_USERATTRIBS:
+ case WID_PAGE_ISDARK:
+ case WID_NAVORDER:
+ case WID_PAGE_BACKFULL:
+ break;
+
+ default:
+ throw beans::UnknownPropertyException(rPropertyName, getXWeak());
+ }
+}
+
+uno::Any SwFmDrawPage::getPropertyValue(const OUString& rPropertyName)
+{
+ SolarMutexGuard aGuard;
+ const SfxItemPropertyMapEntry* pEntry = m_pPropertySet->getPropertyMap().getByName( rPropertyName);
+
+ uno::Any aAny;
+
+ switch (pEntry ? pEntry->nWID : -1)
+ {
+ case WID_PAGE_THEME:
+ {
+ css::uno::Reference<css::util::XTheme> xTheme;
+
+ auto pTheme = GetSdrPage()->getSdrModelFromSdrPage().getTheme();
+ if (pTheme)
+ xTheme = model::theme::createXTheme(pTheme);
+ aAny <<= xTheme;
+ }
+ break;
+
+ case WID_PAGE_NUMBER:
+ {
+ const sal_uInt16 nPageNumber(GetSdrPage()->GetPageNum());
+ aAny <<= o3tl::narrowing<sal_Int16>(nPageNumber);
+ }
+ break;
+
+ case WID_PAGE_BOTTOM:
+ case WID_PAGE_LEFT:
+ case WID_PAGE_RIGHT:
+ case WID_PAGE_TOP:
+ case WID_PAGE_WIDTH:
+ case WID_PAGE_HEIGHT:
+ case WID_PAGE_ORIENT:
+ case WID_PAGE_USERATTRIBS:
+ case WID_PAGE_ISDARK:
+ case WID_NAVORDER:
+ case WID_PAGE_BACKFULL:
+ break;
+
+ default:
+ throw beans::UnknownPropertyException(rPropertyName, getXWeak());
+ }
+ return aAny;
+}
+
+void SwFmDrawPage::addPropertyChangeListener(const OUString& /*PropertyName*/,
+ const uno::Reference<beans::XPropertyChangeListener> & /*aListener*/)
+{
+ OSL_FAIL("not implemented");
+}
+
+void SwFmDrawPage::removePropertyChangeListener(const OUString& /*PropertyName*/,
+ const uno::Reference<beans::XPropertyChangeListener> & /*aListener*/)
+{
+ OSL_FAIL("not implemented");
+}
+
+void SwFmDrawPage::addVetoableChangeListener(const OUString& /*PropertyName*/,
+ const uno::Reference<beans::XVetoableChangeListener> & /*aListener*/)
+{
+ OSL_FAIL("not implemented");
+}
+
+void SwFmDrawPage::removeVetoableChangeListener(const OUString& /*PropertyName*/,
+ const uno::Reference<beans::XVetoableChangeListener> & /*aListener*/)
+{
+ OSL_FAIL("not implemented");
+}
+
+namespace
+{
+ class SwXShapesEnumeration
+ : public SwSimpleEnumeration_Base
+ {
+ private:
+ std::vector< css::uno::Any > m_aShapes;
+ protected:
+ virtual ~SwXShapesEnumeration() override {};
+ public:
+ explicit SwXShapesEnumeration(SwFmDrawPage* const pDrawPage);
+
+ //XEnumeration
+ virtual sal_Bool SAL_CALL hasMoreElements() override;
+ virtual uno::Any SAL_CALL nextElement() override;
+
+ //XServiceInfo
+ virtual OUString SAL_CALL getImplementationName() override;
+ virtual sal_Bool SAL_CALL supportsService(const OUString& ServiceName) override;
+ virtual uno::Sequence<OUString> SAL_CALL getSupportedServiceNames() override;
+ };
+}
+
+SwXShapesEnumeration::SwXShapesEnumeration(SwFmDrawPage* const pDrawPage)
+{
+ SolarMutexGuard aGuard;
+ sal_Int32 nCount = pDrawPage->getCount();
+ m_aShapes.reserve(nCount);
+ for(sal_Int32 nIdx = 0; nIdx < nCount; nIdx++)
+ {
+ uno::Reference<drawing::XShape> xShape(pDrawPage->getByIndex(nIdx), uno::UNO_QUERY);
+ m_aShapes.push_back(uno::Any(xShape));
+ }
+}
+
+sal_Bool SwXShapesEnumeration::hasMoreElements()
+{
+ SolarMutexGuard aGuard;
+ return !m_aShapes.empty();
+}
+
+uno::Any SwXShapesEnumeration::nextElement()
+{
+ SolarMutexGuard aGuard;
+ if(m_aShapes.empty())
+ throw container::NoSuchElementException();
+ uno::Any aResult = m_aShapes.back();
+ m_aShapes.pop_back();
+ return aResult;
+}
+
+OUString SwXShapesEnumeration::getImplementationName()
+{
+ return "SwXShapeEnumeration";
+}
+
+sal_Bool SwXShapesEnumeration::supportsService(const OUString& ServiceName)
+{
+ return cppu::supportsService(this, ServiceName);
+}
+
+uno::Sequence< OUString > SwXShapesEnumeration::getSupportedServiceNames()
+{
+ return { OUString("com.sun.star.container.XEnumeration") };
+}
+
+uno::Reference< container::XEnumeration > SwFmDrawPage::createEnumeration()
+{
+ SolarMutexGuard aGuard;
+ return uno::Reference< container::XEnumeration >(
+ new SwXShapesEnumeration(this));
+}
+
+OUString SwFmDrawPage::getImplementationName()
+{
+ return "SwFmDrawPage";
+}
+
+sal_Bool SwFmDrawPage::supportsService(const OUString& rServiceName)
+{
+ return cppu::supportsService(this, rServiceName);
+}
+
+uno::Sequence< OUString > SwFmDrawPage::getSupportedServiceNames()
+{
+ return { "com.sun.star.drawing.GenericDrawPage" };
+}
+
+sal_Int32 SwFmDrawPage::getCount()
+{
+ SolarMutexGuard aGuard;
+ if(!m_pDoc)
+ throw uno::RuntimeException();
+ if(!m_pDoc->getIDocumentDrawModelAccess().GetDrawModel())
+ return 0;
+ else
+ return SwTextBoxHelper::getCount(GetSdrPage());
+}
+
+uno::Any SwFmDrawPage::getByIndex(sal_Int32 nIndex)
+{
+ SolarMutexGuard aGuard;
+ if(!m_pDoc)
+ throw uno::RuntimeException();
+ if(!m_pDoc->getIDocumentDrawModelAccess().GetDrawModel())
+ throw lang::IndexOutOfBoundsException();
+
+ return SwTextBoxHelper::getByIndex(GetSdrPage(), nIndex);
+}
+
+uno::Type SwFmDrawPage::getElementType()
+{
+ return cppu::UnoType<drawing::XShape>::get();
+}
+
+sal_Bool SwFmDrawPage::hasElements()
+{
+ SolarMutexGuard aGuard;
+ if(!m_pDoc)
+ throw uno::RuntimeException();
+ if(!m_pDoc->getIDocumentDrawModelAccess().GetDrawModel())
+ return false;
+ return SvxDrawPage::hasElements();
+}
+
+void SwFmDrawPage::add(const uno::Reference< drawing::XShape > & xShape)
+{
+ SolarMutexGuard aGuard;
+ if(!m_pDoc)
+ throw uno::RuntimeException();
+ uno::Reference< lang::XUnoTunnel > xShapeTunnel(xShape, uno::UNO_QUERY);
+ SwXShape* pShape = comphelper::getFromUnoTunnel<SwXShape>(xShapeTunnel);
+ SvxShape* pSvxShape = comphelper::getFromUnoTunnel<SvxShape>(xShapeTunnel);
+
+ // this is not a writer shape
+ if(!pShape)
+ throw uno::RuntimeException("illegal object",
+ getXWeak() );
+
+ // we're already registered in the model / SwXDrawPage::add() already called
+ if(pShape->m_pPage || !pShape->m_bDescriptor )
+ return;
+
+ // we're inserted elsewhere already
+ if ( pSvxShape->GetSdrObject() )
+ {
+ if ( pSvxShape->GetSdrObject()->IsInserted() )
+ {
+ return;
+ }
+ }
+ SvxDrawPage::add(xShape);
+
+ OSL_ENSURE(pSvxShape, "Why is here no SvxShape?");
+ // this position is definitely in 1/100 mm
+ awt::Point aMM100Pos(pSvxShape->getPosition());
+
+ // now evaluate the properties of SwShapeDescriptor_Impl
+ SwShapeDescriptor_Impl* pDesc = pShape->GetDescImpl();
+
+ SfxItemSetFixed<RES_FRMATR_BEGIN, RES_FRMATR_END-1> aSet( m_pDoc->GetAttrPool() );
+ SwFormatAnchor aAnchor( RndStdIds::FLY_AS_CHAR );
+ bool bOpaque = false;
+ if( pDesc )
+ {
+ if(pDesc->GetSurround())
+ aSet.Put( *pDesc->GetSurround());
+ // all items are already in Twip
+ if(pDesc->GetLRSpace())
+ {
+ aSet.Put(*pDesc->GetLRSpace());
+ }
+ if(pDesc->GetULSpace())
+ {
+ aSet.Put(*pDesc->GetULSpace());
+ }
+ if(pDesc->GetAnchor())
+ aAnchor = *pDesc->GetAnchor();
+
+ // #i32349# - if no horizontal position exists, create one
+ if ( !pDesc->GetHOrient() )
+ {
+ SwFormatHoriOrient* pHori = pDesc->GetHOrient( true );
+ SwTwips nHoriPos = o3tl::toTwips(aMM100Pos.X, o3tl::Length::mm100);
+ pHori->SetPos( nHoriPos );
+ }
+ {
+ if(pDesc->GetHOrient()->GetHoriOrient() == text::HoriOrientation::NONE)
+ aMM100Pos.X = convertTwipToMm100(pDesc->GetHOrient()->GetPos());
+ aSet.Put( *pDesc->GetHOrient() );
+ }
+ // #i32349# - if no vertical position exists, create one
+ if ( !pDesc->GetVOrient() )
+ {
+ SwFormatVertOrient* pVert = pDesc->GetVOrient( true );
+ SwTwips nVertPos = o3tl::toTwips(aMM100Pos.Y, o3tl::Length::mm100);
+ pVert->SetPos( nVertPos );
+ }
+ {
+ if(pDesc->GetVOrient()->GetVertOrient() == text::VertOrientation::NONE)
+ aMM100Pos.Y = convertTwipToMm100(pDesc->GetVOrient()->GetPos());
+ aSet.Put( *pDesc->GetVOrient() );
+ }
+
+ if(pDesc->GetSurround())
+ aSet.Put( *pDesc->GetSurround());
+ bOpaque = pDesc->IsOpaque();
+
+ // #i26791#
+ if ( pDesc->GetFollowTextFlow() )
+ {
+ aSet.Put( *pDesc->GetFollowTextFlow() );
+ }
+
+ // #i28701#
+ if ( pDesc->GetWrapInfluenceOnObjPos() )
+ {
+ aSet.Put( *pDesc->GetWrapInfluenceOnObjPos() );
+ }
+ }
+
+ pSvxShape->setPosition(aMM100Pos);
+ SdrObject* pObj = pSvxShape->GetSdrObject();
+ // #108784# - set layer of new drawing object to corresponding
+ // invisible layer.
+ if(SdrInventor::FmForm != pObj->GetObjInventor())
+ pObj->SetLayer( bOpaque ? m_pDoc->getIDocumentDrawModelAccess().GetInvisibleHeavenId() : m_pDoc->getIDocumentDrawModelAccess().GetInvisibleHellId() );
+ else
+ pObj->SetLayer(m_pDoc->getIDocumentDrawModelAccess().GetInvisibleControlsId());
+
+ std::optional<SwPaM> pPam(m_pDoc->GetNodes().GetEndOfContent());
+ std::unique_ptr<SwUnoInternalPaM> pInternalPam;
+ uno::Reference< text::XTextRange > xRg;
+ if( pDesc && (xRg = pDesc->GetTextRange()).is() )
+ {
+ pInternalPam.reset(new SwUnoInternalPaM(*m_pDoc));
+ if (!::sw::XTextRangeToSwPaM(*pInternalPam, xRg))
+ throw uno::RuntimeException();
+
+ if(RndStdIds::FLY_AT_FLY == aAnchor.GetAnchorId() &&
+ !pInternalPam->GetPointNode().FindFlyStartNode())
+ {
+ aAnchor.SetType(RndStdIds::FLY_AS_CHAR);
+ }
+ else if (RndStdIds::FLY_AT_PAGE == aAnchor.GetAnchorId()
+ && 0 == aAnchor.GetPageNum())
+ {
+ aAnchor.SetAnchor(pInternalPam->Start());
+ aAnchor.SetType(RndStdIds::FLY_AT_CHAR); // convert invalid at-page
+ }
+
+ }
+ else if ((aAnchor.GetAnchorId() != RndStdIds::FLY_AT_PAGE) && m_pDoc->getIDocumentLayoutAccess().GetCurrentLayout())
+ {
+ SwCursorMoveState aState( CursorMoveState::SetOnlyText );
+ Point aTmp(o3tl::toTwips(aMM100Pos.X, o3tl::Length::mm100), o3tl::toTwips(aMM100Pos.Y, o3tl::Length::mm100));
+ m_pDoc->getIDocumentLayoutAccess().GetCurrentLayout()->GetModelPositionForViewPoint( pPam->GetPoint(), aTmp, &aState );
+ aAnchor.SetAnchor( pPam->GetPoint() );
+
+ // #i32349# - adjustment of vertical positioning
+ // attributes no longer needed, because it's already got a default.
+ }
+ else
+ {
+ aAnchor.SetType(RndStdIds::FLY_AT_PAGE);
+
+ // #i32349# - adjustment of vertical positioning
+ // attributes no longer needed, because it's already got a default.
+ }
+ aSet.Put(aAnchor);
+ SwPaM* pTemp = pInternalPam.get();
+ if ( !pTemp )
+ pTemp = &*pPam;
+ UnoActionContext aAction(m_pDoc);
+ m_pDoc->getIDocumentContentOperations().InsertDrawObj( *pTemp, *pObj, aSet );
+
+ if (pSvxShape->GetSdrObject()->GetName().isEmpty())
+ {
+ pSvxShape->GetSdrObject()->SetName(m_pDoc->GetUniqueShapeName());
+ }
+
+ SwFrameFormat* pFormat = ::FindFrameFormat( pObj );
+ if (pFormat)
+ {
+ if (pFormat->GetName().isEmpty())
+ {
+ pFormat->SetFormatName(pSvxShape->GetSdrObject()->GetName(), false);
+ }
+ }
+ pShape->m_bDescriptor = false;
+
+ pPam.reset();
+ pInternalPam.reset();
+}
+
+void SwFmDrawPage::remove(const uno::Reference< drawing::XShape > & xShape)
+{
+ SolarMutexGuard aGuard;
+ if(!m_pDoc)
+ throw uno::RuntimeException();
+ // tdf#41466 remove TextFrame too which is belonged to the actual shape
+ auto xTextFrame = SwTextBoxHelper::getUnoTextFrame(xShape);
+ if (xTextFrame)
+ {
+ uno::Reference<lang::XComponent> xComp(xTextFrame, uno::UNO_QUERY);
+ if (xComp)
+ xComp->dispose();
+ }
+ // remove shape
+ uno::Reference<lang::XComponent> xComp(xShape, uno::UNO_QUERY);
+ xComp->dispose();
+}
+
+uno::Reference< drawing::XShapeGroup > SwFmDrawPage::group(const uno::Reference< drawing::XShapes > & xShapes)
+{
+ SolarMutexGuard aGuard;
+ if(!m_pDoc || !xShapes.is())
+ throw uno::RuntimeException();
+ uno::Reference< drawing::XShapeGroup > xRet;
+ // mark and return MarkList
+ const SdrMarkList& rMarkList = PreGroup(xShapes);
+ if ( rMarkList.GetMarkCount() > 0 )
+ {
+ for (size_t i = 0; i < rMarkList.GetMarkCount(); ++i)
+ {
+ const SdrObject *pObj = rMarkList.GetMark( i )->GetMarkedSdrObj();
+ if (RndStdIds::FLY_AS_CHAR == ::FindFrameFormat(const_cast<SdrObject*>(
+ pObj))->GetAnchor().GetAnchorId())
+ {
+ throw lang::IllegalArgumentException(
+ "Shape must not have 'as character' anchor!", nullptr, 0);
+ }
+ }
+
+ UnoActionContext aContext(m_pDoc);
+ m_pDoc->GetIDocumentUndoRedo().StartUndo( SwUndoId::START, nullptr );
+
+ SwDrawContact* pContact = m_pDoc->GroupSelection( *GetDrawView() );
+ m_pDoc->ChgAnchor(
+ GetDrawView()->GetMarkedObjectList(),
+ RndStdIds::FLY_AT_PARA,
+ true, false );
+
+ GetDrawView()->UnmarkAll();
+ if(pContact)
+ xRet = SwFmDrawPage::GetShapeGroup( pContact->GetMaster() );
+ m_pDoc->GetIDocumentUndoRedo().EndUndo( SwUndoId::END, nullptr );
+ }
+ RemovePageView();
+ return xRet;
+}
+
+void SwFmDrawPage::ungroup(const uno::Reference< drawing::XShapeGroup > & rShapeGroup)
+{
+ SolarMutexGuard aGuard;
+ if(!m_pDoc)
+ throw uno::RuntimeException();
+
+ PreUnGroup(rShapeGroup);
+ UnoActionContext aContext(m_pDoc);
+ m_pDoc->GetIDocumentUndoRedo().StartUndo( SwUndoId::START, nullptr );
+
+ m_pDoc->UnGroupSelection( *GetDrawView() );
+ m_pDoc->ChgAnchor( GetDrawView()->GetMarkedObjectList(),
+ RndStdIds::FLY_AT_PARA,
+ true, false );
+ m_pDoc->GetIDocumentUndoRedo().EndUndo( SwUndoId::END, nullptr );
+ RemovePageView();
+}
+
+/**
+ * Renamed and outlined to detect where it's called
+ */
+void SwFmDrawPage::InvalidateSwDoc()
+{
+ m_pDoc = nullptr;
+}
+
+const uno::Sequence< sal_Int8 > & SwXShape::getUnoTunnelId()
+{
+ static const comphelper::UnoIdInit theSwXShapeUnoTunnelId;
+ return theSwXShapeUnoTunnelId.getSeq();
+}
+
+sal_Int64 SAL_CALL SwXShape::getSomething( const uno::Sequence< sal_Int8 >& rId )
+{
+ if( comphelper::isUnoTunnelId<SwXShape>(rId) )
+ {
+ return comphelper::getSomething_cast(this);
+ }
+
+ if( m_xShapeAgg.is() )
+ {
+ const uno::Type& rTunnelType = cppu::UnoType<lang::XUnoTunnel>::get();
+ uno::Any aAgg = m_xShapeAgg->queryAggregation( rTunnelType );
+ if(auto xAggTunnel = o3tl::tryAccess<uno::Reference<lang::XUnoTunnel>>(
+ aAgg))
+ {
+ if(xAggTunnel->is())
+ return (*xAggTunnel)->getSomething(rId);
+ }
+ }
+ return 0;
+}
+
+SwXShape::SwXShape(
+ uno::Reference<uno::XInterface> & xShape,
+ SwDoc const*const pDoc)
+ : m_pPage(nullptr)
+ , m_pPropSet(aSwMapProvider.GetPropertySet(PROPERTY_MAP_TEXT_SHAPE))
+ , m_pPropertyMapEntries(aSwMapProvider.GetPropertyMapEntries(PROPERTY_MAP_TEXT_SHAPE))
+ , m_pImpl(new SwShapeDescriptor_Impl(pDoc))
+ , m_bDescriptor(true)
+{
+ if(!xShape.is()) // default Ctor
+ return;
+
+ const uno::Type& rAggType = cppu::UnoType<uno::XAggregation>::get();
+ //aAgg contains a reference of the SvxShape!
+ {
+ uno::Any aAgg = xShape->queryInterface(rAggType);
+ aAgg >>= m_xShapeAgg;
+ // #i31698#
+ if ( m_xShapeAgg.is() )
+ {
+ m_xShapeAgg->queryAggregation( cppu::UnoType<drawing::XShape>::get()) >>= mxShape;
+ OSL_ENSURE( mxShape.is(),
+ "<SwXShape::SwXShape(..)> - no XShape found at <xShapeAgg>" );
+ }
+ }
+ xShape = nullptr;
+ osl_atomic_increment(&m_refCount);
+ if( m_xShapeAgg.is() )
+ m_xShapeAgg->setDelegator( getXWeak() );
+ osl_atomic_decrement(&m_refCount);
+}
+
+SwFrameFormat* SwXShape::GetFrameFormat() const
+{
+ SdrObject* pObj = SdrObject::getSdrObjectFromXShape(m_xShapeAgg);
+ if(pObj)
+ return ::FindFrameFormat( pObj );
+ return nullptr;
+}
+
+void SwXShape::AddExistingShapeToFormat( SdrObject const & _rObj )
+{
+ SdrObjListIter aIter( _rObj, SdrIterMode::DeepNoGroups );
+ while ( aIter.IsMore() )
+ {
+ SdrObject* pCurrent = aIter.Next();
+ OSL_ENSURE( pCurrent, "SwXShape::AddExistingShapeToFormat: invalid object list element!" );
+ if ( !pCurrent )
+ continue;
+
+ auto pSwShape = comphelper::getFromUnoTunnel<SwXShape>(pCurrent->getWeakUnoShape());
+ if ( pSwShape )
+ {
+ if ( pSwShape->m_bDescriptor )
+ pSwShape->m_bDescriptor = false;
+ }
+ }
+}
+
+SwXShape::~SwXShape()
+{
+ SolarMutexGuard aGuard;
+
+ if (m_xShapeAgg.is())
+ {
+ uno::Reference< uno::XInterface > xRef;
+ m_xShapeAgg->setDelegator(xRef);
+ }
+ m_pImpl.reset();
+ if(m_pPage)
+ const_cast<SwFmDrawPage*>(m_pPage)->RemoveShape(this);
+}
+
+uno::Any SwXShape::queryInterface( const uno::Type& aType )
+{
+ uno::Any aRet;
+ SdrObject* pObj = nullptr;
+
+ if ((aType == cppu::UnoType<text::XText>::get())
+ || (aType == cppu::UnoType<text::XTextRange>::get())
+ || (aType == cppu::UnoType<text::XTextAppend>::get()))
+ {
+ pObj = SdrObject::getSdrObjectFromXShape(mxShape);
+
+ aRet = SwTextBoxHelper::queryInterface(GetFrameFormat(), aType, pObj);
+ if (aRet.hasValue())
+ return aRet;
+ }
+ aRet = SwXShapeBaseClass::queryInterface(aType);
+ // #i53320# - follow-up of #i31698#
+ // interface drawing::XShape is overloaded. Thus, provide
+ // correct object instance.
+ if(!aRet.hasValue() && m_xShapeAgg.is())
+ {
+ if(aType == cppu::UnoType<XShape>::get())
+ aRet <<= uno::Reference<XShape>(this);
+ else
+ aRet = m_xShapeAgg->queryAggregation(aType);
+ }
+ return aRet;
+}
+
+uno::Sequence< uno::Type > SwXShape::getTypes( )
+{
+ uno::Sequence< uno::Type > aRet = SwXShapeBaseClass::getTypes();
+ if(m_xShapeAgg.is())
+ {
+ uno::Any aProv = m_xShapeAgg->queryAggregation(cppu::UnoType<XTypeProvider>::get());
+ if(aProv.hasValue())
+ {
+ uno::Reference< XTypeProvider > xAggProv;
+ aProv >>= xAggProv;
+ return comphelper::concatSequences(aRet, xAggProv->getTypes());
+ }
+ }
+ return aRet;
+}
+
+uno::Sequence< sal_Int8 > SwXShape::getImplementationId( )
+{
+ return css::uno::Sequence<sal_Int8>();
+}
+
+uno::Reference< beans::XPropertySetInfo > SwXShape::getPropertySetInfo()
+{
+ SolarMutexGuard aGuard;
+ if (!mxPropertySetInfo)
+ {
+ if(m_xShapeAgg.is())
+ {
+ const uno::Type& rPropSetType = cppu::UnoType<beans::XPropertySet>::get();
+ uno::Any aPSet = m_xShapeAgg->queryAggregation( rPropSetType );
+ if(auto xPrSet = o3tl::tryAccess<uno::Reference<beans::XPropertySet>>(
+ aPSet))
+ {
+ uno::Reference< beans::XPropertySetInfo > xInfo = (*xPrSet)->getPropertySetInfo();
+ // Expand PropertySetInfo!
+ const uno::Sequence<beans::Property> aPropSeq = xInfo->getProperties();
+ mxPropertySetInfo = new SfxExtItemPropertySetInfo( m_pPropertyMapEntries, aPropSeq );
+ }
+ }
+ if(!mxPropertySetInfo)
+ mxPropertySetInfo = m_pPropSet->getPropertySetInfo();
+ }
+ return mxPropertySetInfo;
+}
+
+void SwXShape::setPropertyValue(const OUString& rPropertyName, const uno::Any& aValue)
+{
+ SolarMutexGuard aGuard;
+ SwFrameFormat* pFormat = GetFrameFormat();
+ const SfxItemPropertyMapEntry* pEntry = m_pPropSet->getPropertyMap().getByName( rPropertyName );
+ if(!m_xShapeAgg.is())
+ return;
+
+ if(pEntry)
+ {
+ if ( pEntry->nFlags & beans::PropertyAttribute::READONLY)
+ throw beans::PropertyVetoException ("Property is read-only: " + rPropertyName, getXWeak() );
+ // with the layout it is possible to move the anchor without changing the position
+ if(pFormat)
+ {
+ SwAttrSet aSet(pFormat->GetAttrSet());
+ SwDoc* pDoc = pFormat->GetDoc();
+ if(RES_ANCHOR == pEntry->nWID && MID_ANCHOR_ANCHORFRAME == pEntry->nMemberId)
+ {
+ bool bDone = false;
+ uno::Reference<text::XTextFrame> xFrame;
+ if(aValue >>= xFrame)
+ {
+ SwXFrame* pFrame = dynamic_cast<SwXFrame*>(xFrame.get());
+ if(pFrame && pFrame->GetFrameFormat() &&
+ pFrame->GetFrameFormat()->GetDoc() == pDoc)
+ {
+ UnoActionContext aCtx(pDoc);
+ SfxItemSetFixed<RES_FRMATR_BEGIN, RES_FRMATR_END - 1> aItemSet( pDoc->GetAttrPool() );
+ aItemSet.SetParent(&pFormat->GetAttrSet());
+ SwFormatAnchor aAnchor = static_cast<const SwFormatAnchor&>(aItemSet.Get(pEntry->nWID));
+ SwPosition aPos(*pFrame->GetFrameFormat()->GetContent().GetContentIdx());
+ aAnchor.SetAnchor(&aPos);
+ aAnchor.SetType(RndStdIds::FLY_AT_FLY);
+ aItemSet.Put(aAnchor);
+ pFormat->SetFormatAttr(aItemSet);
+ bDone = true;
+ }
+ }
+ if(!bDone)
+ throw lang::IllegalArgumentException();
+ }
+ else if(RES_OPAQUE == pEntry->nWID)
+ {
+ SvxShape* pSvxShape = GetSvxShape();
+ SAL_WARN_IF(!pSvxShape, "sw.uno", "No SvxShape found!");
+ if(pSvxShape)
+ {
+ SdrObject* pObj = pSvxShape->GetSdrObject();
+ // set layer of new drawing
+ // object to corresponding invisible layer.
+ bool bIsVisible = pDoc->getIDocumentDrawModelAccess().IsVisibleLayerId( pObj->GetLayer() );
+ if(SdrInventor::FmForm != pObj->GetObjInventor())
+ {
+ pObj->SetLayer( *o3tl::doAccess<bool>(aValue)
+ ? ( bIsVisible ? pDoc->getIDocumentDrawModelAccess().GetHeavenId() : pDoc->getIDocumentDrawModelAccess().GetInvisibleHeavenId() )
+ : ( bIsVisible ? pDoc->getIDocumentDrawModelAccess().GetHellId() : pDoc->getIDocumentDrawModelAccess().GetInvisibleHellId() ));
+ }
+ else
+ {
+ pObj->SetLayer( bIsVisible ? pDoc->getIDocumentDrawModelAccess().GetControlsId() : pDoc->getIDocumentDrawModelAccess().GetInvisibleControlsId());
+ }
+
+ }
+
+ }
+ // #i26791# - special handling for property FN_TEXT_RANGE
+ else if ( FN_TEXT_RANGE == pEntry->nWID )
+ {
+ SwFormatAnchor aAnchor( aSet.Get( RES_ANCHOR ) );
+ if (aAnchor.GetAnchorId() == RndStdIds::FLY_AT_PAGE)
+ {
+ // set property <TextRange> not valid for to-page anchored shapes
+ throw lang::IllegalArgumentException();
+ }
+
+ std::unique_ptr<SwUnoInternalPaM> pInternalPam(
+ new SwUnoInternalPaM( *(pFormat->GetDoc()) ));
+ uno::Reference< text::XTextRange > xRg;
+ aValue >>= xRg;
+ if (!::sw::XTextRangeToSwPaM(*pInternalPam, xRg) )
+ {
+ throw uno::RuntimeException();
+ }
+
+ if (aAnchor.GetAnchorId() == RndStdIds::FLY_AS_CHAR)
+ {
+ //delete old SwFormatFlyCnt
+ //With AnchorAsCharacter the current TextAttribute has to be deleted.
+ //Tbis removes the frame format too.
+ //To prevent this the connection between format and attribute has to be broken before.
+ SwTextNode *pTextNode = aAnchor.GetAnchorNode()->GetTextNode();
+ SAL_WARN_IF( !pTextNode->HasHints(), "sw.uno", "Missing FlyInCnt-Hint." );
+ const sal_Int32 nIdx = aAnchor.GetAnchorContentOffset();
+ SwTextAttr * const pHint =
+ pTextNode->GetTextAttrForCharAt(
+ nIdx, RES_TXTATR_FLYCNT );
+ assert(pHint && "Missing Hint.");
+ SAL_WARN_IF( pHint->Which() != RES_TXTATR_FLYCNT,
+ "sw.uno", "Missing FlyInCnt-Hint." );
+ SAL_WARN_IF( pHint->GetFlyCnt().GetFrameFormat() != pFormat,
+ "sw.uno", "Wrong TextFlyCnt-Hint." );
+ const_cast<SwFormatFlyCnt&>(pHint->GetFlyCnt())
+ .SetFlyFormat();
+
+ //The connection is removed now the attribute can be deleted.
+ pTextNode->DeleteAttributes( RES_TXTATR_FLYCNT, nIdx );
+ //create a new one
+ SwTextNode *pNd = pInternalPam->GetPointNode().GetTextNode();
+ SAL_WARN_IF( !pNd, "sw.uno", "Cursor not at TextNode." );
+ SwFormatFlyCnt aFormat( pFormat );
+ pNd->InsertItem(aFormat, pInternalPam->GetPoint()
+ ->GetContentIndex(), 0 );
+ //Refetch in case SwTextNode::InsertItem causes it to be deleted
+ pFormat = GetFrameFormat();
+ }
+ else
+ {
+ aAnchor.SetAnchor( pInternalPam->GetPoint() );
+ aSet.Put(aAnchor);
+ pFormat->SetFormatAttr(aSet);
+ }
+ }
+ else if (pEntry->nWID == FN_TEXT_BOX)
+ {
+ auto pObj = SdrObject::getSdrObjectFromXShape(mxShape);
+ if (pEntry->nMemberId == MID_TEXT_BOX)
+ {
+ bool bValue(false);
+ aValue >>= bValue;
+
+ if (bValue)
+ SwTextBoxHelper::create(pFormat, pObj);
+ else
+ SwTextBoxHelper::destroy(pFormat, pObj);
+ }
+ else if (pEntry->nMemberId == MID_TEXT_BOX_CONTENT)
+ {
+ if (aValue.getValueType()
+ == cppu::UnoType<uno::Reference<text::XTextFrame>>::get())
+ SwTextBoxHelper::set(pFormat, pObj,
+ aValue.get<uno::Reference<text::XTextFrame>>());
+ else
+ SAL_WARN( "sw.uno", "This is not a TextFrame!" );
+ }
+ }
+ else if (pEntry->nWID == RES_CHAIN)
+ {
+ if (pEntry->nMemberId == MID_CHAIN_NEXTNAME || pEntry->nMemberId == MID_CHAIN_PREVNAME)
+ SwTextBoxHelper::syncProperty(pFormat, pEntry->nWID, pEntry->nMemberId, aValue,
+ SdrObject::getSdrObjectFromXShape(mxShape));
+ }
+ // #i28749#
+ else if ( FN_SHAPE_POSITION_LAYOUT_DIR == pEntry->nWID )
+ {
+ sal_Int16 nPositionLayoutDir = 0;
+ aValue >>= nPositionLayoutDir;
+ pFormat->SetPositionLayoutDir( nPositionLayoutDir );
+ }
+ else if( pDoc->getIDocumentLayoutAccess().GetCurrentLayout())
+ {
+ UnoActionContext aCtx(pDoc);
+ if(RES_ANCHOR == pEntry->nWID && MID_ANCHOR_ANCHORTYPE == pEntry->nMemberId)
+ {
+ SdrObject* pObj = pFormat->FindSdrObject();
+ SdrMarkList aList;
+ SdrMark aMark(pObj);
+ aList.InsertEntry(aMark);
+ sal_Int32 nAnchor = 0;
+ cppu::enum2int( nAnchor, aValue );
+ pDoc->ChgAnchor( aList, static_cast<RndStdIds>(nAnchor),
+ false, true );
+ }
+ else
+ {
+ m_pPropSet->setPropertyValue(*pEntry, aValue, aSet);
+ pFormat->SetFormatAttr(aSet);
+ }
+ }
+ else if( RES_FRM_SIZE == pEntry->nWID &&
+ ( pEntry->nMemberId == MID_FRMSIZE_REL_HEIGHT || pEntry->nMemberId == MID_FRMSIZE_REL_WIDTH
+ || pEntry->nMemberId == MID_FRMSIZE_REL_HEIGHT_RELATION
+ || pEntry->nMemberId == MID_FRMSIZE_REL_WIDTH_RELATION ) )
+ {
+ SvxShape* pSvxShape = GetSvxShape();
+ SAL_WARN_IF(!pSvxShape, "sw.uno", "No SvxShape found!");
+ if(pSvxShape)
+ {
+ SdrObject* pObj = pSvxShape->GetSdrObject();
+ sal_Int16 nPercent(100);
+ aValue >>= nPercent;
+ switch (pEntry->nMemberId)
+ {
+ case MID_FRMSIZE_REL_WIDTH:
+ pObj->SetRelativeWidth( nPercent / 100.0 );
+ break;
+ case MID_FRMSIZE_REL_HEIGHT:
+ pObj->SetRelativeHeight( nPercent / 100.0 );
+ break;
+ case MID_FRMSIZE_REL_WIDTH_RELATION:
+ pObj->SetRelativeWidthRelation(nPercent);
+ break;
+ case MID_FRMSIZE_REL_HEIGHT_RELATION:
+ pObj->SetRelativeHeightRelation(nPercent);
+ break;
+ }
+ }
+ }
+ else if (pEntry->nWID == RES_HORI_ORIENT
+ && pEntry->nMemberId == MID_HORIORIENT_RELATION
+ && aSet.Get(RES_ANCHOR).GetAnchorId() == RndStdIds::FLY_AT_PAGE)
+ {
+ uno::Any value(aValue);
+ sal_Int16 nRelOrient(text::RelOrientation::PAGE_FRAME);
+ aValue >>= nRelOrient;
+ if (sw::GetAtPageRelOrientation(nRelOrient, true))
+ {
+ SAL_WARN("sw.core", "SwXShape: fixing invalid horizontal RelOrientation for at-page anchor");
+ value <<= nRelOrient;
+ }
+ m_pPropSet->setPropertyValue( *pEntry, value, aSet );
+ pFormat->SetFormatAttr(aSet);
+ }
+ else
+ {
+ m_pPropSet->setPropertyValue( *pEntry, aValue, aSet );
+
+ if(RES_ANCHOR == pEntry->nWID && MID_ANCHOR_ANCHORTYPE == pEntry->nMemberId)
+ {
+ bool bSetAttr = true;
+ text::TextContentAnchorType eNewAnchor = static_cast<text::TextContentAnchorType>(SWUnoHelper::GetEnumAsInt32( aValue ));
+
+ //if old anchor was in_cntnt the related text attribute has to be removed
+ const SwFormatAnchor& rOldAnchor = pFormat->GetAnchor();
+ RndStdIds eOldAnchorId = rOldAnchor.GetAnchorId();
+ SdrObject* pObj = pFormat->FindSdrObject();
+ SwFrameFormat *pFlyFormat = FindFrameFormat( pObj );
+ pFlyFormat->DelFrames();
+ if( text::TextContentAnchorType_AS_CHARACTER != eNewAnchor &&
+ (RndStdIds::FLY_AS_CHAR == eOldAnchorId))
+ {
+ //With AnchorAsCharacter the current TextAttribute has to be deleted.
+ //Tbis removes the frame format too.
+ //To prevent this the connection between format and attribute has to be broken before.
+ SwTextNode *pTextNode = rOldAnchor.GetAnchorNode()->GetTextNode();
+ SAL_WARN_IF( !pTextNode->HasHints(), "sw.uno", "Missing FlyInCnt-Hint." );
+ const sal_Int32 nIdx = rOldAnchor.GetAnchorContentOffset();
+ SwTextAttr * const pHint =
+ pTextNode->GetTextAttrForCharAt(
+ nIdx, RES_TXTATR_FLYCNT );
+ assert(pHint && "Missing Hint.");
+ SAL_WARN_IF( pHint->Which() != RES_TXTATR_FLYCNT,
+ "sw.uno", "Missing FlyInCnt-Hint." );
+ SAL_WARN_IF( pHint->GetFlyCnt().GetFrameFormat() != pFlyFormat,
+ "sw.uno", "Wrong TextFlyCnt-Hint." );
+ const_cast<SwFormatFlyCnt&>(pHint->GetFlyCnt())
+ .SetFlyFormat();
+
+ //The connection is removed now the attribute can be deleted.
+ pTextNode->DeleteAttributes(RES_TXTATR_FLYCNT, nIdx);
+ }
+ else if( text::TextContentAnchorType_AT_PAGE != eNewAnchor &&
+ (RndStdIds::FLY_AT_PAGE == eOldAnchorId))
+ {
+ SwFormatAnchor aNewAnchor( aSet.Get( RES_ANCHOR ) );
+ //if the fly has been anchored at page then it needs to be connected
+ //to the content position
+ SwPaM aPam(pDoc->GetNodes().GetEndOfContent());
+ if( pDoc->getIDocumentLayoutAccess().GetCurrentLayout() )
+ {
+ SwCursorMoveState aState( CursorMoveState::SetOnlyText );
+ Point aTmp( pObj->GetSnapRect().TopLeft() );
+ pDoc->getIDocumentLayoutAccess().GetCurrentLayout()->GetModelPositionForViewPoint( aPam.GetPoint(), aTmp, &aState );
+ }
+ else
+ {
+ //without access to the layout the last node of the body will be used as anchor position
+ aPam.Move( fnMoveBackward, GoInDoc );
+ }
+ //anchor position has to be inserted after the text attribute has been inserted
+ aNewAnchor.SetAnchor( aPam.GetPoint() );
+ aSet.Put( aNewAnchor );
+ pFormat->SetFormatAttr(aSet);
+ bSetAttr = false;
+ }
+ if( text::TextContentAnchorType_AS_CHARACTER == eNewAnchor &&
+ (RndStdIds::FLY_AS_CHAR != eOldAnchorId))
+ {
+ SwPaM aPam(pDoc->GetNodes().GetEndOfContent());
+ if( pDoc->getIDocumentLayoutAccess().GetCurrentLayout() )
+ {
+ SwCursorMoveState aState( CursorMoveState::SetOnlyText );
+ Point aTmp( pObj->GetSnapRect().TopLeft() );
+ pDoc->getIDocumentLayoutAccess().GetCurrentLayout()->GetModelPositionForViewPoint( aPam.GetPoint(), aTmp, &aState );
+ }
+ else
+ {
+ //without access to the layout the last node of the body will be used as anchor position
+ aPam.Move( fnMoveBackward, GoInDoc );
+ }
+ //the RES_TXTATR_FLYCNT needs to be added now
+ SwTextNode *pNd = aPam.GetPointNode().GetTextNode();
+ SAL_WARN_IF( !pNd, "sw.uno", "Cursor is not in a TextNode." );
+ SwFormatFlyCnt aFormat( pFlyFormat );
+ pNd->InsertItem(aFormat,
+ aPam.GetPoint()->GetContentIndex(), 0 );
+ aPam.GetPoint()->AdjustContent(-1); // InsertItem moved it
+ SwFormatAnchor aNewAnchor(
+ aSet.Get(RES_ANCHOR));
+ aNewAnchor.SetAnchor( aPam.GetPoint() );
+ aSet.Put( aNewAnchor );
+ }
+ if( bSetAttr )
+ pFormat->SetFormatAttr(aSet);
+
+ // If this property is an anchor change, and there is a group shape with textboxes
+ // do anchor sync in time unless the anchor sync in the porfly will cause crash during
+ // layout calculation (When importing an inline shape in docx via dmapper).
+ if (pFormat->Which() == RES_DRAWFRMFMT && pFormat->GetOtherTextBoxFormats())
+ {
+ SwTextBoxHelper::synchronizeGroupTextBoxProperty(
+ SwTextBoxHelper::changeAnchor, pFormat,
+ SdrObject::getSdrObjectFromXShape(mxShape));
+ }
+ }
+ else
+ pFormat->SetFormatAttr(aSet);
+ }
+
+ // We have a pFormat and a pEntry as well: try to sync TextBox property.
+ SwTextBoxHelper::syncProperty(pFormat, pEntry->nWID, pEntry->nMemberId, aValue,
+ SdrObject::getSdrObjectFromXShape(mxShape));
+ }
+ else
+ {
+ SfxPoolItem* pItem = nullptr;
+ switch(pEntry->nWID)
+ {
+ case RES_ANCHOR:
+ pItem = m_pImpl->GetAnchor(true);
+ break;
+ case RES_HORI_ORIENT:
+ pItem = m_pImpl->GetHOrient(true);
+ break;
+ case RES_VERT_ORIENT:
+ pItem = m_pImpl->GetVOrient(true);
+ break;
+ case RES_LR_SPACE:
+ pItem = m_pImpl->GetLRSpace(true);
+ break;
+ case RES_UL_SPACE:
+ pItem = m_pImpl->GetULSpace(true);
+ break;
+ case RES_SURROUND:
+ pItem = m_pImpl->GetSurround(true);
+ break;
+ case FN_TEXT_RANGE:
+ if(auto tr = o3tl::tryAccess<
+ uno::Reference<text::XTextRange>>(aValue))
+ {
+ uno::Reference< text::XTextRange > & rRange = m_pImpl->GetTextRange();
+ rRange = *tr;
+ }
+ break;
+ case RES_OPAQUE :
+ m_pImpl->SetOpaque(*o3tl::doAccess<bool>(aValue));
+ break;
+ // #i26791#
+ case RES_FOLLOW_TEXT_FLOW:
+ {
+ pItem = m_pImpl->GetFollowTextFlow( true );
+ }
+ break;
+ // #i28701#
+ case RES_WRAP_INFLUENCE_ON_OBJPOS:
+ {
+ pItem = m_pImpl->GetWrapInfluenceOnObjPos( true );
+ }
+ break;
+ // #i28749#
+ case FN_SHAPE_POSITION_LAYOUT_DIR :
+ {
+ sal_Int16 nPositionLayoutDir = 0;
+ aValue >>= nPositionLayoutDir;
+ m_pImpl->SetPositionLayoutDir( nPositionLayoutDir );
+ }
+ break;
+ }
+ if(pItem)
+ pItem->PutValue(aValue, pEntry->nMemberId);
+ }
+ }
+ else
+ {
+ const uno::Type& rPSetType =
+ cppu::UnoType<beans::XPropertySet>::get();
+ uno::Any aPSet = m_xShapeAgg->queryAggregation(rPSetType);
+ auto xPrSet = o3tl::tryAccess<uno::Reference<beans::XPropertySet>>(
+ aPSet);
+ if(!xPrSet)
+ throw uno::RuntimeException();
+ // #i31698# - setting the caption point of a
+ // caption object doesn't have to change the object position.
+ // Thus, keep the position, before the caption point is set and
+ // restore it afterwards.
+ awt::Point aKeepedPosition( 0, 0 );
+ if ( rPropertyName == "CaptionPoint" && getShapeType() == "com.sun.star.drawing.CaptionShape" )
+ {
+ aKeepedPosition = getPosition();
+ }
+ if( pFormat && pFormat->GetDoc()->getIDocumentLayoutAccess().GetCurrentViewShell() )
+ {
+ UnoActionContext aCtx(pFormat->GetDoc());
+ (*xPrSet)->setPropertyValue(rPropertyName, aValue);
+ }
+ else
+ (*xPrSet)->setPropertyValue(rPropertyName, aValue);
+
+ if (pFormat)
+ {
+ // We have a pFormat (but no pEntry): try to sync TextBox property.
+ SwTextBoxHelper::syncProperty(pFormat, rPropertyName, aValue,
+ SdrObject::getSdrObjectFromXShape(mxShape));
+ }
+
+ // #i31698# - restore object position, if caption point is set.
+ if ( rPropertyName == "CaptionPoint" && getShapeType() == "com.sun.star.drawing.CaptionShape" )
+ {
+ setPosition( aKeepedPosition );
+ }
+ }
+}
+
+uno::Any SwXShape::getPropertyValue(const OUString& rPropertyName)
+{
+ SolarMutexGuard aGuard;
+ uno::Any aRet;
+ SwFrameFormat* pFormat = GetFrameFormat();
+ if(m_xShapeAgg.is())
+ {
+ const SfxItemPropertyMapEntry* pEntry = m_pPropSet->getPropertyMap().getByName( rPropertyName );
+ if(pEntry)
+ {
+ if(pFormat)
+ {
+ if(RES_OPAQUE == pEntry->nWID)
+ {
+ SvxShape* pSvxShape = GetSvxShape();
+ OSL_ENSURE(pSvxShape, "No SvxShape found!");
+ if(pSvxShape)
+ {
+ SdrObject* pObj = pSvxShape->GetSdrObject();
+ // consider invisible layers
+ aRet <<=
+ ( pObj->GetLayer() != pFormat->GetDoc()->getIDocumentDrawModelAccess().GetHellId() &&
+ pObj->GetLayer() != pFormat->GetDoc()->getIDocumentDrawModelAccess().GetInvisibleHellId() );
+ }
+ }
+ else if(FN_ANCHOR_POSITION == pEntry->nWID)
+ {
+ SvxShape* pSvxShape = GetSvxShape();
+ OSL_ENSURE(pSvxShape, "No SvxShape found!");
+ if(pSvxShape)
+ {
+ SdrObject* pObj = pSvxShape->GetSdrObject();
+ Point aPt = pObj->GetAnchorPos();
+ awt::Point aPoint( convertTwipToMm100( aPt.X() ),
+ convertTwipToMm100( aPt.Y() ) );
+ aRet <<= aPoint;
+ }
+ }
+ // #i26791# - special handling for FN_TEXT_RANGE
+ else if ( FN_TEXT_RANGE == pEntry->nWID )
+ {
+ const SwFormatAnchor aAnchor = pFormat->GetAnchor();
+ if (aAnchor.GetAnchorId() == RndStdIds::FLY_AT_PAGE)
+ {
+ // return nothing, because property <TextRange> isn't
+ // valid for to-page anchored shapes
+ uno::Any aAny;
+ aRet = aAny;
+ }
+ else
+ {
+ if ( aAnchor.GetAnchorNode() )
+ {
+ const rtl::Reference<SwXTextRange> xTextRange
+ = SwXTextRange::CreateXTextRange(
+ *pFormat->GetDoc(),
+ *aAnchor.GetContentAnchor(),
+ nullptr );
+ aRet <<= uno::Reference<text::XTextRange>(xTextRange);
+ }
+ else
+ {
+ // return nothing
+ uno::Any aAny;
+ aRet = aAny;
+ }
+ }
+ }
+ else if (pEntry->nWID == FN_TEXT_BOX)
+ {
+ if (pEntry->nMemberId == MID_TEXT_BOX)
+ {
+ auto pSvxShape = GetSvxShape();
+ bool bValue = SwTextBoxHelper::isTextBox(
+ pFormat, RES_DRAWFRMFMT,
+ ((pSvxShape && pSvxShape->GetSdrObject()) ? pSvxShape->GetSdrObject()
+ : pFormat->FindRealSdrObject()));
+ aRet <<= bValue;
+ }
+ else if (pEntry->nMemberId == MID_TEXT_BOX_CONTENT)
+ {
+ auto pObj = SdrObject::getSdrObjectFromXShape(mxShape);
+ auto xRange = SwTextBoxHelper::queryInterface(
+ pFormat, cppu::UnoType<text::XText>::get(),
+ pObj ? pObj : pFormat->FindRealSdrObject());
+ uno::Reference<text::XTextFrame> xFrame(xRange, uno::UNO_QUERY);
+ if (xFrame.is())
+ aRet <<= xFrame;
+ }
+ }
+ else if (pEntry->nWID == RES_CHAIN)
+ {
+ switch (pEntry->nMemberId)
+ {
+ case MID_CHAIN_PREVNAME:
+ case MID_CHAIN_NEXTNAME:
+ case MID_CHAIN_NAME:
+ SwTextBoxHelper::getProperty(pFormat, pEntry->nWID, pEntry->nMemberId, aRet);
+ break;
+ }
+ }
+ // #i28749#
+ else if ( FN_SHAPE_TRANSFORMATION_IN_HORI_L2R == pEntry->nWID )
+ {
+ // get property <::drawing::Shape::Transformation>
+ // without conversion to layout direction as below
+ aRet = _getPropAtAggrObj( "Transformation" );
+ }
+ else if ( FN_SHAPE_POSITION_LAYOUT_DIR == pEntry->nWID )
+ {
+ aRet <<= pFormat->GetPositionLayoutDir();
+ }
+ // #i36248#
+ else if ( FN_SHAPE_STARTPOSITION_IN_HORI_L2R == pEntry->nWID )
+ {
+ // get property <::drawing::Shape::StartPosition>
+ // without conversion to layout direction as below
+ aRet = _getPropAtAggrObj( "StartPosition" );
+ }
+ else if ( FN_SHAPE_ENDPOSITION_IN_HORI_L2R == pEntry->nWID )
+ {
+ // get property <::drawing::Shape::EndPosition>
+ // without conversion to layout direction as below
+ aRet = _getPropAtAggrObj( "EndPosition" );
+ }
+ else if (pEntry->nWID == RES_FRM_SIZE &&
+ (pEntry->nMemberId == MID_FRMSIZE_REL_HEIGHT ||
+ pEntry->nMemberId == MID_FRMSIZE_REL_WIDTH ||
+ pEntry->nMemberId == MID_FRMSIZE_REL_HEIGHT_RELATION ||
+ pEntry->nMemberId == MID_FRMSIZE_REL_WIDTH_RELATION))
+ {
+ SvxShape* pSvxShape = GetSvxShape();
+ SAL_WARN_IF(!pSvxShape, "sw.uno", "No SvxShape found!");
+ sal_Int16 nRet = 0;
+ if (pSvxShape)
+ {
+ SdrObject* pObj = pSvxShape->GetSdrObject();
+ switch (pEntry->nMemberId)
+ {
+ case MID_FRMSIZE_REL_WIDTH:
+ if (pObj->GetRelativeWidth())
+ nRet = *pObj->GetRelativeWidth() * 100;
+ break;
+ case MID_FRMSIZE_REL_HEIGHT:
+ if (pObj->GetRelativeHeight())
+ nRet = *pObj->GetRelativeHeight() * 100;
+ break;
+ case MID_FRMSIZE_REL_WIDTH_RELATION:
+ nRet = pObj->GetRelativeWidthRelation();
+ break;
+ case MID_FRMSIZE_REL_HEIGHT_RELATION:
+ nRet = pObj->GetRelativeHeightRelation();
+ break;
+ }
+ }
+ aRet <<= nRet;
+ }
+ else
+ {
+ const SwAttrSet& rSet = pFormat->GetAttrSet();
+ m_pPropSet->getPropertyValue(*pEntry, rSet, aRet);
+ }
+ }
+ else
+ {
+ SfxPoolItem* pItem = nullptr;
+ switch(pEntry->nWID)
+ {
+ case RES_ANCHOR:
+ pItem = m_pImpl->GetAnchor();
+ break;
+ case RES_HORI_ORIENT:
+ pItem = m_pImpl->GetHOrient();
+ break;
+ case RES_VERT_ORIENT:
+ pItem = m_pImpl->GetVOrient();
+ break;
+ case RES_LR_SPACE:
+ pItem = m_pImpl->GetLRSpace();
+ break;
+ case RES_UL_SPACE:
+ pItem = m_pImpl->GetULSpace();
+ break;
+ case RES_SURROUND:
+ pItem = m_pImpl->GetSurround();
+ break;
+ case FN_TEXT_RANGE :
+ aRet <<= m_pImpl->GetTextRange();
+ break;
+ case RES_OPAQUE :
+ aRet <<= m_pImpl->GetOpaque();
+ break;
+ case FN_ANCHOR_POSITION :
+ {
+ aRet <<= awt::Point();
+ }
+ break;
+ // #i26791#
+ case RES_FOLLOW_TEXT_FLOW :
+ {
+ pItem = m_pImpl->GetFollowTextFlow();
+ }
+ break;
+ // #i28701#
+ case RES_WRAP_INFLUENCE_ON_OBJPOS:
+ {
+ pItem = m_pImpl->GetWrapInfluenceOnObjPos();
+ }
+ break;
+ // #i28749#
+ case FN_SHAPE_TRANSFORMATION_IN_HORI_L2R:
+ {
+ // get property <::drawing::Shape::Transformation>
+ // without conversion to layout direction as below
+ aRet = _getPropAtAggrObj( "Transformation" );
+ }
+ break;
+ case FN_SHAPE_POSITION_LAYOUT_DIR:
+ {
+ aRet <<= m_pImpl->GetPositionLayoutDir();
+ }
+ break;
+ // #i36248#
+ case FN_SHAPE_STARTPOSITION_IN_HORI_L2R:
+ {
+ // get property <::drawing::Shape::StartPosition>
+ // without conversion to layout direction as below
+ aRet = _getPropAtAggrObj( "StartPosition" );
+ }
+ break;
+ case FN_SHAPE_ENDPOSITION_IN_HORI_L2R:
+ {
+ // get property <::drawing::Shape::StartPosition>
+ // without conversion to layout direction as below
+ aRet = _getPropAtAggrObj( "EndPosition" );
+ }
+ break;
+ }
+ if(pItem)
+ pItem->QueryValue(aRet, pEntry->nMemberId);
+ }
+ }
+ else
+ {
+ aRet = _getPropAtAggrObj( rPropertyName );
+
+ // #i31698# - convert the position (translation)
+ // of the drawing object in the transformation
+ if ( rPropertyName == "Transformation" )
+ {
+ drawing::HomogenMatrix3 aMatrix;
+ aRet >>= aMatrix;
+ aRet <<= ConvertTransformationToLayoutDir( aMatrix );
+ }
+ // #i36248#
+ else if ( rPropertyName == "StartPosition" )
+ {
+ awt::Point aStartPos;
+ aRet >>= aStartPos;
+ // #i59051#
+ aRet <<= ConvertStartOrEndPosToLayoutDir( aStartPos );
+ }
+ else if ( rPropertyName == "EndPosition" )
+ {
+ awt::Point aEndPos;
+ aRet >>= aEndPos;
+ // #i59051#
+ aRet <<= ConvertStartOrEndPosToLayoutDir( aEndPos );
+ }
+ // #i59051#
+ else if ( rPropertyName == "PolyPolygonBezier" )
+ {
+ drawing::PolyPolygonBezierCoords aPath;
+ aRet >>= aPath;
+ aRet <<= ConvertPolyPolygonBezierToLayoutDir( aPath );
+ }
+ else if (rPropertyName == "ZOrder")
+ {
+ // Convert the real draw page position to the logical one that ignores textboxes.
+ if (pFormat)
+ {
+ const SdrObject* pObj = pFormat->FindRealSdrObject();
+ if (pObj)
+ {
+ bool bConvert = true;
+ if (SvxShape* pSvxShape = GetSvxShape())
+ // In case of group shapes, pSvxShape points to the child shape, while pObj points to the outermost group shape.
+ if (pSvxShape->GetSdrObject() != pObj)
+ // Textboxes are not expected inside group shapes, so no conversion is necessary there.
+ bConvert = false;
+ if (bConvert)
+ {
+ aRet <<= SwTextBoxHelper::getOrdNum(pObj);
+ }
+ }
+ }
+ }
+ }
+ }
+ return aRet;
+}
+
+uno::Any SwXShape::_getPropAtAggrObj( const OUString& _rPropertyName )
+{
+ uno::Any aRet;
+
+ const uno::Type& rPSetType =
+ cppu::UnoType<beans::XPropertySet>::get();
+ uno::Any aPSet = m_xShapeAgg->queryAggregation(rPSetType);
+ auto xPrSet = o3tl::tryAccess<uno::Reference<beans::XPropertySet>>(aPSet);
+ if ( !xPrSet )
+ {
+ throw uno::RuntimeException();
+ }
+ aRet = (*xPrSet)->getPropertyValue( _rPropertyName );
+
+ return aRet;
+}
+
+beans::PropertyState SwXShape::getPropertyState( const OUString& rPropertyName )
+{
+ SolarMutexGuard aGuard;
+ uno::Sequence< OUString > aNames { rPropertyName };
+ uno::Sequence< beans::PropertyState > aStates = getPropertyStates(aNames);
+ return aStates.getConstArray()[0];
+}
+
+uno::Sequence< beans::PropertyState > SwXShape::getPropertyStates(
+ const uno::Sequence< OUString >& aPropertyNames )
+{
+ SolarMutexGuard aGuard;
+ SwFrameFormat* pFormat = GetFrameFormat();
+ uno::Sequence< beans::PropertyState > aRet(aPropertyNames.getLength());
+ if(!m_xShapeAgg.is())
+ throw uno::RuntimeException();
+
+ SvxShape* pSvxShape = GetSvxShape();
+ bool bGroupMember = false;
+ bool bFormControl = false;
+ SdrObject* pObject = pSvxShape ? pSvxShape->GetSdrObject() : nullptr;
+ if(pObject)
+ {
+ bGroupMember = pObject->getParentSdrObjectFromSdrObject() != nullptr;
+ bFormControl = pObject->GetObjInventor() == SdrInventor::FmForm;
+ }
+ const OUString* pNames = aPropertyNames.getConstArray();
+ beans::PropertyState* pRet = aRet.getArray();
+ uno::Reference< XPropertyState > xShapePrState;
+ for(sal_Int32 nProperty = 0; nProperty < aPropertyNames.getLength(); nProperty++)
+ {
+ const SfxItemPropertyMapEntry* pEntry = m_pPropSet->getPropertyMap().getByName( pNames[nProperty] );
+ if(pEntry)
+ {
+ if(RES_OPAQUE == pEntry->nWID)
+ pRet[nProperty] = bFormControl ?
+ beans::PropertyState_DEFAULT_VALUE : beans::PropertyState_DIRECT_VALUE;
+ else if(FN_ANCHOR_POSITION == pEntry->nWID)
+ pRet[nProperty] = beans::PropertyState_DIRECT_VALUE;
+ else if(FN_TEXT_RANGE == pEntry->nWID)
+ pRet[nProperty] = beans::PropertyState_DIRECT_VALUE;
+ else if(bGroupMember)
+ pRet[nProperty] = beans::PropertyState_DEFAULT_VALUE;
+ else if (pEntry->nWID == RES_FRM_SIZE &&
+ (pEntry->nMemberId == MID_FRMSIZE_REL_HEIGHT_RELATION ||
+ pEntry->nMemberId == MID_FRMSIZE_REL_WIDTH_RELATION))
+ pRet[nProperty] = beans::PropertyState_DIRECT_VALUE;
+ else if (pEntry->nWID == FN_TEXT_BOX)
+ {
+ // The TextBox property is set, if we can find a textbox for this shape.
+ if (pFormat
+ && SwTextBoxHelper::isTextBox(pFormat, RES_DRAWFRMFMT,
+ SdrObject::getSdrObjectFromXShape(mxShape)))
+ pRet[nProperty] = beans::PropertyState_DIRECT_VALUE;
+ else
+ pRet[nProperty] = beans::PropertyState_DEFAULT_VALUE;
+ }
+ else if(pFormat)
+ {
+ const SwAttrSet& rSet = pFormat->GetAttrSet();
+ SfxItemState eItemState = rSet.GetItemState(pEntry->nWID, false);
+
+ if(SfxItemState::SET == eItemState)
+ pRet[nProperty] = beans::PropertyState_DIRECT_VALUE;
+ else if(SfxItemState::DEFAULT == eItemState)
+ pRet[nProperty] = beans::PropertyState_DEFAULT_VALUE;
+ else
+ pRet[nProperty] = beans::PropertyState_AMBIGUOUS_VALUE;
+ }
+ else
+ {
+ SfxPoolItem* pItem = nullptr;
+ switch(pEntry->nWID)
+ {
+ case RES_ANCHOR:
+ pItem = m_pImpl->GetAnchor();
+ break;
+ case RES_HORI_ORIENT:
+ pItem = m_pImpl->GetHOrient();
+ break;
+ case RES_VERT_ORIENT:
+ pItem = m_pImpl->GetVOrient();
+ break;
+ case RES_LR_SPACE:
+ pItem = m_pImpl->GetLRSpace();
+ break;
+ case RES_UL_SPACE:
+ pItem = m_pImpl->GetULSpace();
+ break;
+ case RES_SURROUND:
+ pItem = m_pImpl->GetSurround();
+ break;
+ // #i28701#
+ case RES_WRAP_INFLUENCE_ON_OBJPOS:
+ {
+ pItem = m_pImpl->GetWrapInfluenceOnObjPos();
+ }
+ break;
+ }
+ if(pItem)
+ pRet[nProperty] = beans::PropertyState_DIRECT_VALUE;
+ else
+ pRet[nProperty] = beans::PropertyState_DEFAULT_VALUE;
+ }
+ }
+ else
+ {
+ if(!xShapePrState.is())
+ {
+ const uno::Type& rPStateType = cppu::UnoType<XPropertyState>::get();
+ uno::Any aPState = m_xShapeAgg->queryAggregation(rPStateType);
+ auto ps = o3tl::tryAccess<uno::Reference<XPropertyState>>(
+ aPState);
+ if(!ps)
+ throw uno::RuntimeException();
+ xShapePrState = *ps;
+ }
+ pRet[nProperty] = xShapePrState->getPropertyState(pNames[nProperty]);
+ }
+ }
+
+ return aRet;
+}
+
+void SwXShape::setPropertyToDefault( const OUString& rPropertyName )
+{
+ SolarMutexGuard aGuard;
+ SwFrameFormat* pFormat = GetFrameFormat();
+ if(!m_xShapeAgg.is())
+ throw uno::RuntimeException();
+
+ const SfxItemPropertyMapEntry* pEntry = m_pPropSet->getPropertyMap().getByName( rPropertyName );
+ if(pEntry)
+ {
+ if ( pEntry->nFlags & beans::PropertyAttribute::READONLY)
+ throw uno::RuntimeException("Property is read-only: " + rPropertyName, getXWeak() );
+ if(pFormat)
+ {
+ const SfxItemSet& rSet = pFormat->GetAttrSet();
+ SfxItemSet aSet(pFormat->GetDoc()->GetAttrPool(), pEntry->nWID, pEntry->nWID);
+ aSet.SetParent(&rSet);
+ aSet.ClearItem(pEntry->nWID);
+ pFormat->GetDoc()->SetAttr(aSet, *pFormat);
+ }
+ else
+ {
+ switch(pEntry->nWID)
+ {
+ case RES_ANCHOR: m_pImpl->RemoveAnchor(); break;
+ case RES_HORI_ORIENT: m_pImpl->RemoveHOrient(); break;
+ case RES_VERT_ORIENT: m_pImpl->RemoveVOrient(); break;
+ case RES_LR_SPACE: m_pImpl->RemoveLRSpace(); break;
+ case RES_UL_SPACE: m_pImpl->RemoveULSpace(); break;
+ case RES_SURROUND: m_pImpl->RemoveSurround();break;
+ case RES_OPAQUE : m_pImpl->SetOpaque(false); break;
+ case FN_TEXT_RANGE :
+ break;
+ // #i26791#
+ case RES_FOLLOW_TEXT_FLOW:
+ {
+ m_pImpl->RemoveFollowTextFlow();
+ }
+ break;
+ // #i28701#
+ case RES_WRAP_INFLUENCE_ON_OBJPOS:
+ {
+ m_pImpl->RemoveWrapInfluenceOnObjPos();
+ }
+ break;
+ }
+ }
+ }
+ else
+ {
+ const uno::Type& rPStateType = cppu::UnoType<XPropertyState>::get();
+ uno::Any aPState = m_xShapeAgg->queryAggregation(rPStateType);
+ auto xShapePrState = o3tl::tryAccess<uno::Reference<XPropertyState>>(
+ aPState);
+ if(!xShapePrState)
+ throw uno::RuntimeException();
+ (*xShapePrState)->setPropertyToDefault( rPropertyName );
+ }
+
+}
+
+uno::Any SwXShape::getPropertyDefault( const OUString& rPropertyName )
+{
+ SolarMutexGuard aGuard;
+ SwFrameFormat* pFormat = GetFrameFormat();
+ uno::Any aRet;
+ if(!m_xShapeAgg.is())
+ throw uno::RuntimeException();
+
+ const SfxItemPropertyMapEntry* pEntry = m_pPropSet->getPropertyMap().getByName( rPropertyName );
+ if(pEntry)
+ {
+ if(!(pEntry->nWID < RES_FRMATR_END && pFormat))
+ throw uno::RuntimeException();
+
+ const SfxPoolItem& rDefItem =
+ pFormat->GetDoc()->GetAttrPool().GetDefaultItem(pEntry->nWID);
+ rDefItem.QueryValue(aRet, pEntry->nMemberId);
+
+ }
+ else
+ {
+ const uno::Type& rPStateType = cppu::UnoType<XPropertyState>::get();
+ uno::Any aPState = m_xShapeAgg->queryAggregation(rPStateType);
+ auto xShapePrState = o3tl::tryAccess<uno::Reference<XPropertyState>>(
+ aPState);
+ if(!xShapePrState)
+ throw uno::RuntimeException();
+ (*xShapePrState)->getPropertyDefault( rPropertyName );
+ }
+
+ return aRet;
+}
+
+void SwXShape::addPropertyChangeListener(
+ const OUString& _propertyName,
+ const uno::Reference< beans::XPropertyChangeListener > & _listener )
+{
+ if ( !m_xShapeAgg.is() )
+ throw uno::RuntimeException("no shape aggregate", *this );
+
+ // must be handled by the aggregate
+ uno::Reference< beans::XPropertySet > xShapeProps;
+ if ( m_xShapeAgg->queryAggregation( cppu::UnoType<beans::XPropertySet>::get() ) >>= xShapeProps )
+ xShapeProps->addPropertyChangeListener( _propertyName, _listener );
+}
+
+void SwXShape::removePropertyChangeListener(
+ const OUString& _propertyName,
+ const uno::Reference< beans::XPropertyChangeListener > & _listener)
+{
+ if ( !m_xShapeAgg.is() )
+ throw uno::RuntimeException("no shape aggregate", *this );
+
+ // must be handled by the aggregate
+ uno::Reference< beans::XPropertySet > xShapeProps;
+ if ( m_xShapeAgg->queryAggregation( cppu::UnoType<beans::XPropertySet>::get() ) >>= xShapeProps )
+ xShapeProps->removePropertyChangeListener( _propertyName, _listener );
+}
+
+void SwXShape::addVetoableChangeListener(
+ const OUString& /*PropertyName*/,
+ const uno::Reference< beans::XVetoableChangeListener > & /*aListener*/ )
+{
+ OSL_FAIL("not implemented");
+}
+
+void SwXShape::removeVetoableChangeListener(
+ const OUString& /*PropertyName*/,
+ const uno::Reference< beans::XVetoableChangeListener > & /*aListener*/)
+{
+ OSL_FAIL("not implemented");
+}
+
+void SwXShape::attach(const uno::Reference< text::XTextRange > & xTextRange)
+{
+ SolarMutexGuard aGuard;
+
+ // get access to SwDoc
+ // (see also SwXTextRange::XTextRangeToSwPaM)
+ const SwDoc* pDoc = nullptr;
+ if (auto pRange = dynamic_cast<SwXTextRange*>(xTextRange.get()))
+ pDoc = &pRange->GetDoc();
+ else if (auto pText = dynamic_cast<SwXText*>(xTextRange.get()))
+ pDoc = pText->GetDoc();
+ else if (auto pCursor = dynamic_cast<OTextCursorHelper*>(xTextRange.get()))
+ pDoc = pCursor->GetDoc();
+ else if (auto pPortion = dynamic_cast<SwXTextPortion*>(xTextRange.get()))
+ pDoc = &pPortion->GetCursor().GetDoc();
+ else if (auto pParagraph = dynamic_cast<SwXParagraph*>(xTextRange.get());
+ pParagraph && pParagraph->GetTextNode())
+ pDoc = &pParagraph->GetTextNode()->GetDoc();
+
+ if(!pDoc)
+ throw uno::RuntimeException();
+ const SwDocShell* pDocSh = pDoc->GetDocShell();
+ if (!pDocSh)
+ return;
+
+ uno::Reference<frame::XModel> xModel = pDocSh->GetModel();
+ uno::Reference< drawing::XDrawPageSupplier > xDPS(xModel, uno::UNO_QUERY);
+ if (xDPS.is())
+ {
+ uno::Reference< drawing::XDrawPage > xDP( xDPS->getDrawPage() );
+ if (xDP.is())
+ {
+ uno::Any aPos;
+ aPos <<= xTextRange;
+ setPropertyValue("TextRange", aPos);
+ uno::Reference< drawing::XShape > xTemp( getXWeak(), uno::UNO_QUERY );
+ xDP->add( xTemp );
+ }
+ }
+}
+
+uno::Reference< text::XTextRange > SwXShape::getAnchor()
+{
+ SolarMutexGuard aGuard;
+ uno::Reference< text::XTextRange > aRef;
+ SwFrameFormat* pFormat = GetFrameFormat();
+ if(pFormat)
+ {
+ const SwFormatAnchor& rAnchor = pFormat->GetAnchor();
+ // return an anchor for non-page bound frames
+ // and for page bound frames that have a page no == NULL and a content position
+ if ((rAnchor.GetAnchorId() != RndStdIds::FLY_AT_PAGE) ||
+ (rAnchor.GetAnchorNode() && !rAnchor.GetPageNum()))
+ {
+ if (rAnchor.GetAnchorId() == RndStdIds::FLY_AT_PARA)
+ { // ensure that SwXTextRange has SwContentIndex
+ const SwNode* pAnchorNode = rAnchor.GetAnchorNode();
+ aRef = SwXTextRange::CreateXTextRange(*pFormat->GetDoc(), SwPosition(*pAnchorNode), nullptr);
+ }
+ else
+ {
+ aRef = SwXTextRange::CreateXTextRange(*pFormat->GetDoc(), *rAnchor.GetContentAnchor(), nullptr);
+ }
+ }
+ }
+ else
+ aRef = m_pImpl->GetTextRange().get();
+ return aRef;
+}
+
+void SwXShape::dispose()
+{
+ SolarMutexGuard aGuard;
+ SwFrameFormat* pFormat = GetFrameFormat();
+ if(pFormat)
+ {
+ // determine correct <SdrObject>
+ SvxShape* pSvxShape = GetSvxShape();
+ SdrObject* pObj = pSvxShape ? pSvxShape->GetSdrObject() : nullptr;
+ // safety assertion:
+ // <pObj> must be the same as <pFormat->FindSdrObject()>, if <pObj> isn't
+ // a 'virtual' drawing object.
+ // correct assertion and refine it for safety reason.
+ OSL_ENSURE( !pObj ||
+ dynamic_cast<const SwDrawVirtObj*>( pObj) != nullptr ||
+ pObj->getParentSdrObjectFromSdrObject() ||
+ pObj == pFormat->FindSdrObject(),
+ "<SwXShape::dispose(..) - different 'master' drawing objects!!" );
+ // perform delete of draw frame format *not*
+ // for 'virtual' drawing objects.
+ // no delete of draw format for members
+ // of a group
+ if ( pObj &&
+ dynamic_cast<const SwDrawVirtObj*>( pObj) == nullptr &&
+ !pObj->getParentSdrObjectFromSdrObject() &&
+ pObj->IsInserted() )
+ {
+ const SwFormatAnchor& rFormatAnchor = pFormat->GetAnchor();
+ if (rFormatAnchor.GetAnchorId() == RndStdIds::FLY_AS_CHAR)
+ {
+ SwTextNode *pTextNode = rFormatAnchor.GetAnchorNode()->GetTextNode();
+ const sal_Int32 nIdx = rFormatAnchor.GetAnchorContentOffset();
+ pTextNode->DeleteAttributes( RES_TXTATR_FLYCNT, nIdx );
+ }
+ else
+ pFormat->GetDoc()->getIDocumentLayoutAccess().DelLayoutFormat( pFormat );
+ }
+ }
+ if(m_xShapeAgg.is())
+ {
+ uno::Any aAgg(m_xShapeAgg->queryAggregation( cppu::UnoType<XComponent>::get()));
+ uno::Reference<XComponent> xComp;
+ aAgg >>= xComp;
+ if(xComp.is())
+ xComp->dispose();
+ }
+ if(m_pPage)
+ {
+ auto pPage = const_cast<SwFmDrawPage*>(m_pPage);
+ m_pPage = nullptr;
+ pPage->RemoveShape(this);
+ }
+}
+
+void SwXShape::addEventListener(
+ const uno::Reference< lang::XEventListener > & aListener)
+{
+ SvxShape* pSvxShape = GetSvxShape();
+ if(pSvxShape)
+ pSvxShape->addEventListener(aListener);
+}
+
+void SwXShape::removeEventListener(
+ const uno::Reference< lang::XEventListener > & aListener)
+{
+ SvxShape* pSvxShape = GetSvxShape();
+ if(pSvxShape)
+ pSvxShape->removeEventListener(aListener);
+}
+
+OUString SwXShape::getImplementationName()
+{
+ return "SwXShape";
+}
+
+sal_Bool SwXShape::supportsService(const OUString& rServiceName)
+{
+ return cppu::supportsService(this, rServiceName);
+}
+
+uno::Sequence< OUString > SwXShape::getSupportedServiceNames()
+{
+ uno::Sequence< OUString > aSeq;
+ if (SvxShape* pSvxShape = GetSvxShape())
+ aSeq = pSvxShape->getSupportedServiceNames();
+ return comphelper::concatSequences(
+ aSeq, std::initializer_list<std::u16string_view>{ u"com.sun.star.drawing.Shape" });
+}
+
+SvxShape* SwXShape::GetSvxShape()
+{
+ if(m_xShapeAgg.is())
+ return comphelper::getFromUnoTunnel<SvxShape>(m_xShapeAgg);
+ return nullptr;
+}
+
+// #i31698#
+// implementation of virtual methods from drawing::XShape
+awt::Point SAL_CALL SwXShape::getPosition()
+{
+ awt::Point aPos( GetAttrPosition() );
+
+ // handle group members
+ SvxShape* pSvxShape = GetSvxShape();
+ if ( pSvxShape )
+ {
+ SdrObject* pTopGroupObj = GetTopGroupObj( pSvxShape );
+ if ( pTopGroupObj )
+ {
+ // #i34750# - get attribute position of top group
+ // shape and add offset between top group object and group member
+ uno::Reference< drawing::XShape > xGroupShape( pTopGroupObj->getUnoShape(), uno::UNO_QUERY );
+ aPos = xGroupShape->getPosition();
+ // add offset between top group object and group member
+ // to the determined attribute position
+ // #i34750#:
+ // consider the layout direction
+ const tools::Rectangle aMemberObjRect = GetSvxShape()->GetSdrObject()->GetSnapRect();
+ const tools::Rectangle aGroupObjRect = pTopGroupObj->GetSnapRect();
+ // #i53320# - relative position of group member and
+ // top group object is always given in horizontal left-to-right layout.
+ awt::Point aOffset( 0, 0 );
+ {
+ aOffset.X = ( aMemberObjRect.Left() - aGroupObjRect.Left() );
+ aOffset.Y = ( aMemberObjRect.Top() - aGroupObjRect.Top() );
+ }
+ aOffset.X = convertTwipToMm100(aOffset.X);
+ aOffset.Y = convertTwipToMm100(aOffset.Y);
+ aPos.X += aOffset.X;
+ aPos.Y += aOffset.Y;
+ }
+ }
+
+ return aPos;
+}
+
+void SAL_CALL SwXShape::setPosition( const awt::Point& aPosition )
+{
+ SdrObject* pTopGroupObj = GetTopGroupObj();
+ if ( !pTopGroupObj )
+ {
+ // #i37877# - no adjustment of position attributes,
+ // if the position also has to be applied at the drawing object and
+ // a contact object is already registered at the drawing object.
+ bool bApplyPosAtDrawObj(false);
+ bool bNoAdjustOfPosProp(false);
+ // #i35798# - apply position also to drawing object,
+ // if drawing object has no anchor position set.
+ if ( mxShape.is() )
+ {
+ SvxShape* pSvxShape = GetSvxShape();
+ if ( pSvxShape )
+ {
+ const SdrObject* pObj = pSvxShape->GetSdrObject();
+ if ( pObj &&
+ pObj->GetAnchorPos().X() == 0 &&
+ pObj->GetAnchorPos().Y() == 0 )
+ {
+ bApplyPosAtDrawObj = true;
+ if ( pObj->GetUserCall() &&
+ dynamic_cast<const SwDrawContact*>( pObj->GetUserCall()) != nullptr )
+ {
+ bNoAdjustOfPosProp = true;
+ }
+ }
+ }
+ }
+ // shape isn't a group member. Thus, set positioning attributes
+ if ( !bNoAdjustOfPosProp )
+ {
+ AdjustPositionProperties( aPosition );
+ }
+ if ( bApplyPosAtDrawObj )
+ {
+ mxShape->setPosition( aPosition );
+ }
+ }
+ else if ( mxShape.is() )
+ {
+ // shape is a member of a group. Thus, set its position.
+ awt::Point aNewPos( aPosition );
+ // The given position is given in the according layout direction. Thus,
+ // it has to be converted to a position in horizontal left-to-right
+ // layout.
+ // convert given absolute attribute position in layout direction into
+ // position in horizontal left-to-right layout.
+ {
+ aNewPos = ConvertPositionToHoriL2R( aNewPos, getSize() );
+ }
+ // Convert given absolute position in horizontal left-to-right
+ // layout into relative position in horizontal left-to-right layout.
+ uno::Reference< drawing::XShape > xGroupShape( pTopGroupObj->getUnoShape(), uno::UNO_QUERY );
+ {
+ // #i34750#
+ // use method <xGroupShape->getPosition()> to get the correct
+ // position of the top group object.
+ awt::Point aAttrPosInHoriL2R(
+ ConvertPositionToHoriL2R( xGroupShape->getPosition(),
+ xGroupShape->getSize() ) );
+ aNewPos.X = o3tl::saturating_sub(aNewPos.X, aAttrPosInHoriL2R.X);
+ aNewPos.Y = o3tl::saturating_sub(aNewPos.Y, aAttrPosInHoriL2R.Y);
+ }
+ // convert relative position in horizontal left-to-right layout into
+ // absolute position in horizontal left-to-right layout
+ {
+ // #i34750#
+ // use method <SvxShape->getPosition()> to get the correct
+ // 'Drawing layer' position of the top group shape.
+ auto pSvxGroupShape = comphelper::getFromUnoTunnel<SvxShape>(pTopGroupObj->getUnoShape());
+ const awt::Point aGroupPos = pSvxGroupShape->getPosition();
+ aNewPos.X = o3tl::saturating_add(aNewPos.X, aGroupPos.X);
+ aNewPos.Y = o3tl::saturating_add(aNewPos.Y, aGroupPos.Y);
+ }
+ // set position
+ mxShape->setPosition( aNewPos );
+ }
+}
+
+awt::Size SAL_CALL SwXShape::getSize()
+{
+ awt::Size aSize;
+ if ( mxShape.is() )
+ {
+ aSize = mxShape->getSize();
+ }
+ return aSize;
+}
+
+void SAL_CALL SwXShape::setSize( const awt::Size& aSize )
+{
+ comphelper::ProfileZone aZone("SwXShape::setSize");
+
+ if ( mxShape.is() )
+ {
+ mxShape->setSize( aSize );
+ }
+ SwTextBoxHelper::syncProperty(GetFrameFormat(), RES_FRM_SIZE, MID_FRMSIZE_SIZE, uno::Any(aSize));
+}
+// #i31698#
+// implementation of virtual methods from drawing::XShapeDescriptor
+OUString SAL_CALL SwXShape::getShapeType()
+{
+ if ( mxShape.is() )
+ {
+ return mxShape->getShapeType();
+ }
+ return OUString();
+}
+/** method to determine top group object
+ #i31698#
+*/
+SdrObject* SwXShape::GetTopGroupObj( SvxShape* _pSvxShape )
+{
+ SdrObject* pTopGroupObj( nullptr );
+
+ SvxShape* pSvxShape = _pSvxShape ? _pSvxShape : GetSvxShape();
+ if ( pSvxShape )
+ {
+ SdrObject* pSdrObj = pSvxShape->GetSdrObject();
+ if ( pSdrObj && pSdrObj->getParentSdrObjectFromSdrObject() )
+ {
+ pTopGroupObj = pSdrObj->getParentSdrObjectFromSdrObject();
+ while ( pTopGroupObj->getParentSdrObjectFromSdrObject() )
+ {
+ pTopGroupObj = pTopGroupObj->getParentSdrObjectFromSdrObject();
+ }
+ }
+ }
+
+ return pTopGroupObj;
+}
+
+/** method to determine position according to the positioning attributes
+ #i31698#
+*/
+awt::Point SwXShape::GetAttrPosition()
+{
+ awt::Point aAttrPos;
+
+ uno::Any aHoriPos( getPropertyValue("HoriOrientPosition") );
+ aHoriPos >>= aAttrPos.X;
+ uno::Any aVertPos( getPropertyValue("VertOrientPosition") );
+ aVertPos >>= aAttrPos.Y;
+ // #i35798# - fallback, if attribute position is (0,0)
+ // and no anchor position is applied to the drawing object
+ SvxShape* pSvxShape = GetSvxShape();
+ if ( pSvxShape )
+ {
+ const SdrObject* pObj = pSvxShape->GetSdrObject();
+ if ( pObj &&
+ pObj->GetAnchorPos().X() == 0 &&
+ pObj->GetAnchorPos().Y() == 0 &&
+ aAttrPos.X == 0 && aAttrPos.Y == 0 )
+ {
+ const tools::Rectangle aObjRect = pObj->GetSnapRect();
+ aAttrPos.X = convertTwipToMm100(aObjRect.Left());
+ aAttrPos.Y = convertTwipToMm100(aObjRect.Top());
+ }
+ }
+ // #i35007# - If drawing object is anchored as-character,
+ // it's x-position isn't sensible. Thus, return the x-position as zero in this case.
+ text::TextContentAnchorType eTextAnchorType =
+ text::TextContentAnchorType_AT_PARAGRAPH;
+ {
+ uno::Any aAny = getPropertyValue( "AnchorType" );
+ aAny >>= eTextAnchorType;
+ }
+ if ( eTextAnchorType == text::TextContentAnchorType_AS_CHARACTER )
+ {
+ aAttrPos.X = 0;
+ }
+
+ return aAttrPos;
+}
+
+/** method to convert the position (translation) of the drawing object to
+ the layout direction horizontal left-to-right.
+ #i31698#
+*/
+awt::Point SwXShape::ConvertPositionToHoriL2R( const awt::Point& rObjPos,
+ const awt::Size& rObjSize )
+{
+ awt::Point aObjPosInHoriL2R( rObjPos );
+
+ SwFrameFormat* pFrameFormat = GetFrameFormat();
+ if ( pFrameFormat )
+ {
+ SwFrameFormat::tLayoutDir eLayoutDir = pFrameFormat->GetLayoutDir();
+ switch ( eLayoutDir )
+ {
+ case SwFrameFormat::HORI_L2R:
+ {
+ // nothing to do
+ }
+ break;
+ case SwFrameFormat::HORI_R2L:
+ {
+ aObjPosInHoriL2R.X = -rObjPos.X - rObjSize.Width;
+ }
+ break;
+ case SwFrameFormat::VERT_R2L:
+ {
+ aObjPosInHoriL2R.X = -rObjPos.Y - rObjSize.Width;
+ aObjPosInHoriL2R.Y = rObjPos.X;
+ }
+ break;
+ default:
+ {
+ OSL_FAIL( "<SwXShape::ConvertPositionToHoriL2R(..)> - unsupported layout direction" );
+ }
+ }
+ }
+
+ return aObjPosInHoriL2R;
+}
+
+/** method to convert the transformation of the drawing object to the layout
+ direction, the drawing object is in
+ #i31698#
+*/
+drawing::HomogenMatrix3 SwXShape::ConvertTransformationToLayoutDir(
+ const drawing::HomogenMatrix3& rMatrixInHoriL2R )
+{
+ drawing::HomogenMatrix3 aMatrix(rMatrixInHoriL2R);
+
+ // #i44334#, #i44681# - direct manipulation of the
+ // transformation structure isn't valid, if it contains rotation.
+ SvxShape* pSvxShape = GetSvxShape();
+ OSL_ENSURE( pSvxShape,
+ "<SwXShape::ConvertTransformationToLayoutDir(..)> - no SvxShape found!");
+ if ( pSvxShape )
+ {
+ const SdrObject* pObj = pSvxShape->GetSdrObject();
+ OSL_ENSURE( pObj,
+ "<SwXShape::ConvertTransformationToLayoutDir(..)> - no SdrObject found!");
+ if ( pObj )
+ {
+ // get position of object in Writer coordinate system.
+ awt::Point aPos( getPosition() );
+ // get position of object in Drawing layer coordinate system
+ const Point aTmpObjPos( pObj->GetSnapRect().TopLeft() );
+ const awt::Point aObjPos(
+ convertTwipToMm100( aTmpObjPos.X() - pObj->GetAnchorPos().X() ),
+ convertTwipToMm100( aTmpObjPos.Y() - pObj->GetAnchorPos().Y() ) );
+ // determine difference between these positions according to the
+ // Writer coordinate system
+ const awt::Point aTranslateDiff( aPos.X - aObjPos.X,
+ aPos.Y - aObjPos.Y );
+ // apply translation difference to transformation matrix.
+ if ( aTranslateDiff.X != 0 || aTranslateDiff.Y != 0 )
+ {
+ // #i73079# - use correct matrix type
+ ::basegfx::B2DHomMatrix aTempMatrix;
+
+ aTempMatrix.set(0, 0, aMatrix.Line1.Column1 );
+ aTempMatrix.set(0, 1, aMatrix.Line1.Column2 );
+ aTempMatrix.set(0, 2, aMatrix.Line1.Column3 );
+ aTempMatrix.set(1, 0, aMatrix.Line2.Column1 );
+ aTempMatrix.set(1, 1, aMatrix.Line2.Column2 );
+ aTempMatrix.set(1, 2, aMatrix.Line2.Column3 );
+ // For this to be a valid 2D transform matrix, the last row must be [0,0,1]
+ assert( aMatrix.Line3.Column1 == 0 );
+ assert( aMatrix.Line3.Column2 == 0 );
+ assert( aMatrix.Line3.Column3 == 1 );
+ // #i73079#
+ aTempMatrix.translate( aTranslateDiff.X, aTranslateDiff.Y );
+ aMatrix.Line1.Column1 = aTempMatrix.get(0, 0);
+ aMatrix.Line1.Column2 = aTempMatrix.get(0, 1);
+ aMatrix.Line1.Column3 = aTempMatrix.get(0, 2);
+ aMatrix.Line2.Column1 = aTempMatrix.get(1, 0);
+ aMatrix.Line2.Column2 = aTempMatrix.get(1, 1);
+ aMatrix.Line2.Column3 = aTempMatrix.get(1, 2);
+ aMatrix.Line3.Column1 = 0;
+ aMatrix.Line3.Column2 = 0;
+ aMatrix.Line3.Column3 = 1;
+ }
+ }
+ }
+
+ return aMatrix;
+}
+
+/** method to adjust the positioning properties
+ #i31698#
+*/
+void SwXShape::AdjustPositionProperties( const awt::Point& rPosition )
+{
+ // handle x-position
+ // #i35007# - no handling of x-position, if drawing
+ // object is anchored as-character, because it doesn't make sense.
+ text::TextContentAnchorType eTextAnchorType =
+ text::TextContentAnchorType_AT_PARAGRAPH;
+ {
+ uno::Any aAny = getPropertyValue( "AnchorType" );
+ aAny >>= eTextAnchorType;
+ }
+ if ( eTextAnchorType != text::TextContentAnchorType_AS_CHARACTER )
+ {
+ // determine current x-position
+ static constexpr OUString aHoriPosPropStr(u"HoriOrientPosition"_ustr);
+ uno::Any aHoriPos( getPropertyValue( aHoriPosPropStr ) );
+ sal_Int32 dCurrX = 0;
+ aHoriPos >>= dCurrX;
+ // change x-position attribute, if needed
+ if ( dCurrX != rPosition.X )
+ {
+ // adjust x-position orientation to text::HoriOrientation::NONE, if needed
+ // Note: has to be done before setting x-position attribute
+ static constexpr OUString aHoriOrientPropStr(u"HoriOrient"_ustr);
+ uno::Any aHoriOrient( getPropertyValue( aHoriOrientPropStr ) );
+ sal_Int16 eHoriOrient;
+ if (aHoriOrient >>= eHoriOrient) // may be void
+ {
+ if ( eHoriOrient != text::HoriOrientation::NONE )
+ {
+ eHoriOrient = text::HoriOrientation::NONE;
+ aHoriOrient <<= eHoriOrient;
+ setPropertyValue( aHoriOrientPropStr, aHoriOrient );
+ }
+ }
+ // set x-position attribute
+ aHoriPos <<= rPosition.X;
+ setPropertyValue( aHoriPosPropStr, aHoriPos );
+ }
+ }
+
+ // handle y-position
+ {
+ // determine current y-position
+ static constexpr OUString aVertPosPropStr(u"VertOrientPosition"_ustr);
+ uno::Any aVertPos( getPropertyValue( aVertPosPropStr ) );
+ sal_Int32 dCurrY = 0;
+ aVertPos >>= dCurrY;
+ // change y-position attribute, if needed
+ if ( dCurrY != rPosition.Y )
+ {
+ // adjust y-position orientation to text::VertOrientation::NONE, if needed
+ // Note: has to be done before setting y-position attribute
+ static constexpr OUString aVertOrientPropStr(u"VertOrient"_ustr);
+ uno::Any aVertOrient( getPropertyValue( aVertOrientPropStr ) );
+ sal_Int16 eVertOrient;
+ if (aVertOrient >>= eVertOrient) // may be void
+ {
+ if ( eVertOrient != text::VertOrientation::NONE )
+ {
+ eVertOrient = text::VertOrientation::NONE;
+ aVertOrient <<= eVertOrient;
+ setPropertyValue( aVertOrientPropStr, aVertOrient );
+ }
+ }
+ // set y-position attribute
+ aVertPos <<= rPosition.Y;
+ setPropertyValue( aVertPosPropStr, aVertPos );
+ }
+ }
+}
+
+/** method to convert start or end position of the drawing object to the
+ Writer specific position, which is the attribute position in layout direction
+ #i59051#
+*/
+css::awt::Point SwXShape::ConvertStartOrEndPosToLayoutDir(
+ const css::awt::Point& aStartOrEndPos )
+{
+ awt::Point aConvertedPos( aStartOrEndPos );
+
+ SvxShape* pSvxShape = GetSvxShape();
+ OSL_ENSURE( pSvxShape,
+ "<SwXShape::ConvertStartOrEndPosToLayoutDir(..)> - no SvxShape found!");
+ if ( pSvxShape )
+ {
+ const SdrObject* pObj = pSvxShape->GetSdrObject();
+ OSL_ENSURE( pObj,
+ "<SwXShape::ConvertStartOrEndPosToLayoutDir(..)> - no SdrObject found!");
+ if ( pObj )
+ {
+ // get position of object in Writer coordinate system.
+ awt::Point aPos( getPosition() );
+ // get position of object in Drawing layer coordinate system
+ const Point aTmpObjPos( pObj->GetSnapRect().TopLeft() );
+ const awt::Point aObjPos(
+ convertTwipToMm100( aTmpObjPos.X() - pObj->GetAnchorPos().X() ),
+ convertTwipToMm100( aTmpObjPos.Y() - pObj->GetAnchorPos().Y() ) );
+ // determine difference between these positions according to the
+ // Writer coordinate system
+ const awt::Point aTranslateDiff( aPos.X - aObjPos.X,
+ aPos.Y - aObjPos.Y );
+ // apply translation difference to transformation matrix.
+ if ( aTranslateDiff.X != 0 || aTranslateDiff.Y != 0 )
+ {
+ aConvertedPos.X = aConvertedPos.X + aTranslateDiff.X;
+ aConvertedPos.Y = aConvertedPos.Y + aTranslateDiff.Y;
+ }
+ }
+ }
+
+ return aConvertedPos;
+}
+
+css::drawing::PolyPolygonBezierCoords SwXShape::ConvertPolyPolygonBezierToLayoutDir(
+ const css::drawing::PolyPolygonBezierCoords& aPath )
+{
+ drawing::PolyPolygonBezierCoords aConvertedPath( aPath );
+
+ SvxShape* pSvxShape = GetSvxShape();
+ OSL_ENSURE( pSvxShape,
+ "<SwXShape::ConvertStartOrEndPosToLayoutDir(..)> - no SvxShape found!");
+ if ( pSvxShape )
+ {
+ const SdrObject* pObj = pSvxShape->GetSdrObject();
+ OSL_ENSURE( pObj,
+ "<SwXShape::ConvertStartOrEndPosToLayoutDir(..)> - no SdrObject found!");
+ if ( pObj )
+ {
+ // get position of object in Writer coordinate system.
+ awt::Point aPos( getPosition() );
+ // get position of object in Drawing layer coordinate system
+ const Point aTmpObjPos( pObj->GetSnapRect().TopLeft() );
+ const awt::Point aObjPos(
+ convertTwipToMm100( aTmpObjPos.X() - pObj->GetAnchorPos().X() ),
+ convertTwipToMm100( aTmpObjPos.Y() - pObj->GetAnchorPos().Y() ) );
+ // determine difference between these positions according to the
+ // Writer coordinate system
+ const awt::Point aTranslateDiff( aPos.X - aObjPos.X,
+ aPos.Y - aObjPos.Y );
+ // apply translation difference to PolyPolygonBezier.
+ if ( aTranslateDiff.X != 0 || aTranslateDiff.Y != 0 )
+ {
+ const basegfx::B2DHomMatrix aMatrix(basegfx::utils::createTranslateB2DHomMatrix(
+ aTranslateDiff.X, aTranslateDiff.Y));
+
+ for(drawing::PointSequence& rInnerSequence : asNonConstRange(aConvertedPath.Coordinates))
+ {
+ for(awt::Point& rPoint : asNonConstRange(rInnerSequence))
+ {
+ basegfx::B2DPoint aNewCoordinatePair(rPoint.X, rPoint.Y);
+ aNewCoordinatePair *= aMatrix;
+ rPoint.X = basegfx::fround(aNewCoordinatePair.getX());
+ rPoint.Y = basegfx::fround(aNewCoordinatePair.getY());
+ }
+ }
+ }
+ }
+ }
+
+ return aConvertedPath;
+}
+
+SwXGroupShape::SwXGroupShape(uno::Reference<XInterface> & xShape,
+ SwDoc const*const pDoc)
+ : SwXShape(xShape, pDoc)
+{
+#if OSL_DEBUG_LEVEL > 0
+ uno::Reference<XShapes> xShapes(m_xShapeAgg, uno::UNO_QUERY);
+ OSL_ENSURE(xShapes.is(), "no SvxShape found or shape is not a group shape");
+#endif
+}
+
+SwXGroupShape::~SwXGroupShape()
+{
+}
+
+uno::Any SwXGroupShape::queryInterface( const uno::Type& rType )
+{
+ uno::Any aRet;
+ if(rType == cppu::UnoType<XShapes>::get())
+ aRet <<= uno::Reference<XShapes>(this);
+ else
+ aRet = SwXShape::queryInterface(rType);
+ return aRet;
+}
+
+void SwXGroupShape::acquire( ) noexcept
+{
+ SwXShape::acquire();
+}
+
+void SwXGroupShape::release( ) noexcept
+{
+ SwXShape::release();
+}
+
+void SwXGroupShape::add( const uno::Reference< XShape >& xShape )
+{
+ SolarMutexGuard aGuard;
+ SvxShape* pSvxShape = GetSvxShape();
+ SwFrameFormat* pFormat = GetFrameFormat();
+ if(!(pSvxShape && pFormat))
+ throw uno::RuntimeException();
+
+ uno::Reference<XShapes> xShapes;
+ if( m_xShapeAgg.is() )
+ {
+ const uno::Type& rType = cppu::UnoType<XShapes>::get();
+ uno::Any aAgg = m_xShapeAgg->queryAggregation( rType );
+ aAgg >>= xShapes;
+ }
+ if(!xShapes.is())
+ throw uno::RuntimeException();
+
+ xShapes->add(xShape);
+
+
+ uno::Reference<lang::XUnoTunnel> xTunnel(xShape, uno::UNO_QUERY);
+ SwXShape* pSwShape = comphelper::getFromUnoTunnel<SwXShape>(xTunnel);
+ if(!(pSwShape && pSwShape->m_bDescriptor))
+ return;
+
+ SvxShape* pAddShape = comphelper::getFromUnoTunnel<SvxShape>(xTunnel);
+ if(pAddShape)
+ {
+ SdrObject* pObj = pAddShape->GetSdrObject();
+ if(pObj)
+ {
+ SwDoc* pDoc = pFormat->GetDoc();
+ // set layer of new drawing
+ // object to corresponding invisible layer.
+ if( SdrInventor::FmForm != pObj->GetObjInventor())
+ {
+ pObj->SetLayer( pSwShape->m_pImpl->GetOpaque()
+ ? pDoc->getIDocumentDrawModelAccess().GetInvisibleHeavenId()
+ : pDoc->getIDocumentDrawModelAccess().GetInvisibleHellId() );
+ }
+ else
+ {
+ pObj->SetLayer(pDoc->getIDocumentDrawModelAccess().GetInvisibleControlsId());
+ }
+ }
+ }
+ pSwShape->m_bDescriptor = false;
+}
+
+void SwXGroupShape::remove( const uno::Reference< XShape >& xShape )
+{
+ SolarMutexGuard aGuard;
+ uno::Reference<XShapes> xShapes;
+ if( m_xShapeAgg.is() )
+ {
+ const uno::Type& rType = cppu::UnoType<XShapes>::get();
+ uno::Any aAgg = m_xShapeAgg->queryAggregation( rType );
+ aAgg >>= xShapes;
+ }
+ if(!xShapes.is())
+ throw uno::RuntimeException();
+ xShapes->remove(xShape);
+}
+
+sal_Int32 SwXGroupShape::getCount()
+{
+ SolarMutexGuard aGuard;
+ uno::Reference<XIndexAccess> xAcc;
+ if( m_xShapeAgg.is() )
+ {
+ const uno::Type& rType = cppu::UnoType<XIndexAccess>::get();
+ uno::Any aAgg = m_xShapeAgg->queryAggregation( rType );
+ aAgg >>= xAcc;
+ }
+ if(!xAcc.is())
+ throw uno::RuntimeException();
+ return xAcc->getCount();
+}
+
+uno::Any SwXGroupShape::getByIndex(sal_Int32 nIndex)
+{
+ SolarMutexGuard aGuard;
+ uno::Reference<XIndexAccess> xAcc;
+ if( m_xShapeAgg.is() )
+ {
+ const uno::Type& rType = cppu::UnoType<XIndexAccess>::get();
+ uno::Any aAgg = m_xShapeAgg->queryAggregation( rType );
+ aAgg >>= xAcc;
+ }
+ if(!xAcc.is())
+ throw uno::RuntimeException();
+ return xAcc->getByIndex(nIndex);
+}
+
+uno::Type SwXGroupShape::getElementType( )
+{
+ SolarMutexGuard aGuard;
+ uno::Reference<XIndexAccess> xAcc;
+ if( m_xShapeAgg.is() )
+ {
+ const uno::Type& rType = cppu::UnoType<XIndexAccess>::get();
+ uno::Any aAgg = m_xShapeAgg->queryAggregation( rType );
+ aAgg >>= xAcc;
+ }
+ if(!xAcc.is())
+ throw uno::RuntimeException();
+ return xAcc->getElementType();
+}
+
+sal_Bool SwXGroupShape::hasElements( )
+{
+ SolarMutexGuard aGuard;
+ uno::Reference<XIndexAccess> xAcc;
+ if( m_xShapeAgg.is() )
+ {
+ const uno::Type& rType = cppu::UnoType<XIndexAccess>::get();
+ uno::Any aAgg = m_xShapeAgg->queryAggregation( rType );
+ aAgg >>= xAcc;
+ }
+ if(!xAcc.is())
+ throw uno::RuntimeException();
+ return xAcc->hasElements();
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/core/unocore/unoevent.cxx b/sw/source/core/unocore/unoevent.cxx
new file mode 100644
index 0000000000..09b1a089f8
--- /dev/null
+++ b/sw/source/core/unocore/unoevent.cxx
@@ -0,0 +1,233 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+// HINTIDs must be on top; it is required for the macitem.hxx header
+#include <hintids.hxx>
+#include <unoevent.hxx>
+#include <unoframe.hxx>
+#include <unostyle.hxx>
+#include <fmtinfmt.hxx>
+#include <svl/macitem.hxx>
+#include <sfx2/event.hxx>
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+
+using ::com::sun::star::container::XNameReplace;
+
+// tables of allowed events for specific objects
+
+const struct SvEventDescription aGraphicEvents[] =
+{
+ { SvMacroItemId::SwObjectSelect, "OnSelect" },
+ { SvMacroItemId::OnMouseOver, "OnMouseOver" },
+ { SvMacroItemId::OnClick, "OnClick" },
+ { SvMacroItemId::OnMouseOut, "OnMouseOut" },
+ { SvMacroItemId::OnImageLoadDone, "OnLoadDone" },
+ { SvMacroItemId::OnImageLoadCancel, "OnLoadCancel" },
+ { SvMacroItemId::OnImageLoadError, "OnLoadError" },
+ { SvMacroItemId::NONE, nullptr }
+};
+
+const struct SvEventDescription aFrameEvents[] =
+{
+ { SvMacroItemId::SwObjectSelect, "OnSelect" },
+ { SvMacroItemId::SwFrmKeyInputAlpha, "OnAlphaCharInput" },
+ { SvMacroItemId::SwFrmKeyInputNoAlpha, "OnNonAlphaCharInput" },
+ { SvMacroItemId::SwFrmResize, "OnResize" },
+ { SvMacroItemId::SwFrmMove, "OnMove" },
+ { SvMacroItemId::OnMouseOver, "OnMouseOver" },
+ { SvMacroItemId::OnClick, "OnClick" },
+ { SvMacroItemId::OnMouseOut, "OnMouseOut" },
+ { SvMacroItemId::NONE, nullptr }
+};
+
+const struct SvEventDescription aOLEEvents[] =
+{
+ { SvMacroItemId::SwObjectSelect, "OnSelect" },
+ { SvMacroItemId::OnMouseOver, "OnMouseOver" },
+ { SvMacroItemId::OnClick, "OnClick" },
+ { SvMacroItemId::OnMouseOut, "OnMouseOut" },
+ { SvMacroItemId::NONE, nullptr }
+};
+
+const struct SvEventDescription aHyperlinkEvents[] =
+{
+ { SvMacroItemId::OnMouseOver, "OnMouseOver" },
+ { SvMacroItemId::OnClick, "OnClick" },
+ { SvMacroItemId::OnMouseOut, "OnMouseOut" },
+ { SvMacroItemId::NONE, nullptr }
+};
+
+const struct SvEventDescription aFrameStyleEvents[] =
+{
+ { SvMacroItemId::SwObjectSelect, "OnSelect" },
+ { SvMacroItemId::SwFrmKeyInputAlpha, "OnAlphaCharInput" },
+ { SvMacroItemId::SwFrmKeyInputNoAlpha, "OnNonAlphaCharInput" },
+ { SvMacroItemId::SwFrmResize, "OnResize" },
+ { SvMacroItemId::SwFrmMove, "OnMove" },
+ { SvMacroItemId::OnMouseOver, "OnMouseOver" },
+ { SvMacroItemId::OnClick, "OnClick" },
+ { SvMacroItemId::OnMouseOut, "OnMouseOut" },
+ { SvMacroItemId::OnImageLoadDone, "OnLoadDone" },
+ { SvMacroItemId::OnImageLoadCancel, "OnLoadCancel" },
+ { SvMacroItemId::OnImageLoadError, "OnLoadError" },
+ { SvMacroItemId::NONE, nullptr }
+};
+
+SwHyperlinkEventDescriptor::SwHyperlinkEventDescriptor() :
+ SvDetachedEventDescriptor(aHyperlinkEvents)
+{
+}
+
+SwHyperlinkEventDescriptor::~SwHyperlinkEventDescriptor()
+{
+}
+
+OUString SwHyperlinkEventDescriptor::getImplementationName()
+{
+ return "SwHyperlinkEventDescriptor";
+}
+
+void SwHyperlinkEventDescriptor::copyMacrosFromINetFormat(
+ const SwFormatINetFormat& aFormat)
+{
+ for(sal_uInt16 i = 0; mpSupportedMacroItems[i].mnEvent != SvMacroItemId::NONE; ++i)
+ {
+ const SvMacroItemId nEvent = mpSupportedMacroItems[i].mnEvent;
+ const SvxMacro* aMacro = aFormat.GetMacro(nEvent);
+ if (nullptr != aMacro)
+ replaceByName(nEvent, *aMacro);
+ }
+}
+
+void SwHyperlinkEventDescriptor::copyMacrosIntoINetFormat(
+ SwFormatINetFormat& aFormat)
+{
+ for(sal_uInt16 i = 0; mpSupportedMacroItems[i].mnEvent != SvMacroItemId::NONE; ++i)
+ {
+ const SvMacroItemId nEvent = mpSupportedMacroItems[i].mnEvent;
+ if (hasById(nEvent))
+ {
+ SvxMacro aMacro("", "");
+ getByName(aMacro, nEvent);
+ aFormat.SetMacro(nEvent, aMacro);
+ }
+ }
+}
+
+void SwHyperlinkEventDescriptor::copyMacrosFromNameReplace(
+ uno::Reference<
+ container::XNameReplace> const & xReplace)
+{
+ // iterate over all names (all names that *we* support)
+ const Sequence<OUString> aNames = getElementNames();
+ for(const OUString& rName : aNames)
+ {
+ // copy element for that name
+ if (xReplace->hasByName(rName))
+ {
+ SvBaseEventDescriptor::replaceByName(rName,
+ xReplace->getByName(rName));
+ }
+ }
+}
+
+// use double cast in superclass constructor to avoid ambiguous cast
+SwFrameEventDescriptor::SwFrameEventDescriptor(
+ SwXTextFrame& rFrameRef ) :
+ SvEventDescriptor(static_cast<text::XTextFrame&>(rFrameRef), aFrameEvents),
+ m_rFrame(rFrameRef)
+{
+}
+
+SwFrameEventDescriptor::SwFrameEventDescriptor(
+ SwXTextGraphicObject& rGraphicRef ) :
+ SvEventDescriptor(static_cast<text::XTextContent&>(rGraphicRef), aGraphicEvents),
+ m_rFrame(static_cast<SwXFrame&>(rGraphicRef))
+{
+}
+
+SwFrameEventDescriptor::SwFrameEventDescriptor(
+ SwXTextEmbeddedObject& rObjectRef ) :
+ SvEventDescriptor(static_cast<text::XTextContent&>(rObjectRef), aOLEEvents),
+ m_rFrame(static_cast<SwXFrame&>(rObjectRef))
+{
+}
+
+SwFrameEventDescriptor::~SwFrameEventDescriptor()
+{
+}
+
+void SwFrameEventDescriptor::setMacroItem(const SvxMacroItem& rItem)
+{
+ m_rFrame.GetFrameFormat()->SetFormatAttr(rItem);
+}
+
+const SvxMacroItem& SwFrameEventDescriptor::getMacroItem()
+{
+ return m_rFrame.GetFrameFormat()->GetFormatAttr(RES_FRMMACRO);
+}
+
+sal_uInt16 SwFrameEventDescriptor::getMacroItemWhich() const
+{
+ return RES_FRMMACRO;
+}
+
+OUString SwFrameEventDescriptor::getImplementationName()
+{
+ return "SwFrameEventDescriptor";
+}
+
+SwFrameStyleEventDescriptor::SwFrameStyleEventDescriptor(
+ sw::ICoreFrameStyle& rStyle ) :
+ SvEventDescriptor(rStyle.GetEventsSupplier(),
+ aFrameStyleEvents),
+ m_rStyle(rStyle)
+{
+}
+
+SwFrameStyleEventDescriptor::~SwFrameStyleEventDescriptor()
+{
+}
+
+void SwFrameStyleEventDescriptor::setMacroItem(const SvxMacroItem& rItem)
+{
+ m_rStyle.SetItem(RES_FRMMACRO, rItem);
+}
+
+const SvxMacroItem aEmptyMacroItem(RES_FRMMACRO);
+
+const SvxMacroItem& SwFrameStyleEventDescriptor::getMacroItem()
+{
+ const SfxPoolItem* pItem(m_rStyle.GetItem(RES_FRMMACRO));
+ return pItem ? static_cast<const SvxMacroItem&>(*pItem) : aEmptyMacroItem;
+}
+
+OUString SwFrameStyleEventDescriptor::getImplementationName()
+{
+ return "SwFrameStyleEventDescriptor";
+}
+
+sal_uInt16 SwFrameStyleEventDescriptor::getMacroItemWhich() const
+{
+ return RES_FRMMACRO;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/core/unocore/unofield.cxx b/sw/source/core/unocore/unofield.cxx
new file mode 100644
index 0000000000..d73c0b59b3
--- /dev/null
+++ b/sw/source/core/unocore/unofield.cxx
@@ -0,0 +1,3024 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <sal/config.h>
+#include <algorithm>
+#include <memory>
+
+#include <unofield.hxx>
+#include <unofieldcoll.hxx>
+#include <unobookmark.hxx>
+#include <swtypes.hxx>
+#include <cmdid.h>
+#include <doc.hxx>
+#include <IDocumentFieldsAccess.hxx>
+#include <IDocumentStatistics.hxx>
+#include <IDocumentStylePoolAccess.hxx>
+#include <IDocumentLayoutAccess.hxx>
+#include <IDocumentState.hxx>
+#include <fmtfld.hxx>
+#include <txtfld.hxx>
+#include <ndtxt.hxx>
+#include <unomap.hxx>
+#include <unoprnms.hxx>
+#include <unotextrange.hxx>
+#include <unotextcursor.hxx>
+#include <unocoll.hxx>
+#include <sfx2/linkmgr.hxx>
+#include <editsh.hxx>
+#include <viewsh.hxx>
+#include <comphelper/interfacecontainer4.hxx>
+#include <comphelper/servicehelper.hxx>
+#include <comphelper/string.hxx>
+#include <cppuhelper/supportsservice.hxx>
+#include <com/sun/star/util/DateTime.hpp>
+#include <com/sun/star/util/Date.hpp>
+#include <com/sun/star/beans/PropertyAttribute.hpp>
+
+//undef to prevent error (from sfx2/docfile.cxx)
+#undef SEQUENCE
+#include <com/sun/star/text/SetVariableType.hpp>
+#include <com/sun/star/text/WrapTextMode.hpp>
+#include <com/sun/star/text/TextContentAnchorType.hpp>
+#include <authfld.hxx>
+#include <flddat.hxx>
+#include <dbfld.hxx>
+#include <usrfld.hxx>
+#include <docufld.hxx>
+#include <expfld.hxx>
+#include <chpfld.hxx>
+#include <flddropdown.hxx>
+#include <poolfmt.hxx>
+#include <strings.hrc>
+#include <pagedesc.hxx>
+#include <docary.hxx>
+#include <reffld.hxx>
+#include <ddefld.hxx>
+#include <SwStyleNameMapper.hxx>
+#include <swunohelper.hxx>
+#include <unofldmid.h>
+#include <scriptinfo.hxx>
+#include <tools/datetime.hxx>
+#include <tools/urlobj.hxx>
+#include <svl/itemprop.hxx>
+#include <svl/listener.hxx>
+#include <svx/dataaccessdescriptor.hxx>
+#include <o3tl/any.hxx>
+#include <o3tl/safeint.hxx>
+#include <mutex>
+#include <vcl/svapp.hxx>
+#include <textapi.hxx>
+#include <fmtmeta.hxx>
+#include <vector>
+
+using namespace ::com::sun::star;
+using namespace nsSwDocInfoSubType;
+
+// case-corrected version of the first part for the service names (see #i67811)
+constexpr OUString COM_TEXT_FLDMASTER_CC = u"com.sun.star.text.fieldmaster."_ustr;
+
+// note: this thing is indexed as an array, so do not insert/remove entries!
+const sal_uInt16 aDocInfoSubTypeFromService[] =
+{
+ DI_CHANGE | DI_SUB_AUTHOR, //PROPERTY_MAP_FLDTYP_DOCINFO_CHANGE_AUTHOR
+ DI_CHANGE | DI_SUB_DATE, //PROPERTY_MAP_FLDTYP_DOCINFO_CHANGE_DATE_TIME
+ DI_EDIT | DI_SUB_TIME, //PROPERTY_MAP_FLDTYP_DOCINFO_EDIT_TIME
+ DI_COMMENT, //PROPERTY_MAP_FLDTYP_DOCINFO_DESCRIPTION
+ DI_CREATE | DI_SUB_AUTHOR, //PROPERTY_MAP_FLDTYP_DOCINFO_CREATE_AUTHOR
+ DI_CREATE | DI_SUB_DATE, //PROPERTY_MAP_FLDTYP_DOCINFO_CREATE_DATE_TIME
+ 0, //DUMMY
+ 0, //DUMMY
+ 0, //DUMMY
+ 0, //DUMMY
+ DI_CUSTOM, //PROPERTY_MAP_FLDTYP_DOCINFO_CUSTOM
+ DI_PRINT | DI_SUB_AUTHOR, //PROPERTY_MAP_FLDTYP_DOCINFO_PRINT_AUTHOR
+ DI_PRINT | DI_SUB_DATE, //PROPERTY_MAP_FLDTYP_DOCINFO_PRINT_DATE_TIME
+ DI_KEYS, //PROPERTY_MAP_FLDTYP_DOCINFO_KEY_WORDS
+ DI_SUBJECT, //PROPERTY_MAP_FLDTYP_DOCINFO_SUBJECT
+ DI_TITLE, //PROPERTY_MAP_FLDTYP_DOCINFO_TITLE
+ DI_DOCNO //PROPERTY_MAP_FLDTYP_DOCINFO_REVISION
+};
+
+namespace {
+
+struct ServiceIdResId
+{
+ SwFieldIds nResId;
+ SwServiceType nServiceId;
+};
+
+}
+
+const ServiceIdResId aServiceToRes[] =
+{
+ {SwFieldIds::DateTime, SwServiceType::FieldTypeDateTime },
+ {SwFieldIds::User, SwServiceType::FieldTypeUser },
+ {SwFieldIds::SetExp, SwServiceType::FieldTypeSetExp },
+ {SwFieldIds::GetExp, SwServiceType::FieldTypeGetExp },
+ {SwFieldIds::Filename, SwServiceType::FieldTypeFileName },
+ {SwFieldIds::PageNumber, SwServiceType::FieldTypePageNum },
+ {SwFieldIds::Author, SwServiceType::FieldTypeAuthor },
+ {SwFieldIds::Chapter, SwServiceType::FieldTypeChapter },
+ {SwFieldIds::GetRef, SwServiceType::FieldTypeGetReference },
+ {SwFieldIds::HiddenText, SwServiceType::FieldTypeConditionedText },
+ {SwFieldIds::Postit, SwServiceType::FieldTypeAnnotation },
+ {SwFieldIds::Input, SwServiceType::FieldTypeInput },
+ {SwFieldIds::Macro, SwServiceType::FieldTypeMacro },
+ {SwFieldIds::Dde, SwServiceType::FieldTypeDDE },
+ {SwFieldIds::HiddenPara, SwServiceType::FieldTypeHiddenPara },
+ {SwFieldIds::DocInfo, SwServiceType::FieldTypeDocInfo },
+ {SwFieldIds::TemplateName, SwServiceType::FieldTypeTemplateName },
+ {SwFieldIds::ExtUser, SwServiceType::FieldTypeUserExt },
+ {SwFieldIds::RefPageSet, SwServiceType::FieldTypeRefPageSet },
+ {SwFieldIds::RefPageGet, SwServiceType::FieldTypeRefPageGet },
+ {SwFieldIds::JumpEdit, SwServiceType::FieldTypeJumpEdit },
+ {SwFieldIds::Script, SwServiceType::FieldTypeScript },
+ {SwFieldIds::DbNextSet, SwServiceType::FieldTypeDatabaseNextSet },
+ {SwFieldIds::DbNumSet, SwServiceType::FieldTypeDatabaseNumSet },
+ {SwFieldIds::DbSetNumber, SwServiceType::FieldTypeDatabaseSetNum },
+ {SwFieldIds::Database, SwServiceType::FieldTypeDatabase },
+ {SwFieldIds::DatabaseName, SwServiceType::FieldTypeDatabaseName },
+ {SwFieldIds::DocStat, SwServiceType::FieldTypePageCount },
+ {SwFieldIds::DocStat, SwServiceType::FieldTypeParagraphCount },
+ {SwFieldIds::DocStat, SwServiceType::FieldTypeWordCount },
+ {SwFieldIds::DocStat, SwServiceType::FieldTypeCharacterCount },
+ {SwFieldIds::DocStat, SwServiceType::FieldTypeTableCount },
+ {SwFieldIds::DocStat, SwServiceType::FieldTypeGraphicObjectCount },
+ {SwFieldIds::DocStat, SwServiceType::FieldTypeEmbeddedObjectCount },
+ {SwFieldIds::DocInfo, SwServiceType::FieldTypeDocInfoChangeAuthor },
+ {SwFieldIds::DocInfo, SwServiceType::FieldTypeDocInfoChangeDateTime },
+ {SwFieldIds::DocInfo, SwServiceType::FieldTypeDocInfoEditTime },
+ {SwFieldIds::DocInfo, SwServiceType::FieldTypeDocInfoDescription },
+ {SwFieldIds::DocInfo, SwServiceType::FieldTypeDocInfoCreateAuthor },
+ {SwFieldIds::DocInfo, SwServiceType::FieldTypeDocInfoCreateDateTime },
+ {SwFieldIds::DocInfo, SwServiceType::FieldTypeDocInfoCustom },
+ {SwFieldIds::DocInfo, SwServiceType::FieldTypeDocInfoPrintAuthor },
+ {SwFieldIds::DocInfo, SwServiceType::FieldTypeDocInfoPrintDateTime },
+ {SwFieldIds::DocInfo, SwServiceType::FieldTypeDocInfoKeywords },
+ {SwFieldIds::DocInfo, SwServiceType::FieldTypeDocInfoSubject },
+ {SwFieldIds::DocInfo, SwServiceType::FieldTypeDocInfoTitle },
+ {SwFieldIds::Input, SwServiceType::FieldTypeInputUser },
+ {SwFieldIds::HiddenText, SwServiceType::FieldTypeHiddenText },
+ {SwFieldIds::TableOfAuthorities, SwServiceType::FieldTypeBibliography },
+ {SwFieldIds::CombinedChars, SwServiceType::FieldTypeCombinedCharacters },
+ {SwFieldIds::Dropdown, SwServiceType::FieldTypeDropdown },
+ {SwFieldIds::Table, SwServiceType::FieldTypeTableFormula }
+};
+
+static SwFieldIds lcl_ServiceIdToResId(SwServiceType nServiceId)
+{
+ for (auto const& aEntry : aServiceToRes)
+ if (aEntry.nServiceId == nServiceId)
+ return aEntry.nResId;
+#if OSL_DEBUG_LEVEL > 0
+ OSL_FAIL("service id not found");
+#endif
+ return SwFieldIds::Unknown;
+}
+
+static SwServiceType lcl_GetServiceForField( const SwField& rField )
+{
+ const SwFieldIds nWhich = rField.Which();
+ SwServiceType nSrvId = SwServiceType::Invalid;
+ //special handling for some fields
+ switch( nWhich )
+ {
+ case SwFieldIds::Input:
+ if( INP_USR == (rField.GetSubType() & 0x00ff) )
+ nSrvId = SwServiceType::FieldTypeInputUser;
+ break;
+
+ case SwFieldIds::DocInfo:
+ {
+ const sal_uInt16 nSubType = rField.GetSubType();
+ switch( nSubType & 0xff )
+ {
+ case DI_CHANGE:
+ nSrvId = ((nSubType&0x300) == DI_SUB_AUTHOR)
+ ? SwServiceType::FieldTypeDocInfoChangeAuthor
+ : SwServiceType::FieldTypeDocInfoChangeDateTime;
+ break;
+ case DI_CREATE:
+ nSrvId = ((nSubType&0x300) == DI_SUB_AUTHOR)
+ ? SwServiceType::FieldTypeDocInfoCreateAuthor
+ : SwServiceType::FieldTypeDocInfoCreateDateTime;
+ break;
+ case DI_PRINT:
+ nSrvId = ((nSubType&0x300) == DI_SUB_AUTHOR)
+ ? SwServiceType::FieldTypeDocInfoPrintAuthor
+ : SwServiceType::FieldTypeDocInfoPrintDateTime;
+ break;
+ case DI_EDIT: nSrvId = SwServiceType::FieldTypeDocInfoEditTime;break;
+ case DI_COMMENT:nSrvId = SwServiceType::FieldTypeDocInfoDescription;break;
+ case DI_KEYS: nSrvId = SwServiceType::FieldTypeDocInfoKeywords;break;
+ case DI_SUBJECT:nSrvId = SwServiceType::FieldTypeDocInfoSubject; break;
+ case DI_TITLE: nSrvId = SwServiceType::FieldTypeDocInfoTitle; break;
+ case DI_DOCNO: nSrvId = SwServiceType::FieldTypeDocInfoRevision; break;
+ case DI_CUSTOM: nSrvId = SwServiceType::FieldTypeDocInfoCustom; break;
+ }
+ }
+ break;
+
+ case SwFieldIds::HiddenText:
+ nSrvId = SwFieldTypesEnum::ConditionalText == static_cast<SwFieldTypesEnum>(rField.GetSubType())
+ ? SwServiceType::FieldTypeConditionedText
+ : SwServiceType::FieldTypeHiddenText;
+ break;
+
+ case SwFieldIds::DocStat:
+ {
+ switch( rField.GetSubType() )
+ {
+ case DS_PAGE: nSrvId = SwServiceType::FieldTypePageCount; break;
+ case DS_PARA: nSrvId = SwServiceType::FieldTypeParagraphCount; break;
+ case DS_WORD: nSrvId = SwServiceType::FieldTypeWordCount ; break;
+ case DS_CHAR: nSrvId = SwServiceType::FieldTypeCharacterCount; break;
+ case DS_TBL: nSrvId = SwServiceType::FieldTypeTableCount ; break;
+ case DS_GRF: nSrvId = SwServiceType::FieldTypeGraphicObjectCount; break;
+ case DS_OLE: nSrvId = SwServiceType::FieldTypeEmbeddedObjectCount; break;
+ }
+ }
+ break;
+ default: break;
+ }
+ if( SwServiceType::Invalid == nSrvId )
+ {
+ for( const ServiceIdResId* pMap = aServiceToRes;
+ SwFieldIds::Unknown != pMap->nResId; ++pMap )
+ if( nWhich == pMap->nResId )
+ {
+ nSrvId = pMap->nServiceId;
+ break;
+ }
+ }
+#if OSL_DEBUG_LEVEL > 0
+ if( SwServiceType::Invalid == nSrvId )
+ OSL_FAIL("resid not found");
+#endif
+ return nSrvId;
+}
+
+static sal_uInt16 lcl_GetPropMapIdForFieldType( SwFieldIds nWhich )
+{
+ sal_uInt16 nId;
+ switch( nWhich )
+ {
+ case SwFieldIds::User: nId = PROPERTY_MAP_FLDMSTR_USER; break;
+ case SwFieldIds::Database: nId = PROPERTY_MAP_FLDMSTR_DATABASE; break;
+ case SwFieldIds::SetExp: nId = PROPERTY_MAP_FLDMSTR_SET_EXP; break;
+ case SwFieldIds::Dde: nId = PROPERTY_MAP_FLDMSTR_DDE; break;
+ case SwFieldIds::TableOfAuthorities:
+ nId = PROPERTY_MAP_FLDMSTR_BIBLIOGRAPHY; break;
+ default: nId = PROPERTY_MAP_FLDMSTR_DUMMY0;
+ }
+ return nId;
+}
+
+static sal_Int32 lcl_PropName2TokenPos(std::u16string_view rPropertyName)
+{
+ if (rPropertyName == UNO_NAME_DDE_COMMAND_TYPE)
+ return 0;
+
+ if (rPropertyName == UNO_NAME_DDE_COMMAND_FILE)
+ return 1;
+
+ if (rPropertyName == UNO_NAME_DDE_COMMAND_ELEMENT)
+ return 2;
+
+ if (rPropertyName == UNO_NAME_IS_AUTOMATIC_UPDATE)
+ return 3;
+
+ return SAL_MAX_INT32;
+}
+
+static sal_uInt16 GetFieldTypeMId( std::u16string_view rProperty, const SwFieldType& rTyp )
+{
+ sal_uInt16 nId = lcl_GetPropMapIdForFieldType( rTyp.Which() );
+ const SfxItemPropertySet* pSet = aSwMapProvider.GetPropertySet( nId );
+ if( !pSet )
+ nId = USHRT_MAX;
+ else
+ {
+ const SfxItemPropertyMapEntry* pEntry = pSet->getPropertyMap().getByName(rProperty);
+ nId = pEntry ? pEntry->nWID : USHRT_MAX;
+ }
+ return nId;
+}
+
+static sal_uInt16 lcl_GetPropertyMapOfService( SwServiceType nServiceId )
+{
+ sal_uInt16 nRet;
+ switch ( nServiceId)
+ {
+ case SwServiceType::FieldTypeDateTime: nRet = PROPERTY_MAP_FLDTYP_DATETIME; break;
+ case SwServiceType::FieldTypeUser: nRet = PROPERTY_MAP_FLDTYP_USER; break;
+ case SwServiceType::FieldTypeSetExp: nRet = PROPERTY_MAP_FLDTYP_SET_EXP; break;
+ case SwServiceType::FieldTypeGetExp: nRet = PROPERTY_MAP_FLDTYP_GET_EXP; break;
+ case SwServiceType::FieldTypeFileName: nRet = PROPERTY_MAP_FLDTYP_FILE_NAME; break;
+ case SwServiceType::FieldTypePageNum: nRet = PROPERTY_MAP_FLDTYP_PAGE_NUM; break;
+ case SwServiceType::FieldTypeAuthor: nRet = PROPERTY_MAP_FLDTYP_AUTHOR; break;
+ case SwServiceType::FieldTypeChapter: nRet = PROPERTY_MAP_FLDTYP_CHAPTER; break;
+ case SwServiceType::FieldTypeGetReference: nRet = PROPERTY_MAP_FLDTYP_GET_REFERENCE; break;
+ case SwServiceType::FieldTypeConditionedText: nRet = PROPERTY_MAP_FLDTYP_CONDITIONED_TEXT; break;
+ case SwServiceType::FieldTypeAnnotation: nRet = PROPERTY_MAP_FLDTYP_ANNOTATION; break;
+ case SwServiceType::FieldTypeInputUser:
+ case SwServiceType::FieldTypeInput: nRet = PROPERTY_MAP_FLDTYP_INPUT; break;
+ case SwServiceType::FieldTypeMacro: nRet = PROPERTY_MAP_FLDTYP_MACRO; break;
+ case SwServiceType::FieldTypeDDE: nRet = PROPERTY_MAP_FLDTYP_DDE; break;
+ case SwServiceType::FieldTypeHiddenPara: nRet = PROPERTY_MAP_FLDTYP_HIDDEN_PARA; break;
+ case SwServiceType::FieldTypeDocInfo: nRet = PROPERTY_MAP_FLDTYP_DOC_INFO; break;
+ case SwServiceType::FieldTypeTemplateName: nRet = PROPERTY_MAP_FLDTYP_TEMPLATE_NAME; break;
+ case SwServiceType::FieldTypeUserExt: nRet = PROPERTY_MAP_FLDTYP_USER_EXT; break;
+ case SwServiceType::FieldTypeRefPageSet: nRet = PROPERTY_MAP_FLDTYP_REF_PAGE_SET; break;
+ case SwServiceType::FieldTypeRefPageGet: nRet = PROPERTY_MAP_FLDTYP_REF_PAGE_GET; break;
+ case SwServiceType::FieldTypeJumpEdit: nRet = PROPERTY_MAP_FLDTYP_JUMP_EDIT; break;
+ case SwServiceType::FieldTypeScript: nRet = PROPERTY_MAP_FLDTYP_SCRIPT; break;
+ case SwServiceType::FieldTypeDatabaseNextSet: nRet = PROPERTY_MAP_FLDTYP_DATABASE_NEXT_SET; break;
+ case SwServiceType::FieldTypeDatabaseNumSet: nRet = PROPERTY_MAP_FLDTYP_DATABASE_NUM_SET; break;
+ case SwServiceType::FieldTypeDatabaseSetNum: nRet = PROPERTY_MAP_FLDTYP_DATABASE_SET_NUM; break;
+ case SwServiceType::FieldTypeDatabase: nRet = PROPERTY_MAP_FLDTYP_DATABASE; break;
+ case SwServiceType::FieldTypeDatabaseName: nRet = PROPERTY_MAP_FLDTYP_DATABASE_NAME; break;
+ case SwServiceType::FieldTypeTableFormula: nRet = PROPERTY_MAP_FLDTYP_TABLE_FORMULA; break;
+ case SwServiceType::FieldTypePageCount:
+ case SwServiceType::FieldTypeParagraphCount:
+ case SwServiceType::FieldTypeWordCount:
+ case SwServiceType::FieldTypeCharacterCount:
+ case SwServiceType::FieldTypeTableCount:
+ case SwServiceType::FieldTypeGraphicObjectCount:
+ case SwServiceType::FieldTypeEmbeddedObjectCount: nRet = PROPERTY_MAP_FLDTYP_DOCSTAT; break;
+ case SwServiceType::FieldTypeDocInfoChangeAuthor:
+ case SwServiceType::FieldTypeDocInfoCreateAuthor:
+ case SwServiceType::FieldTypeDocInfoPrintAuthor: nRet = PROPERTY_MAP_FLDTYP_DOCINFO_AUTHOR; break;
+ case SwServiceType::FieldTypeDocInfoChangeDateTime:
+ case SwServiceType::FieldTypeDocInfoCreateDateTime:
+ case SwServiceType::FieldTypeDocInfoPrintDateTime: nRet = PROPERTY_MAP_FLDTYP_DOCINFO_DATE_TIME; break;
+ case SwServiceType::FieldTypeDocInfoEditTime: nRet = PROPERTY_MAP_FLDTYP_DOCINFO_EDIT_TIME; break;
+ case SwServiceType::FieldTypeDocInfoCustom: nRet = PROPERTY_MAP_FLDTYP_DOCINFO_CUSTOM; break;
+ case SwServiceType::FieldTypeDocInfoDescription:
+ case SwServiceType::FieldTypeDocInfoKeywords:
+ case SwServiceType::FieldTypeDocInfoSubject:
+ case SwServiceType::FieldTypeDocInfoTitle: nRet = PROPERTY_MAP_FLDTYP_DOCINFO_MISC; break;
+ case SwServiceType::FieldTypeDocInfoRevision: nRet = PROPERTY_MAP_FLDTYP_DOCINFO_REVISION; break;
+ case SwServiceType::FieldTypeBibliography: nRet = PROPERTY_MAP_FLDTYP_BIBLIOGRAPHY; break;
+ case SwServiceType::FieldTypeDummy0:
+ case SwServiceType::FieldTypeCombinedCharacters: nRet = PROPERTY_MAP_FLDTYP_COMBINED_CHARACTERS; break;
+ case SwServiceType::FieldTypeDropdown: nRet = PROPERTY_MAP_FLDTYP_DROPDOWN; break;
+ case SwServiceType::FieldTypeDummy4:
+ case SwServiceType::FieldTypeDummy5:
+ case SwServiceType::FieldTypeDummy6:
+ case SwServiceType::FieldTypeDummy7:
+ nRet = PROPERTY_MAP_FLDTYP_DUMMY_0; break;
+ case SwServiceType::FieldMasterUser: nRet = PROPERTY_MAP_FLDMSTR_USER; break;
+ case SwServiceType::FieldMasterDDE: nRet = PROPERTY_MAP_FLDMSTR_DDE; break;
+ case SwServiceType::FieldMasterSetExp: nRet = PROPERTY_MAP_FLDMSTR_SET_EXP; break;
+ case SwServiceType::FieldMasterDatabase: nRet = PROPERTY_MAP_FLDMSTR_DATABASE; break;
+ case SwServiceType::FieldMasterBibliography: nRet = PROPERTY_MAP_FLDMSTR_BIBLIOGRAPHY; break;
+ case SwServiceType::FieldMasterDummy2:
+ case SwServiceType::FieldMasterDummy3:
+ case SwServiceType::FieldMasterDummy4:
+ case SwServiceType::FieldMasterDummy5: nRet = PROPERTY_MAP_FLDMSTR_DUMMY0; break;
+ case SwServiceType::FieldTypeHiddenText: nRet = PROPERTY_MAP_FLDTYP_HIDDEN_TEXT; break;
+ default:
+ nRet = USHRT_MAX;
+ }
+ assert(nRet != USHRT_MAX && "wrong service id");
+ return nRet;
+}
+
+class SwXFieldMaster::Impl
+ : public SvtListener
+{
+public:
+ std::mutex m_Mutex; // just for OInterfaceContainerHelper4
+
+ unotools::WeakReference<SwXFieldMaster> m_wThis;
+ ::comphelper::OInterfaceContainerHelper4<css::lang::XEventListener> m_EventListeners;
+
+ SwDoc* m_pDoc;
+ SwFieldType* m_pType;
+
+ SwFieldIds m_nResTypeId;
+
+ OUString m_sParam1; // Content / Database / NumberingSeparator
+ OUString m_sParam2; // - /DataTablename
+ OUString m_sParam3; // - /DataFieldName
+ OUString m_sParam5; // - /DataBaseURL
+ double m_fParam1; // Value / -
+ sal_Int8 m_nParam1; // ChapterNumberingLevel
+ bool m_bParam1; // IsExpression
+ sal_Int32 m_nParam2;
+
+ Impl(SwPageDesc* const pPageDesc, SwDoc* pDoc, SwFieldIds nResId)
+ : m_pDoc(pDoc)
+ , m_pType(nullptr)
+ , m_nResTypeId(nResId)
+ , m_fParam1(0.0)
+ , m_nParam1(-1)
+ , m_bParam1(false)
+ , m_nParam2(0)
+ {
+ StartListening(pPageDesc->GetNotifier());
+ }
+
+ Impl(SwFieldType* const pType, SwDoc* pDoc, SwFieldIds nResId)
+ : m_pDoc(pDoc)
+ , m_pType(pType)
+ , m_nResTypeId(nResId)
+ , m_fParam1(0.0)
+ , m_nParam1(-1)
+ , m_bParam1(false)
+ , m_nParam2(0)
+ {
+ StartListening(m_pType->GetNotifier());
+ }
+ void SetFieldType(SwFieldType* pType)
+ {
+ EndListeningAll();
+ m_pType = pType;
+ StartListening(m_pType->GetNotifier());
+ }
+protected:
+ virtual void Notify(const SfxHint& rHint) override;
+};
+
+OUString SAL_CALL
+SwXFieldMaster::getImplementationName()
+{
+ return "SwXFieldMaster";
+}
+
+namespace
+{
+
+OUString getServiceName(const SwFieldIds aId)
+{
+ const char* pEntry;
+ switch (aId)
+ {
+ case SwFieldIds::User:
+ pEntry = "User";
+ break;
+ case SwFieldIds::Database:
+ pEntry = "Database";
+ break;
+ case SwFieldIds::SetExp:
+ pEntry = "SetExpression";
+ break;
+ case SwFieldIds::Dde:
+ pEntry = "DDE";
+ break;
+ case SwFieldIds::TableOfAuthorities:
+ pEntry = "Bibliography";
+ break;
+ default:
+ return OUString();
+ }
+
+ return "com.sun.star.text.fieldmaster." + OUString::createFromAscii(pEntry);
+}
+
+}
+
+sal_Bool SAL_CALL SwXFieldMaster::supportsService(const OUString& rServiceName)
+{
+ return cppu::supportsService(this, rServiceName);
+}
+
+uno::Sequence< OUString > SAL_CALL
+SwXFieldMaster::getSupportedServiceNames()
+{
+ return { "com.sun.star.text.TextFieldMaster", getServiceName(m_pImpl->m_nResTypeId) };
+}
+
+SwXFieldMaster::SwXFieldMaster(SwDoc& rDoc, SwFieldIds const nResId)
+ : m_pImpl(new Impl(rDoc.getIDocumentStylePoolAccess().GetPageDescFromPool(RES_POOLPAGE_STANDARD), &rDoc, nResId))
+{
+}
+
+SwXFieldMaster::SwXFieldMaster(SwFieldType& rType, SwDoc * pDoc)
+ : m_pImpl(new Impl(&rType, pDoc, rType.Which()))
+{
+}
+
+SwXFieldMaster::~SwXFieldMaster()
+{
+}
+
+rtl::Reference<SwXFieldMaster>
+SwXFieldMaster::CreateXFieldMaster(SwDoc * pDoc, SwFieldType *const pType,
+ SwFieldIds nResId)
+{
+ // re-use existing SwXFieldMaster
+ rtl::Reference<SwXFieldMaster> xFM;
+ if (pType)
+ {
+ xFM = pType->GetXObject().get();
+ }
+ if (!xFM.is())
+ {
+ SwXFieldMaster *const pFM( pType
+ ? new SwXFieldMaster(*pType, pDoc)
+ : new SwXFieldMaster(*pDoc, nResId));
+ xFM.set(pFM);
+ if (pType)
+ {
+ pType->SetXObject(xFM);
+ }
+ // need a permanent Reference to initialize m_wThis
+ pFM->m_pImpl->m_wThis = xFM.get();
+ }
+ return xFM;
+}
+
+uno::Reference<beans::XPropertySetInfo> SAL_CALL
+SwXFieldMaster::getPropertySetInfo()
+{
+ SolarMutexGuard aGuard;
+ uno::Reference< beans::XPropertySetInfo > aRef =
+ aSwMapProvider.GetPropertySet(
+ lcl_GetPropMapIdForFieldType(m_pImpl->m_nResTypeId))->getPropertySetInfo();
+ return aRef;
+}
+
+void SAL_CALL SwXFieldMaster::setPropertyValue(
+ const OUString& rPropertyName, const uno::Any& rValue)
+{
+ SolarMutexGuard aGuard;
+ SwFieldType* pType = GetFieldType(true);
+ if(pType)
+ {
+ bool bSetValue = true;
+ if( rPropertyName == UNO_NAME_SUB_TYPE )
+ {
+ const std::vector<OUString>& rExtraArr(
+ SwStyleNameMapper::GetExtraUINameArray());
+ const OUString sTypeName = pType->GetName();
+ static sal_uInt16 nIds[] =
+ {
+ RES_POOLCOLL_LABEL_DRAWING - RES_POOLCOLL_EXTRA_BEGIN,
+ RES_POOLCOLL_LABEL_ABB - RES_POOLCOLL_EXTRA_BEGIN,
+ RES_POOLCOLL_LABEL_TABLE - RES_POOLCOLL_EXTRA_BEGIN,
+ RES_POOLCOLL_LABEL_FRAME- RES_POOLCOLL_EXTRA_BEGIN,
+ RES_POOLCOLL_LABEL_FIGURE - RES_POOLCOLL_EXTRA_BEGIN,
+ 0
+ };
+ for(const sal_uInt16 * pIds = nIds; *pIds; ++pIds)
+ {
+ if(sTypeName == rExtraArr[ *pIds ] )
+ {
+ bSetValue = false;
+ break;
+ }
+ }
+ }
+ if ( bSetValue )
+ {
+ // nothing special to be done here for the properties
+ // UNO_NAME_DATA_BASE_NAME and UNO_NAME_DATA_BASE_URL.
+ // We just call PutValue (empty string is allowed).
+ // Thus the last property set will be used as Data Source.
+
+ const sal_uInt16 nMemberValueId = GetFieldTypeMId( rPropertyName, *pType );
+ if ( USHRT_MAX == nMemberValueId )
+ {
+ throw beans::UnknownPropertyException(
+ "Unknown property: " + rPropertyName,
+ getXWeak() );
+ }
+
+ pType->PutValue( rValue, nMemberValueId );
+ if ( pType->Which() == SwFieldIds::User )
+ {
+ // trigger update of User field in order to get depending Input Fields updated.
+ pType->UpdateFields();
+ }
+
+ }
+ }
+ else if (m_pImpl->m_pDoc && rPropertyName == UNO_NAME_NAME)
+ {
+ OUString sTypeName;
+ rValue >>= sTypeName;
+ SwFieldType * pType2 = m_pImpl->m_pDoc->getIDocumentFieldsAccess().GetFieldType(
+ m_pImpl->m_nResTypeId, sTypeName, false);
+
+ if(pType2 ||
+ (SwFieldIds::SetExp == m_pImpl->m_nResTypeId &&
+ ( sTypeName == SwResId(STR_POOLCOLL_LABEL_TABLE) ||
+ sTypeName == SwResId(STR_POOLCOLL_LABEL_DRAWING) ||
+ sTypeName == SwResId(STR_POOLCOLL_LABEL_FRAME) ||
+ sTypeName == SwResId(STR_POOLCOLL_LABEL_ABB) ||
+ sTypeName == SwResId(STR_POOLCOLL_LABEL_FIGURE) )))
+ {
+ throw lang::IllegalArgumentException();
+ }
+
+ switch (m_pImpl->m_nResTypeId)
+ {
+ case SwFieldIds::User :
+ {
+ SwUserFieldType aType(m_pImpl->m_pDoc, sTypeName);
+ pType2 = m_pImpl->m_pDoc->getIDocumentFieldsAccess().InsertFieldType(aType);
+ static_cast<SwUserFieldType*>(pType2)->SetContent(m_pImpl->m_sParam1);
+ static_cast<SwUserFieldType*>(pType2)->SetValue(m_pImpl->m_fParam1);
+ static_cast<SwUserFieldType*>(pType2)->SetType(m_pImpl->m_bParam1
+ ? nsSwGetSetExpType::GSE_EXPR : nsSwGetSetExpType::GSE_STRING);
+ }
+ break;
+ case SwFieldIds::Dde :
+ {
+ SwDDEFieldType aType(sTypeName, m_pImpl->m_sParam1,
+ m_pImpl->m_bParam1 ? SfxLinkUpdateMode::ALWAYS : SfxLinkUpdateMode::ONCALL);
+ pType2 = m_pImpl->m_pDoc->getIDocumentFieldsAccess().InsertFieldType(aType);
+ }
+ break;
+ case SwFieldIds::SetExp :
+ {
+ SwSetExpFieldType aType(m_pImpl->m_pDoc, sTypeName);
+ if (!m_pImpl->m_sParam1.isEmpty())
+ aType.SetDelimiter(OUString(m_pImpl->m_sParam1[0]));
+ if (m_pImpl->m_nParam1 > -1 && m_pImpl->m_nParam1 < MAXLEVEL)
+ aType.SetOutlineLvl(m_pImpl->m_nParam1);
+ pType2 = m_pImpl->m_pDoc->getIDocumentFieldsAccess().InsertFieldType(aType);
+ }
+ break;
+ case SwFieldIds::Database :
+ {
+ rValue >>= m_pImpl->m_sParam3;
+ pType2 = GetFieldType();
+ }
+ break;
+ default: break;
+ }
+ if (!pType2)
+ {
+ throw uno::RuntimeException("no field type found!", *this);
+ }
+ m_pImpl->SetFieldType(pType2);
+ }
+ else
+ {
+ switch (m_pImpl->m_nResTypeId)
+ {
+ case SwFieldIds::User:
+ if(rPropertyName == UNO_NAME_CONTENT)
+ rValue >>= m_pImpl->m_sParam1;
+ else if(rPropertyName == UNO_NAME_VALUE)
+ {
+ if(rValue.getValueType() != ::cppu::UnoType<double>::get())
+ throw lang::IllegalArgumentException();
+ rValue >>= m_pImpl->m_fParam1;
+ }
+ else if(rPropertyName == UNO_NAME_IS_EXPRESSION)
+ {
+ if(rValue.getValueType() != cppu::UnoType<bool>::get())
+ throw lang::IllegalArgumentException();
+ rValue >>= m_pImpl->m_bParam1;
+ }
+
+ break;
+ case SwFieldIds::Database:
+ if(rPropertyName == UNO_NAME_DATA_BASE_NAME)
+ rValue >>= m_pImpl->m_sParam1;
+ else if(rPropertyName == UNO_NAME_DATA_TABLE_NAME)
+ rValue >>= m_pImpl->m_sParam2;
+ else if(rPropertyName == UNO_NAME_DATA_COLUMN_NAME)
+ rValue >>= m_pImpl->m_sParam3;
+ else if(rPropertyName == UNO_NAME_DATA_COMMAND_TYPE)
+ rValue >>= m_pImpl->m_nParam2;
+ if(rPropertyName == UNO_NAME_DATA_BASE_URL)
+ rValue >>= m_pImpl->m_sParam5;
+
+ if ( ( !m_pImpl->m_sParam1.isEmpty()
+ || !m_pImpl->m_sParam5.isEmpty())
+ && !m_pImpl->m_sParam2.isEmpty()
+ && !m_pImpl->m_sParam3.isEmpty())
+ {
+ GetFieldType();
+ }
+ break;
+ case SwFieldIds::SetExp:
+ if(rPropertyName == UNO_NAME_NUMBERING_SEPARATOR)
+ rValue >>= m_pImpl->m_sParam1;
+ else if(rPropertyName == UNO_NAME_CHAPTER_NUMBERING_LEVEL)
+ rValue >>= m_pImpl->m_nParam1;
+ break;
+ case SwFieldIds::Dde:
+ {
+ sal_Int32 nPart = lcl_PropName2TokenPos(rPropertyName);
+ if(nPart < 3 )
+ {
+ if (m_pImpl->m_sParam1.isEmpty())
+ {
+ m_pImpl->m_sParam1
+ = OUStringChar(sfx2::cTokenSeparator)
+ + OUStringChar(sfx2::cTokenSeparator);
+ }
+ OUString sTmp;
+ rValue >>= sTmp;
+ sal_Int32 nIndex(0);
+ sal_Int32 nStart(0);
+ while (nIndex < m_pImpl->m_sParam1.getLength())
+ {
+ if (m_pImpl->m_sParam1[nIndex] == sfx2::cTokenSeparator)
+ {
+ if (0 == nPart)
+ break;
+ nStart = nIndex + 1;
+ --nPart;
+ }
+ ++nIndex;
+ }
+ assert(0 == nPart);
+ m_pImpl->m_sParam1 = m_pImpl->m_sParam1.replaceAt(
+ nStart, nIndex - nStart, sTmp);
+ }
+ else if(3 == nPart)
+ {
+ rValue >>= m_pImpl->m_bParam1;
+ }
+ }
+ break;
+ default:
+ throw beans::UnknownPropertyException( "Unknown property: " + rPropertyName, getXWeak() );
+ }
+ }
+}
+
+SwFieldType* SwXFieldMaster::GetFieldType(bool const bDontCreate) const
+{
+ if (!bDontCreate && SwFieldIds::Database == m_pImpl->m_nResTypeId
+ && !m_pImpl->m_pType && m_pImpl->m_pDoc)
+ {
+ SwDBData aData;
+
+ // set DataSource
+ svx::ODataAccessDescriptor aAcc;
+ if (!m_pImpl->m_sParam1.isEmpty())
+ aAcc[svx::DataAccessDescriptorProperty::DataSource] <<= m_pImpl->m_sParam1; // DataBaseName
+ else if (!m_pImpl->m_sParam5.isEmpty())
+ aAcc[svx::DataAccessDescriptorProperty::DatabaseLocation] <<= m_pImpl->m_sParam5; // DataBaseURL
+ aData.sDataSource = aAcc.getDataSource();
+
+ aData.sCommand = m_pImpl->m_sParam2;
+ aData.nCommandType = m_pImpl->m_nParam2;
+
+ SwDBFieldType aType(m_pImpl->m_pDoc, m_pImpl->m_sParam3, std::move(aData));
+ SwFieldType *const pType = m_pImpl->m_pDoc->getIDocumentFieldsAccess().InsertFieldType(aType);
+ m_pImpl->SetFieldType(pType);
+ }
+ return m_pImpl->m_pType;
+}
+
+uno::Any SAL_CALL
+SwXFieldMaster::getPropertyValue(const OUString& rPropertyName)
+{
+ SolarMutexGuard aGuard;
+ uno::Any aRet;
+ SwFieldType* pType = GetFieldType(true);
+ if( rPropertyName == UNO_NAME_INSTANCE_NAME )
+ {
+ OUString sName;
+ if(pType)
+ SwXTextFieldMasters::getInstanceName(*pType, sName);
+ aRet <<= sName;
+ }
+ else if(pType)
+ {
+ if(rPropertyName == UNO_NAME_NAME)
+ {
+ aRet <<= SwXFieldMaster::GetProgrammaticName(*pType, *m_pImpl->m_pDoc);
+ }
+ else if(rPropertyName == UNO_NAME_DEPENDENT_TEXT_FIELDS)
+ {
+ //fill all text fields into a sequence
+ std::vector<SwFormatField*> vpFields;
+ pType->GatherFields(vpFields);
+ uno::Sequence<uno::Reference <text::XDependentTextField> > aSeq(vpFields.size());
+ std::transform(vpFields.begin(), vpFields.end(), aSeq.getArray(),
+ [this](SwFormatField* pF) { return uno::Reference<text::XDependentTextField>(SwXTextField::CreateXTextField(m_pImpl->m_pDoc, pF)); });
+ aRet <<= aSeq;
+ }
+ else
+ {
+ //TODO: add properties for the other field types
+ const sal_uInt16 nMId = GetFieldTypeMId( rPropertyName, *pType );
+ if (USHRT_MAX == nMId)
+ {
+ throw beans::UnknownPropertyException(
+ "Unknown property: " + rPropertyName,
+ getXWeak());
+ }
+ pType->QueryValue( aRet, nMId );
+
+ if (rPropertyName == UNO_NAME_DATA_BASE_NAME ||
+ rPropertyName == UNO_NAME_DATA_BASE_URL)
+ {
+ OUString aDataSource;
+ aRet >>= aDataSource;
+ aRet <<= OUString();
+
+ OUString *pStr = nullptr; // only one of this properties will return
+ // a non-empty string.
+ INetURLObject aObj;
+ aObj.SetURL( aDataSource );
+ bool bIsURL = aObj.GetProtocol() != INetProtocol::NotValid;
+ if (bIsURL && rPropertyName == UNO_NAME_DATA_BASE_URL)
+ pStr = &aDataSource; // DataBaseURL
+ else if (!bIsURL && rPropertyName == UNO_NAME_DATA_BASE_NAME)
+ pStr = &aDataSource; // DataBaseName
+
+ if (pStr)
+ aRet <<= *pStr;
+ }
+ }
+ }
+ else
+ {
+ if(rPropertyName == UNO_NAME_DATA_COMMAND_TYPE)
+ aRet <<= m_pImpl->m_nParam2;
+ else if(rPropertyName == UNO_NAME_DEPENDENT_TEXT_FIELDS )
+ {
+ uno::Sequence<uno::Reference <text::XDependentTextField> > aRetSeq(0);
+ aRet <<= aRetSeq;
+ }
+ else
+ {
+ switch (m_pImpl->m_nResTypeId)
+ {
+ case SwFieldIds::User:
+ if( rPropertyName == UNO_NAME_CONTENT )
+ aRet <<= m_pImpl->m_sParam1;
+ else if(rPropertyName == UNO_NAME_VALUE)
+ aRet <<= m_pImpl->m_fParam1;
+ else if(rPropertyName == UNO_NAME_IS_EXPRESSION)
+ aRet <<= m_pImpl->m_bParam1;
+ break;
+ case SwFieldIds::Database:
+ if(rPropertyName == UNO_NAME_DATA_BASE_NAME ||
+ rPropertyName == UNO_NAME_DATA_BASE_URL)
+ {
+ // only one of these properties returns a non-empty string.
+ INetURLObject aObj;
+ aObj.SetURL(m_pImpl->m_sParam5); // SetSmartURL
+ bool bIsURL = aObj.GetProtocol() != INetProtocol::NotValid;
+ if (bIsURL && rPropertyName == UNO_NAME_DATA_BASE_URL)
+ aRet <<= m_pImpl->m_sParam5; // DataBaseURL
+ else if ( rPropertyName == UNO_NAME_DATA_BASE_NAME)
+ aRet <<= m_pImpl->m_sParam1; // DataBaseName
+ }
+ else if(rPropertyName == UNO_NAME_DATA_TABLE_NAME)
+ aRet <<= m_pImpl->m_sParam2;
+ else if(rPropertyName == UNO_NAME_DATA_COLUMN_NAME)
+ aRet <<= m_pImpl->m_sParam3;
+ break;
+ case SwFieldIds::SetExp:
+ if(rPropertyName == UNO_NAME_NUMBERING_SEPARATOR)
+ aRet <<= m_pImpl->m_sParam1;
+ else if(rPropertyName == UNO_NAME_CHAPTER_NUMBERING_LEVEL)
+ aRet <<= m_pImpl->m_nParam1;
+ break;
+ case SwFieldIds::Dde:
+ {
+ const sal_Int32 nPart = lcl_PropName2TokenPos(rPropertyName);
+ if(nPart < 3 )
+ aRet <<= m_pImpl->m_sParam1.getToken(nPart, sfx2::cTokenSeparator);
+ else if(3 == nPart)
+ aRet <<= m_pImpl->m_bParam1;
+ }
+ break;
+ default:
+ throw beans::UnknownPropertyException( "Unknown property: " + rPropertyName, getXWeak() );
+ }
+ }
+ }
+ return aRet;
+}
+
+void SwXFieldMaster::addPropertyChangeListener(const OUString& /*PropertyName*/, const uno::Reference< beans::XPropertyChangeListener > & /*aListener*/)
+{
+ OSL_FAIL("not implemented");
+}
+
+void SwXFieldMaster::removePropertyChangeListener(const OUString& /*PropertyName*/, const uno::Reference< beans::XPropertyChangeListener > & /*aListener*/)
+{
+ OSL_FAIL("not implemented");
+}
+
+void SwXFieldMaster::addVetoableChangeListener(const OUString& /*PropertyName*/, const uno::Reference< beans::XVetoableChangeListener > & /*aListener*/)
+{
+ OSL_FAIL("not implemented");
+}
+
+void SwXFieldMaster::removeVetoableChangeListener(const OUString& /*PropertyName*/, const uno::Reference< beans::XVetoableChangeListener > & /*aListener*/)
+{
+ OSL_FAIL("not implemented");
+}
+
+void SAL_CALL SwXFieldMaster::dispose()
+{
+ SolarMutexGuard aGuard;
+ SwFieldType *const pFieldType = GetFieldType(true);
+ if (!pFieldType)
+ throw uno::RuntimeException();
+ size_t nTypeIdx = SIZE_MAX;
+ const SwFieldTypes* pTypes = m_pImpl->m_pDoc->getIDocumentFieldsAccess().GetFieldTypes();
+ for( size_t i = 0; i < pTypes->size(); i++ )
+ {
+ if((*pTypes)[i].get()== pFieldType)
+ nTypeIdx = i;
+ }
+
+ // first delete all fields
+ std::vector<SwFormatField*> vpFields;
+ pFieldType->GatherFields(vpFields);
+ for(auto pField : vpFields)
+ SwTextField::DeleteTextField(*pField->GetTextField());
+ // then delete FieldType
+ m_pImpl->m_pDoc->getIDocumentFieldsAccess().RemoveFieldType(nTypeIdx);
+}
+
+void SAL_CALL SwXFieldMaster::addEventListener(
+ const uno::Reference<lang::XEventListener> & xListener)
+{
+ std::unique_lock aGuard(m_pImpl->m_Mutex);
+ m_pImpl->m_EventListeners.addInterface(aGuard, xListener);
+}
+
+void SAL_CALL SwXFieldMaster::removeEventListener(
+ const uno::Reference<lang::XEventListener> & xListener)
+{
+ std::unique_lock aGuard(m_pImpl->m_Mutex);
+ m_pImpl->m_EventListeners.removeInterface(aGuard, xListener);
+}
+
+void SwXFieldMaster::Impl::Notify(const SfxHint& rHint)
+{
+ if(rHint.GetId() == SfxHintId::Dying)
+ {
+ m_pDoc = nullptr;
+ m_pType = nullptr;
+ uno::Reference<uno::XInterface> const xThis(m_wThis);
+ if (!xThis.is())
+ { // fdo#72695: if UNO object is already dead, don't revive it with event
+ return;
+ }
+ lang::EventObject const ev(xThis);
+ std::unique_lock aGuard(m_Mutex);
+ m_EventListeners.disposeAndClear(aGuard, ev);
+ }
+}
+
+OUString SwXFieldMaster::GetProgrammaticName(const SwFieldType& rType, SwDoc& rDoc)
+{
+ const OUString sName(rType.GetName());
+ if(SwFieldIds::SetExp == rType.Which())
+ {
+ const SwFieldTypes* pTypes = rDoc.getIDocumentFieldsAccess().GetFieldTypes();
+ for( size_t i = 0; i <= o3tl::make_unsigned(INIT_FLDTYPES); i++ )
+ {
+ if((*pTypes)[i].get() == &rType)
+ {
+ return SwStyleNameMapper::GetProgName( sName, SwGetPoolIdFromName::TxtColl );
+ }
+ }
+ }
+ return sName;
+}
+
+OUString SwXFieldMaster::LocalizeFormula(
+ const SwSetExpField& rField,
+ const OUString& rFormula,
+ bool bQuery)
+{
+ const OUString sTypeName(rField.GetTyp()->GetName());
+ const OUString sProgName(
+ SwStyleNameMapper::GetProgName(sTypeName, SwGetPoolIdFromName::TxtColl ));
+ if(sProgName != sTypeName)
+ {
+ const OUString sSource = bQuery ? sTypeName : sProgName;
+ const OUString sDest = bQuery ? sProgName : sTypeName;
+ if(rFormula.startsWith(sSource))
+ {
+ return sDest + rFormula.subView(sSource.getLength());
+ }
+ }
+ return rFormula;
+}
+
+namespace {
+
+struct SwFieldProperties_Impl
+{
+ OUString sPar1;
+ OUString sPar2;
+ OUString sPar3;
+ OUString sPar4;
+ OUString sPar5;
+ OUString sPar6;
+ OUString sPar7;
+ Date aDate;
+ double fDouble;
+ uno::Sequence<beans::PropertyValue> aPropSeq;
+ uno::Sequence<OUString> aStrings;
+ std::unique_ptr<util::DateTime> pDateTime;
+
+ sal_Int32 nSubType;
+ sal_Int32 nFormat;
+ sal_uInt16 nUSHORT1;
+ sal_uInt16 nUSHORT2;
+ sal_uInt16 nUSHORT3;
+ sal_Int16 nSHORT1;
+ sal_Int8 nByte1;
+ bool bFormatIsDefault;
+ bool bBool1;
+ bool bBool2;
+ bool bBool3;
+ bool bBool4;
+
+ SwFieldProperties_Impl():
+ aDate( Date::EMPTY ),
+ fDouble(0.),
+ nSubType(0),
+ nFormat(0),
+ nUSHORT1(0),
+ nUSHORT2(0),
+ nUSHORT3(0),
+ nSHORT1(0),
+ nByte1(0),
+ bFormatIsDefault(true),
+ bBool1(false),
+ bBool2(false),
+ bBool3(false),
+ bBool4(true) //Automatic language
+ {}
+};
+
+}
+
+class SwXTextField::Impl
+ : public SvtListener
+{
+public:
+ std::mutex m_Mutex; // just for OInterfaceContainerHelper4
+ SwFieldType* m_pFieldType;
+ SwFormatField* m_pFormatField;
+
+ unotools::WeakReference<SwXTextField> m_wThis;
+ ::comphelper::OInterfaceContainerHelper4<css::lang::XEventListener> m_EventListeners;
+
+ SwDoc* m_pDoc;
+ rtl::Reference<SwTextAPIObject> m_xTextObject;
+ bool m_bIsDescriptor;
+ bool m_bCallUpdate;
+ SwServiceType m_nServiceId;
+ OUString m_sTypeName;
+ std::unique_ptr<SwFieldProperties_Impl> m_pProps;
+
+ Impl(SwDoc *const pDoc, SwFormatField *const pFormat, SwServiceType nServiceId)
+ : m_pFieldType(nullptr)
+ , m_pFormatField(pFormat)
+ , m_pDoc(pDoc)
+ , m_bIsDescriptor(pFormat == nullptr)
+ , m_bCallUpdate(false)
+ , m_nServiceId(pFormat
+ ? lcl_GetServiceForField(*pFormat->GetField())
+ : nServiceId)
+ , m_pProps(pFormat ? nullptr : new SwFieldProperties_Impl)
+ {
+ if(m_pFormatField)
+ StartListening(m_pFormatField->GetNotifier());
+ }
+
+ virtual ~Impl() override
+ {
+ if (m_xTextObject.is())
+ {
+ m_xTextObject->DisposeEditSource();
+ }
+ }
+
+ void SetFormatField(SwFormatField* pFormatField, SwDoc* pDoc)
+ {
+ m_pFormatField = pFormatField;
+ m_pDoc = pDoc;
+ if(m_pFormatField)
+ {
+ EndListeningAll();
+ StartListening(m_pFormatField->GetNotifier());
+ }
+ }
+ SwFormatField* GetFormatField()
+ {
+ return m_pFormatField;
+ }
+ bool IsDescriptor() const
+ {
+ // ideally should be: !m_pFormatField && m_pDoc
+ // but: SwXServiceProvider::MakeInstance() passes nullptr SwDoc, see comment there
+ return m_bIsDescriptor;
+ }
+ void Invalidate();
+
+ const SwField* GetField() const;
+
+ SwFieldType* GetFieldType() const
+ {
+ if(!m_pDoc && !IsDescriptor())
+ throw uno::RuntimeException();
+ else if (IsDescriptor())
+ return m_pFieldType;
+
+ return m_pFormatField->GetField()->GetTyp();
+ }
+ void SetFieldType(SwFieldType& rType)
+ {
+ EndListeningAll();
+ m_pFieldType = &rType;
+ StartListening(m_pFieldType->GetNotifier());
+ }
+ void ClearFieldType()
+ {
+ SvtListener::EndListeningAll();
+ m_pFieldType = nullptr;
+ }
+ virtual void Notify(const SfxHint&) override;
+};
+
+SwXTextField::SwXTextField(
+ SwServiceType nServiceId,
+ SwDoc* pDoc)
+ : m_pImpl(new Impl(pDoc, nullptr, nServiceId))
+{
+ //Set visible as default!
+ if ( SwServiceType::FieldTypeSetExp == nServiceId
+ || SwServiceType::FieldTypeDatabaseSetNum == nServiceId
+ || SwServiceType::FieldTypeDatabase == nServiceId
+ || SwServiceType::FieldTypeDatabaseName == nServiceId )
+ {
+ m_pImpl->m_pProps->bBool2 = true;
+ }
+ else if(SwServiceType::FieldTypeTableFormula == nServiceId)
+ {
+ m_pImpl->m_pProps->bBool1 = true;
+ }
+ if(SwServiceType::FieldTypeSetExp == nServiceId)
+ {
+ m_pImpl->m_pProps->nUSHORT2 = USHRT_MAX;
+ }
+}
+
+SwXTextField::SwXTextField(SwFormatField& rFormat, SwDoc & rDoc)
+ : m_pImpl(new Impl(&rDoc, &rFormat, SwServiceType::Invalid))
+{
+}
+
+SwXTextField::~SwXTextField()
+{
+}
+
+rtl::Reference<SwXTextField>
+SwXTextField::CreateXTextField(SwDoc *const pDoc, SwFormatField const* pFormat,
+ SwServiceType nServiceId)
+{
+ assert(!pFormat || pDoc);
+ assert(pFormat || nServiceId != SwServiceType::Invalid);
+ // re-use existing SwXTextField
+ rtl::Reference<SwXTextField> xField;
+ if (pFormat)
+ {
+ xField = pFormat->GetXTextField();
+ }
+ if (!xField.is())
+ {
+ SwXTextField *const pField( pFormat
+ ? new SwXTextField(const_cast<SwFormatField&>(*pFormat), *pDoc)
+ : new SwXTextField(nServiceId, pDoc));
+ xField.set(pField);
+ if (pFormat)
+ {
+ const_cast<SwFormatField *>(pFormat)->SetXTextField(xField);
+ }
+ // need a permanent Reference to initialize m_wThis
+ pField->m_pImpl->m_wThis = xField.get();
+ }
+ return xField;
+}
+
+SwServiceType SwXTextField::GetServiceId() const
+{
+ return m_pImpl->m_nServiceId;
+}
+
+/** Convert between SwSetExpField with InputFlag false and InputFlag true.
+ Unfortunately the InputFlag is exposed in the API as "Input" property
+ and is mutable; in the UI and in ODF these are 2 different types of
+ fields, so the API design is very questionable.
+ In order to keep the mutable property, the whole thing has to be
+ reconstructed from scratch, to replace the SwTextField hint with
+ SwTextInputField or vice versa.
+ The SwFormatField will be replaced - it must be, because the Which
+ changes - but the SwXTextField *must not* be disposed in the operation,
+ it has to be disconnected first and at the end connected to the
+ new instance!
+ */
+void SwXTextField::TransmuteLeadToInputField(SwSetExpField & rField)
+{
+ assert(rField.GetFormatField()->Which() == (rField.GetInputFlag() ? RES_TXTATR_INPUTFIELD : RES_TXTATR_FIELD));
+ rtl::Reference<SwXTextField> const pXField(
+ rField.GetFormatField()->GetXTextField());
+ if (pXField)
+ pXField->m_pImpl->SetFormatField(nullptr, nullptr);
+ SwTextField *const pOldAttr(rField.GetFormatField()->GetTextField());
+ SwSetExpField tempField(rField);
+ tempField.SetInputFlag(!rField.GetInputFlag());
+ SwFormatField tempFormat(tempField);
+ assert(tempFormat.GetField() != &rField);
+ assert(tempFormat.GetField() != &tempField); // this copies it again?
+ assert(tempFormat.Which() == (static_cast<SwSetExpField const*>(tempFormat.GetField())->GetInputFlag() ? RES_TXTATR_INPUTFIELD : RES_TXTATR_FIELD));
+ SwTextNode & rNode(pOldAttr->GetTextNode());
+ std::shared_ptr<SwPaM> pPamForTextField;
+ IDocumentContentOperations & rIDCO(rNode.GetDoc().getIDocumentContentOperations());
+ SwTextField::GetPamForTextField(*pOldAttr, pPamForTextField);
+ assert(pPamForTextField);
+ sal_Int32 const nStart(pPamForTextField->Start()->GetContentIndex());
+ rIDCO.DeleteAndJoin(*pPamForTextField);
+ // ATTENTION: rField is dead now! hope nobody accesses it...
+ bool bSuccess = rIDCO.InsertPoolItem(*pPamForTextField, tempFormat);
+ assert(bSuccess);
+ (void) bSuccess;
+ SwTextField const* pNewAttr(rNode.GetFieldTextAttrAt(nStart, ::sw::GetTextAttrMode::Default));
+ assert(pNewAttr);
+ SwFormatField const& rNewFormat(pNewAttr->GetFormatField());
+ assert(rNewFormat.Which() == (static_cast<SwSetExpField const*>(rNewFormat.GetField())->GetInputFlag() ? RES_TXTATR_INPUTFIELD : RES_TXTATR_FIELD));
+ assert(static_cast<SwSetExpField const*>(rNewFormat.GetField())->GetInputFlag() == (dynamic_cast<SwTextInputField const*>(pNewAttr) != nullptr));
+ if (pXField)
+ {
+ pXField->m_pImpl->SetFormatField(const_cast<SwFormatField*>(&rNewFormat), &rNode.GetDoc());
+ const_cast<SwFormatField&>(rNewFormat).SetXTextField(pXField);
+ }
+}
+
+void SAL_CALL SwXTextField::attachTextFieldMaster(
+ const uno::Reference< beans::XPropertySet > & xFieldMaster)
+{
+ SolarMutexGuard aGuard;
+
+ if (!m_pImpl->IsDescriptor())
+ throw uno::RuntimeException();
+ SwXFieldMaster* pMaster = dynamic_cast<SwXFieldMaster*>(xFieldMaster.get());
+
+ SwFieldType* pFieldType = pMaster ? pMaster->GetFieldType() : nullptr;
+ if (!pFieldType ||
+ pFieldType->Which() != lcl_ServiceIdToResId(m_pImpl->m_nServiceId))
+ {
+ throw lang::IllegalArgumentException();
+ }
+ m_pImpl->m_sTypeName = pFieldType->GetName();
+ m_pImpl->SetFieldType(*pFieldType);
+}
+
+uno::Reference< beans::XPropertySet > SAL_CALL
+SwXTextField::getTextFieldMaster()
+{
+ SolarMutexGuard aGuard;
+
+ SwFieldType* pType = m_pImpl->GetFieldType();
+ if (!pType && !m_pImpl->m_pDoc) // tdf#152619
+ return nullptr;
+ uno::Reference<beans::XPropertySet> const xRet(
+ SwXFieldMaster::CreateXFieldMaster(m_pImpl->m_pDoc, pType));
+ return xRet;
+}
+
+OUString SAL_CALL SwXTextField::getPresentation(sal_Bool bShowCommand)
+{
+ SolarMutexGuard aGuard;
+
+ SwField const*const pField = m_pImpl->GetField();
+ if (!pField)
+ {
+ throw uno::RuntimeException();
+ }
+ return bShowCommand ? pField->GetFieldName() : pField->ExpandField(true, nullptr);
+}
+
+void SAL_CALL SwXTextField::attach(
+ const uno::Reference< text::XTextRange > & xTextRange)
+{
+ SolarMutexGuard aGuard;
+ if (m_pImpl->IsDescriptor())
+ {
+ SwXTextRange* pRange = dynamic_cast<SwXTextRange*>(xTextRange.get());
+ OTextCursorHelper* pCursor = dynamic_cast<OTextCursorHelper*>(xTextRange.get());
+
+ SwDoc* pDoc = pRange ? &pRange->GetDoc() : pCursor ? pCursor->GetDoc() : nullptr;
+ // if a FieldMaster was attached, then the document is already fixed!
+ // NOTE: sw.SwXAutoTextEntry unoapi test depends on m_pDoc = 0 being valid
+ if (!pDoc || (m_pImpl->m_pDoc && m_pImpl->m_pDoc != pDoc))
+ throw lang::IllegalArgumentException();
+
+ SwUnoInternalPaM aPam(*pDoc);
+ // this now needs to return TRUE
+ ::sw::XTextRangeToSwPaM(aPam, xTextRange);
+ std::unique_ptr<SwField> xField;
+ switch (m_pImpl->m_nServiceId)
+ {
+ case SwServiceType::FieldTypeAnnotation:
+ {
+ SwFieldType* pFieldType = pDoc->getIDocumentFieldsAccess().GetSysFieldType(SwFieldIds::Postit);
+
+ DateTime aDateTime( DateTime::EMPTY );
+ if (m_pImpl->m_pProps->pDateTime)
+ {
+ aDateTime = *(m_pImpl->m_pProps->pDateTime);
+ }
+
+ sal_uInt32 nImportedId = 0;
+ if (!m_pImpl->m_pProps->sPar6.isEmpty())
+ nImportedId = m_pImpl->m_pProps->sPar6.toInt32(16);
+ sal_uInt32 nParentId = 0;
+ if (!m_pImpl->m_pProps->sPar5.isEmpty())
+ nParentId = m_pImpl->m_pProps->sPar5.toInt32(16);
+
+ SwPostItField* pPostItField = new SwPostItField(
+ static_cast<SwPostItFieldType*>(pFieldType),
+ m_pImpl->m_pProps->sPar1, // author
+ m_pImpl->m_pProps->sPar2, // content
+ m_pImpl->m_pProps->sPar3, // author's initials
+ m_pImpl->m_pProps->sPar4, // name
+ aDateTime,
+ m_pImpl->m_pProps->bBool1, // resolvedflag
+ 0, // id
+ nParentId, // parent id
+ nImportedId, // imported para id
+ 0, // PostIt Parent ID.
+ m_pImpl->m_pProps->sPar7
+ );
+ if ( m_pImpl->m_xTextObject.is() )
+ {
+ pPostItField->SetTextObject( m_pImpl->m_xTextObject->CreateText() );
+ pPostItField->SetPar2(m_pImpl->m_xTextObject->GetText());
+ }
+ xField.reset(pPostItField);
+ }
+ break;
+ case SwServiceType::FieldTypeScript:
+ {
+ SwFieldType* pFieldType = pDoc->getIDocumentFieldsAccess().GetSysFieldType(SwFieldIds::Script);
+ xField.reset(new SwScriptField(static_cast<SwScriptFieldType*>(pFieldType),
+ m_pImpl->m_pProps->sPar1, m_pImpl->m_pProps->sPar2,
+ m_pImpl->m_pProps->bBool1));
+ }
+ break;
+ case SwServiceType::FieldTypeDateTime:
+ {
+ sal_uInt16 nSub = 0;
+ if (m_pImpl->m_pProps->bBool1)
+ nSub |= FIXEDFLD;
+ if (m_pImpl->m_pProps->bBool2)
+ nSub |= DATEFLD;
+ else
+ nSub |= TIMEFLD;
+ SwFieldType* pFieldType = pDoc->getIDocumentFieldsAccess().GetSysFieldType(SwFieldIds::DateTime);
+ SwDateTimeField *const pDTField = new SwDateTimeField(
+ static_cast<SwDateTimeFieldType*>(pFieldType),
+ nSub, m_pImpl->m_pProps->nFormat);
+ xField.reset(pDTField);
+ if (m_pImpl->m_pProps->fDouble > 0.)
+ {
+ pDTField->SetValue(m_pImpl->m_pProps->fDouble);
+ }
+ if (m_pImpl->m_pProps->pDateTime)
+ {
+ uno::Any aVal; aVal <<= *m_pImpl->m_pProps->pDateTime;
+ xField->PutValue( aVal, FIELD_PROP_DATE_TIME );
+ }
+ pDTField->SetOffset(m_pImpl->m_pProps->nSubType);
+ }
+ break;
+ case SwServiceType::FieldTypeFileName:
+ {
+ SwFieldType* pFieldType = pDoc->getIDocumentFieldsAccess().GetSysFieldType(SwFieldIds::Filename);
+ sal_Int32 nFormat = m_pImpl->m_pProps->nFormat;
+ if (m_pImpl->m_pProps->bBool2)
+ nFormat |= FF_FIXED;
+ SwFileNameField *const pFNField = new SwFileNameField(
+ static_cast<SwFileNameFieldType*>(pFieldType), nFormat);
+ xField.reset(pFNField);
+ if (!m_pImpl->m_pProps->sPar3.isEmpty())
+ pFNField->SetExpansion(m_pImpl->m_pProps->sPar3);
+ uno::Any aFormat;
+ aFormat <<= m_pImpl->m_pProps->nFormat;
+ xField->PutValue( aFormat, FIELD_PROP_FORMAT );
+ }
+ break;
+ case SwServiceType::FieldTypeTemplateName:
+ {
+ SwFieldType* pFieldType = pDoc->getIDocumentFieldsAccess().GetSysFieldType(SwFieldIds::TemplateName);
+ xField.reset(new SwTemplNameField(static_cast<SwTemplNameFieldType*>(pFieldType),
+ m_pImpl->m_pProps->nFormat));
+ uno::Any aFormat;
+ aFormat <<= m_pImpl->m_pProps->nFormat;
+ xField->PutValue(aFormat, FIELD_PROP_FORMAT);
+ }
+ break;
+ case SwServiceType::FieldTypeChapter:
+ {
+ SwFieldType* pFieldType = pDoc->getIDocumentFieldsAccess().GetSysFieldType(SwFieldIds::Chapter);
+ SwChapterField *const pChapterField = new SwChapterField(
+ static_cast<SwChapterFieldType*>(pFieldType),
+ m_pImpl->m_pProps->nUSHORT1);
+ xField.reset(pChapterField);
+ pChapterField->SetLevel(m_pImpl->m_pProps->nByte1);
+ uno::Any aVal;
+ aVal <<= static_cast<sal_Int16>(m_pImpl->m_pProps->nUSHORT1);
+ xField->PutValue(aVal, FIELD_PROP_USHORT1 );
+ }
+ break;
+ case SwServiceType::FieldTypeAuthor:
+ {
+ tools::Long nFormat = m_pImpl->m_pProps->bBool1 ? AF_NAME : AF_SHORTCUT;
+ if (m_pImpl->m_pProps->bBool2)
+ nFormat |= AF_FIXED;
+
+ SwFieldType* pFieldType = pDoc->getIDocumentFieldsAccess().GetSysFieldType(SwFieldIds::Author);
+ SwAuthorField *const pAuthorField = new SwAuthorField(
+ static_cast<SwAuthorFieldType*>(pFieldType), nFormat);
+ xField.reset(pAuthorField);
+ pAuthorField->SetExpansion(m_pImpl->m_pProps->sPar1);
+ }
+ break;
+ case SwServiceType::FieldTypeConditionedText:
+ case SwServiceType::FieldTypeHiddenText:
+ {
+ SwFieldType* pFieldType = pDoc->getIDocumentFieldsAccess().GetSysFieldType(SwFieldIds::HiddenText);
+ SwHiddenTextField *const pHTField = new SwHiddenTextField(
+ static_cast<SwHiddenTextFieldType*>(pFieldType),
+ m_pImpl->m_pProps->sPar1,
+ m_pImpl->m_pProps->sPar2, m_pImpl->m_pProps->sPar3,
+ SwServiceType::FieldTypeHiddenText == m_pImpl->m_nServiceId ?
+ SwFieldTypesEnum::HiddenText : SwFieldTypesEnum::ConditionalText);
+ xField.reset(pHTField);
+ pHTField->SetValue(m_pImpl->m_pProps->bBool1);
+ uno::Any aVal;
+ aVal <<= m_pImpl->m_pProps->sPar4;
+ xField->PutValue(aVal, FIELD_PROP_PAR4 );
+ }
+ break;
+ case SwServiceType::FieldTypeHiddenPara:
+ {
+ SwFieldType* pFieldType = pDoc->getIDocumentFieldsAccess().GetSysFieldType(SwFieldIds::HiddenPara);
+ SwHiddenParaField *const pHPField = new SwHiddenParaField(
+ static_cast<SwHiddenParaFieldType*>(pFieldType),
+ m_pImpl->m_pProps->sPar1);
+ xField.reset(pHPField);
+ pHPField->SetHidden(m_pImpl->m_pProps->bBool1);
+ }
+ break;
+ case SwServiceType::FieldTypeGetReference:
+ {
+ SwFieldType* pFieldType = pDoc->getIDocumentFieldsAccess().GetSysFieldType(SwFieldIds::GetRef);
+ xField.reset(new SwGetRefField(static_cast<SwGetRefFieldType*>(pFieldType),
+ m_pImpl->m_pProps->sPar1,
+ m_pImpl->m_pProps->sPar4,
+ 0,
+ 0,
+ 0,
+ 0));
+ if (!m_pImpl->m_pProps->sPar3.isEmpty())
+ static_cast<SwGetRefField*>(xField.get())->SetExpand(m_pImpl->m_pProps->sPar3);
+ uno::Any aVal;
+ aVal <<= static_cast<sal_Int16>(m_pImpl->m_pProps->nUSHORT1);
+ xField->PutValue(aVal, FIELD_PROP_USHORT1 );
+ aVal <<= static_cast<sal_Int16>(m_pImpl->m_pProps->nUSHORT2);
+ xField->PutValue(aVal, FIELD_PROP_USHORT2 );
+ aVal <<= static_cast<sal_Int16>(m_pImpl->m_pProps->nUSHORT3);
+ xField->PutValue(aVal, FIELD_PROP_USHORT3 );
+ aVal <<= m_pImpl->m_pProps->nSHORT1;
+ xField->PutValue(aVal, FIELD_PROP_SHORT1 );
+ }
+ break;
+ case SwServiceType::FieldTypeJumpEdit:
+ {
+ SwFieldType* pFieldType = pDoc->getIDocumentFieldsAccess().GetSysFieldType(SwFieldIds::JumpEdit);
+ xField.reset(new SwJumpEditField(static_cast<SwJumpEditFieldType*>(pFieldType),
+ m_pImpl->m_pProps->nUSHORT1, m_pImpl->m_pProps->sPar2,
+ m_pImpl->m_pProps->sPar1));
+ }
+ break;
+ case SwServiceType::FieldTypeDocInfoChangeAuthor:
+ case SwServiceType::FieldTypeDocInfoChangeDateTime:
+ case SwServiceType::FieldTypeDocInfoEditTime:
+ case SwServiceType::FieldTypeDocInfoDescription:
+ case SwServiceType::FieldTypeDocInfoCreateAuthor:
+ case SwServiceType::FieldTypeDocInfoCreateDateTime:
+ case SwServiceType::FieldTypeDocInfoCustom:
+ case SwServiceType::FieldTypeDocInfoPrintAuthor:
+ case SwServiceType::FieldTypeDocInfoPrintDateTime:
+ case SwServiceType::FieldTypeDocInfoKeywords:
+ case SwServiceType::FieldTypeDocInfoSubject:
+ case SwServiceType::FieldTypeDocInfoTitle:
+ case SwServiceType::FieldTypeDocInfoRevision:
+ case SwServiceType::FieldTypeDocInfo:
+ {
+ SwFieldType* pFieldType = pDoc->getIDocumentFieldsAccess().GetSysFieldType(SwFieldIds::DocInfo);
+ sal_uInt16 nSubType = aDocInfoSubTypeFromService[
+ static_cast<sal_uInt16>(m_pImpl->m_nServiceId) - sal_uInt16(SwServiceType::FieldTypeDocInfoChangeAuthor)];
+ if (SwServiceType::FieldTypeDocInfoChangeDateTime == m_pImpl->m_nServiceId ||
+ SwServiceType::FieldTypeDocInfoCreateDateTime == m_pImpl->m_nServiceId ||
+ SwServiceType::FieldTypeDocInfoPrintDateTime == m_pImpl->m_nServiceId ||
+ SwServiceType::FieldTypeDocInfoEditTime == m_pImpl->m_nServiceId)
+ {
+ if (m_pImpl->m_pProps->bBool2) //IsDate
+ {
+ nSubType &= 0xf0ff;
+ nSubType |= DI_SUB_DATE;
+ }
+ else
+ {
+ nSubType &= 0xf0ff;
+ nSubType |= DI_SUB_TIME;
+ }
+ }
+ if (m_pImpl->m_pProps->bBool1)
+ nSubType |= DI_SUB_FIXED;
+ xField.reset(new SwDocInfoField(
+ static_cast<SwDocInfoFieldType*>(pFieldType), nSubType,
+ m_pImpl->m_pProps->sPar4, m_pImpl->m_pProps->nFormat));
+ if (!m_pImpl->m_pProps->sPar3.isEmpty())
+ static_cast<SwDocInfoField*>(xField.get())->SetExpansion(m_pImpl->m_pProps->sPar3);
+ }
+ break;
+ case SwServiceType::FieldTypeUserExt:
+ {
+ sal_Int32 nFormat = 0;
+ if (m_pImpl->m_pProps->bBool1)
+ nFormat = AF_FIXED;
+
+ SwFieldType* pFieldType = pDoc->getIDocumentFieldsAccess().GetSysFieldType(SwFieldIds::ExtUser);
+ SwExtUserField *const pEUField = new SwExtUserField(
+ static_cast<SwExtUserFieldType*>(pFieldType),
+ m_pImpl->m_pProps->nUSHORT1, nFormat);
+ xField.reset(pEUField);
+ pEUField->SetExpansion(m_pImpl->m_pProps->sPar1);
+ }
+ break;
+ case SwServiceType::FieldTypeUser:
+ {
+ SwFieldType* pFieldType =
+ pDoc->getIDocumentFieldsAccess().GetFieldType(SwFieldIds::User, m_pImpl->m_sTypeName, true);
+ if (!pFieldType)
+ throw uno::RuntimeException();
+ sal_uInt16 nUserSubType = (m_pImpl->m_pProps->bBool1)
+ ? nsSwExtendedSubType::SUB_INVISIBLE : 0;
+ if (m_pImpl->m_pProps->bBool2)
+ nUserSubType |= nsSwExtendedSubType::SUB_CMD;
+ if (m_pImpl->m_pProps->bFormatIsDefault &&
+ nsSwGetSetExpType::GSE_STRING == static_cast<SwUserFieldType*>(pFieldType)->GetType())
+ {
+ m_pImpl->m_pProps->nFormat = -1;
+ }
+ xField.reset(new SwUserField(static_cast<SwUserFieldType*>(pFieldType),
+ nUserSubType,
+ m_pImpl->m_pProps->nFormat));
+ }
+ break;
+ case SwServiceType::FieldTypeRefPageSet:
+ {
+ SwFieldType* pFieldType = pDoc->getIDocumentFieldsAccess().GetSysFieldType(SwFieldIds::RefPageSet);
+ xField.reset(new SwRefPageSetField( static_cast<SwRefPageSetFieldType*>(pFieldType),
+ m_pImpl->m_pProps->nUSHORT1,
+ m_pImpl->m_pProps->bBool1 ));
+ }
+ break;
+ case SwServiceType::FieldTypeRefPageGet:
+ {
+ SwFieldType* pFieldType = pDoc->getIDocumentFieldsAccess().GetSysFieldType(SwFieldIds::RefPageGet);
+ SwRefPageGetField *const pRGField = new SwRefPageGetField(
+ static_cast<SwRefPageGetFieldType*>(pFieldType),
+ m_pImpl->m_pProps->nUSHORT1 );
+ xField.reset(pRGField);
+ pRGField->SetText(m_pImpl->m_pProps->sPar1, nullptr);
+ }
+ break;
+ case SwServiceType::FieldTypePageNum:
+ {
+ SwFieldType* pFieldType = pDoc->getIDocumentFieldsAccess().GetSysFieldType(SwFieldIds::PageNumber);
+ SwPageNumberField *const pPNField = new SwPageNumberField(
+ static_cast<SwPageNumberFieldType*>(pFieldType), PG_RANDOM,
+ m_pImpl->m_pProps->nFormat,
+ m_pImpl->m_pProps->nUSHORT1);
+ xField.reset(pPNField);
+ pPNField->SetUserString(m_pImpl->m_pProps->sPar1);
+ uno::Any aVal;
+ aVal <<= m_pImpl->m_pProps->nSubType;
+ xField->PutValue( aVal, FIELD_PROP_SUBTYPE );
+ }
+ break;
+ case SwServiceType::FieldTypeDDE:
+ {
+ SwFieldType* pFieldType =
+ pDoc->getIDocumentFieldsAccess().GetFieldType(SwFieldIds::Dde, m_pImpl->m_sTypeName, true);
+ if (!pFieldType)
+ throw uno::RuntimeException();
+ xField.reset(new SwDDEField( static_cast<SwDDEFieldType*>(pFieldType) ));
+ }
+ break;
+ case SwServiceType::FieldTypeDatabaseName:
+ {
+ SwFieldType* pFieldType = pDoc->getIDocumentFieldsAccess().GetSysFieldType(SwFieldIds::DatabaseName);
+ SwDBData aData;
+ aData.sDataSource = m_pImpl->m_pProps->sPar1;
+ aData.sCommand = m_pImpl->m_pProps->sPar2;
+ aData.nCommandType = m_pImpl->m_pProps->nSHORT1;
+ xField.reset(new SwDBNameField(static_cast<SwDBNameFieldType*>(pFieldType), aData));
+ sal_uInt16 nSubType = xField->GetSubType();
+ if (m_pImpl->m_pProps->bBool2)
+ nSubType &= ~nsSwExtendedSubType::SUB_INVISIBLE;
+ else
+ nSubType |= nsSwExtendedSubType::SUB_INVISIBLE;
+ xField->SetSubType(nSubType);
+ }
+ break;
+ case SwServiceType::FieldTypeDatabaseNextSet:
+ {
+ SwDBData aData;
+ aData.sDataSource = m_pImpl->m_pProps->sPar1;
+ aData.sCommand = m_pImpl->m_pProps->sPar2;
+ aData.nCommandType = m_pImpl->m_pProps->nSHORT1;
+ SwFieldType* pFieldType = pDoc->getIDocumentFieldsAccess().GetSysFieldType(SwFieldIds::DbNextSet);
+ xField.reset(new SwDBNextSetField(static_cast<SwDBNextSetFieldType*>(pFieldType),
+ m_pImpl->m_pProps->sPar3, aData));
+ }
+ break;
+ case SwServiceType::FieldTypeDatabaseNumSet:
+ {
+ SwDBData aData;
+ aData.sDataSource = m_pImpl->m_pProps->sPar1;
+ aData.sCommand = m_pImpl->m_pProps->sPar2;
+ aData.nCommandType = m_pImpl->m_pProps->nSHORT1;
+ xField.reset(new SwDBNumSetField( static_cast<SwDBNumSetFieldType*>(
+ pDoc->getIDocumentFieldsAccess().GetSysFieldType(SwFieldIds::DbNumSet)),
+ m_pImpl->m_pProps->sPar3,
+ OUString::number(m_pImpl->m_pProps->nFormat),
+ aData ));
+ }
+ break;
+ case SwServiceType::FieldTypeDatabaseSetNum:
+ {
+ SwDBData aData;
+ aData.sDataSource = m_pImpl->m_pProps->sPar1;
+ aData.sCommand = m_pImpl->m_pProps->sPar2;
+ aData.nCommandType = m_pImpl->m_pProps->nSHORT1;
+ SwDBSetNumberField *const pDBSNField =
+ new SwDBSetNumberField(static_cast<SwDBSetNumberFieldType*>(
+ pDoc->getIDocumentFieldsAccess().GetSysFieldType(SwFieldIds::DbSetNumber)), aData,
+ m_pImpl->m_pProps->nUSHORT1);
+ xField.reset(pDBSNField);
+ pDBSNField->SetSetNumber(m_pImpl->m_pProps->nFormat);
+ sal_uInt16 nSubType = xField->GetSubType();
+ if (m_pImpl->m_pProps->bBool2)
+ nSubType &= ~nsSwExtendedSubType::SUB_INVISIBLE;
+ else
+ nSubType |= nsSwExtendedSubType::SUB_INVISIBLE;
+ xField->SetSubType(nSubType);
+ }
+ break;
+ case SwServiceType::FieldTypeDatabase:
+ {
+ SwFieldType* pFieldType =
+ pDoc->getIDocumentFieldsAccess().GetFieldType(SwFieldIds::Database, m_pImpl->m_sTypeName, false);
+ if (!pFieldType)
+ throw uno::RuntimeException();
+ xField.reset(new SwDBField(static_cast<SwDBFieldType*>(pFieldType),
+ m_pImpl->m_pProps->nFormat));
+ static_cast<SwDBField*>(xField.get())->InitContent(m_pImpl->m_pProps->sPar1);
+ sal_uInt16 nSubType = xField->GetSubType();
+ if (m_pImpl->m_pProps->bBool2)
+ nSubType &= ~nsSwExtendedSubType::SUB_INVISIBLE;
+ else
+ nSubType |= nsSwExtendedSubType::SUB_INVISIBLE;
+ xField->SetSubType(nSubType);
+ }
+ break;
+ case SwServiceType::FieldTypeSetExp:
+ {
+ SwFieldType* pFieldType =
+ pDoc->getIDocumentFieldsAccess().GetFieldType(SwFieldIds::SetExp, m_pImpl->m_sTypeName, true);
+ if (!pFieldType)
+ throw uno::RuntimeException();
+ // detect the field type's sub type and set an appropriate number format
+ if (m_pImpl->m_pProps->bFormatIsDefault &&
+ nsSwGetSetExpType::GSE_STRING == static_cast<SwSetExpFieldType*>(pFieldType)->GetType())
+ {
+ m_pImpl->m_pProps->nFormat = -1;
+ }
+ SwSetExpField *const pSEField = new SwSetExpField(
+ static_cast<SwSetExpFieldType*>(pFieldType),
+ m_pImpl->m_pProps->sPar2,
+ m_pImpl->m_pProps->nUSHORT2 != USHRT_MAX ? //#i79471# the field can have a number format or a number_ing_ format
+ m_pImpl->m_pProps->nUSHORT2 : m_pImpl->m_pProps->nFormat);
+ xField.reset(pSEField);
+
+ sal_uInt16 nSubType = xField->GetSubType();
+ if (m_pImpl->m_pProps->bBool2)
+ nSubType &= ~nsSwExtendedSubType::SUB_INVISIBLE;
+ else
+ nSubType |= nsSwExtendedSubType::SUB_INVISIBLE;
+ if (m_pImpl->m_pProps->bBool3)
+ nSubType |= nsSwExtendedSubType::SUB_CMD;
+ else
+ nSubType &= ~nsSwExtendedSubType::SUB_CMD;
+ xField->SetSubType(nSubType);
+ pSEField->SetSeqNumber(m_pImpl->m_pProps->nUSHORT1);
+ pSEField->SetInputFlag(m_pImpl->m_pProps->bBool1);
+ pSEField->SetPromptText(m_pImpl->m_pProps->sPar3);
+ if (!m_pImpl->m_pProps->sPar4.isEmpty())
+ pSEField->ChgExpStr(m_pImpl->m_pProps->sPar4, nullptr);
+
+ }
+ break;
+ case SwServiceType::FieldTypeGetExp:
+ {
+ sal_uInt16 nSubType;
+ switch (m_pImpl->m_pProps->nSubType)
+ {
+ case text::SetVariableType::STRING: nSubType = nsSwGetSetExpType::GSE_STRING; break;
+ case text::SetVariableType::VAR: nSubType = nsSwGetSetExpType::GSE_EXPR; break;
+ //case text::SetVariableType::SEQUENCE: nSubType = nsSwGetSetExpType::GSE_SEQ; break;
+ case text::SetVariableType::FORMULA: nSubType = nsSwGetSetExpType::GSE_FORMULA; break;
+ default:
+ OSL_FAIL("wrong value");
+ nSubType = nsSwGetSetExpType::GSE_EXPR;
+ }
+ //make sure the SubType matches the field type
+ SwFieldType* pSetExpField = pDoc->getIDocumentFieldsAccess().GetFieldType(
+ SwFieldIds::SetExp, m_pImpl->m_pProps->sPar1, false);
+ bool bSetGetExpFieldUninitialized = false;
+ if (pSetExpField)
+ {
+ if (nSubType != nsSwGetSetExpType::GSE_STRING &&
+ static_cast< SwSetExpFieldType* >(pSetExpField)->GetType() == nsSwGetSetExpType::GSE_STRING)
+ nSubType = nsSwGetSetExpType::GSE_STRING;
+ }
+ else
+ bSetGetExpFieldUninitialized = true; // #i82544#
+
+ if (m_pImpl->m_pProps->bBool2)
+ nSubType |= nsSwExtendedSubType::SUB_CMD;
+ else
+ nSubType &= ~nsSwExtendedSubType::SUB_CMD;
+ SwGetExpField *const pGEField = new SwGetExpField(
+ static_cast<SwGetExpFieldType*>(
+ pDoc->getIDocumentFieldsAccess().GetSysFieldType(SwFieldIds::GetExp)),
+ m_pImpl->m_pProps->sPar1, nSubType,
+ m_pImpl->m_pProps->nFormat);
+ xField.reset(pGEField);
+ //TODO: evaluate SubType!
+ if (!m_pImpl->m_pProps->sPar4.isEmpty())
+ pGEField->ChgExpStr(m_pImpl->m_pProps->sPar4, nullptr);
+ // #i82544#
+ if (bSetGetExpFieldUninitialized)
+ pGEField->SetLateInitialization();
+ }
+ break;
+ case SwServiceType::FieldTypeInputUser:
+ case SwServiceType::FieldTypeInput:
+ {
+ SwFieldType* pFieldType =
+ pDoc->getIDocumentFieldsAccess().GetFieldType(SwFieldIds::Input, m_pImpl->m_sTypeName, true);
+ if (!pFieldType)
+ throw uno::RuntimeException();
+ sal_uInt16 nInpSubType =
+ sal::static_int_cast<sal_uInt16>(
+ SwServiceType::FieldTypeInputUser == m_pImpl->m_nServiceId
+ ? INP_USR : INP_TXT);
+ SwInputField * pTextField =
+ new SwInputField(static_cast<SwInputFieldType*>(pFieldType),
+ m_pImpl->m_pProps->sPar1,
+ m_pImpl->m_pProps->sPar2,
+ nInpSubType);
+ pTextField->SetHelp(m_pImpl->m_pProps->sPar3);
+ pTextField->SetToolTip(m_pImpl->m_pProps->sPar4);
+
+ xField.reset(pTextField);
+ }
+ break;
+ case SwServiceType::FieldTypeMacro:
+ {
+ SwFieldType* pFieldType = pDoc->getIDocumentFieldsAccess().GetSysFieldType(SwFieldIds::Macro);
+ OUString aName;
+
+ // support for Scripting Framework macros
+ if (!m_pImpl->m_pProps->sPar4.isEmpty())
+ {
+ aName = m_pImpl->m_pProps->sPar4;
+ }
+ else
+ {
+ SwMacroField::CreateMacroString(aName,
+ m_pImpl->m_pProps->sPar1, m_pImpl->m_pProps->sPar3);
+ }
+ xField.reset(new SwMacroField(static_cast<SwMacroFieldType*>(pFieldType), aName,
+ m_pImpl->m_pProps->sPar2));
+ }
+ break;
+ case SwServiceType::FieldTypePageCount:
+ case SwServiceType::FieldTypeParagraphCount:
+ case SwServiceType::FieldTypeWordCount:
+ case SwServiceType::FieldTypeCharacterCount:
+ case SwServiceType::FieldTypeTableCount:
+ case SwServiceType::FieldTypeGraphicObjectCount:
+ case SwServiceType::FieldTypeEmbeddedObjectCount:
+ {
+ sal_uInt16 nSubType = DS_PAGE;
+ switch (m_pImpl->m_nServiceId)
+ {
+ case SwServiceType::FieldTypeParagraphCount : nSubType = DS_PARA; break;
+ case SwServiceType::FieldTypeWordCount : nSubType = DS_WORD; break;
+ case SwServiceType::FieldTypeCharacterCount : nSubType = DS_CHAR; break;
+ case SwServiceType::FieldTypeTableCount : nSubType = DS_TBL; break;
+ case SwServiceType::FieldTypeGraphicObjectCount : nSubType = DS_GRF; break;
+ case SwServiceType::FieldTypeEmbeddedObjectCount : nSubType = DS_OLE; break;
+ default: break;
+ }
+ SwFieldType* pFieldType = pDoc->getIDocumentFieldsAccess().GetSysFieldType(SwFieldIds::DocStat);
+ xField.reset(new SwDocStatField(
+ static_cast<SwDocStatFieldType*>(pFieldType),
+ nSubType, m_pImpl->m_pProps->nUSHORT2));
+ }
+ break;
+ case SwServiceType::FieldTypeBibliography:
+ {
+ SwAuthorityFieldType const type(pDoc);
+ xField.reset(new SwAuthorityField(static_cast<SwAuthorityFieldType*>(
+ pDoc->getIDocumentFieldsAccess().InsertFieldType(type)),
+ u""));
+ if (m_pImpl->m_pProps->aPropSeq.hasElements())
+ {
+ uno::Any aVal;
+ aVal <<= m_pImpl->m_pProps->aPropSeq;
+ xField->PutValue( aVal, FIELD_PROP_PROP_SEQ );
+ }
+ }
+ break;
+ case SwServiceType::FieldTypeCombinedCharacters:
+ // create field
+ xField.reset(new SwCombinedCharField( static_cast<SwCombinedCharFieldType*>(
+ pDoc->getIDocumentFieldsAccess().GetSysFieldType(SwFieldIds::CombinedChars)),
+ m_pImpl->m_pProps->sPar1));
+ break;
+ case SwServiceType::FieldTypeDropdown:
+ {
+ SwDropDownField *const pDDField = new SwDropDownField(
+ static_cast<SwDropDownFieldType *>(
+ pDoc->getIDocumentFieldsAccess().GetSysFieldType(SwFieldIds::Dropdown)));
+ xField.reset(pDDField);
+
+ pDDField->SetItems(m_pImpl->m_pProps->aStrings);
+ pDDField->SetSelectedItem(m_pImpl->m_pProps->sPar1);
+ pDDField->SetName(m_pImpl->m_pProps->sPar2);
+ pDDField->SetHelp(m_pImpl->m_pProps->sPar3);
+ pDDField->SetToolTip(m_pImpl->m_pProps->sPar4);
+ }
+ break;
+
+ case SwServiceType::FieldTypeTableFormula:
+ {
+ // create field
+ sal_uInt16 nType = nsSwGetSetExpType::GSE_FORMULA;
+ if (m_pImpl->m_pProps->bBool1)
+ {
+ nType |= nsSwExtendedSubType::SUB_CMD;
+ if (m_pImpl->m_pProps->bFormatIsDefault)
+ m_pImpl->m_pProps->nFormat = -1;
+ }
+ xField.reset(new SwTableField( static_cast<SwTableFieldType*>(
+ pDoc->getIDocumentFieldsAccess().GetSysFieldType(SwFieldIds::Table)),
+ m_pImpl->m_pProps->sPar2,
+ nType,
+ m_pImpl->m_pProps->nFormat));
+ static_cast<SwTableField*>(xField.get())->ChgExpStr(m_pImpl->m_pProps->sPar1);
+ }
+ break;
+ default: OSL_FAIL("What kind of type is that?");
+ }
+
+ if (!xField)
+ throw uno::RuntimeException("no SwField created?");
+
+ xField->SetAutomaticLanguage(!m_pImpl->m_pProps->bBool4);
+ SwFormatField aFormat(*xField);
+
+ UnoActionContext aCont(pDoc);
+ if (aPam.HasMark() &&
+ m_pImpl->m_nServiceId != SwServiceType::FieldTypeAnnotation)
+ {
+ pDoc->getIDocumentContentOperations().DeleteAndJoin(aPam);
+ }
+
+ SwXTextCursor const*const pTextCursor(dynamic_cast<SwXTextCursor*>(pCursor));
+ const bool bForceExpandHints(
+ pTextCursor
+ && pTextCursor->IsAtEndOfMeta() );
+ const SetAttrMode nInsertFlags =
+ bForceExpandHints
+ ? SetAttrMode::FORCEHINTEXPAND
+ : SetAttrMode::DEFAULT;
+
+ if (*aPam.GetPoint() != *aPam.GetMark() &&
+ m_pImpl->m_nServiceId == SwServiceType::FieldTypeAnnotation)
+ {
+ // Make sure we always insert the field at the end
+ SwPaM aEnd(*aPam.End(), *aPam.End());
+ pDoc->getIDocumentContentOperations().InsertPoolItem(aEnd, aFormat, nInsertFlags);
+ }
+ else
+ pDoc->getIDocumentContentOperations().InsertPoolItem(aPam, aFormat, nInsertFlags);
+
+ SwTextAttr* pTextAttr = aPam.GetPointNode().GetTextNode()->GetFieldTextAttrAt(aPam.GetPoint()->GetContentIndex()-1, ::sw::GetTextAttrMode::Default);
+
+ // What about updating the fields? (see fldmgr.cxx)
+ if (!pTextAttr)
+ throw uno::RuntimeException("no SwTextAttr inserted?"); // could theoretically happen, if paragraph is full
+
+ m_pImpl->ClearFieldType();
+ const SwFormatField& rField = pTextAttr->GetFormatField();
+ m_pImpl->SetFormatField(const_cast<SwFormatField*>(&rField), pDoc);
+
+ if ( pTextAttr->Which() == RES_TXTATR_ANNOTATION
+ && *aPam.GetPoint() != *aPam.GetMark() )
+ {
+ // create annotation mark
+ const SwPostItField* pPostItField = dynamic_cast< const SwPostItField* >(pTextAttr->GetFormatField().GetField());
+ OSL_ENSURE( pPostItField != nullptr, "<SwXTextField::attachToRange(..)> - annotation field missing!" );
+ if ( pPostItField != nullptr )
+ {
+ IDocumentMarkAccess* pMarksAccess = pDoc->getIDocumentMarkAccess();
+ pMarksAccess->makeAnnotationMark( aPam, pPostItField->GetName() );
+ }
+ }
+
+ xField.reset();
+
+ assert(m_pImpl->GetFormatField());
+ m_pImpl->m_pDoc = pDoc;
+ m_pImpl->GetFormatField()->SetXTextField(this);
+ m_pImpl->m_wThis = this;
+ m_pImpl->m_bIsDescriptor = false;
+ m_pImpl->m_pProps.reset();
+ if (m_pImpl->m_bCallUpdate)
+ update();
+ }
+ else if ( !m_pImpl->IsDescriptor()
+ && m_pImpl->m_pDoc != nullptr
+ && m_pImpl->m_nServiceId == SwServiceType::FieldTypeAnnotation )
+ {
+ SwDoc* pDoc = m_pImpl->m_pDoc;
+ SwUnoInternalPaM aIntPam( *pDoc );
+ if ( !::sw::XTextRangeToSwPaM( aIntPam, xTextRange ) )
+ throw lang::IllegalArgumentException();
+
+ // Nothing to do, if the text range has a separate start and end, but they have the same
+ // value.
+ if (!aIntPam.HasMark() || *aIntPam.Start() != *aIntPam.End())
+ {
+ UnoActionContext aCont( pDoc );
+ // insert copy of annotation at new text range
+ std::unique_ptr<SwPostItField> pPostItField(static_cast< SwPostItField* >(m_pImpl->GetFormatField()->GetField()->CopyField().release()));
+ SwFormatField aFormatField( *pPostItField );
+ pPostItField.reset();
+ SwPaM aEnd( *aIntPam.End(), *aIntPam.End() );
+ pDoc->getIDocumentContentOperations().InsertPoolItem( aEnd, aFormatField );
+ // delete former annotation
+ {
+ const SwTextField* pTextField = m_pImpl->GetFormatField()->GetTextField();
+ SwTextNode& rTextNode = *pTextField->GetpTextNode();
+ SwPaM aPam( rTextNode, pTextField->GetStart() );
+ aPam.SetMark();
+ aPam.Move();
+ pDoc->getIDocumentContentOperations().DeleteAndJoin(aPam);
+ }
+ // keep inserted annotation
+ {
+ SwTextField *const pTextAttr = aEnd.GetPointNode().GetTextNode()->GetFieldTextAttrAt(aEnd.End()->GetContentIndex()-1, ::sw::GetTextAttrMode::Default);
+ if ( pTextAttr != nullptr )
+ {
+ m_pImpl->SetFormatField(const_cast<SwFormatField*>(&pTextAttr->GetFormatField()), pDoc);
+
+ if ( *aIntPam.GetPoint() != *aIntPam.GetMark() )
+ {
+ // create annotation mark
+ const SwPostItField* pField = dynamic_cast< const SwPostItField* >(pTextAttr->GetFormatField().GetField());
+ OSL_ENSURE( pField != nullptr, "<SwXTextField::attach(..)> - annotation field missing!" );
+ if ( pField != nullptr )
+ {
+ IDocumentMarkAccess* pMarksAccess = aIntPam.GetDoc().getIDocumentMarkAccess();
+ pMarksAccess->makeAnnotationMark( aIntPam, pField->GetName() );
+ }
+ }
+ }
+ }
+ }
+
+ }
+ else
+ throw lang::IllegalArgumentException();
+}
+
+uno::Reference< text::XTextRange > SAL_CALL
+SwXTextField::getAnchor()
+{
+ SolarMutexGuard aGuard;
+
+ SwField const*const pField = m_pImpl->GetField();
+ if (!pField)
+ return nullptr;
+
+ const SwTextField* pTextField = m_pImpl->GetFormatField()->GetTextField();
+ if (!pTextField)
+ throw uno::RuntimeException();
+
+ std::shared_ptr< SwPaM > pPamForTextField;
+ SwTextField::GetPamForTextField(*pTextField, pPamForTextField);
+ if (pPamForTextField == nullptr)
+ return nullptr;
+
+ // If this is a postit field, then return the range of its annotation mark if it has one.
+ if (pField->Which() == SwFieldIds::Postit)
+ {
+ const SwPostItField* pPostItField = static_cast<const SwPostItField*>(pField);
+ IDocumentMarkAccess* pMarkAccess = m_pImpl->m_pDoc->getIDocumentMarkAccess();
+ for (IDocumentMarkAccess::const_iterator_t ppMark = pMarkAccess->getAnnotationMarksBegin(); ppMark != pMarkAccess->getAnnotationMarksEnd(); ++ppMark)
+ {
+ if ((*ppMark)->GetName() == pPostItField->GetName())
+ {
+ pPamForTextField = std::make_shared<SwPaM>((*ppMark)->GetMarkStart(), (*ppMark)->GetMarkEnd());
+ break;
+ }
+ }
+ }
+
+ rtl::Reference<SwXTextRange> xRange = SwXTextRange::CreateXTextRange(
+ *m_pImpl->m_pDoc, *(pPamForTextField->GetPoint()), pPamForTextField->GetMark());
+ return xRange;
+}
+
+void SAL_CALL SwXTextField::dispose()
+{
+ SolarMutexGuard aGuard;
+ SwField const*const pField = m_pImpl->GetField();
+ if(pField && m_pImpl->m_pDoc)
+ {
+ UnoActionContext aContext(m_pImpl->m_pDoc);
+ assert(m_pImpl->GetFormatField()->GetTextField() && "<SwXTextField::dispose()> - missing <SwTextField> --> crash");
+ SwTextField::DeleteTextField(*(m_pImpl->GetFormatField()->GetTextField()));
+ }
+
+ if (m_pImpl->m_xTextObject.is())
+ {
+ m_pImpl->m_xTextObject->DisposeEditSource();
+ m_pImpl->m_xTextObject.clear();
+ }
+ m_pImpl->Invalidate();
+}
+
+void SAL_CALL SwXTextField::addEventListener(
+ const uno::Reference<lang::XEventListener> & xListener)
+{
+ std::unique_lock aGuard(m_pImpl->m_Mutex);
+ m_pImpl->m_EventListeners.addInterface(aGuard, xListener);
+}
+
+void SAL_CALL SwXTextField::removeEventListener(
+ const uno::Reference<lang::XEventListener> & xListener)
+{
+ std::unique_lock aGuard(m_pImpl->m_Mutex);
+ m_pImpl->m_EventListeners.removeInterface(aGuard, xListener);
+}
+
+uno::Reference< beans::XPropertySetInfo > SAL_CALL
+SwXTextField::getPropertySetInfo()
+{
+ SolarMutexGuard aGuard;
+ // no static
+ uno::Reference< beans::XPropertySetInfo > aRef;
+ if (m_pImpl->m_nServiceId == SwServiceType::Invalid)
+ {
+ throw uno::RuntimeException();
+ }
+ const SfxItemPropertySet* pPropSet = aSwMapProvider.GetPropertySet(
+ lcl_GetPropertyMapOfService(m_pImpl->m_nServiceId));
+ const uno::Reference<beans::XPropertySetInfo>& xInfo = pPropSet->getPropertySetInfo();
+ // extend PropertySetInfo!
+ const uno::Sequence<beans::Property> aPropSeq = xInfo->getProperties();
+ aRef = new SfxExtItemPropertySetInfo(
+ aSwMapProvider.GetPropertyMapEntries(PROPERTY_MAP_PARAGRAPH_EXTENSIONS),
+ aPropSeq );
+ return aRef;
+}
+
+void SAL_CALL
+SwXTextField::setPropertyValue(
+ const OUString& rPropertyName, const uno::Any& rValue)
+{
+ SolarMutexGuard aGuard;
+ SwField const*const pField = m_pImpl->GetField();
+ const SfxItemPropertySet* _pPropSet = aSwMapProvider.GetPropertySet(
+ lcl_GetPropertyMapOfService(m_pImpl->m_nServiceId));
+ const SfxItemPropertyMapEntry* pEntry = _pPropSet->getPropertyMap().getByName(rPropertyName);
+
+ if (!pEntry)
+ throw beans::UnknownPropertyException( "Unknown property: " + rPropertyName, getXWeak() );
+ if ( pEntry->nFlags & beans::PropertyAttribute::READONLY)
+ throw beans::PropertyVetoException( "Property is read-only: " + rPropertyName, getXWeak() );
+
+ if(pField)
+ {
+ // special treatment for mail merge fields
+ const SwFieldIds nWhich = pField->Which();
+ if( SwFieldIds::Database == nWhich &&
+ (rPropertyName == UNO_NAME_DATA_BASE_NAME ||
+ rPropertyName == UNO_NAME_DATA_BASE_URL||
+ rPropertyName == UNO_NAME_DATA_TABLE_NAME||
+ rPropertyName == UNO_NAME_DATA_COLUMN_NAME))
+ {
+ // here a new field type must be created and the field must
+ // be registered at the new type
+ OSL_FAIL("not implemented");
+ }
+ else
+ {
+ SwDoc * pDoc = m_pImpl->m_pDoc;
+ assert(pDoc);
+ const SwTextField* pTextField = m_pImpl->GetFormatField()->GetTextField();
+ if(!pTextField)
+ throw uno::RuntimeException();
+ SwPosition aPosition( pTextField->GetTextNode(), pTextField->GetStart() );
+ pDoc->getIDocumentFieldsAccess().PutValueToField( aPosition, rValue, pEntry->nWID);
+ }
+
+ //#i100374# notify SwPostIt about new field content
+ assert(m_pImpl->GetFormatField());
+ if (SwFieldIds::Postit == nWhich)
+ {
+ m_pImpl->GetFormatField()->Broadcast(
+ SwFormatFieldHint( nullptr, SwFormatFieldHintWhich::CHANGED ));
+ }
+
+ // fdo#42073 notify SwTextField about changes of the expanded string
+ if (m_pImpl->GetFormatField()->GetTextField())
+ {
+ m_pImpl->GetFormatField()->GetTextField()->ExpandTextField();
+ }
+
+ //#i100374# changing a document field should set the modify flag
+ SwDoc* pDoc = m_pImpl->m_pDoc;
+ if (pDoc)
+ pDoc->getIDocumentState().SetModified();
+
+ }
+ else if (m_pImpl->m_pProps)
+ {
+ bool* pBool = nullptr;
+ switch(pEntry->nWID)
+ {
+ case FIELD_PROP_PAR1:
+ rValue >>= m_pImpl->m_pProps->sPar1;
+ break;
+ case FIELD_PROP_PAR2:
+ rValue >>= m_pImpl->m_pProps->sPar2;
+ break;
+ case FIELD_PROP_PAR3:
+ rValue >>= m_pImpl->m_pProps->sPar3;
+ break;
+ case FIELD_PROP_PAR4:
+ rValue >>= m_pImpl->m_pProps->sPar4;
+ break;
+ case FIELD_PROP_PAR7:
+ rValue >>= m_pImpl->m_pProps->sPar7;
+ break;
+ case FIELD_PROP_PAR5:
+ rValue >>= m_pImpl->m_pProps->sPar5;
+ break;
+ case FIELD_PROP_PAR6:
+ rValue >>= m_pImpl->m_pProps->sPar6;
+ break;
+ case FIELD_PROP_FORMAT:
+ rValue >>= m_pImpl->m_pProps->nFormat;
+ m_pImpl->m_pProps->bFormatIsDefault = false;
+ break;
+ case FIELD_PROP_SUBTYPE:
+ m_pImpl->m_pProps->nSubType = SWUnoHelper::GetEnumAsInt32(rValue);
+ break;
+ case FIELD_PROP_BYTE1 :
+ rValue >>= m_pImpl->m_pProps->nByte1;
+ break;
+ case FIELD_PROP_BOOL1 :
+ pBool = &m_pImpl->m_pProps->bBool1;
+ break;
+ case FIELD_PROP_BOOL2 :
+ pBool = &m_pImpl->m_pProps->bBool2;
+ break;
+ case FIELD_PROP_BOOL3 :
+ pBool = &m_pImpl->m_pProps->bBool3;
+ break;
+ case FIELD_PROP_BOOL4:
+ pBool = &m_pImpl->m_pProps->bBool4;
+ break;
+ case FIELD_PROP_DATE :
+ {
+ auto aTemp = o3tl::tryAccess<util::Date>(rValue);
+ if(!aTemp)
+ throw lang::IllegalArgumentException();
+
+ m_pImpl->m_pProps->aDate = Date(aTemp->Day, aTemp->Month, aTemp->Year);
+ }
+ break;
+ case FIELD_PROP_USHORT1:
+ case FIELD_PROP_USHORT2:
+ case FIELD_PROP_USHORT3:
+ {
+ sal_Int16 nVal = 0;
+ rValue >>= nVal;
+ if( FIELD_PROP_USHORT1 == pEntry->nWID)
+ m_pImpl->m_pProps->nUSHORT1 = nVal;
+ else if( FIELD_PROP_USHORT2 == pEntry->nWID)
+ m_pImpl->m_pProps->nUSHORT2 = nVal;
+ else
+ m_pImpl->m_pProps->nUSHORT3 = nVal;
+ }
+ break;
+ case FIELD_PROP_SHORT1:
+ rValue >>= m_pImpl->m_pProps->nSHORT1;
+ break;
+ case FIELD_PROP_DOUBLE:
+ if(rValue.getValueType() != ::cppu::UnoType<double>::get())
+ throw lang::IllegalArgumentException();
+ rValue >>= m_pImpl->m_pProps->fDouble;
+ break;
+
+ case FIELD_PROP_DATE_TIME :
+ if (!m_pImpl->m_pProps->pDateTime)
+ m_pImpl->m_pProps->pDateTime.reset( new util::DateTime );
+ rValue >>= *m_pImpl->m_pProps->pDateTime;
+ break;
+ case FIELD_PROP_PROP_SEQ:
+ rValue >>= m_pImpl->m_pProps->aPropSeq;
+ break;
+ case FIELD_PROP_STRINGS:
+ rValue >>= m_pImpl->m_pProps->aStrings;
+ break;
+ }
+ if (pBool)
+ {
+ std::optional<const bool> b = o3tl::tryAccess<bool>(rValue);
+ if( !b.has_value() )
+ throw lang::IllegalArgumentException();
+ *pBool = *b;
+
+ }
+ }
+ else
+ throw uno::RuntimeException();
+}
+
+uno::Any SAL_CALL SwXTextField::getPropertyValue(const OUString& rPropertyName)
+{
+ SolarMutexGuard aGuard;
+ uno::Any aRet;
+ SwField const*const pField = m_pImpl->GetField();
+ const SfxItemPropertySet* _pPropSet = aSwMapProvider.GetPropertySet(
+ lcl_GetPropertyMapOfService(m_pImpl->m_nServiceId));
+ const SfxItemPropertyMapEntry* pEntry = _pPropSet->getPropertyMap().getByName(rPropertyName);
+ if(!pEntry )
+ {
+ const SfxItemPropertySet* _pParaPropSet = aSwMapProvider.GetPropertySet(PROPERTY_MAP_PARAGRAPH_EXTENSIONS);
+ pEntry = _pParaPropSet->getPropertyMap().getByName(rPropertyName);
+ }
+ if (!pEntry)
+ throw beans::UnknownPropertyException( "Unknown property: " + rPropertyName, getXWeak() );
+
+ switch( pEntry->nWID )
+ {
+ case FN_UNO_TEXT_WRAP:
+ aRet <<= text::WrapTextMode_NONE;
+ break;
+ case FN_UNO_ANCHOR_TYPE:
+ aRet <<= text::TextContentAnchorType_AS_CHARACTER;
+ break;
+ case FN_UNO_ANCHOR_TYPES:
+ {
+ uno::Sequence<text::TextContentAnchorType> aTypes { text::TextContentAnchorType_AS_CHARACTER };
+ aRet <<= aTypes;
+ }
+ break;
+
+ default:
+ if( pField )
+ {
+ if (FIELD_PROP_IS_FIELD_USED == pEntry->nWID ||
+ FIELD_PROP_IS_FIELD_DISPLAYED == pEntry->nWID)
+ {
+ bool bIsFieldUsed = false;
+ bool bIsFieldDisplayed = false;
+
+ // in order to have the information about fields
+ // correctly evaluated the document needs a layout
+ // (has to be already formatted)
+ SwDoc *pDoc = m_pImpl->m_pDoc;
+ SwViewShell *pViewShell = nullptr;
+ SwEditShell *pEditShell = nullptr;
+ if( pDoc )
+ {
+ pViewShell = pDoc->getIDocumentLayoutAccess().GetCurrentViewShell();
+ pEditShell = pDoc->GetEditShell();
+ }
+
+ if (pEditShell)
+ pEditShell->CalcLayout();
+ else if (pViewShell) // a page preview has no SwEditShell it should only have a view shell
+ pViewShell->CalcLayout();
+ else
+ throw uno::RuntimeException();
+
+ // get text node for the text field
+ const SwFormatField *pFieldFormat =
+ (m_pImpl->GetField()) ? m_pImpl->GetFormatField() : nullptr;
+ const SwTextField* pTextField = pFieldFormat
+ ? m_pImpl->GetFormatField()->GetTextField() : nullptr;
+ if(!pTextField)
+ throw uno::RuntimeException();
+ const SwTextNode& rTextNode = pTextField->GetTextNode();
+
+ // skip fields that are currently not in the document
+ // e.g. fields in undo or redo array
+ if (rTextNode.GetNodes().IsDocNodes())
+ {
+ bool bFrame = 0 != rTextNode.FindLayoutRect().Width(); // or so
+ bool bHidden = rTextNode.IsHidden();
+ if ( !bHidden )
+ {
+ sal_Int32 nHiddenStart;
+ sal_Int32 nHiddenEnd;
+ bHidden = SwScriptInfo::GetBoundsOfHiddenRange( pTextField->GetTextNode(),
+ pTextField->GetStart(),
+ nHiddenStart, nHiddenEnd );
+ }
+
+ // !bFrame && !bHidden: most probably a field in an unused page style
+
+ // FME: Problem: hidden field in unused page template =>
+ // bIsFieldUsed = true
+ // bIsFieldDisplayed = false
+ bIsFieldUsed = bFrame || bHidden;
+ bIsFieldDisplayed = bIsFieldUsed && !bHidden;
+ }
+ aRet <<= (FIELD_PROP_IS_FIELD_USED == pEntry->nWID) ? bIsFieldUsed : bIsFieldDisplayed;
+ }
+ else
+ pField->QueryValue( aRet, pEntry->nWID );
+ }
+ else if (m_pImpl->m_pProps) // currently just a descriptor...
+ {
+ switch(pEntry->nWID)
+ {
+ case FIELD_PROP_TEXT:
+ {
+ if (!m_pImpl->m_xTextObject.is())
+ {
+ m_pImpl->m_xTextObject
+ = new SwTextAPIObject( std::make_unique<SwTextAPIEditSource>(m_pImpl->m_pDoc) );
+ }
+
+ uno::Reference<text::XText> xText(m_pImpl->m_xTextObject);
+ aRet <<= xText;
+ break;
+ }
+ case FIELD_PROP_PAR1:
+ aRet <<= m_pImpl->m_pProps->sPar1;
+ break;
+ case FIELD_PROP_PAR2:
+ aRet <<= m_pImpl->m_pProps->sPar2;
+ break;
+ case FIELD_PROP_PAR3:
+ aRet <<= m_pImpl->m_pProps->sPar3;
+ break;
+ case FIELD_PROP_PAR4:
+ aRet <<= m_pImpl->m_pProps->sPar4;
+ break;
+ case FIELD_PROP_PAR7:
+ aRet <<= m_pImpl->m_pProps->sPar7;
+ break;
+ case FIELD_PROP_PAR5:
+ aRet <<= m_pImpl->m_pProps->sPar5;
+ break;
+ case FIELD_PROP_PAR6:
+ aRet <<= m_pImpl->m_pProps->sPar6;
+ break;
+ case FIELD_PROP_FORMAT:
+ aRet <<= m_pImpl->m_pProps->nFormat;
+ break;
+ case FIELD_PROP_SUBTYPE:
+ aRet <<= m_pImpl->m_pProps->nSubType;
+ break;
+ case FIELD_PROP_BYTE1 :
+ aRet <<= m_pImpl->m_pProps->nByte1;
+ break;
+ case FIELD_PROP_BOOL1 :
+ aRet <<= m_pImpl->m_pProps->bBool1;
+ break;
+ case FIELD_PROP_BOOL2 :
+ aRet <<= m_pImpl->m_pProps->bBool2;
+ break;
+ case FIELD_PROP_BOOL3 :
+ aRet <<= m_pImpl->m_pProps->bBool3;
+ break;
+ case FIELD_PROP_BOOL4 :
+ aRet <<= m_pImpl->m_pProps->bBool4;
+ break;
+ case FIELD_PROP_DATE :
+ aRet <<= m_pImpl->m_pProps->aDate.GetUNODate();
+ break;
+ case FIELD_PROP_USHORT1:
+ aRet <<= static_cast<sal_Int16>(m_pImpl->m_pProps->nUSHORT1);
+ break;
+ case FIELD_PROP_USHORT2:
+ aRet <<= static_cast<sal_Int16>(m_pImpl->m_pProps->nUSHORT2);
+ break;
+ case FIELD_PROP_USHORT3:
+ aRet <<= static_cast<sal_Int16>(m_pImpl->m_pProps->nUSHORT3);
+ break;
+ case FIELD_PROP_SHORT1:
+ aRet <<= m_pImpl->m_pProps->nSHORT1;
+ break;
+ case FIELD_PROP_DOUBLE:
+ aRet <<= m_pImpl->m_pProps->fDouble;
+ break;
+ case FIELD_PROP_DATE_TIME :
+ if (m_pImpl->m_pProps->pDateTime)
+ aRet <<= *m_pImpl->m_pProps->pDateTime;
+ break;
+ case FIELD_PROP_PROP_SEQ:
+ aRet <<= m_pImpl->m_pProps->aPropSeq;
+ break;
+ case FIELD_PROP_STRINGS:
+ aRet <<= m_pImpl->m_pProps->aStrings;
+ break;
+ case FIELD_PROP_IS_FIELD_USED:
+ case FIELD_PROP_IS_FIELD_DISPLAYED:
+ aRet <<= false;
+ break;
+ }
+ }
+ else
+ throw uno::RuntimeException();
+ }
+ return aRet;
+}
+
+void SwXTextField::addPropertyChangeListener(const OUString& /*PropertyName*/, const uno::Reference< beans::XPropertyChangeListener > & /*aListener*/)
+{
+ OSL_FAIL("not implemented");
+}
+
+void SwXTextField::removePropertyChangeListener(const OUString& /*PropertyName*/, const uno::Reference< beans::XPropertyChangeListener > & /*aListener*/)
+{
+ OSL_FAIL("not implemented");
+}
+
+void SwXTextField::addVetoableChangeListener(const OUString& /*PropertyName*/, const uno::Reference< beans::XVetoableChangeListener > & /*aListener*/)
+{
+ OSL_FAIL("not implemented");
+}
+
+void SwXTextField::removeVetoableChangeListener(const OUString& /*PropertyName*/, const uno::Reference< beans::XVetoableChangeListener > & /*aListener*/)
+{
+ OSL_FAIL("not implemented");
+}
+
+void SAL_CALL SwXTextField::update()
+{
+ SolarMutexGuard aGuard;
+ SwField * pField = const_cast<SwField*>(m_pImpl->GetField());
+ if (pField)
+ {
+ switch(pField->Which())
+ {
+ case SwFieldIds::DateTime:
+ static_cast<SwDateTimeField*>(pField)->SetDateTime( ::DateTime( ::DateTime::SYSTEM ) );
+ break;
+
+ case SwFieldIds::ExtUser:
+ {
+ SwExtUserField* pExtUserField = static_cast<SwExtUserField*>(pField);
+ pExtUserField->SetExpansion( SwExtUserFieldType::Expand(
+ pExtUserField->GetSubType() ) );
+ }
+ break;
+
+ case SwFieldIds::Author:
+ {
+ SwAuthorField* pAuthorField = static_cast<SwAuthorField*>(pField);
+ pAuthorField->SetExpansion( SwAuthorFieldType::Expand(
+ pAuthorField->GetFormat() ) );
+ }
+ break;
+
+ case SwFieldIds::Filename:
+ {
+ SwFileNameField* pFileNameField = static_cast<SwFileNameField*>(pField);
+ pFileNameField->SetExpansion( static_cast<SwFileNameFieldType*>(pField->GetTyp())->Expand(
+ pFileNameField->GetFormat() ) );
+ }
+ break;
+
+ case SwFieldIds::DocInfo:
+ {
+ SwDocInfoField* pDocInfField = static_cast<SwDocInfoField*>(pField);
+ pDocInfField->SetExpansion( static_cast<SwDocInfoFieldType*>(pField->GetTyp())->Expand(
+ pDocInfField->GetSubType(),
+ pDocInfField->GetFormat(),
+ pDocInfField->GetLanguage(),
+ pDocInfField->GetName() ) );
+ }
+ break;
+ default: break;
+ }
+ // Text formatting has to be triggered.
+ m_pImpl->GetFormatField()->ForceUpdateTextNode();
+ }
+ else
+ m_pImpl->m_bCallUpdate = true;
+}
+
+OUString SAL_CALL SwXTextField::getImplementationName()
+{
+ return "SwXTextField";
+}
+
+static OUString OldNameToNewName_Impl( const OUString &rOld )
+{
+ static const char aOldNamePart1[] = ".TextField.DocInfo.";
+ static const char aOldNamePart2[] = ".TextField.";
+ OUString sServiceNameCC( rOld );
+ sal_Int32 nIdx = sServiceNameCC.indexOf( aOldNamePart1 );
+ if (nIdx >= 0)
+ sServiceNameCC = sServiceNameCC.replaceAt( nIdx, strlen(aOldNamePart1), u".textfield.docinfo." );
+ nIdx = sServiceNameCC.indexOf( aOldNamePart2 );
+ if (nIdx >= 0)
+ sServiceNameCC = sServiceNameCC.replaceAt( nIdx, strlen(aOldNamePart2), u".textfield." );
+ return sServiceNameCC;
+}
+
+sal_Bool SAL_CALL SwXTextField::supportsService(const OUString& rServiceName)
+{
+ return cppu::supportsService(this, rServiceName);
+}
+
+uno::Sequence< OUString > SAL_CALL SwXTextField::getSupportedServiceNames()
+{
+ const OUString sServiceName =
+ SwXServiceProvider::GetProviderName(m_pImpl->m_nServiceId);
+
+ // case-corrected version of service-name (see #i67811)
+ // (need to supply both because of compatibility to older versions)
+ const OUString sServiceNameCC( OldNameToNewName_Impl( sServiceName ) );
+ sal_Int32 nLen = sServiceName == sServiceNameCC ? 2 : 3;
+
+ uno::Sequence< OUString > aRet( nLen );
+ OUString* pArray = aRet.getArray();
+ *pArray++ = sServiceName;
+ if (nLen == 3)
+ *pArray++ = sServiceNameCC;
+ *pArray++ = "com.sun.star.text.TextContent";
+ return aRet;
+}
+
+void SwXTextField::Impl::Invalidate()
+{
+ EndListeningAll();
+ m_pFormatField = nullptr;
+ m_pDoc = nullptr;
+ uno::Reference<uno::XInterface> const xThis(m_wThis);
+ if (!xThis.is())
+ { // fdo#72695: if UNO object is already dead, don't revive it with event
+ return;
+ }
+ lang::EventObject const ev(xThis);
+ std::unique_lock aGuard(m_Mutex);
+ m_EventListeners.disposeAndClear(aGuard, ev);
+}
+
+void SwXTextField::Impl::Notify(const SfxHint& rHint)
+{
+
+ if(rHint.GetId() == SfxHintId::Dying)
+ Invalidate();
+ else if (rHint.GetId() == SfxHintId::SwLegacyModify)
+ {
+ auto pLegacyHint = static_cast<const sw::LegacyModifyHint*>(&rHint);
+ switch(pLegacyHint->m_pOld ? pLegacyHint->m_pOld->Which() : 0)
+ {
+ case RES_REMOVE_UNO_OBJECT:
+ case RES_OBJECTDYING:
+ Invalidate();
+ break;
+ }
+ }
+}
+
+const SwField* SwXTextField::Impl::GetField() const
+{
+ return m_pFormatField ? m_pFormatField->GetField() : nullptr;
+}
+
+OUString SwXTextFieldMasters::getImplementationName()
+{
+ return "SwXTextFieldMasters";
+}
+
+sal_Bool SwXTextFieldMasters::supportsService(const OUString& rServiceName)
+{
+ return cppu::supportsService(this, rServiceName);
+}
+
+uno::Sequence< OUString > SwXTextFieldMasters::getSupportedServiceNames()
+{
+ uno::Sequence<OUString> aRet { "com.sun.star.text.TextFieldMasters" };
+ return aRet;
+}
+
+SwXTextFieldMasters::SwXTextFieldMasters(SwDoc* _pDoc) :
+ SwUnoCollection(_pDoc)
+{
+}
+
+SwXTextFieldMasters::~SwXTextFieldMasters()
+{
+
+}
+
+/*
+ Iteration over non-standard field types
+ USER/SETEXP/DDE/DATABASE
+ Thus the names are:
+ "com.sun.star.text.fieldmaster.User" + <field type name>
+ "com.sun.star.text.fieldmaster.DDE" + <field type name>
+ "com.sun.star.text.fieldmaster.SetExpression" + <field type name>
+ "com.sun.star.text.fieldmaster.DataBase" + <field type name>
+
+ If too much, maybe one could leave out the "com.sun.star.text".
+ */
+static SwFieldIds lcl_GetIdByName( OUString& rName, OUString& rTypeName )
+{
+ if (rName.startsWithIgnoreAsciiCase(COM_TEXT_FLDMASTER_CC))
+ rName = rName.copy(COM_TEXT_FLDMASTER_CC.getLength());
+
+ SwFieldIds nResId = SwFieldIds::Unknown;
+ sal_Int32 nIdx = 0;
+ rTypeName = rName.getToken( 0, '.', nIdx );
+ if (rTypeName == "User")
+ nResId = SwFieldIds::User;
+ else if (rTypeName == "DDE")
+ nResId = SwFieldIds::Dde;
+ else if (rTypeName == "SetExpression")
+ {
+ nResId = SwFieldIds::SetExp;
+
+ const OUString sFieldTypName( rName.getToken( 0, '.', nIdx ));
+ const OUString sUIName( SwStyleNameMapper::GetSpecialExtraUIName( sFieldTypName ) );
+
+ if( sUIName != sFieldTypName )
+ rName = comphelper::string::setToken(rName, 1, '.', sUIName);
+ }
+ else if (rTypeName.equalsIgnoreAsciiCase("DataBase"))
+ {
+ rName = rName.copy(RTL_CONSTASCII_LENGTH("DataBase."));
+ if (!rName.isEmpty())
+ {
+ // #i51815#
+ rName = "DataBase." + rName;
+ nResId = SwFieldIds::Database;
+ }
+ }
+ else if (rTypeName == "Bibliography")
+ nResId = SwFieldIds::TableOfAuthorities;
+ return nResId;
+}
+
+uno::Any SwXTextFieldMasters::getByName(const OUString& rName)
+{
+ SolarMutexGuard aGuard;
+
+ OUString sName(rName), sTypeName;
+ const SwFieldIds nResId = lcl_GetIdByName( sName, sTypeName );
+ if( SwFieldIds::Unknown == nResId )
+ throw container::NoSuchElementException(
+ "SwXTextFieldMasters::getByName(" + rName + ")",
+ css::uno::Reference<css::uno::XInterface>());
+
+ sName = sName.copy(std::min(sTypeName.getLength()+1, sName.getLength()));
+ auto& rDoc = GetDoc();
+ SwFieldType* pType = rDoc.getIDocumentFieldsAccess().GetFieldType(nResId, sName, true);
+ if(!pType)
+ throw container::NoSuchElementException(
+ "SwXTextFieldMasters::getByName(" + rName + ")",
+ css::uno::Reference<css::uno::XInterface>());
+
+ uno::Reference<beans::XPropertySet> const xRet(
+ SwXFieldMaster::CreateXFieldMaster(&rDoc, pType));
+ return uno::Any(xRet);
+}
+
+bool SwXTextFieldMasters::getInstanceName(
+ const SwFieldType& rFieldType, OUString& rName)
+{
+ OUString sField;
+
+ switch( rFieldType.Which() )
+ {
+ case SwFieldIds::User:
+ sField = "User." + rFieldType.GetName();
+ break;
+ case SwFieldIds::Dde:
+ sField = "DDE." + rFieldType.GetName();
+ break;
+
+ case SwFieldIds::SetExp:
+ sField = "SetExpression." + SwStyleNameMapper::GetSpecialExtraProgName( rFieldType.GetName() );
+ break;
+
+ case SwFieldIds::Database:
+ sField = "DataBase." + rFieldType.GetName().replaceAll(OUStringChar(DB_DELIM), ".");
+ break;
+
+ case SwFieldIds::TableOfAuthorities:
+ sField = "Bibliography";
+ break;
+
+ default:
+ return false;
+ }
+
+ rName += COM_TEXT_FLDMASTER_CC + sField;
+ return true;
+}
+
+uno::Sequence< OUString > SwXTextFieldMasters::getElementNames()
+{
+ SolarMutexGuard aGuard;
+
+ const SwFieldTypes* pFieldTypes = GetDoc().getIDocumentFieldsAccess().GetFieldTypes();
+ const size_t nCount = pFieldTypes->size();
+
+ std::vector<OUString> aFieldNames;
+ for( size_t i = 0; i < nCount; ++i )
+ {
+ SwFieldType& rFieldType = *((*pFieldTypes)[i]);
+
+ OUString sFieldName;
+ if (SwXTextFieldMasters::getInstanceName(rFieldType, sFieldName))
+ {
+ aFieldNames.push_back(sFieldName);
+ }
+ }
+
+ return comphelper::containerToSequence(aFieldNames);
+}
+
+sal_Bool SwXTextFieldMasters::hasByName(const OUString& rName)
+{
+ SolarMutexGuard aGuard;
+
+ OUString sName(rName), sTypeName;
+ const SwFieldIds nResId = lcl_GetIdByName( sName, sTypeName );
+ bool bRet = false;
+ if( SwFieldIds::Unknown != nResId )
+ {
+ sName = sName.copy(std::min(sTypeName.getLength()+1, sName.getLength()));
+ bRet = nullptr != GetDoc().getIDocumentFieldsAccess().GetFieldType(nResId, sName, true);
+ }
+ return bRet;
+}
+
+uno::Type SwXTextFieldMasters::getElementType()
+{
+ return cppu::UnoType<beans::XPropertySet>::get();
+
+}
+
+sal_Bool SwXTextFieldMasters::hasElements()
+{
+ SolarMutexGuard aGuard;
+ if(!IsValid())
+ throw uno::RuntimeException();
+ return true;
+}
+
+class SwXTextFieldTypes::Impl
+{
+public:
+ std::mutex m_Mutex; // just for OInterfaceContainerHelper3
+ ::comphelper::OInterfaceContainerHelper4<util::XRefreshListener> m_RefreshListeners;
+};
+
+OUString SwXTextFieldTypes::getImplementationName()
+{
+ return "SwXTextFieldTypes";
+}
+
+sal_Bool SwXTextFieldTypes::supportsService(const OUString& rServiceName)
+{
+ return cppu::supportsService(this, rServiceName);
+}
+
+uno::Sequence< OUString > SwXTextFieldTypes::getSupportedServiceNames()
+{
+ uno::Sequence<OUString> aRet { "com.sun.star.text.TextFields" };
+ return aRet;
+}
+
+SwXTextFieldTypes::SwXTextFieldTypes(SwDoc* _pDoc)
+ : SwUnoCollection (_pDoc)
+ , m_pImpl(new Impl)
+{
+}
+
+SwXTextFieldTypes::~SwXTextFieldTypes()
+{
+}
+
+void SwXTextFieldTypes::Invalidate()
+{
+ SwUnoCollection::Invalidate();
+ lang::EventObject const ev(getXWeak());
+ std::unique_lock aGuard(m_pImpl->m_Mutex);
+ m_pImpl->m_RefreshListeners.disposeAndClear(aGuard, ev);
+}
+
+uno::Reference< container::XEnumeration > SwXTextFieldTypes::createEnumeration()
+{
+ SolarMutexGuard aGuard;
+ return new SwXFieldEnumeration(GetDoc());
+}
+
+uno::Type SwXTextFieldTypes::getElementType()
+{
+ return cppu::UnoType<text::XDependentTextField>::get();
+}
+
+sal_Bool SwXTextFieldTypes::hasElements()
+{
+ SolarMutexGuard aGuard;
+ if(!IsValid())
+ throw uno::RuntimeException();
+ return true; // they always exist
+}
+
+void SAL_CALL SwXTextFieldTypes::refresh()
+{
+ {
+ SolarMutexGuard aGuard;
+ auto& rDoc = GetDoc();
+ UnoActionContext aContext(&rDoc);
+ rDoc.getIDocumentStatistics().UpdateDocStat(false, true);
+ rDoc.getIDocumentFieldsAccess().UpdateFields(false);
+ }
+ // call refresh listeners (without SolarMutex locked)
+ lang::EventObject const event(getXWeak());
+ std::unique_lock aGuard(m_pImpl->m_Mutex);
+ m_pImpl->m_RefreshListeners.notifyEach(aGuard,
+ & util::XRefreshListener::refreshed, event);
+}
+
+void SAL_CALL SwXTextFieldTypes::addRefreshListener(
+ const uno::Reference<util::XRefreshListener> & xListener)
+{
+ std::unique_lock aGuard(m_pImpl->m_Mutex);
+ m_pImpl->m_RefreshListeners.addInterface(aGuard, xListener);
+}
+
+void SAL_CALL SwXTextFieldTypes::removeRefreshListener(
+ const uno::Reference<util::XRefreshListener> & xListener)
+{
+ std::unique_lock aGuard(m_pImpl->m_Mutex);
+ m_pImpl->m_RefreshListeners.removeInterface(aGuard, xListener);
+}
+
+class SwXFieldEnumeration::Impl
+ : public SvtListener
+{
+public:
+ SwDoc* m_pDoc;
+ std::vector<uno::Reference<text::XTextField>> m_Items;
+ sal_Int32 m_nNextIndex; ///< index of next element to be returned
+
+ explicit Impl(SwDoc& rDoc)
+ : m_pDoc(&rDoc)
+ , m_nNextIndex(0)
+ {
+ StartListening(rDoc.getIDocumentStylePoolAccess().GetPageDescFromPool(RES_POOLPAGE_STANDARD)->GetNotifier());
+ }
+
+ virtual void Notify(const SfxHint& rHint) override
+ {
+ if(rHint.GetId() == SfxHintId::Dying)
+ m_pDoc = nullptr;
+ }
+};
+
+OUString SAL_CALL
+SwXFieldEnumeration::getImplementationName()
+{
+ return "SwXFieldEnumeration";
+}
+
+sal_Bool SAL_CALL SwXFieldEnumeration::supportsService(const OUString& rServiceName)
+{
+ return cppu::supportsService(this, rServiceName);
+}
+
+uno::Sequence<OUString> SAL_CALL
+SwXFieldEnumeration::getSupportedServiceNames()
+{
+ return { "com.sun.star.text.FieldEnumeration" };
+}
+
+SwXFieldEnumeration::SwXFieldEnumeration(SwDoc & rDoc)
+ : m_pImpl(new Impl(rDoc))
+{
+ // build sequence
+ m_pImpl->m_Items.clear();
+
+ const SwFieldTypes* pFieldTypes = m_pImpl->m_pDoc->getIDocumentFieldsAccess().GetFieldTypes();
+ const size_t nCount = pFieldTypes->size();
+ for(size_t nType = 0; nType < nCount; ++nType)
+ {
+ const SwFieldType* pCurType = (*pFieldTypes)[nType].get();
+ std::vector<SwFormatField*> vFormatFields;
+ pCurType->GatherFields(vFormatFields);
+ std::for_each(vFormatFields.begin(), vFormatFields.end(),
+ [this](SwFormatField* pF) { m_pImpl->m_Items.push_back(SwXTextField::CreateXTextField(m_pImpl->m_pDoc, pF)); });
+ }
+ // now handle meta-fields, which are not SwFields
+ const std::vector< uno::Reference<text::XTextField> > MetaFields(
+ m_pImpl->m_pDoc->GetMetaFieldManager().getMetaFields() );
+ for (const auto & rMetaField : MetaFields)
+ {
+ 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(cppu::getXWeak(SwXFieldmark::CreateXFieldmark(rDoc, *iter).get()), uno::UNO_QUERY);
+ }
+}
+
+SwXFieldEnumeration::~SwXFieldEnumeration()
+{
+}
+
+sal_Bool SAL_CALL SwXFieldEnumeration::hasMoreElements()
+{
+ SolarMutexGuard aGuard;
+
+ return m_pImpl->m_nNextIndex < static_cast<sal_Int32>(m_pImpl->m_Items.size());
+}
+
+uno::Any SAL_CALL SwXFieldEnumeration::nextElement()
+{
+ SolarMutexGuard aGuard;
+
+ if (m_pImpl->m_nNextIndex >= static_cast<sal_Int32>(m_pImpl->m_Items.size()))
+ throw container::NoSuchElementException(
+ "SwXFieldEnumeration::nextElement",
+ css::uno::Reference<css::uno::XInterface>());
+
+ uno::Reference< text::XTextField > &rxField =
+ m_pImpl->m_Items[ m_pImpl->m_nNextIndex++ ];
+ uno::Any aRet;
+ aRet <<= rxField;
+ rxField = nullptr; // free memory for item that is no longer used
+ return aRet;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/core/unocore/unoflatpara.cxx b/sw/source/core/unocore/unoflatpara.cxx
new file mode 100644
index 0000000000..0f158e49fc
--- /dev/null
+++ b/sw/source/core/unocore/unoflatpara.cxx
@@ -0,0 +1,581 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <unobaseclass.hxx>
+#include <unocrsrhelper.hxx>
+#include <unoflatpara.hxx>
+
+#include <o3tl/safeint.hxx>
+#include <utility>
+#include <vcl/svapp.hxx>
+#include <com/sun/star/text/TextMarkupType.hpp>
+#include <com/sun/star/beans/PropertyAttribute.hpp>
+#include <unotextmarkup.hxx>
+#include <ndtxt.hxx>
+#include <doc.hxx>
+#include <IDocumentLayoutAccess.hxx>
+#include <IDocumentStylePoolAccess.hxx>
+#include <viewsh.hxx>
+#include <viewimp.hxx>
+#include <breakit.hxx>
+#include <pam.hxx>
+#include <unotextrange.hxx>
+#include <pagefrm.hxx>
+#include <cntfrm.hxx>
+#include <txtfrm.hxx>
+#include <rootfrm.hxx>
+#include <poolfmt.hxx>
+#include <pagedesc.hxx>
+#include <GrammarContact.hxx>
+#include <viewopt.hxx>
+#include <comphelper/servicehelper.hxx>
+#include <comphelper/propertysetinfo.hxx>
+#include <comphelper/sequence.hxx>
+#include <sal/log.hxx>
+
+#include <com/sun/star/lang/XUnoTunnel.hpp>
+#include <com/sun/star/text/XTextRange.hpp>
+
+using namespace ::com::sun::star;
+
+namespace SwUnoCursorHelper {
+
+uno::Reference<text::XFlatParagraphIterator>
+CreateFlatParagraphIterator(SwDoc & rDoc, sal_Int32 const nTextMarkupType,
+ bool const bAutomatic)
+{
+ return new SwXFlatParagraphIterator(rDoc, nTextMarkupType, bAutomatic);
+}
+
+}
+
+SwXFlatParagraph::SwXFlatParagraph( SwTextNode& rTextNode, OUString aExpandText, const ModelToViewHelper& rMap )
+ : SwXFlatParagraph_Base(& rTextNode, rMap)
+ , maExpandText(std::move(aExpandText))
+ , maOrigText(rTextNode.GetText())
+{
+}
+
+SwXFlatParagraph::~SwXFlatParagraph()
+{
+}
+
+
+// XPropertySet
+uno::Reference< beans::XPropertySetInfo > SAL_CALL
+SwXFlatParagraph::getPropertySetInfo()
+{
+ static const comphelper::PropertyMapEntry s_Entries[] = {
+ { OUString("FieldPositions"), -1, ::cppu::UnoType<uno::Sequence<sal_Int32>>::get(), beans::PropertyAttribute::READONLY, 0 },
+ { OUString("FootnotePositions"), -1, ::cppu::UnoType<uno::Sequence<sal_Int32>>::get(), beans::PropertyAttribute::READONLY, 0 },
+ { OUString("SortedTextId"), -1, ::cppu::UnoType<sal_Int32>::get(), beans::PropertyAttribute::READONLY, 0 },
+ { OUString("DocumentElementsCount"), -1, ::cppu::UnoType<sal_Int32>::get(), beans::PropertyAttribute::READONLY, 0 },
+ };
+ return new comphelper::PropertySetInfo(s_Entries);
+}
+
+void SAL_CALL
+SwXFlatParagraph::setPropertyValue(const OUString&, const uno::Any&)
+{
+ throw lang::IllegalArgumentException("no values can be set",
+ getXWeak(), 0);
+}
+
+uno::Any SAL_CALL
+SwXFlatParagraph::getPropertyValue(const OUString& rPropertyName)
+{
+ SolarMutexGuard g;
+
+ if (rPropertyName == "FieldPositions")
+ {
+ return uno::Any( comphelper::containerToSequence( GetConversionMap().getFieldPositions() ) );
+ }
+ else if (rPropertyName == "FootnotePositions")
+ {
+ return uno::Any( comphelper::containerToSequence( GetConversionMap().getFootnotePositions() ) );
+ }
+ else if (rPropertyName == "SortedTextId")
+ {
+ SwTextNode const*const pCurrentNode = GetTextNode();
+ sal_Int32 nIndex = -1;
+ if ( pCurrentNode )
+ nIndex = pCurrentNode->GetIndex().get();
+ return uno::Any( nIndex );
+ }
+ else if (rPropertyName == "DocumentElementsCount")
+ {
+ SwTextNode const*const pCurrentNode = GetTextNode();
+ sal_Int32 nCount = -1;
+ if ( pCurrentNode )
+ nCount = pCurrentNode->GetDoc().GetNodes().Count().get();
+ return uno::Any( nCount );
+ }
+ return uno::Any();
+}
+
+void SAL_CALL
+SwXFlatParagraph::addPropertyChangeListener(
+ const OUString& /*rPropertyName*/,
+ const uno::Reference< beans::XPropertyChangeListener >& /*xListener*/)
+{
+ SAL_WARN("sw.uno",
+ "SwXFlatParagraph::addPropertyChangeListener(): not implemented");
+}
+
+void SAL_CALL
+SwXFlatParagraph::removePropertyChangeListener(
+ const OUString& /*rPropertyName*/,
+ const uno::Reference< beans::XPropertyChangeListener >& /*xListener*/)
+{
+ SAL_WARN("sw.uno",
+ "SwXFlatParagraph::removePropertyChangeListener(): not implemented");
+}
+
+void SAL_CALL
+SwXFlatParagraph::addVetoableChangeListener(
+ const OUString& /*rPropertyName*/,
+ const uno::Reference< beans::XVetoableChangeListener >& /*xListener*/)
+{
+ SAL_WARN("sw.uno",
+ "SwXFlatParagraph::addVetoableChangeListener(): not implemented");
+}
+
+void SAL_CALL
+SwXFlatParagraph::removeVetoableChangeListener(
+ const OUString& /*rPropertyName*/,
+ const uno::Reference< beans::XVetoableChangeListener >& /*xListener*/)
+{
+ SAL_WARN("sw.uno",
+ "SwXFlatParagraph::removeVetoableChangeListener(): not implemented");
+}
+
+
+css::uno::Reference< css::container::XStringKeyMap > SAL_CALL SwXFlatParagraph::getMarkupInfoContainer()
+{
+ return SwXTextMarkup::getMarkupInfoContainer();
+}
+
+void SAL_CALL SwXFlatParagraph::commitTextRangeMarkup(::sal_Int32 nType, const OUString & aIdentifier, const uno::Reference< text::XTextRange> & xRange,
+ const css::uno::Reference< css::container::XStringKeyMap > & xMarkupInfoContainer)
+{
+ SolarMutexGuard aGuard;
+ SwXTextMarkup::commitTextRangeMarkup( nType, aIdentifier, xRange, xMarkupInfoContainer );
+}
+
+void SAL_CALL SwXFlatParagraph::commitStringMarkup(::sal_Int32 nType, const OUString & rIdentifier, ::sal_Int32 nStart, ::sal_Int32 nLength, const css::uno::Reference< css::container::XStringKeyMap > & rxMarkupInfoContainer)
+{
+ SolarMutexGuard aGuard;
+ SwXTextMarkup::commitStringMarkup( nType, rIdentifier, nStart, nLength, rxMarkupInfoContainer );
+}
+
+// text::XFlatParagraph:
+OUString SAL_CALL SwXFlatParagraph::getText()
+{
+ return maExpandText;
+}
+
+// text::XFlatParagraph:
+void SAL_CALL SwXFlatParagraph::setChecked( ::sal_Int32 nType, sal_Bool bVal )
+{
+ SolarMutexGuard aGuard;
+
+ if (!GetTextNode())
+ return;
+
+ if ( text::TextMarkupType::SPELLCHECK == nType )
+ {
+ GetTextNode()->SetWrongDirty(
+ bVal ? sw::WrongState::DONE : sw::WrongState::TODO);
+ }
+ else if ( text::TextMarkupType::SMARTTAG == nType )
+ GetTextNode()->SetSmartTagDirty( !bVal );
+ else if( text::TextMarkupType::PROOFREADING == nType )
+ {
+ GetTextNode()->SetGrammarCheckDirty( !bVal );
+ if( bVal )
+ sw::finishGrammarCheckFor(*GetTextNode());
+ }
+}
+
+// text::XFlatParagraph:
+sal_Bool SAL_CALL SwXFlatParagraph::isChecked( ::sal_Int32 nType )
+{
+ SolarMutexGuard aGuard;
+ if (GetTextNode())
+ {
+ if ( text::TextMarkupType::SPELLCHECK == nType )
+ return !GetTextNode()->IsWrongDirty();
+ else if ( text::TextMarkupType::PROOFREADING == nType )
+ return !GetTextNode()->IsGrammarCheckDirty();
+ else if ( text::TextMarkupType::SMARTTAG == nType )
+ return !GetTextNode()->IsSmartTagDirty();
+ }
+
+ return true;
+}
+
+// text::XFlatParagraph:
+sal_Bool SAL_CALL SwXFlatParagraph::isModified()
+{
+ SolarMutexGuard aGuard;
+ return !GetTextNode() || GetTextNode()->GetText() != maOrigText;
+}
+
+// text::XFlatParagraph:
+lang::Locale SAL_CALL SwXFlatParagraph::getLanguageOfText(::sal_Int32 nPos, ::sal_Int32 nLen)
+{
+ SolarMutexGuard aGuard;
+ if (!GetTextNode())
+ return LanguageTag::convertToLocale( LANGUAGE_NONE );
+
+ const lang::Locale aLocale( SW_BREAKITER()->GetLocale( GetTextNode()->GetLang(nPos, nLen) ) );
+ return aLocale;
+}
+
+// text::XFlatParagraph:
+lang::Locale SAL_CALL SwXFlatParagraph::getPrimaryLanguageOfText(::sal_Int32 nPos, ::sal_Int32 nLen)
+{
+ SolarMutexGuard aGuard;
+
+ if (!GetTextNode())
+ return LanguageTag::convertToLocale( LANGUAGE_NONE );
+
+ const lang::Locale aLocale( SW_BREAKITER()->GetLocale( GetTextNode()->GetLang(nPos, nLen) ) );
+ return aLocale;
+}
+
+// text::XFlatParagraph:
+void SAL_CALL SwXFlatParagraph::changeText(::sal_Int32 nPos, ::sal_Int32 nLen, const OUString & aNewText, const css::uno::Sequence< css::beans::PropertyValue > & aAttributes)
+{
+ SolarMutexGuard aGuard;
+
+ if (!GetTextNode())
+ return;
+
+ SwTextNode *const pOldTextNode = GetTextNode();
+
+ if (nPos < 0 || pOldTextNode->Len() < nPos || nLen < 0 || o3tl::make_unsigned(pOldTextNode->Len()) < static_cast<sal_uInt32>(nPos) + nLen)
+ {
+ throw lang::IllegalArgumentException();
+ }
+
+ SwPaM aPaM( *GetTextNode(), nPos, *GetTextNode(), nPos+nLen );
+
+ UnoActionContext aAction( &GetTextNode()->GetDoc() );
+
+ const rtl::Reference<SwXTextRange> xRange =
+ SwXTextRange::CreateXTextRange(
+ GetTextNode()->GetDoc(), *aPaM.GetPoint(), aPaM.GetMark() );
+ if ( xRange.is() )
+ {
+ for ( const auto& rAttribute : aAttributes )
+ xRange->setPropertyValue( rAttribute.Name, rAttribute.Value );
+ }
+
+ IDocumentContentOperations& rIDCO = pOldTextNode->getIDocumentContentOperations();
+ rIDCO.ReplaceRange( aPaM, aNewText, false );
+
+ ClearTextNode(); // TODO: is this really needed?
+}
+
+// text::XFlatParagraph:
+void SAL_CALL SwXFlatParagraph::changeAttributes(::sal_Int32 nPos, ::sal_Int32 nLen, const css::uno::Sequence< css::beans::PropertyValue > & aAttributes)
+{
+ SolarMutexGuard aGuard;
+
+ if (!GetTextNode())
+ return;
+
+ if (nPos < 0 || GetTextNode()->Len() < nPos || nLen < 0 || o3tl::make_unsigned(GetTextNode()->Len()) < static_cast<sal_uInt32>(nPos) + nLen)
+ {
+ throw lang::IllegalArgumentException();
+ }
+
+ SwPaM aPaM( *GetTextNode(), nPos, *GetTextNode(), nPos+nLen );
+
+ UnoActionContext aAction( &GetTextNode()->GetDoc() );
+
+ const rtl::Reference<SwXTextRange> xRange =
+ SwXTextRange::CreateXTextRange(
+ GetTextNode()->GetDoc(), *aPaM.GetPoint(), aPaM.GetMark() );
+ if ( xRange.is() )
+ {
+ for ( const auto& rAttribute : aAttributes )
+ xRange->setPropertyValue( rAttribute.Name, rAttribute.Value );
+ }
+
+ ClearTextNode(); // TODO: is this really needed?
+}
+
+// text::XFlatParagraph:
+css::uno::Sequence< ::sal_Int32 > SAL_CALL SwXFlatParagraph::getLanguagePortions()
+{
+ return css::uno::Sequence< ::sal_Int32>();
+}
+
+SwXFlatParagraphIterator::SwXFlatParagraphIterator( SwDoc& rDoc, sal_Int32 nType, bool bAutomatic )
+ : mpDoc( &rDoc ),
+ mnType( nType ),
+ mbAutomatic( bAutomatic ),
+ mnCurrentNode( 0 ),
+ mnEndNode( rDoc.GetNodes().Count() )
+{
+ //mnStartNode = mnCurrentNode = get node from current cursor TODO!
+
+ // register as listener and get notified when document is closed
+ StartListening(mpDoc->getIDocumentStylePoolAccess().GetPageDescFromPool( RES_POOLPAGE_STANDARD )->GetNotifier());
+}
+
+SwXFlatParagraphIterator::~SwXFlatParagraphIterator()
+{
+ SolarMutexGuard aGuard;
+ EndListeningAll();
+}
+
+void SwXFlatParagraphIterator::Notify( const SfxHint& rHint )
+{
+ if(rHint.GetId() == SfxHintId::Dying)
+ {
+ SolarMutexGuard aGuard;
+ mpDoc = nullptr;
+ }
+}
+
+uno::Reference< text::XFlatParagraph > SwXFlatParagraphIterator::getFirstPara()
+{
+ return getNextPara(); // TODO
+}
+
+uno::Reference< text::XFlatParagraph > SwXFlatParagraphIterator::getNextPara()
+{
+ SolarMutexGuard aGuard;
+
+ uno::Reference< text::XFlatParagraph > xRet;
+ if (!mpDoc)
+ return xRet;
+
+ SwTextNode* pRet = nullptr;
+ if ( mbAutomatic )
+ {
+ SwViewShell* pViewShell = mpDoc->getIDocumentLayoutAccess().GetCurrentViewShell();
+
+ SwPageFrame* pCurrentPage = pViewShell ? pViewShell->Imp()->GetFirstVisPage(pViewShell->GetOut()) : nullptr;
+ SwPageFrame* pStartPage = pCurrentPage;
+ SwPageFrame* pStopPage = nullptr;
+
+ while ( pCurrentPage && pCurrentPage != pStopPage )
+ {
+ if (mnType != text::TextMarkupType::SPELLCHECK || pCurrentPage->IsInvalidSpelling() )
+ {
+ // this method is supposed to return an empty paragraph in case Online Checking is disabled
+ if ( ( mnType == text::TextMarkupType::PROOFREADING || mnType == text::TextMarkupType::SPELLCHECK )
+ && !pViewShell->GetViewOptions()->IsOnlineSpell() )
+ return xRet;
+
+ // search for invalid content:
+ SwContentFrame* pCnt = pCurrentPage->ContainsContent();
+
+ while( pCnt && pCurrentPage->IsAnLower( pCnt ) )
+ {
+ if (pCnt->IsTextFrame())
+ {
+ SwTextFrame const*const pText(static_cast<SwTextFrame const*>(pCnt));
+ if (sw::MergedPara const*const pMergedPara = pText->GetMergedPara()
+ )
+ {
+ SwTextNode * pTextNode(nullptr);
+ for (auto const& e : pMergedPara->extents)
+ {
+ if (e.pNode != pTextNode)
+ {
+ pTextNode = e.pNode;
+ if ((mnType == text::TextMarkupType::SPELLCHECK
+ && pTextNode->IsWrongDirty()) ||
+ (mnType == text::TextMarkupType::PROOFREADING
+ && pTextNode->IsGrammarCheckDirty()))
+ {
+ pRet = pTextNode;
+ break;
+ }
+ }
+ }
+ }
+ else
+ {
+ SwTextNode const*const pTextNode(pText->GetTextNodeFirst());
+ if ((mnType == text::TextMarkupType::SPELLCHECK
+ && pTextNode->IsWrongDirty()) ||
+ (mnType == text::TextMarkupType::PROOFREADING
+ && pTextNode->IsGrammarCheckDirty()))
+
+ {
+ pRet = const_cast<SwTextNode*>(pTextNode);
+ }
+ }
+
+ if (pRet)
+ {
+ break;
+ }
+ }
+
+ pCnt = pCnt->GetNextContentFrame();
+ }
+ }
+
+ if ( pRet )
+ break;
+
+ // if there is no invalid text node on the current page,
+ // we validate the page
+ pCurrentPage->ValidateSpelling();
+
+ // proceed with next page, wrap at end of document if required:
+ pCurrentPage = static_cast<SwPageFrame*>(pCurrentPage->GetNext());
+
+ if ( !pCurrentPage && !pStopPage )
+ {
+ pStopPage = pStartPage;
+ pCurrentPage = static_cast<SwPageFrame*>(pViewShell->GetLayout()->Lower());
+ }
+ }
+ }
+ else // non-automatic checking
+ {
+ const SwNodes& rNodes = mpDoc->GetNodes();
+ const SwNodeOffset nMaxNodes = rNodes.Count();
+
+ while ( mnCurrentNode < mnEndNode && mnCurrentNode < nMaxNodes )
+ {
+ SwNode* pNd = rNodes[ mnCurrentNode ];
+
+ ++mnCurrentNode;
+
+ pRet = pNd->GetTextNode();
+ if ( pRet )
+ break;
+
+ if ( mnCurrentNode == mnEndNode )
+ {
+ mnCurrentNode = SwNodeOffset(0);
+ mnEndNode = SwNodeOffset(0);
+ }
+ }
+ }
+
+ if ( pRet )
+ {
+ // Expand the string:
+ const ModelToViewHelper aConversionMap(*pRet, mpDoc->getIDocumentLayoutAccess().GetCurrentLayout());
+ const OUString& aExpandText = aConversionMap.getViewText();
+
+ xRet = new SwXFlatParagraph( *pRet, aExpandText, aConversionMap );
+ }
+
+ return xRet;
+}
+
+uno::Reference< text::XFlatParagraph > SwXFlatParagraphIterator::getLastPara()
+{
+ return getNextPara();
+}
+
+uno::Reference< text::XFlatParagraph > SwXFlatParagraphIterator::getParaAfter(const uno::Reference< text::XFlatParagraph > & xPara)
+{
+ SolarMutexGuard aGuard;
+
+ uno::Reference< text::XFlatParagraph > xRet;
+ if (!mpDoc)
+ return xRet;
+
+ SwXFlatParagraph* const pFlatParagraph(dynamic_cast<SwXFlatParagraph*>(xPara.get()));
+ SAL_WARN_IF(!pFlatParagraph, "sw.core", "invalid argument");
+ if ( !pFlatParagraph )
+ return xRet;
+
+ SwTextNode const*const pCurrentNode = pFlatParagraph->GetTextNode();
+
+ if ( !pCurrentNode )
+ return xRet;
+
+ SwTextNode* pNextTextNode = nullptr;
+ const SwNodes& rNodes = pCurrentNode->GetDoc().GetNodes();
+
+ for( SwNodeOffset nCurrentNode = pCurrentNode->GetIndex() + 1; nCurrentNode < rNodes.Count(); ++nCurrentNode )
+ {
+ SwNode* pNd = rNodes[ nCurrentNode ];
+ pNextTextNode = pNd->GetTextNode();
+ if ( pNextTextNode )
+ break;
+ }
+
+ if ( pNextTextNode )
+ {
+ // Expand the string:
+ const ModelToViewHelper aConversionMap(*pNextTextNode, mpDoc->getIDocumentLayoutAccess().GetCurrentLayout());
+ const OUString& aExpandText = aConversionMap.getViewText();
+
+ xRet = new SwXFlatParagraph( *pNextTextNode, aExpandText, aConversionMap );
+ }
+
+ return xRet;
+}
+
+uno::Reference< text::XFlatParagraph > SwXFlatParagraphIterator::getParaBefore(const uno::Reference< text::XFlatParagraph > & xPara )
+{
+ SolarMutexGuard aGuard;
+
+ uno::Reference< text::XFlatParagraph > xRet;
+ if (!mpDoc)
+ return xRet;
+
+ SwXFlatParagraph* const pFlatParagraph(dynamic_cast<SwXFlatParagraph*>(xPara.get()));
+ SAL_WARN_IF(!pFlatParagraph, "sw.core", "invalid argument");
+ if ( !pFlatParagraph )
+ return xRet;
+
+ SwTextNode const*const pCurrentNode = pFlatParagraph->GetTextNode();
+
+ if ( !pCurrentNode )
+ return xRet;
+
+ SwTextNode* pPrevTextNode = nullptr;
+ const SwNodes& rNodes = pCurrentNode->GetDoc().GetNodes();
+
+ for( SwNodeOffset nCurrentNode = pCurrentNode->GetIndex() - 1; nCurrentNode > SwNodeOffset(0); --nCurrentNode )
+ {
+ SwNode* pNd = rNodes[ nCurrentNode ];
+ pPrevTextNode = pNd->GetTextNode();
+ if ( pPrevTextNode )
+ break;
+ }
+
+ if ( pPrevTextNode )
+ {
+ // Expand the string:
+ const ModelToViewHelper aConversionMap(*pPrevTextNode, mpDoc->getIDocumentLayoutAccess().GetCurrentLayout());
+ const OUString& aExpandText = aConversionMap.getViewText();
+
+ xRet = new SwXFlatParagraph( *pPrevTextNode, aExpandText, aConversionMap );
+ }
+
+ return xRet;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/core/unocore/unoframe.cxx b/sw/source/core/unocore/unoframe.cxx
new file mode 100644
index 0000000000..7880a749b9
--- /dev/null
+++ b/sw/source/core/unocore/unoframe.cxx
@@ -0,0 +1,3691 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <com/sun/star/awt/XBitmap.hpp>
+#include <com/sun/star/embed/NoVisualAreaSizeException.hpp>
+#include <com/sun/star/container/XChild.hpp>
+#include <com/sun/star/drawing/BitmapMode.hpp>
+#include <com/sun/star/drawing/FillStyle.hpp>
+#include <com/sun/star/embed/EmbedStates.hpp>
+#include <com/sun/star/embed/Aspects.hpp>
+#include <com/sun/star/frame/XTitle.hpp>
+#include <com/sun/star/frame/XModel.hpp>
+#include <o3tl/any.hxx>
+#include <svx/xfillit0.hxx>
+#include <svx/xflgrit.hxx>
+#include <svx/sdtaitm.hxx>
+#include <svx/xflclit.hxx>
+#include <tools/globname.hxx>
+#include <tools/UnitConversion.hxx>
+#include <editeng/memberids.h>
+#include <swtypes.hxx>
+#include <cmdid.h>
+#include <unomid.h>
+#include <memory>
+#include <utility>
+#include <cntfrm.hxx>
+#include <doc.hxx>
+#include <drawdoc.hxx>
+#include <IDocumentUndoRedo.hxx>
+#include <IDocumentDrawModelAccess.hxx>
+#include <IDocumentLayoutAccess.hxx>
+#include <IDocumentStylePoolAccess.hxx>
+#include <UndoAttribute.hxx>
+#include <docsh.hxx>
+#include <editsh.hxx>
+#include <ndindex.hxx>
+#include <pam.hxx>
+#include <ndnotxt.hxx>
+#include <svx/unomid.hxx>
+#include <unocrsr.hxx>
+#include <unocrsrhelper.hxx>
+#include <docstyle.hxx>
+#include <dcontact.hxx>
+#include <fmtcnct.hxx>
+#include <ndole.hxx>
+#include <frmfmt.hxx>
+#include <frame.hxx>
+#include <textboxhelper.hxx>
+#include <unotextrange.hxx>
+#include <unotextcursor.hxx>
+#include <unoparagraph.hxx>
+#include <unomap.hxx>
+#include <unoprnms.hxx>
+#include <unoevent.hxx>
+#include <com/sun/star/util/XModifyBroadcaster.hpp>
+#include <com/sun/star/text/TextContentAnchorType.hpp>
+#include <com/sun/star/text/WrapTextMode.hpp>
+#include <com/sun/star/beans/PropertyAttribute.hpp>
+#include <com/sun/star/drawing/PointSequenceSequence.hpp>
+#include <com/sun/star/drawing/PointSequence.hpp>
+#include <tools/poly.hxx>
+#include <swundo.hxx>
+#include <svx/svdpage.hxx>
+#include <editeng/brushitem.hxx>
+#include <editeng/protitem.hxx>
+#include <fmtornt.hxx>
+#include <fmteiro.hxx>
+#include <fmturl.hxx>
+#include <editeng/lrspitem.hxx>
+#include <editeng/ulspitem.hxx>
+#include <editeng/boxitem.hxx>
+#include <editeng/opaqitem.hxx>
+#include <editeng/prntitem.hxx>
+#include <editeng/shaditem.hxx>
+#include <fmtsrnd.hxx>
+#include <fmtfsize.hxx>
+#include <grfatr.hxx>
+#include <unoframe.hxx>
+#include <fmtanchr.hxx>
+#include <fmtclds.hxx>
+#include <fmtcntnt.hxx>
+#include <frmatr.hxx>
+#include <ndtxt.hxx>
+#include <ndgrf.hxx>
+#include <mutex>
+#include <vcl/svapp.hxx>
+#include <vcl/GraphicLoader.hxx>
+#include <SwStyleNameMapper.hxx>
+#include <editeng/xmlcnitm.hxx>
+#include <poolfmt.hxx>
+#include <pagedesc.hxx>
+#include <com/sun/star/style/XStyleFamiliesSupplier.hpp>
+#include <editeng/frmdiritem.hxx>
+#include <fmtfollowtextflow.hxx>
+#include <fmtwrapinfluenceonobjpos.hxx>
+#include <toolkit/helper/vclunohelper.hxx>
+#include <comphelper/interfacecontainer4.hxx>
+#include <comphelper/servicehelper.hxx>
+#include <cppuhelper/supportsservice.hxx>
+#include <sal/log.hxx>
+#include <vcl/errinf.hxx>
+
+#include <svx/unobrushitemhelper.hxx>
+#include <svx/xbtmpit.hxx>
+#include <svx/xgrscit.hxx>
+#include <svx/xflbmtit.hxx>
+#include <svx/xflbmpit.hxx>
+#include <svx/xflbmsxy.hxx>
+#include <svx/xflftrit.hxx>
+#include <svx/xsflclit.hxx>
+#include <svx/xflbmsli.hxx>
+#include <svx/xflbtoxy.hxx>
+#include <svx/xflbstit.hxx>
+#include <svx/xflboxy.hxx>
+#include <svx/xflbckit.hxx>
+#include <svx/unoshape.hxx>
+#include <svx/xflhtit.hxx>
+#include <svx/xfltrit.hxx>
+#include <swunohelper.hxx>
+#include <fefly.hxx>
+#include <formatflysplit.hxx>
+#include <formatwraptextatflystart.hxx>
+
+using namespace ::com::sun::star;
+
+using ::com::sun::star::frame::XModel;
+using ::com::sun::star::container::XNameAccess;
+using ::com::sun::star::style::XStyleFamiliesSupplier;
+
+class BaseFrameProperties_Impl
+{
+ SwUnoCursorHelper::SwAnyMapHelper m_aAnyMap;
+
+public:
+ virtual ~BaseFrameProperties_Impl();
+
+ void SetProperty(sal_uInt16 nWID, sal_uInt8 nMemberId, const uno::Any& rVal);
+ bool GetProperty(sal_uInt16 nWID, sal_uInt8 nMemberId, const uno::Any*& pAny );
+ bool FillBaseProperties(SfxItemSet& rToSet, const SfxItemSet &rFromSet, bool& rSizeFound);
+
+ virtual bool AnyToItemSet( SwDoc* pDoc, SfxItemSet& rFrameSet, SfxItemSet& rSet, bool& rSizeFound) = 0;
+};
+
+BaseFrameProperties_Impl::~BaseFrameProperties_Impl()
+{
+}
+
+void BaseFrameProperties_Impl::SetProperty(sal_uInt16 nWID, sal_uInt8 nMemberId, const uno::Any& rVal)
+{
+ m_aAnyMap.SetValue( nWID, nMemberId, rVal );
+}
+
+bool BaseFrameProperties_Impl::GetProperty(sal_uInt16 nWID, sal_uInt8 nMemberId, const uno::Any*& rpAny)
+{
+ return m_aAnyMap.FillValue( nWID, nMemberId, rpAny );
+}
+
+bool BaseFrameProperties_Impl::FillBaseProperties(SfxItemSet& rToSet, const SfxItemSet& rFromSet, bool& rSizeFound)
+{
+ // assert when the target SfxItemSet has no parent. It *should* have the pDfltFrameFormat
+ // from SwDoc set as parent (or similar) to have the necessary XFILL_NONE in the ItemSet
+ if(!rToSet.GetParent())
+ {
+ OSL_ENSURE(false, "OOps, target SfxItemSet *should* have a parent which contains XFILL_NONE as XFillStyleItem (!)");
+ }
+
+ bool bRet = true;
+ // always add an anchor to the set
+ SwFormatAnchor aAnchor ( rFromSet.Get ( RES_ANCHOR ) );
+ {
+ const ::uno::Any* pAnchorType;
+ if(GetProperty(RES_ANCHOR, MID_ANCHOR_ANCHORTYPE, pAnchorType))
+ bRet &= static_cast<SfxPoolItem&>(aAnchor).PutValue(*pAnchorType, MID_ANCHOR_ANCHORTYPE);
+ const ::uno::Any* pAnchorPgNo;
+ if(GetProperty(RES_ANCHOR, MID_ANCHOR_PAGENUM, pAnchorPgNo))
+ bRet &= static_cast<SfxPoolItem&>(aAnchor).PutValue(*pAnchorPgNo, MID_ANCHOR_PAGENUM);
+ }
+
+ rToSet.Put(aAnchor);
+
+ // check for SvxBrushItem (RES_BACKGROUND) properties
+ const ::uno::Any* pCol = nullptr; GetProperty(RES_BACKGROUND, MID_BACK_COLOR, pCol );
+ const ::uno::Any* pRGBCol = nullptr; GetProperty(RES_BACKGROUND, MID_BACK_COLOR_R_G_B, pRGBCol );
+ const ::uno::Any* pColTrans = nullptr; GetProperty(RES_BACKGROUND, MID_BACK_COLOR_TRANSPARENCY, pColTrans);
+ const ::uno::Any* pTrans = nullptr; GetProperty(RES_BACKGROUND, MID_GRAPHIC_TRANSPARENT, pTrans );
+ const ::uno::Any* pGrLoc = nullptr; GetProperty(RES_BACKGROUND, MID_GRAPHIC_POSITION, pGrLoc );
+ const ::uno::Any* pGraphic = nullptr; GetProperty(RES_BACKGROUND, MID_GRAPHIC, pGraphic );
+ const ::uno::Any* pGrFilter = nullptr; GetProperty(RES_BACKGROUND, MID_GRAPHIC_FILTER, pGrFilter );
+ const ::uno::Any* pGraphicURL = nullptr; GetProperty(RES_BACKGROUND, MID_GRAPHIC_URL, pGraphicURL );
+ const ::uno::Any* pGrTransparency = nullptr; GetProperty(RES_BACKGROUND, MID_GRAPHIC_TRANSPARENCY, pGrTransparency );
+ const bool bSvxBrushItemPropertiesUsed(
+ pCol ||
+ pTrans ||
+ pGraphic ||
+ pGraphicURL ||
+ pGrFilter ||
+ pGrLoc ||
+ pGrTransparency ||
+ pColTrans ||
+ pRGBCol);
+
+ // check for FillStyle properties in the range XATTR_FILL_FIRST, XATTR_FILL_LAST
+ const uno::Any* pXFillStyleItem = nullptr; GetProperty(XATTR_FILLSTYLE, 0, pXFillStyleItem);
+ const uno::Any* pXFillColorItem = nullptr; GetProperty(XATTR_FILLCOLOR, 0, pXFillColorItem);
+
+ // XFillGradientItem: two possible slots supported in UNO API
+ const uno::Any* pXFillGradientItem = nullptr; GetProperty(XATTR_FILLGRADIENT, MID_FILLGRADIENT, pXFillGradientItem);
+ const uno::Any* pXFillGradientNameItem = nullptr; GetProperty(XATTR_FILLGRADIENT, MID_NAME, pXFillGradientNameItem);
+
+ // XFillHatchItem: two possible slots supported in UNO API
+ const uno::Any* pXFillHatchItem = nullptr; GetProperty(XATTR_FILLHATCH, MID_FILLHATCH, pXFillHatchItem);
+ const uno::Any* pXFillHatchNameItem = nullptr; GetProperty(XATTR_FILLHATCH, MID_NAME, pXFillHatchNameItem);
+
+ // XFillBitmapItem: three possible slots supported in UNO API
+ const uno::Any* pXFillBitmapItem = nullptr; GetProperty(XATTR_FILLBITMAP, MID_BITMAP, pXFillBitmapItem);
+ const uno::Any* pXFillBitmapNameItem = nullptr; GetProperty(XATTR_FILLBITMAP, MID_NAME, pXFillBitmapNameItem);
+
+ const uno::Any* pXFillTransparenceItem = nullptr; GetProperty(XATTR_FILLTRANSPARENCE, 0, pXFillTransparenceItem);
+ const uno::Any* pXGradientStepCountItem = nullptr; GetProperty(XATTR_GRADIENTSTEPCOUNT, 0, pXGradientStepCountItem);
+ const uno::Any* pXFillBmpPosItem = nullptr; GetProperty(XATTR_FILLBMP_POS, 0, pXFillBmpPosItem);
+ const uno::Any* pXFillBmpSizeXItem = nullptr; GetProperty(XATTR_FILLBMP_SIZEX, 0, pXFillBmpSizeXItem);
+ const uno::Any* pXFillBmpSizeYItem = nullptr; GetProperty(XATTR_FILLBMP_SIZEY, 0, pXFillBmpSizeYItem);
+
+ // XFillFloatTransparenceItem: two possible slots supported in UNO API
+ const uno::Any* pXFillFloatTransparenceItem = nullptr; GetProperty(XATTR_FILLFLOATTRANSPARENCE, MID_FILLGRADIENT, pXFillFloatTransparenceItem);
+ const uno::Any* pXFillFloatTransparenceNameItem = nullptr; GetProperty(XATTR_FILLFLOATTRANSPARENCE, MID_NAME, pXFillFloatTransparenceNameItem);
+
+ const uno::Any* pXSecondaryFillColorItem = nullptr; GetProperty(XATTR_SECONDARYFILLCOLOR, 0, pXSecondaryFillColorItem);
+ const uno::Any* pXFillBmpSizeLogItem = nullptr; GetProperty(XATTR_FILLBMP_SIZELOG, 0, pXFillBmpSizeLogItem);
+ const uno::Any* pXFillBmpTileOffsetXItem = nullptr; GetProperty(XATTR_FILLBMP_TILEOFFSETX, 0, pXFillBmpTileOffsetXItem);
+ const uno::Any* pXFillBmpTileOffsetYItem = nullptr; GetProperty(XATTR_FILLBMP_TILEOFFSETY, 0, pXFillBmpTileOffsetYItem);
+ const uno::Any* pXFillBmpPosOffsetXItem = nullptr; GetProperty(XATTR_FILLBMP_POSOFFSETX, 0, pXFillBmpPosOffsetXItem);
+ const uno::Any* pXFillBmpPosOffsetYItem = nullptr; GetProperty(XATTR_FILLBMP_POSOFFSETY, 0, pXFillBmpPosOffsetYItem);
+ const uno::Any* pXFillBackgroundItem = nullptr; GetProperty(XATTR_FILLBACKGROUND, 0, pXFillBackgroundItem);
+ const uno::Any* pOwnAttrFillBmpItem = nullptr; GetProperty(OWN_ATTR_FILLBMP_MODE, 0, pOwnAttrFillBmpItem);
+
+ // tdf#91140: ignore SOLID fill style for determining if fill style is used
+ // but there is a Graphic
+ const bool bFillStyleUsed(pXFillStyleItem && pXFillStyleItem->hasValue() &&
+ (pXFillStyleItem->get<drawing::FillStyle>() != drawing::FillStyle_SOLID || (!pGraphic || !pGraphicURL) ));
+ SAL_INFO_IF(pXFillStyleItem && pXFillStyleItem->hasValue() && !bFillStyleUsed,
+ "sw.uno", "FillBaseProperties: ignoring invalid FillStyle");
+ const bool bXFillStyleItemUsed(
+ bFillStyleUsed ||
+ pXFillColorItem ||
+ pXFillGradientItem || pXFillGradientNameItem ||
+ pXFillHatchItem || pXFillHatchNameItem ||
+ pXFillBitmapItem || pXFillBitmapNameItem ||
+ pXFillTransparenceItem ||
+ pXGradientStepCountItem ||
+ pXFillBmpPosItem ||
+ pXFillBmpSizeXItem ||
+ pXFillBmpSizeYItem ||
+ pXFillFloatTransparenceItem || pXFillFloatTransparenceNameItem ||
+ pXSecondaryFillColorItem ||
+ pXFillBmpSizeLogItem ||
+ pXFillBmpTileOffsetXItem ||
+ pXFillBmpTileOffsetYItem ||
+ pXFillBmpPosOffsetXItem ||
+ pXFillBmpPosOffsetYItem ||
+ pXFillBackgroundItem ||
+ pOwnAttrFillBmpItem);
+
+ // use brush items, but *only* if no FillStyle properties are used; if both are used and when applying both
+ // in the obvious order some attributes may be wrong since they are set by the 1st set, but not
+ // redefined as needed by the 2nd set when they are default (and thus no tset) in the 2nd set. If
+ // it is necessary for any reason to set both (it should not) an in-between step will be needed
+ // that resets the items for FillAttributes in rToSet to default.
+ // Note: There are other mechanisms in XMLOFF to pre-sort this relationship already, but this version
+ // was used initially, is tested and works. Keep it to be able to react when another feed adds attributes
+ // from both sets.
+ if(bSvxBrushItemPropertiesUsed && !bXFillStyleItemUsed)
+ {
+ // create a temporary SvxBrushItem, fill the attributes to it and use it to set
+ // the corresponding FillAttributes
+ SvxBrushItem aBrush(RES_BACKGROUND);
+
+ if(pCol)
+ {
+ bRet &= static_cast<SfxPoolItem&>(aBrush).PutValue(*pCol,MID_BACK_COLOR );
+ }
+
+ if(pColTrans)
+ {
+ bRet &= static_cast<SfxPoolItem&>(aBrush).PutValue(*pColTrans, MID_BACK_COLOR_TRANSPARENCY);
+ }
+
+ if(pRGBCol)
+ {
+ bRet &= static_cast<SfxPoolItem&>(aBrush).PutValue(*pRGBCol, MID_BACK_COLOR_R_G_B);
+ }
+
+ if(pTrans)
+ {
+ // don't overwrite transparency with a non-transparence flag
+ if(!pColTrans || Any2Bool( *pTrans ))
+ bRet &= static_cast<SfxPoolItem&>(aBrush).PutValue(*pTrans, MID_GRAPHIC_TRANSPARENT);
+ }
+
+ if (pGraphic)
+ {
+ bRet &= static_cast<SfxPoolItem&>(aBrush).PutValue(*pGraphic, MID_GRAPHIC);
+ }
+
+ if (pGraphicURL)
+ {
+ bRet &= static_cast<SfxPoolItem&>(aBrush).PutValue(*pGraphicURL, MID_GRAPHIC_URL);
+ }
+
+ if(pGrFilter)
+ {
+ bRet &= static_cast<SfxPoolItem&>(aBrush).PutValue(*pGrFilter, MID_GRAPHIC_FILTER);
+ }
+
+ if(pGrLoc)
+ {
+ bRet &= static_cast<SfxPoolItem&>(aBrush).PutValue(*pGrLoc, MID_GRAPHIC_POSITION);
+ }
+
+ if(pGrTransparency)
+ {
+ bRet &= static_cast<SfxPoolItem&>(aBrush).PutValue(*pGrTransparency, MID_GRAPHIC_TRANSPARENCY);
+ }
+
+ setSvxBrushItemAsFillAttributesToTargetSet(aBrush, rToSet);
+ }
+
+ if(bXFillStyleItemUsed)
+ {
+ XFillStyleItem aXFillStyleItem;
+ std::unique_ptr<SvxBrushItem> aBrush(std::make_unique<SvxBrushItem>(RES_BACKGROUND));
+
+ if(pXFillStyleItem)
+ {
+ aXFillStyleItem.PutValue(*pXFillStyleItem, 0);
+ rToSet.Put(aXFillStyleItem);
+ }
+
+ if(pXFillColorItem)
+ {
+ const Color aNullCol(COL_DEFAULT_SHAPE_FILLING);
+ XFillColorItem aXFillColorItem(OUString(), aNullCol);
+
+ aXFillColorItem.PutValue(*pXFillColorItem, 0);
+ rToSet.Put(aXFillColorItem);
+ //set old-school brush color if we later encounter the
+ //MID_BACK_COLOR_TRANSPARENCY case below
+ aBrush = getSvxBrushItemFromSourceSet(rToSet, RES_BACKGROUND, false);
+ }
+ else if (aXFillStyleItem.GetValue() == drawing::FillStyle_SOLID && (pCol || pRGBCol))
+ {
+ // Fill style is set to solid, but no fill color is given.
+ // On the other hand, we have a BackColor, so use that.
+ if (pCol)
+ aBrush->PutValue(*pCol, MID_BACK_COLOR);
+ else
+ aBrush->PutValue(*pRGBCol, MID_BACK_COLOR_R_G_B);
+ setSvxBrushItemAsFillAttributesToTargetSet(*aBrush, rToSet);
+ }
+
+ if(pXFillGradientItem || pXFillGradientNameItem)
+ {
+ if(pXFillGradientItem)
+ {
+ // basegfx::BGradient() default already creates [COL_BLACK, COL_WHITE] as defaults
+ const basegfx::BGradient aNullGrad;
+ XFillGradientItem aXFillGradientItem(aNullGrad);
+
+ aXFillGradientItem.PutValue(*pXFillGradientItem, MID_FILLGRADIENT);
+ rToSet.Put(aXFillGradientItem);
+ }
+
+ if(pXFillGradientNameItem)
+ {
+ OUString aTempName;
+
+ if(!(*pXFillGradientNameItem >>= aTempName ))
+ {
+ throw lang::IllegalArgumentException();
+ }
+
+ bool const bSuccess = SvxShape::SetFillAttribute(
+ XATTR_FILLGRADIENT, aTempName, rToSet);
+ if (aXFillStyleItem.GetValue() == drawing::FillStyle_GRADIENT)
+ { // tdf#90946 ignore invalid gradient-name if SOLID
+ bRet &= bSuccess;
+ }
+ else
+ {
+ SAL_INFO_IF(!bSuccess, "sw.uno",
+ "FillBaseProperties: ignoring invalid FillGradientName");
+ }
+ }
+ }
+
+ if(pXFillHatchItem || pXFillHatchNameItem)
+ {
+ if(pXFillHatchItem)
+ {
+ const Color aNullCol(COL_DEFAULT_SHAPE_STROKE);
+ const XHatch aNullHatch(aNullCol);
+ XFillHatchItem aXFillHatchItem(aNullHatch);
+
+ aXFillHatchItem.PutValue(*pXFillHatchItem, MID_FILLHATCH);
+ rToSet.Put(aXFillHatchItem);
+ }
+
+ if(pXFillHatchNameItem)
+ {
+ OUString aTempName;
+
+ if(!(*pXFillHatchNameItem >>= aTempName ))
+ {
+ throw lang::IllegalArgumentException();
+ }
+
+ bRet &= SvxShape::SetFillAttribute(XATTR_FILLHATCH, aTempName, rToSet);
+ }
+ }
+
+ if (pXFillBitmapItem || pXFillBitmapNameItem)
+ {
+ if(pXFillBitmapItem)
+ {
+ Graphic aNullGraphic;
+ XFillBitmapItem aXFillBitmapItem(std::move(aNullGraphic));
+
+ aXFillBitmapItem.PutValue(*pXFillBitmapItem, MID_BITMAP);
+ rToSet.Put(aXFillBitmapItem);
+ }
+
+ if(pXFillBitmapNameItem)
+ {
+ OUString aTempName;
+
+ if(!(*pXFillBitmapNameItem >>= aTempName ))
+ {
+ throw lang::IllegalArgumentException();
+ }
+
+ bRet &= SvxShape::SetFillAttribute(XATTR_FILLBITMAP, aTempName, rToSet);
+ }
+ }
+
+ if (pXFillTransparenceItem)
+ {
+ XFillTransparenceItem aXFillTransparenceItem;
+ aXFillTransparenceItem.PutValue(*pXFillTransparenceItem, 0);
+ rToSet.Put(aXFillTransparenceItem);
+ }
+ else if (pColTrans &&
+ !pXFillFloatTransparenceItem && !pXFillFloatTransparenceNameItem)
+ {
+ // No fill transparency is given. On the other hand, we have a
+ // BackColorTransparency, so use that.
+ // tdf#90640 tdf#90130: this is necessary for LO 4.4.0 - 4.4.2
+ // that forgot to write draw:opacity into documents
+ // but: the value was *always* wrong for bitmaps! => ignore it
+ sal_Int8 nGraphicTransparency(0);
+ *pColTrans >>= nGraphicTransparency;
+ if (aXFillStyleItem.GetValue() != drawing::FillStyle_BITMAP)
+ {
+ rToSet.Put(XFillTransparenceItem(nGraphicTransparency));
+ }
+ if (aXFillStyleItem.GetValue() == drawing::FillStyle_SOLID)
+ {
+ aBrush->PutValue(*pColTrans, MID_BACK_COLOR_TRANSPARENCY);
+ setSvxBrushItemAsFillAttributesToTargetSet(*aBrush, rToSet);
+ }
+ }
+
+ if(pXGradientStepCountItem)
+ {
+ XGradientStepCountItem aXGradientStepCountItem;
+
+ aXGradientStepCountItem.PutValue(*pXGradientStepCountItem, 0);
+ rToSet.Put(aXGradientStepCountItem);
+ }
+
+ if(pXFillBmpPosItem)
+ {
+ XFillBmpPosItem aXFillBmpPosItem;
+
+ aXFillBmpPosItem.PutValue(*pXFillBmpPosItem, 0);
+ rToSet.Put(aXFillBmpPosItem);
+ }
+
+ if(pXFillBmpSizeXItem)
+ {
+ XFillBmpSizeXItem aXFillBmpSizeXItem;
+
+ aXFillBmpSizeXItem.PutValue(*pXFillBmpSizeXItem, 0);
+ rToSet.Put(aXFillBmpSizeXItem);
+ }
+
+ if(pXFillBmpSizeYItem)
+ {
+ XFillBmpSizeYItem aXFillBmpSizeYItem;
+
+ aXFillBmpSizeYItem.PutValue(*pXFillBmpSizeYItem, 0);
+ rToSet.Put(aXFillBmpSizeYItem);
+ }
+
+ if(pXFillFloatTransparenceItem || pXFillFloatTransparenceNameItem)
+ {
+ if(pXFillFloatTransparenceItem)
+ {
+ // basegfx::BGradient() default already creates [COL_BLACK, COL_WHITE] as defaults
+ const basegfx::BGradient aNullGrad;
+ XFillFloatTransparenceItem aXFillFloatTransparenceItem(aNullGrad, false);
+
+ aXFillFloatTransparenceItem.PutValue(*pXFillFloatTransparenceItem, MID_FILLGRADIENT);
+ rToSet.Put(aXFillFloatTransparenceItem);
+ }
+
+ if(pXFillFloatTransparenceNameItem)
+ {
+ OUString aTempName;
+
+ if(!(*pXFillFloatTransparenceNameItem >>= aTempName ))
+ {
+ throw lang::IllegalArgumentException();
+ }
+
+ bRet &= SvxShape::SetFillAttribute(XATTR_FILLFLOATTRANSPARENCE, aTempName, rToSet);
+ }
+ }
+
+ if(pXSecondaryFillColorItem)
+ {
+ const Color aNullCol(COL_DEFAULT_SHAPE_FILLING);
+ XSecondaryFillColorItem aXSecondaryFillColorItem(OUString(), aNullCol);
+
+ aXSecondaryFillColorItem.PutValue(*pXSecondaryFillColorItem, 0);
+ rToSet.Put(aXSecondaryFillColorItem);
+ }
+
+ if(pXFillBmpSizeLogItem)
+ {
+ XFillBmpSizeLogItem aXFillBmpSizeLogItem;
+
+ aXFillBmpSizeLogItem.PutValue(*pXFillBmpSizeLogItem, 0);
+ rToSet.Put(aXFillBmpSizeLogItem);
+ }
+
+ if(pXFillBmpTileOffsetXItem)
+ {
+ XFillBmpTileOffsetXItem aXFillBmpTileOffsetXItem;
+
+ aXFillBmpTileOffsetXItem.PutValue(*pXFillBmpTileOffsetXItem, 0);
+ rToSet.Put(aXFillBmpTileOffsetXItem);
+ }
+
+ if(pXFillBmpTileOffsetYItem)
+ {
+ XFillBmpTileOffsetYItem aXFillBmpTileOffsetYItem;
+
+ aXFillBmpTileOffsetYItem.PutValue(*pXFillBmpTileOffsetYItem, 0);
+ rToSet.Put(aXFillBmpTileOffsetYItem);
+ }
+
+ if(pXFillBmpPosOffsetXItem)
+ {
+ XFillBmpPosOffsetXItem aXFillBmpPosOffsetXItem;
+
+ aXFillBmpPosOffsetXItem.PutValue(*pXFillBmpPosOffsetXItem, 0);
+ rToSet.Put(aXFillBmpPosOffsetXItem);
+ }
+
+ if(pXFillBmpPosOffsetYItem)
+ {
+ XFillBmpPosOffsetYItem aXFillBmpPosOffsetYItem;
+
+ aXFillBmpPosOffsetYItem.PutValue(*pXFillBmpPosOffsetYItem, 0);
+ rToSet.Put(aXFillBmpPosOffsetYItem);
+ }
+
+ if(pXFillBackgroundItem)
+ {
+ XFillBackgroundItem aXFillBackgroundItem;
+
+ aXFillBackgroundItem.PutValue(*pXFillBackgroundItem, 0);
+ rToSet.Put(aXFillBackgroundItem);
+ }
+
+ if(pOwnAttrFillBmpItem)
+ {
+ drawing::BitmapMode eMode;
+
+ if(!(*pOwnAttrFillBmpItem >>= eMode))
+ {
+ sal_Int32 nMode = 0;
+
+ if(!(*pOwnAttrFillBmpItem >>= nMode))
+ {
+ throw lang::IllegalArgumentException();
+ }
+
+ eMode = static_cast<drawing::BitmapMode>(nMode);
+ }
+
+ rToSet.Put(XFillBmpStretchItem(drawing::BitmapMode_STRETCH == eMode));
+ rToSet.Put(XFillBmpTileItem(drawing::BitmapMode_REPEAT == eMode));
+ }
+ }
+ {
+ const ::uno::Any* pCont = nullptr;
+ GetProperty(RES_PROTECT, MID_PROTECT_CONTENT, pCont );
+ const ::uno::Any* pPos = nullptr;
+ GetProperty(RES_PROTECT,MID_PROTECT_POSITION, pPos );
+ const ::uno::Any* pName = nullptr;
+ GetProperty(RES_PROTECT, MID_PROTECT_SIZE, pName );
+ if(pCont||pPos||pName)
+ {
+ SvxProtectItem aProt ( rFromSet.Get ( RES_PROTECT ) );
+ if(pCont)
+ bRet &= static_cast<SfxPoolItem&>(aProt).PutValue(*pCont, MID_PROTECT_CONTENT);
+ if(pPos )
+ bRet &= static_cast<SfxPoolItem&>(aProt).PutValue(*pPos, MID_PROTECT_POSITION);
+ if(pName)
+ bRet &= static_cast<SfxPoolItem&>(aProt).PutValue(*pName, MID_PROTECT_SIZE);
+ rToSet.Put(aProt);
+ }
+ }
+ {
+ const ::uno::Any* pHori = nullptr;
+ GetProperty(RES_HORI_ORIENT, MID_HORIORIENT_ORIENT, pHori );
+ const ::uno::Any* pHoriP = nullptr;
+ GetProperty(RES_HORI_ORIENT, MID_HORIORIENT_POSITION|CONVERT_TWIPS, pHoriP );
+ const ::uno::Any* pHoriR = nullptr;
+ GetProperty(RES_HORI_ORIENT, MID_HORIORIENT_RELATION, pHoriR );
+ const ::uno::Any* pPageT = nullptr;
+ GetProperty(RES_HORI_ORIENT, MID_HORIORIENT_PAGETOGGLE, pPageT);
+ if(pHori||pHoriP||pHoriR||pPageT)
+ {
+ SwFormatHoriOrient aOrient ( rFromSet.Get ( RES_HORI_ORIENT ) );
+ if(pHori )
+ bRet &= static_cast<SfxPoolItem&>(aOrient).PutValue(*pHori, MID_HORIORIENT_ORIENT);
+ if(pHoriP)
+ bRet &= static_cast<SfxPoolItem&>(aOrient).PutValue(*pHoriP, MID_HORIORIENT_POSITION|CONVERT_TWIPS);
+ if(pHoriR)
+ bRet &= static_cast<SfxPoolItem&>(aOrient).PutValue(*pHoriR, MID_HORIORIENT_RELATION);
+ if(pPageT)
+ bRet &= static_cast<SfxPoolItem&>(aOrient).PutValue(*pPageT, MID_HORIORIENT_PAGETOGGLE);
+ rToSet.Put(aOrient);
+ }
+ }
+
+ {
+ const ::uno::Any* pVert = nullptr;
+ GetProperty(RES_VERT_ORIENT, MID_VERTORIENT_ORIENT, pVert);
+ const ::uno::Any* pVertP = nullptr;
+ GetProperty(RES_VERT_ORIENT, MID_VERTORIENT_POSITION|CONVERT_TWIPS, pVertP );
+ const ::uno::Any* pVertR = nullptr;
+ GetProperty(RES_VERT_ORIENT, MID_VERTORIENT_RELATION, pVertR );
+ if(pVert||pVertP||pVertR)
+ {
+ SwFormatVertOrient aOrient ( rFromSet.Get ( RES_VERT_ORIENT ) );
+ if(pVert )
+ bRet &= static_cast<SfxPoolItem&>(aOrient).PutValue(*pVert, MID_VERTORIENT_ORIENT);
+ if(pVertP)
+ bRet &= static_cast<SfxPoolItem&>(aOrient).PutValue(*pVertP, MID_VERTORIENT_POSITION|CONVERT_TWIPS);
+ if(pVertR)
+ bRet &= static_cast<SfxPoolItem&>(aOrient).PutValue(*pVertR, MID_VERTORIENT_RELATION);
+ rToSet.Put(aOrient);
+ }
+ }
+ {
+ const ::uno::Any* pURL = nullptr;
+ GetProperty(RES_URL, MID_URL_URL, pURL );
+ const ::uno::Any* pTarget = nullptr;
+ GetProperty(RES_URL, MID_URL_TARGET, pTarget );
+ const ::uno::Any* pHyLNm = nullptr;
+ GetProperty(RES_URL, MID_URL_HYPERLINKNAME, pHyLNm );
+ const ::uno::Any* pHySMp = nullptr;
+ GetProperty(RES_URL, MID_URL_SERVERMAP, pHySMp );
+ if(pURL||pTarget||pHyLNm||pHySMp)
+ {
+ SwFormatURL aURL ( rFromSet.Get ( RES_URL ) );
+ if(pURL)
+ bRet &= static_cast<SfxPoolItem&>(aURL).PutValue(*pURL, MID_URL_URL);
+ if(pTarget)
+ bRet &= static_cast<SfxPoolItem&>(aURL).PutValue(*pTarget, MID_URL_TARGET);
+ if(pHyLNm)
+ bRet &= static_cast<SfxPoolItem&>(aURL).PutValue(*pHyLNm, MID_URL_HYPERLINKNAME );
+ if(pHySMp)
+ bRet &= static_cast<SfxPoolItem&>(aURL).PutValue(*pHySMp, MID_URL_SERVERMAP);
+ rToSet.Put(aURL);
+ }
+ }
+ const ::uno::Any* pL = nullptr;
+ GetProperty(RES_LR_SPACE, MID_L_MARGIN|CONVERT_TWIPS, pL );
+ const ::uno::Any* pR = nullptr;
+ GetProperty(RES_LR_SPACE, MID_R_MARGIN|CONVERT_TWIPS, pR );
+ if(pL||pR)
+ {
+ SvxLRSpaceItem aLR ( rFromSet.Get ( RES_LR_SPACE ) );
+ if(pL)
+ bRet &= static_cast<SfxPoolItem&>(aLR).PutValue(*pL, MID_L_MARGIN|CONVERT_TWIPS);
+ if(pR)
+ bRet &= static_cast<SfxPoolItem&>(aLR).PutValue(*pR, MID_R_MARGIN|CONVERT_TWIPS);
+ rToSet.Put(aLR);
+ }
+ const ::uno::Any* pT = nullptr;
+ GetProperty(RES_UL_SPACE, MID_UP_MARGIN|CONVERT_TWIPS, pT );
+ const ::uno::Any* pB = nullptr;
+ GetProperty(RES_UL_SPACE, MID_LO_MARGIN|CONVERT_TWIPS, pB );
+ if(pT||pB)
+ {
+ SvxULSpaceItem aTB ( rFromSet.Get ( RES_UL_SPACE ) );
+ if(pT)
+ bRet &= static_cast<SfxPoolItem&>(aTB).PutValue(*pT, MID_UP_MARGIN|CONVERT_TWIPS);
+ if(pB)
+ bRet &= static_cast<SfxPoolItem&>(aTB).PutValue(*pB, MID_LO_MARGIN|CONVERT_TWIPS);
+ rToSet.Put(aTB);
+ }
+ const ::uno::Any* pOp;
+ if(GetProperty(RES_OPAQUE, 0, pOp))
+ {
+ SvxOpaqueItem aOp ( rFromSet.Get ( RES_OPAQUE ) );
+ bRet &= static_cast<SfxPoolItem&>(aOp).PutValue(*pOp, 0);
+ rToSet.Put(aOp);
+ }
+ const ::uno::Any* pPrt;
+ if(GetProperty(RES_PRINT, 0, pPrt))
+ {
+ SvxPrintItem aPrt ( rFromSet.Get ( RES_PRINT ) );
+ bRet &= static_cast<SfxPoolItem&>(aPrt).PutValue(*pPrt, 0);
+ rToSet.Put(aPrt);
+ }
+ const ::uno::Any* pSh;
+ if(GetProperty(RES_SHADOW, CONVERT_TWIPS, pSh))
+ {
+ SvxShadowItem aSh ( rFromSet.Get ( RES_SHADOW ) );
+ bRet &= static_cast<SfxPoolItem&>(aSh).PutValue(*pSh, CONVERT_TWIPS);
+ rToSet.Put(aSh);
+ }
+ const ::uno::Any* pShTr;
+ if(GetProperty(RES_SHADOW, MID_SHADOW_TRANSPARENCE, pShTr) && rToSet.HasItem(RES_SHADOW))
+ {
+ SvxShadowItem aSh(rToSet.Get(RES_SHADOW));
+ bRet &= aSh.PutValue(*pShTr, MID_SHADOW_TRANSPARENCE);
+ rToSet.Put(aSh);
+ }
+ const ::uno::Any* pSur = nullptr;
+ GetProperty(RES_SURROUND, MID_SURROUND_SURROUNDTYPE, pSur);
+ const ::uno::Any* pSurCont = nullptr;
+ GetProperty(RES_SURROUND, MID_SURROUND_CONTOUR, pSurCont);
+ const ::uno::Any* pSurAnch = nullptr;
+ GetProperty(RES_SURROUND, MID_SURROUND_ANCHORONLY, pSurAnch);
+ if(pSur || pSurAnch)
+ {
+ SwFormatSurround aSrnd ( rFromSet.Get ( RES_SURROUND ) );
+ if(pSur)
+ bRet &= static_cast<SfxPoolItem&>(aSrnd).PutValue(*pSur, MID_SURROUND_SURROUNDTYPE);
+ if(pSurCont)
+ bRet &= static_cast<SfxPoolItem&>(aSrnd).PutValue(*pSurCont, MID_SURROUND_CONTOUR);
+ if(pSurAnch)
+ bRet &= static_cast<SfxPoolItem&>(aSrnd).PutValue(*pSurAnch, MID_SURROUND_ANCHORONLY);
+ rToSet.Put(aSrnd);
+ }
+ const ::uno::Any* pLeft = nullptr;
+ GetProperty(RES_BOX, LEFT_BORDER |CONVERT_TWIPS, pLeft );
+ const ::uno::Any* pRight = nullptr;
+ GetProperty(RES_BOX, CONVERT_TWIPS|RIGHT_BORDER , pRight );
+ const ::uno::Any* pTop = nullptr;
+ GetProperty(RES_BOX, CONVERT_TWIPS|TOP_BORDER , pTop );
+ const ::uno::Any* pBottom = nullptr;
+ GetProperty(RES_BOX, CONVERT_TWIPS|BOTTOM_BORDER, pBottom);
+ const ::uno::Any* pDistance = nullptr;
+ GetProperty(RES_BOX, CONVERT_TWIPS|BORDER_DISTANCE, pDistance);
+ const ::uno::Any* pLeftDistance = nullptr;
+ GetProperty(RES_BOX, CONVERT_TWIPS|LEFT_BORDER_DISTANCE, pLeftDistance);
+ const ::uno::Any* pRightDistance = nullptr;
+ GetProperty(RES_BOX, CONVERT_TWIPS|RIGHT_BORDER_DISTANCE, pRightDistance);
+ const ::uno::Any* pTopDistance = nullptr;
+ GetProperty(RES_BOX, CONVERT_TWIPS|TOP_BORDER_DISTANCE, pTopDistance);
+ const ::uno::Any* pBottomDistance = nullptr;
+ GetProperty(RES_BOX, CONVERT_TWIPS|BOTTOM_BORDER_DISTANCE, pBottomDistance);
+ const ::uno::Any* pLineStyle = nullptr;
+ GetProperty(RES_BOX, LINE_STYLE, pLineStyle);
+ const ::uno::Any* pLineWidth = nullptr;
+ GetProperty(RES_BOX, LINE_WIDTH, pLineWidth);
+ if( pLeft || pRight || pTop || pBottom || pDistance ||
+ pLeftDistance || pRightDistance || pTopDistance || pBottomDistance ||
+ pLineStyle || pLineWidth )
+ {
+ SvxBoxItem aBox ( rFromSet.Get ( RES_BOX ) );
+ if( pLeft )
+ bRet &= static_cast<SfxPoolItem&>(aBox).PutValue(*pLeft, CONVERT_TWIPS|LEFT_BORDER );
+ if( pRight )
+ bRet &= static_cast<SfxPoolItem&>(aBox).PutValue(*pRight, CONVERT_TWIPS|RIGHT_BORDER );
+ if( pTop )
+ bRet &= static_cast<SfxPoolItem&>(aBox).PutValue(*pTop, CONVERT_TWIPS|TOP_BORDER);
+ if( pBottom )
+ bRet &= static_cast<SfxPoolItem&>(aBox).PutValue(*pBottom, CONVERT_TWIPS|BOTTOM_BORDER);
+ if( pDistance )
+ bRet &= static_cast<SfxPoolItem&>(aBox).PutValue(*pDistance, CONVERT_TWIPS|BORDER_DISTANCE);
+ if( pLeftDistance )
+ bRet &= static_cast<SfxPoolItem&>(aBox).PutValue(*pLeftDistance, CONVERT_TWIPS|LEFT_BORDER_DISTANCE);
+ if( pRightDistance )
+ bRet &= static_cast<SfxPoolItem&>(aBox).PutValue(*pRightDistance, CONVERT_TWIPS|RIGHT_BORDER_DISTANCE);
+ if( pTopDistance )
+ bRet &= static_cast<SfxPoolItem&>(aBox).PutValue(*pTopDistance, CONVERT_TWIPS|TOP_BORDER_DISTANCE);
+ if( pBottomDistance )
+ bRet &= static_cast<SfxPoolItem&>(aBox).PutValue(*pBottomDistance, CONVERT_TWIPS|BOTTOM_BORDER_DISTANCE);
+ if( pLineStyle )
+ bRet &= static_cast<SfxPoolItem&>(aBox).PutValue(*pLineStyle, LINE_STYLE);
+ if( pLineWidth )
+ bRet &= static_cast<SfxPoolItem&>(aBox).PutValue(*pLineWidth, LINE_WIDTH|CONVERT_TWIPS);
+ rToSet.Put(aBox);
+ }
+ {
+ const ::uno::Any* pRelH = nullptr;
+ GetProperty(RES_FRM_SIZE, MID_FRMSIZE_REL_HEIGHT, pRelH);
+ const ::uno::Any* pRelHRelation = nullptr;
+ GetProperty(RES_FRM_SIZE, MID_FRMSIZE_REL_HEIGHT_RELATION, pRelHRelation);
+ const ::uno::Any* pRelW = nullptr;
+ GetProperty(RES_FRM_SIZE, MID_FRMSIZE_REL_WIDTH, pRelW);
+ const ::uno::Any* pRelWRelation = nullptr;
+ GetProperty(RES_FRM_SIZE, MID_FRMSIZE_REL_WIDTH_RELATION, pRelWRelation);
+ const ::uno::Any* pSyncWidth = nullptr;
+ GetProperty(RES_FRM_SIZE, MID_FRMSIZE_IS_SYNC_WIDTH_TO_HEIGHT, pSyncWidth);
+ const ::uno::Any* pSyncHeight = nullptr;
+ GetProperty(RES_FRM_SIZE, MID_FRMSIZE_IS_SYNC_HEIGHT_TO_WIDTH, pSyncHeight);
+ const ::uno::Any* pWidth = nullptr;
+ GetProperty(RES_FRM_SIZE, MID_FRMSIZE_WIDTH|CONVERT_TWIPS, pWidth);
+ const ::uno::Any* pHeight = nullptr;
+ GetProperty(RES_FRM_SIZE, MID_FRMSIZE_HEIGHT|CONVERT_TWIPS, pHeight);
+ const ::uno::Any* pSize = nullptr;
+ GetProperty(RES_FRM_SIZE, MID_FRMSIZE_SIZE|CONVERT_TWIPS, pSize);
+ const ::uno::Any* pSizeType = nullptr;
+ GetProperty(RES_FRM_SIZE, MID_FRMSIZE_SIZE_TYPE, pSizeType);
+ const ::uno::Any* pWidthType = nullptr;
+ GetProperty(RES_FRM_SIZE, MID_FRMSIZE_WIDTH_TYPE, pWidthType);
+ if( pWidth || pHeight ||pRelH || pRelHRelation || pRelW || pRelWRelation || pSize ||pSizeType ||
+ pWidthType ||pSyncWidth || pSyncHeight )
+ {
+ rSizeFound = true;
+ SwFormatFrameSize aFrameSz ( rFromSet.Get ( RES_FRM_SIZE ) );
+ if(pWidth)
+ bRet &= static_cast<SfxPoolItem&>(aFrameSz).PutValue(*pWidth, MID_FRMSIZE_WIDTH|CONVERT_TWIPS);
+ if(pHeight)
+ bRet &= static_cast<SfxPoolItem&>(aFrameSz).PutValue(*pHeight, MID_FRMSIZE_HEIGHT|CONVERT_TWIPS);
+ if(pRelH )
+ bRet &= static_cast<SfxPoolItem&>(aFrameSz).PutValue(*pRelH, MID_FRMSIZE_REL_HEIGHT);
+ if (pRelHRelation)
+ bRet &= aFrameSz.PutValue(*pRelHRelation, MID_FRMSIZE_REL_HEIGHT_RELATION);
+ if(pRelW )
+ bRet &= static_cast<SfxPoolItem&>(aFrameSz).PutValue(*pRelW, MID_FRMSIZE_REL_WIDTH);
+ if (pRelWRelation)
+ bRet &= aFrameSz.PutValue(*pRelWRelation, MID_FRMSIZE_REL_WIDTH_RELATION);
+ if(pSyncWidth)
+ bRet &= static_cast<SfxPoolItem&>(aFrameSz).PutValue(*pSyncWidth, MID_FRMSIZE_IS_SYNC_WIDTH_TO_HEIGHT);
+ if(pSyncHeight)
+ bRet &= static_cast<SfxPoolItem&>(aFrameSz).PutValue(*pSyncHeight, MID_FRMSIZE_IS_SYNC_HEIGHT_TO_WIDTH);
+ if(pSize)
+ bRet &= static_cast<SfxPoolItem&>(aFrameSz).PutValue(*pSize, MID_FRMSIZE_SIZE|CONVERT_TWIPS);
+ if(pSizeType)
+ bRet &= static_cast<SfxPoolItem&>(aFrameSz).PutValue(*pSizeType, MID_FRMSIZE_SIZE_TYPE);
+ if(pWidthType)
+ bRet &= static_cast<SfxPoolItem&>(aFrameSz).PutValue(*pWidthType, MID_FRMSIZE_WIDTH_TYPE);
+ if(!aFrameSz.GetWidth())
+ aFrameSz.SetWidth(MINFLY);
+ if(!aFrameSz.GetHeight())
+ aFrameSz.SetHeight(MINFLY);
+ rToSet.Put(aFrameSz);
+ }
+ else
+ {
+ rSizeFound = false;
+ SwFormatFrameSize aFrameSz;
+ constexpr sal_Int32 constTwips_1cm = o3tl::toTwips(1, o3tl::Length::cm);
+ awt::Size aSize;
+ aSize.Width = constTwips_1cm;
+ aSize.Height = constTwips_1cm;
+ ::uno::Any aSizeVal;
+ aSizeVal <<= aSize;
+ static_cast<SfxPoolItem&>(aFrameSz).PutValue(aSizeVal, MID_FRMSIZE_SIZE|CONVERT_TWIPS);
+ rToSet.Put(aFrameSz);
+ }
+ }
+ const ::uno::Any* pFrameDirection = nullptr;
+ GetProperty(RES_FRAMEDIR, 0, pFrameDirection);
+ if(pFrameDirection)
+ {
+ SvxFrameDirectionItem aAttr(SvxFrameDirection::Horizontal_LR_TB, RES_FRAMEDIR);
+ aAttr.PutValue(*pFrameDirection, 0);
+ rToSet.Put(aAttr);
+ }
+ const ::uno::Any* pUnknown = nullptr;
+ GetProperty(RES_UNKNOWNATR_CONTAINER, 0, pUnknown);
+ if(pUnknown)
+ {
+ SvXMLAttrContainerItem aAttr(RES_UNKNOWNATR_CONTAINER);
+ aAttr.PutValue(*pUnknown, 0);
+ rToSet.Put(aAttr);
+ }
+
+ // #i18732#
+ const ::uno::Any* pFollowTextFlow = nullptr;
+ GetProperty(RES_FOLLOW_TEXT_FLOW, MID_FOLLOW_TEXT_FLOW, pFollowTextFlow);
+
+ if (pFollowTextFlow)
+ {
+ SwFormatFollowTextFlow aFormatFollowTextFlow;
+ if( pFollowTextFlow )
+ {
+ aFormatFollowTextFlow.PutValue(*pFollowTextFlow, MID_FOLLOW_TEXT_FLOW);
+ }
+
+ rToSet.Put(aFormatFollowTextFlow);
+ }
+
+ // #i28701# - RES_WRAP_INFLUENCE_ON_OBJPOS
+ const ::uno::Any* pWrapInfluenceOnObjPos = nullptr;
+ GetProperty(RES_WRAP_INFLUENCE_ON_OBJPOS, MID_WRAP_INFLUENCE, pWrapInfluenceOnObjPos);
+ const ::uno::Any* pAllowOverlap = nullptr;
+ GetProperty(RES_WRAP_INFLUENCE_ON_OBJPOS, MID_ALLOW_OVERLAP, pAllowOverlap);
+ if ( pWrapInfluenceOnObjPos || pAllowOverlap )
+ {
+ SwFormatWrapInfluenceOnObjPos aFormatWrapInfluenceOnObjPos;
+ if (pWrapInfluenceOnObjPos)
+ aFormatWrapInfluenceOnObjPos.PutValue( *pWrapInfluenceOnObjPos, MID_WRAP_INFLUENCE );
+ if (pAllowOverlap)
+ aFormatWrapInfluenceOnObjPos.PutValue( *pAllowOverlap, MID_ALLOW_OVERLAP );
+ rToSet.Put(aFormatWrapInfluenceOnObjPos);
+ }
+
+ {
+ const ::uno::Any* pTextVertAdjust = nullptr;
+ GetProperty(RES_TEXT_VERT_ADJUST, 0, pTextVertAdjust);
+ if ( pTextVertAdjust )
+ {
+ SdrTextVertAdjustItem aTextVertAdjust( rFromSet.Get ( RES_TEXT_VERT_ADJUST ) );
+ bRet &= static_cast<SfxPoolItem&>(aTextVertAdjust).PutValue(*pTextVertAdjust, 0);
+ rToSet.Put(aTextVertAdjust);
+ }
+ }
+
+ const ::uno::Any* pDecorative = nullptr;
+ GetProperty(RES_DECORATIVE, 0, pDecorative);
+ if (pDecorative)
+ {
+ SfxBoolItem item(RES_DECORATIVE);
+ bRet &= item.PutValue(*pDecorative, 0);
+ rToSet.Put(item);
+ }
+
+ const ::uno::Any* pFlySplit = nullptr;
+ GetProperty(RES_FLY_SPLIT, 0, pFlySplit);
+ if (pFlySplit)
+ {
+ SwFormatFlySplit aSplit(true);
+ bRet &= aSplit.PutValue(*pFlySplit, 0);
+ rToSet.Put(aSplit);
+ }
+
+ const ::uno::Any* pWrapTextAtFlyStart = nullptr;
+ GetProperty(RES_WRAP_TEXT_AT_FLY_START, 0, pWrapTextAtFlyStart);
+ if (pWrapTextAtFlyStart)
+ {
+ SwFormatWrapTextAtFlyStart aWrapTextAtFlyStart(true);
+ bRet &= aWrapTextAtFlyStart.PutValue(*pWrapTextAtFlyStart, 0);
+ rToSet.Put(aWrapTextAtFlyStart);
+ }
+
+ return bRet;
+}
+
+namespace {
+
+class SwFrameProperties_Impl : public BaseFrameProperties_Impl
+{
+public:
+ SwFrameProperties_Impl();
+
+ bool AnyToItemSet( SwDoc* pDoc, SfxItemSet& rFrameSet, SfxItemSet& rSet, bool& rSizeFound) override;
+};
+
+}
+
+SwFrameProperties_Impl::SwFrameProperties_Impl():
+ BaseFrameProperties_Impl(/*aSwMapProvider.GetPropertyMap(PROPERTY_MAP_TEXT_FRAME)*/ )
+{
+}
+
+static void lcl_FillCol ( SfxItemSet &rToSet, const ::SfxItemSet &rFromSet, const ::uno::Any *pAny)
+{
+ if ( pAny )
+ {
+ SwFormatCol aCol ( rFromSet.Get ( RES_COL ) );
+ static_cast<SfxPoolItem&>(aCol).PutValue( *pAny, MID_COLUMNS);
+ rToSet.Put(aCol);
+ }
+}
+
+bool SwFrameProperties_Impl::AnyToItemSet(SwDoc *pDoc, SfxItemSet& rSet, SfxItemSet&, bool& rSizeFound)
+{
+ // Properties for all frames
+ const ::uno::Any *pStyleName;
+ SwDocStyleSheet* pStyle = nullptr;
+ bool bRet;
+
+ if ( GetProperty ( FN_UNO_FRAME_STYLE_NAME, 0, pStyleName ) )
+ {
+ OUString sStyle;
+ *pStyleName >>= sStyle;
+ SwStyleNameMapper::FillUIName(sStyle, sStyle, SwGetPoolIdFromName::FrmFmt);
+ pStyle = static_cast<SwDocStyleSheet*>(pDoc->GetDocShell()->GetStyleSheetPool()->Find(sStyle,
+ SfxStyleFamily::Frame));
+ }
+
+ const ::uno::Any* pColumns = nullptr;
+ GetProperty (RES_COL, MID_COLUMNS, pColumns);
+ if ( pStyle )
+ {
+ rtl::Reference< SwDocStyleSheet > xStyle( new SwDocStyleSheet( *pStyle ) );
+ const ::SfxItemSet *pItemSet = &xStyle->GetItemSet();
+ bRet = FillBaseProperties( rSet, *pItemSet, rSizeFound );
+ lcl_FillCol ( rSet, *pItemSet, pColumns );
+ }
+ else
+ {
+ const ::SfxItemSet *pItemSet = &pDoc->getIDocumentStylePoolAccess().GetFrameFormatFromPool( RES_POOLFRM_FRAME )->GetAttrSet();
+ bRet = FillBaseProperties( rSet, *pItemSet, rSizeFound );
+ lcl_FillCol ( rSet, *pItemSet, pColumns );
+ }
+ const ::uno::Any* pEdit;
+ if(GetProperty(RES_EDIT_IN_READONLY, 0, pEdit))
+ {
+ SwFormatEditInReadonly item(RES_EDIT_IN_READONLY);
+ item.PutValue(*pEdit, 0);
+ rSet.Put(item);
+ }
+ return bRet;
+}
+
+namespace {
+
+class SwGraphicProperties_Impl : public BaseFrameProperties_Impl
+{
+public:
+ SwGraphicProperties_Impl();
+
+ virtual bool AnyToItemSet( SwDoc* pDoc, SfxItemSet& rFrameSet, SfxItemSet& rSet, bool& rSizeFound) override;
+};
+
+}
+
+SwGraphicProperties_Impl::SwGraphicProperties_Impl( ) :
+ BaseFrameProperties_Impl(/*aSwMapProvider.GetPropertyMap(PROPERTY_MAP_TEXT_GRAPHIC)*/ )
+{
+}
+
+static void lcl_FillMirror ( SfxItemSet &rToSet, const ::SfxItemSet &rFromSet, const ::uno::Any *pHEvenMirror, const ::uno::Any *pHOddMirror, const ::uno::Any *pVMirror, bool &rRet )
+{
+ if(pHEvenMirror || pHOddMirror || pVMirror )
+ {
+ SwMirrorGrf aMirror ( rFromSet.Get ( RES_GRFATR_MIRRORGRF ) );
+ if(pHEvenMirror)
+ rRet &= static_cast<SfxPoolItem&>(aMirror).PutValue(*pHEvenMirror, MID_MIRROR_HORZ_EVEN_PAGES);
+ if(pHOddMirror)
+ rRet &= static_cast<SfxPoolItem&>(aMirror).PutValue(*pHOddMirror, MID_MIRROR_HORZ_ODD_PAGES);
+ if(pVMirror)
+ rRet &= static_cast<SfxPoolItem&>(aMirror).PutValue(*pVMirror, MID_MIRROR_VERT);
+ rToSet.Put(aMirror);
+ }
+}
+
+bool SwGraphicProperties_Impl::AnyToItemSet(
+ SwDoc* pDoc,
+ SfxItemSet& rFrameSet,
+ SfxItemSet& rGrSet,
+ bool& rSizeFound)
+{
+ // Properties for all frames
+ bool bRet;
+ const ::uno::Any *pStyleName;
+ SwDocStyleSheet* pStyle = nullptr;
+
+ if ( GetProperty ( FN_UNO_FRAME_STYLE_NAME, 0, pStyleName ) )
+ {
+ OUString sStyle;
+ *pStyleName >>= sStyle;
+ SwStyleNameMapper::FillUIName(sStyle, sStyle, SwGetPoolIdFromName::FrmFmt);
+ pStyle = static_cast<SwDocStyleSheet*>(pDoc->GetDocShell()->GetStyleSheetPool()->Find(sStyle,
+ SfxStyleFamily::Frame));
+ }
+
+ const ::uno::Any* pHEvenMirror = nullptr;
+ const ::uno::Any* pHOddMirror = nullptr;
+ const ::uno::Any* pVMirror = nullptr;
+ GetProperty(RES_GRFATR_MIRRORGRF, MID_MIRROR_HORZ_EVEN_PAGES, pHEvenMirror);
+ GetProperty(RES_GRFATR_MIRRORGRF, MID_MIRROR_HORZ_ODD_PAGES, pHOddMirror);
+ GetProperty(RES_GRFATR_MIRRORGRF, MID_MIRROR_VERT, pVMirror);
+
+ if ( pStyle )
+ {
+ rtl::Reference< SwDocStyleSheet > xStyle( new SwDocStyleSheet(*pStyle) );
+ const ::SfxItemSet *pItemSet = &xStyle->GetItemSet();
+ bRet = FillBaseProperties(rFrameSet, *pItemSet, rSizeFound);
+ lcl_FillMirror ( rGrSet, *pItemSet, pHEvenMirror, pHOddMirror, pVMirror, bRet );
+ }
+ else
+ {
+ const ::SfxItemSet *pItemSet = &pDoc->getIDocumentStylePoolAccess().GetFrameFormatFromPool( RES_POOLFRM_GRAPHIC )->GetAttrSet();
+ bRet = FillBaseProperties(rFrameSet, *pItemSet, rSizeFound);
+ lcl_FillMirror ( rGrSet, *pItemSet, pHEvenMirror, pHOddMirror, pVMirror, bRet );
+ }
+
+ static const ::sal_uInt16 nIDs[] =
+ {
+ RES_GRFATR_CROPGRF,
+ RES_GRFATR_ROTATION,
+ RES_GRFATR_LUMINANCE,
+ RES_GRFATR_CONTRAST,
+ RES_GRFATR_CHANNELR,
+ RES_GRFATR_CHANNELG,
+ RES_GRFATR_CHANNELB,
+ RES_GRFATR_GAMMA,
+ RES_GRFATR_INVERT,
+ RES_GRFATR_TRANSPARENCY,
+ RES_GRFATR_DRAWMODE,
+ 0
+ };
+ const ::uno::Any* pAny;
+ for(sal_Int16 nIndex = 0; nIDs[nIndex]; nIndex++)
+ {
+ sal_uInt8 nMId = RES_GRFATR_CROPGRF == nIDs[nIndex] ? CONVERT_TWIPS : 0;
+ if(GetProperty(nIDs[nIndex], nMId, pAny ))
+ {
+ std::unique_ptr<SfxPoolItem> pItem(::GetDfltAttr( nIDs[nIndex] )->Clone());
+ bRet &= pItem->PutValue(*pAny, nMId );
+ rGrSet.Put(std::move(pItem));
+ }
+ }
+
+ return bRet;
+}
+
+namespace {
+
+class SwOLEProperties_Impl : public SwFrameProperties_Impl
+{
+public:
+ SwOLEProperties_Impl() {}
+
+ virtual bool AnyToItemSet( SwDoc* pDoc, SfxItemSet& rFrameSet, SfxItemSet& rSet, bool& rSizeFound) override;
+};
+
+}
+
+bool SwOLEProperties_Impl::AnyToItemSet(
+ SwDoc* pDoc, SfxItemSet& rFrameSet, SfxItemSet& rSet, bool& rSizeFound)
+{
+ const ::uno::Any* pTemp;
+ if(!GetProperty(FN_UNO_CLSID, 0, pTemp) && !GetProperty(FN_UNO_STREAM_NAME, 0, pTemp)
+ && !GetProperty(FN_EMBEDDED_OBJECT, 0, pTemp)
+ && !GetProperty(FN_UNO_VISIBLE_AREA_WIDTH, 0, pTemp)
+ && !GetProperty(FN_UNO_VISIBLE_AREA_HEIGHT, 0, pTemp) )
+ return false;
+ SwFrameProperties_Impl::AnyToItemSet( pDoc, rFrameSet, rSet, rSizeFound);
+
+ return true;
+}
+
+class SwXFrame::Impl
+{
+public:
+ uno::WeakReference<uno::XInterface> m_wThis;
+ std::mutex m_Mutex; // just for OInterfaceContainerHelper4
+ ::comphelper::OInterfaceContainerHelper4<css::lang::XEventListener> m_EventListeners;
+};
+
+OUString SwXFrame::getImplementationName()
+{
+ return "SwXFrame";
+}
+
+sal_Bool SwXFrame::supportsService(const OUString& rServiceName)
+{
+ return cppu::supportsService(this, rServiceName);
+}
+
+uno::Sequence< OUString > SwXFrame::getSupportedServiceNames()
+{
+ return { "com.sun.star.text.BaseFrame", "com.sun.star.text.TextContent", "com.sun.star.document.LinkTarget" };
+}
+
+SwXFrame::SwXFrame(FlyCntType eSet, const ::SfxItemPropertySet* pSet, SwDoc *pDoc)
+ : m_pImpl(new Impl)
+ , m_pFrameFormat(nullptr)
+ , m_pPropSet(pSet)
+ , m_pDoc(pDoc)
+ , m_eType(eSet)
+ , m_bIsDescriptor(true)
+ , m_nDrawAspect(embed::Aspects::MSOLE_CONTENT)
+ , m_nVisibleAreaWidth(0)
+ , m_nVisibleAreaHeight(0)
+{
+ // Register ourselves as a listener to the document (via the page descriptor)
+ StartListening(pDoc->getIDocumentStylePoolAccess().GetPageDescFromPool(RES_POOLPAGE_STANDARD)->GetNotifier());
+ // get the property set for the default style data
+ // First get the model
+ uno::Reference < XModel > xModel = pDoc->GetDocShell()->GetBaseModel();
+ // Ask the model for its family supplier interface
+ uno::Reference < XStyleFamiliesSupplier > xFamilySupplier ( xModel, uno::UNO_QUERY );
+ // Get the style families
+ uno::Reference < XNameAccess > xFamilies = xFamilySupplier->getStyleFamilies();
+ // Get the Frame family (and keep it for later)
+ const ::uno::Any aAny = xFamilies->getByName ("FrameStyles");
+ aAny >>= mxStyleFamily;
+ // In the derived class, we'll ask mxStyleFamily for the relevant default style
+ // mxStyleFamily is initialised in the SwXFrame constructor
+ switch(m_eType)
+ {
+ case FLYCNTTYPE_FRM:
+ {
+ uno::Any aAny2 = mxStyleFamily->getByName ("Frame");
+ aAny2 >>= mxStyleData;
+ m_pProps.reset(new SwFrameProperties_Impl);
+ }
+ break;
+ case FLYCNTTYPE_GRF:
+ {
+ uno::Any aAny2 = mxStyleFamily->getByName ("Graphics");
+ aAny2 >>= mxStyleData;
+ m_pProps.reset(new SwGraphicProperties_Impl);
+ }
+ break;
+ case FLYCNTTYPE_OLE:
+ {
+ uno::Any aAny2 = mxStyleFamily->getByName ("OLE");
+ aAny2 >>= mxStyleData;
+ m_pProps.reset(new SwOLEProperties_Impl);
+ }
+ break;
+
+ default:
+ m_pProps.reset();
+ break;
+ }
+}
+
+SwXFrame::SwXFrame(SwFrameFormat& rFrameFormat, FlyCntType eSet, const ::SfxItemPropertySet* pSet)
+ : m_pImpl(new Impl)
+ , m_pFrameFormat(&rFrameFormat)
+ , m_pPropSet(pSet)
+ , m_pDoc(nullptr)
+ , m_eType(eSet)
+ , m_bIsDescriptor(false)
+ , m_nDrawAspect(embed::Aspects::MSOLE_CONTENT)
+ , m_nVisibleAreaWidth(0)
+ , m_nVisibleAreaHeight(0)
+{
+ StartListening(rFrameFormat.GetNotifier());
+}
+
+SwXFrame::~SwXFrame()
+{
+ SolarMutexGuard aGuard;
+ m_pProps.reset();
+ EndListeningAll();
+}
+
+template<class NameLookupIsHard>
+rtl::Reference<NameLookupIsHard>
+SwXFrame::CreateXFrame(SwDoc & rDoc, SwFrameFormat *const pFrameFormat)
+{
+ assert(!pFrameFormat || &rDoc == pFrameFormat->GetDoc());
+ rtl::Reference<NameLookupIsHard> xFrame;
+ if (pFrameFormat)
+ {
+ xFrame = dynamic_cast<NameLookupIsHard*>(pFrameFormat->GetXObject().get().get()); // cached?
+ }
+ if (!xFrame.is())
+ {
+ xFrame = pFrameFormat
+ ? new NameLookupIsHard(*pFrameFormat)
+ : new NameLookupIsHard(&rDoc);
+ if (pFrameFormat)
+ {
+ pFrameFormat->SetXObject(cppu::getXWeak(xFrame.get()));
+ }
+ // need a permanent Reference to initialize m_wThis
+ xFrame->SwXFrame::m_pImpl->m_wThis = uno::Reference<XWeak>(xFrame.get());
+ }
+ return xFrame;
+}
+
+OUString SwXFrame::getName()
+{
+ SolarMutexGuard aGuard;
+ SwFrameFormat* pFormat = GetFrameFormat();
+ if(pFormat)
+ return pFormat->GetName();
+ if(!m_bIsDescriptor)
+ throw uno::RuntimeException();
+ return m_sName;
+}
+
+void SwXFrame::setName(const OUString& rName)
+{
+ SolarMutexGuard aGuard;
+ SwFrameFormat* pFormat = GetFrameFormat();
+ if(pFormat)
+ {
+ pFormat->GetDoc()->SetFlyName(static_cast<SwFlyFrameFormat&>(*pFormat), rName);
+ if(pFormat->GetName() != rName)
+ {
+ throw uno::RuntimeException("SwXFrame::setName(): Illegal object name. Duplicate name?");
+ }
+ }
+ else if(m_bIsDescriptor)
+ m_sName = rName;
+ else
+ throw uno::RuntimeException();
+}
+
+uno::Reference< beans::XPropertySetInfo > SwXFrame::getPropertySetInfo()
+{
+ uno::Reference< beans::XPropertySetInfo > xRef;
+ static uno::Reference< beans::XPropertySetInfo > xFrameRef;
+ static uno::Reference< beans::XPropertySetInfo > xGrfRef;
+ static uno::Reference< beans::XPropertySetInfo > xOLERef;
+ switch(m_eType)
+ {
+ case FLYCNTTYPE_FRM:
+ if( !xFrameRef.is() )
+ xFrameRef = m_pPropSet->getPropertySetInfo();
+ xRef = xFrameRef;
+ break;
+ case FLYCNTTYPE_GRF:
+ if( !xGrfRef.is() )
+ xGrfRef = m_pPropSet->getPropertySetInfo();
+ xRef = xGrfRef;
+ break;
+ case FLYCNTTYPE_OLE:
+ if( !xOLERef.is() )
+ xOLERef = m_pPropSet->getPropertySetInfo();
+ xRef = xOLERef;
+ break;
+ default:
+ ;
+ }
+ return xRef;
+}
+
+SdrObject *SwXFrame::GetOrCreateSdrObject(SwFlyFrameFormat &rFormat)
+{
+ SdrObject* pObject = rFormat.FindSdrObject();
+ if( !pObject )
+ {
+ SwDoc *pDoc = rFormat.GetDoc();
+ // #i52858# - method name changed
+ SwFlyDrawContact* pContactObject(rFormat.GetOrCreateContact());
+ pObject = pContactObject->GetMaster();
+
+ const ::SwFormatSurround& rSurround = rFormat.GetSurround();
+ pObject->SetLayer(
+ ( css::text::WrapTextMode_THROUGH == rSurround.GetSurround() &&
+ !rFormat.GetOpaque().GetValue() ) ? pDoc->getIDocumentDrawModelAccess().GetHellId()
+ : pDoc->getIDocumentDrawModelAccess().GetHeavenId() );
+ SwDrawModel* pDrawModel = pDoc->getIDocumentDrawModelAccess().GetOrCreateDrawModel();
+ pDrawModel->GetPage(0)->InsertObject( pObject );
+ }
+
+ return pObject;
+}
+
+static SwFrameFormat *lcl_GetFrameFormat( const ::uno::Any& rValue, SwDoc *pDoc )
+{
+ SwFrameFormat *pRet = nullptr;
+ SwDocShell* pDocSh = pDoc->GetDocShell();
+ if(pDocSh)
+ {
+ OUString uTemp;
+ rValue >>= uTemp;
+ OUString sStyle;
+ SwStyleNameMapper::FillUIName(uTemp, sStyle,
+ SwGetPoolIdFromName::FrmFmt);
+ SwDocStyleSheet* pStyle =
+ static_cast<SwDocStyleSheet*>(pDocSh->GetStyleSheetPool()->Find(sStyle,
+ SfxStyleFamily::Frame));
+ if(pStyle)
+ pRet = pStyle->GetFrameFormat();
+ }
+
+ return pRet;
+}
+
+void SwXFrame::setPropertyValue(const OUString& rPropertyName, const ::uno::Any& _rValue)
+{
+ SolarMutexGuard aGuard;
+ SwFrameFormat* pFormat = GetFrameFormat();
+ if (!pFormat && !IsDescriptor())
+ throw uno::RuntimeException();
+
+ // Hack to support hidden property to transfer textDirection
+ if(rPropertyName == "FRMDirection")
+ {
+ if (pFormat)
+ {
+ SwDocModifyAndUndoGuard guard(*pFormat);
+ SvxFrameDirectionItem aItem(SvxFrameDirection::Environment, RES_FRAMEDIR);
+ aItem.PutValue(_rValue, 0);
+ pFormat->SetFormatAttr(aItem);
+ }
+ else // if(IsDescriptor())
+ {
+ m_pProps->SetProperty(o3tl::narrowing<sal_uInt16>(RES_FRAMEDIR), 0, _rValue);
+ }
+ return;
+ }
+
+ const ::SfxItemPropertyMapEntry* pEntry = m_pPropSet->getPropertyMap().getByName(rPropertyName);
+
+ if (!pEntry)
+ {
+ // Hack to skip the dummy CursorNotIgnoreTables property
+ if (rPropertyName != "CursorNotIgnoreTables")
+ throw beans::UnknownPropertyException("Unknown property: " + rPropertyName, getXWeak());
+ return;
+ }
+
+ const sal_uInt8 nMemberId(pEntry->nMemberId);
+ uno::Any aValue(_rValue);
+
+ // check for needed metric translation
+ if(pEntry->nMoreFlags & PropertyMoreFlags::METRIC_ITEM)
+ {
+ bool bDoIt(true);
+
+ if(XATTR_FILLBMP_SIZEX == pEntry->nWID || XATTR_FILLBMP_SIZEY == pEntry->nWID)
+ {
+ // exception: If these ItemTypes are used, do not convert when these are negative
+ // since this means they are intended as percent values
+ sal_Int32 nValue = 0;
+
+ if(aValue >>= nValue)
+ {
+ bDoIt = nValue > 0;
+ }
+ }
+
+ if(bDoIt)
+ {
+ const SwDoc* pDoc = (IsDescriptor() ? m_pDoc : pFormat->GetDoc());
+ const SfxItemPool& rPool = pDoc->GetAttrPool();
+ const MapUnit eMapUnit(rPool.GetMetric(pEntry->nWID));
+
+ if(eMapUnit != MapUnit::Map100thMM)
+ {
+ SvxUnoConvertFromMM(eMapUnit, aValue);
+ }
+ }
+ }
+
+ if(pFormat)
+ {
+ bool bNextFrame = false;
+ if ( pEntry->nFlags & beans::PropertyAttribute::READONLY)
+ throw beans::PropertyVetoException("Property is read-only: " + rPropertyName, getXWeak() );
+
+ SwDoc* pDoc = pFormat->GetDoc();
+ if ( ((m_eType == FLYCNTTYPE_GRF) && isGRFATR(pEntry->nWID)) ||
+ (FN_PARAM_CONTOUR_PP == pEntry->nWID) ||
+ (FN_UNO_IS_AUTOMATIC_CONTOUR == pEntry->nWID) ||
+ (FN_UNO_IS_PIXEL_CONTOUR == pEntry->nWID) )
+ {
+ const ::SwNodeIndex* pIdx = pFormat->GetContent().GetContentIdx();
+ if(pIdx)
+ {
+ SwNodeIndex aIdx(*pIdx, 1);
+ SwNoTextNode* pNoText = aIdx.GetNode().GetNoTextNode();
+ if(pEntry->nWID == FN_PARAM_CONTOUR_PP)
+ {
+ drawing::PointSequenceSequence aParam;
+ if(!aValue.hasValue())
+ pNoText->SetContour(nullptr);
+ else if(aValue >>= aParam)
+ {
+ tools::PolyPolygon aPoly(o3tl::narrowing<sal_uInt16>(aParam.getLength()));
+ for(const ::drawing::PointSequence& rPointSeq : std::as_const(aParam))
+ {
+ sal_Int32 nPoints = rPointSeq.getLength();
+ const ::awt::Point* pPoints = rPointSeq.getConstArray();
+ tools::Polygon aSet( o3tl::narrowing<sal_uInt16>(nPoints) );
+ for(sal_Int32 j = 0; j < nPoints; j++)
+ {
+ Point aPoint(pPoints[j].X, pPoints[j].Y);
+ aSet.SetPoint(aPoint, o3tl::narrowing<sal_uInt16>(j));
+ }
+ // Close polygon if it isn't closed already.
+ aSet.Optimize( PolyOptimizeFlags::CLOSE );
+ aPoly.Insert( aSet );
+ }
+ pNoText->SetContourAPI( &aPoly );
+ }
+ else
+ throw lang::IllegalArgumentException();
+ }
+ else if(pEntry->nWID == FN_UNO_IS_AUTOMATIC_CONTOUR )
+ {
+ pNoText->SetAutomaticContour( *o3tl::doAccess<bool>(aValue) );
+ }
+ else if(pEntry->nWID == FN_UNO_IS_PIXEL_CONTOUR )
+ {
+ // The IsPixelContour property can only be set if there
+ // is no contour, or if the contour has been set by the
+ // API itself (or in other words, if the contour isn't
+ // used already).
+ if( pNoText->HasContour_() && pNoText->IsContourMapModeValid() )
+ throw lang::IllegalArgumentException();
+
+ pNoText->SetPixelContour( *o3tl::doAccess<bool>(aValue) );
+
+ }
+ else
+ {
+ SfxItemSet aSet(pNoText->GetSwAttrSet());
+ m_pPropSet->setPropertyValue(*pEntry, aValue, aSet);
+ pNoText->SetAttr(aSet);
+ }
+ }
+ }
+ // New attribute Title
+ else if( FN_UNO_TITLE == pEntry->nWID )
+ {
+ SwFlyFrameFormat& rFlyFormat = dynamic_cast<SwFlyFrameFormat&>(*pFormat);
+ OUString sTitle;
+ aValue >>= sTitle;
+ // assure that <SdrObject> instance exists.
+ GetOrCreateSdrObject(rFlyFormat);
+ rFlyFormat.GetDoc()->SetFlyFrameTitle(rFlyFormat, sTitle);
+ }
+ else if (pEntry->nWID == FN_UNO_TOOLTIP)
+ {
+ SwFlyFrameFormat& rFlyFormat = dynamic_cast<SwFlyFrameFormat&>(*pFormat);
+ OUString sTooltip;
+ aValue >>= sTooltip;
+ rFlyFormat.SetObjTooltip(sTooltip);
+ }
+ // New attribute Description
+ else if( FN_UNO_DESCRIPTION == pEntry->nWID )
+ {
+ SwFlyFrameFormat& rFlyFormat = dynamic_cast<SwFlyFrameFormat&>(*pFormat);
+ OUString sDescription;
+ aValue >>= sDescription;
+ // assure that <SdrObject> instance exists.
+ GetOrCreateSdrObject(rFlyFormat);
+ rFlyFormat.GetDoc()->SetFlyFrameDescription(rFlyFormat, sDescription);
+ }
+ else if(FN_UNO_FRAME_STYLE_NAME == pEntry->nWID)
+ {
+ SwFrameFormat *pFrameFormat = lcl_GetFrameFormat( aValue, pFormat->GetDoc() );
+ if( !pFrameFormat )
+ throw lang::IllegalArgumentException();
+
+ UnoActionContext aAction(pFormat->GetDoc());
+
+ std::optional<SfxItemSet> pSet;
+ // #i31771#, #i25798# - No adjustment of
+ // anchor ( no call of method <sw_ChkAndSetNewAnchor(..)> ),
+ // if document is currently in reading mode.
+ if ( !pFormat->GetDoc()->IsInReading() )
+ {
+ // see SwFEShell::SetFrameFormat( SwFrameFormat *pNewFormat, bool bKeepOrient, Point* pDocPos )
+ SwFlyFrame *pFly = nullptr;
+ if (auto pFlyFrameFormat = dynamic_cast<const SwFlyFrameFormat*>(pFormat) )
+ pFly = pFlyFrameFormat->GetFrame();
+ if ( pFly )
+ {
+ if( const SwFormatAnchor* pItem = pFrameFormat->GetItemIfSet( RES_ANCHOR, false ))
+ {
+ pSet.emplace( pDoc->GetAttrPool(), aFrameFormatSetRange );
+ pSet->Put( *pItem );
+ if ( pFormat->GetDoc()->GetEditShell() != nullptr
+ && !sw_ChkAndSetNewAnchor( *pFly, *pSet ) )
+ {
+ pSet.reset();
+ }
+ }
+ }
+ }
+
+ pFormat->GetDoc()->SetFrameFormatToFly( *pFormat, *pFrameFormat, pSet ? &*pSet : nullptr );
+ }
+ else if (FN_UNO_GRAPHIC_FILTER == pEntry->nWID)
+ {
+ OUString sGrfName;
+ OUString sFltName;
+ SwDoc::GetGrfNms( *static_cast<SwFlyFrameFormat*>(pFormat), &sGrfName, &sFltName );
+ aValue >>= sFltName;
+ UnoActionContext aAction(pFormat->GetDoc());
+ const ::SwNodeIndex* pIdx = pFormat->GetContent().GetContentIdx();
+ if (pIdx)
+ {
+ SwNodeIndex aIdx(*pIdx, 1);
+ SwGrfNode* pGrfNode = aIdx.GetNode().GetGrfNode();
+ if(!pGrfNode)
+ {
+ throw uno::RuntimeException();
+ }
+ SwPaM aGrfPaM(*pGrfNode);
+ pFormat->GetDoc()->getIDocumentContentOperations().ReRead(aGrfPaM, sGrfName, sFltName, nullptr);
+ }
+ }
+ else if (FN_UNO_GRAPHIC == pEntry->nWID || FN_UNO_GRAPHIC_URL == pEntry->nWID)
+ {
+ Graphic aGraphic;
+ if (aValue.has<OUString>())
+ {
+ OUString aURL = aValue.get<OUString>();
+ if (!aURL.isEmpty())
+ {
+ aGraphic = vcl::graphic::loadFromURL(aURL);
+ }
+ }
+ else if (aValue.has<uno::Reference<graphic::XGraphic>>())
+ {
+ uno::Reference<graphic::XGraphic> xGraphic = aValue.get<uno::Reference<graphic::XGraphic>>();
+ if (xGraphic.is())
+ {
+ aGraphic = Graphic(xGraphic);
+ }
+ }
+
+ if (!aGraphic.IsNone())
+ {
+ const ::SwNodeIndex* pIdx = pFormat->GetContent().GetContentIdx();
+ if (pIdx)
+ {
+ SwNodeIndex aIdx(*pIdx, 1);
+ SwGrfNode* pGrfNode = aIdx.GetNode().GetGrfNode();
+ if (!pGrfNode)
+ {
+ throw uno::RuntimeException();
+ }
+ SwPaM aGrfPaM(*pGrfNode);
+ pFormat->GetDoc()->getIDocumentContentOperations().ReRead(aGrfPaM, OUString(), OUString(), &aGraphic);
+ }
+ }
+ }
+ else if (FN_UNO_REPLACEMENT_GRAPHIC == pEntry->nWID || FN_UNO_REPLACEMENT_GRAPHIC_URL == pEntry->nWID)
+ {
+ Graphic aGraphic;
+ if (aValue.has<OUString>())
+ {
+ OUString aURL = aValue.get<OUString>();
+ if (!aURL.isEmpty())
+ {
+ aGraphic = vcl::graphic::loadFromURL(aURL);
+ }
+ }
+ else if (aValue.has<uno::Reference<graphic::XGraphic>>())
+ {
+ uno::Reference<graphic::XGraphic> xGraphic = aValue.get<uno::Reference<graphic::XGraphic>>();
+ if (xGraphic.is())
+ {
+ aGraphic = Graphic(xGraphic);
+ }
+ }
+
+ if (!aGraphic.IsNone())
+ {
+ const ::SwFormatContent* pCnt = &pFormat->GetContent();
+ if ( pCnt->GetContentIdx() && pDoc->GetNodes()[ pCnt->GetContentIdx()->GetIndex() + 1 ] )
+ {
+ SwOLENode* pOleNode = pDoc->GetNodes()[ pCnt->GetContentIdx()->GetIndex() + 1 ]->GetOLENode();
+
+ if ( pOleNode )
+ {
+ svt::EmbeddedObjectRef &rEmbeddedObject = pOleNode->GetOLEObj().GetObject();
+ rEmbeddedObject.SetGraphic(aGraphic, OUString() );
+ }
+ }
+ }
+ }
+ else if((bNextFrame = (rPropertyName == UNO_NAME_CHAIN_NEXT_NAME))
+ || rPropertyName == UNO_NAME_CHAIN_PREV_NAME)
+ {
+ OUString sChainName;
+ aValue >>= sChainName;
+ if (sChainName.isEmpty())
+ {
+ if(bNextFrame)
+ pDoc->Unchain(*pFormat);
+ else
+ {
+ const SwFormatChain& aChain( pFormat->GetChain() );
+ SwFrameFormat *pPrev = aChain.GetPrev();
+ if(pPrev)
+ pDoc->Unchain(*pPrev);
+ }
+ }
+ else
+ {
+ const size_t nCount = pDoc->GetFlyCount(FLYCNTTYPE_FRM);
+
+ SwFrameFormat* pChain = nullptr;
+ for( size_t i = 0; i < nCount; ++i )
+ {
+ SwFrameFormat* pFormat2 = pDoc->GetFlyNum(i, FLYCNTTYPE_FRM);
+ if(sChainName == pFormat2->GetName() )
+ {
+ pChain = pFormat2;
+ break;
+ }
+ }
+ if(pChain)
+ {
+ SwFrameFormat* pSource = bNextFrame ? pFormat : pChain;
+ SwFrameFormat* pDest = bNextFrame ? pChain: pFormat;
+ pDoc->Chain(*pSource, *pDest);
+ }
+ }
+ }
+ else if(FN_UNO_Z_ORDER == pEntry->nWID)
+ {
+ sal_Int32 nZOrder = - 1;
+ aValue >>= nZOrder;
+
+ // Don't set an explicit ZOrder on TextBoxes.
+ if( nZOrder >= 0 && !SwTextBoxHelper::isTextBox(pFormat, RES_FLYFRMFMT) )
+ {
+ SdrObject* pObject =
+ GetOrCreateSdrObject( static_cast<SwFlyFrameFormat&>(*pFormat) );
+ SwDrawModel *pDrawModel = pDoc->getIDocumentDrawModelAccess().GetDrawModel();
+ pDrawModel->GetPage(0)->
+ SetObjectOrdNum(pObject->GetOrdNum(), nZOrder);
+ }
+ }
+ else if(RES_ANCHOR == pEntry->nWID && MID_ANCHOR_ANCHORFRAME == nMemberId)
+ {
+ bool bDone = false;
+ uno::Reference<text::XTextFrame> xFrame;
+ if(aValue >>= xFrame)
+ {
+ SwXFrame* pFrame = dynamic_cast<SwXFrame*>(xFrame.get());
+ if(pFrame && this != pFrame && pFrame->GetFrameFormat() && pFrame->GetFrameFormat()->GetDoc() == pDoc)
+ {
+ SfxItemSetFixed<RES_FRMATR_BEGIN, RES_FRMATR_END - 1> aSet( pDoc->GetAttrPool() );
+ aSet.SetParent(&pFormat->GetAttrSet());
+ SwFormatAnchor aAnchor = static_cast<const SwFormatAnchor&>(aSet.Get(pEntry->nWID));
+
+ SwPosition aPos(*pFrame->GetFrameFormat()->GetContent().GetContentIdx());
+ aAnchor.SetAnchor(&aPos);
+ aAnchor.SetType(RndStdIds::FLY_AT_FLY);
+ aSet.Put(aAnchor);
+ pDoc->SetFlyFrameAttr( *pFormat, aSet );
+ bDone = true;
+ }
+ }
+ if(!bDone)
+ throw lang::IllegalArgumentException();
+ }
+ else
+ {
+ // standard UNO API write attributes
+ // adapt former attr from SvxBrushItem::PutValue to new items XATTR_FILL_FIRST, XATTR_FILL_LAST
+ SfxItemSetFixed
+ <RES_FRMATR_BEGIN, RES_FRMATR_END - 1,
+ RES_UNKNOWNATR_CONTAINER, RES_UNKNOWNATR_CONTAINER,
+
+ // FillAttribute support
+ XATTR_FILL_FIRST, XATTR_FILL_LAST>
+ aSet( pDoc->GetAttrPool());
+ bool bDone(false);
+
+ aSet.SetParent(&pFormat->GetAttrSet());
+
+ if(RES_BACKGROUND == pEntry->nWID)
+ {
+ const SwAttrSet& rSet = pFormat->GetAttrSet();
+ const std::unique_ptr<SvxBrushItem> aOriginalBrushItem(getSvxBrushItemFromSourceSet(rSet, RES_BACKGROUND, true, pDoc->IsInXMLImport()));
+ std::unique_ptr<SvxBrushItem> aChangedBrushItem(aOriginalBrushItem->Clone());
+
+ aChangedBrushItem->PutValue(aValue, nMemberId);
+
+ if(*aChangedBrushItem != *aOriginalBrushItem)
+ {
+ setSvxBrushItemAsFillAttributesToTargetSet(*aChangedBrushItem, aSet);
+ pFormat->GetDoc()->SetFlyFrameAttr( *pFormat, aSet );
+ }
+
+ bDone = true;
+ }
+ else if(OWN_ATTR_FILLBMP_MODE == pEntry->nWID)
+ {
+ drawing::BitmapMode eMode;
+
+ if(!(aValue >>= eMode))
+ {
+ sal_Int32 nMode = 0;
+
+ if(!(aValue >>= nMode))
+ {
+ throw lang::IllegalArgumentException();
+ }
+
+ eMode = static_cast<drawing::BitmapMode>(nMode);
+ }
+
+ aSet.Put(XFillBmpStretchItem(drawing::BitmapMode_STRETCH == eMode));
+ aSet.Put(XFillBmpTileItem(drawing::BitmapMode_REPEAT == eMode));
+ pFormat->GetDoc()->SetFlyFrameAttr( *pFormat, aSet );
+ bDone = true;
+ }
+
+ switch(nMemberId)
+ {
+ case MID_NAME:
+ {
+ // when named items get set, replace these with the NameOrIndex items
+ // which exist already in the pool
+ switch(pEntry->nWID)
+ {
+ case XATTR_FILLGRADIENT:
+ case XATTR_FILLHATCH:
+ case XATTR_FILLBITMAP:
+ case XATTR_FILLFLOATTRANSPARENCE:
+ {
+ OUString aTempName;
+
+ if(!(aValue >>= aTempName ))
+ {
+ throw lang::IllegalArgumentException();
+ }
+
+ bDone = SvxShape::SetFillAttribute(pEntry->nWID, aTempName, aSet);
+ break;
+ }
+ default:
+ {
+ break;
+ }
+ }
+ break;
+ }
+ case MID_BITMAP:
+ {
+ switch(pEntry->nWID)
+ {
+ case XATTR_FILLBITMAP:
+ {
+ Graphic aNullGraphic;
+ XFillBitmapItem aXFillBitmapItem(std::move(aNullGraphic));
+
+ aXFillBitmapItem.PutValue(aValue, nMemberId);
+ aSet.Put(aXFillBitmapItem);
+ bDone = true;
+ break;
+ }
+ default:
+ {
+ break;
+ }
+ }
+ break;
+ }
+ default:
+ {
+ break;
+ }
+ }
+
+ if(!bDone)
+ {
+ m_pPropSet->setPropertyValue(*pEntry, aValue, aSet);
+ }
+
+ if(RES_ANCHOR == pEntry->nWID && MID_ANCHOR_ANCHORTYPE == nMemberId)
+ {
+ SwFormatAnchor aAnchor = static_cast<const SwFormatAnchor&>(aSet.Get(pEntry->nWID));
+ if(aAnchor.GetAnchorId() == RndStdIds::FLY_AT_FLY)
+ {
+ const ::SwNode* pAnchorNode = aAnchor.GetAnchorNode();
+ SwFrameFormat* pFlyFormat = pAnchorNode ? pAnchorNode->GetFlyFormat() : nullptr;
+ if(!pFlyFormat || pFlyFormat->Which() == RES_DRAWFRMFMT)
+ {
+ throw lang::IllegalArgumentException("Anchor to frame: no frame found", nullptr, 0);
+ }
+ else
+ {
+ SwPosition aPos = *aAnchor.GetContentAnchor();
+ aPos.Assign( *pFlyFormat->GetContent().GetContentIdx() );
+ aAnchor.SetAnchor(&aPos);
+ aSet.Put(aAnchor);
+ }
+ }
+ else if ((aAnchor.GetAnchorId() != RndStdIds::FLY_AT_PAGE) &&
+ !aAnchor.GetAnchorNode())
+ {
+ SwNode& rNode = pDoc->GetNodes().GetEndOfContent();
+ SwPaM aPam(rNode);
+ aPam.Move( fnMoveBackward, GoInDoc );
+ aAnchor.SetAnchor( aPam.Start() );
+ aSet.Put(aAnchor);
+ }
+
+ // #i31771#, #i25798# - No adjustment of
+ // anchor ( no call of method <sw_ChkAndSetNewAnchor(..)> ),
+ // if document is currently in reading mode.
+ if ( !pFormat->GetDoc()->IsInReading() )
+ {
+ // see SwFEShell::SetFlyFrameAttr( SfxItemSet& rSet )
+ SwFlyFrame *pFly = nullptr;
+ if (auto pFrameFormat = dynamic_cast<SwFlyFrameFormat*>( pFormat) )
+ pFly = pFrameFormat->GetFrame();
+ if (pFly)
+ {
+ if( const SwFormatAnchor* pItem = aSet.GetItemIfSet( RES_ANCHOR, false ))
+ {
+ aSet.Put( *pItem );
+ if ( pFormat->GetDoc()->GetEditShell() != nullptr )
+ {
+ sw_ChkAndSetNewAnchor( *pFly, aSet );
+ }
+ }
+ }
+ }
+
+ pFormat->GetDoc()->SetFlyFrameAttr( *pFormat, aSet );
+ }
+ else if(FN_UNO_CLSID == pEntry->nWID || FN_UNO_STREAM_NAME == pEntry->nWID || FN_EMBEDDED_OBJECT == pEntry->nWID)
+ {
+ throw lang::IllegalArgumentException();
+ }
+ else
+ {
+ SwDocModifyAndUndoGuard guard(*pFormat);
+ pFormat->SetFormatAttr(aSet);
+ }
+ }
+ }
+ else // if(IsDescriptor())
+ {
+ m_pProps->SetProperty(pEntry->nWID, nMemberId, aValue);
+ if( FN_UNO_FRAME_STYLE_NAME == pEntry->nWID )
+ {
+ OUString sStyleName;
+ aValue >>= sStyleName;
+ try
+ {
+ uno::Any aAny = mxStyleFamily->getByName ( sStyleName );
+ aAny >>= mxStyleData;
+ }
+ catch ( container::NoSuchElementException const & )
+ {
+ }
+ catch ( lang::WrappedTargetException const & )
+ {
+ }
+ catch ( uno::RuntimeException const & )
+ {
+ }
+ }
+ else if (FN_UNO_DRAW_ASPECT == pEntry->nWID)
+ {
+ OUString sAspect = "";
+ aValue >>= sAspect;
+
+ if (sAspect == "Icon")
+ m_nDrawAspect = embed::Aspects::MSOLE_ICON;
+ else if (sAspect == "Content")
+ m_nDrawAspect = embed::Aspects::MSOLE_CONTENT;
+ }
+ else if (FN_UNO_VISIBLE_AREA_WIDTH == pEntry->nWID)
+ {
+ OUString sAspect = "";
+ aValue >>= sAspect;
+ m_nVisibleAreaWidth = sAspect.toInt64();
+ }
+ else if (FN_UNO_VISIBLE_AREA_HEIGHT == pEntry->nWID)
+ {
+ OUString sAspect = "";
+ aValue >>= sAspect;
+ m_nVisibleAreaHeight = sAspect.toInt64();
+ }
+ }
+}
+
+namespace
+{
+/// Redirect error popups to developer warnings for the duration of the UNO API call.
+class DisplayLockGuard
+{
+ bool m_bLock;
+
+public:
+ DisplayLockGuard()
+ {
+ m_bLock = ErrorRegistry::GetLock();
+ ErrorRegistry::SetLock(true);
+ }
+
+ ~DisplayLockGuard() { ErrorRegistry::SetLock(m_bLock); }
+};
+}
+
+uno::Any SwXFrame::getPropertyValue(const OUString& rPropertyName)
+{
+ SolarMutexGuard aGuard;
+ DisplayLockGuard aDisplayGuard;
+ uno::Any aAny;
+ SwFrameFormat* pFormat = GetFrameFormat();
+ const SfxItemPropertyMapEntry* pEntry = m_pPropSet->getPropertyMap().getByName(rPropertyName);
+ if (!pEntry)
+ throw beans::UnknownPropertyException( "Unknown property: " + rPropertyName, getXWeak() );
+
+ const sal_uInt8 nMemberId(pEntry->nMemberId);
+
+ if(FN_UNO_ANCHOR_TYPES == pEntry->nWID)
+ {
+ uno::Sequence<text::TextContentAnchorType> aTypes
+ {
+ text::TextContentAnchorType_AT_PARAGRAPH,
+ text::TextContentAnchorType_AS_CHARACTER,
+ text::TextContentAnchorType_AT_PAGE,
+ text::TextContentAnchorType_AT_FRAME,
+ text::TextContentAnchorType_AT_CHARACTER
+ };
+ aAny <<= aTypes;
+ }
+ else if(pFormat)
+ {
+ if( ((m_eType == FLYCNTTYPE_GRF) || (m_eType == FLYCNTTYPE_OLE)) &&
+ (isGRFATR(pEntry->nWID) ||
+ pEntry->nWID == FN_PARAM_CONTOUR_PP ||
+ pEntry->nWID == FN_UNO_IS_AUTOMATIC_CONTOUR ||
+ pEntry->nWID == FN_UNO_IS_PIXEL_CONTOUR ))
+ {
+ const SwNodeIndex* pIdx = pFormat->GetContent().GetContentIdx();
+ if(pIdx)
+ {
+ SwNodeIndex aIdx(*pIdx, 1);
+ SwNoTextNode* pNoText = aIdx.GetNode().GetNoTextNode();
+ if(pEntry->nWID == FN_PARAM_CONTOUR_PP)
+ {
+ tools::PolyPolygon aContour;
+ if( pNoText->GetContourAPI( aContour ) )
+ {
+ drawing::PointSequenceSequence aPtSeq(aContour.Count());
+ drawing::PointSequence* pPSeq = aPtSeq.getArray();
+ for(sal_uInt16 i = 0; i < aContour.Count(); i++)
+ {
+ const tools::Polygon& rPoly = aContour.GetObject(i);
+ pPSeq[i].realloc(rPoly.GetSize());
+ awt::Point* pPoints = pPSeq[i].getArray();
+ for(sal_uInt16 j = 0; j < rPoly.GetSize(); j++)
+ {
+ const Point& rPoint = rPoly.GetPoint(j);
+ pPoints[j].X = rPoint.X();
+ pPoints[j].Y = rPoint.Y();
+ }
+ }
+ aAny <<= aPtSeq;
+ }
+ }
+ else if(pEntry->nWID == FN_UNO_IS_AUTOMATIC_CONTOUR )
+ {
+ aAny <<= pNoText->HasAutomaticContour();
+ }
+ else if(pEntry->nWID == FN_UNO_IS_PIXEL_CONTOUR )
+ {
+ aAny <<= pNoText->IsPixelContour();
+ }
+ else
+ {
+ const SfxItemSet& aSet(pNoText->GetSwAttrSet());
+ m_pPropSet->getPropertyValue(*pEntry, aSet, aAny);
+ }
+ }
+ }
+ else if (FN_UNO_REPLACEMENT_GRAPHIC == pEntry->nWID)
+ {
+ const SwNodeIndex* pIdx = pFormat->GetContent().GetContentIdx();
+ uno::Reference<graphic::XGraphic> xGraphic;
+
+ if (pIdx)
+ {
+ SwNodeIndex aIdx(*pIdx, 1);
+ SwGrfNode* pGrfNode = aIdx.GetNode().GetGrfNode();
+ if (!pGrfNode)
+ throw uno::RuntimeException();
+
+ const GraphicObject* pGraphicObject = pGrfNode->GetReplacementGrfObj();
+
+ if (pGraphicObject)
+ {
+ xGraphic = pGraphicObject->GetGraphic().GetXGraphic();
+ }
+ }
+ aAny <<= xGraphic;
+ }
+ else if( FN_UNO_GRAPHIC_FILTER == pEntry->nWID )
+ {
+ OUString sFltName;
+ SwDoc::GetGrfNms( *static_cast<SwFlyFrameFormat*>(pFormat), nullptr, &sFltName );
+ aAny <<= sFltName;
+ }
+ else if( FN_UNO_GRAPHIC_URL == pEntry->nWID )
+ {
+ throw uno::RuntimeException("Getting from this property is not supported");
+ }
+ else if( FN_UNO_GRAPHIC == pEntry->nWID )
+ {
+ const SwNodeIndex* pIdx = pFormat->GetContent().GetContentIdx();
+ if(pIdx)
+ {
+ SwNodeIndex aIdx(*pIdx, 1);
+ SwGrfNode* pGrfNode = aIdx.GetNode().GetGrfNode();
+ if(!pGrfNode)
+ throw uno::RuntimeException();
+ aAny <<= pGrfNode->GetGrf().GetXGraphic();
+ }
+ }
+ else if( FN_UNO_TRANSFORMED_GRAPHIC == pEntry->nWID
+ || FN_UNO_GRAPHIC_PREVIEW == pEntry->nWID )
+ {
+ const SwNodeIndex* pIdx = pFormat->GetContent().GetContentIdx();
+ if(pIdx)
+ {
+ SwNodeIndex aIdx(*pIdx, 1);
+ SwGrfNode* pGrfNode = aIdx.GetNode().GetGrfNode();
+ if(!pGrfNode)
+ throw uno::RuntimeException();
+
+ SwDoc* pDoc = pFormat->GetDoc();
+ if (pDoc)
+ {
+ if (const SwEditShell* pEditShell = pDoc->GetEditShell())
+ {
+ SwFrame* pCurrFrame = pEditShell->GetCurrFrame(false);
+ GraphicAttr aGraphicAttr;
+ pGrfNode->GetGraphicAttr( aGraphicAttr, pCurrFrame );
+ const GraphicObject aGraphicObj = pGrfNode->GetGrfObj();
+
+ awt::Size aFrameSize = getSize();
+ Size aSize100thmm(aFrameSize.Width, aFrameSize.Height);
+ Size aSize = OutputDevice::LogicToLogic(aSize100thmm, MapMode(MapUnit::Map100thMM), aGraphicObj.GetPrefMapMode());
+
+ if (FN_UNO_GRAPHIC_PREVIEW == pEntry->nWID)
+ {
+ double fX = static_cast<double>(aSize.getWidth()) / 1280;
+ double fY = static_cast<double>(aSize.getHeight()) / 720;
+ double fFactor = fX > fY ? fX : fY;
+ if (fFactor > 1.0)
+ {
+ aSize.setWidth(aSize.getWidth() / fFactor);
+ aSize.setHeight(aSize.getHeight() / fFactor);
+ }
+ }
+
+ Graphic aGraphic = aGraphicObj.GetTransformedGraphic(aSize, aGraphicObj.GetPrefMapMode(), aGraphicAttr);
+ aAny <<= aGraphic.GetXGraphic();
+ }
+ }
+ }
+ }
+ else if(FN_UNO_FRAME_STYLE_NAME == pEntry->nWID)
+ {
+ aAny <<= SwStyleNameMapper::GetProgName(pFormat->DerivedFrom()->GetName(), SwGetPoolIdFromName::FrmFmt );
+ }
+ // #i73249#
+ else if( FN_UNO_TITLE == pEntry->nWID )
+ {
+ SwFlyFrameFormat& rFlyFormat = dynamic_cast<SwFlyFrameFormat&>(*pFormat);
+ // assure that <SdrObject> instance exists.
+ GetOrCreateSdrObject(rFlyFormat);
+ aAny <<= rFlyFormat.GetObjTitle();
+ }
+ else if (pEntry->nWID == FN_UNO_TOOLTIP)
+ {
+ SwFlyFrameFormat& rFlyFormat = dynamic_cast<SwFlyFrameFormat&>(*pFormat);
+ aAny <<= rFlyFormat.GetObjTooltip();
+ }
+ // New attribute Description
+ else if( FN_UNO_DESCRIPTION == pEntry->nWID )
+ {
+ SwFlyFrameFormat& rFlyFormat = dynamic_cast<SwFlyFrameFormat&>(*pFormat);
+ // assure that <SdrObject> instance exists.
+ GetOrCreateSdrObject(rFlyFormat);
+ aAny <<= rFlyFormat.GetObjDescription();
+ }
+ else if(m_eType == FLYCNTTYPE_GRF &&
+ (rPropertyName == UNO_NAME_ACTUAL_SIZE))
+ {
+ const SwNodeIndex* pIdx = pFormat->GetContent().GetContentIdx();
+ if(pIdx)
+ {
+ SwNodeIndex aIdx(*pIdx, 1);
+ Size aActSize = aIdx.GetNode().GetNoTextNode()->GetTwipSize();
+ awt::Size aTmp;
+ aTmp.Width = convertTwipToMm100(aActSize.Width());
+ aTmp.Height = convertTwipToMm100(aActSize.Height());
+ aAny <<= aTmp;
+ }
+ }
+ else if(FN_PARAM_LINK_DISPLAY_NAME == pEntry->nWID)
+ {
+ aAny <<= pFormat->GetName();
+ }
+ else if(FN_UNO_Z_ORDER == pEntry->nWID)
+ {
+ const SdrObject* pObj = pFormat->FindRealSdrObject();
+ if( pObj == nullptr )
+ pObj = pFormat->FindSdrObject();
+ if( pObj )
+ {
+ aAny <<= static_cast<sal_Int32>(pObj->GetOrdNum());
+ }
+ }
+ else if(FN_UNO_CLSID == pEntry->nWID || FN_UNO_MODEL == pEntry->nWID||
+ FN_UNO_COMPONENT == pEntry->nWID ||FN_UNO_STREAM_NAME == pEntry->nWID||
+ FN_EMBEDDED_OBJECT == pEntry->nWID)
+ {
+ SwDoc* pDoc = pFormat->GetDoc();
+ const SwFormatContent* pCnt = &pFormat->GetContent();
+ OSL_ENSURE( pCnt->GetContentIdx() &&
+ pDoc->GetNodes()[ pCnt->GetContentIdx()->
+ GetIndex() + 1 ]->GetOLENode(), "no OLE-Node?");
+
+ SwOLENode* pOleNode = pDoc->GetNodes()[ pCnt->GetContentIdx()
+ ->GetIndex() + 1 ]->GetOLENode();
+ uno::Reference < embed::XEmbeddedObject > xIP = pOleNode->GetOLEObj().GetOleRef();
+ OUString aHexCLSID;
+ {
+ SvGlobalName aClassName( xIP->getClassID() );
+ aHexCLSID = aClassName.GetHexName();
+ if(FN_UNO_CLSID != pEntry->nWID)
+ {
+ if ( svt::EmbeddedObjectRef::TryRunningState( xIP ) )
+ {
+ uno::Reference < lang::XComponent > xComp( xIP->getComponent(), uno::UNO_QUERY );
+ uno::Reference < frame::XModel > xModel( xComp, uno::UNO_QUERY );
+ if ( FN_EMBEDDED_OBJECT == pEntry->nWID )
+ {
+ // when exposing the EmbeddedObject, ensure it has a client site
+ OSL_ENSURE( pDoc->GetDocShell(), "no doc shell => no client site" );
+ if ( pDoc->GetDocShell() )
+ pDoc->GetDocShell()->GetIPClient( svt::EmbeddedObjectRef( xIP, embed::Aspects::MSOLE_CONTENT ) );
+ aAny <<= xIP;
+ }
+ else if ( xModel.is() )
+ aAny <<= xModel;
+ else if ( FN_UNO_COMPONENT == pEntry->nWID )
+ aAny <<= xComp;
+ }
+ }
+ }
+
+ if(FN_UNO_CLSID == pEntry->nWID)
+ aAny <<= aHexCLSID;
+ else if(FN_UNO_STREAM_NAME == pEntry->nWID)
+ {
+ aAny <<= pOleNode->GetOLEObj().GetCurrentPersistName();
+ }
+ else if(FN_EMBEDDED_OBJECT == pEntry->nWID)
+ {
+ aAny <<= pOleNode->GetOLEObj().GetOleRef();
+ }
+ }
+ else if(WID_LAYOUT_SIZE == pEntry->nWID)
+ {
+ // format document completely in order to get correct value (no EditShell for ole embedded case)
+ if (SwEditShell* pEditShell = pFormat->GetDoc()->GetEditShell())
+ pEditShell->CalcLayout();
+
+ SwFrame* pTmpFrame = SwIterator<SwFrame,SwFormat>( *pFormat ).First();
+ if ( pTmpFrame )
+ {
+ OSL_ENSURE( pTmpFrame->isFrameAreaDefinitionValid(), "frame not valid" );
+ const SwRect &rRect = pTmpFrame->getFrameArea();
+ Size aMM100Size = o3tl::convert(
+ Size( rRect.Width(), rRect.Height() ),
+ o3tl::Length::twip, o3tl::Length::mm100 );
+ aAny <<= awt::Size( aMM100Size.Width(), aMM100Size.Height() );
+ }
+ }
+ else if(pEntry->nWID == FN_UNO_PARENT_TEXT)
+ {
+ if (!m_xParentText.is())
+ {
+ const SwFormatAnchor& rFormatAnchor = pFormat->GetAnchor();
+ if (rFormatAnchor.GetAnchorNode())
+ {
+ m_xParentText = sw::CreateParentXText(*pFormat->GetDoc(), *rFormatAnchor.GetContentAnchor());
+ }
+ }
+ aAny <<= m_xParentText;
+ }
+ else
+ {
+ // standard UNO API read attributes
+ // adapt former attr from SvxBrushItem::PutValue to new items XATTR_FILL_FIRST, XATTR_FILL_LAST
+ const SwAttrSet& rSet = pFormat->GetAttrSet();
+ bool bDone(false);
+
+ if(RES_BACKGROUND == pEntry->nWID)
+ {
+ const std::unique_ptr<SvxBrushItem> aOriginalBrushItem(getSvxBrushItemFromSourceSet(rSet, RES_BACKGROUND));
+
+ if(!aOriginalBrushItem->QueryValue(aAny, nMemberId))
+ {
+ OSL_ENSURE(false, "Error getting attribute from RES_BACKGROUND (!)");
+ }
+
+ bDone = true;
+ }
+ else if(OWN_ATTR_FILLBMP_MODE == pEntry->nWID)
+ {
+ if (rSet.Get(XATTR_FILLBMP_TILE).GetValue())
+ {
+ aAny <<= drawing::BitmapMode_REPEAT;
+ }
+ else if (rSet.Get(XATTR_FILLBMP_STRETCH).GetValue())
+ {
+ aAny <<= drawing::BitmapMode_STRETCH;
+ }
+ else
+ {
+ aAny <<= drawing::BitmapMode_NO_REPEAT;
+ }
+
+ bDone = true;
+ }
+
+ if(!bDone)
+ {
+ m_pPropSet->getPropertyValue(*pEntry, rSet, aAny);
+ }
+ }
+ }
+ else if(IsDescriptor())
+ {
+ if ( ! m_pDoc )
+ throw uno::RuntimeException();
+ if(WID_LAYOUT_SIZE != pEntry->nWID) // there is no LayoutSize in a descriptor
+ {
+ const uno::Any* pAny = nullptr;
+ if (!m_pProps->GetProperty(pEntry->nWID, nMemberId, pAny))
+ aAny = mxStyleData->getPropertyValue( rPropertyName );
+ else if ( pAny )
+ aAny = *pAny;
+ }
+ }
+ else
+ throw uno::RuntimeException();
+
+ if (pEntry->aType == ::cppu::UnoType<sal_Int16>::get() && pEntry->aType != aAny.getValueType())
+ {
+ // since the sfx uint16 item now exports a sal_Int32, we may have to fix this here
+ sal_Int32 nValue = 0;
+ aAny >>= nValue;
+ aAny <<= static_cast<sal_Int16>(nValue);
+ }
+
+ // check for needed metric translation
+ if(pEntry->nMoreFlags & PropertyMoreFlags::METRIC_ITEM)
+ {
+ bool bDoIt(true);
+
+ if(XATTR_FILLBMP_SIZEX == pEntry->nWID || XATTR_FILLBMP_SIZEY == pEntry->nWID)
+ {
+ // exception: If these ItemTypes are used, do not convert when these are negative
+ // since this means they are intended as percent values
+ sal_Int32 nValue = 0;
+
+ if(aAny >>= nValue)
+ {
+ bDoIt = nValue > 0;
+ }
+ }
+
+ if(bDoIt)
+ {
+ const SwDoc* pDoc = (IsDescriptor() ? m_pDoc : GetFrameFormat()->GetDoc());
+ const SfxItemPool& rPool = pDoc->GetAttrPool();
+ const MapUnit eMapUnit(rPool.GetMetric(pEntry->nWID));
+
+ if(eMapUnit != MapUnit::Map100thMM)
+ {
+ SvxUnoConvertToMM(eMapUnit, aAny);
+ }
+ }
+ }
+
+ return aAny;
+}
+
+void SwXFrame::addPropertyChangeListener(const OUString& /*PropertyName*/,
+ const uno::Reference< beans::XPropertyChangeListener > & /*aListener*/)
+{
+ OSL_FAIL("not implemented");
+}
+
+void SwXFrame::removePropertyChangeListener(const OUString& /*PropertyName*/,
+ const uno::Reference< beans::XPropertyChangeListener > & /*aListener*/)
+{
+ OSL_FAIL("not implemented");
+}
+
+void SwXFrame::addVetoableChangeListener(const OUString& /*PropertyName*/,
+ const uno::Reference< beans::XVetoableChangeListener > & /*aListener*/)
+{
+ OSL_FAIL("not implemented");
+}
+
+void SwXFrame::removeVetoableChangeListener(
+ const OUString& /*PropertyName*/, const uno::Reference< beans::XVetoableChangeListener > & /*aListener*/)
+{
+ OSL_FAIL("not implemented");
+}
+
+beans::PropertyState SwXFrame::getPropertyState( const OUString& rPropertyName )
+{
+ SolarMutexGuard aGuard;
+ uno::Sequence< OUString > aPropertyNames { rPropertyName };
+ uno::Sequence< beans::PropertyState > aStates = getPropertyStates(aPropertyNames);
+ return aStates.getConstArray()[0];
+}
+
+uno::Sequence< beans::PropertyState > SwXFrame::getPropertyStates(
+ const uno::Sequence< OUString >& aPropertyNames )
+{
+ SolarMutexGuard aGuard;
+ uno::Sequence< beans::PropertyState > aStates(aPropertyNames.getLength());
+ auto [pStates, end] = asNonConstRange(aStates);
+ SwFrameFormat* pFormat = GetFrameFormat();
+ if(pFormat)
+ {
+ const OUString* pNames = aPropertyNames.getConstArray();
+ const SwAttrSet& rFormatSet = pFormat->GetAttrSet();
+ for(int i = 0; i < aPropertyNames.getLength(); i++)
+ {
+ const SfxItemPropertyMapEntry* pEntry = m_pPropSet->getPropertyMap().getByName(pNames[i]);
+ if (!pEntry)
+ throw beans::UnknownPropertyException("Unknown property: " + pNames[i], getXWeak() );
+
+ if(pEntry->nWID == FN_UNO_ANCHOR_TYPES||
+ pEntry->nWID == FN_PARAM_LINK_DISPLAY_NAME||
+ FN_UNO_FRAME_STYLE_NAME == pEntry->nWID||
+ FN_UNO_GRAPHIC == pEntry->nWID||
+ FN_UNO_GRAPHIC_URL == pEntry->nWID||
+ FN_UNO_GRAPHIC_FILTER == pEntry->nWID||
+ FN_UNO_ACTUAL_SIZE == pEntry->nWID||
+ FN_UNO_ALTERNATIVE_TEXT == pEntry->nWID)
+ {
+ pStates[i] = beans::PropertyState_DIRECT_VALUE;
+ }
+ else if(OWN_ATTR_FILLBMP_MODE == pEntry->nWID)
+ {
+ if(SfxItemState::SET == rFormatSet.GetItemState(XATTR_FILLBMP_STRETCH, false)
+ || SfxItemState::SET == rFormatSet.GetItemState(XATTR_FILLBMP_TILE, false))
+ {
+ pStates[i] = beans::PropertyState_DIRECT_VALUE;
+ }
+ else
+ {
+ pStates[i] = beans::PropertyState_AMBIGUOUS_VALUE;
+ }
+ }
+ // for FlyFrames we need to mark the used properties from type RES_BACKGROUND
+ // as beans::PropertyState_DIRECT_VALUE to let users of this property call
+ // getPropertyValue where the member properties will be mapped from the
+ // fill attributes to the according SvxBrushItem entries
+ else if (RES_BACKGROUND == pEntry->nWID)
+ {
+ if (SWUnoHelper::needToMapFillItemsToSvxBrushItemTypes(rFormatSet, pEntry->nMemberId))
+ pStates[i] = beans::PropertyState_DIRECT_VALUE;
+ else
+ pStates[i] = beans::PropertyState_DEFAULT_VALUE;
+ }
+ else
+ {
+ if ((m_eType == FLYCNTTYPE_GRF) && isGRFATR(pEntry->nWID))
+ {
+ const SwNodeIndex* pIdx = pFormat->GetContent().GetContentIdx();
+ if(pIdx)
+ {
+ SwNodeIndex aIdx(*pIdx, 1);
+ SwNoTextNode* pNoText = aIdx.GetNode().GetNoTextNode();
+ const SfxItemSet& aSet(pNoText->GetSwAttrSet());
+ aSet.GetItemState(pEntry->nWID);
+ if(SfxItemState::SET == aSet.GetItemState( pEntry->nWID, false ))
+ pStates[i] = beans::PropertyState_DIRECT_VALUE;
+ }
+ }
+ else
+ {
+ if(SfxItemState::SET == rFormatSet.GetItemState( pEntry->nWID, false ))
+ pStates[i] = beans::PropertyState_DIRECT_VALUE;
+ else
+ pStates[i] = beans::PropertyState_DEFAULT_VALUE;
+ }
+ }
+ }
+ }
+ else if(IsDescriptor())
+ {
+ std::fill(pStates, end, beans::PropertyState_DIRECT_VALUE);
+ }
+ else
+ throw uno::RuntimeException();
+ return aStates;
+}
+
+void SwXFrame::setPropertyToDefault( const OUString& rPropertyName )
+{
+ SolarMutexGuard aGuard;
+ SwFrameFormat* pFormat = GetFrameFormat();
+ if(pFormat)
+ {
+ const SfxItemPropertyMapEntry* pEntry = m_pPropSet->getPropertyMap().getByName(rPropertyName);
+ if (!pEntry)
+ throw beans::UnknownPropertyException( "Unknown property: " + rPropertyName, getXWeak() );
+ if ( pEntry->nFlags & beans::PropertyAttribute::READONLY)
+ throw uno::RuntimeException("setPropertyToDefault: property is read-only: " + rPropertyName, getXWeak() );
+
+ if(OWN_ATTR_FILLBMP_MODE == pEntry->nWID)
+ {
+ SwDoc* pDoc = pFormat->GetDoc();
+ SfxItemSetFixed<XATTR_FILL_FIRST, XATTR_FILL_LAST> aSet(pDoc->GetAttrPool());
+ aSet.SetParent(&pFormat->GetAttrSet());
+
+ aSet.ClearItem(XATTR_FILLBMP_STRETCH);
+ aSet.ClearItem(XATTR_FILLBMP_TILE);
+
+ SwDocModifyAndUndoGuard guard(*pFormat);
+ pFormat->SetFormatAttr(aSet);
+ }
+ else if( pEntry->nWID &&
+ pEntry->nWID != FN_UNO_ANCHOR_TYPES &&
+ pEntry->nWID != FN_PARAM_LINK_DISPLAY_NAME)
+ {
+ if ( (m_eType == FLYCNTTYPE_GRF) && isGRFATR(pEntry->nWID) )
+ {
+ const SwNodeIndex* pIdx = pFormat->GetContent().GetContentIdx();
+ if(pIdx)
+ {
+ SwNodeIndex aIdx(*pIdx, 1);
+ SwNoTextNode* pNoText = aIdx.GetNode().GetNoTextNode();
+ {
+ SfxItemSet aSet(pNoText->GetSwAttrSet());
+ aSet.ClearItem(pEntry->nWID);
+ pNoText->SetAttr(aSet);
+ }
+ }
+ }
+ // #i73249#
+ else if( FN_UNO_TITLE == pEntry->nWID )
+ {
+ SwFlyFrameFormat& rFlyFormat = dynamic_cast<SwFlyFrameFormat&>(*pFormat);
+ // assure that <SdrObject> instance exists.
+ GetOrCreateSdrObject(rFlyFormat);
+ rFlyFormat.GetDoc()->SetFlyFrameTitle(rFlyFormat, OUString());
+ }
+ // New attribute Description
+ else if( FN_UNO_DESCRIPTION == pEntry->nWID )
+ {
+ SwFlyFrameFormat& rFlyFormat = dynamic_cast<SwFlyFrameFormat&>(*pFormat);
+ // assure that <SdrObject> instance exists.
+ GetOrCreateSdrObject(rFlyFormat);
+ rFlyFormat.GetDoc()->SetFlyFrameDescription(rFlyFormat, OUString());
+ }
+ else if (rPropertyName != UNO_NAME_ANCHOR_TYPE)
+ {
+ SwDoc* pDoc = pFormat->GetDoc();
+ SfxItemSetFixed<RES_FRMATR_BEGIN, RES_FRMATR_END - 1> aSet( pDoc->GetAttrPool() );
+ aSet.SetParent(&pFormat->GetAttrSet());
+ aSet.ClearItem(pEntry->nWID);
+ SwDocModifyAndUndoGuard guard(*pFormat);
+ pFormat->SetFormatAttr(aSet);
+ }
+ }
+ else
+ {
+ bool bNextFrame = rPropertyName == UNO_NAME_CHAIN_NEXT_NAME;
+ if( bNextFrame || rPropertyName == UNO_NAME_CHAIN_PREV_NAME )
+ {
+ SwDoc* pDoc = pFormat->GetDoc();
+ if(bNextFrame)
+ pDoc->Unchain(*pFormat);
+ else
+ {
+ const SwFormatChain& aChain( pFormat->GetChain() );
+ SwFrameFormat *pPrev = aChain.GetPrev();
+ if(pPrev)
+ pDoc->Unchain(*pPrev);
+ }
+ }
+ }
+ }
+ else if(!IsDescriptor())
+ throw uno::RuntimeException();
+
+}
+
+uno::Any SwXFrame::getPropertyDefault( const OUString& rPropertyName )
+{
+ SolarMutexGuard aGuard;
+ uno::Any aRet;
+ SwFrameFormat* pFormat = GetFrameFormat();
+ if(pFormat)
+ {
+ const SfxItemPropertyMapEntry* pEntry = m_pPropSet->getPropertyMap().getByName(rPropertyName);
+ if(!pEntry)
+ throw beans::UnknownPropertyException( "Unknown property: " + rPropertyName, getXWeak() );
+
+ if ( pEntry->nWID < RES_FRMATR_END )
+ {
+ const SfxPoolItem& rDefItem =
+ pFormat->GetDoc()->GetAttrPool().GetDefaultItem(pEntry->nWID);
+ rDefItem.QueryValue(aRet, pEntry->nMemberId);
+ }
+
+ }
+ else if(!IsDescriptor())
+ throw uno::RuntimeException();
+ return aRet;
+}
+
+void SAL_CALL SwXFrame::addEventListener(
+ const uno::Reference<lang::XEventListener> & xListener)
+{
+ std::unique_lock aGuard(m_pImpl->m_Mutex);
+ m_pImpl->m_EventListeners.addInterface(aGuard, xListener);
+}
+
+void SAL_CALL SwXFrame::removeEventListener(
+ const uno::Reference<lang::XEventListener> & xListener)
+{
+ std::unique_lock aGuard(m_pImpl->m_Mutex);
+ m_pImpl->m_EventListeners.removeInterface(aGuard, xListener);
+}
+
+void SwXFrame::DisposeInternal()
+{
+ mxStyleData.clear();
+ mxStyleFamily.clear();
+ m_pDoc = nullptr;
+ uno::Reference<uno::XInterface> const xThis(m_pImpl->m_wThis);
+ if (!xThis.is())
+ { // fdo#72695: if UNO object is already dead, don't revive it with event
+ return;
+ }
+ {
+ lang::EventObject const ev(xThis);
+ std::unique_lock aGuard(m_pImpl->m_Mutex);
+ m_pImpl->m_EventListeners.disposeAndClear(aGuard, ev);
+ }
+ m_pFrameFormat = nullptr;
+ EndListeningAll();
+}
+void SwXFrame::Notify(const SfxHint& rHint)
+{
+ if(rHint.GetId() == SfxHintId::Dying)
+ DisposeInternal();
+}
+
+void SwXFrame::dispose()
+{
+ SolarMutexGuard aGuard;
+ SwFrameFormat* pFormat = GetFrameFormat();
+ if (!pFormat)
+ return;
+
+ DisposeInternal();
+ SdrObject* pObj = pFormat->FindSdrObject();
+ // OD 11.09.2003 #112039# - add condition to perform delete of
+ // format/anchor sign, not only if the object is inserted, but also
+ // if a contact object is registered, which isn't in the destruction.
+ if ( pObj &&
+ ( pObj->IsInserted() ||
+ ( pObj->GetUserCall() &&
+ !static_cast<SwContact*>(pObj->GetUserCall())->IsInDTOR() ) ) )
+ {
+ const SwFormatAnchor& rFormatAnchor = pFormat->GetAnchor();
+ if (rFormatAnchor.GetAnchorId() == RndStdIds::FLY_AS_CHAR)
+ {
+ SwTextNode *pTextNode = rFormatAnchor.GetAnchorNode()->GetTextNode();
+ const sal_Int32 nIdx = rFormatAnchor.GetAnchorContentOffset();
+ pTextNode->DeleteAttributes( RES_TXTATR_FLYCNT, nIdx, nIdx );
+ }
+ else
+ pFormat->GetDoc()->getIDocumentLayoutAccess().DelLayoutFormat(pFormat);
+ }
+
+}
+
+uno::Reference< text::XTextRange > SwXFrame::getAnchor()
+{
+ SolarMutexGuard aGuard;
+ rtl::Reference<SwXTextRange> aRef;
+ SwFrameFormat* pFormat = GetFrameFormat();
+ if(!pFormat)
+ throw uno::RuntimeException();
+
+ const SwFormatAnchor& rAnchor = pFormat->GetAnchor();
+ // return an anchor for non-page bound frames
+ // and for page bound frames that have a page no == NULL and a content position
+ if ((rAnchor.GetAnchorId() != RndStdIds::FLY_AT_PAGE) ||
+ (rAnchor.GetAnchorNode() && !rAnchor.GetPageNum()))
+ {
+ if (rAnchor.GetAnchorId() == RndStdIds::FLY_AT_PARA)
+ { // ensure that SwXTextRange has SwContentIndex
+ aRef = SwXTextRange::CreateXTextRange(*pFormat->GetDoc(), SwPosition(*rAnchor.GetAnchorNode()), nullptr);
+ }
+ else
+ {
+ aRef = SwXTextRange::CreateXTextRange(*pFormat->GetDoc(), *rAnchor.GetContentAnchor(), nullptr);
+ }
+ }
+
+ return aRef;
+}
+
+void SwXFrame::ResetDescriptor()
+{
+ m_bIsDescriptor = false;
+ mxStyleData.clear();
+ mxStyleFamily.clear();
+ m_pProps.reset();
+}
+
+void SwXFrame::attachToRange(uno::Reference<text::XTextRange> const& xTextRange,
+ SwPaM const*const pCopySource)
+{
+ SolarMutexGuard aGuard;
+ if(!IsDescriptor())
+ throw uno::RuntimeException();
+ SwXTextRange* pRange = dynamic_cast<SwXTextRange*>(xTextRange.get());
+ OTextCursorHelper* pCursor = dynamic_cast<OTextCursorHelper*>(xTextRange.get());
+
+ SwDoc* pDoc = pRange ? &pRange->GetDoc() : pCursor ? pCursor->GetDoc() : nullptr;
+ if(!pDoc)
+ throw lang::IllegalArgumentException();
+
+ SwUnoInternalPaM aIntPam(*pDoc);
+ // this now needs to return TRUE
+ ::sw::XTextRangeToSwPaM(aIntPam, xTextRange);
+
+ SwNode& rNode = pDoc->GetNodes().GetEndOfContent();
+ SwPaM aPam(rNode);
+ aPam.Move( fnMoveBackward, GoInDoc );
+
+ SfxItemSetFixed<RES_GRFATR_BEGIN, RES_GRFATR_END-1> aGrSet(pDoc->GetAttrPool());
+
+ SfxItemSetFixed<
+ RES_FRMATR_BEGIN, RES_FRMATR_END-1,
+ RES_UNKNOWNATR_CONTAINER, RES_UNKNOWNATR_CONTAINER,
+
+ // FillAttribute support
+ XATTR_FILL_FIRST, XATTR_FILL_LAST,
+
+ SID_ATTR_BORDER_INNER, SID_ATTR_BORDER_INNER>
+ aFrameSet(pDoc->GetAttrPool() );
+
+ // set correct parent to get the XFILL_NONE FillStyle as needed
+ aFrameSet.SetParent(&pDoc->GetDfltFrameFormat()->GetAttrSet());
+
+ // no the related items need to be added to the set
+ bool bSizeFound;
+ if (!m_pProps->AnyToItemSet(pDoc, aFrameSet, aGrSet, bSizeFound))
+ throw lang::IllegalArgumentException();
+ // a TextRange is handled separately
+ *aPam.GetPoint() = *aIntPam.GetPoint();
+ if(aIntPam.HasMark())
+ {
+ aPam.SetMark();
+ *aPam.GetMark() = *aIntPam.GetMark();
+ }
+
+ RndStdIds eAnchorId = RndStdIds::FLY_AT_PARA;
+ if(const SwFormatAnchor* pItem = aFrameSet.GetItemIfSet(RES_ANCHOR, false) )
+ {
+ eAnchorId = pItem->GetAnchorId();
+ if( RndStdIds::FLY_AT_FLY == eAnchorId &&
+ !aPam.GetPointNode().FindFlyStartNode())
+ {
+ // framebound only where a frame exists
+ SwFormatAnchor aAnchor(RndStdIds::FLY_AT_PARA);
+ aFrameSet.Put(aAnchor);
+ }
+ else if ((RndStdIds::FLY_AT_PAGE == eAnchorId) &&
+ 0 == pItem->GetPageNum() )
+ {
+ SwFormatAnchor aAnchor( *pItem );
+ aAnchor.SetType(RndStdIds::FLY_AT_CHAR); // convert invalid at-page
+ aAnchor.SetAnchor( aPam.GetPoint() );
+ aFrameSet.Put(aAnchor);
+ }
+
+ if (eAnchorId == RndStdIds::FLY_AT_PAGE)
+ {
+ sal_Int16 nRelOrient(aFrameSet.Get(RES_HORI_ORIENT).GetRelationOrient());
+ if (sw::GetAtPageRelOrientation(nRelOrient, true))
+ {
+ SAL_WARN("sw.core", "SwXFrame: fixing invalid horizontal RelOrientation for at-page anchor");
+
+ SwFormatHoriOrient item(aFrameSet.Get(RES_HORI_ORIENT));
+ item.SetRelationOrient(nRelOrient);
+ aFrameSet.Put(item);
+ }
+ }
+ }
+
+ const ::uno::Any* pStyle;
+ SwFrameFormat *pParentFrameFormat = nullptr;
+ if (m_pProps->GetProperty(FN_UNO_FRAME_STYLE_NAME, 0, pStyle))
+ pParentFrameFormat = lcl_GetFrameFormat( *pStyle, pDoc );
+
+ SwFlyFrameFormat* pFormat = nullptr;
+ if( m_eType == FLYCNTTYPE_FRM)
+ {
+ UnoActionContext aCont(pDoc);
+ if (pCopySource)
+ {
+ std::unique_ptr<SwFormatAnchor> pAnchorItem;
+ // the frame is inserted bound to page
+ // to prevent conflicts if the to-be-anchored position is part of the to-be-copied text
+ if (eAnchorId != RndStdIds::FLY_AT_PAGE)
+ {
+ pAnchorItem.reset(aFrameSet.Get(RES_ANCHOR).Clone());
+ aFrameSet.Put( SwFormatAnchor( RndStdIds::FLY_AT_PAGE, 1 ));
+ }
+
+ // park these no longer needed PaMs somewhere safe so MakeFlyAndMove
+ // can delete what it likes without any assert these are pointing to
+ // that content
+ aPam.DeleteMark();
+ aIntPam.DeleteMark();
+ aIntPam.GetPoint()->Assign(*pDoc->GetNodes()[SwNodeOffset(0)]);
+ *aPam.GetPoint() = *aIntPam.GetPoint();
+
+ pFormat = pDoc->MakeFlyAndMove( *pCopySource, aFrameSet,
+ nullptr,
+ pParentFrameFormat );
+ if(pAnchorItem && pFormat)
+ {
+ pFormat->DelFrames();
+ pAnchorItem->SetAnchor( pCopySource->Start() );
+ SfxItemSetFixed<RES_ANCHOR, RES_ANCHOR> aAnchorSet( pDoc->GetAttrPool() );
+ aAnchorSet.Put( std::move(pAnchorItem) );
+ pDoc->SetFlyFrameAttr( *pFormat, aAnchorSet );
+ }
+ }
+ else
+ {
+ pFormat = pDoc->MakeFlySection( RndStdIds::FLY_AT_PARA, aPam.GetPoint(),
+ &aFrameSet, pParentFrameFormat );
+ }
+ if(pFormat)
+ {
+ EndListeningAll();
+ m_pFrameFormat = pFormat;
+ StartListening(pFormat->GetNotifier());
+ if(!m_sName.isEmpty())
+ pDoc->SetFlyName(*pFormat, m_sName);
+ }
+ // wake up the SwXTextFrame
+ static_cast<SwXTextFrame*>(this)->SetDoc( m_bIsDescriptor ? m_pDoc : GetFrameFormat()->GetDoc() );
+ }
+ else if( m_eType == FLYCNTTYPE_GRF)
+ {
+ UnoActionContext aActionContext(pDoc);
+ Graphic aGraphic;
+
+ // Read graphic URL from the descriptor, if it has any.
+ const ::uno::Any* pGraphicURL;
+ if (m_pProps->GetProperty(FN_UNO_GRAPHIC_URL, 0, pGraphicURL))
+ {
+ OUString sGraphicURL;
+ uno::Reference<awt::XBitmap> xBitmap;
+ if (((*pGraphicURL) >>= sGraphicURL) && !sGraphicURL.isEmpty())
+ aGraphic = vcl::graphic::loadFromURL(sGraphicURL);
+ else if ((*pGraphicURL) >>= xBitmap)
+ {
+ uno::Reference<graphic::XGraphic> xGraphic(xBitmap, uno::UNO_QUERY);
+ if (xGraphic.is())
+ aGraphic = xGraphic;
+ }
+ }
+
+ const ::uno::Any* pGraphicAny;
+ const bool bHasGraphic = m_pProps->GetProperty(FN_UNO_GRAPHIC, 0, pGraphicAny);
+ if (bHasGraphic)
+ {
+ uno::Reference<graphic::XGraphic> xGraphic;
+ (*pGraphicAny) >>= xGraphic;
+ aGraphic = Graphic(xGraphic);
+ }
+
+ OUString sFilterName;
+ const uno::Any* pFilterAny;
+ if (m_pProps->GetProperty(FN_UNO_GRAPHIC_FILTER, 0, pFilterAny))
+ {
+ (*pFilterAny) >>= sFilterName;
+ }
+
+ pFormat = pDoc->getIDocumentContentOperations().InsertGraphic(
+ aPam, OUString(), sFilterName, &aGraphic, &aFrameSet, &aGrSet, pParentFrameFormat);
+ if (pFormat)
+ {
+ SwGrfNode *pGrfNd = pDoc->GetNodes()[ pFormat->GetContent().GetContentIdx()
+ ->GetIndex()+1 ]->GetGrfNode();
+ if (pGrfNd)
+ pGrfNd->SetChgTwipSize( !bSizeFound );
+ m_pFrameFormat = pFormat;
+ EndListeningAll();
+ StartListening(m_pFrameFormat->GetNotifier());
+ if(!m_sName.isEmpty())
+ pDoc->SetFlyName(*pFormat, m_sName);
+
+ }
+ const ::uno::Any* pSurroundContour;
+ if (m_pProps->GetProperty(RES_SURROUND, MID_SURROUND_CONTOUR, pSurroundContour))
+ setPropertyValue(UNO_NAME_SURROUND_CONTOUR, *pSurroundContour);
+ const ::uno::Any* pContourOutside;
+ if (m_pProps->GetProperty(RES_SURROUND, MID_SURROUND_CONTOUROUTSIDE, pContourOutside))
+ setPropertyValue(UNO_NAME_CONTOUR_OUTSIDE, *pContourOutside);
+ const ::uno::Any* pContourPoly;
+ if (m_pProps->GetProperty(FN_PARAM_CONTOUR_PP, 0, pContourPoly))
+ setPropertyValue(UNO_NAME_CONTOUR_POLY_POLYGON, *pContourPoly);
+ const ::uno::Any* pPixelContour;
+ if (m_pProps->GetProperty(FN_UNO_IS_PIXEL_CONTOUR, 0, pPixelContour))
+ setPropertyValue(UNO_NAME_IS_PIXEL_CONTOUR, *pPixelContour);
+ const ::uno::Any* pAutoContour;
+ if (m_pProps->GetProperty(FN_UNO_IS_AUTOMATIC_CONTOUR, 0, pAutoContour))
+ setPropertyValue(UNO_NAME_IS_AUTOMATIC_CONTOUR, *pAutoContour);
+ }
+ else
+ {
+ const ::uno::Any* pCLSID = nullptr;
+ const ::uno::Any* pStreamName = nullptr;
+ const ::uno::Any* pEmbeddedObject = nullptr;
+ if (!m_pProps->GetProperty(FN_UNO_CLSID, 0, pCLSID)
+ && !m_pProps->GetProperty(FN_UNO_STREAM_NAME, 0, pStreamName)
+ && !m_pProps->GetProperty(FN_EMBEDDED_OBJECT, 0, pEmbeddedObject))
+ {
+ throw uno::RuntimeException();
+ }
+ if(pCLSID)
+ {
+ OUString aCLSID;
+ SvGlobalName aClassName;
+ uno::Reference < embed::XEmbeddedObject > xIPObj;
+ std::unique_ptr < comphelper::EmbeddedObjectContainer > pCnt;
+ if( (*pCLSID) >>= aCLSID )
+ {
+ if( !aClassName.MakeId( aCLSID ) )
+ {
+ throw lang::IllegalArgumentException("CLSID invalid", nullptr, 0);
+ }
+
+ pCnt.reset( new comphelper::EmbeddedObjectContainer );
+ OUString aName;
+
+ OUString sDocumentBaseURL = pDoc->GetPersist()->getDocumentBaseURL();
+ xIPObj = pCnt->CreateEmbeddedObject(aClassName.GetByteSequence(), aName,
+ &sDocumentBaseURL);
+ }
+ if ( xIPObj.is() )
+ {
+ UnoActionContext aAction(pDoc);
+ pDoc->GetIDocumentUndoRedo().StartUndo(SwUndoId::INSERT, nullptr);
+
+ // tdf#99631 set imported VisibleArea settings of embedded XLSX OLE objects
+ if ( m_nDrawAspect == embed::Aspects::MSOLE_CONTENT
+ && m_nVisibleAreaWidth && m_nVisibleAreaHeight )
+ {
+ sal_Int64 nAspect = m_nDrawAspect;
+ MapUnit aUnit = VCLUnoHelper::UnoEmbed2VCLMapUnit( xIPObj->getMapUnit( nAspect ) );
+ Size aSize( OutputDevice::LogicToLogic(Size( m_nVisibleAreaWidth, m_nVisibleAreaHeight),
+ MapMode(MapUnit::MapTwip), MapMode(aUnit)));
+ awt::Size aSz;
+ aSz.Width = aSize.Width();
+ aSz.Height = aSize.Height();
+ xIPObj->setVisualAreaSize(m_nDrawAspect, aSz);
+ }
+
+ if(!bSizeFound)
+ {
+ //TODO/LATER: how do I transport it to the OLENode?
+ sal_Int64 nAspect = m_nDrawAspect;
+
+ // TODO/LEAN: VisualArea still needs running state
+ (void)svt::EmbeddedObjectRef::TryRunningState( xIPObj );
+
+ // set parent to get correct VisArea(in case of object needing parent printer)
+ uno::Reference < container::XChild > xChild( xIPObj, uno::UNO_QUERY );
+ if ( xChild.is() )
+ xChild->setParent( pDoc->GetDocShell()->GetModel() );
+
+ //The Size should be suggested by the OLE server if not manually set
+ MapUnit aRefMap = VCLUnoHelper::UnoEmbed2VCLMapUnit( xIPObj->getMapUnit( nAspect ) );
+ awt::Size aSize;
+ try
+ {
+ aSize = xIPObj->getVisualAreaSize( nAspect );
+ }
+ catch ( embed::NoVisualAreaSizeException& )
+ {
+ // the default size will be set later
+ }
+
+ Size aSz( aSize.Width, aSize.Height );
+ if ( !aSz.Width() || !aSz.Height() )
+ {
+ aSz.setWidth(5000);
+ aSz.setHeight(5000);
+ aSz = OutputDevice::LogicToLogic(aSz,
+ MapMode(MapUnit::Map100thMM), MapMode(aRefMap));
+ }
+ MapMode aMyMap( MapUnit::MapTwip );
+ aSz = OutputDevice::LogicToLogic(aSz, MapMode(aRefMap), aMyMap);
+ SwFormatFrameSize aFrameSz;
+ aFrameSz.SetSize(aSz);
+ aFrameSet.Put(aFrameSz);
+ }
+ SwFlyFrameFormat* pFormat2 = nullptr;
+
+ ::svt::EmbeddedObjectRef xObjRef( xIPObj, m_nDrawAspect);
+ pFormat2 = pDoc->getIDocumentContentOperations().InsertEmbObject(
+ aPam, xObjRef, &aFrameSet );
+
+ // store main document name to show in the title bar
+ uno::Reference< frame::XTitle > xModelTitle( pDoc->GetDocShell()->GetModel(), css::uno::UNO_QUERY );
+ if( xModelTitle.is() )
+ xIPObj->setContainerName( xModelTitle->getTitle() );
+
+ assert(pFormat2 && "Doc->Insert(notxt) failed.");
+
+ pDoc->GetIDocumentUndoRedo().EndUndo(SwUndoId::INSERT, nullptr);
+ m_pFrameFormat = pFormat2;
+ EndListeningAll();
+ StartListening(m_pFrameFormat->GetNotifier());
+ if(!m_sName.isEmpty())
+ pDoc->SetFlyName(*pFormat2, m_sName);
+ }
+ }
+ else if( pStreamName )
+ {
+ OUString sStreamName;
+ (*pStreamName) >>= sStreamName;
+ pDoc->GetIDocumentUndoRedo().StartUndo(SwUndoId::INSERT, nullptr);
+
+ SwFlyFrameFormat* pFrameFormat = pDoc->getIDocumentContentOperations().InsertOLE(
+ aPam, sStreamName, m_nDrawAspect, &aFrameSet, nullptr);
+
+ // store main document name to show in the title bar
+ SwOLENode* pNd = nullptr;
+ const SwNodeIndex* pIdx = pFrameFormat->GetContent().GetContentIdx();
+ if( pIdx )
+ {
+ SwNodeIndex aIdx( *pIdx, 1 );
+ SwNoTextNode* pNoText = aIdx.GetNode().GetNoTextNode();
+ pNd = pNoText->GetOLENode();
+ }
+ if( pNd )
+ {
+ uno::Reference < embed::XEmbeddedObject > xObj = pNd->GetOLEObj().GetOleRef();
+ if( xObj.is() )
+ {
+ uno::Reference< frame::XTitle > xModelTitle( pDoc->GetDocShell()->GetModel(), css::uno::UNO_QUERY );
+ if( xModelTitle.is() )
+ xObj->setContainerName( xModelTitle->getTitle() );
+ }
+ }
+
+ pDoc->GetIDocumentUndoRedo().EndUndo(SwUndoId::INSERT, nullptr);
+ m_pFrameFormat = pFrameFormat;
+ EndListeningAll();
+ StartListening(m_pFrameFormat->GetNotifier());
+ if(!m_sName.isEmpty())
+ pDoc->SetFlyName(*pFrameFormat, m_sName);
+ }
+ else if (pEmbeddedObject)
+ {
+ uno::Reference< embed::XEmbeddedObject > obj;
+ (*pEmbeddedObject) >>= obj;
+ svt::EmbeddedObjectRef xObj;
+ xObj.Assign( obj, embed::Aspects::MSOLE_CONTENT );
+
+ pDoc->GetIDocumentUndoRedo().StartUndo(SwUndoId::INSERT, nullptr);
+
+ // Do not call here container::XChild(obj)->setParent() and
+ // pDoc->GetPersist()->GetEmbeddedObjectContainer().InsertEmbeddedObject:
+ // they are called indirectly by pDoc->getIDocumentContentOperations().InsertEmbObject
+ // below. Calling them twice will add the same object twice to EmbeddedObjectContainer's
+ // pImpl->maNameToObjectMap, and then it will misbehave in
+ // EmbeddedObjectContainer::StoreAsChildren and SfxObjectShell::SaveCompletedChildren.
+
+ SwFlyFrameFormat* pFrameFormat
+ = pDoc->getIDocumentContentOperations().InsertEmbObject(aPam, xObj, &aFrameSet);
+ pDoc->GetIDocumentUndoRedo().EndUndo(SwUndoId::INSERT, nullptr);
+ m_pFrameFormat = pFrameFormat;
+ EndListeningAll();
+ StartListening(m_pFrameFormat->GetNotifier());
+ if(!m_sName.isEmpty())
+ pDoc->SetFlyName(*pFrameFormat, m_sName);
+ }
+ }
+ if( pFormat && pDoc->getIDocumentDrawModelAccess().GetDrawModel() )
+ GetOrCreateSdrObject(*pFormat);
+ const ::uno::Any* pOrder;
+ if (m_pProps->GetProperty(FN_UNO_Z_ORDER, 0, pOrder))
+ setPropertyValue(UNO_NAME_Z_ORDER, *pOrder);
+ const ::uno::Any* pReplacement;
+ if (m_pProps->GetProperty(FN_UNO_REPLACEMENT_GRAPHIC, 0, pReplacement))
+ setPropertyValue(UNO_NAME_GRAPHIC, *pReplacement);
+ // new attribute Title
+ const ::uno::Any* pTitle;
+ if (m_pProps->GetProperty(FN_UNO_TITLE, 0, pTitle))
+ {
+ setPropertyValue(UNO_NAME_TITLE, *pTitle);
+ }
+ // new attribute Description
+ const ::uno::Any* pDescription;
+ if (m_pProps->GetProperty(FN_UNO_DESCRIPTION, 0, pDescription))
+ {
+ setPropertyValue(UNO_NAME_DESCRIPTION, *pDescription);
+ }
+
+ // For grabbag
+ const uno::Any* pFrameIntropgrabbagItem;
+ if (m_pProps->GetProperty(RES_FRMATR_GRABBAG, 0, pFrameIntropgrabbagItem))
+ {
+ setPropertyValue(UNO_NAME_FRAME_INTEROP_GRAB_BAG, *pFrameIntropgrabbagItem);
+ }
+
+ // reset the flag and delete Descriptor pointer
+ ResetDescriptor();
+}
+
+void SwXFrame::attach(const uno::Reference< text::XTextRange > & xTextRange)
+{
+ SolarMutexGuard g;
+
+ if(IsDescriptor())
+ {
+ attachToRange(xTextRange);
+ return;
+ }
+
+ SwFrameFormat* pFormat = GetFrameFormat();
+ if( !pFormat )
+ return;
+
+ SwDoc* pDoc = pFormat->GetDoc();
+ SwUnoInternalPaM aIntPam(*pDoc);
+ if (!::sw::XTextRangeToSwPaM(aIntPam, xTextRange))
+ throw lang::IllegalArgumentException();
+
+ SfxItemSetFixed<RES_ANCHOR, RES_ANCHOR> aSet( pDoc->GetAttrPool() );
+ aSet.SetParent(&pFormat->GetAttrSet());
+ SwFormatAnchor aAnchor = aSet.Get(RES_ANCHOR);
+
+ if (aAnchor.GetAnchorId() == RndStdIds::FLY_AS_CHAR)
+ {
+ throw lang::IllegalArgumentException(
+ "SwXFrame::attach(): re-anchoring AS_CHAR not supported",
+ *this, 0);
+ }
+
+ aAnchor.SetAnchor( aIntPam.Start() );
+ aSet.Put(aAnchor);
+ pDoc->SetFlyFrameAttr( *pFormat, aSet );
+}
+
+awt::Point SwXFrame::getPosition()
+{
+ throw uno::RuntimeException("position cannot be determined with this method");
+}
+
+void SwXFrame::setPosition(const awt::Point& /*aPosition*/)
+{
+ throw uno::RuntimeException("position cannot be changed with this method");
+}
+
+awt::Size SwXFrame::getSize()
+{
+ const ::uno::Any aVal = getPropertyValue("Size");
+ awt::Size const * pRet = o3tl::doAccess<awt::Size>(aVal);
+ return *pRet;
+}
+
+void SwXFrame::setSize(const awt::Size& aSize)
+{
+ const ::uno::Any aVal(&aSize, ::cppu::UnoType<awt::Size>::get());
+ setPropertyValue("Size", aVal);
+}
+
+OUString SwXFrame::getShapeType()
+{
+ return "FrameShape";
+}
+
+SwXTextFrame::SwXTextFrame( SwDoc *_pDoc ) :
+ SwXTextFrameBaseClass(FLYCNTTYPE_FRM, aSwMapProvider.GetPropertySet(PROPERTY_MAP_TEXT_FRAME), _pDoc ),
+ SwXText(nullptr, CursorType::Frame)
+{
+}
+
+SwXTextFrame::SwXTextFrame(SwFrameFormat& rFormat) :
+ SwXTextFrameBaseClass(rFormat, FLYCNTTYPE_FRM, aSwMapProvider.GetPropertySet(PROPERTY_MAP_TEXT_FRAME)),
+ SwXText(rFormat.GetDoc(), CursorType::Frame)
+{
+
+}
+
+SwXTextFrame::~SwXTextFrame()
+{
+}
+
+rtl::Reference<SwXTextFrame>
+SwXTextFrame::CreateXTextFrame(SwDoc & rDoc, SwFrameFormat *const pFrameFormat)
+{
+ return CreateXFrame<SwXTextFrame>(rDoc, pFrameFormat);
+}
+
+void SAL_CALL SwXTextFrame::acquire( )noexcept
+{
+ SwXFrame::acquire();
+}
+
+void SAL_CALL SwXTextFrame::release( )noexcept
+{
+ SwXFrame::release();
+}
+
+::uno::Any SAL_CALL SwXTextFrame::queryInterface( const uno::Type& aType )
+{
+ ::uno::Any aRet = SwXFrame::queryInterface(aType);
+ if(aRet.getValueType() == cppu::UnoType<void>::get())
+ aRet = SwXText::queryInterface(aType);
+ if(aRet.getValueType() == cppu::UnoType<void>::get())
+ aRet = SwXTextFrameBaseClass::queryInterface(aType);
+ return aRet;
+}
+
+uno::Sequence< uno::Type > SAL_CALL SwXTextFrame::getTypes( )
+{
+ return comphelper::concatSequences(
+ SwXTextFrameBaseClass::getTypes(),
+ SwXFrame::getTypes(),
+ SwXText::getTypes()
+ );
+}
+
+uno::Sequence< sal_Int8 > SAL_CALL SwXTextFrame::getImplementationId( )
+{
+ return css::uno::Sequence<sal_Int8>();
+}
+
+uno::Reference< text::XText > SwXTextFrame::getText()
+{
+ return this;
+}
+
+const SwStartNode *SwXTextFrame::GetStartNode() const
+{
+ const SwStartNode *pSttNd = nullptr;
+
+ const SwFrameFormat* pFormat = GetFrameFormat();
+ if(pFormat)
+ {
+ const SwFormatContent& rFlyContent = pFormat->GetContent();
+ if( rFlyContent.GetContentIdx() )
+ pSttNd = rFlyContent.GetContentIdx()->GetNode().GetStartNode();
+ }
+
+ return pSttNd;
+}
+
+rtl::Reference<SwXTextCursor> SwXTextFrame::createXTextCursor()
+{
+ SwFrameFormat* pFormat = GetFrameFormat();
+ if(!pFormat)
+ throw uno::RuntimeException();
+
+ //save current start node to be able to check if there is content after the table -
+ //otherwise the cursor would be in the body text!
+ const SwNode& rNode = pFormat->GetContent().GetContentIdx()->GetNode();
+ const SwStartNode* pOwnStartNode = rNode.FindSttNodeByType(SwFlyStartNode);
+
+ SwPaM aPam(rNode);
+ aPam.Move(fnMoveForward, GoInNode);
+ SwTableNode* pTableNode = aPam.GetPointNode().FindTableNode();
+ while( pTableNode )
+ {
+ aPam.GetPoint()->Assign( *pTableNode->EndOfSectionNode() );
+ SwContentNode* pCont = GetDoc()->GetNodes().GoNext(aPam.GetPoint());
+ pTableNode = pCont->FindTableNode();
+ }
+
+ const SwStartNode* pNewStartNode =
+ aPam.GetPointNode().FindSttNodeByType(SwFlyStartNode);
+ if(!pNewStartNode || pNewStartNode != pOwnStartNode)
+ {
+ throw uno::RuntimeException("no text available");
+ }
+
+ return new SwXTextCursor(
+ *pFormat->GetDoc(), this, CursorType::Frame, *aPam.GetPoint());
+}
+
+rtl::Reference< SwXTextCursor > SwXTextFrame::createXTextCursorByRange(const uno::Reference< text::XTextRange > & aTextPosition)
+{
+ SwFrameFormat* pFormat = GetFrameFormat();
+ if (!pFormat)
+ throw uno::RuntimeException();
+ SwUnoInternalPaM aPam(*GetDoc());
+ if (!::sw::XTextRangeToSwPaM(aPam, aTextPosition))
+ throw uno::RuntimeException();
+
+ rtl::Reference< SwXTextCursor > aRef;
+ SwNode& rNode = pFormat->GetContent().GetContentIdx()->GetNode();
+ if(aPam.GetPointNode().FindFlyStartNode() == rNode.FindFlyStartNode())
+ {
+ aRef = new SwXTextCursor(*pFormat->GetDoc(), this, CursorType::Frame,
+ *aPam.GetPoint(), aPam.GetMark());
+ }
+
+ return aRef;
+}
+
+uno::Reference< container::XEnumeration > SwXTextFrame::createEnumeration()
+{
+ SolarMutexGuard aGuard;
+ SwFrameFormat* pFormat = GetFrameFormat();
+ if(!pFormat)
+ return nullptr;
+ SwPosition aPos(pFormat->GetContent().GetContentIdx()->GetNode());
+ auto pUnoCursor(GetDoc()->CreateUnoCursor(aPos));
+ pUnoCursor->Move(fnMoveForward, GoInNode);
+ return SwXParagraphEnumeration::Create(this, pUnoCursor, CursorType::Frame);
+}
+
+uno::Type SwXTextFrame::getElementType()
+{
+ return cppu::UnoType<text::XTextRange>::get();
+}
+
+sal_Bool SwXTextFrame::hasElements()
+{
+ return true;
+}
+
+void SwXTextFrame::attach(const uno::Reference< text::XTextRange > & xTextRange)
+{
+ SwXFrame::attach(xTextRange);
+}
+
+uno::Reference< text::XTextRange > SwXTextFrame::getAnchor()
+{
+ SolarMutexGuard aGuard;
+ return SwXFrame::getAnchor();
+}
+
+void SwXTextFrame::dispose()
+{
+ SolarMutexGuard aGuard;
+ SwXFrame::dispose();
+}
+
+void SwXTextFrame::addEventListener(const uno::Reference< lang::XEventListener > & aListener)
+{
+ SwXFrame::addEventListener(aListener);
+}
+
+void SwXTextFrame::removeEventListener(const uno::Reference< lang::XEventListener > & aListener)
+{
+ SwXFrame::removeEventListener(aListener);
+}
+
+OUString SwXTextFrame::getImplementationName()
+{
+ return "SwXTextFrame";
+}
+
+sal_Bool SwXTextFrame::supportsService(const OUString& rServiceName)
+{
+ return cppu::supportsService(this, rServiceName);
+}
+
+uno::Sequence< OUString > SwXTextFrame::getSupportedServiceNames()
+{
+ uno::Sequence < OUString > aRet = SwXFrame::getSupportedServiceNames();
+ aRet.realloc(aRet.getLength() + 2);
+ OUString* pArray = aRet.getArray();
+ pArray[aRet.getLength() - 2] = "com.sun.star.text.TextFrame";
+ pArray[aRet.getLength() - 1] = "com.sun.star.text.Text";
+ return aRet;
+}
+
+uno::Reference<container::XNameReplace > SAL_CALL SwXTextFrame::getEvents()
+{
+ return new SwFrameEventDescriptor( *this );
+}
+
+::uno::Any SwXTextFrame::getPropertyValue(const OUString& rPropertyName)
+{
+ SolarMutexGuard aGuard;
+ ::uno::Any aRet;
+ if(rPropertyName == UNO_NAME_START_REDLINE||
+ rPropertyName == UNO_NAME_END_REDLINE)
+ {
+ //redline can only be returned if it's a living object
+ if(!IsDescriptor())
+ aRet = SwXText::getPropertyValue(rPropertyName);
+ }
+ else
+ aRet = SwXFrame::getPropertyValue(rPropertyName);
+ return aRet;
+}
+
+SwXTextGraphicObject::SwXTextGraphicObject( SwDoc *pDoc )
+ : SwXTextGraphicObjectBaseClass(FLYCNTTYPE_GRF,
+ aSwMapProvider.GetPropertySet(PROPERTY_MAP_TEXT_GRAPHIC), pDoc)
+{
+}
+
+SwXTextGraphicObject::SwXTextGraphicObject(SwFrameFormat& rFormat)
+ : SwXTextGraphicObjectBaseClass(rFormat, FLYCNTTYPE_GRF,
+ aSwMapProvider.GetPropertySet(PROPERTY_MAP_TEXT_GRAPHIC))
+{
+}
+
+SwXTextGraphicObject::~SwXTextGraphicObject()
+{
+}
+
+rtl::Reference<SwXTextGraphicObject>
+SwXTextGraphicObject::CreateXTextGraphicObject(SwDoc & rDoc, SwFrameFormat *const pFrameFormat)
+{
+ return CreateXFrame<SwXTextGraphicObject>(rDoc, pFrameFormat);
+}
+
+OUString SwXTextGraphicObject::getImplementationName()
+{
+ return "SwXTextGraphicObject";
+}
+
+sal_Bool SwXTextGraphicObject::supportsService(const OUString& rServiceName)
+{
+ return cppu::supportsService(this, rServiceName);
+}
+
+uno::Sequence< OUString > SwXTextGraphicObject::getSupportedServiceNames()
+{
+ uno::Sequence < OUString > aRet = SwXFrame::getSupportedServiceNames();
+ aRet.realloc(aRet.getLength() + 1);
+ OUString* pArray = aRet.getArray();
+ pArray[aRet.getLength() - 1] = "com.sun.star.text.TextGraphicObject";
+ return aRet;
+}
+
+uno::Reference<container::XNameReplace> SAL_CALL
+ SwXTextGraphicObject::getEvents()
+{
+ return new SwFrameEventDescriptor( *this );
+}
+
+SwXTextEmbeddedObject::SwXTextEmbeddedObject( SwDoc *pDoc )
+ : SwXTextEmbeddedObjectBaseClass(FLYCNTTYPE_OLE,
+ aSwMapProvider.GetPropertySet(PROPERTY_MAP_EMBEDDED_OBJECT), pDoc)
+{
+}
+
+SwXTextEmbeddedObject::SwXTextEmbeddedObject(SwFrameFormat& rFormat)
+ : SwXTextEmbeddedObjectBaseClass(rFormat, FLYCNTTYPE_OLE,
+ aSwMapProvider.GetPropertySet(PROPERTY_MAP_EMBEDDED_OBJECT))
+{
+}
+
+SwXTextEmbeddedObject::~SwXTextEmbeddedObject()
+{
+}
+
+rtl::Reference<SwXTextEmbeddedObject>
+SwXTextEmbeddedObject::CreateXTextEmbeddedObject(SwDoc & rDoc, SwFrameFormat *const pFrameFormat)
+{
+ return CreateXFrame<SwXTextEmbeddedObject>(rDoc, pFrameFormat);
+}
+
+uno::Reference< lang::XComponent > SwXTextEmbeddedObject::getEmbeddedObject()
+{
+ uno::Reference<embed::XEmbeddedObject> xObj(getExtendedControlOverEmbeddedObject());
+ return xObj.is() ? uno::Reference<lang::XComponent>(xObj->getComponent(), uno::UNO_QUERY) : nullptr;
+}
+
+uno::Reference< embed::XEmbeddedObject > SAL_CALL SwXTextEmbeddedObject::getExtendedControlOverEmbeddedObject()
+{
+ uno::Reference< embed::XEmbeddedObject > xResult;
+ SwFrameFormat* pFormat = GetFrameFormat();
+ if(pFormat)
+ {
+ SwDoc* pDoc = pFormat->GetDoc();
+ const SwFormatContent* pCnt = &pFormat->GetContent();
+ OSL_ENSURE( pCnt->GetContentIdx() &&
+ pDoc->GetNodes()[ pCnt->GetContentIdx()->
+ GetIndex() + 1 ]->GetOLENode(), "no OLE-Node?");
+
+ SwOLENode* pOleNode = pDoc->GetNodes()[ pCnt->GetContentIdx()
+ ->GetIndex() + 1 ]->GetOLENode();
+ xResult = pOleNode->GetOLEObj().GetOleRef();
+ if ( svt::EmbeddedObjectRef::TryRunningState( xResult ) )
+ {
+ // TODO/LATER: the listener registered after client creation should be able to handle scaling, after that the client is not necessary here
+ if ( pDoc->GetDocShell() )
+ pDoc->GetDocShell()->GetIPClient( svt::EmbeddedObjectRef( xResult, embed::Aspects::MSOLE_CONTENT ) );
+
+ uno::Reference < lang::XComponent > xComp( xResult->getComponent(), uno::UNO_QUERY );
+ uno::Reference< util::XModifyBroadcaster > xBrdcst( xComp, uno::UNO_QUERY);
+ uno::Reference< frame::XModel > xModel( xComp, uno::UNO_QUERY);
+ if(xBrdcst.is() && xModel.is() && !m_xOLEListener.is())
+ {
+ m_xOLEListener = new SwXOLEListener(*pFormat, xModel);
+ xBrdcst->addModifyListener( m_xOLEListener );
+ }
+ }
+ }
+ return xResult;
+}
+
+sal_Int64 SAL_CALL SwXTextEmbeddedObject::getAspect()
+{
+ SwFrameFormat* pFormat = GetFrameFormat();
+ if(pFormat)
+ {
+ SwDoc* pDoc = pFormat->GetDoc();
+ const SwFormatContent* pCnt = &pFormat->GetContent();
+ OSL_ENSURE( pCnt->GetContentIdx() &&
+ pDoc->GetNodes()[ pCnt->GetContentIdx()->
+ GetIndex() + 1 ]->GetOLENode(), "no OLE-Node?");
+
+ return pDoc->GetNodes()[ pCnt->GetContentIdx()->GetIndex() + 1 ]->GetOLENode()->GetAspect();
+ }
+
+ return embed::Aspects::MSOLE_CONTENT; // return the default value
+}
+
+void SAL_CALL SwXTextEmbeddedObject::setAspect( sal_Int64 nAspect )
+{
+ SwFrameFormat* pFormat = GetFrameFormat();
+ if(pFormat)
+ {
+ SwDoc* pDoc = pFormat->GetDoc();
+ const SwFormatContent* pCnt = &pFormat->GetContent();
+ OSL_ENSURE( pCnt->GetContentIdx() &&
+ pDoc->GetNodes()[ pCnt->GetContentIdx()->
+ GetIndex() + 1 ]->GetOLENode(), "no OLE-Node?");
+
+ pDoc->GetNodes()[ pCnt->GetContentIdx()->GetIndex() + 1 ]->GetOLENode()->SetAspect( nAspect );
+ }
+}
+
+uno::Reference< graphic::XGraphic > SAL_CALL SwXTextEmbeddedObject::getReplacementGraphic()
+{
+ SwFrameFormat* pFormat = GetFrameFormat();
+ if(pFormat)
+ {
+ SwDoc* pDoc = pFormat->GetDoc();
+ const SwFormatContent* pCnt = &pFormat->GetContent();
+ OSL_ENSURE( pCnt->GetContentIdx() &&
+ pDoc->GetNodes()[ pCnt->GetContentIdx()->
+ GetIndex() + 1 ]->GetOLENode(), "no OLE-Node?");
+
+ const Graphic* pGraphic = pDoc->GetNodes()[ pCnt->GetContentIdx()->GetIndex() + 1 ]->GetOLENode()->GetGraphic();
+ if ( pGraphic )
+ return pGraphic->GetXGraphic();
+ }
+
+ return uno::Reference< graphic::XGraphic >();
+}
+
+OUString SwXTextEmbeddedObject::getImplementationName()
+{
+ return "SwXTextEmbeddedObject";
+}
+
+sal_Bool SwXTextEmbeddedObject::supportsService(const OUString& rServiceName)
+{
+ return cppu::supportsService(this, rServiceName);
+}
+
+uno::Sequence< OUString > SwXTextEmbeddedObject::getSupportedServiceNames()
+{
+ uno::Sequence < OUString > aRet = SwXFrame::getSupportedServiceNames();
+ aRet.realloc(aRet.getLength() + 1);
+ OUString* pArray = aRet.getArray();
+ pArray[aRet.getLength() - 1] = "com.sun.star.text.TextEmbeddedObject";
+ return aRet;
+}
+
+uno::Reference<container::XNameReplace> SAL_CALL
+ SwXTextEmbeddedObject::getEvents()
+{
+ return new SwFrameEventDescriptor( *this );
+}
+
+namespace
+{
+ SwOLENode* lcl_GetOLENode(const SwFormat* pFormat)
+ {
+ if(!pFormat)
+ return nullptr;
+ const SwNodeIndex* pIdx(pFormat->GetContent().GetContentIdx());
+ if(!pIdx)
+ return nullptr;
+ const SwNodeIndex aIdx(*pIdx, 1);
+ return aIdx.GetNode().GetNoTextNode()->GetOLENode();
+ }
+}
+
+SwXOLEListener::SwXOLEListener( SwFormat& rOLEFormat, uno::Reference< XModel > xOLE)
+ : m_pOLEFormat(&rOLEFormat)
+ , m_xOLEModel(std::move(xOLE))
+{
+ StartListening(m_pOLEFormat->GetNotifier());
+}
+
+SwXOLEListener::~SwXOLEListener()
+{}
+
+void SwXOLEListener::modified( const lang::EventObject& /*rEvent*/ )
+{
+ SolarMutexGuard aGuard;
+ const auto pNd = lcl_GetOLENode(m_pOLEFormat);
+ if(!pNd)
+ throw uno::RuntimeException();
+ const auto xIP = pNd->GetOLEObj().GetOleRef();
+ if(xIP.is())
+ {
+ sal_Int32 nState = xIP->getCurrentState();
+ if(nState == embed::EmbedStates::INPLACE_ACTIVE || nState == embed::EmbedStates::UI_ACTIVE)
+ // if the OLE-Node is UI-Active do nothing
+ return;
+ }
+ pNd->SetOLESizeInvalid(true);
+ pNd->GetDoc().SetOLEObjModified();
+}
+
+void SwXOLEListener::disposing( const lang::EventObject& rEvent )
+{
+ SolarMutexGuard aGuard;
+ uno::Reference<util::XModifyListener> xListener( this );
+ uno::Reference<frame::XModel> xModel(rEvent.Source, uno::UNO_QUERY);
+ uno::Reference<util::XModifyBroadcaster> xBrdcst(xModel, uno::UNO_QUERY);
+ if(!xBrdcst.is())
+ return;
+ try
+ {
+ xBrdcst->removeModifyListener(xListener);
+ }
+ catch(uno::Exception const &)
+ {
+ OSL_FAIL("OLE Listener couldn't be removed");
+ }
+}
+
+void SwXOLEListener::Notify( const SfxHint& rHint )
+{
+ if(rHint.GetId() == SfxHintId::Dying)
+ {
+ m_xOLEModel = nullptr;
+ m_pOLEFormat = nullptr;
+ }
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/core/unocore/unoftn.cxx b/sw/source/core/unocore/unoftn.cxx
new file mode 100644
index 0000000000..1a73e2e617
--- /dev/null
+++ b/sw/source/core/unocore/unoftn.cxx
@@ -0,0 +1,538 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <sal/config.h>
+
+#include <comphelper/interfacecontainer4.hxx>
+#include <comphelper/sequence.hxx>
+#include <comphelper/servicehelper.hxx>
+#include <cppuhelper/supportsservice.hxx>
+#include <svl/listener.hxx>
+#include <mutex>
+
+#include <unofootnote.hxx>
+#include <unotextrange.hxx>
+#include <unotextcursor.hxx>
+#include <unoparagraph.hxx>
+#include <unomap.hxx>
+#include <unoprnms.hxx>
+#include <doc.hxx>
+#include <ftnidx.hxx>
+#include <fmtftn.hxx>
+#include <txtftn.hxx>
+#include <ndtxt.hxx>
+#include <unocrsr.hxx>
+#include <svl/itemprop.hxx>
+
+using namespace ::com::sun::star;
+
+namespace {
+
+uno::Sequence< OUString >
+GetSupportedServiceNamesImpl(
+ size_t const nServices, char const*const pServices[])
+{
+ uno::Sequence< OUString > ret(static_cast<sal_Int32>(nServices));
+
+ std::transform(pServices, pServices + nServices, ret.getArray(),
+ [](const char* pService) -> OUString { return OUString::createFromAscii(pService); });
+
+ return ret;
+}
+
+}
+
+class SwXFootnote::Impl
+ : public SvtListener
+{
+public:
+
+ SwXFootnote& m_rThis;
+ unotools::WeakReference<SwXFootnote> m_wThis;
+ const bool m_bIsEndnote;
+ std::mutex m_Mutex; // just for OInterfaceContainerHelper4
+ ::comphelper::OInterfaceContainerHelper4<css::lang::XEventListener> m_EventListeners;
+ bool m_bIsDescriptor;
+ SwFormatFootnote* m_pFormatFootnote;
+ OUString m_sLabel;
+
+ Impl(SwXFootnote& rThis,
+ SwFormatFootnote* const pFootnote,
+ const bool bIsEndnote)
+ : m_rThis(rThis)
+ , m_bIsEndnote(bIsEndnote)
+ , m_bIsDescriptor(nullptr == pFootnote)
+ , m_pFormatFootnote(pFootnote)
+ {
+ m_pFormatFootnote && StartListening(m_pFormatFootnote->GetNotifier());
+ }
+
+ const SwFormatFootnote* GetFootnoteFormat() const {
+ return m_rThis.GetDoc() ? m_pFormatFootnote : nullptr;
+ }
+
+ SwFormatFootnote const& GetFootnoteFormatOrThrow() const {
+ SwFormatFootnote const*const pFootnote( GetFootnoteFormat() );
+ if (!pFootnote) {
+ throw uno::RuntimeException("SwXFootnote: disposed or invalid", nullptr);
+ }
+ return *pFootnote;
+ }
+
+ void Invalidate();
+protected:
+ void Notify(const SfxHint& rHint) override;
+
+};
+
+void SwXFootnote::Impl::Invalidate()
+{
+ EndListeningAll();
+ m_pFormatFootnote = nullptr;
+ m_rThis.SetDoc(nullptr);
+ uno::Reference<uno::XInterface> const xThis(m_wThis);
+ if (!xThis.is())
+ { // fdo#72695: if UNO object is already dead, don't revive it with event
+ return;
+ }
+ lang::EventObject const ev(xThis);
+ std::unique_lock aGuard(m_Mutex);
+ m_EventListeners.disposeAndClear(aGuard, ev);
+}
+
+void SwXFootnote::Impl::Notify(const SfxHint& rHint)
+{
+ if(rHint.GetId() == SfxHintId::Dying)
+ Invalidate();
+}
+
+SwXFootnote::SwXFootnote(const bool bEndnote)
+ : SwXText(nullptr, CursorType::Footnote)
+ , m_pImpl( new SwXFootnote::Impl(*this, nullptr, bEndnote) )
+{
+}
+
+SwXFootnote::SwXFootnote(SwDoc & rDoc, SwFormatFootnote & rFormat)
+ : SwXText(& rDoc, CursorType::Footnote)
+ , m_pImpl( new SwXFootnote::Impl(*this, &rFormat, rFormat.IsEndNote()) )
+{
+}
+
+SwXFootnote::~SwXFootnote()
+{
+}
+
+rtl::Reference<SwXFootnote>
+SwXFootnote::CreateXFootnote(SwDoc & rDoc, SwFormatFootnote *const pFootnoteFormat,
+ bool const isEndnote)
+{
+ // i#105557: do not iterate over the registered clients: race condition
+ rtl::Reference<SwXFootnote> xNote;
+ if (pFootnoteFormat)
+ {
+ xNote = pFootnoteFormat->GetXFootnote();
+ }
+ if (!xNote.is())
+ {
+ xNote = pFootnoteFormat
+ ? new SwXFootnote(rDoc, *pFootnoteFormat)
+ : new SwXFootnote(isEndnote);
+ if (pFootnoteFormat)
+ {
+ pFootnoteFormat->SetXFootnote(xNote);
+ }
+ // need a permanent Reference to initialize m_wThis
+ xNote->m_pImpl->m_wThis = xNote.get();
+ }
+ return xNote;
+}
+
+OUString SAL_CALL
+SwXFootnote::getImplementationName()
+{
+ return "SwXFootnote";
+}
+
+char const*const g_ServicesFootnote[] =
+{
+ "com.sun.star.text.TextContent",
+ "com.sun.star.text.Footnote",
+ "com.sun.star.text.Text",
+ "com.sun.star.text.Endnote", // NB: only supported for endnotes!
+};
+
+const size_t g_nServicesEndnote( SAL_N_ELEMENTS(g_ServicesFootnote) );
+
+const size_t g_nServicesFootnote( g_nServicesEndnote - 1 ); // NB: omit!
+
+sal_Bool SAL_CALL SwXFootnote::supportsService(const OUString& rServiceName)
+{
+ return cppu::supportsService(this, rServiceName);
+}
+
+uno::Sequence< OUString > SAL_CALL
+SwXFootnote::getSupportedServiceNames()
+{
+ SolarMutexGuard g;
+ return GetSupportedServiceNamesImpl(
+ (m_pImpl->m_bIsEndnote) ? g_nServicesEndnote : g_nServicesFootnote,
+ g_ServicesFootnote);
+}
+
+uno::Sequence< uno::Type > SAL_CALL
+SwXFootnote::getTypes()
+{
+ const uno::Sequence< uno::Type > aTypes = SwXFootnote_Base::getTypes();
+ const uno::Sequence< uno::Type > aTextTypes = SwXText::getTypes();
+ return ::comphelper::concatSequences(aTypes, aTextTypes);
+}
+
+uno::Sequence< sal_Int8 > SAL_CALL
+SwXFootnote::getImplementationId()
+{
+ return css::uno::Sequence<sal_Int8>();
+}
+
+uno::Any SAL_CALL
+SwXFootnote::queryInterface(const uno::Type& rType)
+{
+ const uno::Any ret = SwXFootnote_Base::queryInterface(rType);
+ return (ret.getValueType() == cppu::UnoType<void>::get())
+ ? SwXText::queryInterface(rType)
+ : ret;
+}
+
+OUString SAL_CALL SwXFootnote::getLabel()
+{
+ SolarMutexGuard aGuard;
+
+ OUString sRet;
+ SwFormatFootnote const*const pFormat = m_pImpl->GetFootnoteFormat();
+ if(pFormat)
+ {
+ sRet = pFormat->GetNumStr();
+ }
+ else if (m_pImpl->m_bIsDescriptor)
+ {
+ sRet = m_pImpl->m_sLabel;
+ }
+ else
+ {
+ throw uno::RuntimeException();
+ }
+ return sRet;
+}
+
+void SAL_CALL
+SwXFootnote::setLabel(const OUString& aLabel)
+{
+ SolarMutexGuard aGuard;
+ OUString newLabel(aLabel);
+ //new line must not occur as footnote label
+ if(newLabel.indexOf('\n') >=0 )
+ {
+ newLabel = newLabel.replace('\n', ' ');
+ }
+ SwFormatFootnote const*const pFormat = m_pImpl->GetFootnoteFormat();
+ if(pFormat)
+ {
+ const SwTextFootnote* pTextFootnote = pFormat->GetTextFootnote();
+ OSL_ENSURE(pTextFootnote, "No TextNode?");
+ SwTextNode& rTextNode = const_cast<SwTextNode&>(pTextFootnote->GetTextNode());
+
+ SwPaM aPam(rTextNode, pTextFootnote->GetStart());
+ GetDoc()->SetCurFootnote(aPam, newLabel, pFormat->IsEndNote());
+ }
+ else if (m_pImpl->m_bIsDescriptor)
+ {
+ m_pImpl->m_sLabel = newLabel;
+ }
+ else
+ {
+ throw uno::RuntimeException();
+ }
+}
+
+void SAL_CALL
+SwXFootnote::attach(const uno::Reference< text::XTextRange > & xTextRange)
+{
+ SolarMutexGuard aGuard;
+
+ if (!m_pImpl->m_bIsDescriptor)
+ {
+ throw uno::RuntimeException();
+ }
+ SwXTextRange *const pRange = dynamic_cast<SwXTextRange*>(xTextRange.get());
+ OTextCursorHelper *const pCursor = dynamic_cast<OTextCursorHelper*>(xTextRange.get());
+ SwDoc *const pNewDoc =
+ pRange ? &pRange->GetDoc() : (pCursor ? pCursor->GetDoc() : nullptr);
+ if (!pNewDoc)
+ {
+ throw lang::IllegalArgumentException();
+ }
+
+ SwUnoInternalPaM aPam(*pNewDoc);
+ // this now needs to return TRUE
+ ::sw::XTextRangeToSwPaM(aPam, xTextRange);
+
+ UnoActionContext aCont(pNewDoc);
+ pNewDoc->getIDocumentContentOperations().DeleteAndJoin(aPam);
+ aPam.DeleteMark();
+ SwFormatFootnote aFootNote(m_pImpl->m_bIsEndnote);
+ if (!m_pImpl->m_sLabel.isEmpty())
+ {
+ aFootNote.SetNumStr(m_pImpl->m_sLabel);
+ }
+
+ SwXTextCursor const*const pTextCursor(
+ dynamic_cast<SwXTextCursor*>(pCursor));
+ const bool bForceExpandHints( pTextCursor && pTextCursor->IsAtEndOfMeta() );
+ const SetAttrMode nInsertFlags = bForceExpandHints
+ ? SetAttrMode::FORCEHINTEXPAND
+ : SetAttrMode::DEFAULT;
+
+ pNewDoc->getIDocumentContentOperations().InsertPoolItem(aPam, aFootNote, nInsertFlags);
+
+ SwTextFootnote *const pTextAttr = static_cast<SwTextFootnote*>(
+ aPam.GetPointNode().GetTextNode()->GetTextAttrForCharAt(
+ aPam.GetPoint()->GetContentIndex()-1, RES_TXTATR_FTN ));
+
+ if (pTextAttr)
+ {
+ m_pImpl->EndListeningAll();
+ SwFormatFootnote* pFootnote = const_cast<SwFormatFootnote*>(&pTextAttr->GetFootnote());
+ m_pImpl->m_pFormatFootnote = pFootnote;
+ m_pImpl->StartListening(pFootnote->GetNotifier());
+ // force creation of sequence id - is used for references
+ if (pNewDoc->IsInReading())
+ {
+ pTextAttr->SetSeqNo(pNewDoc->GetFootnoteIdxs().size());
+ }
+ else
+ {
+ pTextAttr->SetSeqRefNo();
+ }
+ }
+ m_pImpl->m_bIsDescriptor = false;
+ SetDoc(pNewDoc);
+}
+
+uno::Reference< text::XTextRange > SAL_CALL
+SwXFootnote::getAnchor()
+{
+ SolarMutexGuard aGuard;
+ return m_pImpl->GetFootnoteFormatOrThrow().getAnchor(*GetDoc());
+}
+
+void SAL_CALL SwXFootnote::dispose()
+{
+ SolarMutexGuard aGuard;
+
+ SwFormatFootnote const& rFormat( m_pImpl->GetFootnoteFormatOrThrow() );
+
+ SwTextFootnote const*const pTextFootnote = rFormat.GetTextFootnote();
+ OSL_ENSURE(pTextFootnote, "no TextNode?");
+ SwTextNode& rTextNode = const_cast<SwTextNode&>(pTextFootnote->GetTextNode());
+ const sal_Int32 nPos = pTextFootnote->GetStart();
+ SwPaM aPam(rTextNode, nPos, rTextNode, nPos+1);
+ GetDoc()->getIDocumentContentOperations().DeleteAndJoin( aPam );
+}
+
+void SAL_CALL
+SwXFootnote::addEventListener(
+ const uno::Reference< lang::XEventListener > & xListener)
+{
+ // no need to lock here as m_pImpl is const and container threadsafe
+ std::unique_lock aGuard(m_pImpl->m_Mutex);
+ m_pImpl->m_EventListeners.addInterface(aGuard, xListener);
+}
+
+void SAL_CALL
+SwXFootnote::removeEventListener(
+ const uno::Reference< lang::XEventListener > & xListener)
+{
+ // no need to lock here as m_pImpl is const and container threadsafe
+ std::unique_lock aGuard(m_pImpl->m_Mutex);
+ m_pImpl->m_EventListeners.removeInterface(aGuard, xListener);
+}
+
+const SwStartNode *SwXFootnote::GetStartNode() const
+{
+ SwFormatFootnote const*const pFormat = m_pImpl->GetFootnoteFormat();
+ if(pFormat)
+ {
+ const SwTextFootnote* pTextFootnote = pFormat->GetTextFootnote();
+ if( pTextFootnote )
+ {
+ return pTextFootnote->GetStartNode()->GetNode().GetStartNode();
+ }
+ }
+ return nullptr;
+}
+
+rtl::Reference< SwXTextCursor >
+SwXFootnote::createXTextCursor()
+{
+ SwFormatFootnote const& rFormat( m_pImpl->GetFootnoteFormatOrThrow() );
+
+ SwTextFootnote const*const pTextFootnote = rFormat.GetTextFootnote();
+ SwPosition aPos( *pTextFootnote->GetStartNode() );
+ rtl::Reference<SwXTextCursor> pXCursor =
+ new SwXTextCursor(*GetDoc(), this, CursorType::Footnote, aPos);
+ auto& rUnoCursor(pXCursor->GetCursor());
+ rUnoCursor.Move(fnMoveForward, GoInNode);
+ return pXCursor;
+}
+
+rtl::Reference< SwXTextCursor >
+SwXFootnote::createXTextCursorByRange(
+ const uno::Reference< text::XTextRange > & xTextPosition)
+{
+ SwFormatFootnote const& rFormat( m_pImpl->GetFootnoteFormatOrThrow() );
+
+ SwUnoInternalPaM aPam(*GetDoc());
+ if (!::sw::XTextRangeToSwPaM(aPam, xTextPosition))
+ {
+ throw uno::RuntimeException();
+ }
+
+ SwTextFootnote const*const pTextFootnote = rFormat.GetTextFootnote();
+ SwNode const*const pFootnoteStartNode = &pTextFootnote->GetStartNode()->GetNode();
+
+ const SwNode* pStart = aPam.GetPointNode().FindFootnoteStartNode();
+ if (pStart != pFootnoteStartNode)
+ {
+ throw uno::RuntimeException();
+ }
+
+ const rtl::Reference< SwXTextCursor > xRet =
+ new SwXTextCursor(*GetDoc(), this, CursorType::Footnote,
+ *aPam.GetPoint(), aPam.GetMark());
+ return xRet;
+}
+
+uno::Reference< container::XEnumeration > SAL_CALL
+SwXFootnote::createEnumeration()
+{
+ SolarMutexGuard aGuard;
+
+ SwFormatFootnote const& rFormat( m_pImpl->GetFootnoteFormatOrThrow() );
+
+ SwTextFootnote const*const pTextFootnote = rFormat.GetTextFootnote();
+ SwPosition aPos( *pTextFootnote->GetStartNode() );
+ auto pUnoCursor(GetDoc()->CreateUnoCursor(aPos));
+ pUnoCursor->Move(fnMoveForward, GoInNode);
+ return SwXParagraphEnumeration::Create(this, pUnoCursor, CursorType::Footnote);
+}
+
+uno::Type SAL_CALL SwXFootnote::getElementType()
+{
+ return cppu::UnoType<text::XTextRange>::get();
+}
+
+sal_Bool SAL_CALL SwXFootnote::hasElements()
+{
+ return true;
+}
+
+uno::Reference< beans::XPropertySetInfo > SAL_CALL
+SwXFootnote::getPropertySetInfo()
+{
+ SolarMutexGuard g;
+ static uno::Reference< beans::XPropertySetInfo > xRet =
+ aSwMapProvider.GetPropertySet(PROPERTY_MAP_FOOTNOTE)
+ ->getPropertySetInfo();
+ return xRet;
+}
+
+void SAL_CALL
+SwXFootnote::setPropertyValue(const OUString&, const uno::Any&)
+{
+ //no values to be set
+ throw lang::IllegalArgumentException();
+}
+
+uno::Any SAL_CALL
+SwXFootnote::getPropertyValue(const OUString& rPropertyName)
+{
+ SolarMutexGuard aGuard;
+
+ uno::Any aRet;
+ if (! ::sw::GetDefaultTextContentValue(aRet, rPropertyName))
+ {
+ if (rPropertyName == UNO_NAME_START_REDLINE ||
+ rPropertyName == UNO_NAME_END_REDLINE)
+ {
+ //redline can only be returned if it's a living object
+ if (!m_pImpl->m_bIsDescriptor)
+ {
+ aRet = SwXText::getPropertyValue(rPropertyName);
+ }
+ }
+ else if (rPropertyName == UNO_NAME_REFERENCE_ID)
+ {
+ SwFormatFootnote const*const pFormat = m_pImpl->GetFootnoteFormat();
+ if (pFormat)
+ {
+ SwTextFootnote const*const pTextFootnote = pFormat->GetTextFootnote();
+ OSL_ENSURE(pTextFootnote, "no TextNode?");
+ aRet <<= static_cast<sal_Int16>(pTextFootnote->GetSeqRefNo());
+ }
+ }
+ else
+ {
+ throw beans::UnknownPropertyException(rPropertyName);
+ }
+ }
+ return aRet;
+}
+
+void SAL_CALL
+SwXFootnote::addPropertyChangeListener(
+ const OUString& /*rPropertyName*/,
+ const uno::Reference< beans::XPropertyChangeListener >& /*xListener*/)
+{
+ OSL_FAIL("SwXFootnote::addPropertyChangeListener(): not implemented");
+}
+
+void SAL_CALL
+SwXFootnote::removePropertyChangeListener(
+ const OUString& /*rPropertyName*/,
+ const uno::Reference< beans::XPropertyChangeListener >& /*xListener*/)
+{
+ OSL_FAIL("SwXFootnote::removePropertyChangeListener(): not implemented");
+}
+
+void SAL_CALL
+SwXFootnote::addVetoableChangeListener(
+ const OUString& /*rPropertyName*/,
+ const uno::Reference< beans::XVetoableChangeListener >& /*xListener*/)
+{
+ OSL_FAIL("SwXFootnote::addVetoableChangeListener(): not implemented");
+}
+
+void SAL_CALL
+SwXFootnote::removeVetoableChangeListener(
+ const OUString& /*rPropertyName*/,
+ const uno::Reference< beans::XVetoableChangeListener >& /*xListener*/)
+{
+ OSL_FAIL("SwXFootnote::removeVetoableChangeListener(): not implemented");
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/core/unocore/unoidx.cxx b/sw/source/core/unocore/unoidx.cxx
new file mode 100644
index 0000000000..3617c22b8d
--- /dev/null
+++ b/sw/source/core/unocore/unoidx.cxx
@@ -0,0 +1,3086 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <memory>
+#include <unoidx.hxx>
+#include <unoidxcoll.hxx>
+
+#include <com/sun/star/beans/PropertyAttribute.hpp>
+#include <com/sun/star/container/XIndexReplace.hpp>
+#include <com/sun/star/frame/XModel.hpp>
+#include <com/sun/star/lang/IndexOutOfBoundsException.hpp>
+#include <com/sun/star/text/ChapterFormat.hpp>
+#include <com/sun/star/text/ReferenceFieldPart.hpp>
+#include <com/sun/star/text/BibliographyDataField.hpp>
+#include <com/sun/star/text/XTextDocument.hpp>
+
+#include <comphelper/interfacecontainer4.hxx>
+#include <cppuhelper/supportsservice.hxx>
+#include <tools/UnitConversion.hxx>
+#include <vcl/svapp.hxx>
+#include <i18nlangtag/languagetag.hxx>
+#include <editeng/memberids.h>
+#include <swtypes.hxx>
+#include <shellres.hxx>
+#include <viewsh.hxx>
+#include <doc.hxx>
+#include <IDocumentLayoutAccess.hxx>
+#include <docary.hxx>
+#include <fmtcntnt.hxx>
+#include <unomap.hxx>
+#include <unotextrange.hxx>
+#include <unotextcursor.hxx>
+#include <unosection.hxx>
+#include <doctxm.hxx>
+#include <txttxmrk.hxx>
+#include <ndtxt.hxx>
+#include <docsh.hxx>
+#include <chpfld.hxx>
+#include <editsh.hxx>
+#include <SwStyleNameMapper.hxx>
+#include <strings.hrc>
+#include <comphelper/servicehelper.hxx>
+#include <comphelper/string.hxx>
+#include <cppuhelper/implbase.hxx>
+#include <svl/itemprop.hxx>
+#include <svl/listener.hxx>
+#include <mutex>
+
+using namespace ::com::sun::star;
+
+/// @throws lang::IllegalArgumentException
+template<typename T>
+static T
+lcl_AnyToType(uno::Any const& rVal)
+{
+ T aRet{};
+ if(!(rVal >>= aRet))
+ {
+ throw lang::IllegalArgumentException();
+ }
+ return aRet;
+}
+
+/// @throws lang::IllegalArgumentException
+template<typename T>
+static void lcl_AnyToBitMask(uno::Any const& rValue,
+ T & rBitMask, const T nBit)
+{
+ rBitMask = lcl_AnyToType<bool>(rValue)
+ ? (rBitMask | nBit)
+ : (rBitMask & ~nBit);
+}
+
+template<typename T>
+static void lcl_BitMaskToAny(uno::Any & o_rValue,
+ const T nBitMask, const T nBit)
+{
+ const bool bRet(nBitMask & nBit);
+ o_rValue <<= bRet;
+}
+
+static void
+lcl_ReAssignTOXType(SwDoc& rDoc, SwTOXBase& rTOXBase, const OUString& rNewName)
+{
+ const sal_uInt16 nUserCount = rDoc.GetTOXTypeCount( TOX_USER );
+ const SwTOXType* pNewType = nullptr;
+ for(sal_uInt16 nUser = 0; nUser < nUserCount; nUser++)
+ {
+ const SwTOXType* pType = rDoc.GetTOXType( TOX_USER, nUser );
+ if (pType->GetTypeName()==rNewName)
+ {
+ pNewType = pType;
+ break;
+ }
+ }
+ if(!pNewType)
+ {
+ SwTOXType aNewType(rDoc, TOX_USER, rNewName);
+ pNewType = rDoc.InsertTOXType( aNewType );
+ }
+
+ rTOXBase.RegisterToTOXType( *const_cast<SwTOXType*>(pNewType) );
+}
+
+constexpr OUString cUserDefined = u"User-Defined"_ustr;
+const char cUserSuffix[] = " (user)";
+#define USER_LEN 12
+#define USER_AND_SUFFIXLEN 19
+
+static void lcl_ConvertTOUNameToProgrammaticName(OUString& rTmp)
+{
+ ShellResource* pShellRes = SwViewShell::GetShellRes();
+
+ if(rTmp==pShellRes->aTOXUserName)
+ {
+ rTmp = cUserDefined;
+ }
+ // if the version is not English but the alternative index's name is
+ // "User-Defined" a " (user)" is appended
+ else if(rTmp == cUserDefined)
+ {
+ rTmp += cUserSuffix;
+ }
+}
+
+static void
+lcl_ConvertTOUNameToUserName(OUString& rTmp)
+{
+ ShellResource* pShellRes = SwViewShell::GetShellRes();
+ if (rTmp == cUserDefined)
+ {
+ rTmp = pShellRes->aTOXUserName;
+ }
+ else if (pShellRes->aTOXUserName != cUserDefined &&
+ USER_AND_SUFFIXLEN == rTmp.getLength())
+ {
+ //make sure that in non-English versions the " (user)" suffix is removed
+ if (rTmp.startsWith(cUserDefined) &&
+ rTmp.match(cUserSuffix, USER_LEN))
+ {
+ rTmp = cUserDefined;
+ }
+ }
+}
+
+typedef ::cppu::WeakImplHelper
+< lang::XServiceInfo
+, container::XIndexReplace
+> SwXDocumentIndexStyleAccess_Base;
+
+class SwXDocumentIndex::StyleAccess_Impl
+ : public SwXDocumentIndexStyleAccess_Base
+{
+
+private:
+ /// can be destroyed threadsafely, so no UnoImplPtr here
+ ::rtl::Reference<SwXDocumentIndex> m_xParent;
+
+ virtual ~StyleAccess_Impl() override;
+
+public:
+ explicit StyleAccess_Impl(SwXDocumentIndex& rParentIdx);
+
+ // XServiceInfo
+ virtual OUString SAL_CALL getImplementationName() override;
+ virtual sal_Bool SAL_CALL
+ supportsService(const OUString& rServiceName) override;
+ virtual uno::Sequence< OUString > SAL_CALL
+ getSupportedServiceNames() override;
+
+ // XElementAccess
+ virtual uno::Type SAL_CALL getElementType() override;
+ virtual sal_Bool SAL_CALL hasElements() override;
+
+ // XIndexAccess
+ virtual sal_Int32 SAL_CALL getCount() override;
+ virtual uno::Any SAL_CALL getByIndex(sal_Int32 nIndex) override;
+
+ // XIndexReplace
+ virtual void SAL_CALL
+ replaceByIndex(sal_Int32 Index, const uno::Any& rElement) override;
+
+};
+
+typedef ::cppu::WeakImplHelper
+< lang::XServiceInfo
+, container::XIndexReplace
+> SwXDocumentIndexTokenAccess_Base;
+
+class SwXDocumentIndex::TokenAccess_Impl
+ : public SwXDocumentIndexTokenAccess_Base
+{
+
+private:
+ /// can be destroyed threadsafely, so no UnoImplPtr here
+ ::rtl::Reference<SwXDocumentIndex> m_xParent;
+
+ virtual ~TokenAccess_Impl() override;
+
+public:
+
+ explicit TokenAccess_Impl(SwXDocumentIndex& rParentIdx);
+
+ // XServiceInfo
+ virtual OUString SAL_CALL getImplementationName() override;
+ virtual sal_Bool SAL_CALL
+ supportsService(const OUString& rServiceName) override;
+ virtual uno::Sequence< OUString > SAL_CALL
+ getSupportedServiceNames() override;
+
+ // XElementAccess
+ virtual uno::Type SAL_CALL getElementType() override;
+ virtual sal_Bool SAL_CALL hasElements() override;
+
+ // XIndexAccess
+ virtual sal_Int32 SAL_CALL getCount() override;
+ virtual uno::Any SAL_CALL getByIndex(sal_Int32 nIndex) override;
+
+ // XIndexReplace
+ virtual void SAL_CALL
+ replaceByIndex(sal_Int32 Index, const uno::Any& rElement) override;
+
+};
+
+namespace {
+
+class SwDocIndexDescriptorProperties_Impl
+{
+private:
+ std::unique_ptr<SwTOXBase> m_pTOXBase;
+ OUString m_sUserTOXTypeName;
+
+public:
+ explicit SwDocIndexDescriptorProperties_Impl(SwTOXType const*const pType);
+
+ SwTOXBase & GetTOXBase() { return *m_pTOXBase; }
+ const OUString& GetTypeName() const { return m_sUserTOXTypeName; }
+ void SetTypeName(const OUString& rSet) { m_sUserTOXTypeName = rSet; }
+};
+
+}
+
+SwDocIndexDescriptorProperties_Impl::SwDocIndexDescriptorProperties_Impl(
+ SwTOXType const*const pType)
+{
+ SwForm aForm(pType->GetType());
+ m_pTOXBase.reset(new SwTOXBase(pType, aForm,
+ SwTOXElement::Mark, pType->GetTypeName()));
+ if(pType->GetType() == TOX_CONTENT || pType->GetType() == TOX_USER)
+ {
+ m_pTOXBase->SetLevel(MAXLEVEL);
+ }
+ m_sUserTOXTypeName = pType->GetTypeName();
+}
+
+static sal_uInt16
+lcl_TypeToPropertyMap_Index(const TOXTypes eType)
+{
+ switch (eType)
+ {
+ case TOX_INDEX: return PROPERTY_MAP_INDEX_IDX;
+ case TOX_CONTENT: return PROPERTY_MAP_INDEX_CNTNT;
+ case TOX_TABLES: return PROPERTY_MAP_INDEX_TABLES;
+ case TOX_ILLUSTRATIONS: return PROPERTY_MAP_INDEX_ILLUSTRATIONS;
+ case TOX_OBJECTS: return PROPERTY_MAP_INDEX_OBJECTS;
+ case TOX_AUTHORITIES: return PROPERTY_MAP_BIBLIOGRAPHY;
+ //case TOX_USER:
+ default:
+ return PROPERTY_MAP_INDEX_USER;
+ }
+}
+
+class SwXDocumentIndex::Impl final: public SvtListener
+{
+private:
+ SwSectionFormat* m_pFormat;
+
+public:
+ unotools::WeakReference<SwXDocumentIndex> m_wThis;
+ std::mutex m_Mutex; // just for OInterfaceContainerHelper4
+ ::comphelper::OInterfaceContainerHelper4<util::XRefreshListener> m_RefreshListeners;
+ ::comphelper::OInterfaceContainerHelper4<lang::XEventListener> m_EventListeners;
+ SfxItemPropertySet const& m_rPropSet;
+ const TOXTypes m_eTOXType;
+ bool m_bIsDescriptor;
+ SwDoc* m_pDoc;
+ std::optional<SwDocIndexDescriptorProperties_Impl> m_oProps;
+ uno::WeakReference<container::XIndexReplace> m_wStyleAccess;
+ uno::WeakReference<container::XIndexReplace> m_wTokenAccess;
+
+ Impl(SwDoc& rDoc, const TOXTypes eType, SwTOXBaseSection *const pBaseSection)
+ : m_pFormat(pBaseSection ? pBaseSection->GetFormat() : nullptr)
+ , m_rPropSet(*aSwMapProvider.GetPropertySet(lcl_TypeToPropertyMap_Index(eType)))
+ , m_eTOXType(eType)
+ , m_bIsDescriptor(nullptr == pBaseSection)
+ , m_pDoc(&rDoc)
+ , m_oProps(m_bIsDescriptor
+ ? std::optional<SwDocIndexDescriptorProperties_Impl>(rDoc.GetTOXType(eType, 0))
+ : std::nullopt)
+ {
+ if(m_pFormat)
+ StartListening(m_pFormat->GetNotifier());
+ }
+
+ void SetSectionFormat(SwSectionFormat& rFormat)
+ {
+ EndListeningAll();
+ m_pFormat = &rFormat;
+ StartListening(rFormat.GetNotifier());
+ }
+
+ SwSectionFormat* GetSectionFormat() const {
+ return m_pFormat;
+ }
+
+ SwTOXBase & GetTOXSectionOrThrow() const
+ {
+ SwSectionFormat *const pSectionFormat(GetSectionFormat());
+ SwTOXBase *const pTOXSection( m_bIsDescriptor
+ ? &const_cast<SwDocIndexDescriptorProperties_Impl&>(*m_oProps).GetTOXBase()
+ : (pSectionFormat
+ ? static_cast<SwTOXBaseSection*>(pSectionFormat->GetSection())
+ : nullptr));
+ if (!pTOXSection)
+ {
+ throw uno::RuntimeException(
+ "SwXDocumentIndex: disposed or invalid", nullptr);
+ }
+ return *pTOXSection;
+ }
+
+ sal_Int32 GetFormMax() const
+ {
+ SwTOXBase & rSection( GetTOXSectionOrThrow() );
+ return m_bIsDescriptor
+ ? SwForm::GetFormMaxLevel(m_eTOXType)
+ : rSection.GetTOXForm().GetFormMax();
+ }
+ virtual void Notify(const SfxHint&) override;
+
+};
+
+void SwXDocumentIndex::Impl::Notify(const SfxHint& rHint)
+{
+ if (rHint.GetId() == SfxHintId::SwLegacyModify)
+ {
+ auto pLegacy = static_cast<const sw::LegacyModifyHint*>(&rHint);
+ if(pLegacy->m_pOld && pLegacy->m_pOld->Which() == RES_REMOVE_UNO_OBJECT)
+ m_pFormat = nullptr;
+ }
+ else if(rHint.GetId() == SfxHintId::Dying)
+ m_pFormat = nullptr;
+ if(!m_pFormat)
+ {
+ EndListeningAll();
+ rtl::Reference<SwXDocumentIndex> const xThis(m_wThis);
+ if (!xThis.is())
+ { // fdo#72695: if UNO object is already dead, don't revive it with event
+ return;
+ }
+ std::unique_lock g(m_Mutex);
+ lang::EventObject const ev(xThis->getXWeak());
+ m_RefreshListeners.disposeAndClear(g, ev);
+ m_EventListeners.disposeAndClear(g, ev);
+ }
+}
+
+SwXDocumentIndex::SwXDocumentIndex(
+ SwTOXBaseSection & rBaseSection, SwDoc & rDoc)
+ : m_pImpl( new SwXDocumentIndex::Impl(
+ rDoc, rBaseSection.SwTOXBase::GetType(), & rBaseSection) )
+{
+}
+
+SwXDocumentIndex::SwXDocumentIndex(const TOXTypes eType, SwDoc& rDoc)
+ : m_pImpl( new SwXDocumentIndex::Impl(rDoc, eType, nullptr) )
+{
+}
+
+SwXDocumentIndex::~SwXDocumentIndex()
+{
+}
+
+rtl::Reference<SwXDocumentIndex>
+SwXDocumentIndex::CreateXDocumentIndex(
+ SwDoc & rDoc, SwTOXBaseSection * pSection, TOXTypes const eTypes)
+{
+ // re-use existing SwXDocumentIndex
+ // #i105557#: do not iterate over the registered clients: race condition
+ rtl::Reference<SwXDocumentIndex> xIndex;
+ if (pSection)
+ {
+ SwSectionFormat const *const pFormat = pSection->GetFormat();
+ xIndex = dynamic_cast<SwXDocumentIndex*>(pFormat->GetXObject().get().get());
+ }
+ if (!xIndex.is())
+ {
+ xIndex = pSection
+ ? new SwXDocumentIndex(*pSection, rDoc)
+ : new SwXDocumentIndex(eTypes, rDoc);
+ if (pSection)
+ {
+ pSection->GetFormat()->SetXObject(xIndex->getXWeak());
+ }
+ // need a permanent Reference to initialize m_wThis
+ xIndex->m_pImpl->m_wThis = xIndex.get();
+ }
+ return xIndex;
+}
+
+OUString SAL_CALL
+SwXDocumentIndex::getImplementationName()
+{
+ return "SwXDocumentIndex";
+}
+
+sal_Bool SAL_CALL
+SwXDocumentIndex::supportsService(const OUString& rServiceName)
+{
+ return cppu::supportsService(this, rServiceName);
+}
+
+uno::Sequence< OUString > SAL_CALL
+SwXDocumentIndex::getSupportedServiceNames()
+{
+ SolarMutexGuard g;
+
+ uno::Sequence< OUString > aRet(2);
+ OUString* pArray = aRet.getArray();
+ pArray[0] = "com.sun.star.text.BaseIndex";
+ switch (m_pImpl->m_eTOXType)
+ {
+ case TOX_INDEX:
+ pArray[1] = "com.sun.star.text.DocumentIndex";
+ break;
+ case TOX_CONTENT:
+ pArray[1] = "com.sun.star.text.ContentIndex";
+ break;
+ case TOX_TABLES:
+ pArray[1] = "com.sun.star.text.TableIndex";
+ break;
+ case TOX_ILLUSTRATIONS:
+ pArray[1] = "com.sun.star.text.IllustrationsIndex";
+ break;
+ case TOX_OBJECTS:
+ pArray[1] = "com.sun.star.text.ObjectIndex";
+ break;
+ case TOX_AUTHORITIES:
+ pArray[1] = "com.sun.star.text.Bibliography";
+ break;
+ //case TOX_USER:
+ default:
+ pArray[1] = "com.sun.star.text.UserDefinedIndex";
+ }
+ return aRet;
+}
+
+OUString SAL_CALL SwXDocumentIndex::getServiceName()
+{
+ SolarMutexGuard g;
+
+ SwServiceType nObjectType = SwServiceType::TypeIndex;
+ switch (m_pImpl->m_eTOXType)
+ {
+ case TOX_USER: nObjectType = SwServiceType::UserIndex;
+ break;
+ case TOX_CONTENT: nObjectType = SwServiceType::ContentIndex;
+ break;
+ case TOX_ILLUSTRATIONS: nObjectType = SwServiceType::IndexIllustrations;
+ break;
+ case TOX_OBJECTS: nObjectType = SwServiceType::IndexObjects;
+ break;
+ case TOX_TABLES: nObjectType = SwServiceType::IndexTables;
+ break;
+ case TOX_AUTHORITIES: nObjectType = SwServiceType::IndexBibliography;
+ break;
+ default:
+ break;
+ }
+ return SwXServiceProvider::GetProviderName(nObjectType);
+}
+
+void SAL_CALL SwXDocumentIndex::update()
+{
+ return refresh(); // update is from deprecated XDocumentIndex
+}
+
+uno::Reference< beans::XPropertySetInfo > SAL_CALL
+SwXDocumentIndex::getPropertySetInfo()
+{
+ SolarMutexGuard g;
+
+ const uno::Reference< beans::XPropertySetInfo > xRef =
+ m_pImpl->m_rPropSet.getPropertySetInfo();
+ return xRef;
+}
+
+void SAL_CALL
+SwXDocumentIndex::setPropertyValue(
+ const OUString& rPropertyName, const uno::Any& rValue)
+{
+ SolarMutexGuard aGuard;
+
+ SfxItemPropertyMapEntry const*const pEntry =
+ m_pImpl->m_rPropSet.getPropertyMap().getByName(rPropertyName);
+ if (!pEntry)
+ {
+ throw beans::UnknownPropertyException(
+ "Unknown property: " + rPropertyName,
+ getXWeak());
+ }
+ if (pEntry->nFlags & beans::PropertyAttribute::READONLY)
+ {
+ throw beans::PropertyVetoException(
+ "Property is read-only: " + rPropertyName,
+ getXWeak());
+ }
+
+ SwSectionFormat *const pSectionFormat(m_pImpl->GetSectionFormat());
+ SwTOXBase & rTOXBase( m_pImpl->GetTOXSectionOrThrow() );
+
+ SwTOXElement nCreate = rTOXBase.GetCreateType();
+ SwTOOElements nOLEOptions = rTOXBase.GetOLEOptions();
+ const TOXTypes eTxBaseType = rTOXBase.GetTOXType()->GetType();
+ SwTOIOptions nTOIOptions = (eTxBaseType == TOX_INDEX)
+ ? rTOXBase.GetOptions() : SwTOIOptions::NONE;
+ SwForm aForm(rTOXBase.GetTOXForm());
+ bool bForm = false;
+ switch (pEntry->nWID)
+ {
+ case WID_IDX_TITLE:
+ {
+ OUString sNewName;
+ if (!(rValue >>= sNewName))
+ {
+ throw lang::IllegalArgumentException();
+ }
+ rTOXBase.SetTitle(sNewName);
+ }
+ break;
+ case WID_IDX_NAME:
+ {
+ OUString sNewName;
+ if (!(rValue >>= sNewName))
+ {
+ throw lang::IllegalArgumentException();
+ }
+ rTOXBase.SetTOXName(sNewName);
+ }
+ break;
+ case WID_USER_IDX_NAME:
+ {
+ OUString sNewName;
+ if (!(rValue >>= sNewName))
+ {
+ throw lang::IllegalArgumentException();
+ }
+ lcl_ConvertTOUNameToUserName(sNewName);
+ OSL_ENSURE(TOX_USER == eTxBaseType,
+ "tox type name can only be changed for user indexes");
+ if (pSectionFormat)
+ {
+ if (rTOXBase.GetTOXType()->GetTypeName() != sNewName)
+ {
+ lcl_ReAssignTOXType(*pSectionFormat->GetDoc(),
+ rTOXBase, sNewName);
+ }
+ }
+ else
+ {
+ m_pImpl->m_oProps->SetTypeName(sNewName);
+ }
+ }
+ break;
+ case WID_IDX_LOCALE:
+ {
+ lang::Locale aLocale;
+ if (!(rValue>>= aLocale))
+ {
+ throw lang::IllegalArgumentException();
+ }
+ rTOXBase.SetLanguage( LanguageTag::convertToLanguageType(aLocale));
+ }
+ break;
+ case WID_IDX_SORT_ALGORITHM:
+ {
+ OUString sTmp;
+ if (!(rValue >>= sTmp))
+ {
+ throw lang::IllegalArgumentException();
+ }
+ rTOXBase.SetSortAlgorithm(sTmp);
+ }
+ break;
+ case WID_LEVEL:
+ {
+ rTOXBase.SetLevel(lcl_AnyToType<sal_Int16>(rValue));
+ }
+ break;
+ case WID_TOC_BOOKMARK:
+ {
+ rTOXBase.SetBookmarkName(lcl_AnyToType<OUString>(rValue));
+ nCreate = SwTOXElement::Bookmark;
+ rTOXBase.SetCreate(nCreate);
+ }
+ break;
+ case WID_CREATE_FROM_MARKS:
+ lcl_AnyToBitMask(rValue, nCreate, SwTOXElement::Mark);
+ break;
+ case WID_CREATE_FROM_OUTLINE:
+ lcl_AnyToBitMask(rValue, nCreate, SwTOXElement::OutlineLevel);
+ break;
+ case WID_TOC_PARAGRAPH_OUTLINE_LEVEL:
+ lcl_AnyToBitMask(rValue, nCreate, SwTOXElement::ParagraphOutlineLevel);
+ break;
+ case WID_TAB_IN_TOC:
+ lcl_AnyToBitMask(rValue, nCreate, SwTOXElement::TableInToc);
+ break;
+ case WID_TOC_NEWLINE:
+ lcl_AnyToBitMask(rValue, nCreate, SwTOXElement::Newline);
+ break;
+// case WID_PARAGRAPH_STYLE_NAMES :OSL_FAIL("not implemented")
+// break;
+ case WID_HIDE_TABLEADER_PAGENUMBERS:
+ lcl_AnyToBitMask(rValue, nCreate, SwTOXElement::TableLeader);
+ break ;
+ case WID_CREATE_FROM_CHAPTER:
+ rTOXBase.SetFromChapter(lcl_AnyToType<bool>(rValue));
+ break;
+ case WID_CREATE_FROM_LABELS:
+ rTOXBase.SetFromObjectNames(! lcl_AnyToType<bool>(rValue));
+ break;
+ case WID_PROTECTED:
+ {
+ bool bSet = lcl_AnyToType<bool>(rValue);
+ rTOXBase.SetProtected(bSet);
+ if (pSectionFormat)
+ {
+ static_cast<SwTOXBaseSection &>(rTOXBase).SetProtect(bSet);
+ }
+ }
+ break;
+ case WID_USE_ALPHABETICAL_SEPARATORS:
+ lcl_AnyToBitMask(rValue, nTOIOptions,
+ SwTOIOptions::AlphaDelimiter);
+ break;
+ case WID_USE_KEY_AS_ENTRY:
+ lcl_AnyToBitMask(rValue, nTOIOptions,
+ SwTOIOptions::KeyAsEntry);
+ break;
+ case WID_USE_COMBINED_ENTRIES:
+ lcl_AnyToBitMask(rValue, nTOIOptions,
+ SwTOIOptions::SameEntry);
+ break;
+ case WID_IS_CASE_SENSITIVE:
+ lcl_AnyToBitMask(rValue, nTOIOptions,
+ SwTOIOptions::CaseSensitive);
+ break;
+ case WID_USE_P_P:
+ lcl_AnyToBitMask(rValue, nTOIOptions, SwTOIOptions::FF);
+ break;
+ case WID_USE_DASH:
+ lcl_AnyToBitMask(rValue, nTOIOptions, SwTOIOptions::Dash);
+ break;
+ case WID_USE_UPPER_CASE:
+ lcl_AnyToBitMask(rValue, nTOIOptions,
+ SwTOIOptions::InitialCaps);
+ break;
+ case WID_IS_COMMA_SEPARATED:
+ bForm = true;
+ aForm.SetCommaSeparated(lcl_AnyToType<bool>(rValue));
+ break;
+ case WID_LABEL_CATEGORY:
+ {
+ // convert file-format/API/external programmatic english name
+ // to internal UI name before usage
+ rTOXBase.SetSequenceName( SwStyleNameMapper::GetSpecialExtraUIName(
+ lcl_AnyToType<OUString>(rValue) ) );
+ }
+ break;
+ case WID_LABEL_DISPLAY_TYPE:
+ {
+ const sal_Int16 nVal = lcl_AnyToType<sal_Int16>(rValue);
+ sal_uInt16 nSet = CAPTION_COMPLETE;
+ switch (nVal)
+ {
+ case text::ReferenceFieldPart::TEXT:
+ nSet = CAPTION_COMPLETE;
+ break;
+ case text::ReferenceFieldPart::CATEGORY_AND_NUMBER:
+ nSet = CAPTION_NUMBER;
+ break;
+ case text::ReferenceFieldPart::ONLY_CAPTION:
+ nSet = CAPTION_TEXT;
+ break;
+ default:
+ throw lang::IllegalArgumentException();
+ }
+ rTOXBase.SetCaptionDisplay(static_cast<SwCaptionDisplay>(nSet));
+ }
+ break;
+ case WID_USE_LEVEL_FROM_SOURCE:
+ rTOXBase.SetLevelFromChapter(lcl_AnyToType<bool>(rValue));
+ break;
+ case WID_MAIN_ENTRY_CHARACTER_STYLE_NAME:
+ {
+ OUString aString;
+ SwStyleNameMapper::FillUIName(lcl_AnyToType<OUString>(rValue),
+ aString, SwGetPoolIdFromName::ChrFmt);
+ rTOXBase.SetMainEntryCharStyle( aString );
+ }
+ break;
+ case WID_CREATE_FROM_TABLES:
+ lcl_AnyToBitMask(rValue, nCreate, SwTOXElement::Table);
+ break;
+ case WID_CREATE_FROM_TEXT_FRAMES:
+ lcl_AnyToBitMask(rValue, nCreate, SwTOXElement::Frame);
+ break;
+ case WID_CREATE_FROM_GRAPHIC_OBJECTS:
+ lcl_AnyToBitMask(rValue, nCreate, SwTOXElement::Graphic);
+ break;
+ case WID_CREATE_FROM_EMBEDDED_OBJECTS:
+ lcl_AnyToBitMask(rValue, nCreate, SwTOXElement::Ole);
+ break;
+ case WID_CREATE_FROM_STAR_MATH:
+ lcl_AnyToBitMask(rValue, nOLEOptions, SwTOOElements::Math);
+ break;
+ case WID_CREATE_FROM_STAR_CHART:
+ lcl_AnyToBitMask(rValue, nOLEOptions, SwTOOElements::Chart);
+ break;
+ case WID_CREATE_FROM_STAR_CALC:
+ lcl_AnyToBitMask(rValue, nOLEOptions, SwTOOElements::Calc);
+ break;
+ case WID_CREATE_FROM_STAR_DRAW:
+ lcl_AnyToBitMask(rValue, nOLEOptions,
+ SwTOOElements::DrawImpress);
+ break;
+ case WID_CREATE_FROM_OTHER_EMBEDDED_OBJECTS:
+ lcl_AnyToBitMask(rValue, nOLEOptions, SwTOOElements::Other);
+ break;
+ case WID_PARA_HEAD:
+ {
+ OUString aString;
+ SwStyleNameMapper::FillUIName( lcl_AnyToType<OUString>(rValue),
+ aString, SwGetPoolIdFromName::TxtColl);
+ bForm = true;
+ // Header is on Pos 0
+ aForm.SetTemplate( 0, aString );
+ }
+ break;
+ case WID_IS_RELATIVE_TABSTOPS:
+ bForm = true;
+ aForm.SetRelTabPos(lcl_AnyToType<bool>(rValue));
+ break;
+ case WID_PARA_SEP:
+ {
+ OUString aString;
+ bForm = true;
+ SwStyleNameMapper::FillUIName( lcl_AnyToType<OUString>(rValue),
+ aString, SwGetPoolIdFromName::TxtColl);
+ aForm.SetTemplate( 1, aString );
+ }
+ break;
+ case WID_CREATE_FROM_PARAGRAPH_STYLES:
+ lcl_AnyToBitMask(rValue, nCreate, SwTOXElement::Template);
+ break;
+ case WID_CREATE_FROM_PARAGRAPH_STYLE:
+ {
+ OUString style;
+ if (rValue >>= style)
+ {
+ if (style.indexOf(TOX_STYLE_DELIMITER) != -1)
+ {
+ throw lang::IllegalArgumentException();
+ }
+ lcl_AnyToBitMask(uno::Any(true), nCreate, SwTOXElement::Template);
+ OUString uiStyle;
+ SwStyleNameMapper::FillUIName(style, uiStyle, SwGetPoolIdFromName::TxtColl);
+ rTOXBase.SetStyleNames(uiStyle, 0);
+ }
+ else if (!rValue.hasValue())
+ {
+ lcl_AnyToBitMask(uno::Any(false), nCreate, SwTOXElement::Template);
+ }
+ else
+ {
+ throw lang::IllegalArgumentException();
+ }
+ }
+ break;
+
+ case WID_PARA_LEV1:
+ case WID_PARA_LEV2:
+ case WID_PARA_LEV3:
+ case WID_PARA_LEV4:
+ case WID_PARA_LEV5:
+ case WID_PARA_LEV6:
+ case WID_PARA_LEV7:
+ case WID_PARA_LEV8:
+ case WID_PARA_LEV9:
+ case WID_PARA_LEV10:
+ {
+ bForm = true;
+ // in sdbcx::Index Label 1 begins at Pos 2 otherwise at Pos 1
+ const sal_uInt16 nLPos = rTOXBase.GetType() == TOX_INDEX ? 2 : 1;
+ OUString aString;
+ SwStyleNameMapper::FillUIName( lcl_AnyToType<OUString>(rValue),
+ aString, SwGetPoolIdFromName::TxtColl);
+ aForm.SetTemplate(nLPos + pEntry->nWID - WID_PARA_LEV1, aString );
+ }
+ break;
+ default:
+ //this is for items only
+ if (WID_PRIMARY_KEY > pEntry->nWID)
+ {
+ const SwAttrSet& rSet =
+ SwDoc::GetTOXBaseAttrSet(rTOXBase);
+ SfxItemSet aAttrSet(rSet);
+ m_pImpl->m_rPropSet.setPropertyValue(
+ rPropertyName, rValue, aAttrSet);
+
+ const SwSectionFormats& rSects = m_pImpl->m_pDoc->GetSections();
+ for (size_t i = 0; i < rSects.size(); ++i)
+ {
+ const SwSectionFormat* pTmpFormat = rSects[ i ];
+ if (pTmpFormat == pSectionFormat)
+ {
+ SwSectionData tmpData(
+ static_cast<SwTOXBaseSection&>(rTOXBase));
+ m_pImpl->m_pDoc->UpdateSection(i, tmpData, & aAttrSet);
+ break;
+ }
+ }
+ }
+ }
+ rTOXBase.SetCreate(nCreate);
+ rTOXBase.SetOLEOptions(nOLEOptions);
+ if (rTOXBase.GetTOXType()->GetType() == TOX_INDEX)
+ {
+ rTOXBase.SetOptions(nTOIOptions);
+ }
+ if (bForm)
+ {
+ rTOXBase.SetTOXForm(aForm);
+ }
+}
+
+uno::Any SAL_CALL
+SwXDocumentIndex::getPropertyValue(const OUString& rPropertyName)
+{
+ SolarMutexGuard aGuard;
+
+ uno::Any aRet;
+ SfxItemPropertyMapEntry const*const pEntry =
+ m_pImpl->m_rPropSet.getPropertyMap().getByName(rPropertyName);
+ if (!pEntry)
+ {
+ throw beans::UnknownPropertyException(
+ "Unknown property: " + rPropertyName,
+ getXWeak());
+ }
+ // TODO: is this the best approach to tell API clients about the change?
+ if (pEntry->nWID == RES_BACKGROUND && pEntry->nMemberId == MID_GRAPHIC_URL)
+ {
+ throw uno::RuntimeException("Getting GraphicURL property is not supported");
+ }
+
+ SwSectionFormat *const pSectionFormat( m_pImpl->GetSectionFormat() );
+ SwTOXBase* pTOXBase = nullptr;
+ if (pSectionFormat)
+ {
+ pTOXBase = static_cast<SwTOXBaseSection*>(pSectionFormat->GetSection());
+ }
+ else if (m_pImpl->m_bIsDescriptor)
+ {
+ pTOXBase = &m_pImpl->m_oProps->GetTOXBase();
+ }
+ if(pTOXBase)
+ {
+ const SwTOXElement nCreate = pTOXBase->GetCreateType();
+ const SwTOOElements nOLEOptions = pTOXBase->GetOLEOptions();
+ const SwTOIOptions nTOIOptions =
+ (pTOXBase->GetTOXType()->GetType() == TOX_INDEX)
+ ? pTOXBase->GetOptions()
+ : SwTOIOptions::NONE;
+ const SwForm& rForm = pTOXBase->GetTOXForm();
+ switch(pEntry->nWID)
+ {
+ case WID_IDX_CONTENT_SECTION:
+ case WID_IDX_HEADER_SECTION :
+ if(WID_IDX_CONTENT_SECTION == pEntry->nWID)
+ {
+ const uno::Reference <text::XTextSection> xContentSect =
+ SwXTextSection::CreateXTextSection( pSectionFormat );
+ aRet <<= xContentSect;
+ }
+ else if (pSectionFormat)
+ {
+ SwSections aSectArr;
+ pSectionFormat->GetChildSections(aSectArr,
+ SectionSort::Not, false);
+ for(SwSection* pSect : aSectArr)
+ {
+ if(pSect->GetType() == SectionType::ToxHeader)
+ {
+ const uno::Reference <text::XTextSection> xHeader =
+ SwXTextSection::CreateXTextSection(
+ pSect->GetFormat() );
+ aRet <<= xHeader;
+ break;
+ }
+ }
+ }
+ break;
+ case WID_IDX_TITLE :
+ {
+ aRet <<= pTOXBase->GetTitle();
+ break;
+ }
+ case WID_IDX_NAME:
+ aRet <<= pTOXBase->GetTOXName();
+ break;
+ case WID_USER_IDX_NAME:
+ {
+ OUString sTmp((!m_pImpl->m_bIsDescriptor)
+ ? pTOXBase->GetTOXType()->GetTypeName()
+ : m_pImpl->m_oProps->GetTypeName());
+ //I18N
+ lcl_ConvertTOUNameToProgrammaticName(sTmp);
+ aRet <<= sTmp;
+ }
+ break;
+ case WID_IDX_LOCALE:
+ aRet <<= LanguageTag(pTOXBase->GetLanguage()).getLocale();
+ break;
+ case WID_IDX_SORT_ALGORITHM:
+ aRet <<= pTOXBase->GetSortAlgorithm();
+ break;
+ case WID_LEVEL :
+ aRet <<= static_cast<sal_Int16>(pTOXBase->GetLevel());
+ break;
+ case WID_TOC_BOOKMARK :
+ aRet <<= pTOXBase->GetBookmarkName();
+ break;
+ case WID_CREATE_FROM_MARKS:
+ lcl_BitMaskToAny(aRet, nCreate, SwTOXElement::Mark);
+ break;
+ case WID_CREATE_FROM_OUTLINE:
+ lcl_BitMaskToAny(aRet, nCreate,
+ SwTOXElement::OutlineLevel);
+ break;
+ case WID_CREATE_FROM_CHAPTER:
+ {
+ const bool bRet = pTOXBase->IsFromChapter();
+ aRet <<= bRet;
+ }
+ break;
+ case WID_CREATE_FROM_LABELS:
+ {
+ const bool bRet = ! pTOXBase->IsFromObjectNames();
+ aRet <<= bRet;
+ }
+ break;
+ case WID_PROTECTED:
+ {
+ const bool bRet = pTOXBase->IsProtected();
+ aRet <<= bRet;
+ }
+ break;
+ case WID_USE_ALPHABETICAL_SEPARATORS:
+ lcl_BitMaskToAny(aRet, nTOIOptions,
+ SwTOIOptions::AlphaDelimiter);
+ break;
+ case WID_USE_KEY_AS_ENTRY:
+ lcl_BitMaskToAny(aRet, nTOIOptions,
+ SwTOIOptions::KeyAsEntry);
+ break;
+ case WID_USE_COMBINED_ENTRIES:
+ lcl_BitMaskToAny(aRet, nTOIOptions,
+ SwTOIOptions::SameEntry);
+ break;
+ case WID_IS_CASE_SENSITIVE:
+ lcl_BitMaskToAny(aRet, nTOIOptions,
+ SwTOIOptions::CaseSensitive);
+ break;
+ case WID_USE_P_P:
+ lcl_BitMaskToAny(aRet, nTOIOptions, SwTOIOptions::FF);
+ break;
+ case WID_USE_DASH:
+ lcl_BitMaskToAny(aRet, nTOIOptions, SwTOIOptions::Dash);
+ break;
+ case WID_USE_UPPER_CASE:
+ lcl_BitMaskToAny(aRet, nTOIOptions,
+ SwTOIOptions::InitialCaps);
+ break;
+ case WID_IS_COMMA_SEPARATED:
+ {
+ const bool bRet = rForm.IsCommaSeparated();
+ aRet <<= bRet;
+ }
+ break;
+ case WID_LABEL_CATEGORY:
+ {
+ // convert internal UI name to
+ // file-format/API/external programmatic english name
+ // before usage
+ aRet <<= SwStyleNameMapper::GetSpecialExtraProgName(
+ pTOXBase->GetSequenceName() );
+ }
+ break;
+ case WID_LABEL_DISPLAY_TYPE:
+ {
+ sal_Int16 nSet = text::ReferenceFieldPart::TEXT;
+ switch (pTOXBase->GetCaptionDisplay())
+ {
+ case CAPTION_COMPLETE:
+ nSet = text::ReferenceFieldPart::TEXT;
+ break;
+ case CAPTION_NUMBER:
+ nSet = text::ReferenceFieldPart::CATEGORY_AND_NUMBER;
+ break;
+ case CAPTION_TEXT:
+ nSet = text::ReferenceFieldPart::ONLY_CAPTION;
+ break;
+ }
+ aRet <<= nSet;
+ }
+ break;
+ case WID_USE_LEVEL_FROM_SOURCE:
+ {
+ const bool bRet = pTOXBase->IsLevelFromChapter();
+ aRet <<= bRet;
+ }
+ break;
+ case WID_LEVEL_FORMAT:
+ {
+ uno::Reference< container::XIndexReplace > xTokenAccess(
+ m_pImpl->m_wTokenAccess);
+ if (!xTokenAccess.is())
+ {
+ xTokenAccess = new TokenAccess_Impl(*this);
+ m_pImpl->m_wTokenAccess = xTokenAccess;
+ }
+ aRet <<= xTokenAccess;
+ }
+ break;
+ case WID_LEVEL_PARAGRAPH_STYLES:
+ {
+ uno::Reference< container::XIndexReplace > xStyleAccess(
+ m_pImpl->m_wStyleAccess);
+ if (!xStyleAccess.is())
+ {
+ xStyleAccess = new StyleAccess_Impl(*this);
+ m_pImpl->m_wStyleAccess = xStyleAccess;
+ }
+ aRet <<= xStyleAccess;
+ }
+ break;
+ case WID_MAIN_ENTRY_CHARACTER_STYLE_NAME:
+ {
+ OUString aString;
+ SwStyleNameMapper::FillProgName(
+ pTOXBase->GetMainEntryCharStyle(),
+ aString,
+ SwGetPoolIdFromName::ChrFmt);
+ aRet <<= aString;
+ }
+ break;
+ case WID_CREATE_FROM_TABLES:
+ lcl_BitMaskToAny(aRet, nCreate, SwTOXElement::Table);
+ break;
+ case WID_CREATE_FROM_TEXT_FRAMES:
+ lcl_BitMaskToAny(aRet, nCreate, SwTOXElement::Frame);
+ break;
+ case WID_CREATE_FROM_GRAPHIC_OBJECTS:
+ lcl_BitMaskToAny(aRet, nCreate, SwTOXElement::Graphic);
+ break;
+ case WID_CREATE_FROM_EMBEDDED_OBJECTS:
+ lcl_BitMaskToAny(aRet, nCreate, SwTOXElement::Ole);
+ break;
+ case WID_CREATE_FROM_STAR_MATH:
+ lcl_BitMaskToAny(aRet, nOLEOptions, SwTOOElements::Math);
+ break;
+ case WID_CREATE_FROM_STAR_CHART:
+ lcl_BitMaskToAny(aRet, nOLEOptions, SwTOOElements::Chart);
+ break;
+ case WID_CREATE_FROM_STAR_CALC:
+ lcl_BitMaskToAny(aRet, nOLEOptions, SwTOOElements::Calc);
+ break;
+ case WID_CREATE_FROM_STAR_DRAW:
+ lcl_BitMaskToAny(aRet, nOLEOptions,
+ SwTOOElements::DrawImpress);
+ break;
+ case WID_CREATE_FROM_OTHER_EMBEDDED_OBJECTS:
+ lcl_BitMaskToAny(aRet, nOLEOptions, SwTOOElements::Other);
+ break;
+ case WID_CREATE_FROM_PARAGRAPH_STYLES:
+ lcl_BitMaskToAny(aRet, nCreate, SwTOXElement::Template);
+ break;
+ case WID_CREATE_FROM_PARAGRAPH_STYLE:
+ {
+ if (nCreate & SwTOXElement::Template)
+ { // there is only one style, at top level
+ OUString const& rStyle(pTOXBase->GetStyleNames(0));
+ if (!rStyle.isEmpty())
+ {
+ assert(rStyle.indexOf(TOX_STYLE_DELIMITER) == -1);
+ OUString ret;
+ SwStyleNameMapper::FillProgName(rStyle, ret,
+ SwGetPoolIdFromName::TxtColl);
+ aRet <<= ret;
+ }
+ }
+ }
+ break;
+
+ case WID_PARA_HEAD:
+ {
+ //Header is at position 0
+ OUString aString;
+ SwStyleNameMapper::FillProgName(rForm.GetTemplate( 0 ), aString,
+ SwGetPoolIdFromName::TxtColl );
+ aRet <<= aString;
+ }
+ break;
+ case WID_PARA_SEP:
+ {
+ OUString aString;
+ SwStyleNameMapper::FillProgName(
+ rForm.GetTemplate( 1 ),
+ aString,
+ SwGetPoolIdFromName::TxtColl);
+ aRet <<= aString;
+ }
+ break;
+ case WID_PARA_LEV1:
+ case WID_PARA_LEV2:
+ case WID_PARA_LEV3:
+ case WID_PARA_LEV4:
+ case WID_PARA_LEV5:
+ case WID_PARA_LEV6:
+ case WID_PARA_LEV7:
+ case WID_PARA_LEV8:
+ case WID_PARA_LEV9:
+ case WID_PARA_LEV10:
+ {
+ // in sdbcx::Index Label 1 begins at Pos 2 otherwise at Pos 1
+ const sal_uInt16 nLPos = pTOXBase->GetType() == TOX_INDEX ? 2 : 1;
+ OUString aString;
+ SwStyleNameMapper::FillProgName(
+ rForm.GetTemplate(nLPos + pEntry->nWID - WID_PARA_LEV1),
+ aString,
+ SwGetPoolIdFromName::TxtColl);
+ aRet <<= aString;
+ }
+ break;
+ case WID_IS_RELATIVE_TABSTOPS:
+ {
+ const bool bRet = rForm.IsRelTabPos();
+ aRet <<= bRet;
+ }
+ break;
+ case WID_INDEX_MARKS:
+ {
+ SwTOXMarks aMarks;
+ const SwTOXType* pType = pTOXBase->GetTOXType();
+ pType->CollectTextMarks(aMarks);
+ uno::Sequence< uno::Reference<text::XDocumentIndexMark> > aXMarks(aMarks.size());
+ uno::Reference<text::XDocumentIndexMark>* pxMarks = aXMarks.getArray();
+ for(size_t i = 0; i < aMarks.size(); ++i)
+ {
+ SwTOXMark* pMark = aMarks[i];
+ pxMarks[i] = SwXDocumentIndexMark::CreateXDocumentIndexMark(
+ *m_pImpl->m_pDoc, pMark);
+ }
+ aRet <<= aXMarks;
+ }
+ break;
+ default:
+ //this is for items only
+ if(WID_PRIMARY_KEY > pEntry->nWID)
+ {
+ const SwAttrSet& rSet =
+ SwDoc::GetTOXBaseAttrSet(*pTOXBase);
+ aRet = m_pImpl->m_rPropSet.getPropertyValue(
+ rPropertyName, rSet);
+ }
+ }
+ }
+ return aRet;
+}
+
+void SAL_CALL
+SwXDocumentIndex::addPropertyChangeListener(
+ const OUString& /*rPropertyName*/,
+ const uno::Reference< beans::XPropertyChangeListener >& /*xListener*/)
+{
+ OSL_FAIL("SwXDocumentIndex::addPropertyChangeListener(): not implemented");
+}
+
+void SAL_CALL
+SwXDocumentIndex::removePropertyChangeListener(
+ const OUString& /*rPropertyName*/,
+ const uno::Reference< beans::XPropertyChangeListener >& /*xListener*/)
+{
+ OSL_FAIL("SwXDocumentIndex::removePropertyChangeListener(): not implemented");
+}
+
+void SAL_CALL
+SwXDocumentIndex::addVetoableChangeListener(
+ const OUString& /*rPropertyName*/,
+ const uno::Reference< beans::XVetoableChangeListener >& /*xListener*/)
+{
+ OSL_FAIL("SwXDocumentIndex::addVetoableChangeListener(): not implemented");
+}
+
+void SAL_CALL
+SwXDocumentIndex::removeVetoableChangeListener(
+ const OUString& /*rPropertyName*/,
+ const uno::Reference< beans::XVetoableChangeListener >& /*xListener*/)
+{
+ OSL_FAIL("SwXDocumentIndex::removeVetoableChangeListener(): not implemented");
+}
+
+static void lcl_CalcLayout(SwDoc *pDoc)
+{
+ SwViewShell *pViewShell = nullptr;
+ SwEditShell* pEditShell = nullptr;
+ if( pDoc )
+ {
+ pViewShell = pDoc->getIDocumentLayoutAccess().GetCurrentViewShell();
+ pEditShell = pDoc->GetEditShell();
+ }
+
+ if (pEditShell)
+ {
+ pEditShell->CalcLayout();
+ }
+ else if (pViewShell)
+ {
+ pViewShell->CalcLayout();
+ }
+}
+
+// XRefreshable
+void SAL_CALL SwXDocumentIndex::refresh()
+{
+ {
+ SolarMutexGuard g;
+
+ SwSectionFormat *const pFormat = m_pImpl->GetSectionFormat();
+ SwTOXBaseSection *const pTOXBase = pFormat ?
+ static_cast<SwTOXBaseSection*>(pFormat->GetSection()) : nullptr;
+ if (!pTOXBase)
+ {
+ throw uno::RuntimeException(
+ "SwXDocumentIndex::refresh: must be in attached state",
+ getXWeak());
+ }
+ pTOXBase->Update(nullptr, m_pImpl->m_pDoc->getIDocumentLayoutAccess().GetCurrentLayout());
+
+ // the insertion of TOC will affect the document layout
+ lcl_CalcLayout(m_pImpl->m_pDoc);
+
+ // page numbers
+ pTOXBase->UpdatePageNum();
+ }
+
+ std::unique_lock g(m_pImpl->m_Mutex);
+ if (m_pImpl->m_RefreshListeners.getLength(g))
+ {
+ lang::EventObject const event(getXWeak());
+ m_pImpl->m_RefreshListeners.notifyEach(g, & util::XRefreshListener::refreshed, event);
+ }
+}
+
+void SAL_CALL SwXDocumentIndex::addRefreshListener(
+ const uno::Reference<util::XRefreshListener>& xListener)
+{
+ // no need to lock here as m_pImpl is const and container threadsafe
+ std::unique_lock g(m_pImpl->m_Mutex);
+ m_pImpl->m_RefreshListeners.addInterface(g, xListener);
+}
+
+void SAL_CALL SwXDocumentIndex::removeRefreshListener(
+ const uno::Reference<util::XRefreshListener>& xListener)
+{
+ // no need to lock here as m_pImpl is const and container threadsafe
+ std::unique_lock g(m_pImpl->m_Mutex);
+ m_pImpl->m_RefreshListeners.removeInterface(g, xListener);
+}
+
+void SAL_CALL
+SwXDocumentIndex::attach(const uno::Reference< text::XTextRange > & xTextRange)
+{
+ SolarMutexGuard aGuard;
+
+ if (!m_pImpl->m_bIsDescriptor)
+ {
+ throw uno::RuntimeException();
+ }
+ SwXTextRange *const pRange = dynamic_cast<SwXTextRange*>(xTextRange.get());
+ OTextCursorHelper *const pCursor = dynamic_cast<OTextCursorHelper*>(xTextRange.get());
+
+ SwDoc *const pDoc =
+ pRange ? &pRange->GetDoc() : (pCursor ? pCursor->GetDoc() : nullptr);
+ if (!pDoc)
+ {
+ throw lang::IllegalArgumentException();
+ }
+
+ SwUnoInternalPaM aPam(*pDoc);
+ // this now needs to return TRUE
+ ::sw::XTextRangeToSwPaM(aPam, xTextRange);
+
+ const SwTOXBase* pOld = SwDoc::GetCurTOX( *aPam.Start() );
+ if (pOld)
+ {
+ throw lang::IllegalArgumentException();
+ }
+
+ UnoActionContext aAction(pDoc);
+
+ SwTOXBase & rTOXBase = m_pImpl->m_oProps->GetTOXBase();
+ SwTOXType const*const pTOXType = rTOXBase.GetTOXType();
+ if ((TOX_USER == pTOXType->GetType()) &&
+ m_pImpl->m_oProps->GetTypeName() != pTOXType->GetTypeName())
+ {
+ lcl_ReAssignTOXType(*pDoc, rTOXBase, m_pImpl->m_oProps->GetTypeName());
+ }
+ //TODO: apply Section attributes (columns and background)
+ SwTOXBaseSection *const pTOX =
+ pDoc->InsertTableOf( aPam, rTOXBase, nullptr, false,
+ m_pImpl->m_pDoc->getIDocumentLayoutAccess().GetCurrentLayout());
+
+ pDoc->SetTOXBaseName(*pTOX, m_pImpl->m_oProps->GetTOXBase().GetTOXName());
+
+ // update page numbers
+ m_pImpl->SetSectionFormat(*pTOX->GetFormat());
+ pTOX->GetFormat()->SetXObject(getXWeak());
+ pTOX->UpdatePageNum();
+
+ m_pImpl->m_oProps.reset();
+ m_pImpl->m_pDoc = pDoc;
+ m_pImpl->m_bIsDescriptor = false;
+}
+
+uno::Reference< text::XTextRange > SAL_CALL
+SwXDocumentIndex::getAnchor()
+{
+ SolarMutexGuard aGuard;
+
+ SwSectionFormat *const pSectionFormat( m_pImpl->GetSectionFormat() );
+ if (!pSectionFormat)
+ {
+ throw uno::RuntimeException();
+ }
+
+ rtl::Reference<SwXTextRange> xRet;
+ SwNodeIndex const*const pIdx( pSectionFormat->GetContent().GetContentIdx() );
+ if (pIdx && pIdx->GetNode().GetNodes().IsDocNodes())
+ {
+ SwPaM aPaM(*pIdx);
+ aPaM.Move( fnMoveForward, GoInContent );
+ aPaM.SetMark();
+ aPaM.GetPoint()->Assign( *pIdx->GetNode().EndOfSectionNode() );
+ aPaM.Move( fnMoveBackward, GoInContent );
+ xRet = SwXTextRange::CreateXTextRange(*pSectionFormat->GetDoc(),
+ *aPaM.GetMark(), aPaM.GetPoint());
+ }
+ return xRet;
+}
+
+void SAL_CALL SwXDocumentIndex::dispose()
+{
+ SolarMutexGuard aGuard;
+
+ SwSectionFormat *const pSectionFormat( m_pImpl->GetSectionFormat() );
+ if (pSectionFormat)
+ {
+ pSectionFormat->GetDoc()->DeleteTOX(
+ *static_cast<SwTOXBaseSection*>(pSectionFormat->GetSection()),
+ true);
+ }
+}
+
+void SAL_CALL
+SwXDocumentIndex::addEventListener(
+ const uno::Reference< lang::XEventListener > & xListener)
+{
+ // no need to lock here as m_pImpl is const and container threadsafe
+ std::unique_lock g(m_pImpl->m_Mutex);
+ m_pImpl->m_EventListeners.addInterface(g, xListener);
+}
+
+void SAL_CALL
+SwXDocumentIndex::removeEventListener(
+ const uno::Reference< lang::XEventListener > & xListener)
+{
+ // no need to lock here as m_pImpl is const and container threadsafe
+ std::unique_lock g(m_pImpl->m_Mutex);
+ m_pImpl->m_EventListeners.removeInterface(g, xListener);
+}
+
+OUString SAL_CALL SwXDocumentIndex::getName()
+{
+ SolarMutexGuard g;
+
+ SwSectionFormat *const pSectionFormat( m_pImpl->GetSectionFormat() );
+ if (m_pImpl->m_bIsDescriptor)
+ {
+ return m_pImpl->m_oProps->GetTOXBase().GetTOXName();
+ }
+
+ if(!pSectionFormat)
+ {
+ throw uno::RuntimeException();
+ }
+
+ return pSectionFormat->GetSection()->GetSectionName();
+}
+
+void SAL_CALL
+SwXDocumentIndex::setName(const OUString& rName)
+{
+ SolarMutexGuard g;
+
+ if (rName.isEmpty())
+ {
+ throw uno::RuntimeException();
+ }
+
+ SwSectionFormat *const pSectionFormat( m_pImpl->GetSectionFormat() );
+ if (m_pImpl->m_bIsDescriptor)
+ {
+ m_pImpl->m_oProps->GetTOXBase().SetTOXName(rName);
+ }
+ else if (pSectionFormat)
+ {
+ const bool bSuccess = pSectionFormat->GetDoc()->SetTOXBaseName(
+ *static_cast<SwTOXBaseSection*>(pSectionFormat->GetSection()), rName);
+ if (!bSuccess)
+ {
+ throw uno::RuntimeException();
+ }
+ }
+ else
+ {
+ throw uno::RuntimeException();
+ }
+}
+
+// MetadatableMixin
+::sfx2::Metadatable* SwXDocumentIndex::GetCoreObject()
+{
+ SwSectionFormat *const pSectionFormat( m_pImpl->GetSectionFormat() );
+ return pSectionFormat;
+}
+
+uno::Reference<frame::XModel> SwXDocumentIndex::GetModel()
+{
+ SwSectionFormat *const pSectionFormat( m_pImpl->GetSectionFormat() );
+ if (pSectionFormat)
+ {
+ SwDocShell const*const pShell( pSectionFormat->GetDoc()->GetDocShell() );
+ return pShell ? pShell->GetModel() : nullptr;
+ }
+ return nullptr;
+}
+
+static sal_uInt16
+lcl_TypeToPropertyMap_Mark(const TOXTypes eType)
+{
+ switch (eType)
+ {
+ case TOX_INDEX: return PROPERTY_MAP_INDEX_MARK;
+ case TOX_CONTENT: return PROPERTY_MAP_CNTIDX_MARK;
+ case TOX_CITATION : return PROPERTY_MAP_FLDTYP_BIBLIOGRAPHY;
+ //case TOX_USER:
+ default:
+ return PROPERTY_MAP_USER_MARK;
+ }
+}
+
+class SwXDocumentIndexMark::Impl final: public SvtListener
+{
+private:
+ SwXDocumentIndexMark & m_rThis;
+ bool m_bInReplaceMark;
+
+public:
+
+ unotools::WeakReference<SwXDocumentIndexMark> m_wThis;
+ SfxItemPropertySet const& m_rPropSet;
+ const TOXTypes m_eTOXType;
+ std::mutex m_Mutex; // just for OInterfaceContainerHelper4
+ ::comphelper::OInterfaceContainerHelper4<css::lang::XEventListener> m_EventListeners;
+ bool m_bIsDescriptor;
+ const SwTOXType* m_pTOXType;
+ const SwTOXMark* m_pTOXMark;
+ SwDoc* m_pDoc;
+
+ bool m_bMainEntry;
+ sal_uInt16 m_nLevel;
+ OUString m_aBookmarkName;
+ OUString m_sAltText;
+ OUString m_sPrimaryKey;
+ OUString m_sSecondaryKey;
+ OUString m_sTextReading;
+ OUString m_sPrimaryKeyReading;
+ OUString m_sSecondaryKeyReading;
+ OUString m_sUserIndexName;
+
+ Impl(SwXDocumentIndexMark& rThis,
+ SwDoc* const pDoc,
+ const enum TOXTypes eType,
+ const SwTOXType* pType,
+ SwTOXMark const* pMark)
+ : m_rThis(rThis)
+ , m_bInReplaceMark(false)
+ , m_rPropSet(
+ *aSwMapProvider.GetPropertySet(lcl_TypeToPropertyMap_Mark(eType)))
+ , m_eTOXType(eType)
+ , m_bIsDescriptor(nullptr == pMark)
+ , m_pTOXType(pType)
+ , m_pTOXMark(pMark)
+ , m_pDoc(pDoc)
+ , m_bMainEntry(false)
+ , m_nLevel(0)
+ {
+ auto pMarkNonConst = const_cast<SwTOXMark*>(m_pTOXMark);
+ auto pTypeNonConst = const_cast<SwTOXType*>(m_pTOXType);
+
+ if(pMarkNonConst)
+ StartListening(pMarkNonConst->GetNotifier());
+ if(pTypeNonConst)
+ StartListening(pTypeNonConst->GetNotifier());
+ }
+
+ SwTOXType* GetTOXType() const {
+ return const_cast<SwTOXType*>(m_pTOXType);
+ }
+
+ void DeleteTOXMark()
+ {
+ m_pDoc->DeleteTOXMark(m_pTOXMark);
+ Invalidate();
+ }
+
+ void InsertTOXMark(const SwTOXType & rTOXType, SwTOXMark & rMark, SwPaM & rPam,
+ SwXTextCursor const*const pTextCursor);
+
+ void ReplaceTOXMark(const SwTOXType & rTOXType, SwTOXMark & rMark, SwPaM & rPam)
+ {
+ m_bInReplaceMark = true;
+ DeleteTOXMark();
+ m_bInReplaceMark = false;
+ try {
+ InsertTOXMark(rTOXType, rMark, rPam, nullptr);
+ } catch (...) {
+ OSL_FAIL("ReplaceTOXMark() failed!");
+ lang::EventObject const ev(m_rThis.getXWeak());
+ std::unique_lock aGuard(m_Mutex);
+ m_EventListeners.disposeAndClear(aGuard, ev);
+ throw;
+ }
+ }
+
+ void Invalidate();
+ virtual void Notify(const SfxHint&) override;
+};
+
+void SwXDocumentIndexMark::Impl::Invalidate()
+{
+ if (!m_bInReplaceMark) // #i109983# only dispose on delete, not on replace!
+ {
+ rtl::Reference<SwXDocumentIndexMark> const xThis(m_wThis);
+ // fdo#72695: if UNO object is already dead, don't revive it with event
+ if (xThis.is())
+ {
+ lang::EventObject const ev(xThis->getXWeak());
+ std::unique_lock aGuard(m_Mutex);
+ m_EventListeners.disposeAndClear(aGuard, ev);
+ }
+ }
+ EndListeningAll();
+ m_pDoc = nullptr;
+ m_pTOXMark = nullptr;
+ m_pTOXType = nullptr;
+}
+
+void SwXDocumentIndexMark::Impl::Notify(const SfxHint& rHint)
+{
+ if(auto pModifyChangedHint = dynamic_cast<const sw::ModifyChangedHint*>(&rHint))
+ {
+ if(auto pNewType = dynamic_cast<const SwTOXType*>(pModifyChangedHint->m_pNew))
+ m_pTOXType = pNewType;
+
+ else
+ Invalidate();
+ }
+}
+
+SwXDocumentIndexMark::SwXDocumentIndexMark(const TOXTypes eToxType)
+ : m_pImpl( new SwXDocumentIndexMark::Impl(*this, nullptr, eToxType, nullptr, nullptr) )
+{
+}
+
+SwXDocumentIndexMark::SwXDocumentIndexMark(SwDoc & rDoc,
+ const SwTOXType & rType, const SwTOXMark & rMark)
+ : m_pImpl( new SwXDocumentIndexMark::Impl(*this, &rDoc, rType.GetType(),
+ &rType, &rMark) )
+{
+}
+
+SwXDocumentIndexMark::~SwXDocumentIndexMark()
+{
+}
+
+rtl::Reference<SwXDocumentIndexMark>
+SwXDocumentIndexMark::CreateXDocumentIndexMark(
+ SwDoc & rDoc, SwTOXMark *const pMark, TOXTypes const eType)
+{
+ // re-use existing SwXDocumentIndexMark
+ // NB: xmloff depends on this caching to generate ID from the address!
+ // #i105557#: do not iterate over the registered clients: race condition
+ rtl::Reference<SwXDocumentIndexMark> xTOXMark;
+ if (pMark)
+ {
+ xTOXMark = pMark->GetXTOXMark();
+ }
+ if (!xTOXMark.is())
+ {
+ xTOXMark = pMark
+ ? new SwXDocumentIndexMark(rDoc,
+ *const_cast<SwTOXType*>(pMark->GetTOXType()), *pMark)
+ : new SwXDocumentIndexMark(eType);
+ if (pMark)
+ {
+ pMark->SetXTOXMark(xTOXMark);
+ }
+ // need a permanent Reference to initialize m_wThis
+ xTOXMark->m_pImpl->m_wThis = xTOXMark.get();
+ }
+ return xTOXMark;
+}
+
+namespace
+{
+}
+
+OUString SAL_CALL
+SwXDocumentIndexMark::getImplementationName()
+{
+ return "SwXDocumentIndexMark";
+}
+
+sal_Bool SAL_CALL SwXDocumentIndexMark::supportsService(const OUString& rServiceName)
+{
+ return cppu::supportsService(this, rServiceName);
+}
+
+uno::Sequence< OUString > SAL_CALL
+SwXDocumentIndexMark::getSupportedServiceNames()
+{
+ SolarMutexGuard g;
+
+ const sal_Int32 nCnt = (m_pImpl->m_eTOXType == TOX_INDEX) ? 4 : 3;
+ uno::Sequence< OUString > aRet(nCnt);
+ OUString* pArray = aRet.getArray();
+ pArray[0] = "com.sun.star.text.BaseIndexMark";
+ pArray[1] = "com.sun.star.text.TextContent";
+ switch (m_pImpl->m_eTOXType)
+ {
+ case TOX_USER:
+ pArray[2] = "com.sun.star.text.UserIndexMark";
+ break;
+ case TOX_CONTENT:
+ pArray[2] = "com.sun.star.text.ContentIndexMark";
+ break;
+ case TOX_INDEX:
+ pArray[2] = "com.sun.star.text.DocumentIndexMark";
+ pArray[3] = "com.sun.star.text.DocumentIndexMarkAsian";
+ break;
+
+ default:
+ ;
+ }
+ return aRet;
+}
+
+OUString SAL_CALL
+SwXDocumentIndexMark::getMarkEntry()
+{
+ SolarMutexGuard aGuard;
+
+ SwTOXType *const pType = m_pImpl->GetTOXType();
+ if (pType && m_pImpl->m_pTOXMark)
+ {
+ return m_pImpl->m_pTOXMark->GetAlternativeText();
+ }
+
+ if (!m_pImpl->m_bIsDescriptor)
+ {
+ throw uno::RuntimeException();
+ }
+
+ return m_pImpl->m_sAltText;
+}
+
+void SAL_CALL
+SwXDocumentIndexMark::setMarkEntry(const OUString& rIndexEntry)
+{
+ SolarMutexGuard aGuard;
+
+ SwTOXType *const pType = m_pImpl->GetTOXType();
+ if (pType && m_pImpl->m_pTOXMark)
+ {
+ SwTOXMark aMark(*m_pImpl->m_pTOXMark);
+ aMark.SetAlternativeText(rIndexEntry);
+ SwTextTOXMark const*const pTextMark =
+ m_pImpl->m_pTOXMark->GetTextTOXMark();
+ SwPaM aPam(pTextMark->GetTextNode(), pTextMark->GetStart());
+ aPam.SetMark();
+ if(pTextMark->End())
+ {
+ aPam.GetPoint()->SetContent( *pTextMark->End() );
+ }
+ else
+ aPam.GetPoint()->AdjustContent(1);
+
+ m_pImpl->ReplaceTOXMark(*pType, aMark, aPam);
+ }
+ else if (m_pImpl->m_bIsDescriptor)
+ {
+ m_pImpl->m_sAltText = rIndexEntry;
+ }
+ else
+ {
+ throw uno::RuntimeException();
+ }
+}
+
+void SAL_CALL
+SwXDocumentIndexMark::attach(
+ const uno::Reference< text::XTextRange > & xTextRange)
+{
+ SolarMutexGuard aGuard;
+
+ if (!m_pImpl->m_bIsDescriptor)
+ {
+ throw uno::RuntimeException();
+ }
+
+ SwXTextRange *const pRange =
+ dynamic_cast<SwXTextRange*>(xTextRange.get());
+ OTextCursorHelper *const pCursor =
+ dynamic_cast<OTextCursorHelper*>(xTextRange.get());
+ SwDoc *const pDoc =
+ pRange ? &pRange->GetDoc() : (pCursor ? pCursor->GetDoc() : nullptr);
+ if (!pDoc)
+ {
+ throw lang::IllegalArgumentException();
+ }
+
+ const SwTOXType* pTOXType = nullptr;
+ switch (m_pImpl->m_eTOXType)
+ {
+ case TOX_INDEX:
+ case TOX_CONTENT:
+ case TOX_CITATION:
+ pTOXType = pDoc->GetTOXType( m_pImpl->m_eTOXType, 0 );
+ break;
+ case TOX_USER:
+ {
+ if (m_pImpl->m_sUserIndexName.isEmpty())
+ {
+ pTOXType = pDoc->GetTOXType( m_pImpl->m_eTOXType, 0 );
+ }
+ else
+ {
+ const sal_uInt16 nCount =
+ pDoc->GetTOXTypeCount(m_pImpl->m_eTOXType);
+ for (sal_uInt16 i = 0; i < nCount; i++)
+ {
+ SwTOXType const*const pTemp =
+ pDoc->GetTOXType( m_pImpl->m_eTOXType, i );
+ if (m_pImpl->m_sUserIndexName == pTemp->GetTypeName())
+ {
+ pTOXType = pTemp;
+ break;
+ }
+ }
+ if (!pTOXType)
+ {
+ SwTOXType aUserType(*pDoc, TOX_USER, m_pImpl->m_sUserIndexName);
+ pTOXType = pDoc->InsertTOXType(aUserType);
+ }
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+ if (!pTOXType)
+ {
+ throw lang::IllegalArgumentException();
+ }
+
+ SwUnoInternalPaM aPam(*pDoc);
+ // this now needs to return TRUE
+ ::sw::XTextRangeToSwPaM(aPam, xTextRange);
+ SwTOXMark aMark (pTOXType);
+ if (!m_pImpl->m_sAltText.isEmpty())
+ {
+ aMark.SetAlternativeText(m_pImpl->m_sAltText);
+ }
+ switch (m_pImpl->m_eTOXType)
+ {
+ case TOX_INDEX:
+ if (!m_pImpl->m_sPrimaryKey.isEmpty())
+ {
+ aMark.SetPrimaryKey(m_pImpl->m_sPrimaryKey);
+ }
+ if (!m_pImpl->m_sSecondaryKey.isEmpty())
+ {
+ aMark.SetSecondaryKey(m_pImpl->m_sSecondaryKey);
+ }
+ if (!m_pImpl->m_sTextReading.isEmpty())
+ {
+ aMark.SetTextReading(m_pImpl->m_sTextReading);
+ }
+ if (!m_pImpl->m_sPrimaryKeyReading.isEmpty())
+ {
+ aMark.SetPrimaryKeyReading(m_pImpl->m_sPrimaryKeyReading);
+ }
+ if (!m_pImpl->m_sSecondaryKeyReading.isEmpty())
+ {
+ aMark.SetSecondaryKeyReading(m_pImpl->m_sSecondaryKeyReading);
+ }
+ aMark.SetMainEntry(m_pImpl->m_bMainEntry);
+ break;
+ case TOX_CITATION:
+ aMark.SetMainEntry(m_pImpl->m_bMainEntry);
+ break;
+ case TOX_USER:
+ case TOX_CONTENT:
+ if (USHRT_MAX != m_pImpl->m_nLevel)
+ {
+ aMark.SetLevel(m_pImpl->m_nLevel+1);
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ m_pImpl->InsertTOXMark(*const_cast<SwTOXType *>(pTOXType), aMark, aPam,
+ dynamic_cast<SwXTextCursor const*>(pCursor));
+
+ m_pImpl->m_bIsDescriptor = false;
+}
+
+namespace {
+
+template<typename T> struct NotContainedIn
+{
+ std::vector<T> const& m_rVector;
+ explicit NotContainedIn(std::vector<T> const& rVector)
+ : m_rVector(rVector) { }
+ bool operator() (T const& rT) {
+ return std::find(m_rVector.begin(), m_rVector.end(), rT)
+ == m_rVector.end();
+ }
+};
+
+}
+
+void SwXDocumentIndexMark::Impl::InsertTOXMark(
+ const SwTOXType & rTOXType, SwTOXMark & rMark, SwPaM & rPam,
+ SwXTextCursor const*const pTextCursor)
+{
+ SwDoc& rDoc(rPam.GetDoc());
+ UnoActionContext aAction(&rDoc);
+ bool bMark = *rPam.GetPoint() != *rPam.GetMark();
+ // n.b.: toxmarks must have either alternative text or an extent
+ if (bMark && !rMark.GetAlternativeText().isEmpty())
+ {
+ rPam.Normalize();
+ rPam.DeleteMark();
+ bMark = false;
+ }
+ // Marks without alternative text and without selected text cannot be inserted,
+ // thus use a space - is this really the ideal solution?
+ if (!bMark && rMark.GetAlternativeText().isEmpty())
+ {
+ rMark.SetAlternativeText( " " );
+ }
+
+ const bool bForceExpandHints( !bMark && pTextCursor && pTextCursor->IsAtEndOfMeta() );
+ const SetAttrMode nInsertFlags = bForceExpandHints
+ ? ( SetAttrMode::FORCEHINTEXPAND
+ | SetAttrMode::DONTEXPAND)
+ : SetAttrMode::DONTEXPAND;
+
+ // rMark gets copied into the document pool;
+ // pNewTextAttr comes back with the real format
+ SwTextAttr *pNewTextAttr = nullptr;
+ rDoc.getIDocumentContentOperations().InsertPoolItem(rPam, rMark, nInsertFlags,
+ /*pLayout*/nullptr, &pNewTextAttr);
+ if (bMark && *rPam.GetPoint() > *rPam.GetMark())
+ {
+ rPam.Exchange();
+ }
+
+ if (!pNewTextAttr)
+ {
+ throw uno::RuntimeException(
+ "SwXDocumentIndexMark::InsertTOXMark(): cannot insert attribute",
+ nullptr);
+ }
+
+ m_pDoc = &rDoc;
+ m_pTOXMark = &pNewTextAttr->GetTOXMark();
+ m_pTOXType = &rTOXType;
+ EndListeningAll();
+ StartListening(const_cast<SwTOXMark*>(m_pTOXMark)->GetNotifier());
+ StartListening(const_cast<SwTOXType*>(m_pTOXType)->GetNotifier());
+}
+
+uno::Reference< text::XTextRange > SAL_CALL
+SwXDocumentIndexMark::getAnchor()
+{
+ SolarMutexGuard aGuard;
+
+ SwTOXType *const pType = m_pImpl->GetTOXType();
+ if (!pType || !m_pImpl->m_pTOXMark)
+ {
+ throw uno::RuntimeException();
+ }
+ if (!m_pImpl->m_pTOXMark->GetTextTOXMark())
+ {
+ throw uno::RuntimeException();
+ }
+ const SwTextTOXMark* pTextMark = m_pImpl->m_pTOXMark->GetTextTOXMark();
+ SwPaM aPam(pTextMark->GetTextNode(), pTextMark->GetStart());
+ aPam.SetMark();
+ if(pTextMark->End())
+ {
+ aPam.GetPoint()->SetContent( *pTextMark->End() );
+ }
+ else
+ {
+ aPam.GetPoint()->AdjustContent(1);
+ }
+ const uno::Reference< frame::XModel > xModel =
+ m_pImpl->m_pDoc->GetDocShell()->GetBaseModel();
+ const uno::Reference< text::XTextDocument > xTDoc(xModel, uno::UNO_QUERY);
+ const uno::Reference< text::XTextRange > xRet =
+ new SwXTextRange(aPam, xTDoc->getText());
+
+ return xRet;
+}
+
+void SAL_CALL
+SwXDocumentIndexMark::dispose()
+{
+ SolarMutexGuard aGuard;
+
+ SwTOXType *const pType = m_pImpl->GetTOXType();
+ if (pType && m_pImpl->m_pTOXMark)
+ {
+ m_pImpl->DeleteTOXMark(); // call Invalidate() via modify!
+ }
+}
+
+void SAL_CALL
+SwXDocumentIndexMark::addEventListener(
+ const uno::Reference< lang::XEventListener > & xListener)
+{
+ // no need to lock here as m_pImpl is const and container threadsafe
+ std::unique_lock aGuard(m_pImpl->m_Mutex);
+ m_pImpl->m_EventListeners.addInterface(aGuard, xListener);
+}
+
+void SAL_CALL
+SwXDocumentIndexMark::removeEventListener(
+ const uno::Reference< lang::XEventListener > & xListener)
+{
+ // no need to lock here as m_pImpl is const and container threadsafe
+ std::unique_lock aGuard(m_pImpl->m_Mutex);
+ m_pImpl->m_EventListeners.removeInterface(aGuard, xListener);
+}
+
+uno::Reference< beans::XPropertySetInfo > SAL_CALL
+SwXDocumentIndexMark::getPropertySetInfo()
+{
+ SolarMutexGuard g;
+
+ static uno::Reference< beans::XPropertySetInfo > xInfos[3];
+ int nPos = 0;
+ switch (m_pImpl->m_eTOXType)
+ {
+ case TOX_INDEX: nPos = 0; break;
+ case TOX_CONTENT: nPos = 1; break;
+ case TOX_USER: nPos = 2; break;
+ default:
+ ;
+ }
+ if(!xInfos[nPos].is())
+ {
+ const uno::Reference< beans::XPropertySetInfo > xInfo =
+ m_pImpl->m_rPropSet.getPropertySetInfo();
+ // extend PropertySetInfo!
+ const uno::Sequence<beans::Property> aPropSeq = xInfo->getProperties();
+ xInfos[nPos] = new SfxExtItemPropertySetInfo(
+ aSwMapProvider.GetPropertyMapEntries(
+ PROPERTY_MAP_PARAGRAPH_EXTENSIONS),
+ aPropSeq );
+ }
+ return xInfos[nPos];
+}
+
+void SAL_CALL
+SwXDocumentIndexMark::setPropertyValue(
+ const OUString& rPropertyName, const uno::Any& rValue)
+{
+ SolarMutexGuard aGuard;
+
+ SfxItemPropertyMapEntry const*const pEntry =
+ m_pImpl->m_rPropSet.getPropertyMap().getByName(rPropertyName);
+ if (!pEntry)
+ {
+ throw beans::UnknownPropertyException(
+ "Unknown property: " + rPropertyName,
+ getXWeak());
+ }
+ if (pEntry->nFlags & beans::PropertyAttribute::READONLY)
+ {
+ throw beans::PropertyVetoException(
+ "Property is read-only: " + rPropertyName,
+ getXWeak());
+ }
+
+ SwTOXType *const pType = m_pImpl->GetTOXType();
+ if (pType && m_pImpl->m_pTOXMark)
+ {
+ SwTOXMark aMark(*m_pImpl->m_pTOXMark);
+ switch(pEntry->nWID)
+ {
+ case WID_ALT_TEXT:
+ aMark.SetAlternativeText(lcl_AnyToType<OUString>(rValue));
+ break;
+ case WID_LEVEL:
+ aMark.SetLevel(std::min( static_cast<sal_Int8>( MAXLEVEL ),
+ static_cast<sal_Int8>(lcl_AnyToType<sal_Int16>(rValue)+1)));
+ break;
+ case WID_TOC_BOOKMARK :
+ aMark.SetBookmarkName(lcl_AnyToType<OUString>(rValue));
+ break;
+ case WID_PRIMARY_KEY :
+ aMark.SetPrimaryKey(lcl_AnyToType<OUString>(rValue));
+ break;
+ case WID_SECONDARY_KEY:
+ aMark.SetSecondaryKey(lcl_AnyToType<OUString>(rValue));
+ break;
+ case WID_MAIN_ENTRY:
+ aMark.SetMainEntry(lcl_AnyToType<bool>(rValue));
+ break;
+ case WID_TEXT_READING:
+ aMark.SetTextReading(lcl_AnyToType<OUString>(rValue));
+ break;
+ case WID_PRIMARY_KEY_READING:
+ aMark.SetPrimaryKeyReading(lcl_AnyToType<OUString>(rValue));
+ break;
+ case WID_SECONDARY_KEY_READING:
+ aMark.SetSecondaryKeyReading(lcl_AnyToType<OUString>(rValue));
+ break;
+ }
+ SwTextTOXMark const*const pTextMark =
+ m_pImpl->m_pTOXMark->GetTextTOXMark();
+ SwPaM aPam(pTextMark->GetTextNode(), pTextMark->GetStart());
+ aPam.SetMark();
+ if(pTextMark->End())
+ {
+ aPam.GetPoint()->SetContent(*pTextMark->End());
+ }
+ else
+ {
+ aPam.GetPoint()->AdjustContent(1);
+ }
+
+ m_pImpl->ReplaceTOXMark(*pType, aMark, aPam);
+ }
+ else if (m_pImpl->m_bIsDescriptor)
+ {
+ switch(pEntry->nWID)
+ {
+ case WID_ALT_TEXT:
+ m_pImpl->m_sAltText = lcl_AnyToType<OUString>(rValue);
+ break;
+ case WID_LEVEL:
+ {
+ const sal_Int16 nVal = lcl_AnyToType<sal_Int16>(rValue);
+ if(nVal < 0 || nVal >= MAXLEVEL)
+ {
+ throw lang::IllegalArgumentException();
+ }
+ m_pImpl->m_nLevel = nVal;
+ }
+ break;
+ case WID_TOC_BOOKMARK :
+ {
+ m_pImpl->m_aBookmarkName = lcl_AnyToType<OUString>(rValue);
+ }
+ break;
+ case WID_PRIMARY_KEY:
+ m_pImpl->m_sPrimaryKey = lcl_AnyToType<OUString>(rValue);
+ break;
+ case WID_SECONDARY_KEY:
+ m_pImpl->m_sSecondaryKey = lcl_AnyToType<OUString>(rValue);
+ break;
+ case WID_TEXT_READING:
+ m_pImpl->m_sTextReading = lcl_AnyToType<OUString>(rValue);
+ break;
+ case WID_PRIMARY_KEY_READING:
+ m_pImpl->m_sPrimaryKeyReading = lcl_AnyToType<OUString>(rValue);
+ break;
+ case WID_SECONDARY_KEY_READING:
+ m_pImpl->m_sSecondaryKeyReading = lcl_AnyToType<OUString>(rValue);
+ break;
+ case WID_USER_IDX_NAME:
+ {
+ OUString sTmp(lcl_AnyToType<OUString>(rValue));
+ lcl_ConvertTOUNameToUserName(sTmp);
+ m_pImpl->m_sUserIndexName = sTmp;
+ }
+ break;
+ case WID_MAIN_ENTRY:
+ m_pImpl->m_bMainEntry = lcl_AnyToType<bool>(rValue);
+ break;
+ case PROPERTY_MAP_INDEX_OBJECTS:
+ // unsupported
+ break;
+ }
+ }
+ else
+ {
+ throw uno::RuntimeException();
+ }
+}
+
+uno::Any SAL_CALL
+SwXDocumentIndexMark::getPropertyValue(const OUString& rPropertyName)
+{
+ SolarMutexGuard aGuard;
+
+ uno::Any aRet;
+ SfxItemPropertyMapEntry const*const pEntry =
+ m_pImpl->m_rPropSet.getPropertyMap().getByName(rPropertyName);
+ if (!pEntry)
+ {
+ throw beans::UnknownPropertyException(
+ "Unknown property: " + rPropertyName,
+ getXWeak());
+ }
+ if (::sw::GetDefaultTextContentValue(aRet, rPropertyName, pEntry->nWID))
+ {
+ return aRet;
+ }
+
+ SwTOXType *const pType = m_pImpl->GetTOXType();
+ if (pType && m_pImpl->m_pTOXMark)
+ {
+ switch(pEntry->nWID)
+ {
+ case WID_ALT_TEXT:
+ aRet <<= m_pImpl->m_pTOXMark->GetAlternativeText();
+ break;
+ case WID_LEVEL:
+ aRet <<= static_cast<sal_Int16>(
+ m_pImpl->m_pTOXMark->GetLevel() - 1);
+ break;
+ case WID_TOC_BOOKMARK :
+ aRet <<= m_pImpl->m_pTOXMark->GetBookmarkName();
+ break;
+ case WID_PRIMARY_KEY :
+ aRet <<= m_pImpl->m_pTOXMark->GetPrimaryKey();
+ break;
+ case WID_SECONDARY_KEY:
+ aRet <<= m_pImpl->m_pTOXMark->GetSecondaryKey();
+ break;
+ case WID_TEXT_READING:
+ aRet <<= m_pImpl->m_pTOXMark->GetTextReading();
+ break;
+ case WID_PRIMARY_KEY_READING:
+ aRet <<= m_pImpl->m_pTOXMark->GetPrimaryKeyReading();
+ break;
+ case WID_SECONDARY_KEY_READING:
+ aRet <<= m_pImpl->m_pTOXMark->GetSecondaryKeyReading();
+ break;
+ case WID_USER_IDX_NAME :
+ {
+ OUString sTmp(pType->GetTypeName());
+ lcl_ConvertTOUNameToProgrammaticName(sTmp);
+ aRet <<= sTmp;
+ }
+ break;
+ case WID_MAIN_ENTRY:
+ {
+ const bool bTemp = m_pImpl->m_pTOXMark->IsMainEntry();
+ aRet <<= bTemp;
+ }
+ break;
+ }
+ }
+ else if (m_pImpl->m_bIsDescriptor)
+ {
+ switch(pEntry->nWID)
+ {
+ case WID_ALT_TEXT:
+ aRet <<= m_pImpl->m_sAltText;
+ break;
+ case WID_LEVEL:
+ aRet <<= static_cast<sal_Int16>(m_pImpl->m_nLevel);
+ break;
+ case WID_TOC_BOOKMARK :
+ aRet <<= m_pImpl->m_aBookmarkName;
+ break;
+ case WID_PRIMARY_KEY:
+ aRet <<= m_pImpl->m_sPrimaryKey;
+ break;
+ case WID_SECONDARY_KEY:
+ aRet <<= m_pImpl->m_sSecondaryKey;
+ break;
+ case WID_TEXT_READING:
+ aRet <<= m_pImpl->m_sTextReading;
+ break;
+ case WID_PRIMARY_KEY_READING:
+ aRet <<= m_pImpl->m_sPrimaryKeyReading;
+ break;
+ case WID_SECONDARY_KEY_READING:
+ aRet <<= m_pImpl->m_sSecondaryKeyReading;
+ break;
+ case WID_USER_IDX_NAME :
+ aRet <<= m_pImpl->m_sUserIndexName;
+ break;
+ case WID_MAIN_ENTRY:
+ aRet <<= m_pImpl->m_bMainEntry;
+ break;
+ }
+ }
+ else
+ {
+ throw uno::RuntimeException();
+ }
+ return aRet;
+}
+
+void SAL_CALL
+SwXDocumentIndexMark::addPropertyChangeListener(
+ const OUString& /*rPropertyName*/,
+ const uno::Reference< beans::XPropertyChangeListener >& /*xListener*/)
+{
+ OSL_FAIL("SwXDocumentIndexMark::addPropertyChangeListener(): not implemented");
+}
+
+void SAL_CALL
+SwXDocumentIndexMark::removePropertyChangeListener(
+ const OUString& /*rPropertyName*/,
+ const uno::Reference< beans::XPropertyChangeListener >& /*xListener*/)
+{
+ OSL_FAIL("SwXDocumentIndexMark::removePropertyChangeListener(): not implemented");
+}
+
+void SAL_CALL
+SwXDocumentIndexMark::addVetoableChangeListener(
+ const OUString& /*rPropertyName*/,
+ const uno::Reference< beans::XVetoableChangeListener >& /*xListener*/)
+{
+ OSL_FAIL("SwXDocumentIndexMark::addVetoableChangeListener(): not implemented");
+}
+
+void SAL_CALL
+SwXDocumentIndexMark::removeVetoableChangeListener(
+ const OUString& /*rPropertyName*/,
+ const uno::Reference< beans::XVetoableChangeListener >& /*xListener*/)
+{
+ OSL_FAIL("SwXDocumentIndexMark::removeVetoableChangeListener(): not implemented");
+}
+
+SwXDocumentIndexes::SwXDocumentIndexes(SwDoc *const _pDoc)
+ : SwUnoCollection(_pDoc)
+{
+}
+
+SwXDocumentIndexes::~SwXDocumentIndexes()
+{
+}
+
+OUString SAL_CALL
+SwXDocumentIndexes::getImplementationName()
+{
+ return "SwXDocumentIndexes";
+}
+
+sal_Bool SAL_CALL SwXDocumentIndexes::supportsService(const OUString& rServiceName)
+{
+ return cppu::supportsService(this, rServiceName);
+}
+
+uno::Sequence< OUString > SAL_CALL
+SwXDocumentIndexes::getSupportedServiceNames()
+{
+ return { "com.sun.star.text.DocumentIndexes" };
+}
+
+sal_Int32 SAL_CALL
+SwXDocumentIndexes::getCount()
+{
+ SolarMutexGuard aGuard;
+
+ sal_uInt32 nRet = 0;
+ const SwSectionFormats& rFormats = GetDoc().GetSections();
+ for( size_t n = 0; n < rFormats.size(); ++n )
+ {
+ const SwSection* pSect = rFormats[ n ]->GetSection();
+ if( SectionType::ToxContent == pSect->GetType() &&
+ pSect->GetFormat()->GetSectionNode() )
+ {
+ ++nRet;
+ }
+ }
+ return nRet;
+}
+
+uno::Any SAL_CALL
+SwXDocumentIndexes::getByIndex(sal_Int32 nIndex)
+{
+ SolarMutexGuard aGuard;
+
+ sal_Int32 nIdx = 0;
+
+ auto& rDoc = GetDoc();
+ const SwSectionFormats& rFormats = rDoc.GetSections();
+ for( size_t n = 0; n < rFormats.size(); ++n )
+ {
+ SwSection* pSect = rFormats[ n ]->GetSection();
+ if( SectionType::ToxContent == pSect->GetType() &&
+ pSect->GetFormat()->GetSectionNode() &&
+ nIdx++ == nIndex )
+ {
+ const uno::Reference< text::XDocumentIndex > xTmp =
+ SwXDocumentIndex::CreateXDocumentIndex(
+ rDoc, static_cast<SwTOXBaseSection *>(pSect));
+ uno::Any aRet;
+ aRet <<= xTmp;
+ return aRet;
+ }
+ }
+
+ throw lang::IndexOutOfBoundsException();
+}
+
+uno::Any SAL_CALL
+SwXDocumentIndexes::getByName(const OUString& rName)
+{
+ SolarMutexGuard aGuard;
+
+ auto& rDoc = GetDoc();
+ const SwSectionFormats& rFormats = rDoc.GetSections();
+ for( size_t n = 0; n < rFormats.size(); ++n )
+ {
+ SwSection* pSect = rFormats[ n ]->GetSection();
+ if( SectionType::ToxContent == pSect->GetType() &&
+ pSect->GetFormat()->GetSectionNode() &&
+ (static_cast<SwTOXBaseSection const*>(pSect)->GetTOXName()
+ == rName))
+ {
+ const uno::Reference< text::XDocumentIndex > xTmp =
+ SwXDocumentIndex::CreateXDocumentIndex(
+ rDoc, static_cast<SwTOXBaseSection *>(pSect));
+ uno::Any aRet;
+ aRet <<= xTmp;
+ return aRet;
+ }
+ }
+ throw container::NoSuchElementException();
+}
+
+uno::Sequence< OUString > SAL_CALL
+SwXDocumentIndexes::getElementNames()
+{
+ SolarMutexGuard aGuard;
+
+ const SwSectionFormats& rFormats = GetDoc().GetSections();
+ sal_Int32 nCount = 0;
+ for( size_t n = 0; n < rFormats.size(); ++n )
+ {
+ SwSection const*const pSect = rFormats[ n ]->GetSection();
+ if( SectionType::ToxContent == pSect->GetType() &&
+ pSect->GetFormat()->GetSectionNode() )
+ {
+ ++nCount;
+ }
+ }
+
+ uno::Sequence< OUString > aRet(nCount);
+ OUString* pArray = aRet.getArray();
+ sal_Int32 nCnt = 0;
+ for( size_t n = 0; n < rFormats.size(); ++n )
+ {
+ SwSection const*const pSect = rFormats[ n ]->GetSection();
+ if( SectionType::ToxContent == pSect->GetType() &&
+ pSect->GetFormat()->GetSectionNode())
+ {
+ pArray[nCnt++] = static_cast<SwTOXBaseSection const*>(pSect)->GetTOXName();
+ }
+ }
+ return aRet;
+}
+
+sal_Bool SAL_CALL
+SwXDocumentIndexes::hasByName(const OUString& rName)
+{
+ SolarMutexGuard aGuard;
+
+ const SwSectionFormats& rFormats = GetDoc().GetSections();
+ for( size_t n = 0; n < rFormats.size(); ++n )
+ {
+ SwSection const*const pSect = rFormats[ n ]->GetSection();
+ if( SectionType::ToxContent == pSect->GetType() &&
+ pSect->GetFormat()->GetSectionNode())
+ {
+ if (static_cast<SwTOXBaseSection const*>(pSect)->GetTOXName()
+ == rName)
+ {
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
+uno::Type SAL_CALL
+SwXDocumentIndexes::getElementType()
+{
+ return cppu::UnoType<text::XDocumentIndex>::get();
+}
+
+sal_Bool SAL_CALL
+SwXDocumentIndexes::hasElements()
+{
+ return 0 != getCount();
+}
+
+SwXDocumentIndex::StyleAccess_Impl::StyleAccess_Impl(
+ SwXDocumentIndex& rParentIdx)
+ : m_xParent(&rParentIdx)
+{
+}
+
+SwXDocumentIndex::StyleAccess_Impl::~StyleAccess_Impl()
+{
+}
+
+OUString SAL_CALL
+SwXDocumentIndex::StyleAccess_Impl::getImplementationName()
+{
+ return "SwXDocumentIndex::StyleAccess_Impl";
+}
+
+sal_Bool SAL_CALL
+SwXDocumentIndex::StyleAccess_Impl::supportsService(const OUString& rServiceName)
+{
+ return cppu::supportsService(this, rServiceName);
+}
+
+uno::Sequence< OUString > SAL_CALL
+SwXDocumentIndex::StyleAccess_Impl::getSupportedServiceNames()
+{
+ return { "com.sun.star.text.DocumentIndexParagraphStyles" };
+}
+
+void SAL_CALL
+SwXDocumentIndex::StyleAccess_Impl::replaceByIndex(
+ sal_Int32 nIndex, const uno::Any& rElement)
+{
+ SolarMutexGuard aGuard;
+
+ if(nIndex < 0 || nIndex >= MAXLEVEL)
+ {
+ throw lang::IndexOutOfBoundsException();
+ }
+
+ SwTOXBase & rTOXBase( m_xParent->m_pImpl->GetTOXSectionOrThrow() );
+
+ uno::Sequence<OUString> aSeq;
+ if(!(rElement >>= aSeq))
+ {
+ throw lang::IllegalArgumentException();
+ }
+
+ const sal_Int32 nStyles = aSeq.getLength();
+ const OUString* pStyles = aSeq.getConstArray();
+ OUStringBuffer sSetStyles;
+ OUString aString;
+ for(sal_Int32 i = 0; i < nStyles; i++)
+ {
+ if(i)
+ {
+ sSetStyles.append(TOX_STYLE_DELIMITER);
+ }
+ SwStyleNameMapper::FillUIName(pStyles[i], aString,
+ SwGetPoolIdFromName::TxtColl);
+ sSetStyles.append(aString);
+ }
+ rTOXBase.SetStyleNames(sSetStyles.makeStringAndClear(), o3tl::narrowing<sal_uInt16>(nIndex));
+}
+
+sal_Int32 SAL_CALL
+SwXDocumentIndex::StyleAccess_Impl::getCount()
+{
+ return MAXLEVEL;
+}
+
+uno::Any SAL_CALL
+SwXDocumentIndex::StyleAccess_Impl::getByIndex(sal_Int32 nIndex)
+{
+ SolarMutexGuard aGuard;
+
+ if(nIndex < 0 || nIndex >= MAXLEVEL)
+ {
+ throw lang::IndexOutOfBoundsException();
+ }
+
+ SwTOXBase & rTOXBase( m_xParent->m_pImpl->GetTOXSectionOrThrow() );
+
+ const OUString& rStyles =
+ rTOXBase.GetStyleNames(o3tl::narrowing<sal_uInt16>(nIndex));
+ const sal_Int32 nStyles = comphelper::string::getTokenCount(rStyles, TOX_STYLE_DELIMITER);
+ uno::Sequence<OUString> aStyles(nStyles);
+ OUString* pStyles = aStyles.getArray();
+ OUString aString;
+ sal_Int32 nPos = 0;
+ for(sal_Int32 i = 0; i < nStyles; ++i)
+ {
+ SwStyleNameMapper::FillProgName(
+ rStyles.getToken(0, TOX_STYLE_DELIMITER, nPos),
+ aString,
+ SwGetPoolIdFromName::TxtColl);
+ pStyles[i] = aString;
+ }
+ uno::Any aRet(&aStyles, cppu::UnoType<uno::Sequence<OUString>>::get());
+ return aRet;
+}
+
+uno::Type SAL_CALL
+SwXDocumentIndex::StyleAccess_Impl::getElementType()
+{
+ return cppu::UnoType<uno::Sequence<OUString>>::get();
+}
+
+sal_Bool SAL_CALL
+SwXDocumentIndex::StyleAccess_Impl::hasElements()
+{
+ return true;
+}
+
+SwXDocumentIndex::TokenAccess_Impl::TokenAccess_Impl(
+ SwXDocumentIndex& rParentIdx)
+ : m_xParent(&rParentIdx)
+{
+}
+
+SwXDocumentIndex::TokenAccess_Impl::~TokenAccess_Impl()
+{
+}
+
+OUString SAL_CALL
+SwXDocumentIndex::TokenAccess_Impl::getImplementationName()
+{
+ return "SwXDocumentIndex::TokenAccess_Impl";
+}
+
+sal_Bool SAL_CALL SwXDocumentIndex::TokenAccess_Impl::supportsService(
+ const OUString& rServiceName)
+{
+ return cppu::supportsService(this, rServiceName);
+}
+
+uno::Sequence< OUString > SAL_CALL
+SwXDocumentIndex::TokenAccess_Impl::getSupportedServiceNames()
+{
+ return { "com.sun.star.text.DocumentIndexLevelFormat" };
+}
+
+namespace {
+
+struct TokenType_ {
+ const char *pName;
+ enum FormTokenType eTokenType;
+};
+
+}
+
+const struct TokenType_ g_TokenTypes[] =
+{
+ { "TokenEntryNumber", TOKEN_ENTRY_NO },
+ { "TokenEntryText", TOKEN_ENTRY_TEXT },
+ { "TokenTabStop", TOKEN_TAB_STOP },
+ { "TokenText", TOKEN_TEXT },
+ { "TokenPageNumber", TOKEN_PAGE_NUMS },
+ { "TokenChapterInfo", TOKEN_CHAPTER_INFO },
+ { "TokenHyperlinkStart", TOKEN_LINK_START },
+ { "TokenHyperlinkEnd", TOKEN_LINK_END },
+ { "TokenBibliographyDataField", TOKEN_AUTHORITY },
+ { nullptr, static_cast<enum FormTokenType>(0) }
+};
+
+void SAL_CALL
+SwXDocumentIndex::TokenAccess_Impl::replaceByIndex(
+ sal_Int32 nIndex, const uno::Any& rElement)
+{
+ SolarMutexGuard aGuard;
+
+ SwTOXBase & rTOXBase( m_xParent->m_pImpl->GetTOXSectionOrThrow() );
+
+ if ((nIndex < 0) || (nIndex > rTOXBase.GetTOXForm().GetFormMax()))
+ {
+ throw lang::IndexOutOfBoundsException();
+ }
+
+ uno::Sequence<beans::PropertyValues> aSeq;
+ if(!(rElement >>= aSeq))
+ {
+ throw lang::IllegalArgumentException();
+ }
+
+ OUStringBuffer sPattern;
+ for(const beans::PropertyValues& rToken : std::as_const(aSeq))
+ {
+ const beans::PropertyValue* pProperties = rToken.getConstArray();
+ const sal_Int32 nProperties = rToken.getLength();
+ //create an invalid token
+ SwFormToken aToken(TOKEN_END);
+ for(sal_Int32 j = 0; j < nProperties; j++)
+ {
+ if ( pProperties[j].Name == "TokenType" )
+ {
+ const OUString sTokenType =
+ lcl_AnyToType<OUString>(pProperties[j].Value);
+ for (TokenType_ const* pTokenType = g_TokenTypes;
+ pTokenType->pName; ++pTokenType)
+ {
+ if (sTokenType.equalsAscii(pTokenType->pName))
+ {
+ aToken.eTokenType = pTokenType->eTokenType;
+ break;
+ }
+ }
+ }
+ else if ( pProperties[j].Name == "CharacterStyleName" )
+ {
+ OUString sCharStyleName;
+ SwStyleNameMapper::FillUIName(
+ lcl_AnyToType<OUString>(pProperties[j].Value),
+ sCharStyleName,
+ SwGetPoolIdFromName::ChrFmt);
+ aToken.sCharStyleName = sCharStyleName;
+ aToken.nPoolId = SwStyleNameMapper::GetPoolIdFromUIName (
+ sCharStyleName, SwGetPoolIdFromName::ChrFmt );
+ }
+ else if ( pProperties[j].Name == "TabStopRightAligned" )
+ {
+ const bool bRight = lcl_AnyToType<bool>(pProperties[j].Value);
+ aToken.eTabAlign = bRight ?
+ SvxTabAdjust::End : SvxTabAdjust::Left;
+ }
+ else if ( pProperties[j].Name == "TabStopPosition" )
+ {
+ sal_Int32 nPosition = 0;
+ if (!(pProperties[j].Value >>= nPosition))
+ {
+ throw lang::IllegalArgumentException();
+ }
+ nPosition = o3tl::toTwips(nPosition, o3tl::Length::mm100);
+ if(nPosition < 0)
+ {
+ throw lang::IllegalArgumentException();
+ }
+ aToken.nTabStopPosition = nPosition;
+ }
+ else if ( pProperties[j].Name == "TabStopFillCharacter" )
+ {
+ const OUString sFillChar =
+ lcl_AnyToType<OUString>(pProperties[j].Value);
+ if (sFillChar.getLength() > 1)
+ {
+ throw lang::IllegalArgumentException();
+ }
+ aToken.cTabFillChar =
+ sFillChar.isEmpty() ? ' ' : sFillChar[0];
+ }
+ else if ( pProperties[j].Name == "Text" )
+ {
+ aToken.sText = lcl_AnyToType<OUString>(pProperties[j].Value);
+ }
+ else if ( pProperties[j].Name == "ChapterFormat" )
+ {
+ sal_Int16 nFormat = lcl_AnyToType<sal_Int16>(pProperties[j].Value);
+ switch(nFormat)
+ {
+ case text::ChapterFormat::NUMBER:
+ nFormat = CF_NUMBER;
+ break;
+ case text::ChapterFormat::NAME:
+ nFormat = CF_TITLE;
+ break;
+ case text::ChapterFormat::NAME_NUMBER:
+ nFormat = CF_NUM_TITLE;
+ break;
+ case text::ChapterFormat::NO_PREFIX_SUFFIX:
+ nFormat = CF_NUMBER_NOPREPST;
+ break;
+ case text::ChapterFormat::DIGIT:
+ nFormat = CF_NUM_NOPREPST_TITLE;
+ break;
+ default:
+ throw lang::IllegalArgumentException();
+ }
+ aToken.nChapterFormat = nFormat;
+ }
+// #i53420#
+ else if ( pProperties[j].Name == "ChapterLevel" )
+ {
+ const sal_Int16 nLevel = lcl_AnyToType<sal_Int16>(pProperties[j].Value);
+ if( nLevel < 1 || nLevel > MAXLEVEL )
+ {
+ throw lang::IllegalArgumentException();
+ }
+ aToken.nOutlineLevel = nLevel;
+ }
+ else if ( pProperties[j].Name == "BibliographyDataField" )
+ {
+ sal_Int16 nType = 0;
+ pProperties[j].Value >>= nType;
+ if(nType < 0 || nType > text::BibliographyDataField::LOCAL_URL)
+ {
+ throw lang::IllegalArgumentException("BibliographyDataField - wrong value", nullptr, j);
+ }
+ aToken.nAuthorityField = nType;
+ }
+ // #i21237#
+ else if ( pProperties[j].Name == "WithTab" )
+ {
+ aToken.bWithTab = lcl_AnyToType<bool>(pProperties[j].Value);
+ }
+
+ }
+ //exception if wrong TokenType
+ if(TOKEN_END <= aToken.eTokenType )
+ {
+ throw lang::IllegalArgumentException();
+ }
+ // set TokenType from TOKEN_ENTRY_TEXT to TOKEN_ENTRY if it is
+ // not a content index
+ if(TOKEN_ENTRY_TEXT == aToken.eTokenType &&
+ (TOX_CONTENT != rTOXBase.GetType()))
+ {
+ aToken.eTokenType = TOKEN_ENTRY;
+ }
+// #i53420#
+// check for chapter format allowed values if it was TOKEN_ENTRY_NO type
+// only allowed value are CF_NUMBER and CF_NUM_NOPREPST_TITLE
+// reading from file
+ if( TOKEN_ENTRY_NO == aToken.eTokenType )
+ {
+ switch(aToken.nChapterFormat)
+ {
+ case CF_NUMBER:
+ case CF_NUM_NOPREPST_TITLE:
+ break;
+ default:
+ throw lang::IllegalArgumentException();
+ }
+ }
+
+ if (rTOXBase.GetType() == TOX_CONTENT)
+ {
+ if (aToken.eTokenType == TOKEN_LINK_START && aToken.sCharStyleName.isEmpty())
+ {
+ aToken.sCharStyleName = SwResId(STR_POOLCHR_TOXJUMP);
+ }
+ }
+
+ sPattern.append(aToken.GetString());
+ }
+ SwForm aForm(rTOXBase.GetTOXForm());
+ aForm.SetPattern(o3tl::narrowing<sal_uInt16>(nIndex), sPattern.makeStringAndClear());
+ rTOXBase.SetTOXForm(aForm);
+}
+
+sal_Int32 SAL_CALL
+SwXDocumentIndex::TokenAccess_Impl::getCount()
+{
+ SolarMutexGuard aGuard;
+
+ const sal_Int32 nRet = m_xParent->m_pImpl->GetFormMax();
+ return nRet;
+}
+
+uno::Any SAL_CALL
+SwXDocumentIndex::TokenAccess_Impl::getByIndex(sal_Int32 nIndex)
+{
+ SolarMutexGuard aGuard;
+
+ SwTOXBase & rTOXBase( m_xParent->m_pImpl->GetTOXSectionOrThrow() );
+
+ if ((nIndex < 0) || (nIndex > rTOXBase.GetTOXForm().GetFormMax()))
+ {
+ throw lang::IndexOutOfBoundsException();
+ }
+
+ // #i21237#
+ SwFormTokens aPattern = rTOXBase.GetTOXForm().
+ GetPattern(o3tl::narrowing<sal_uInt16>(nIndex));
+
+ sal_Int32 nTokenCount = 0;
+ uno::Sequence< beans::PropertyValues > aRetSeq;
+ OUString aProgCharStyle;
+ for(const SwFormToken& aToken : aPattern) // #i21237#
+ {
+ nTokenCount++;
+ aRetSeq.realloc(nTokenCount);
+ beans::PropertyValues* pTokenProps = aRetSeq.getArray();
+
+ uno::Sequence< beans::PropertyValue >& rCurTokenSeq =
+ pTokenProps[nTokenCount-1];
+ SwStyleNameMapper::FillProgName(
+ aToken.sCharStyleName,
+ aProgCharStyle,
+ SwGetPoolIdFromName::ChrFmt);
+ switch(aToken.eTokenType)
+ {
+ case TOKEN_ENTRY_NO:
+ {
+// #i53420#
+// writing to file (from doc to properties)
+ sal_Int32 nElements = 2;
+ sal_Int32 nCurrentElement = 0;
+
+ // check for default value
+ if (aToken.nChapterFormat != CF_NUMBER)
+ {
+ nElements++;//we need the element
+ }
+ if( aToken.nOutlineLevel != MAXLEVEL )
+ {
+ nElements++;
+ }
+
+ rCurTokenSeq.realloc( nElements );
+
+ beans::PropertyValue* pArr = rCurTokenSeq.getArray();
+
+ pArr[nCurrentElement].Name = "TokenType";
+ pArr[nCurrentElement++].Value <<=
+ OUString("TokenEntryNumber");
+
+ pArr[nCurrentElement].Name = "CharacterStyleName";
+ pArr[nCurrentElement++].Value <<= aProgCharStyle;
+ if( aToken.nChapterFormat != CF_NUMBER )
+ {
+ pArr[nCurrentElement].Name = "ChapterFormat";
+ sal_Int16 nVal;
+// the allowed values for chapter format, when used as entry number,
+// are CF_NUMBER and CF_NUM_NOPREPST_TITLE only, all else forced to
+//CF_NUMBER
+ switch(aToken.nChapterFormat)
+ {
+ default:
+ case CF_NUMBER:
+ nVal = text::ChapterFormat::NUMBER;
+ break;
+ case CF_NUM_NOPREPST_TITLE:
+ nVal = text::ChapterFormat::DIGIT;
+ break;
+ }
+ pArr[nCurrentElement++].Value <<= nVal;
+ }
+
+ // only a ChapterLevel != MAXLEVEL is registered
+ if (aToken.nOutlineLevel != MAXLEVEL)
+ {
+ pArr[nCurrentElement].Name = "ChapterLevel";
+ pArr[nCurrentElement].Value <<= aToken.nOutlineLevel;
+ }
+ }
+ break;
+ case TOKEN_ENTRY: // no difference between Entry and Entry Text
+ case TOKEN_ENTRY_TEXT:
+ {
+ rCurTokenSeq.realloc( 2 );
+ beans::PropertyValue* pArr = rCurTokenSeq.getArray();
+
+ pArr[0].Name = "TokenType";
+ pArr[0].Value <<= OUString("TokenEntryText");
+
+ pArr[1].Name = "CharacterStyleName";
+ pArr[1].Value <<= aProgCharStyle;
+ }
+ break;
+ case TOKEN_TAB_STOP:
+ {
+ rCurTokenSeq.realloc(5); // #i21237#
+ beans::PropertyValue* pArr = rCurTokenSeq.getArray();
+
+ pArr[0].Name = "TokenType";
+ pArr[0].Value <<= OUString("TokenTabStop");
+
+ if(SvxTabAdjust::End == aToken.eTabAlign)
+ {
+ pArr[1].Name = "TabStopRightAligned";
+ pArr[1].Value <<= true;
+ }
+ else
+ {
+ pArr[1].Name = "TabStopPosition";
+ sal_Int32 nPos = convertTwipToMm100(aToken.nTabStopPosition);
+ if(nPos < 0)
+ nPos = 0;
+ pArr[1].Value <<= nPos;
+ }
+ pArr[2].Name = "TabStopFillCharacter";
+ pArr[2].Value <<= OUString(aToken.cTabFillChar);
+ pArr[3].Name = "CharacterStyleName";
+ pArr[3].Value <<= aProgCharStyle;
+ // #i21237#
+ pArr[4].Name = "WithTab";
+ pArr[4].Value <<= aToken.bWithTab;
+ }
+ break;
+ case TOKEN_TEXT:
+ {
+ rCurTokenSeq.realloc( 3 );
+ beans::PropertyValue* pArr = rCurTokenSeq.getArray();
+
+ pArr[0].Name = "TokenType";
+ pArr[0].Value <<= OUString("TokenText");
+
+ pArr[1].Name = "CharacterStyleName";
+ pArr[1].Value <<= aProgCharStyle;
+
+ pArr[2].Name = "Text";
+ pArr[2].Value <<= aToken.sText;
+ }
+ break;
+ case TOKEN_PAGE_NUMS:
+ {
+ rCurTokenSeq.realloc( 2 );
+ beans::PropertyValue* pArr = rCurTokenSeq.getArray();
+
+ pArr[0].Name = "TokenType";
+ pArr[0].Value <<= OUString("TokenPageNumber");
+
+ pArr[1].Name = "CharacterStyleName";
+ pArr[1].Value <<= aProgCharStyle;
+ }
+ break;
+ case TOKEN_CHAPTER_INFO:
+ {
+ rCurTokenSeq.realloc( 4 );
+ beans::PropertyValue* pArr = rCurTokenSeq.getArray();
+
+ pArr[0].Name = "TokenType";
+ pArr[0].Value <<= OUString("TokenChapterInfo");
+
+ pArr[1].Name = "CharacterStyleName";
+ pArr[1].Value <<= aProgCharStyle;
+
+ pArr[2].Name = "ChapterFormat";
+ sal_Int16 nVal = text::ChapterFormat::NUMBER;
+ switch(aToken.nChapterFormat)
+ {
+ case CF_NUMBER:
+ nVal = text::ChapterFormat::NUMBER;
+ break;
+ case CF_TITLE:
+ nVal = text::ChapterFormat::NAME;
+ break;
+ case CF_NUM_TITLE:
+ nVal = text::ChapterFormat::NAME_NUMBER;
+ break;
+ case CF_NUMBER_NOPREPST:
+ nVal = text::ChapterFormat::NO_PREFIX_SUFFIX;
+ break;
+ case CF_NUM_NOPREPST_TITLE:
+ nVal = text::ChapterFormat::DIGIT;
+ break;
+ }
+ pArr[2].Value <<= nVal;
+// #i53420#
+ pArr[3].Name = "ChapterLevel";
+ pArr[3].Value <<= aToken.nOutlineLevel;
+ }
+ break;
+ case TOKEN_LINK_START:
+ {
+ rCurTokenSeq.realloc( 2 );
+ beans::PropertyValue* pArr = rCurTokenSeq.getArray();
+
+ pArr[0].Name = "TokenType";
+ pArr[0].Value <<=
+ OUString("TokenHyperlinkStart");
+ pArr[1].Name = "CharacterStyleName";
+ pArr[1].Value <<= aProgCharStyle;
+ }
+ break;
+ case TOKEN_LINK_END:
+ {
+ rCurTokenSeq.realloc( 1 );
+ beans::PropertyValue* pArr = rCurTokenSeq.getArray();
+
+ pArr[0].Name = "TokenType";
+ pArr[0].Value <<=
+ OUString("TokenHyperlinkEnd");
+ }
+ break;
+ case TOKEN_AUTHORITY:
+ {
+ rCurTokenSeq.realloc( 3 );
+ beans::PropertyValue* pArr = rCurTokenSeq.getArray();
+
+ pArr[0].Name = "TokenType";
+ pArr[0].Value <<=
+ OUString("TokenBibliographyDataField");
+
+ pArr[1].Name = "CharacterStyleName";
+ pArr[1].Value <<= aProgCharStyle;
+
+ pArr[2].Name = "BibliographyDataField";
+ pArr[2].Value <<= sal_Int16(aToken.nAuthorityField);
+ }
+ break;
+
+ default:
+ ;
+ }
+ }
+
+ uno::Any aRet;
+ aRet <<= aRetSeq;
+ return aRet;
+}
+
+uno::Type SAL_CALL
+SwXDocumentIndex::TokenAccess_Impl::getElementType()
+{
+ return cppu::UnoType<uno::Sequence< beans::PropertyValues >>::get();
+}
+
+sal_Bool SAL_CALL
+SwXDocumentIndex::TokenAccess_Impl::hasElements()
+{
+ return true;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/core/unocore/unolinebreak.cxx b/sw/source/core/unocore/unolinebreak.cxx
new file mode 100644
index 0000000000..d040113290
--- /dev/null
+++ b/sw/source/core/unocore/unolinebreak.cxx
@@ -0,0 +1,283 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <unolinebreak.hxx>
+
+#include <cppuhelper/supportsservice.hxx>
+#include <sal/log.hxx>
+#include <svl/listener.hxx>
+#include <svl/itemprop.hxx>
+
+#include <IDocumentContentOperations.hxx>
+#include <doc.hxx>
+#include <formatlinebreak.hxx>
+#include <unotextrange.hxx>
+#include <ndtxt.hxx>
+#include <textlinebreak.hxx>
+#include <unomap.hxx>
+#include <unoprnms.hxx>
+
+using namespace com::sun::star;
+
+/// The inner part SwXLineBreak, which is deleted with a locked SolarMutex.
+class SwXLineBreak::Impl : public SvtListener
+{
+public:
+ bool m_bIsDescriptor;
+ SwFormatLineBreak* m_pFormatLineBreak;
+ SwLineBreakClear m_eClear;
+
+ Impl(SwFormatLineBreak* const pLineBreak)
+ : m_bIsDescriptor(pLineBreak == nullptr)
+ , m_pFormatLineBreak(pLineBreak)
+ , m_eClear(SwLineBreakClear::NONE)
+ {
+ if (m_pFormatLineBreak)
+ {
+ StartListening(m_pFormatLineBreak->GetNotifier());
+ }
+ }
+
+ const SwFormatLineBreak* GetLineBreakFormat() const;
+
+ const SwFormatLineBreak& GetLineBreakFormatOrThrow() const;
+
+ void Invalidate();
+
+protected:
+ void Notify(const SfxHint& rHint) override;
+};
+
+const SwFormatLineBreak* SwXLineBreak::Impl::GetLineBreakFormat() const
+{
+ return m_pFormatLineBreak;
+}
+
+const SwFormatLineBreak& SwXLineBreak::Impl::GetLineBreakFormatOrThrow() const
+{
+ const SwFormatLineBreak* pLineBreak(GetLineBreakFormat());
+ if (!pLineBreak)
+ {
+ throw uno::RuntimeException("SwXLineBreak: disposed or invalid", nullptr);
+ }
+
+ return *pLineBreak;
+}
+
+void SwXLineBreak::Impl::Invalidate()
+{
+ EndListeningAll();
+ m_pFormatLineBreak = nullptr;
+}
+
+void SwXLineBreak::Impl::Notify(const SfxHint& rHint)
+{
+ if (rHint.GetId() == SfxHintId::Dying)
+ {
+ Invalidate();
+ }
+}
+
+SwXLineBreak::SwXLineBreak(SwFormatLineBreak& rFormat)
+ : m_pImpl(new SwXLineBreak::Impl(&rFormat))
+{
+}
+
+SwXLineBreak::SwXLineBreak()
+ : m_pImpl(new SwXLineBreak::Impl(nullptr))
+{
+}
+
+SwXLineBreak::~SwXLineBreak() {}
+
+rtl::Reference<SwXLineBreak> SwXLineBreak::CreateXLineBreak(SwFormatLineBreak* pLineBreakFormat)
+{
+ rtl::Reference<SwXLineBreak> xLineBreak;
+ if (pLineBreakFormat)
+ {
+ xLineBreak = pLineBreakFormat->GetXTextContent();
+ }
+ if (!xLineBreak.is())
+ {
+ xLineBreak = pLineBreakFormat ? new SwXLineBreak(*pLineBreakFormat) : new SwXLineBreak;
+ if (pLineBreakFormat)
+ {
+ pLineBreakFormat->SetXLineBreak(xLineBreak);
+ }
+ }
+ return xLineBreak;
+}
+
+OUString SAL_CALL SwXLineBreak::getImplementationName() { return "SwXLineBreak"; }
+
+sal_Bool SAL_CALL SwXLineBreak::supportsService(const OUString& rServiceName)
+{
+ return cppu::supportsService(this, rServiceName);
+}
+
+uno::Sequence<OUString> SAL_CALL SwXLineBreak::getSupportedServiceNames()
+{
+ return { "com.sun.star.text.LineBreak" };
+}
+
+void SAL_CALL SwXLineBreak::attach(const uno::Reference<text::XTextRange>& xTextRange)
+{
+ SolarMutexGuard aGuard;
+ if (!m_pImpl->m_bIsDescriptor)
+ {
+ throw uno::RuntimeException();
+ }
+
+ auto pRange = dynamic_cast<SwXTextRange*>(xTextRange.get());
+ if (!pRange)
+ {
+ throw lang::IllegalArgumentException();
+ }
+
+ SwDoc& rNewDoc = pRange->GetDoc();
+ SwUnoInternalPaM aPam(rNewDoc);
+ sw::XTextRangeToSwPaM(aPam, xTextRange);
+ UnoActionContext aContext(&rNewDoc);
+ SwFormatLineBreak aLineBreak(m_pImpl->m_eClear);
+ SetAttrMode nInsertFlags = SetAttrMode::DEFAULT;
+ rNewDoc.getIDocumentContentOperations().InsertPoolItem(aPam, aLineBreak, nInsertFlags);
+ auto pTextAttr
+ = static_cast<SwTextLineBreak*>(aPam.GetPointNode().GetTextNode()->GetTextAttrForCharAt(
+ aPam.GetPoint()->GetContentIndex() - 1, RES_TXTATR_LINEBREAK));
+ if (pTextAttr)
+ {
+ m_pImpl->EndListeningAll();
+ auto pLineBreak = const_cast<SwFormatLineBreak*>(&pTextAttr->GetLineBreak());
+ m_pImpl->m_pFormatLineBreak = pLineBreak;
+ m_pImpl->StartListening(pLineBreak->GetNotifier());
+ }
+ m_pImpl->m_bIsDescriptor = false;
+}
+
+uno::Reference<text::XTextRange> SAL_CALL SwXLineBreak::getAnchor()
+{
+ SolarMutexGuard aGuard;
+
+ return m_pImpl->GetLineBreakFormatOrThrow().GetAnchor();
+}
+
+void SAL_CALL SwXLineBreak::dispose()
+{
+ SAL_WARN("sw.uno", "SwXLineBreak::dispose: not implemented");
+}
+
+void SAL_CALL
+SwXLineBreak::addEventListener(const uno::Reference<lang::XEventListener>& /*xListener*/)
+{
+}
+
+void SAL_CALL
+SwXLineBreak::removeEventListener(const uno::Reference<lang::XEventListener>& /*xListener*/)
+{
+}
+
+uno::Reference<beans::XPropertySetInfo> SAL_CALL SwXLineBreak::getPropertySetInfo()
+{
+ SolarMutexGuard aGuard;
+
+ static uno::Reference<beans::XPropertySetInfo> xRet
+ = aSwMapProvider.GetPropertySet(PROPERTY_MAP_LINEBREAK)->getPropertySetInfo();
+ return xRet;
+}
+
+void SAL_CALL SwXLineBreak::setPropertyValue(const OUString& rPropertyName,
+ const css::uno::Any& rValue)
+{
+ SolarMutexGuard aGuard;
+
+ if (rPropertyName != UNO_NAME_CLEAR)
+ {
+ throw lang::IllegalArgumentException();
+ }
+
+ if (m_pImpl->m_bIsDescriptor)
+ {
+ sal_Int16 eValue{};
+ if (rValue >>= eValue)
+ {
+ m_pImpl->m_eClear = static_cast<SwLineBreakClear>(eValue);
+ }
+ }
+ else
+ {
+ m_pImpl->m_pFormatLineBreak->PutValue(rValue, 0);
+ }
+}
+
+uno::Any SAL_CALL SwXLineBreak::getPropertyValue(const OUString& rPropertyName)
+{
+ SolarMutexGuard aGuard;
+
+ uno::Any aRet;
+ if (sw::GetDefaultTextContentValue(aRet, rPropertyName))
+ {
+ return aRet;
+ }
+
+ if (rPropertyName != UNO_NAME_CLEAR)
+ {
+ throw beans::UnknownPropertyException(rPropertyName);
+ }
+
+ if (m_pImpl->m_bIsDescriptor)
+ {
+ auto eValue = static_cast<sal_Int16>(m_pImpl->m_eClear);
+ aRet <<= eValue;
+ }
+ else
+ {
+ aRet <<= m_pImpl->m_pFormatLineBreak->GetEnumValue();
+ }
+ return aRet;
+}
+
+void SAL_CALL SwXLineBreak::addPropertyChangeListener(
+ const OUString& /*rPropertyName*/,
+ const uno::Reference<beans::XPropertyChangeListener>& /*xListener*/)
+{
+ SAL_WARN("sw.uno", "SwXLineBreak::addPropertyChangeListener: not implemented");
+}
+
+void SAL_CALL SwXLineBreak::removePropertyChangeListener(
+ const OUString& /*rPropertyName*/,
+ const uno::Reference<beans::XPropertyChangeListener>& /*xListener*/)
+{
+ SAL_WARN("sw.uno", "SwXLineBreak::removePropertyChangeListener: not implemented");
+}
+
+void SAL_CALL SwXLineBreak::addVetoableChangeListener(
+ const OUString& /*rPropertyName*/,
+ const uno::Reference<beans::XVetoableChangeListener>& /*xListener*/)
+{
+ SAL_WARN("sw.uno", "SwXLineBreak::addVetoableChangeListener: not implemented");
+}
+
+void SAL_CALL SwXLineBreak::removeVetoableChangeListener(
+ const OUString& /*rPropertyName*/,
+ const uno::Reference<beans::XVetoableChangeListener>& /*xListener*/)
+{
+ SAL_WARN("sw.uno", "SwXLineBreak::removeVetoableChangeListener: not implemented");
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/core/unocore/unomap.cxx b/sw/source/core/unocore/unomap.cxx
new file mode 100644
index 0000000000..3004fb684e
--- /dev/null
+++ b/sw/source/core/unocore/unomap.cxx
@@ -0,0 +1,1558 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <hintids.hxx>
+
+#include <com/sun/star/awt/FontSlant.hpp>
+#include <com/sun/star/awt/Point.hpp>
+#include <com/sun/star/awt/XBitmap.hpp>
+#include <com/sun/star/beans/NamedValue.hpp>
+#include <com/sun/star/beans/PropertyAttribute.hpp>
+#include <com/sun/star/beans/PropertyValue.hpp>
+#include <com/sun/star/beans/PropertyValues.hpp>
+#include <com/sun/star/container/XIndexReplace.hpp>
+#include <com/sun/star/frame/XModel.hpp>
+#include <com/sun/star/graphic/XGraphic.hpp>
+#include <com/sun/star/i18n/XForbiddenCharacters.hpp>
+#include <com/sun/star/sdbc/XConnection.hpp>
+#include <com/sun/star/sdbc/XResultSet.hpp>
+#include <com/sun/star/style/GraphicLocation.hpp>
+#include <com/sun/star/table/BorderLine.hpp>
+#include <com/sun/star/text/PageNumberType.hpp>
+#include <com/sun/star/text/TableColumnSeparator.hpp>
+#include <com/sun/star/text/TextContentAnchorType.hpp>
+#include <com/sun/star/text/WrapTextMode.hpp>
+#include <com/sun/star/text/XDependentTextField.hpp>
+#include <com/sun/star/text/XDocumentIndexMark.hpp>
+#include <com/sun/star/text/XTextColumns.hpp>
+#include <com/sun/star/text/XTextFrame.hpp>
+#include <com/sun/star/text/XTextSection.hpp>
+#include <com/sun/star/util/Date.hpp>
+#include <com/sun/star/util/DateTime.hpp>
+#include <com/sun/star/util/XTheme.hpp>
+#include <com/sun/star/util/XComplexColor.hpp>
+#include <com/sun/star/view/PaperOrientation.hpp>
+#include <com/sun/star/script/XLibraryContainer.hpp>
+#include <com/sun/star/drawing/HomogenMatrix3.hpp>
+#include <osl/diagnose.h>
+#include <unomap.hxx>
+#include <unoprnms.hxx>
+#include <unomid.h>
+#include <cmdid.h>
+#include <unofldmid.h>
+#include <editeng/memberids.h>
+#include <editeng/unoprnms.hxx>
+#include <svl/itemprop.hxx>
+#include "unomapproperties.hxx"
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::beans;
+
+#define COMMON_FLDTYP_PROPERTIES \
+ { UNO_NAME_IS_FIELD_USED, FIELD_PROP_IS_FIELD_USED, cppu::UnoType<float>::get(), PropertyAttribute::READONLY, 0},\
+ { UNO_NAME_IS_FIELD_DISPLAYED, FIELD_PROP_IS_FIELD_DISPLAYED, cppu::UnoType<sal_Int16>::get(), PropertyAttribute::READONLY, 0},\
+ { UNO_NAME_TITLE, FIELD_PROP_TITLE, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},\
+
+std::span<const SfxItemPropertyMapEntry> SwUnoPropertyMapProvider::GetPropertyMapEntries(sal_uInt16 nPropertyId)
+{
+ OSL_ENSURE(nPropertyId < PROPERTY_MAP_END, "Id ?" );
+ if( m_aMapEntriesArr[ nPropertyId ].empty() )
+ {
+ switch(nPropertyId)
+ {
+ case PROPERTY_MAP_TEXT_CURSOR:
+ {
+ m_aMapEntriesArr[nPropertyId] = GetTextCursorPropertyMap();
+ }
+ break;
+ case PROPERTY_MAP_ACCESSIBILITY_TEXT_ATTRIBUTE:
+ {
+ m_aMapEntriesArr[nPropertyId] = GetAccessibilityTextAttrPropertyMap();
+ }
+ break;
+ case PROPERTY_MAP_PARAGRAPH:
+ {
+ m_aMapEntriesArr[nPropertyId] = GetParagraphPropertyMap();
+ }
+ break;
+ case PROPERTY_MAP_PARA_AUTO_STYLE :
+ {
+ m_aMapEntriesArr[nPropertyId] = GetAutoParaStylePropertyMap();
+ }
+ break;
+ case PROPERTY_MAP_CHAR_STYLE :
+ {
+ m_aMapEntriesArr[nPropertyId] = GetCharStylePropertyMap();
+ }
+ break;
+ case PROPERTY_MAP_CHAR_AUTO_STYLE :
+ {
+ m_aMapEntriesArr[nPropertyId] = GetAutoCharStylePropertyMap();
+ }
+ break;
+ case PROPERTY_MAP_RUBY_AUTO_STYLE :
+ {
+ static SfxItemPropertyMapEntry const aAutoRubyStyleMap [] =
+ {
+ { UNO_NAME_RUBY_ADJUST, RES_TXTATR_CJK_RUBY, cppu::UnoType<sal_Int16>::get(), PropertyAttribute::MAYBEVOID, MID_RUBY_ADJUST },
+ { UNO_NAME_RUBY_IS_ABOVE, RES_TXTATR_CJK_RUBY, cppu::UnoType<bool>::get(), PropertyAttribute::MAYBEVOID, MID_RUBY_ABOVE },
+ { UNO_NAME_RUBY_POSITION, RES_TXTATR_CJK_RUBY, cppu::UnoType<sal_Int16>::get(), PropertyAttribute::MAYBEVOID, MID_RUBY_POSITION },
+ };
+ m_aMapEntriesArr[nPropertyId] = aAutoRubyStyleMap;
+ }
+ break;
+ case PROPERTY_MAP_PARA_STYLE :
+ {
+ m_aMapEntriesArr[nPropertyId] = GetParaStylePropertyMap();
+ }
+ break;
+ case PROPERTY_MAP_CONDITIONAL_PARA_STYLE :
+ {
+ m_aMapEntriesArr[nPropertyId] = GetConditionalParaStylePropertyMap();
+ }
+ break;
+ case PROPERTY_MAP_FRAME_STYLE:
+ {
+ m_aMapEntriesArr[nPropertyId] = GetFrameStylePropertyMap();
+ }
+ break;
+ case PROPERTY_MAP_PAGE_STYLE :
+ {
+ m_aMapEntriesArr[nPropertyId] = GetPageStylePropertyMap();
+ }
+ break;
+ case PROPERTY_MAP_NUM_STYLE :
+ {
+ static SfxItemPropertyMapEntry const aNumStyleMap [] =
+ {
+ { UNO_NAME_NUMBERING_RULES, FN_UNO_NUM_RULES, cppu::UnoType<css::container::XIndexReplace>::get(), PROPERTY_NONE, CONVERT_TWIPS},
+ { UNO_NAME_IS_PHYSICAL, FN_UNO_IS_PHYSICAL, cppu::UnoType<bool>::get(), PropertyAttribute::READONLY, 0},
+ { UNO_NAME_DISPLAY_NAME, FN_UNO_DISPLAY_NAME, cppu::UnoType<OUString>::get(), PropertyAttribute::READONLY, 0},
+ { UNO_NAME_HIDDEN, FN_UNO_HIDDEN, cppu::UnoType<bool>::get(), PROPERTY_NONE, 0},
+ { UNO_NAME_STYLE_INTEROP_GRAB_BAG, FN_UNO_STYLE_INTEROP_GRAB_BAG, cppu::UnoType< cppu::UnoSequenceType<css::beans::PropertyValue> >::get(), PROPERTY_NONE, 0},
+ };
+ m_aMapEntriesArr[nPropertyId] = aNumStyleMap;
+ }
+ break;
+ case PROPERTY_MAP_TEXT_TABLE :
+ {
+ m_aMapEntriesArr[nPropertyId] = GetTablePropertyMap();
+ }
+ break;
+ case PROPERTY_MAP_TABLE_CELL :
+ {
+ static SfxItemPropertyMapEntry const aCellMap_Impl[] =
+ {
+ { UNO_NAME_BACK_COLOR, RES_BACKGROUND, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE , MID_BACK_COLOR },
+ { UNO_NAME_BACKGROUND_COMPLEX_COLOR, RES_BACKGROUND, cppu::UnoType<css::util::XComplexColor>::get(), PROPERTY_NONE, MID_BACKGROUND_COMPLEX_COLOR },
+ { UNO_NAME_BACK_GRAPHIC_URL, RES_BACKGROUND, cppu::UnoType<OUString>::get(), PROPERTY_NONE ,MID_GRAPHIC_URL },
+ { UNO_NAME_BACK_GRAPHIC, RES_BACKGROUND, cppu::UnoType<graphic::XGraphic>::get(), PROPERTY_NONE, MID_GRAPHIC },
+ { UNO_NAME_BACK_GRAPHIC_FILTER, RES_BACKGROUND, cppu::UnoType<OUString>::get(), PROPERTY_NONE ,MID_GRAPHIC_FILTER },
+ { UNO_NAME_BACK_GRAPHIC_LOCATION, RES_BACKGROUND, cppu::UnoType<css::style::GraphicLocation>::get(), PROPERTY_NONE ,MID_GRAPHIC_POSITION},
+ { UNO_NAME_BACK_TRANSPARENT, RES_BACKGROUND, cppu::UnoType<bool>::get(), PROPERTY_NONE , MID_GRAPHIC_TRANSPARENT },
+ { UNO_NAME_NUMBER_FORMAT, RES_BOXATR_FORMAT, cppu::UnoType<sal_Int32>::get(), PropertyAttribute::MAYBEVOID ,0 },
+ { UNO_NAME_LEFT_BORDER, RES_BOX, cppu::UnoType<css::table::BorderLine>::get(), 0, LEFT_BORDER |CONVERT_TWIPS },
+ { UNO_NAME_RIGHT_BORDER, RES_BOX, cppu::UnoType<css::table::BorderLine>::get(), 0, RIGHT_BORDER |CONVERT_TWIPS },
+ { UNO_NAME_TOP_BORDER, RES_BOX, cppu::UnoType<css::table::BorderLine>::get(), 0, TOP_BORDER |CONVERT_TWIPS },
+ { UNO_NAME_BOTTOM_BORDER, RES_BOX, cppu::UnoType<css::table::BorderLine>::get(), 0, BOTTOM_BORDER|CONVERT_TWIPS },
+ { UNO_NAME_BORDER_DISTANCE, RES_BOX, cppu::UnoType<sal_Int32>::get(), 0, BORDER_DISTANCE|CONVERT_TWIPS },
+ { UNO_NAME_LEFT_BORDER_DISTANCE, RES_BOX, cppu::UnoType<sal_Int32>::get(), 0, LEFT_BORDER_DISTANCE |CONVERT_TWIPS },
+ { UNO_NAME_RIGHT_BORDER_DISTANCE, RES_BOX, cppu::UnoType<sal_Int32>::get(), 0, RIGHT_BORDER_DISTANCE |CONVERT_TWIPS },
+ { UNO_NAME_TOP_BORDER_DISTANCE, RES_BOX, cppu::UnoType<sal_Int32>::get(), 0, TOP_BORDER_DISTANCE |CONVERT_TWIPS },
+ { UNO_NAME_BOTTOM_BORDER_DISTANCE, RES_BOX, cppu::UnoType<sal_Int32>::get(), 0, BOTTOM_BORDER_DISTANCE|CONVERT_TWIPS },
+ { UNO_NAME_BORDER_LEFT_COMPLEX_COLOR, RES_BOX, cppu::UnoType<css::util::XComplexColor>::get(), 0, MID_BORDER_LEFT_COLOR },
+ { UNO_NAME_BORDER_RIGHT_COMPLEX_COLOR, RES_BOX, cppu::UnoType<css::util::XComplexColor>::get(), 0, MID_BORDER_RIGHT_COLOR },
+ { UNO_NAME_BORDER_TOP_COMPLEX_COLOR, RES_BOX, cppu::UnoType<css::util::XComplexColor>::get(), 0, MID_BORDER_TOP_COLOR },
+ { UNO_NAME_BORDER_BOTTOM_COMPLEX_COLOR, RES_BOX, cppu::UnoType<css::util::XComplexColor>::get(), 0, MID_BORDER_BOTTOM_COLOR },
+ { UNO_NAME_USER_DEFINED_ATTRIBUTES, RES_UNKNOWNATR_CONTAINER, cppu::UnoType<css::container::XNameContainer>::get(), PropertyAttribute::MAYBEVOID, 0 },
+ { UNO_NAME_TEXT_SECTION, FN_UNO_TEXT_SECTION, cppu::UnoType<css::text::XTextSection>::get(), PropertyAttribute::MAYBEVOID|PropertyAttribute::READONLY ,0 },
+ { UNO_NAME_IS_PROTECTED, RES_PROTECT, cppu::UnoType<bool>::get(), 0, MID_PROTECT_CONTENT},
+ { UNO_NAME_CELL_NAME, FN_UNO_CELL_NAME, cppu::UnoType<OUString>::get(), PropertyAttribute::READONLY,0},
+ { UNO_NAME_VERT_ORIENT, RES_VERT_ORIENT, cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE ,MID_VERTORIENT_ORIENT },
+ { UNO_NAME_WRITING_MODE, RES_FRAMEDIR, cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE, 0 },
+ { UNO_NAME_ROW_SPAN, FN_UNO_CELL_ROW_SPAN, cppu::UnoType<sal_Int32>::get(), 0, 0 },
+ { UNO_NAME_CELL_INTEROP_GRAB_BAG, RES_FRMATR_GRABBAG, cppu::UnoType< cppu::UnoSequenceType<css::beans::PropertyValue> >::get(), PROPERTY_NONE, 0 },
+ { UNO_NAME_PARENT_TEXT, FN_UNO_PARENT_TEXT, cppu::UnoType<text::XText>::get(), PropertyAttribute::MAYBEVOID | PropertyAttribute::READONLY, 0 },
+ { UNO_NAME_HAS_TEXT_CHANGES_ONLY, RES_PRINT, cppu::UnoType<bool>::get() , PropertyAttribute::MAYBEVOID, 0},
+ REDLINE_NODE_PROPERTIES
+ };
+ m_aMapEntriesArr[nPropertyId] = aCellMap_Impl;
+ }
+ break;
+ case PROPERTY_MAP_TABLE_RANGE:
+ {
+ m_aMapEntriesArr[nPropertyId] = GetRangePropertyMap();
+ }
+ break;
+ case PROPERTY_MAP_SECTION:
+ {
+ m_aMapEntriesArr[nPropertyId] = GetSectionPropertyMap();
+ }
+ break;
+ case PROPERTY_MAP_TEXT_SEARCH:
+ {
+ static SfxItemPropertyMapEntry const aSearchPropertyMap_Impl[] =
+ {
+ { UNO_NAME_SEARCH_ALL, WID_SEARCH_ALL, cppu::UnoType<bool>::get() , PROPERTY_NONE, 0},
+ { UNO_NAME_SEARCH_BACKWARDS, WID_BACKWARDS, cppu::UnoType<bool>::get() , PROPERTY_NONE, 0},
+ { UNO_NAME_SEARCH_CASE_SENSITIVE, WID_CASE_SENSITIVE, cppu::UnoType<bool>::get() , PROPERTY_NONE, 0},
+ { UNO_NAME_SEARCH_REGULAR_EXPRESSION, WID_REGULAR_EXPRESSION, cppu::UnoType<bool>::get() , PROPERTY_NONE, 0},
+ { UNO_NAME_SEARCH_SIMILARITY, WID_SIMILARITY, cppu::UnoType<bool>::get() , PROPERTY_NONE, 0},
+ { UNO_NAME_SEARCH_SIMILARITY_ADD, WID_SIMILARITY_ADD, cppu::UnoType<sal_Int16>::get() , PROPERTY_NONE, 0},
+ { UNO_NAME_SEARCH_SIMILARITY_EXCHANGE, WID_SIMILARITY_EXCHANGE,cppu::UnoType<sal_Int16>::get() , PROPERTY_NONE, 0},
+ { UNO_NAME_SEARCH_SIMILARITY_RELAX, WID_SIMILARITY_RELAX, cppu::UnoType<bool>::get() , PROPERTY_NONE, 0},
+ { UNO_NAME_SEARCH_SIMILARITY_REMOVE, WID_SIMILARITY_REMOVE, cppu::UnoType<sal_Int16>::get() , PROPERTY_NONE, 0},
+ { UNO_NAME_SEARCH_STYLES, WID_STYLES, cppu::UnoType<bool>::get() , PROPERTY_NONE, 0},
+ { UNO_NAME_SEARCH_WORDS, WID_WORDS, cppu::UnoType<bool>::get() , PROPERTY_NONE, 0},
+ };
+ m_aMapEntriesArr[nPropertyId] = aSearchPropertyMap_Impl;
+ }
+ break;
+ case PROPERTY_MAP_TEXT_FRAME:
+ {
+ m_aMapEntriesArr[nPropertyId] = GetFramePropertyMap();
+ }
+ break;
+ case PROPERTY_MAP_TEXT_GRAPHIC:
+ {
+ m_aMapEntriesArr[nPropertyId] = GetGraphicPropertyMap();
+ }
+ break;
+ case PROPERTY_MAP_EMBEDDED_OBJECT:
+ {
+ m_aMapEntriesArr[nPropertyId] = GetEmbeddedPropertyMap();
+ }
+ break;
+ case PROPERTY_MAP_TEXT_PAGE:
+ {
+ static SfxItemPropertyMapEntry const aPageMap_Impl[] =
+ {
+ { u"BorderBottom"_ustr, WID_PAGE_BOTTOM, ::cppu::UnoType<sal_Int32>::get(), PropertyAttribute::MAYBEVOID, 0},
+ { u"BorderLeft"_ustr, WID_PAGE_LEFT, ::cppu::UnoType<sal_Int32>::get(), PropertyAttribute::MAYBEVOID, 0},
+ { u"BorderRight"_ustr, WID_PAGE_RIGHT, ::cppu::UnoType<sal_Int32>::get(), PropertyAttribute::MAYBEVOID, 0},
+ { u"BorderTop"_ustr, WID_PAGE_TOP, ::cppu::UnoType<sal_Int32>::get(), PropertyAttribute::MAYBEVOID, 0},
+ { u"Height"_ustr, WID_PAGE_HEIGHT, ::cppu::UnoType<sal_Int32>::get(), PropertyAttribute::MAYBEVOID, 0},
+ { u"Width"_ustr, WID_PAGE_WIDTH, ::cppu::UnoType<sal_Int32>::get(), PropertyAttribute::MAYBEVOID, 0},
+ { u"Number"_ustr, WID_PAGE_NUMBER, ::cppu::UnoType<sal_Int16>::get(), PropertyAttribute::MAYBEVOID, 0},
+ { u"Orientation"_ustr, WID_PAGE_ORIENT, ::cppu::UnoType<view::PaperOrientation>::get(), PropertyAttribute::MAYBEVOID|PropertyAttribute::READONLY, 0},
+ { u"UserDefinedAttributes"_ustr, WID_PAGE_USERATTRIBS, ::cppu::UnoType<container::XNameContainer>::get(), PropertyAttribute::MAYBEVOID, 0},
+ { u"IsBackgroundDark"_ustr, WID_PAGE_ISDARK, ::cppu::UnoType<bool>::get(), PropertyAttribute::MAYBEVOID|PropertyAttribute::READONLY, 0},
+ { u"NavigationOrder"_ustr, WID_NAVORDER, ::cppu::UnoType<container::XIndexAccess>::get(), PropertyAttribute::MAYBEVOID, 0},
+ { u"BackgroundFullSize"_ustr, WID_PAGE_BACKFULL, ::cppu::UnoType<bool>::get(), PropertyAttribute::MAYBEVOID, 0},
+ { u"Theme"_ustr, WID_PAGE_THEME, cppu::UnoType<util::XTheme>::get(), PropertyAttribute::MAYBEVOID, 0}
+ };
+ m_aMapEntriesArr[nPropertyId] = aPageMap_Impl;
+ }
+ break;
+ case PROPERTY_MAP_TEXT_SHAPE:
+ {
+ static SfxItemPropertyMapEntry const aShapeMap_Impl[] =
+ {
+ { UNO_NAME_ANCHOR_PAGE_NO, RES_ANCHOR, cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE|PropertyAttribute::MAYBEVOID, MID_ANCHOR_PAGENUM },
+ { UNO_NAME_ANCHOR_TYPE, RES_ANCHOR, cppu::UnoType<css::text::TextContentAnchorType>::get(), PROPERTY_NONE|PropertyAttribute::MAYBEVOID, MID_ANCHOR_ANCHORTYPE},
+ { UNO_NAME_ANCHOR_FRAME, RES_ANCHOR, cppu::UnoType<css::text::XTextFrame>::get(), PropertyAttribute::MAYBEVOID, MID_ANCHOR_ANCHORFRAME},
+ { UNO_NAME_HORI_ORIENT, RES_HORI_ORIENT, cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE|PropertyAttribute::MAYBEVOID ,MID_HORIORIENT_ORIENT },
+ { UNO_NAME_HORI_ORIENT_POSITION, RES_HORI_ORIENT, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE|PropertyAttribute::MAYBEVOID ,MID_HORIORIENT_POSITION|CONVERT_TWIPS },
+ { UNO_NAME_HORI_ORIENT_RELATION, RES_HORI_ORIENT, cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE|PropertyAttribute::MAYBEVOID ,MID_HORIORIENT_RELATION },
+ { UNO_NAME_LEFT_MARGIN, RES_LR_SPACE, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE|PropertyAttribute::MAYBEVOID, MID_L_MARGIN|CONVERT_TWIPS},
+ { UNO_NAME_RIGHT_MARGIN, RES_LR_SPACE, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE|PropertyAttribute::MAYBEVOID, MID_R_MARGIN|CONVERT_TWIPS},
+ { UNO_NAME_SURROUND, RES_SURROUND, cppu::UnoType<css::text::WrapTextMode>::get(), PROPERTY_NONE|PropertyAttribute::MAYBEVOID, MID_SURROUND_SURROUNDTYPE },
+ { UNO_NAME_TEXT_WRAP, RES_SURROUND, cppu::UnoType<css::text::WrapTextMode>::get(), PROPERTY_NONE, MID_SURROUND_SURROUNDTYPE },
+ { UNO_NAME_SURROUND_ANCHORONLY, RES_SURROUND, cppu::UnoType<bool>::get(), PROPERTY_NONE|PropertyAttribute::MAYBEVOID, MID_SURROUND_ANCHORONLY },
+ { UNO_NAME_SURROUND_CONTOUR, RES_SURROUND, cppu::UnoType<bool>::get(), PROPERTY_NONE, MID_SURROUND_CONTOUR },
+ { UNO_NAME_CONTOUR_OUTSIDE, RES_SURROUND, cppu::UnoType<bool>::get(), PROPERTY_NONE, MID_SURROUND_CONTOUROUTSIDE },
+ { UNO_NAME_TOP_MARGIN, RES_UL_SPACE, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE, MID_UP_MARGIN|CONVERT_TWIPS},
+ { UNO_NAME_BOTTOM_MARGIN, RES_UL_SPACE, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE, MID_LO_MARGIN|CONVERT_TWIPS},
+ { UNO_NAME_VERT_ORIENT, RES_VERT_ORIENT, cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE|PropertyAttribute::MAYBEVOID ,MID_VERTORIENT_ORIENT },
+ { UNO_NAME_VERT_ORIENT_POSITION, RES_VERT_ORIENT, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE|PropertyAttribute::MAYBEVOID ,MID_VERTORIENT_POSITION|CONVERT_TWIPS },
+ { UNO_NAME_VERT_ORIENT_RELATION, RES_VERT_ORIENT, cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE|PropertyAttribute::MAYBEVOID ,MID_VERTORIENT_RELATION },
+ { UNO_NAME_TEXT_RANGE, FN_TEXT_RANGE, cppu::UnoType<css::text::XTextRange>::get(), PROPERTY_NONE, 0},
+ { UNO_NAME_OPAQUE, RES_OPAQUE, cppu::UnoType<bool>::get(), PROPERTY_NONE, 0},
+ { UNO_NAME_ANCHOR_POSITION, FN_ANCHOR_POSITION, cppu::UnoType<css::awt::Point>::get(), PropertyAttribute::READONLY, 0},
+ // #i26791#
+ { UNO_NAME_IS_FOLLOWING_TEXT_FLOW, RES_FOLLOW_TEXT_FLOW, cppu::UnoType<bool>::get(), PROPERTY_NONE, MID_FOLLOW_TEXT_FLOW},
+ // #i28701#
+ { UNO_NAME_WRAP_INFLUENCE_ON_POSITION, RES_WRAP_INFLUENCE_ON_OBJPOS, cppu::UnoType<sal_Int8>::get(), PROPERTY_NONE, MID_WRAP_INFLUENCE},
+ { UNO_NAME_ALLOW_OVERLAP, RES_WRAP_INFLUENCE_ON_OBJPOS, cppu::UnoType<bool>::get(), PROPERTY_NONE, MID_ALLOW_OVERLAP},
+ // #i28749#
+ { UNO_NAME_TRANSFORMATION_IN_HORI_L2R,
+ FN_SHAPE_TRANSFORMATION_IN_HORI_L2R,
+ cppu::UnoType<css::drawing::HomogenMatrix3>::get(),
+ PropertyAttribute::READONLY, 0},
+ { UNO_NAME_POSITION_LAYOUT_DIR,
+ FN_SHAPE_POSITION_LAYOUT_DIR,
+ cppu::UnoType<sal_Int16>::get(),
+ PROPERTY_NONE, 0},
+ // #i36248#
+ { UNO_NAME_STARTPOSITION_IN_HORI_L2R,
+ FN_SHAPE_STARTPOSITION_IN_HORI_L2R,
+ cppu::UnoType<css::awt::Point>::get(),
+ PropertyAttribute::READONLY, 0},
+ { UNO_NAME_ENDPOSITION_IN_HORI_L2R,
+ FN_SHAPE_ENDPOSITION_IN_HORI_L2R,
+ cppu::UnoType<css::awt::Point>::get(),
+ PropertyAttribute::READONLY, 0},
+ // #i71182#
+ // missing map entry for property <PageToggle>
+ { UNO_NAME_PAGE_TOGGLE, RES_HORI_ORIENT, cppu::UnoType<bool>::get(), PROPERTY_NONE ,MID_HORIORIENT_PAGETOGGLE },
+ { UNO_NAME_RELATIVE_HEIGHT, RES_FRM_SIZE, cppu::UnoType<sal_Int16>::get() , PROPERTY_NONE, MID_FRMSIZE_REL_HEIGHT },
+ { UNO_NAME_RELATIVE_HEIGHT_RELATION, RES_FRM_SIZE, cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE, MID_FRMSIZE_REL_HEIGHT_RELATION },
+ { UNO_NAME_RELATIVE_WIDTH, RES_FRM_SIZE, cppu::UnoType<sal_Int16>::get() , PROPERTY_NONE, MID_FRMSIZE_REL_WIDTH },
+ { UNO_NAME_RELATIVE_WIDTH_RELATION, RES_FRM_SIZE, cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE, MID_FRMSIZE_REL_WIDTH_RELATION },
+ { UNO_NAME_TEXT_BOX, FN_TEXT_BOX, cppu::UnoType<bool>::get(), PROPERTY_NONE, MID_TEXT_BOX},
+ { UNO_NAME_TEXT_BOX_CONTENT, FN_TEXT_BOX, cppu::UnoType<text::XTextFrame>::get(), PROPERTY_NONE, MID_TEXT_BOX_CONTENT},
+ { UNO_NAME_CHAIN_NEXT_NAME, RES_CHAIN, cppu::UnoType<OUString>::get(), PropertyAttribute::MAYBEVOID ,MID_CHAIN_NEXTNAME},
+ { UNO_NAME_CHAIN_PREV_NAME, RES_CHAIN, cppu::UnoType<OUString>::get(), PropertyAttribute::MAYBEVOID ,MID_CHAIN_PREVNAME},
+ { UNO_NAME_CHAIN_NAME, RES_CHAIN, cppu::UnoType<OUString>::get(), PropertyAttribute::MAYBEVOID ,MID_CHAIN_NAME },
+ };
+ m_aMapEntriesArr[nPropertyId] = aShapeMap_Impl;
+ }
+ break;
+ case PROPERTY_MAP_INDEX_MARK:
+ {
+ m_aMapEntriesArr[nPropertyId] = GetIndexMarkPropertyMap();
+ }
+ break;
+ case PROPERTY_MAP_CNTIDX_MARK:
+ {
+ m_aMapEntriesArr[nPropertyId] = GetContentMarkPropertyMap();
+ }
+ break;
+ case PROPERTY_MAP_USER_MARK:
+ {
+ m_aMapEntriesArr[nPropertyId] = GetUserMarkPropertyMap();
+ }
+ break;
+ case PROPERTY_MAP_INDEX_IDX:
+ {
+ static SfxItemPropertyMapEntry const aTOXIndexMap_Impl[] =
+ {
+ BASE_INDEX_PROPERTIES_
+ { UNO_NAME_CREATE_FROM_CHAPTER, WID_CREATE_FROM_CHAPTER , cppu::UnoType<bool>::get() , PROPERTY_NONE, 0},
+ { UNO_NAME_IS_PROTECTED, WID_PROTECTED , cppu::UnoType<bool>::get() , PROPERTY_NONE, 0},
+ { UNO_NAME_USE_ALPHABETICAL_SEPARATORS, WID_USE_ALPHABETICAL_SEPARATORS , cppu::UnoType<bool>::get() , PROPERTY_NONE, 0},
+ { UNO_NAME_USE_KEY_AS_ENTRY, WID_USE_KEY_AS_ENTRY , cppu::UnoType<bool>::get() , PROPERTY_NONE, 0},
+ { UNO_NAME_USE_COMBINED_ENTRIES, WID_USE_COMBINED_ENTRIES , cppu::UnoType<bool>::get() , PROPERTY_NONE, 0},
+ { UNO_NAME_IS_CASE_SENSITIVE, WID_IS_CASE_SENSITIVE , cppu::UnoType<bool>::get() , PROPERTY_NONE, 0},
+ { UNO_NAME_USE_P_P, WID_USE_P_P , cppu::UnoType<bool>::get() , PROPERTY_NONE, 0},
+ { UNO_NAME_USE_DASH, WID_USE_DASH , cppu::UnoType<bool>::get() , PROPERTY_NONE, 0},
+ { UNO_NAME_USE_UPPER_CASE, WID_USE_UPPER_CASE , cppu::UnoType<bool>::get() , PROPERTY_NONE, 0},
+ { UNO_NAME_LEVEL_FORMAT, WID_LEVEL_FORMAT , cppu::UnoType<css::container::XIndexReplace>::get() , PROPERTY_NONE, 0},
+ { UNO_NAME_MAIN_ENTRY_CHARACTER_STYLE_NAME, WID_MAIN_ENTRY_CHARACTER_STYLE_NAME , cppu::UnoType<OUString>::get() , PROPERTY_NONE, 0},
+ { UNO_NAME_TEXT_COLUMNS, RES_COL, cppu::UnoType<css::text::XTextColumns>::get(), PROPERTY_NONE, MID_COLUMNS},
+ { UNO_NAME_BACK_GRAPHIC_URL, RES_BACKGROUND, cppu::UnoType<OUString>::get(), PROPERTY_NONE ,MID_GRAPHIC_URL },
+ { UNO_NAME_BACK_GRAPHIC, RES_BACKGROUND, cppu::UnoType<graphic::XGraphic>::get(), PROPERTY_NONE, MID_GRAPHIC },
+ { UNO_NAME_BACK_GRAPHIC_FILTER, RES_BACKGROUND, cppu::UnoType<OUString>::get(), PROPERTY_NONE ,MID_GRAPHIC_FILTER },
+ { UNO_NAME_BACK_GRAPHIC_LOCATION, RES_BACKGROUND, cppu::UnoType<css::style::GraphicLocation>::get(), PROPERTY_NONE ,MID_GRAPHIC_POSITION},
+ { UNO_NAME_BACK_COLOR, RES_BACKGROUND, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE ,MID_BACK_COLOR },
+ { UNO_NAME_BACKGROUND_COMPLEX_COLOR, RES_BACKGROUND, cppu::UnoType<css::util::XComplexColor>::get(), PROPERTY_NONE, MID_BACKGROUND_COMPLEX_COLOR },
+ { UNO_NAME_BACK_TRANSPARENT, RES_BACKGROUND, cppu::UnoType<bool>::get(), PROPERTY_NONE ,MID_GRAPHIC_TRANSPARENT },
+ { UNO_NAME_PARA_STYLEHEADING, WID_PARA_HEAD, cppu::UnoType<OUString>::get() , 0, 0},
+ { UNO_NAME_PARA_STYLESEPARATOR, WID_PARA_SEP, cppu::UnoType<OUString>::get() , 0, 0},
+ { UNO_NAME_PARA_STYLELEVEL1, WID_PARA_LEV1, cppu::UnoType<OUString>::get() , 0, 0},
+ { UNO_NAME_PARA_STYLELEVEL2, WID_PARA_LEV2, cppu::UnoType<OUString>::get() , 0, 0},
+ { UNO_NAME_PARA_STYLELEVEL3, WID_PARA_LEV3, cppu::UnoType<OUString>::get() , 0, 0},
+ { UNO_NAME_IS_COMMA_SEPARATED, WID_IS_COMMA_SEPARATED, cppu::UnoType<bool>::get(), PROPERTY_NONE ,0 },
+ { UNO_NAME_DOCUMENT_INDEX_MARKS, WID_INDEX_MARKS, cppu::UnoType< cppu::UnoSequenceType<css::text::XDocumentIndexMark> >::get(), PropertyAttribute::READONLY ,0 },
+ { UNO_NAME_IS_RELATIVE_TABSTOPS, WID_IS_RELATIVE_TABSTOPS, cppu::UnoType<bool>::get(), PROPERTY_NONE, 0},
+ { UNO_NAME_LOCALE, WID_IDX_LOCALE, cppu::UnoType<css::lang::Locale>::get(), PROPERTY_NONE, 0},
+ { UNO_NAME_SORT_ALGORITHM, WID_IDX_SORT_ALGORITHM, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ };
+ m_aMapEntriesArr[nPropertyId] = aTOXIndexMap_Impl;
+ }
+ break;
+ case PROPERTY_MAP_INDEX_CNTNT:
+ {
+ static SfxItemPropertyMapEntry const aTOXContentMap_Impl[] =
+ {
+ BASE_INDEX_PROPERTIES_
+ { UNO_NAME_LEVEL, WID_LEVEL , cppu::UnoType<sal_Int16>::get() , PROPERTY_NONE, 0},
+ { UNO_NAME_CREATE_FROM_MARKS, WID_CREATE_FROM_MARKS , cppu::UnoType<bool>::get() , PROPERTY_NONE, 0},
+ { UNO_NAME_HIDE_TAB_LEADER_AND_PAGE_NUMBERS, WID_HIDE_TABLEADER_PAGENUMBERS , cppu::UnoType<bool>::get() , PROPERTY_NONE, 0},
+ { UNO_NAME_TAB_IN_TOC, WID_TAB_IN_TOC, cppu::UnoType<bool>::get(), PROPERTY_NONE, 0},
+ { UNO_NAME_TOC_BOOKMARK, WID_TOC_BOOKMARK, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ { UNO_NAME_TOC_NEWLINE, WID_TOC_NEWLINE, cppu::UnoType<bool>::get(), PROPERTY_NONE, 0},
+ { UNO_NAME_TOC_PARAGRAPH_OUTLINE_LEVEL, WID_TOC_PARAGRAPH_OUTLINE_LEVEL, cppu::UnoType<bool>::get(), PROPERTY_NONE, 0},
+ { UNO_NAME_CREATE_FROM_OUTLINE, WID_CREATE_FROM_OUTLINE , cppu::UnoType<bool>::get() , PROPERTY_NONE, 0},
+ { UNO_NAME_CREATE_FROM_CHAPTER, WID_CREATE_FROM_CHAPTER , cppu::UnoType<bool>::get() , PROPERTY_NONE, 0},
+ { UNO_NAME_IS_PROTECTED, WID_PROTECTED , cppu::UnoType<bool>::get() , PROPERTY_NONE, 0},
+ { UNO_NAME_LEVEL_FORMAT, WID_LEVEL_FORMAT , cppu::UnoType<css::container::XIndexReplace>::get() , PROPERTY_NONE, 0},
+ { UNO_NAME_LEVEL_PARAGRAPH_STYLES, WID_LEVEL_PARAGRAPH_STYLES , cppu::UnoType<css::container::XIndexReplace>::get() , PropertyAttribute::READONLY, 0},
+ { UNO_NAME_CREATE_FROM_LEVEL_PARAGRAPH_STYLES, WID_CREATE_FROM_PARAGRAPH_STYLES, cppu::UnoType<bool>::get(), PROPERTY_NONE, 0},
+ { UNO_NAME_TEXT_COLUMNS, RES_COL, cppu::UnoType<css::text::XTextColumns>::get(), PROPERTY_NONE, MID_COLUMNS},
+ { UNO_NAME_BACK_GRAPHIC_URL, RES_BACKGROUND, cppu::UnoType<OUString>::get(), PROPERTY_NONE ,MID_GRAPHIC_URL },
+ { UNO_NAME_BACK_GRAPHIC, RES_BACKGROUND, cppu::UnoType<graphic::XGraphic>::get(), PROPERTY_NONE, MID_GRAPHIC },
+ { UNO_NAME_BACK_GRAPHIC_FILTER, RES_BACKGROUND, cppu::UnoType<OUString>::get(), PROPERTY_NONE ,MID_GRAPHIC_FILTER },
+ { UNO_NAME_BACK_GRAPHIC_LOCATION, RES_BACKGROUND, cppu::UnoType<css::style::GraphicLocation>::get(), PROPERTY_NONE ,MID_GRAPHIC_POSITION},
+ { UNO_NAME_BACK_COLOR, RES_BACKGROUND, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE ,MID_BACK_COLOR },
+ { UNO_NAME_BACKGROUND_COMPLEX_COLOR, RES_BACKGROUND, cppu::UnoType<css::util::XComplexColor>::get(), PROPERTY_NONE ,MID_BACKGROUND_COMPLEX_COLOR },
+ { UNO_NAME_BACK_TRANSPARENT, RES_BACKGROUND, cppu::UnoType<bool>::get(), PROPERTY_NONE ,MID_GRAPHIC_TRANSPARENT },
+ { UNO_NAME_PARA_STYLEHEADING, WID_PARA_HEAD, cppu::UnoType<OUString>::get() , 0, 0},
+ { UNO_NAME_PARA_STYLELEVEL1, WID_PARA_LEV1, cppu::UnoType<OUString>::get() , 0, 0},
+ { UNO_NAME_PARA_STYLELEVEL2, WID_PARA_LEV2, cppu::UnoType<OUString>::get() , 0, 0},
+ { UNO_NAME_PARA_STYLELEVEL3, WID_PARA_LEV3, cppu::UnoType<OUString>::get() , 0, 0},
+ { UNO_NAME_PARA_STYLELEVEL4, WID_PARA_LEV4, cppu::UnoType<OUString>::get() , 0, 0},
+ { UNO_NAME_PARA_STYLELEVEL5, WID_PARA_LEV5, cppu::UnoType<OUString>::get() , 0, 0},
+ { UNO_NAME_PARA_STYLELEVEL6, WID_PARA_LEV6, cppu::UnoType<OUString>::get() , 0, 0},
+ { UNO_NAME_PARA_STYLELEVEL7, WID_PARA_LEV7, cppu::UnoType<OUString>::get() , 0, 0},
+ { UNO_NAME_PARA_STYLELEVEL8, WID_PARA_LEV8, cppu::UnoType<OUString>::get() , 0, 0},
+ { UNO_NAME_PARA_STYLELEVEL9, WID_PARA_LEV9, cppu::UnoType<OUString>::get() , 0, 0},
+ { UNO_NAME_PARA_STYLELEVEL10, WID_PARA_LEV10, cppu::UnoType<OUString>::get() , 0, 0},
+ { UNO_NAME_IS_RELATIVE_TABSTOPS, WID_IS_RELATIVE_TABSTOPS, cppu::UnoType<bool>::get(), PROPERTY_NONE, 0},
+ { UNO_NAME_DOCUMENT_INDEX_MARKS, WID_INDEX_MARKS, cppu::UnoType< cppu::UnoSequenceType<css::text::XDocumentIndexMark> >::get(), PropertyAttribute::READONLY ,0 },
+ };
+ m_aMapEntriesArr[nPropertyId] = aTOXContentMap_Impl;
+ }
+ break;
+ case PROPERTY_MAP_INDEX_USER:
+ {
+ static SfxItemPropertyMapEntry const aTOXUserMap_Impl[] =
+ {
+ BASE_INDEX_PROPERTIES_
+ { UNO_NAME_CREATE_FROM_MARKS, WID_CREATE_FROM_MARKS , cppu::UnoType<bool>::get() , PROPERTY_NONE, 0},
+ { UNO_NAME_HIDE_TAB_LEADER_AND_PAGE_NUMBERS, WID_HIDE_TABLEADER_PAGENUMBERS , cppu::UnoType<bool>::get() , PROPERTY_NONE, 0},
+ { UNO_NAME_TAB_IN_TOC, WID_TAB_IN_TOC, cppu::UnoType<bool>::get(), PROPERTY_NONE, 0},
+ { UNO_NAME_TOC_BOOKMARK, WID_TOC_BOOKMARK, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ { UNO_NAME_TOC_NEWLINE, WID_TOC_NEWLINE, cppu::UnoType<bool>::get(), PROPERTY_NONE, 0},
+ { UNO_NAME_TOC_PARAGRAPH_OUTLINE_LEVEL, WID_TOC_PARAGRAPH_OUTLINE_LEVEL, cppu::UnoType<bool>::get(), PROPERTY_NONE, 0},
+ { UNO_NAME_CREATE_FROM_CHAPTER, WID_CREATE_FROM_CHAPTER , cppu::UnoType<bool>::get() , PROPERTY_NONE, 0},
+ { UNO_NAME_IS_PROTECTED, WID_PROTECTED , cppu::UnoType<bool>::get() , PROPERTY_NONE, 0},
+ { UNO_NAME_USE_LEVEL_FROM_SOURCE, WID_USE_LEVEL_FROM_SOURCE , cppu::UnoType<bool>::get() , PROPERTY_NONE, 0},
+ { UNO_NAME_LEVEL_FORMAT, WID_LEVEL_FORMAT , cppu::UnoType<css::container::XIndexReplace>::get() , PROPERTY_NONE,0},
+ { UNO_NAME_LEVEL_PARAGRAPH_STYLES, WID_LEVEL_PARAGRAPH_STYLES , cppu::UnoType<css::container::XIndexReplace>::get() , PropertyAttribute::READONLY,0},
+ { UNO_NAME_CREATE_FROM_LEVEL_PARAGRAPH_STYLES, WID_CREATE_FROM_PARAGRAPH_STYLES, cppu::UnoType<bool>::get(), PROPERTY_NONE, 0},
+ { UNO_NAME_CREATE_FROM_TABLES, WID_CREATE_FROM_TABLES , cppu::UnoType<bool>::get() , PROPERTY_NONE, 0},
+ { UNO_NAME_CREATE_FROM_TEXT_FRAMES, WID_CREATE_FROM_TEXT_FRAMES , cppu::UnoType<bool>::get() , PROPERTY_NONE, 0},
+ { UNO_NAME_CREATE_FROM_GRAPHIC_OBJECTS, WID_CREATE_FROM_GRAPHIC_OBJECTS , cppu::UnoType<bool>::get() , PROPERTY_NONE, 0},
+ { UNO_NAME_CREATE_FROM_EMBEDDED_OBJECTS, WID_CREATE_FROM_EMBEDDED_OBJECTS , cppu::UnoType<bool>::get() , PROPERTY_NONE, 0},
+ { UNO_NAME_TEXT_COLUMNS, RES_COL, cppu::UnoType<css::text::XTextColumns>::get(), PROPERTY_NONE, MID_COLUMNS},
+ { UNO_NAME_BACK_GRAPHIC_URL, RES_BACKGROUND, cppu::UnoType<OUString>::get(), PROPERTY_NONE ,MID_GRAPHIC_URL },
+ { UNO_NAME_BACK_GRAPHIC, RES_BACKGROUND, cppu::UnoType<graphic::XGraphic>::get(), PROPERTY_NONE, MID_GRAPHIC },
+ { UNO_NAME_BACK_GRAPHIC_FILTER, RES_BACKGROUND, cppu::UnoType<OUString>::get(), PROPERTY_NONE ,MID_GRAPHIC_FILTER },
+ { UNO_NAME_BACK_GRAPHIC_LOCATION, RES_BACKGROUND, cppu::UnoType<css::style::GraphicLocation>::get(), PROPERTY_NONE ,MID_GRAPHIC_POSITION},
+ { UNO_NAME_BACK_COLOR, RES_BACKGROUND, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE ,MID_BACK_COLOR },
+ { UNO_NAME_BACKGROUND_COMPLEX_COLOR, RES_BACKGROUND, cppu::UnoType<css::util::XComplexColor>::get(), PROPERTY_NONE ,MID_BACKGROUND_COMPLEX_COLOR },
+ { UNO_NAME_BACK_TRANSPARENT, RES_BACKGROUND, cppu::UnoType<bool>::get(), PROPERTY_NONE ,MID_GRAPHIC_TRANSPARENT },
+ { UNO_NAME_PARA_STYLEHEADING, WID_PARA_HEAD, cppu::UnoType<OUString>::get() , 0, 0},
+ { UNO_NAME_PARA_STYLELEVEL1, WID_PARA_LEV1, cppu::UnoType<OUString>::get() , 0, 0},
+ { UNO_NAME_PARA_STYLELEVEL2, WID_PARA_LEV2, cppu::UnoType<OUString>::get() , 0, 0},
+ { UNO_NAME_PARA_STYLELEVEL3, WID_PARA_LEV3, cppu::UnoType<OUString>::get() , 0, 0},
+ { UNO_NAME_PARA_STYLELEVEL4, WID_PARA_LEV4, cppu::UnoType<OUString>::get() , 0, 0},
+ { UNO_NAME_PARA_STYLELEVEL5, WID_PARA_LEV5, cppu::UnoType<OUString>::get() , 0, 0},
+ { UNO_NAME_PARA_STYLELEVEL6, WID_PARA_LEV6, cppu::UnoType<OUString>::get() , 0, 0},
+ { UNO_NAME_PARA_STYLELEVEL7, WID_PARA_LEV7, cppu::UnoType<OUString>::get() , 0, 0},
+ { UNO_NAME_PARA_STYLELEVEL8, WID_PARA_LEV8, cppu::UnoType<OUString>::get() , 0, 0},
+ { UNO_NAME_PARA_STYLELEVEL9, WID_PARA_LEV9, cppu::UnoType<OUString>::get() , 0, 0},
+ { UNO_NAME_PARA_STYLELEVEL10, WID_PARA_LEV10, cppu::UnoType<OUString>::get() , 0, 0},
+ { UNO_NAME_DOCUMENT_INDEX_MARKS, WID_INDEX_MARKS, cppu::UnoType< cppu::UnoSequenceType<css::text::XDocumentIndexMark> >::get(), PropertyAttribute::READONLY ,0 },
+ { UNO_NAME_IS_RELATIVE_TABSTOPS, WID_IS_RELATIVE_TABSTOPS, cppu::UnoType<bool>::get(), PROPERTY_NONE, 0},
+ { UNO_NAME_USER_INDEX_NAME, WID_USER_IDX_NAME, cppu::UnoType<OUString>::get() , PROPERTY_NONE, 0},
+ };
+ m_aMapEntriesArr[nPropertyId] = aTOXUserMap_Impl;
+ }
+ break;
+ case PROPERTY_MAP_INDEX_TABLES:
+ {
+ static SfxItemPropertyMapEntry const aTOXTablesMap_Impl[] =
+ {
+ BASE_INDEX_PROPERTIES_
+ { UNO_NAME_CREATE_FROM_CHAPTER, WID_CREATE_FROM_CHAPTER , cppu::UnoType<bool>::get() , PROPERTY_NONE, 0},
+ { UNO_NAME_CREATE_FROM_LABELS, WID_CREATE_FROM_LABELS , cppu::UnoType<bool>::get() , PROPERTY_NONE, 0},
+ { UNO_NAME_CREATE_FROM_PARAGRAPH_STYLE, WID_CREATE_FROM_PARAGRAPH_STYLE, cppu::UnoType<OUString>::get(), PropertyAttribute::MAYBEVOID, 0},
+ { UNO_NAME_IS_PROTECTED, WID_PROTECTED , cppu::UnoType<bool>::get() , PROPERTY_NONE, 0},
+ { UNO_NAME_LABEL_CATEGORY, WID_LABEL_CATEGORY , cppu::UnoType<OUString>::get() , PROPERTY_NONE, 0},
+ { UNO_NAME_LABEL_DISPLAY_TYPE, WID_LABEL_DISPLAY_TYPE , cppu::UnoType<sal_Int16>::get() , PROPERTY_NONE, 0},
+ { UNO_NAME_LEVEL_FORMAT, WID_LEVEL_FORMAT , cppu::UnoType<css::container::XIndexReplace>::get() , PROPERTY_NONE,0},
+ { UNO_NAME_TEXT_COLUMNS, RES_COL, cppu::UnoType<css::text::XTextColumns>::get(), PROPERTY_NONE, MID_COLUMNS},
+ { UNO_NAME_BACK_GRAPHIC_URL, RES_BACKGROUND, cppu::UnoType<OUString>::get(), PROPERTY_NONE ,MID_GRAPHIC_URL },
+ { UNO_NAME_BACK_GRAPHIC, RES_BACKGROUND, cppu::UnoType<graphic::XGraphic>::get(), PROPERTY_NONE, MID_GRAPHIC },
+ { UNO_NAME_BACK_GRAPHIC_FILTER, RES_BACKGROUND, cppu::UnoType<OUString>::get(), PROPERTY_NONE ,MID_GRAPHIC_FILTER },
+ { UNO_NAME_BACK_GRAPHIC_LOCATION, RES_BACKGROUND, cppu::UnoType<css::style::GraphicLocation>::get(), PROPERTY_NONE ,MID_GRAPHIC_POSITION},
+ { UNO_NAME_BACK_COLOR, RES_BACKGROUND, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE ,MID_BACK_COLOR },
+ { UNO_NAME_BACKGROUND_COMPLEX_COLOR, RES_BACKGROUND, cppu::UnoType<css::util::XComplexColor>::get(), PROPERTY_NONE, MID_BACKGROUND_COMPLEX_COLOR },
+ { UNO_NAME_BACK_TRANSPARENT, RES_BACKGROUND, cppu::UnoType<bool>::get(), PROPERTY_NONE ,MID_GRAPHIC_TRANSPARENT },
+ { UNO_NAME_PARA_STYLEHEADING, WID_PARA_HEAD, cppu::UnoType<OUString>::get() , 0, 0},
+ { UNO_NAME_PARA_STYLELEVEL1, WID_PARA_LEV1, cppu::UnoType<OUString>::get() , 0, 0},
+ { UNO_NAME_IS_RELATIVE_TABSTOPS, WID_IS_RELATIVE_TABSTOPS, cppu::UnoType<bool>::get(), PROPERTY_NONE, 0},
+ };
+ m_aMapEntriesArr[nPropertyId] = aTOXTablesMap_Impl;
+ }
+ break;
+ case PROPERTY_MAP_INDEX_OBJECTS:
+ {
+ static SfxItemPropertyMapEntry const aTOXObjectsMap_Impl[] =
+ {
+ BASE_INDEX_PROPERTIES_
+ { UNO_NAME_CREATE_FROM_CHAPTER, WID_CREATE_FROM_CHAPTER , cppu::UnoType<bool>::get() , PROPERTY_NONE, 0},
+ { UNO_NAME_IS_PROTECTED, WID_PROTECTED , cppu::UnoType<bool>::get() , PROPERTY_NONE, 0},
+ { UNO_NAME_USE_ALPHABETICAL_SEPARATORS, WID_USE_ALPHABETICAL_SEPARATORS , cppu::UnoType<bool>::get() , PROPERTY_NONE, 0},
+ { UNO_NAME_LEVEL_FORMAT, WID_LEVEL_FORMAT , cppu::UnoType<css::container::XIndexReplace>::get() , PROPERTY_NONE,0},
+ { UNO_NAME_CREATE_FROM_STAR_MATH, WID_CREATE_FROM_STAR_MATH , cppu::UnoType<bool>::get() , PROPERTY_NONE, 0},
+ { UNO_NAME_CREATE_FROM_STAR_CHART, WID_CREATE_FROM_STAR_CHART , cppu::UnoType<bool>::get() , PROPERTY_NONE, 0},
+ { UNO_NAME_CREATE_FROM_STAR_CALC, WID_CREATE_FROM_STAR_CALC , cppu::UnoType<bool>::get() , PROPERTY_NONE, 0},
+ { UNO_NAME_CREATE_FROM_STAR_DRAW, WID_CREATE_FROM_STAR_DRAW , cppu::UnoType<bool>::get() , PROPERTY_NONE, 0},
+ { UNO_NAME_CREATE_FROM_OTHER_EMBEDDED_OBJECTS, WID_CREATE_FROM_OTHER_EMBEDDED_OBJECTS , cppu::UnoType<bool>::get() , PROPERTY_NONE, 0},
+ { UNO_NAME_CREATE_FROM_PARAGRAPH_STYLE, WID_CREATE_FROM_PARAGRAPH_STYLE, cppu::UnoType<OUString>::get(), PropertyAttribute::MAYBEVOID, 0},
+ { UNO_NAME_TEXT_COLUMNS, RES_COL, cppu::UnoType<css::text::XTextColumns>::get(), PROPERTY_NONE, MID_COLUMNS},
+ { UNO_NAME_BACK_GRAPHIC_URL, RES_BACKGROUND, cppu::UnoType<OUString>::get(), PROPERTY_NONE ,MID_GRAPHIC_URL },
+ { UNO_NAME_BACK_GRAPHIC, RES_BACKGROUND, cppu::UnoType<graphic::XGraphic>::get(), PROPERTY_NONE, MID_GRAPHIC },
+ { UNO_NAME_BACK_GRAPHIC_FILTER, RES_BACKGROUND, cppu::UnoType<OUString>::get(), PROPERTY_NONE ,MID_GRAPHIC_FILTER },
+ { UNO_NAME_BACK_GRAPHIC_LOCATION, RES_BACKGROUND, cppu::UnoType<css::style::GraphicLocation>::get(), PROPERTY_NONE ,MID_GRAPHIC_POSITION},
+ { UNO_NAME_BACK_COLOR, RES_BACKGROUND, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE ,MID_BACK_COLOR },
+ { UNO_NAME_BACKGROUND_COMPLEX_COLOR, RES_BACKGROUND, cppu::UnoType<css::util::XComplexColor>::get(), PROPERTY_NONE, MID_BACKGROUND_COMPLEX_COLOR },
+ { UNO_NAME_BACK_TRANSPARENT, RES_BACKGROUND, cppu::UnoType<bool>::get(), PROPERTY_NONE ,MID_GRAPHIC_TRANSPARENT },
+ { UNO_NAME_PARA_STYLEHEADING, WID_PARA_HEAD, cppu::UnoType<OUString>::get() , 0, 0},
+ { UNO_NAME_PARA_STYLELEVEL1, WID_PARA_LEV1, cppu::UnoType<OUString>::get() , 0, 0},
+ { UNO_NAME_IS_RELATIVE_TABSTOPS, WID_IS_RELATIVE_TABSTOPS, cppu::UnoType<bool>::get(), PROPERTY_NONE, 0},
+ };
+ m_aMapEntriesArr[nPropertyId] = aTOXObjectsMap_Impl;
+ }
+ break;
+ case PROPERTY_MAP_INDEX_ILLUSTRATIONS:
+ {
+ static SfxItemPropertyMapEntry const aTOXIllustrationsMap_Impl[] =
+ {
+ BASE_INDEX_PROPERTIES_
+ { UNO_NAME_CREATE_FROM_CHAPTER, WID_CREATE_FROM_CHAPTER , cppu::UnoType<bool>::get() , PROPERTY_NONE, 0},
+ { UNO_NAME_CREATE_FROM_LABELS, WID_CREATE_FROM_LABELS , cppu::UnoType<bool>::get() , PROPERTY_NONE, 0},
+ { UNO_NAME_CREATE_FROM_PARAGRAPH_STYLE, WID_CREATE_FROM_PARAGRAPH_STYLE, cppu::UnoType<OUString>::get(), PropertyAttribute::MAYBEVOID, 0},
+ { UNO_NAME_IS_PROTECTED, WID_PROTECTED , cppu::UnoType<bool>::get() , PROPERTY_NONE, 0},
+ { UNO_NAME_USE_ALPHABETICAL_SEPARATORS, WID_USE_ALPHABETICAL_SEPARATORS , cppu::UnoType<bool>::get() , PROPERTY_NONE, 0},
+ { UNO_NAME_LABEL_CATEGORY, WID_LABEL_CATEGORY , cppu::UnoType<OUString>::get() , PROPERTY_NONE, 0},
+ { UNO_NAME_LABEL_DISPLAY_TYPE, WID_LABEL_DISPLAY_TYPE , cppu::UnoType<sal_Int16>::get() , PROPERTY_NONE, 0},
+ { UNO_NAME_LEVEL_FORMAT, WID_LEVEL_FORMAT , cppu::UnoType<css::container::XIndexReplace>::get() , PROPERTY_NONE,0},
+ { UNO_NAME_TEXT_COLUMNS, RES_COL, cppu::UnoType<css::text::XTextColumns>::get(), PROPERTY_NONE, MID_COLUMNS},
+ { UNO_NAME_BACK_GRAPHIC_URL, RES_BACKGROUND, cppu::UnoType<OUString>::get(), PROPERTY_NONE ,MID_GRAPHIC_URL },
+ { UNO_NAME_BACK_GRAPHIC, RES_BACKGROUND, cppu::UnoType<graphic::XGraphic>::get(), PROPERTY_NONE, MID_GRAPHIC },
+ { UNO_NAME_BACK_GRAPHIC_FILTER, RES_BACKGROUND, cppu::UnoType<OUString>::get(), PROPERTY_NONE ,MID_GRAPHIC_FILTER },
+ { UNO_NAME_BACK_GRAPHIC_LOCATION, RES_BACKGROUND, cppu::UnoType<css::style::GraphicLocation>::get(), PROPERTY_NONE ,MID_GRAPHIC_POSITION},
+ { UNO_NAME_BACK_COLOR, RES_BACKGROUND, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE ,MID_BACK_COLOR },
+ { UNO_NAME_BACKGROUND_COMPLEX_COLOR, RES_BACKGROUND, cppu::UnoType<css::util::XComplexColor>::get(), PROPERTY_NONE, MID_BACKGROUND_COMPLEX_COLOR },
+ { UNO_NAME_BACK_TRANSPARENT, RES_BACKGROUND, cppu::UnoType<bool>::get(), PROPERTY_NONE ,MID_GRAPHIC_TRANSPARENT },
+ { UNO_NAME_PARA_STYLEHEADING, WID_PARA_HEAD, cppu::UnoType<OUString>::get() , 0, 0},
+ { UNO_NAME_PARA_STYLELEVEL1, WID_PARA_LEV1, cppu::UnoType<OUString>::get() , 0, 0},
+ { UNO_NAME_IS_RELATIVE_TABSTOPS, WID_IS_RELATIVE_TABSTOPS, cppu::UnoType<bool>::get(), PROPERTY_NONE, 0},
+ };
+ m_aMapEntriesArr[nPropertyId] = aTOXIllustrationsMap_Impl;
+ }
+ break;
+ case PROPERTY_MAP_TEXT_TABLE_ROW:
+ {
+ static SfxItemPropertyMapEntry const aTableRowPropertyMap_Impl[] =
+ {
+ { UNO_NAME_BACK_COLOR, RES_BACKGROUND, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE ,MID_BACK_COLOR },
+ { UNO_NAME_BACKGROUND_COMPLEX_COLOR, RES_BACKGROUND, cppu::UnoType<css::util::XComplexColor>::get(), PROPERTY_NONE, MID_BACKGROUND_COMPLEX_COLOR },
+ { UNO_NAME_BACK_GRAPHIC_URL, RES_BACKGROUND, cppu::UnoType<OUString>::get(), PROPERTY_NONE ,MID_GRAPHIC_URL },
+ { UNO_NAME_BACK_GRAPHIC, RES_BACKGROUND, cppu::UnoType<graphic::XGraphic>::get(), PROPERTY_NONE, MID_GRAPHIC },
+ { UNO_NAME_BACK_GRAPHIC_FILTER, RES_BACKGROUND, cppu::UnoType<OUString>::get(), PROPERTY_NONE ,MID_GRAPHIC_FILTER },
+ { UNO_NAME_BACK_GRAPHIC_LOCATION, RES_BACKGROUND, cppu::UnoType<css::style::GraphicLocation>::get(), PROPERTY_NONE ,MID_GRAPHIC_POSITION},
+ { UNO_NAME_BACK_TRANSPARENT, RES_BACKGROUND, cppu::UnoType<bool>::get(), PROPERTY_NONE ,MID_GRAPHIC_TRANSPARENT },
+ { UNO_NAME_TABLE_COLUMN_SEPARATORS, FN_UNO_TABLE_COLUMN_SEPARATORS, cppu::UnoType< cppu::UnoSequenceType<css::text::TableColumnSeparator> >::get(), PropertyAttribute::MAYBEVOID, 0 },
+ { UNO_NAME_HEIGHT, FN_UNO_ROW_HEIGHT, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE ,CONVERT_TWIPS },
+ { UNO_NAME_IS_AUTO_HEIGHT, FN_UNO_ROW_AUTO_HEIGHT, cppu::UnoType<bool>::get(), PROPERTY_NONE , 0 },
+ { UNO_NAME_SIZE_TYPE, RES_FRM_SIZE, cppu::UnoType<sal_Int16>::get() , PROPERTY_NONE, MID_FRMSIZE_SIZE_TYPE },
+ { UNO_NAME_WIDTH_TYPE, RES_FRM_SIZE, cppu::UnoType<sal_Int16>::get() , PROPERTY_NONE, MID_FRMSIZE_WIDTH_TYPE },
+ { UNO_NAME_IS_SPLIT_ALLOWED, RES_ROW_SPLIT, cppu::UnoType<bool>::get() , PropertyAttribute::MAYBEVOID, 0},
+ { UNO_NAME_HAS_TEXT_CHANGES_ONLY, RES_PRINT, cppu::UnoType<bool>::get() , PropertyAttribute::MAYBEVOID, 0},
+ { UNO_NAME_ROW_INTEROP_GRAB_BAG, RES_FRMATR_GRABBAG, cppu::UnoType< cppu::UnoSequenceType<css::beans::PropertyValue> >::get(), PROPERTY_NONE, 0 },
+ };
+
+ m_aMapEntriesArr[nPropertyId] = aTableRowPropertyMap_Impl;
+ }
+ break;
+ case PROPERTY_MAP_TEXT_TABLE_CURSOR:
+ {
+ m_aMapEntriesArr[nPropertyId] = GetTextTableCursorPropertyMap();
+ }
+ break;
+ case PROPERTY_MAP_BOOKMARK:
+ {
+ 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"_ustr, 0, cppu::UnoType<bool>::get(), PROPERTY_NONE, 0},
+ };
+ m_aMapEntriesArr[nPropertyId] = aFieldmarkMap_Impl;
+ }
+ break;
+ case PROPERTY_MAP_PARAGRAPH_EXTENSIONS:
+ {
+ m_aMapEntriesArr[nPropertyId] = GetParagraphExtensionsPropertyMap();
+ }
+ break;
+ case PROPERTY_MAP_BIBLIOGRAPHY :
+ {
+ static SfxItemPropertyMapEntry const aBibliographyMap_Impl[] =
+ {
+ BASE_INDEX_PROPERTIES_
+ { UNO_NAME_IS_PROTECTED, WID_PROTECTED , cppu::UnoType<bool>::get() , PROPERTY_NONE, 0},
+ { UNO_NAME_TEXT_COLUMNS, RES_COL, cppu::UnoType<css::text::XTextColumns>::get(), PROPERTY_NONE, MID_COLUMNS},
+ { UNO_NAME_BACK_GRAPHIC_URL, RES_BACKGROUND, cppu::UnoType<OUString>::get(), PROPERTY_NONE ,MID_GRAPHIC_URL },
+ { UNO_NAME_BACK_GRAPHIC, RES_BACKGROUND, cppu::UnoType<graphic::XGraphic>::get(), PROPERTY_NONE, MID_GRAPHIC },
+ { UNO_NAME_BACK_GRAPHIC_FILTER, RES_BACKGROUND, cppu::UnoType<OUString>::get(), PROPERTY_NONE ,MID_GRAPHIC_FILTER },
+ { UNO_NAME_BACK_GRAPHIC_LOCATION, RES_BACKGROUND, cppu::UnoType<css::style::GraphicLocation>::get(), PROPERTY_NONE ,MID_GRAPHIC_POSITION},
+ { UNO_NAME_BACK_COLOR, RES_BACKGROUND, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE ,MID_BACK_COLOR },
+ { UNO_NAME_BACKGROUND_COMPLEX_COLOR, RES_BACKGROUND, cppu::UnoType<css::util::XComplexColor>::get(), PROPERTY_NONE, MID_BACKGROUND_COMPLEX_COLOR },
+ { UNO_NAME_BACK_TRANSPARENT, RES_BACKGROUND, cppu::UnoType<bool>::get(), PROPERTY_NONE ,MID_GRAPHIC_TRANSPARENT },
+ { UNO_NAME_PARA_STYLEHEADING, WID_PARA_HEAD, cppu::UnoType<OUString>::get() , 0, 0},
+ { UNO_NAME_PARA_STYLELEVEL1, WID_PARA_LEV1, cppu::UnoType<OUString>::get() , 0, 0},
+ { UNO_NAME_LEVEL_FORMAT, WID_LEVEL_FORMAT , cppu::UnoType<css::container::XIndexReplace>::get() , PROPERTY_NONE,0},
+ { UNO_NAME_LOCALE, WID_IDX_LOCALE, cppu::UnoType<css::lang::Locale>::get(), PROPERTY_NONE, 0},
+ { UNO_NAME_SORT_ALGORITHM, WID_IDX_SORT_ALGORITHM, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ };
+ m_aMapEntriesArr[nPropertyId] = aBibliographyMap_Impl;
+ }
+ break;
+ case PROPERTY_MAP_TEXT_DOCUMENT:
+ {
+ static SfxItemPropertyMapEntry const aDocMap_Impl[] =
+ {
+ { UNO_NAME_BASIC_LIBRARIES, WID_DOC_BASIC_LIBRARIES, cppu::UnoType<css::script::XLibraryContainer>::get(), PropertyAttribute::READONLY, 0},
+ { UNO_NAME_CHAR_FONT_NAME, RES_CHRATR_FONT, cppu::UnoType<OUString>::get(), PropertyAttribute::MAYBEVOID, MID_FONT_FAMILY_NAME },
+ { UNO_NAME_CHAR_FONT_STYLE_NAME, RES_CHRATR_FONT, cppu::UnoType<OUString>::get(), PropertyAttribute::MAYBEVOID, MID_FONT_STYLE_NAME },
+ { UNO_NAME_CHAR_FONT_FAMILY, RES_CHRATR_FONT, cppu::UnoType<sal_Int16>::get(), PropertyAttribute::MAYBEVOID, MID_FONT_FAMILY },
+ { UNO_NAME_CHAR_FONT_CHAR_SET, RES_CHRATR_FONT, cppu::UnoType<sal_Int16>::get(), PropertyAttribute::MAYBEVOID, MID_FONT_CHAR_SET },
+ { UNO_NAME_CHAR_FONT_PITCH, RES_CHRATR_FONT, cppu::UnoType<sal_Int16>::get(), PropertyAttribute::MAYBEVOID, MID_FONT_PITCH },
+ { UNO_NAME_CHAR_FONT_NAME_ASIAN, RES_CHRATR_CJK_FONT, cppu::UnoType<OUString>::get(), PropertyAttribute::MAYBEVOID, MID_FONT_FAMILY_NAME },
+ { UNO_NAME_CHAR_FONT_STYLE_NAME_ASIAN, RES_CHRATR_CJK_FONT, cppu::UnoType<OUString>::get(), PropertyAttribute::MAYBEVOID, MID_FONT_STYLE_NAME },
+ { UNO_NAME_CHAR_FONT_FAMILY_ASIAN, RES_CHRATR_CJK_FONT, cppu::UnoType<sal_Int16>::get(), PropertyAttribute::MAYBEVOID, MID_FONT_FAMILY },
+ { UNO_NAME_CHAR_FONT_CHAR_SET_ASIAN, RES_CHRATR_CJK_FONT, cppu::UnoType<sal_Int16>::get(), PropertyAttribute::MAYBEVOID, MID_FONT_CHAR_SET },
+ { UNO_NAME_CHAR_FONT_PITCH_ASIAN, RES_CHRATR_CJK_FONT, cppu::UnoType<sal_Int16>::get(), PropertyAttribute::MAYBEVOID, MID_FONT_PITCH },
+ { UNO_NAME_CHAR_FONT_NAME_COMPLEX, RES_CHRATR_CTL_FONT, cppu::UnoType<OUString>::get(), PropertyAttribute::MAYBEVOID, MID_FONT_FAMILY_NAME },
+ { UNO_NAME_CHAR_FONT_STYLE_NAME_COMPLEX, RES_CHRATR_CTL_FONT, cppu::UnoType<OUString>::get(), PropertyAttribute::MAYBEVOID, MID_FONT_STYLE_NAME },
+ { UNO_NAME_CHAR_FONT_FAMILY_COMPLEX, RES_CHRATR_CTL_FONT, cppu::UnoType<sal_Int16>::get(), PropertyAttribute::MAYBEVOID, MID_FONT_FAMILY },
+ { UNO_NAME_CHAR_FONT_CHAR_SET_COMPLEX, RES_CHRATR_CTL_FONT, cppu::UnoType<sal_Int16>::get(), PropertyAttribute::MAYBEVOID, MID_FONT_CHAR_SET },
+ { UNO_NAME_CHAR_FONT_PITCH_COMPLEX, RES_CHRATR_CTL_FONT, cppu::UnoType<sal_Int16>::get(), PropertyAttribute::MAYBEVOID, MID_FONT_PITCH },
+ { UNO_NAME_CHAR_LOCALE, RES_CHRATR_LANGUAGE , cppu::UnoType<css::lang::Locale>::get(), PropertyAttribute::MAYBEVOID, MID_LANG_LOCALE },
+ { UNO_NAME_CHARACTER_COUNT, WID_DOC_CHAR_COUNT, cppu::UnoType<sal_Int32>::get(), PropertyAttribute::READONLY, 0},
+ { UNO_NAME_DIALOG_LIBRARIES, WID_DOC_DIALOG_LIBRARIES, cppu::UnoType<css::script::XLibraryContainer>::get(), PropertyAttribute::READONLY, 0},
+ { UNO_NAME_VBA_DOCOBJ, WID_DOC_VBA_DOCOBJ, cppu::UnoType<OUString>::get(), PropertyAttribute::READONLY, 0},
+ { UNO_NAME_INDEX_AUTO_MARK_FILE_U_R_L, WID_DOC_AUTO_MARK_URL, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ { UNO_NAME_PARAGRAPH_COUNT, WID_DOC_PARA_COUNT, cppu::UnoType<sal_Int32>::get(), PropertyAttribute::READONLY, 0},
+ { UNO_NAME_RECORD_CHANGES, WID_DOC_CHANGES_RECORD, cppu::UnoType<bool>::get(), PROPERTY_NONE, 0},
+ { UNO_NAME_SHOW_CHANGES, WID_DOC_CHANGES_SHOW, cppu::UnoType<bool>::get(), PROPERTY_NONE, 0},
+ { UNO_NAME_WORD_COUNT, WID_DOC_WORD_COUNT, cppu::UnoType<sal_Int32>::get(), PropertyAttribute::READONLY, 0},
+ { UNO_NAME_IS_TEMPLATE, WID_DOC_ISTEMPLATEID, cppu::UnoType<bool>::get(), PropertyAttribute::READONLY, 0},
+ { UNO_NAME_WORD_SEPARATOR, WID_DOC_WORD_SEPARATOR, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ { UNO_NAME_HIDE_FIELD_TIPS, WID_DOC_HIDE_TIPS, cppu::UnoType<bool>::get(), PROPERTY_NONE, 0},
+ { UNO_NAME_REDLINE_DISPLAY_TYPE, WID_DOC_REDLINE_DISPLAY, cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE, 0},
+ { UNO_NAME_REDLINE_PROTECTION_KEY, WID_DOC_CHANGES_PASSWORD, cppu::UnoType< cppu::UnoSequenceType<sal_Int8> >::get(), PROPERTY_NONE, 0 },
+ { UNO_NAME_FORBIDDEN_CHARACTERS, WID_DOC_FORBIDDEN_CHARS, cppu::UnoType<css::i18n::XForbiddenCharacters>::get(), PROPERTY_NONE, 0},
+ { UNO_NAME_TWO_DIGIT_YEAR, WID_DOC_TWO_DIGIT_YEAR, cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE, 0},
+ { UNO_NAME_AUTOMATIC_CONTROL_FOCUS, WID_DOC_AUTOMATIC_CONTROL_FOCUS, cppu::UnoType<bool>::get(), PROPERTY_NONE, 0},
+ { UNO_NAME_APPLY_FORM_DESIGN_MODE, WID_DOC_APPLY_FORM_DESIGN_MODE, cppu::UnoType<bool>::get(), PROPERTY_NONE, 0},
+ { UNO_NAME_RUNTIME_UID, WID_DOC_RUNTIME_UID, cppu::UnoType<OUString>::get(), PropertyAttribute::READONLY, 0},
+ { UNO_NAME_LOCK_UPDATES, WID_DOC_LOCK_UPDATES, cppu::UnoType<bool>::get(), PROPERTY_NONE, 0},
+ { u"UndocumentedWriterfilterHack"_ustr, WID_DOC_WRITERFILTER, cppu::UnoType<bool>::get(), PROPERTY_NONE, 0},
+ { UNO_NAME_HAS_VALID_SIGNATURES, WID_DOC_HAS_VALID_SIGNATURES, cppu::UnoType<bool>::get(), PropertyAttribute::READONLY, 0},
+ { UNO_NAME_BUILDID, WID_DOC_BUILDID, cppu::UnoType<OUString>::get(), 0, 0},
+ { UNO_NAME_DOC_INTEROP_GRAB_BAG, WID_DOC_INTEROP_GRAB_BAG, cppu::UnoType< cppu::UnoSequenceType<css::beans::PropertyValue> >::get(), PROPERTY_NONE, 0 },
+ { UNO_NAME_DEFAULT_PAGE_MODE, WID_DOC_DEFAULT_PAGE_MODE, cppu::UnoType<bool>::get(), PROPERTY_NONE, 0},
+ };
+ m_aMapEntriesArr[nPropertyId] = aDocMap_Impl;
+ }
+ break;
+ case PROPERTY_MAP_LINK_TARGET:
+ {
+ static SfxItemPropertyMapEntry const aLinkTargetMap_Impl[] =
+ {
+ { UNO_LINK_DISPLAY_BITMAP, 0, cppu::UnoType<css::awt::XBitmap>::get(), PropertyAttribute::READONLY, 0xbf},
+ { UNO_LINK_DISPLAY_NAME, 0, cppu::UnoType<OUString>::get(), PropertyAttribute::READONLY, 0xbf},
+ };
+ m_aMapEntriesArr[nPropertyId] = aLinkTargetMap_Impl;
+ }
+ break;
+ case PROPERTY_MAP_AUTO_TEXT_GROUP :
+ {
+ static SfxItemPropertyMapEntry const aAutoTextGroupMap_Impl[] =
+ {
+ { UNO_NAME_FILE_PATH, WID_GROUP_PATH, cppu::UnoType<OUString>::get(), PropertyAttribute::READONLY, 0},
+ { UNO_NAME_TITLE, WID_GROUP_TITLE, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ };
+ m_aMapEntriesArr[nPropertyId] = aAutoTextGroupMap_Impl;
+ }
+ break;
+ case PROPERTY_MAP_TEXTPORTION_EXTENSIONS:
+ {
+ m_aMapEntriesArr[nPropertyId] = GetTextPortionExtensionPropertyMap();
+ }
+ break;
+ case PROPERTY_MAP_FOOTNOTE:
+ {
+ m_aMapEntriesArr[nPropertyId] = GetFootnotePropertyMap();
+ }
+ break;
+ case PROPERTY_MAP_REDLINE :
+ {
+ m_aMapEntriesArr[nPropertyId] = GetRedlinePropertyMap();
+ }
+ break;
+ case PROPERTY_MAP_TEXT_DEFAULT :
+ {
+ std::span<SfxItemPropertyMapEntry> aTextDefaultMap_Impl = GetTextDefaultPropertyMap();
+ m_aMapEntriesArr[nPropertyId] = aTextDefaultMap_Impl;
+ for( auto & rEntry : aTextDefaultMap_Impl )
+ {
+ // UNO_NAME_PAGE_DESC_NAME should keep its MAYBEVOID flag
+ if (RES_PAGEDESC != rEntry.nWID || MID_PAGEDESC_PAGEDESCNAME != rEntry.nMemberId)
+ rEntry.nFlags &= ~PropertyAttribute::MAYBEVOID;
+ }
+ }
+ break;
+ case PROPERTY_MAP_REDLINE_PORTION :
+ {
+ m_aMapEntriesArr[nPropertyId] = GetRedlinePortionPropertyMap();
+ }
+ break;
+ case PROPERTY_MAP_FLDTYP_DATETIME:
+ {
+ static SfxItemPropertyMapEntry const aDateTimeFieldPropMap[] =
+ {
+ {UNO_NAME_ADJUST, FIELD_PROP_SUBTYPE, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE, 0},
+ {UNO_NAME_DATE_TIME_VALUE, FIELD_PROP_DATE_TIME, cppu::UnoType<css::util::DateTime>::get(), PROPERTY_NONE, 0},
+ {UNO_NAME_IS_FIXED, FIELD_PROP_BOOL1, cppu::UnoType<bool>::get() , PROPERTY_NONE,0},
+ {UNO_NAME_IS_DATE, FIELD_PROP_BOOL2, cppu::UnoType<bool>::get() , PROPERTY_NONE,0},
+ {UNO_NAME_NUMBER_FORMAT, FIELD_PROP_FORMAT, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE, 0},
+ {UNO_NAME_IS_FIXED_LANGUAGE, FIELD_PROP_BOOL4, cppu::UnoType<bool>::get(), PROPERTY_NONE, 0},
+ COMMON_FLDTYP_PROPERTIES
+ };
+ m_aMapEntriesArr[nPropertyId] = aDateTimeFieldPropMap;
+ }
+ break;
+ case PROPERTY_MAP_FLDTYP_USER :
+ {
+ static SfxItemPropertyMapEntry const aUserFieldPropMap[] =
+ {
+ {UNO_NAME_IS_SHOW_FORMULA, FIELD_PROP_BOOL2, cppu::UnoType<bool>::get(), PROPERTY_NONE, 0},
+ {UNO_NAME_IS_VISIBLE, FIELD_PROP_BOOL1, cppu::UnoType<bool>::get(), PROPERTY_NONE, 0},
+ {UNO_NAME_NUMBER_FORMAT, FIELD_PROP_FORMAT, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE, 0},
+ {UNO_NAME_IS_FIXED_LANGUAGE, FIELD_PROP_BOOL4, cppu::UnoType<bool>::get(), PROPERTY_NONE, 0},
+ COMMON_FLDTYP_PROPERTIES
+ };
+
+ m_aMapEntriesArr[nPropertyId] = aUserFieldPropMap;
+ }
+ break;
+ case PROPERTY_MAP_FLDTYP_SET_EXP :
+ {
+ static SfxItemPropertyMapEntry const aSetExpFieldPropMap [] =
+ {
+ {UNO_NAME_CONTENT, FIELD_PROP_PAR2, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ {UNO_NAME_CURRENT_PRESENTATION, FIELD_PROP_PAR4, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ {UNO_NAME_HINT, FIELD_PROP_PAR3, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ {UNO_NAME_NUMBER_FORMAT, FIELD_PROP_FORMAT, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE, 0},
+ {UNO_NAME_NUMBERING_TYPE, FIELD_PROP_USHORT2, cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE, 0},
+ {UNO_NAME_IS_INPUT, FIELD_PROP_BOOL1, cppu::UnoType<bool>::get(), PROPERTY_NONE, 0},
+ // #i69733# wrong name - UNO_NAME_IS_INPUT expanded to "Input" instead of "IsInput"
+ {UNO_NAME_INPUT, FIELD_PROP_BOOL1, cppu::UnoType<bool>::get(), PROPERTY_NONE, 0},
+ {UNO_NAME_IS_SHOW_FORMULA, FIELD_PROP_BOOL3, cppu::UnoType<bool>::get(), PROPERTY_NONE, 0},
+ {UNO_NAME_IS_VISIBLE, FIELD_PROP_BOOL2, cppu::UnoType<bool>::get(), PROPERTY_NONE, 0},
+ {UNO_NAME_SEQUENCE_VALUE, FIELD_PROP_USHORT1, cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE, 0},
+ {UNO_NAME_SUB_TYPE, FIELD_PROP_SUBTYPE, cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE, 0},
+ {UNO_NAME_VALUE, FIELD_PROP_DOUBLE, cppu::UnoType<double>::get(), PROPERTY_NONE, 0},
+ {UNO_NAME_VARIABLE_NAME, FIELD_PROP_PAR1, cppu::UnoType<OUString>::get(), PropertyAttribute::READONLY, 0},
+ {UNO_NAME_IS_FIXED_LANGUAGE, FIELD_PROP_BOOL4, cppu::UnoType<bool>::get(), PROPERTY_NONE, 0},
+ COMMON_FLDTYP_PROPERTIES
+ };
+ m_aMapEntriesArr[nPropertyId] = aSetExpFieldPropMap;
+ }
+ break;
+ case PROPERTY_MAP_FLDTYP_GET_EXP :
+ {
+ static SfxItemPropertyMapEntry const aGetExpFieldPropMap [] =
+ {
+ {UNO_NAME_CONTENT, FIELD_PROP_PAR1, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ {UNO_NAME_CURRENT_PRESENTATION, FIELD_PROP_PAR4, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ {UNO_NAME_IS_SHOW_FORMULA, FIELD_PROP_BOOL2, cppu::UnoType<bool>::get(), PROPERTY_NONE, 0},
+ {UNO_NAME_NUMBER_FORMAT, FIELD_PROP_FORMAT, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE, 0},
+ {UNO_NAME_SUB_TYPE, FIELD_PROP_SUBTYPE, cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE, 0},
+ {UNO_NAME_VALUE, FIELD_PROP_DOUBLE, cppu::UnoType<double>::get(), PropertyAttribute::READONLY, 0},
+ {UNO_NAME_VARIABLE_SUBTYPE, FIELD_PROP_USHORT1, cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE, 0},
+ {UNO_NAME_IS_FIXED_LANGUAGE, FIELD_PROP_BOOL4, cppu::UnoType<bool>::get(), PROPERTY_NONE, 0},
+ COMMON_FLDTYP_PROPERTIES
+ };
+ m_aMapEntriesArr[nPropertyId] = aGetExpFieldPropMap;
+ }
+ break;
+ case PROPERTY_MAP_FLDTYP_FILE_NAME:
+ {
+ static SfxItemPropertyMapEntry const aFileNameFieldPropMap [] =
+ {
+ {UNO_NAME_CURRENT_PRESENTATION, FIELD_PROP_PAR3, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ {UNO_NAME_FILE_FORMAT, FIELD_PROP_FORMAT, cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE, 0},
+ {UNO_NAME_IS_FIXED, FIELD_PROP_BOOL2, cppu::UnoType<bool>::get(), PROPERTY_NONE, 0},
+ COMMON_FLDTYP_PROPERTIES
+ };
+ m_aMapEntriesArr[nPropertyId] = aFileNameFieldPropMap;
+ }
+ break;
+ case PROPERTY_MAP_FLDTYP_PAGE_NUM :
+ {
+ static SfxItemPropertyMapEntry const aPageNumFieldPropMap [] =
+ {
+ {UNO_NAME_NUMBERING_TYPE, FIELD_PROP_FORMAT, cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE, 0},
+ {UNO_NAME_OFFSET, FIELD_PROP_USHORT1, cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE, 0},
+ {UNO_NAME_SUB_TYPE, FIELD_PROP_SUBTYPE, cppu::UnoType<css::text::PageNumberType>::get(), PROPERTY_NONE, 0},
+ {UNO_NAME_USERTEXT, FIELD_PROP_PAR1, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ COMMON_FLDTYP_PROPERTIES
+ };
+ m_aMapEntriesArr[nPropertyId] = aPageNumFieldPropMap;
+ }
+ break;
+ case PROPERTY_MAP_FLDTYP_AUTHOR :
+ {
+ static SfxItemPropertyMapEntry const aAuthorFieldPropMap [] =
+ {
+ {UNO_NAME_CONTENT, FIELD_PROP_PAR1, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ {UNO_NAME_CURRENT_PRESENTATION, FIELD_PROP_PAR1, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ {UNO_NAME_IS_FIXED, FIELD_PROP_BOOL2, cppu::UnoType<bool>::get(), PROPERTY_NONE, 0},
+ {UNO_NAME_FULL_NAME,FIELD_PROP_BOOL1, cppu::UnoType<bool>::get(), PROPERTY_NONE, 0},
+ COMMON_FLDTYP_PROPERTIES
+ };
+ m_aMapEntriesArr[nPropertyId] = aAuthorFieldPropMap;
+ }
+ break;
+ case PROPERTY_MAP_FLDTYP_CHAPTER :
+ {
+ static SfxItemPropertyMapEntry const aChapterFieldPropMap [] =
+ {
+ {UNO_NAME_CHAPTER_FORMAT,FIELD_PROP_USHORT1, cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE, 0},
+ {UNO_NAME_LEVEL,FIELD_PROP_BYTE1, cppu::UnoType<sal_Int8>::get(), PROPERTY_NONE, 0},
+ COMMON_FLDTYP_PROPERTIES
+ };
+ m_aMapEntriesArr[nPropertyId] = aChapterFieldPropMap;
+ }
+ break;
+ case PROPERTY_MAP_FLDTYP_GET_REFERENCE :
+ {
+ static SfxItemPropertyMapEntry const aGetRefFieldPropMap [] =
+ {
+ {UNO_NAME_CURRENT_PRESENTATION, FIELD_PROP_PAR3, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ {UNO_NAME_REFERENCE_FIELD_PART,FIELD_PROP_USHORT1, cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE, 0},
+ {UNO_NAME_REFERENCE_FIELD_SOURCE,FIELD_PROP_USHORT2, cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE, 0},
+ {UNO_NAME_REFERENCE_FIELD_FLAGS, FIELD_PROP_USHORT3, cppu::UnoType<sal_uInt16>::get(), PROPERTY_NONE, 0},
+ {UNO_NAME_SEQUENCE_NUMBER, FIELD_PROP_SHORT1, cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE, 0},
+ {UNO_NAME_SOURCE_NAME, FIELD_PROP_PAR1, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ {UNO_NAME_REFERENCE_FIELD_LANGUAGE, FIELD_PROP_PAR4, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ COMMON_FLDTYP_PROPERTIES
+ };
+ m_aMapEntriesArr[nPropertyId] = aGetRefFieldPropMap;
+ }
+ break;
+ case PROPERTY_MAP_FLDTYP_CONDITIONED_TEXT :
+ {
+ static SfxItemPropertyMapEntry const aConditionedTextFieldPropMap [] =
+ {
+ {UNO_NAME_CONDITION, FIELD_PROP_PAR1, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ {UNO_NAME_FALSE_CONTENT, FIELD_PROP_PAR3, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ {UNO_NAME_IS_CONDITION_TRUE , FIELD_PROP_BOOL1, cppu::UnoType<bool>::get(), PROPERTY_NONE, 0},
+ {UNO_NAME_TRUE_CONTENT , FIELD_PROP_PAR2, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ {UNO_NAME_CURRENT_PRESENTATION, FIELD_PROP_PAR4, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ COMMON_FLDTYP_PROPERTIES
+ };
+ m_aMapEntriesArr[nPropertyId] = aConditionedTextFieldPropMap;
+ }
+ break;
+ case PROPERTY_MAP_FLDTYP_HIDDEN_TEXT :
+ {
+ static SfxItemPropertyMapEntry const aHiddenTextFieldPropMap [] =
+ {
+ {UNO_NAME_CONDITION, FIELD_PROP_PAR1, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ {UNO_NAME_CONTENT , FIELD_PROP_PAR2, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ {UNO_NAME_IS_HIDDEN , FIELD_PROP_BOOL1, cppu::UnoType<bool>::get(), PROPERTY_NONE, 0},
+ {UNO_NAME_CURRENT_PRESENTATION, FIELD_PROP_PAR4, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ COMMON_FLDTYP_PROPERTIES
+ };
+ m_aMapEntriesArr[nPropertyId] = aHiddenTextFieldPropMap;
+ }
+ break;
+ case PROPERTY_MAP_FLDTYP_ANNOTATION :
+ {
+ static SfxItemPropertyMapEntry const aAnnotationFieldPropMap [] =
+ {
+ {UNO_NAME_AUTHOR, FIELD_PROP_PAR1, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ {UNO_NAME_CONTENT, FIELD_PROP_PAR2, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ {UNO_NAME_INITIALS, FIELD_PROP_PAR3, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ {UNO_NAME_NAME, FIELD_PROP_PAR4, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ {UNO_NAME_PARA_ID_PARENT, FIELD_PROP_PAR5, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ {UNO_NAME_PARA_ID, FIELD_PROP_PAR6, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ {UNO_NAME_PARENT_NAME, FIELD_PROP_PAR7, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ {UNO_NAME_RESOLVED, FIELD_PROP_BOOL1, cppu::UnoType<bool>::get(), PROPERTY_NONE, 0},
+ {UNO_NAME_DATE_TIME_VALUE, FIELD_PROP_DATE_TIME, cppu::UnoType<css::util::DateTime>::get(), PROPERTY_NONE, 0},
+ {UNO_NAME_DATE, FIELD_PROP_DATE, cppu::UnoType<css::util::Date>::get(), PROPERTY_NONE, 0},
+ {UNO_NAME_TEXT_RANGE, FIELD_PROP_TEXT, cppu::UnoType<css::uno::XInterface>::get(), PropertyAttribute::READONLY, 0},
+ COMMON_FLDTYP_PROPERTIES
+ };
+ m_aMapEntriesArr[nPropertyId] = aAnnotationFieldPropMap;
+ }
+ break;
+ case PROPERTY_MAP_FLDTYP_INPUT:
+ {
+ static SfxItemPropertyMapEntry const aInputFieldPropMap [] =
+ {
+ {UNO_NAME_CONTENT, FIELD_PROP_PAR1, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ {UNO_NAME_HINT, FIELD_PROP_PAR2, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ {UNO_NAME_HELP, FIELD_PROP_PAR3, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ {UNO_NAME_TOOLTIP, FIELD_PROP_PAR4, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ {UNO_NAME_MISC_OBJ_INTEROPGRABBAG, FIELD_PROP_GRABBAG, cppu::UnoType< cppu::UnoSequenceType<css::beans::PropertyValue> >::get(), PROPERTY_NONE, 0},
+ COMMON_FLDTYP_PROPERTIES
+ };
+ m_aMapEntriesArr[nPropertyId] = aInputFieldPropMap;
+ }
+ break;
+ case PROPERTY_MAP_FLDTYP_MACRO :
+ {
+ static SfxItemPropertyMapEntry const aMacroFieldPropMap [] =
+ {
+ {UNO_NAME_HINT, FIELD_PROP_PAR2, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ {UNO_NAME_MACRO_NAME,FIELD_PROP_PAR1, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ {UNO_NAME_MACRO_LIBRARY,FIELD_PROP_PAR3, cppu::UnoType<OUString>::get(),PROPERTY_NONE, 0},
+ {UNO_NAME_SCRIPT_URL,FIELD_PROP_PAR4, cppu::UnoType<OUString>::get(),PROPERTY_NONE, 0},
+ COMMON_FLDTYP_PROPERTIES
+ };
+ m_aMapEntriesArr[nPropertyId] = aMacroFieldPropMap;
+ }
+ break;
+ case PROPERTY_MAP_FLDTYP_DDE :
+ {
+ static SfxItemPropertyMapEntry const aDDEFieldPropMap [] =
+ {
+ COMMON_FLDTYP_PROPERTIES
+ };
+ m_aMapEntriesArr[nPropertyId] = aDDEFieldPropMap;
+ }
+ break;
+ case PROPERTY_MAP_FLDTYP_DROPDOWN :
+ {
+ static SfxItemPropertyMapEntry const aDropDownMap [] =
+ {
+ {UNO_NAME_ITEMS, FIELD_PROP_STRINGS, cppu::UnoType< cppu::UnoSequenceType<OUString> >::get(), PROPERTY_NONE, 0},
+ {UNO_NAME_SELITEM, FIELD_PROP_PAR1, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ {UNO_NAME_NAME, FIELD_PROP_PAR2, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ {UNO_NAME_HELP, FIELD_PROP_PAR3, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ {UNO_NAME_TOOLTIP, FIELD_PROP_PAR4, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ COMMON_FLDTYP_PROPERTIES
+ };
+ m_aMapEntriesArr[nPropertyId] = aDropDownMap;
+ }
+ break;
+ case PROPERTY_MAP_FLDTYP_HIDDEN_PARA :
+ {
+ static SfxItemPropertyMapEntry const aHiddenParaFieldPropMap [] =
+ {
+ {UNO_NAME_CONDITION,FIELD_PROP_PAR1, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ {UNO_NAME_IS_HIDDEN , FIELD_PROP_BOOL1, cppu::UnoType<bool>::get(), PROPERTY_NONE, 0},
+ COMMON_FLDTYP_PROPERTIES
+ };
+ m_aMapEntriesArr[nPropertyId] = aHiddenParaFieldPropMap;
+ }
+ break;
+ case PROPERTY_MAP_FLDTYP_DOC_INFO :
+ {
+ static SfxItemPropertyMapEntry const aDocInfoFieldPropMap [] =
+ {
+ {UNO_NAME_IS_FIXED, FIELD_PROP_BOOL1, cppu::UnoType<bool>::get(), PROPERTY_NONE, 0},
+ {UNO_NAME_INFO_FORMAT, FIELD_PROP_USHORT2, cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE, 0},
+ {UNO_NAME_INFO_TYPE, FIELD_PROP_USHORT1, cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE, 0},
+ COMMON_FLDTYP_PROPERTIES
+ };
+ m_aMapEntriesArr[nPropertyId] = aDocInfoFieldPropMap;
+ }
+ break;
+ case PROPERTY_MAP_FLDTYP_TEMPLATE_NAME :
+ {
+ static SfxItemPropertyMapEntry const aTmplNameFieldPropMap [] =
+ {
+ {UNO_NAME_FILE_FORMAT, FIELD_PROP_FORMAT, cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE, 0},
+ COMMON_FLDTYP_PROPERTIES
+ };
+ m_aMapEntriesArr[nPropertyId] = aTmplNameFieldPropMap;
+ }
+ break;
+ case PROPERTY_MAP_FLDTYP_USER_EXT :
+ {
+ static SfxItemPropertyMapEntry const aUsrExtFieldPropMap [] =
+ {
+ {UNO_NAME_CONTENT, FIELD_PROP_PAR1, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ {UNO_NAME_CURRENT_PRESENTATION, FIELD_PROP_PAR1, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ {UNO_NAME_IS_FIXED, FIELD_PROP_BOOL1, cppu::UnoType<bool>::get(), PROPERTY_NONE, 0},
+ {UNO_NAME_USER_DATA_TYPE, FIELD_PROP_USHORT1, cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE, 0},
+ COMMON_FLDTYP_PROPERTIES
+ };
+ m_aMapEntriesArr[nPropertyId]= aUsrExtFieldPropMap;
+ }
+ break;
+ case PROPERTY_MAP_FLDTYP_REF_PAGE_SET :
+ {
+ static SfxItemPropertyMapEntry const aRefPgSetFieldPropMap [] =
+ {
+ {UNO_NAME_OFFSET, FIELD_PROP_USHORT1, cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE, 0},
+ {UNO_NAME_ON, FIELD_PROP_BOOL1, cppu::UnoType<bool>::get(), PROPERTY_NONE, 0},
+ COMMON_FLDTYP_PROPERTIES
+ };
+ m_aMapEntriesArr[nPropertyId] = aRefPgSetFieldPropMap;
+ }
+ break;
+ case PROPERTY_MAP_FLDTYP_REF_PAGE_GET :
+ {
+ static SfxItemPropertyMapEntry const aRefPgGetFieldPropMap [] =
+ {
+ {UNO_NAME_CURRENT_PRESENTATION, FIELD_PROP_PAR1, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ {UNO_NAME_NUMBERING_TYPE, FIELD_PROP_USHORT1, cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE, 0},
+ COMMON_FLDTYP_PROPERTIES
+ };
+ m_aMapEntriesArr[nPropertyId] = aRefPgGetFieldPropMap;
+ }
+ break;
+ case PROPERTY_MAP_FLDTYP_JUMP_EDIT :
+ {
+ static SfxItemPropertyMapEntry const aJumpEdtFieldPropMap [] =
+ {
+ {UNO_NAME_HINT, FIELD_PROP_PAR1, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ {UNO_NAME_PLACEHOLDER, FIELD_PROP_PAR2, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ {UNO_NAME_PLACEHOLDER_TYPE, FIELD_PROP_USHORT1, cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE, 0},
+ COMMON_FLDTYP_PROPERTIES
+ };
+ m_aMapEntriesArr[nPropertyId] = aJumpEdtFieldPropMap;
+ }
+ break;
+ case PROPERTY_MAP_FLDTYP_SCRIPT :
+ {
+ static SfxItemPropertyMapEntry const aScriptFieldPropMap [] =
+ {
+ {UNO_NAME_CONTENT, FIELD_PROP_PAR2, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ {UNO_NAME_SCRIPT_TYPE, FIELD_PROP_PAR1, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ {UNO_NAME_URL_CONTENT, FIELD_PROP_BOOL1, cppu::UnoType<bool>::get(), PROPERTY_NONE, 0},
+ COMMON_FLDTYP_PROPERTIES
+ };
+ m_aMapEntriesArr[nPropertyId] = aScriptFieldPropMap;
+ }
+ break;
+ case PROPERTY_MAP_FLDTYP_DATABASE_NEXT_SET :
+ {
+ static SfxItemPropertyMapEntry const aDBNextSetFieldPropMap [] =
+ {
+ // Note: DATA_BASE_NAME and DATA_BASE_URL
+ // are mapped to the same nMId, because internally we only use
+ // them as DataSource and it does not matter which one it is.
+
+ {UNO_NAME_DATA_BASE_NAME , FIELD_PROP_PAR1, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ {UNO_NAME_DATA_TABLE_NAME , FIELD_PROP_PAR2, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ {UNO_NAME_CONDITION , FIELD_PROP_PAR3, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ {UNO_NAME_DATA_BASE_URL , FIELD_PROP_PAR1, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ {UNO_NAME_DATA_COMMAND_TYPE, FIELD_PROP_SHORT1, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE, 0},
+ COMMON_FLDTYP_PROPERTIES
+ };
+ m_aMapEntriesArr[nPropertyId] = aDBNextSetFieldPropMap;
+ }
+ break;
+ case PROPERTY_MAP_FLDTYP_DATABASE_NUM_SET :
+ {
+ static SfxItemPropertyMapEntry const aDBNumSetFieldPropMap [] =
+ {
+ // Note: DATA_BASE_NAME and DATA_BASE_URL
+ // are mapped to the same nMId, because internally we only use
+ // them as DataSource and it does not matter which one it is.
+
+ {UNO_NAME_DATA_BASE_NAME , FIELD_PROP_PAR1, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ {UNO_NAME_DATA_TABLE_NAME, FIELD_PROP_PAR2, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ {UNO_NAME_CONDITION, FIELD_PROP_PAR3, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ {UNO_NAME_DATA_BASE_URL , FIELD_PROP_PAR1, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ {UNO_NAME_DATA_COMMAND_TYPE, FIELD_PROP_SHORT1, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE, 0},
+ {UNO_NAME_SET_NUMBER, FIELD_PROP_FORMAT, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE, 0},
+ COMMON_FLDTYP_PROPERTIES
+ };
+ m_aMapEntriesArr[nPropertyId] = aDBNumSetFieldPropMap;
+ }
+ break;
+ case PROPERTY_MAP_FLDTYP_DATABASE_SET_NUM :
+ {
+ static SfxItemPropertyMapEntry const aDBSetNumFieldPropMap [] =
+ {
+ // Note: DATA_BASE_NAME and DATA_BASE_URL
+ // are mapped to the same nMId, because internally we only use
+ // them as DataSource and it does not matter which one it is.
+
+ {UNO_NAME_DATA_BASE_NAME , FIELD_PROP_PAR1, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ {UNO_NAME_DATA_TABLE_NAME , FIELD_PROP_PAR2, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ {UNO_NAME_DATA_BASE_URL , FIELD_PROP_PAR1, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ {UNO_NAME_DATA_COMMAND_TYPE, FIELD_PROP_SHORT1, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE, 0},
+ {UNO_NAME_NUMBERING_TYPE, FIELD_PROP_USHORT1, cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE, 0},
+ {UNO_NAME_SET_NUMBER, FIELD_PROP_FORMAT, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE, 0},
+ {UNO_NAME_IS_VISIBLE, FIELD_PROP_BOOL2, cppu::UnoType<bool>::get(), PROPERTY_NONE, 0},
+ COMMON_FLDTYP_PROPERTIES
+ };
+ m_aMapEntriesArr[nPropertyId] = aDBSetNumFieldPropMap;
+ }
+ break;
+ case PROPERTY_MAP_FLDTYP_DATABASE :
+ {
+ static SfxItemPropertyMapEntry const aDBFieldPropMap [] =
+ {
+ {UNO_NAME_CONTENT, FIELD_PROP_PAR1, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ {UNO_NAME_CURRENT_PRESENTATION, FIELD_PROP_PAR1, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ {UNO_NAME_FIELD_CODE, FIELD_PROP_PAR2, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ {UNO_NAME_IS_DATA_BASE_FORMAT,FIELD_PROP_BOOL1, cppu::UnoType<bool>::get() , PROPERTY_NONE,0},
+ {UNO_NAME_NUMBER_FORMAT, FIELD_PROP_FORMAT, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE, 0},
+ {UNO_NAME_IS_VISIBLE, FIELD_PROP_BOOL2, cppu::UnoType<bool>::get(), PROPERTY_NONE, 0},
+ COMMON_FLDTYP_PROPERTIES
+ };
+ m_aMapEntriesArr[nPropertyId] = aDBFieldPropMap;
+ }
+ break;
+ case PROPERTY_MAP_FLDTYP_DATABASE_NAME :
+ {
+ static SfxItemPropertyMapEntry const aDBNameFieldPropMap [] =
+ {
+ // Note: DATA_BASE_NAME and DATA_BASE_URL
+ // are mapped to the same nMId, because internally we only use
+ // them as DataSource and it does not matter which one it is.
+
+ {UNO_NAME_DATA_BASE_NAME , FIELD_PROP_PAR1, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ {UNO_NAME_DATA_TABLE_NAME , FIELD_PROP_PAR2, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ {UNO_NAME_DATA_BASE_URL , FIELD_PROP_PAR1, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ {UNO_NAME_DATA_COMMAND_TYPE, FIELD_PROP_SHORT1, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE, 0},
+ {UNO_NAME_IS_VISIBLE, FIELD_PROP_BOOL2, cppu::UnoType<bool>::get(), PROPERTY_NONE, 0},
+ COMMON_FLDTYP_PROPERTIES
+ };
+ m_aMapEntriesArr[nPropertyId] = aDBNameFieldPropMap;
+ }
+ break;
+ case PROPERTY_MAP_FLDTYP_DOCSTAT:
+ {
+ static SfxItemPropertyMapEntry const aDocstatFieldPropMap [] =
+ {
+ {UNO_NAME_NUMBERING_TYPE, FIELD_PROP_USHORT2, cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE, 0},
+ // {UNO_NAME_STATISTIC_TYPE_ID,FIELD_PROP_USHORT1, cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE, 0},
+ COMMON_FLDTYP_PROPERTIES
+ };
+ m_aMapEntriesArr[nPropertyId] = aDocstatFieldPropMap;
+ }
+ break;
+ case PROPERTY_MAP_FLDTYP_DOCINFO_AUTHOR:
+ {
+ static SfxItemPropertyMapEntry const aDocInfoAuthorPropMap [] =
+ {
+ {UNO_NAME_AUTHOR, FIELD_PROP_PAR1, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ {UNO_NAME_CURRENT_PRESENTATION, FIELD_PROP_PAR3, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ {UNO_NAME_IS_FIXED, FIELD_PROP_BOOL1, cppu::UnoType<bool>::get() , PROPERTY_NONE,0},
+ COMMON_FLDTYP_PROPERTIES
+ };
+ m_aMapEntriesArr[nPropertyId] = aDocInfoAuthorPropMap;
+ }
+ break;
+ case PROPERTY_MAP_FLDTYP_DOCINFO_DATE_TIME:
+ {
+ static SfxItemPropertyMapEntry const aDocInfoDateTimePropMap [] =
+ {
+ {UNO_NAME_CURRENT_PRESENTATION, FIELD_PROP_PAR3, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ {UNO_NAME_DATE_TIME_VALUE, FIELD_PROP_DOUBLE, cppu::UnoType<double>::get(), PropertyAttribute::READONLY, 0},
+ {UNO_NAME_IS_DATE, FIELD_PROP_BOOL2, cppu::UnoType<bool>::get() , PROPERTY_NONE,0},
+ {UNO_NAME_NUMBER_FORMAT,FIELD_PROP_FORMAT, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE, 0},
+ {UNO_NAME_IS_FIXED, FIELD_PROP_BOOL1, cppu::UnoType<bool>::get() , PROPERTY_NONE, 0},
+ {UNO_NAME_IS_FIXED_LANGUAGE, FIELD_PROP_BOOL4, cppu::UnoType<bool>::get(), PROPERTY_NONE, 0},
+ };
+ m_aMapEntriesArr[nPropertyId] = aDocInfoDateTimePropMap;
+ }
+ break;
+ case PROPERTY_MAP_FLDTYP_DOCINFO_EDIT_TIME :
+ {
+ static SfxItemPropertyMapEntry const aDocInfoEditTimePropMap [] =
+ {
+ {UNO_NAME_CURRENT_PRESENTATION, FIELD_PROP_PAR3, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ {UNO_NAME_DATE_TIME_VALUE, FIELD_PROP_DOUBLE, cppu::UnoType<double>::get(), PropertyAttribute::READONLY, 0},
+ {UNO_NAME_NUMBER_FORMAT,FIELD_PROP_FORMAT, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE, 0},
+ {UNO_NAME_IS_FIXED, FIELD_PROP_BOOL1, cppu::UnoType<bool>::get() , PROPERTY_NONE, 0},
+ {UNO_NAME_IS_FIXED_LANGUAGE, FIELD_PROP_BOOL4, cppu::UnoType<bool>::get(), PROPERTY_NONE, 0},
+ COMMON_FLDTYP_PROPERTIES
+ };
+ m_aMapEntriesArr[nPropertyId] = aDocInfoEditTimePropMap;
+ }
+ break;
+ case PROPERTY_MAP_FLDTYP_DOCINFO_MISC:
+ {
+ static SfxItemPropertyMapEntry const aDocInfoStringContentPropMap [] =
+ {
+ {UNO_NAME_CONTENT, FIELD_PROP_PAR1, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ {UNO_NAME_CURRENT_PRESENTATION, FIELD_PROP_PAR3, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ {UNO_NAME_IS_FIXED, FIELD_PROP_BOOL1, cppu::UnoType<bool>::get() , PROPERTY_NONE,0},
+ COMMON_FLDTYP_PROPERTIES
+ };
+ m_aMapEntriesArr[nPropertyId] = aDocInfoStringContentPropMap;
+ }
+ break;
+ case PROPERTY_MAP_FLDTYP_DOCINFO_CUSTOM:
+ {
+ static SfxItemPropertyMapEntry const aDocInfoCustomPropMap [] =
+ {
+ {UNO_NAME_NAME, FIELD_PROP_PAR4, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ {UNO_NAME_CURRENT_PRESENTATION, FIELD_PROP_PAR3, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ {UNO_NAME_IS_FIXED, FIELD_PROP_BOOL1, cppu::UnoType<bool>::get() , PROPERTY_NONE,0},
+ {UNO_NAME_NUMBER_FORMAT, FIELD_PROP_FORMAT, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE, 0},
+ {UNO_NAME_IS_FIXED_LANGUAGE, FIELD_PROP_BOOL4, cppu::UnoType<bool>::get(), PROPERTY_NONE, 0},
+ COMMON_FLDTYP_PROPERTIES
+ };
+ m_aMapEntriesArr[nPropertyId] = aDocInfoCustomPropMap;
+ }
+ break;
+ case PROPERTY_MAP_FLDTYP_DOCINFO_REVISION :
+ {
+ static SfxItemPropertyMapEntry const aDocInfoRevisionPropMap [] =
+ {
+ {UNO_NAME_CURRENT_PRESENTATION, FIELD_PROP_PAR3, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ {UNO_NAME_REVISION, FIELD_PROP_USHORT1, cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE, 0},
+ {UNO_NAME_IS_FIXED, FIELD_PROP_BOOL1, cppu::UnoType<bool>::get() , PROPERTY_NONE,0},
+ COMMON_FLDTYP_PROPERTIES
+ };
+ m_aMapEntriesArr[nPropertyId] = aDocInfoRevisionPropMap;
+ }
+ break;
+ case PROPERTY_MAP_FLDTYP_COMBINED_CHARACTERS:
+ {
+ static SfxItemPropertyMapEntry const aCombinedCharactersPropMap[] =
+ {
+ {UNO_NAME_CONTENT, FIELD_PROP_PAR1, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ COMMON_FLDTYP_PROPERTIES
+ };
+ m_aMapEntriesArr[nPropertyId] = aCombinedCharactersPropMap;
+ }
+ break;
+ case PROPERTY_MAP_FLDTYP_TABLE_FORMULA:
+ {
+ static SfxItemPropertyMapEntry const aTableFormulaPropMap[] =
+ {
+ {UNO_NAME_CURRENT_PRESENTATION, FIELD_PROP_PAR1, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ {UNO_NAME_CONTENT, FIELD_PROP_PAR2, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ {UNO_NAME_IS_SHOW_FORMULA, FIELD_PROP_BOOL1, cppu::UnoType<bool>::get(), PROPERTY_NONE, 0},
+ {UNO_NAME_NUMBER_FORMAT, FIELD_PROP_FORMAT, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE, 0},
+ COMMON_FLDTYP_PROPERTIES
+ };
+ m_aMapEntriesArr[nPropertyId] = aTableFormulaPropMap;
+ }
+ break;
+ case PROPERTY_MAP_FLDTYP_DUMMY_0:
+ {
+ static SfxItemPropertyMapEntry const aEmptyPropMap [] =
+ {
+ COMMON_FLDTYP_PROPERTIES
+ };
+ m_aMapEntriesArr[nPropertyId] = aEmptyPropMap;
+ }
+ break;
+ case PROPERTY_MAP_FLDMSTR_USER :
+ {
+ static SfxItemPropertyMapEntry const aUserFieldTypePropMap[] =
+ {
+ {UNO_NAME_DEPENDENT_TEXT_FIELDS, FIELD_PROP_PROP_SEQ, cppu::UnoType< cppu::UnoSequenceType<css::text::XDependentTextField> >::get(), PropertyAttribute::READONLY, 0},
+ {UNO_NAME_IS_EXPRESSION, FIELD_PROP_BOOL1, cppu::UnoType<bool>::get(), PROPERTY_NONE, 0},
+ {UNO_NAME_NAME, FIELD_PROP_PAR1, cppu::UnoType<OUString>::get(), PropertyAttribute::MAYBEVOID, 0},
+ {UNO_NAME_VALUE, FIELD_PROP_DOUBLE, cppu::UnoType<double>::get(), PROPERTY_NONE, 0},
+ {UNO_NAME_CONTENT, FIELD_PROP_PAR2, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ {UNO_NAME_INSTANCE_NAME, FIELD_PROP_PAR3, cppu::UnoType<OUString>::get(), PropertyAttribute::READONLY, 0},
+ };
+ m_aMapEntriesArr[nPropertyId] = aUserFieldTypePropMap;
+ }
+ break;
+ case PROPERTY_MAP_FLDMSTR_DDE :
+ {
+ static SfxItemPropertyMapEntry const aDDEFieldTypePropMap[] =
+ {
+ {UNO_NAME_DDE_COMMAND_ELEMENT, FIELD_PROP_PAR2, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ {UNO_NAME_DDE_COMMAND_FILE, FIELD_PROP_PAR4, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ {UNO_NAME_DDE_COMMAND_TYPE, FIELD_PROP_SUBTYPE, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ {UNO_NAME_DEPENDENT_TEXT_FIELDS, FIELD_PROP_PROP_SEQ, cppu::UnoType< cppu::UnoSequenceType<css::text::XDependentTextField> >::get(), PropertyAttribute::READONLY, 0},
+ {UNO_NAME_IS_AUTOMATIC_UPDATE, FIELD_PROP_BOOL1, cppu::UnoType<bool>::get(), PROPERTY_NONE, 0},
+ {UNO_NAME_NAME, FIELD_PROP_PAR1, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ {UNO_NAME_INSTANCE_NAME, FIELD_PROP_PAR3, cppu::UnoType<OUString>::get(), PropertyAttribute::READONLY, 0},
+ {UNO_NAME_CONTENT, FIELD_PROP_PAR5, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ };
+ m_aMapEntriesArr[nPropertyId] = aDDEFieldTypePropMap;
+ }
+ break;
+ case PROPERTY_MAP_FLDMSTR_SET_EXP :
+ {
+ static SfxItemPropertyMapEntry const aSetExpFieldTypePropMap[] =
+ {
+ {UNO_NAME_CHAPTER_NUMBERING_LEVEL,FIELD_PROP_SHORT1, cppu::UnoType<sal_Int8>::get(), PROPERTY_NONE, 0},
+ {UNO_NAME_DEPENDENT_TEXT_FIELDS, FIELD_PROP_PROP_SEQ, cppu::UnoType< cppu::UnoSequenceType<css::text::XDependentTextField> >::get(), PropertyAttribute::READONLY, 0},
+ {UNO_NAME_NAME, FIELD_PROP_PAR1, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ {UNO_NAME_NUMBERING_SEPARATOR, FIELD_PROP_PAR2, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ {UNO_NAME_SUB_TYPE, FIELD_PROP_SUBTYPE, cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE, 0},
+ {UNO_NAME_INSTANCE_NAME, FIELD_PROP_PAR3, cppu::UnoType<OUString>::get(), PropertyAttribute::READONLY, 0},
+ };
+ m_aMapEntriesArr[nPropertyId] = aSetExpFieldTypePropMap;
+ }
+ break;
+ case PROPERTY_MAP_FLDMSTR_DATABASE :
+ {
+ static SfxItemPropertyMapEntry const aDBFieldTypePropMap [] =
+ {
+ // Note: DATA_BASE_NAME and DATA_BASE_URL
+ // are mapped to the same nMId, because internally we only use
+ // them as DataSource and it does not matter which one it is.
+
+ {UNO_NAME_DATA_BASE_NAME , FIELD_PROP_PAR1, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ {UNO_NAME_NAME, FIELD_PROP_PAR3, cppu::UnoType<OUString>::get(), PropertyAttribute::MAYBEVOID, 0},
+ {UNO_NAME_DATA_TABLE_NAME, FIELD_PROP_PAR2, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ {UNO_NAME_DATA_COLUMN_NAME, FIELD_PROP_PAR3, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ {UNO_NAME_INSTANCE_NAME, FIELD_PROP_PAR4, cppu::UnoType<OUString>::get(), PropertyAttribute::READONLY, 0},
+ {UNO_NAME_DATA_BASE_URL , FIELD_PROP_PAR1, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ {UNO_NAME_DATA_COMMAND_TYPE, FIELD_PROP_SHORT1, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE, 0},
+ {UNO_NAME_DEPENDENT_TEXT_FIELDS, FIELD_PROP_PROP_SEQ, cppu::UnoType< cppu::UnoSequenceType<css::text::XDependentTextField> >::get(), PropertyAttribute::READONLY, 0},
+ };
+ m_aMapEntriesArr[nPropertyId] = aDBFieldTypePropMap;
+ }
+ break;
+ case PROPERTY_MAP_FLDMSTR_DUMMY0 :
+ {
+ static SfxItemPropertyMapEntry const aStandardFieldMasterMap[] =
+ {
+ {UNO_NAME_DEPENDENT_TEXT_FIELDS, 0, cppu::UnoType< cppu::UnoSequenceType<css::text::XDependentTextField> >::get(), PropertyAttribute::READONLY, 0},
+ {UNO_NAME_NAME, 0, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ {UNO_NAME_INSTANCE_NAME, 0, cppu::UnoType<OUString>::get(), PropertyAttribute::READONLY, 0},
+ };
+ m_aMapEntriesArr[nPropertyId] = aStandardFieldMasterMap;
+ }
+ break;
+ case PROPERTY_MAP_FLDTYP_BIBLIOGRAPHY:
+ {
+ static SfxItemPropertyMapEntry const aBibliographyFieldMap[] =
+ {
+ {UNO_NAME_FIELDS , FIELD_PROP_PROP_SEQ, cppu::UnoType< cppu::UnoSequenceType<css::beans::PropertyValue> >::get(),PROPERTY_NONE, 0},
+ COMMON_FLDTYP_PROPERTIES
+ };
+ m_aMapEntriesArr[nPropertyId] = aBibliographyFieldMap;
+ }
+ break;
+ case PROPERTY_MAP_FLDMSTR_BIBLIOGRAPHY:
+ {
+ static SfxItemPropertyMapEntry const aBibliographyFieldMasterMap[] =
+ {
+ {UNO_NAME_BRACKET_BEFORE , FIELD_PROP_PAR1, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ {UNO_NAME_BRACKET_AFTER , FIELD_PROP_PAR2, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ {UNO_NAME_IS_NUMBER_ENTRIES , FIELD_PROP_BOOL1, cppu::UnoType<bool>::get(), PROPERTY_NONE, 0},
+ {UNO_NAME_IS_SORT_BY_POSITION , FIELD_PROP_BOOL2, cppu::UnoType<bool>::get(), PROPERTY_NONE, 0},
+ {UNO_NAME_LOCALE, FIELD_PROP_LOCALE, cppu::UnoType<css::lang::Locale>::get() , PROPERTY_NONE, 0},
+ {UNO_NAME_SORT_ALGORITHM, FIELD_PROP_PAR3, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ {UNO_NAME_SORT_KEYS , FIELD_PROP_PROP_SEQ, cppu::UnoType< cppu::UnoSequenceType<css::beans::PropertyValues> >::get(), PROPERTY_NONE, 0},
+ {UNO_NAME_INSTANCE_NAME, FIELD_PROP_PAR4, cppu::UnoType<OUString>::get(), PropertyAttribute::READONLY, 0},
+ };
+ m_aMapEntriesArr[nPropertyId] = aBibliographyFieldMasterMap;
+ }
+ break;
+ case PROPERTY_MAP_TEXT :
+ {
+ static SfxItemPropertyMapEntry const aTextMap[] =
+ {
+ REDLINE_NODE_PROPERTIES
+ };
+ m_aMapEntriesArr[nPropertyId] = aTextMap;
+ }
+ break;
+ case PROPERTY_MAP_MAILMERGE :
+ {
+ static SfxItemPropertyMapEntry const aMailMergeMap[] =
+ {
+ { UNO_NAME_SELECTION, WID_SELECTION, cppu::UnoType< cppu::UnoSequenceType<css::uno::Any> >::get(), PROPERTY_NONE, 0},
+ { UNO_NAME_RESULT_SET, WID_RESULT_SET, cppu::UnoType<css::sdbc::XResultSet>::get(), PROPERTY_NONE, 0},
+ { UNO_NAME_CONNECTION, WID_CONNECTION, cppu::UnoType<css::sdbc::XConnection>::get(), PROPERTY_NONE, 0},
+ { UNO_NAME_MODEL, WID_MODEL, cppu::UnoType<css::frame::XModel>::get(), PropertyAttribute::READONLY, 0},
+ { UNO_NAME_DATA_SOURCE_NAME, WID_DATA_SOURCE_NAME, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ { UNO_NAME_DAD_COMMAND, WID_DATA_COMMAND, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ { UNO_NAME_FILTER, WID_FILTER, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ { UNO_NAME_DOCUMENT_URL, WID_DOCUMENT_URL, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ { UNO_NAME_OUTPUT_URL, WID_OUTPUT_URL, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ { UNO_NAME_DAD_COMMAND_TYPE, WID_DATA_COMMAND_TYPE, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE, 0},
+ { UNO_NAME_OUTPUT_TYPE, WID_OUTPUT_TYPE, cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE, 0},
+ { UNO_NAME_ESCAPE_PROCESSING, WID_ESCAPE_PROCESSING, cppu::UnoType<bool>::get(), PROPERTY_NONE, 0},
+ { UNO_NAME_SINGLE_PRINT_JOBS, WID_SINGLE_PRINT_JOBS, cppu::UnoType<bool>::get(), PROPERTY_NONE, 0},
+ { UNO_NAME_FILE_NAME_FROM_COLUMN, WID_FILE_NAME_FROM_COLUMN, cppu::UnoType<bool>::get(), PROPERTY_NONE, 0},
+ { UNO_NAME_FILE_NAME_PREFIX, WID_FILE_NAME_PREFIX, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ { UNO_NAME_SUBJECT, WID_MAIL_SUBJECT, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ { UNO_NAME_ADDRESS_FROM_COLUMN, WID_ADDRESS_FROM_COLUMN, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ { UNO_NAME_SEND_AS_HTML, WID_SEND_AS_HTML, cppu::UnoType<bool>::get(), PROPERTY_NONE, 0},
+ { UNO_NAME_SEND_AS_ATTACHMENT, WID_SEND_AS_ATTACHMENT, cppu::UnoType<bool>::get(), PROPERTY_NONE, 0},
+ { UNO_NAME_MAIL_BODY, WID_MAIL_BODY, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ { UNO_NAME_ATTACHMENT_NAME, WID_ATTACHMENT_NAME, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ { UNO_NAME_ATTACHMENT_FILTER, WID_ATTACHMENT_FILTER, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ { UNO_NAME_PRINT_OPTIONS, WID_PRINT_OPTIONS, cppu::UnoType< cppu::UnoSequenceType<css::beans::PropertyValue> >::get(), PROPERTY_NONE, 0},
+ { UNO_NAME_SAVE_AS_SINGLE_FILE, WID_SAVE_AS_SINGLE_FILE, cppu::UnoType<bool>::get(), PROPERTY_NONE, 0},
+ { UNO_NAME_SAVE_FILTER, WID_SAVE_FILTER, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ { UNO_NAME_SAVE_FILTER_OPTIONS, WID_SAVE_FILTER_OPTIONS, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ { UNO_NAME_SAVE_FILTER_DATA, WID_SAVE_FILTER_DATA, cppu::UnoType< cppu::UnoSequenceType<css::beans::PropertyValue> >::get(), PROPERTY_NONE, 0},
+ { UNO_NAME_COPIES_TO, WID_COPIES_TO, cppu::UnoType< cppu::UnoSequenceType<OUString> >::get(), PROPERTY_NONE, 0},
+ { UNO_NAME_BLIND_COPIES_TO, WID_BLIND_COPIES_TO, cppu::UnoType< cppu::UnoSequenceType<OUString> >::get(), PROPERTY_NONE, 0},
+ { UNO_NAME_IN_SERVER_PASSWORD, WID_IN_SERVER_PASSWORD, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ { UNO_NAME_OUT_SERVER_PASSWORD, WID_OUT_SERVER_PASSWORD, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ };
+ m_aMapEntriesArr[nPropertyId] = aMailMergeMap;
+ }
+ break;
+ case PROPERTY_MAP_TEXT_VIEW :
+ {
+ static SfxItemPropertyMapEntry pTextViewMap[] =
+ {
+ {UNO_NAME_PAGE_COUNT, WID_PAGE_COUNT, cppu::UnoType<sal_Int32>::get(), PropertyAttribute::READONLY, 0},
+ {UNO_NAME_LINE_COUNT, WID_LINE_COUNT, cppu::UnoType<sal_Int32>::get(), PropertyAttribute::READONLY, 0},
+ {UNO_NAME_IS_CONSTANT_SPELLCHECK, WID_IS_CONSTANT_SPELLCHECK, cppu::UnoType<bool>::get(), PROPERTY_NONE, 0},
+ {UNO_NAME_IS_HIDE_SPELL_MARKS, WID_IS_HIDE_SPELL_MARKS, cppu::UnoType<bool>::get(), PROPERTY_NONE, 0}, // deprecated #i91949
+ };
+ m_aMapEntriesArr[nPropertyId] = pTextViewMap;
+ }
+ break;
+ case PROPERTY_MAP_CHART2_DATA_SEQUENCE :
+ {
+ static SfxItemPropertyMapEntry const aChart2DataSequenceMap[] =
+ {
+ {UNO_NAME_ROLE, 0, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0 },
+ };
+ m_aMapEntriesArr[nPropertyId] = aChart2DataSequenceMap;
+ }
+ break;
+ case PROPERTY_MAP_METAFIELD:
+ {
+ static SfxItemPropertyMapEntry const aMetaFieldMap[] =
+ {
+ { UNO_NAME_NUMBER_FORMAT, 0,
+ cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE, 0 },
+ { UNO_NAME_IS_FIXED_LANGUAGE, 0,
+ cppu::UnoType<bool>::get(), PROPERTY_NONE, 0 },
+ };
+ m_aMapEntriesArr[nPropertyId] = aMetaFieldMap;
+ }
+ break;
+ case PROPERTY_MAP_TABLE_STYLE:
+ {
+ static SfxItemPropertyMapEntry const aTableStyleMap[] =
+ {
+ { UNO_NAME_TABLE_FIRST_ROW_END_COLUMN, 0, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0 },
+ { UNO_NAME_TABLE_FIRST_ROW_START_COLUMN, 0, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0 },
+ { UNO_NAME_TABLE_LAST_ROW_END_COLUMN, 0, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0 },
+ { UNO_NAME_TABLE_LAST_ROW_START_COLUMN, 0, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0 },
+ { UNO_NAME_DISPLAY_NAME, 0, cppu::UnoType<OUString>::get(), PropertyAttribute::READONLY, 0 },
+ };
+ m_aMapEntriesArr[nPropertyId] = aTableStyleMap;
+ }
+ break;
+ case PROPERTY_MAP_CELL_STYLE:
+ {
+ static SfxItemPropertyMapEntry const aCellStyleMap[] =
+ {
+ // SvxBrushItem
+ { UNO_NAME_BACK_COLOR, RES_BACKGROUND, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE, MID_BACK_COLOR },
+ { UNO_NAME_BACKGROUND_COMPLEX_COLOR, RES_BACKGROUND, cppu::UnoType<css::util::XComplexColor>::get(), PROPERTY_NONE, MID_BACKGROUND_COMPLEX_COLOR },
+ // SvxBoxItem
+ { UNO_NAME_LEFT_BORDER, RES_BOX, cppu::UnoType<css::table::BorderLine>::get(), PROPERTY_NONE, LEFT_BORDER|CONVERT_TWIPS },
+ { UNO_NAME_RIGHT_BORDER, RES_BOX, cppu::UnoType<css::table::BorderLine>::get(), PROPERTY_NONE, RIGHT_BORDER|CONVERT_TWIPS },
+ { UNO_NAME_TOP_BORDER, RES_BOX, cppu::UnoType<css::table::BorderLine>::get(), PROPERTY_NONE, TOP_BORDER|CONVERT_TWIPS },
+ { UNO_NAME_BOTTOM_BORDER, RES_BOX, cppu::UnoType<css::table::BorderLine>::get(), PROPERTY_NONE, BOTTOM_BORDER|CONVERT_TWIPS },
+ { UNO_NAME_BORDER_DISTANCE, RES_BOX, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE, BORDER_DISTANCE|CONVERT_TWIPS },
+ { UNO_NAME_LEFT_BORDER_DISTANCE, RES_BOX, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE, LEFT_BORDER_DISTANCE |CONVERT_TWIPS },
+ { UNO_NAME_RIGHT_BORDER_DISTANCE, RES_BOX, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE, RIGHT_BORDER_DISTANCE |CONVERT_TWIPS },
+ { UNO_NAME_TOP_BORDER_DISTANCE, RES_BOX, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE, TOP_BORDER_DISTANCE |CONVERT_TWIPS },
+ { UNO_NAME_BOTTOM_BORDER_DISTANCE, RES_BOX, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE, BOTTOM_BORDER_DISTANCE|CONVERT_TWIPS },
+ { UNO_NAME_BORDER_LEFT_COMPLEX_COLOR, RES_BOX, cppu::UnoType<css::util::XComplexColor>::get(), PROPERTY_NONE, MID_BORDER_LEFT_COLOR },
+ { UNO_NAME_BORDER_RIGHT_COMPLEX_COLOR, RES_BOX, cppu::UnoType<css::util::XComplexColor>::get(), PROPERTY_NONE, MID_BORDER_RIGHT_COLOR },
+ { UNO_NAME_BORDER_TOP_COMPLEX_COLOR, RES_BOX, cppu::UnoType<css::util::XComplexColor>::get(), PROPERTY_NONE, MID_BORDER_TOP_COLOR },
+ { UNO_NAME_BORDER_BOTTOM_COMPLEX_COLOR, RES_BOX, cppu::UnoType<css::util::XComplexColor>::get(), PROPERTY_NONE, MID_BORDER_BOTTOM_COLOR },
+ // SwFormatVertOrient
+ { UNO_NAME_VERT_ORIENT, RES_VERT_ORIENT, cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE, MID_VERTORIENT_ORIENT },
+ // SvxFrameDirectionItem
+ { UNO_NAME_WRITING_MODE, RES_FRAMEDIR, cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE, 0 },
+ // SvNumberformat
+ { UNO_NAME_NUMBER_FORMAT, RES_BOXATR_FORMAT, cppu::UnoType<sal_Int32>::get(),PropertyAttribute::MAYBEVOID, 0 },
+ // SvxAdjustItem
+ { UNO_NAME_PARA_ADJUST, RES_PARATR_ADJUST, cppu::UnoType<sal_Int16>::get(),PropertyAttribute::MAYBEVOID, MID_PARA_ADJUST },
+ // SvxColorItem
+ { UNO_NAME_CHAR_COLOR, RES_CHRATR_COLOR, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE, 0 },
+ { UNO_NAME_CHAR_COLOR_THEME, RES_CHRATR_COLOR, cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE, MID_COLOR_THEME_INDEX },
+ { UNO_NAME_CHAR_COLOR_TINT_OR_SHADE, RES_CHRATR_COLOR, cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE, MID_COLOR_TINT_OR_SHADE },
+ { UNO_NAME_CHAR_COMPLEX_COLOR, RES_CHRATR_COLOR, cppu::UnoType<css::util::XComplexColor>::get(), PROPERTY_NONE, MID_COMPLEX_COLOR },
+ // SvxShadowedItem
+ { UNO_NAME_CHAR_SHADOWED, RES_CHRATR_SHADOWED, cppu::UnoType<bool>::get(), PROPERTY_NONE, 0 },
+ // SvxContouredItem
+ { UNO_NAME_CHAR_CONTOURED, RES_CHRATR_CONTOUR, cppu::UnoType<bool>::get(), PROPERTY_NONE, 0 },
+ // SvxCrossedOutItem
+ { UNO_NAME_CHAR_STRIKEOUT, RES_CHRATR_CROSSEDOUT, cppu::UnoType<sal_Int16>::get(),PropertyAttribute::MAYBEVOID, MID_CROSS_OUT },
+ // SvxUnderlineItem
+ { UNO_NAME_CHAR_UNDERLINE, RES_CHRATR_UNDERLINE, cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE, MID_TL_STYLE },
+ { UNO_NAME_CHAR_UNDERLINE_COLOR, RES_CHRATR_UNDERLINE,cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE, MID_TL_COLOR },
+ { UNO_NAME_CHAR_UNDERLINE_COMPLEX_COLOR, RES_CHRATR_UNDERLINE, cppu::UnoType<css::util::XComplexColor>::get(), PROPERTY_NONE, MID_TL_COMPLEX_COLOR },
+ { UNO_NAME_CHAR_UNDERLINE_HAS_COLOR, RES_CHRATR_UNDERLINE, cppu::UnoType<bool>::get(), PROPERTY_NONE, MID_TL_HASCOLOR },
+ // standard font
+ // SvxFontHeightItem
+ { UNO_NAME_CHAR_HEIGHT, RES_CHRATR_FONTSIZE, cppu::UnoType<float>::get(),PropertyAttribute::MAYBEVOID, MID_FONTHEIGHT|CONVERT_TWIPS },
+ // SvxWeightItem
+ { UNO_NAME_CHAR_WEIGHT, RES_CHRATR_WEIGHT, cppu::UnoType<float>::get(),PropertyAttribute::MAYBEVOID, MID_WEIGHT },
+ // SvxPostureItem
+ { UNO_NAME_CHAR_POSTURE, RES_CHRATR_POSTURE, cppu::UnoType<css::awt::FontSlant>::get(),PropertyAttribute::MAYBEVOID, MID_POSTURE },
+ // SvxFontItem
+ { UNO_NAME_CHAR_FONT_NAME, RES_CHRATR_FONT, cppu::UnoType<OUString>::get(), PropertyAttribute::MAYBEVOID, MID_FONT_FAMILY_NAME },
+ { UNO_NAME_CHAR_FONT_STYLE_NAME, RES_CHRATR_FONT, cppu::UnoType<OUString>::get(), PropertyAttribute::MAYBEVOID, MID_FONT_STYLE_NAME },
+ { UNO_NAME_CHAR_FONT_FAMILY, RES_CHRATR_FONT, cppu::UnoType<sal_Int16>::get(), PropertyAttribute::MAYBEVOID, MID_FONT_FAMILY },
+ { UNO_NAME_CHAR_FONT_CHAR_SET, RES_CHRATR_FONT, cppu::UnoType<sal_Int16>::get(), PropertyAttribute::MAYBEVOID, MID_FONT_CHAR_SET },
+ { UNO_NAME_CHAR_FONT_PITCH, RES_CHRATR_FONT, cppu::UnoType<sal_Int16>::get(), PropertyAttribute::MAYBEVOID, MID_FONT_PITCH },
+ // cjk font
+ { UNO_NAME_CHAR_HEIGHT_ASIAN, RES_CHRATR_CJK_FONTSIZE, cppu::UnoType<float>::get(), PropertyAttribute::MAYBEVOID, MID_FONTHEIGHT|CONVERT_TWIPS },
+ { UNO_NAME_CHAR_WEIGHT_ASIAN, RES_CHRATR_CJK_WEIGHT, cppu::UnoType<float>::get(), PropertyAttribute::MAYBEVOID, MID_WEIGHT },
+ { UNO_NAME_CHAR_POSTURE_ASIAN, RES_CHRATR_CJK_POSTURE, cppu::UnoType<css::awt::FontSlant>::get(), PropertyAttribute::MAYBEVOID, MID_POSTURE },
+ { UNO_NAME_CHAR_FONT_NAME_ASIAN, RES_CHRATR_CJK_FONT, cppu::UnoType<OUString>::get(), PropertyAttribute::MAYBEVOID, MID_FONT_FAMILY_NAME },
+ { UNO_NAME_CHAR_FONT_STYLE_NAME_ASIAN, RES_CHRATR_CJK_FONT, cppu::UnoType<OUString>::get(), PropertyAttribute::MAYBEVOID, MID_FONT_STYLE_NAME },
+ { UNO_NAME_CHAR_FONT_FAMILY_ASIAN, RES_CHRATR_CJK_FONT, cppu::UnoType<sal_Int16>::get(), PropertyAttribute::MAYBEVOID, MID_FONT_FAMILY },
+ { UNO_NAME_CHAR_FONT_CHAR_SET_ASIAN, RES_CHRATR_CJK_FONT, cppu::UnoType<sal_Int16>::get(), PropertyAttribute::MAYBEVOID, MID_FONT_CHAR_SET },
+ { UNO_NAME_CHAR_FONT_PITCH_ASIAN, RES_CHRATR_CJK_FONT, cppu::UnoType<sal_Int16>::get(), PropertyAttribute::MAYBEVOID, MID_FONT_PITCH },
+ // ctl font
+ { UNO_NAME_CHAR_HEIGHT_COMPLEX, RES_CHRATR_CTL_FONTSIZE, cppu::UnoType<float>::get(), PropertyAttribute::MAYBEVOID, MID_FONTHEIGHT|CONVERT_TWIPS },
+ { UNO_NAME_CHAR_WEIGHT_COMPLEX, RES_CHRATR_CTL_WEIGHT, cppu::UnoType<float>::get(), PropertyAttribute::MAYBEVOID, MID_WEIGHT },
+ { UNO_NAME_CHAR_POSTURE_COMPLEX, RES_CHRATR_CTL_POSTURE, cppu::UnoType<css::awt::FontSlant>::get(), PropertyAttribute::MAYBEVOID, MID_POSTURE },
+ { UNO_NAME_CHAR_FONT_NAME_COMPLEX, RES_CHRATR_CTL_FONT, cppu::UnoType<OUString>::get(), PropertyAttribute::MAYBEVOID, MID_FONT_FAMILY_NAME },
+ { UNO_NAME_CHAR_FONT_STYLE_NAME_COMPLEX, RES_CHRATR_CTL_FONT, cppu::UnoType<OUString>::get(), PropertyAttribute::MAYBEVOID, MID_FONT_STYLE_NAME },
+ { UNO_NAME_CHAR_FONT_FAMILY_COMPLEX, RES_CHRATR_CTL_FONT, cppu::UnoType<sal_Int16>::get(), PropertyAttribute::MAYBEVOID, MID_FONT_FAMILY },
+ { UNO_NAME_CHAR_FONT_CHAR_SET_COMPLEX, RES_CHRATR_CTL_FONT, cppu::UnoType<sal_Int16>::get(), PropertyAttribute::MAYBEVOID, MID_FONT_CHAR_SET },
+ { UNO_NAME_CHAR_FONT_PITCH_COMPLEX, RES_CHRATR_CTL_FONT, cppu::UnoType<sal_Int16>::get(), PropertyAttribute::MAYBEVOID, MID_FONT_PITCH },
+ };
+ m_aMapEntriesArr[nPropertyId] = aCellStyleMap;
+ }
+ break;
+ case PROPERTY_MAP_LINEBREAK:
+ {
+ m_aMapEntriesArr[nPropertyId] = GetLineBreakPropertyMap();
+ }
+ break;
+ case PROPERTY_MAP_CONTENTCONTROL:
+ {
+ m_aMapEntriesArr[nPropertyId] = GetContentControlPropertyMap();
+ }
+ break;
+
+ default:
+ OSL_FAIL( "unexpected property map ID" );
+ }
+ }
+ return m_aMapEntriesArr[nPropertyId];
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/core/unocore/unomap1.cxx b/sw/source/core/unocore/unomap1.cxx
new file mode 100644
index 0000000000..ee4422a22e
--- /dev/null
+++ b/sw/source/core/unocore/unomap1.cxx
@@ -0,0 +1,1737 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <hintids.hxx>
+
+#include <svx/unomid.hxx>
+#include <com/sun/star/awt/FontSlant.hpp>
+#include <com/sun/star/awt/Gradient.hpp>
+#include <com/sun/star/awt/Size.hpp>
+#include <com/sun/star/awt/XBitmap.hpp>
+#include <com/sun/star/beans/NamedValue.hpp>
+#include <com/sun/star/beans/PropertyAttribute.hpp>
+#include <com/sun/star/beans/PropertyValue.hpp>
+#include <com/sun/star/container/XIndexContainer.hpp>
+#include <com/sun/star/container/XIndexReplace.hpp>
+#include <com/sun/star/container/XNameContainer.hpp>
+#include <com/sun/star/drawing/BitmapMode.hpp>
+#include <com/sun/star/drawing/ColorMode.hpp>
+#include <com/sun/star/drawing/FillStyle.hpp>
+#include <com/sun/star/drawing/Hatch.hpp>
+#include <com/sun/star/drawing/LineStyle.hpp>
+#include <com/sun/star/drawing/PointSequenceSequence.hpp>
+#include <com/sun/star/drawing/RectanglePoint.hpp>
+#include <com/sun/star/drawing/TextVerticalAdjust.hpp>
+#include <com/sun/star/embed/XEmbeddedObject.hpp>
+#include <com/sun/star/frame/XModel.hpp>
+#include <com/sun/star/graphic/XGraphic.hpp>
+#include <com/sun/star/lang/Locale.hpp>
+#include <com/sun/star/style/BreakType.hpp>
+#include <com/sun/star/style/DropCapFormat.hpp>
+#include <com/sun/star/style/GraphicLocation.hpp>
+#include <com/sun/star/style/LineSpacing.hpp>
+#include <com/sun/star/style/PageStyleLayout.hpp>
+#include <com/sun/star/style/TabStop.hpp>
+#include <com/sun/star/table/BorderLine.hpp>
+#include <com/sun/star/table/ShadowFormat.hpp>
+#include <com/sun/star/table/TableBorder.hpp>
+#include <com/sun/star/table/TableBorder2.hpp>
+#include <com/sun/star/table/TableBorderDistances.hpp>
+#include <com/sun/star/table/XCell.hpp>
+#include <com/sun/star/text/GraphicCrop.hpp>
+#include <com/sun/star/text/SectionFileLink.hpp>
+#include <com/sun/star/text/TableColumnSeparator.hpp>
+#include <com/sun/star/text/TextContentAnchorType.hpp>
+#include <com/sun/star/text/WrapTextMode.hpp>
+#include <com/sun/star/text/XDocumentIndex.hpp>
+#include <com/sun/star/text/XDocumentIndexMark.hpp>
+#include <com/sun/star/text/XFootnote.hpp>
+#include <com/sun/star/text/XTextColumns.hpp>
+#include <com/sun/star/text/XTextContent.hpp>
+#include <com/sun/star/text/XTextField.hpp>
+#include <com/sun/star/text/XTextFrame.hpp>
+#include <com/sun/star/text/XTextSection.hpp>
+#include <com/sun/star/text/XTextTable.hpp>
+#include <com/sun/star/util/DateTime.hpp>
+#include <com/sun/star/util/XComplexColor.hpp>
+#include <unomap.hxx>
+#include <unoprnms.hxx>
+#include <unomid.h>
+#include <cmdid.h>
+#include <editeng/memberids.h>
+#include <editeng/unoprnms.hxx>
+#include <svl/itemprop.hxx>
+#include <svx/xdef.hxx>
+#include "unomapproperties.hxx"
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::beans;
+
+SwUnoPropertyMapProvider aSwMapProvider;
+
+SwUnoPropertyMapProvider::SwUnoPropertyMapProvider()
+{
+ for( sal_uInt16 i = 0; i < PROPERTY_MAP_END; i++ )
+ {
+ m_aPropertySetArr[i] = nullptr;
+ }
+}
+
+std::span<const SfxItemPropertyMapEntry> SwUnoPropertyMapProvider::GetTextCursorPropertyMap()
+{
+ static SfxItemPropertyMapEntry const aCharAndParaMap_Impl[] =
+ {
+ COMPLETE_TEXT_CURSOR_MAP
+ };
+
+ return aCharAndParaMap_Impl;
+}
+
+std::span<const SfxItemPropertyMapEntry> SwUnoPropertyMapProvider::GetAccessibilityTextAttrPropertyMap()
+{
+ static SfxItemPropertyMapEntry const aAccessibilityTextAttrMap_Impl[] =
+ {
+ COMMON_ACCESSIBILITY_TEXT_ATTRIBUTE
+ };
+
+ return aAccessibilityTextAttrMap_Impl;
+}
+
+std::span<const SfxItemPropertyMapEntry> SwUnoPropertyMapProvider::GetParagraphPropertyMap()
+{
+ static SfxItemPropertyMapEntry const aParagraphMap_Impl[] =
+ {
+ COMMON_CRSR_PARA_PROPERTIES_2
+ TABSTOPS_MAP_ENTRY
+ COMMON_TEXT_CONTENT_PROPERTIES
+ { UNO_NAME_CHAR_STYLE_NAME, RES_TXTATR_CHARFMT, cppu::UnoType<OUString>::get(), PropertyAttribute::MAYBEVOID, 0},
+ { UNO_NAME_CHAR_STYLE_NAMES, FN_UNO_CHARFMT_SEQUENCE, cppu::UnoType< cppu::UnoSequenceType<OUString> >::get(), PropertyAttribute::MAYBEVOID, 0},
+ // added FillProperties for SW, same as FILL_PROPERTIES in svx
+ // but need own defines in Writer due to later association of strings
+ // and uno types (see loop at end of this method and definition of SW_PROP_NMID)
+ // This entry is for adding that properties to style import/export
+ // Added for paragraph backgrounds, this is for paragraph itself
+ FILL_PROPERTIES_SW
+ };
+
+ return aParagraphMap_Impl;
+}
+
+std::span<const SfxItemPropertyMapEntry> SwUnoPropertyMapProvider::GetAutoParaStylePropertyMap()
+{
+ static SfxItemPropertyMapEntry const aAutoParaStyleMap [] =
+ {
+ { UNO_NAME_PARA_STYLE_NAME, RES_FRMATR_STYLE_NAME, cppu::UnoType<OUString>::get(), PropertyAttribute::MAYBEVOID, 0},
+ { UNO_NAME_PAGE_STYLE_NAME, FN_UNO_PAGE_STYLE, cppu::UnoType<OUString>::get(), PropertyAttribute::MAYBEVOID|PropertyAttribute::READONLY, 0},
+ { UNO_NAME_NUMBERING_IS_NUMBER, FN_UNO_IS_NUMBER, cppu::UnoType<bool>::get() , PropertyAttribute::MAYBEVOID, 0},
+ { UNO_NAME_NUMBERING_LEVEL, FN_UNO_NUM_LEVEL, cppu::UnoType<sal_Int16>::get(), PropertyAttribute::MAYBEVOID, 0},
+ { UNO_NAME_NUMBERING_START_VALUE, FN_UNO_NUM_START_VALUE, cppu::UnoType<sal_Int16>::get(), PropertyAttribute::MAYBEVOID, CONVERT_TWIPS},
+ { UNO_NAME_DOCUMENT_INDEX, FN_UNO_DOCUMENT_INDEX, cppu::UnoType<css::text::XDocumentIndex>::get(), PropertyAttribute::MAYBEVOID|PropertyAttribute::READONLY ,0 },
+ { UNO_NAME_TEXT_TABLE, FN_UNO_TEXT_TABLE, cppu::UnoType<css::text::XTextTable>::get(), PropertyAttribute::MAYBEVOID|PropertyAttribute::READONLY ,0 },
+ { UNO_NAME_CELL, FN_UNO_CELL, cppu::UnoType<css::table::XCell>::get(), PropertyAttribute::MAYBEVOID|PropertyAttribute::READONLY ,0 },
+ { UNO_NAME_TEXT_FRAME, FN_UNO_TEXT_FRAME, cppu::UnoType<css::text::XTextFrame>::get(), PropertyAttribute::MAYBEVOID|PropertyAttribute::READONLY ,0 },
+ { UNO_NAME_TEXT_SECTION, FN_UNO_TEXT_SECTION, cppu::UnoType<css::text::XTextSection>::get(), PropertyAttribute::MAYBEVOID|PropertyAttribute::READONLY ,0 },
+ { UNO_NAME_PARA_CHAPTER_NUMBERING_LEVEL, FN_UNO_PARA_CHAPTER_NUMBERING_LEVEL,cppu::UnoType<sal_Int8>::get(), PropertyAttribute::MAYBEVOID, 0},
+ { UNO_NAME_PARA_CONDITIONAL_STYLE_NAME, RES_FRMATR_CONDITIONAL_STYLE_NAME, cppu::UnoType<OUString>::get(), PropertyAttribute::MAYBEVOID|PropertyAttribute::READONLY, 0},
+ { UNO_NAME_PARA_IS_NUMBERING_RESTART, FN_NUMBER_NEWSTART, cppu::UnoType<bool>::get(), PropertyAttribute::MAYBEVOID, 0 },
+ // TODO add RES_PARATR_LIST_AUTOFMT?
+ { UNO_NAME_OUTLINE_LEVEL, RES_PARATR_OUTLINELEVEL, cppu::UnoType<sal_Int16>::get(), PropertyAttribute::MAYBEVOID, 0},
+ { UNO_NAME_OUTLINE_CONTENT_VISIBLE, RES_PARATR_GRABBAG, cppu::UnoType<bool>::get(), PropertyAttribute::MAYBEVOID, 0 },
+ COMMON_CRSR_PARA_PROPERTIES_WITHOUT_FN
+ TABSTOPS_MAP_ENTRY
+ COMMON_TEXT_CONTENT_PROPERTIES
+ { UNO_NAME_PARA_AUTO_STYLE_NAME, RES_AUTO_STYLE, cppu::UnoType<OUString>::get(), PropertyAttribute::MAYBEVOID, 0},
+ // added FillProperties for SW, same as FILL_PROPERTIES in svx
+ // but need own defines in Writer due to later association of strings
+ // and uno types (see loop at end of this method and definition of SW_PROP_NMID)
+ // This entry is for adding that properties to style import/export
+ // Added for paragraph backgrounds, this is for Paragraph AutoStyles
+ FILL_PROPERTIES_SW
+ };
+
+ return aAutoParaStyleMap;
+}
+
+std::span<const SfxItemPropertyMapEntry> SwUnoPropertyMapProvider::GetCharStylePropertyMap()
+{
+ static SfxItemPropertyMapEntry const aCharStyleMap [] =
+ {
+ { UNO_NAME_CHAR_AUTO_KERNING, RES_CHRATR_AUTOKERN , cppu::UnoType<bool>::get() , PROPERTY_NONE, 0},
+ { UNO_NAME_CHAR_BACK_TRANSPARENT, RES_CHRATR_BACKGROUND, cppu::UnoType<bool>::get(), PROPERTY_NONE ,MID_GRAPHIC_TRANSPARENT },
+ { UNO_NAME_CHAR_BACK_COLOR, RES_CHRATR_BACKGROUND, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE ,MID_BACK_COLOR },
+ { UNO_NAME_CHAR_BACKGROUND_COMPLEX_COLOR, RES_CHRATR_BACKGROUND, cppu::UnoType<css::util::XComplexColor>::get(), PROPERTY_NONE ,MID_BACKGROUND_COMPLEX_COLOR },
+ { UNO_NAME_CHAR_HIGHLIGHT, RES_CHRATR_HIGHLIGHT, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE, MID_BACK_COLOR },
+ { UNO_NAME_CHAR_CASE_MAP, RES_CHRATR_CASEMAP, cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE, 0},
+ { UNO_NAME_CHAR_COLOR, RES_CHRATR_COLOR, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE, 0 },
+ { UNO_NAME_CHAR_COLOR_THEME, RES_CHRATR_COLOR, cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE, MID_COLOR_THEME_INDEX },
+ { UNO_NAME_CHAR_COLOR_TINT_OR_SHADE, RES_CHRATR_COLOR, cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE, MID_COLOR_TINT_OR_SHADE },
+ { UNO_NAME_CHAR_COMPLEX_COLOR, RES_CHRATR_COLOR, cppu::UnoType<css::util::XComplexColor>::get(), PROPERTY_NONE, MID_COMPLEX_COLOR },
+ { UNO_NAME_CHAR_TRANSPARENCE, RES_CHRATR_COLOR, cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE, MID_COLOR_ALPHA},
+ { UNO_NAME_CHAR_STRIKEOUT, RES_CHRATR_CROSSEDOUT, cppu::UnoType<sal_Int16>::get(), PropertyAttribute::MAYBEVOID, MID_CROSS_OUT},
+ { UNO_NAME_CHAR_CROSSED_OUT, RES_CHRATR_CROSSEDOUT, cppu::UnoType<bool>::get() , PROPERTY_NONE, 0},
+ { UNO_NAME_CHAR_ESCAPEMENT, RES_CHRATR_ESCAPEMENT, cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE, MID_ESC },
+ { UNO_NAME_CHAR_ESCAPEMENT_HEIGHT, RES_CHRATR_ESCAPEMENT, cppu::UnoType<sal_Int8>::get() , PROPERTY_NONE, MID_ESC_HEIGHT},
+ { UNO_NAME_CHAR_FLASH, RES_CHRATR_BLINK , cppu::UnoType<bool>::get() , PROPERTY_NONE, 0},
+ { UNO_NAME_CHAR_HIDDEN, RES_CHRATR_HIDDEN, cppu::UnoType<bool>::get() , PROPERTY_NONE, 0},
+ STANDARD_FONT_PROPERTIES
+ CJK_FONT_PROPERTIES
+ CTL_FONT_PROPERTIES
+ { UNO_NAME_CHAR_UNDERLINE, RES_CHRATR_UNDERLINE , cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE, MID_TL_STYLE},
+ { UNO_NAME_CHAR_UNDERLINE_COLOR, RES_CHRATR_UNDERLINE , cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE, MID_TL_COLOR},
+ { UNO_NAME_CHAR_UNDERLINE_COMPLEX_COLOR, RES_CHRATR_UNDERLINE , cppu::UnoType<css::util::XComplexColor>::get(), PROPERTY_NONE, MID_TL_COMPLEX_COLOR },
+ { UNO_NAME_CHAR_UNDERLINE_HAS_COLOR, RES_CHRATR_UNDERLINE , cppu::UnoType<bool>::get(), PROPERTY_NONE, MID_TL_HASCOLOR},
+ { UNO_NAME_CHAR_OVERLINE, RES_CHRATR_OVERLINE , cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE, MID_TL_STYLE},
+ { UNO_NAME_CHAR_OVERLINE_COLOR, RES_CHRATR_OVERLINE , cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE, MID_TL_COLOR},
+ { UNO_NAME_CHAR_OVERLINE_COMPLEX_COLOR, RES_CHRATR_OVERLINE, cppu::UnoType<css::util::XComplexColor>::get(), PROPERTY_NONE, MID_TL_COMPLEX_COLOR },
+ { UNO_NAME_CHAR_OVERLINE_HAS_COLOR, RES_CHRATR_OVERLINE , cppu::UnoType<bool>::get(), PROPERTY_NONE, MID_TL_HASCOLOR},
+ { UNO_NAME_CHAR_KERNING, RES_CHRATR_KERNING , cppu::UnoType<sal_Int16>::get() , PROPERTY_NONE, CONVERT_TWIPS},
+ { UNO_NAME_CHAR_NO_HYPHENATION, RES_CHRATR_NOHYPHEN , cppu::UnoType<bool>::get() , PROPERTY_NONE, 0},
+ { UNO_NAME_CHAR_SHADOWED, RES_CHRATR_SHADOWED , cppu::UnoType<bool>::get() , PROPERTY_NONE, 0},
+ { UNO_NAME_CHAR_CONTOURED, RES_CHRATR_CONTOUR, cppu::UnoType<bool>::get() , PROPERTY_NONE, 0},
+ { UNO_NAME_CHAR_WORD_MODE, RES_CHRATR_WORDLINEMODE,cppu::UnoType<bool>::get() , PROPERTY_NONE, 0},
+ { UNO_NAME_USER_DEFINED_ATTRIBUTES, RES_UNKNOWNATR_CONTAINER, cppu::UnoType<css::container::XNameContainer>::get(), PropertyAttribute::MAYBEVOID, 0 },
+ { UNO_NAME_IS_PHYSICAL, FN_UNO_IS_PHYSICAL, cppu::UnoType<bool>::get(), PropertyAttribute::READONLY, 0},
+ { UNO_NAME_HIDDEN, FN_UNO_HIDDEN, cppu::UnoType<bool>::get(), PROPERTY_NONE, 0},
+ { UNO_NAME_STYLE_INTEROP_GRAB_BAG, FN_UNO_STYLE_INTEROP_GRAB_BAG, cppu::UnoType< cppu::UnoSequenceType<css::beans::PropertyValue> >::get(), PROPERTY_NONE, 0},
+ { UNO_NAME_DISPLAY_NAME, FN_UNO_DISPLAY_NAME, cppu::UnoType<OUString>::get(), PropertyAttribute::READONLY, 0},
+ { UNO_NAME_CHAR_COMBINE_IS_ON, RES_CHRATR_TWO_LINES, cppu::UnoType<bool>::get(), PROPERTY_NONE, MID_TWOLINES},
+ { UNO_NAME_CHAR_COMBINE_PREFIX, RES_CHRATR_TWO_LINES, cppu::UnoType<OUString>::get(), PROPERTY_NONE, MID_START_BRACKET},
+ { UNO_NAME_CHAR_COMBINE_SUFFIX, RES_CHRATR_TWO_LINES, cppu::UnoType<OUString>::get(), PROPERTY_NONE, MID_END_BRACKET},
+ { UNO_NAME_CHAR_EMPHASIS, RES_CHRATR_EMPHASIS_MARK, cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE, MID_EMPHASIS},
+ PROP_DIFF_FONTHEIGHT
+ { UNO_NAME_CHAR_ROTATION, RES_CHRATR_ROTATE, cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE, MID_ROTATE },
+ { UNO_NAME_CHAR_ROTATION_IS_FIT_TO_LINE, RES_CHRATR_ROTATE, cppu::UnoType<bool>::get(), PROPERTY_NONE, MID_FITTOLINE },
+ { UNO_NAME_CHAR_SCALE_WIDTH, RES_CHRATR_SCALEW, cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE, 0 },
+ { UNO_NAME_CHAR_RELIEF, RES_CHRATR_RELIEF, cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE, MID_RELIEF },
+ { UNO_NAME_CHAR_LEFT_BORDER, RES_CHRATR_BOX, cppu::UnoType<css::table::BorderLine>::get(), PROPERTY_NONE, LEFT_BORDER |CONVERT_TWIPS },
+ { UNO_NAME_CHAR_RIGHT_BORDER, RES_CHRATR_BOX, cppu::UnoType<css::table::BorderLine>::get(), PROPERTY_NONE, RIGHT_BORDER |CONVERT_TWIPS },
+ { UNO_NAME_CHAR_TOP_BORDER, RES_CHRATR_BOX, cppu::UnoType<css::table::BorderLine>::get(), PROPERTY_NONE, TOP_BORDER |CONVERT_TWIPS },
+ { UNO_NAME_CHAR_BOTTOM_BORDER, RES_CHRATR_BOX, cppu::UnoType<css::table::BorderLine>::get(), PROPERTY_NONE, BOTTOM_BORDER |CONVERT_TWIPS },
+ { UNO_NAME_CHAR_BORDER_DISTANCE, RES_CHRATR_BOX, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE, BORDER_DISTANCE |CONVERT_TWIPS },
+ { UNO_NAME_CHAR_LEFT_BORDER_DISTANCE, RES_CHRATR_BOX, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE, LEFT_BORDER_DISTANCE |CONVERT_TWIPS },
+ { UNO_NAME_CHAR_RIGHT_BORDER_DISTANCE, RES_CHRATR_BOX, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE, RIGHT_BORDER_DISTANCE |CONVERT_TWIPS },
+ { UNO_NAME_CHAR_TOP_BORDER_DISTANCE, RES_CHRATR_BOX, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE, TOP_BORDER_DISTANCE |CONVERT_TWIPS },
+ { UNO_NAME_CHAR_BOTTOM_BORDER_DISTANCE, RES_CHRATR_BOX, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE, BOTTOM_BORDER_DISTANCE|CONVERT_TWIPS },
+ { UNO_NAME_CHAR_BORDER_LEFT_COMPLEX_COLOR, RES_CHRATR_BOX, cppu::UnoType<css::util::XComplexColor>::get(), PropertyAttribute::MAYBEVOID, MID_BORDER_LEFT_COLOR },
+ { UNO_NAME_CHAR_BORDER_RIGHT_COMPLEX_COLOR, RES_CHRATR_BOX, cppu::UnoType<css::util::XComplexColor>::get(), PropertyAttribute::MAYBEVOID, MID_BORDER_RIGHT_COLOR },
+ { UNO_NAME_CHAR_BORDER_TOP_COMPLEX_COLOR, RES_CHRATR_BOX, cppu::UnoType<css::util::XComplexColor>::get(), PropertyAttribute::MAYBEVOID, MID_BORDER_TOP_COLOR },
+ { UNO_NAME_CHAR_BORDER_BOTTOM_COMPLEX_COLOR, RES_CHRATR_BOX, cppu::UnoType<css::util::XComplexColor>::get(), PropertyAttribute::MAYBEVOID, MID_BORDER_BOTTOM_COLOR },
+ { UNO_NAME_CHAR_SHADOW_FORMAT, RES_CHRATR_SHADOW, cppu::UnoType<css::table::ShadowFormat>::get(), PROPERTY_NONE, CONVERT_TWIPS},
+ { UNO_NAME_LINK_STYLE, FN_UNO_LINK_STYLE, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ };
+
+ return aCharStyleMap;
+}
+
+std::span<const SfxItemPropertyMapEntry> SwUnoPropertyMapProvider::GetAutoCharStylePropertyMap()
+{
+ // same as PROPERTY_MAP_TEXTPORTION_EXTENSIONS
+ static SfxItemPropertyMapEntry const aAutoCharStyleMap [] =
+ {
+ { UNO_NAME_CHAR_AUTO_KERNING, RES_CHRATR_AUTOKERN , cppu::UnoType<bool>::get() , PROPERTY_NONE, 0},
+ { UNO_NAME_CHAR_BACK_TRANSPARENT, RES_CHRATR_BACKGROUND, cppu::UnoType<bool>::get(), PROPERTY_NONE ,MID_GRAPHIC_TRANSPARENT },
+ { UNO_NAME_CHAR_BACK_COLOR, RES_CHRATR_BACKGROUND, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE ,MID_BACK_COLOR },
+ { UNO_NAME_CHAR_BACKGROUND_COMPLEX_COLOR, RES_CHRATR_BACKGROUND, cppu::UnoType<css::util::XComplexColor>::get(), PROPERTY_NONE, MID_BACKGROUND_COMPLEX_COLOR },
+ { UNO_NAME_CHAR_HIGHLIGHT, RES_CHRATR_HIGHLIGHT, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE, MID_BACK_COLOR },
+ { UNO_NAME_CHAR_CASE_MAP, RES_CHRATR_CASEMAP, cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE, 0},
+ { UNO_NAME_CHAR_COLOR, RES_CHRATR_COLOR, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE, 0},
+ { UNO_NAME_CHAR_COLOR_THEME, RES_CHRATR_COLOR, cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE, MID_COLOR_THEME_INDEX },
+ { UNO_NAME_CHAR_COLOR_TINT_OR_SHADE, RES_CHRATR_COLOR, cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE, MID_COLOR_TINT_OR_SHADE },
+ { UNO_NAME_CHAR_COMPLEX_COLOR, RES_CHRATR_COLOR, cppu::UnoType<css::util::XComplexColor>::get(), PROPERTY_NONE, MID_COMPLEX_COLOR },
+ { UNO_NAME_CHAR_TRANSPARENCE, RES_CHRATR_COLOR, cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE, MID_COLOR_ALPHA},
+ { UNO_NAME_CHAR_STRIKEOUT, RES_CHRATR_CROSSEDOUT, cppu::UnoType<sal_Int16>::get(), PropertyAttribute::MAYBEVOID, MID_CROSS_OUT},
+ { UNO_NAME_CHAR_CROSSED_OUT, RES_CHRATR_CROSSEDOUT, cppu::UnoType<bool>::get() , PROPERTY_NONE, 0},
+ { UNO_NAME_CHAR_ESCAPEMENT, RES_CHRATR_ESCAPEMENT, cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE, MID_ESC },
+ { UNO_NAME_CHAR_ESCAPEMENT_HEIGHT, RES_CHRATR_ESCAPEMENT, cppu::UnoType<sal_Int8>::get() , PROPERTY_NONE, MID_ESC_HEIGHT},
+ { UNO_NAME_CHAR_FLASH, RES_CHRATR_BLINK , cppu::UnoType<bool>::get() , PROPERTY_NONE, 0},
+ { UNO_NAME_CHAR_HIDDEN, RES_CHRATR_HIDDEN, cppu::UnoType<bool>::get() , PROPERTY_NONE, 0},
+ STANDARD_FONT_PROPERTIES
+ CJK_FONT_PROPERTIES
+ CTL_FONT_PROPERTIES
+ { UNO_NAME_CHAR_UNDERLINE, RES_CHRATR_UNDERLINE , cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE, MID_TL_STYLE},
+ { UNO_NAME_CHAR_UNDERLINE_COLOR, RES_CHRATR_UNDERLINE , cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE, MID_TL_COLOR},
+ { UNO_NAME_CHAR_UNDERLINE_COMPLEX_COLOR, RES_CHRATR_UNDERLINE, cppu::UnoType<css::util::XComplexColor>::get(), PROPERTY_NONE, MID_TL_COMPLEX_COLOR },
+ { UNO_NAME_CHAR_UNDERLINE_HAS_COLOR, RES_CHRATR_UNDERLINE , cppu::UnoType<bool>::get(), PROPERTY_NONE, MID_TL_HASCOLOR},
+ { UNO_NAME_CHAR_OVERLINE, RES_CHRATR_OVERLINE , cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE, MID_TL_STYLE},
+ { UNO_NAME_CHAR_OVERLINE_COLOR, RES_CHRATR_OVERLINE , cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE, MID_TL_COLOR},
+ { UNO_NAME_CHAR_OVERLINE_COMPLEX_COLOR, RES_CHRATR_OVERLINE, cppu::UnoType<css::util::XComplexColor>::get(), PROPERTY_NONE, MID_TL_COMPLEX_COLOR },
+ { UNO_NAME_CHAR_OVERLINE_HAS_COLOR, RES_CHRATR_OVERLINE , cppu::UnoType<bool>::get(), PROPERTY_NONE, MID_TL_HASCOLOR},
+ { UNO_NAME_CHAR_KERNING, RES_CHRATR_KERNING , cppu::UnoType<sal_Int16>::get() , PROPERTY_NONE, CONVERT_TWIPS},
+ { UNO_NAME_CHAR_NO_HYPHENATION, RES_CHRATR_NOHYPHEN , cppu::UnoType<bool>::get() , PROPERTY_NONE, 0},
+ { UNO_NAME_CHAR_SHADOWED, RES_CHRATR_SHADOWED , cppu::UnoType<bool>::get() , PROPERTY_NONE, 0},
+ { UNO_NAME_CHAR_CONTOURED, RES_CHRATR_CONTOUR, cppu::UnoType<bool>::get() , PROPERTY_NONE, 0},
+ { UNO_NAME_CHAR_WORD_MODE, RES_CHRATR_WORDLINEMODE,cppu::UnoType<bool>::get() , PROPERTY_NONE, 0},
+ { UNO_NAME_USER_DEFINED_ATTRIBUTES, RES_UNKNOWNATR_CONTAINER, cppu::UnoType<css::container::XNameContainer>::get(), PropertyAttribute::MAYBEVOID, 0 },
+ { UNO_NAME_TEXT_USER_DEFINED_ATTRIBUTES, RES_TXTATR_UNKNOWN_CONTAINER, cppu::UnoType<css::container::XNameContainer>::get(), PropertyAttribute::MAYBEVOID, 0 },
+ { UNO_NAME_IS_PHYSICAL, FN_UNO_IS_PHYSICAL, cppu::UnoType<bool>::get(), PropertyAttribute::READONLY, 0},
+ { UNO_NAME_DISPLAY_NAME, FN_UNO_DISPLAY_NAME, cppu::UnoType<OUString>::get(), PropertyAttribute::READONLY, 0},
+ { UNO_NAME_CHAR_COMBINE_IS_ON, RES_CHRATR_TWO_LINES, cppu::UnoType<bool>::get(), PROPERTY_NONE, MID_TWOLINES},
+ { UNO_NAME_CHAR_COMBINE_PREFIX, RES_CHRATR_TWO_LINES, cppu::UnoType<OUString>::get(), PROPERTY_NONE, MID_START_BRACKET},
+ { UNO_NAME_CHAR_COMBINE_SUFFIX, RES_CHRATR_TWO_LINES, cppu::UnoType<OUString>::get(), PROPERTY_NONE, MID_END_BRACKET},
+ { UNO_NAME_CHAR_EMPHASIS, RES_CHRATR_EMPHASIS_MARK, cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE, MID_EMPHASIS},
+ { UNO_NAME_CHAR_ROTATION, RES_CHRATR_ROTATE, cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE, MID_ROTATE },
+ { UNO_NAME_CHAR_ROTATION_IS_FIT_TO_LINE, RES_CHRATR_ROTATE, cppu::UnoType<bool>::get(), PROPERTY_NONE, MID_FITTOLINE },
+ { UNO_NAME_CHAR_SCALE_WIDTH, RES_CHRATR_SCALEW, cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE, 0 },
+ { UNO_NAME_CHAR_RELIEF, RES_CHRATR_RELIEF, cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE, MID_RELIEF },
+ { UNO_NAME_CHAR_AUTO_STYLE_NAME, RES_TXTATR_AUTOFMT, cppu::UnoType<OUString>::get(), PropertyAttribute::MAYBEVOID, 0},
+ { UNO_NAME_CHAR_SHADING_VALUE, RES_CHRATR_BACKGROUND, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE, MID_SHADING_VALUE },
+ { UNO_NAME_CHAR_LEFT_BORDER, RES_CHRATR_BOX, cppu::UnoType<css::table::BorderLine>::get(), PROPERTY_NONE, LEFT_BORDER |CONVERT_TWIPS },
+ { UNO_NAME_CHAR_RIGHT_BORDER, RES_CHRATR_BOX, cppu::UnoType<css::table::BorderLine>::get(), PROPERTY_NONE, RIGHT_BORDER |CONVERT_TWIPS },
+ { UNO_NAME_CHAR_TOP_BORDER, RES_CHRATR_BOX, cppu::UnoType<css::table::BorderLine>::get(), PROPERTY_NONE, TOP_BORDER |CONVERT_TWIPS },
+ { UNO_NAME_CHAR_BOTTOM_BORDER, RES_CHRATR_BOX, cppu::UnoType<css::table::BorderLine>::get(), PROPERTY_NONE, BOTTOM_BORDER |CONVERT_TWIPS },
+ { UNO_NAME_CHAR_BORDER_DISTANCE, RES_CHRATR_BOX, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE, BORDER_DISTANCE |CONVERT_TWIPS },
+ { UNO_NAME_CHAR_LEFT_BORDER_DISTANCE, RES_CHRATR_BOX, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE, LEFT_BORDER_DISTANCE |CONVERT_TWIPS },
+ { UNO_NAME_CHAR_RIGHT_BORDER_DISTANCE, RES_CHRATR_BOX, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE, RIGHT_BORDER_DISTANCE |CONVERT_TWIPS },
+ { UNO_NAME_CHAR_TOP_BORDER_DISTANCE, RES_CHRATR_BOX, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE, TOP_BORDER_DISTANCE |CONVERT_TWIPS },
+ { UNO_NAME_CHAR_BOTTOM_BORDER_DISTANCE, RES_CHRATR_BOX, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE, BOTTOM_BORDER_DISTANCE|CONVERT_TWIPS },
+ { UNO_NAME_CHAR_BORDER_LEFT_COMPLEX_COLOR, RES_CHRATR_BOX, cppu::UnoType<css::util::XComplexColor>::get(), PropertyAttribute::MAYBEVOID, MID_BORDER_LEFT_COLOR },
+ { UNO_NAME_CHAR_BORDER_RIGHT_COMPLEX_COLOR, RES_CHRATR_BOX, cppu::UnoType<css::util::XComplexColor>::get(), PropertyAttribute::MAYBEVOID, MID_BORDER_RIGHT_COLOR },
+ { UNO_NAME_CHAR_BORDER_TOP_COMPLEX_COLOR, RES_CHRATR_BOX, cppu::UnoType<css::util::XComplexColor>::get(), PropertyAttribute::MAYBEVOID, MID_BORDER_TOP_COLOR },
+ { UNO_NAME_CHAR_BORDER_BOTTOM_COMPLEX_COLOR, RES_CHRATR_BOX, cppu::UnoType<css::util::XComplexColor>::get(), PropertyAttribute::MAYBEVOID, MID_BORDER_BOTTOM_COLOR },
+ { UNO_NAME_CHAR_SHADOW_FORMAT, RES_CHRATR_SHADOW, cppu::UnoType<css::table::ShadowFormat>::get(), PROPERTY_NONE, CONVERT_TWIPS},
+ };
+
+ return aAutoCharStyleMap;
+}
+
+std::span<const SfxItemPropertyMapEntry> SwUnoPropertyMapProvider::GetParaStylePropertyMap()
+{
+ static SfxItemPropertyMapEntry const aParaStyleMap [] =
+ {
+ COMMON_PARA_STYLE_PROPERTIES
+ // added FillProperties for SW, same as FILL_PROPERTIES in svx
+ // but need own defines in Writer due to later association of strings
+ // and uno types (see loop at end of this method and definition of SW_PROP_NMID)
+ // This entry is for adding that properties to style import/export
+ // Added for paragraph backgrounds, this is for Paragraph Styles
+ FILL_PROPERTIES_SW
+ };
+
+ return aParaStyleMap;
+}
+
+std::span<const SfxItemPropertyMapEntry> SwUnoPropertyMapProvider::GetConditionalParaStylePropertyMap()
+{
+ static SfxItemPropertyMapEntry const aParaStyleMap [] =
+ {
+ COMMON_PARA_STYLE_PROPERTIES
+ { UNO_NAME_PARA_STYLE_CONDITIONS, FN_UNO_PARA_STYLE_CONDITIONS, cppu::UnoType< cppu::UnoSequenceType<css::beans::NamedValue> >::get(), PropertyAttribute::MAYBEVOID, 0},
+
+ // added FillProperties for SW, same as FILL_PROPERTIES in svx
+ // but need own defines in Writer due to later association of strings
+ // and uno types (see loop at end of this method and definition of SW_PROP_NMID)
+ // This entry is for adding that properties to style import/export
+ // Added for paragraph backgrounds, this is for Paragraph Styles
+ FILL_PROPERTIES_SW
+ };
+
+ return aParaStyleMap;
+}
+
+std::span<const SfxItemPropertyMapEntry> SwUnoPropertyMapProvider::GetFrameStylePropertyMap()
+{
+ static SfxItemPropertyMapEntry const aFrameStyleMap [] =
+ {
+ { UNO_NAME_ANCHOR_PAGE_NO, RES_ANCHOR, cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE, MID_ANCHOR_PAGENUM },
+ { UNO_NAME_ANCHOR_TYPE, RES_ANCHOR, cppu::UnoType<css::text::TextContentAnchorType>::get(), PROPERTY_NONE, MID_ANCHOR_ANCHORTYPE},
+ { UNO_NAME_BACK_COLOR, RES_BACKGROUND, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE ,MID_BACK_COLOR },
+ { UNO_NAME_BACKGROUND_COMPLEX_COLOR, RES_BACKGROUND, cppu::UnoType<css::util::XComplexColor>::get(), PROPERTY_NONE ,MID_BACKGROUND_COMPLEX_COLOR },
+ { UNO_NAME_BACK_COLOR_R_G_B, RES_BACKGROUND, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE ,MID_BACK_COLOR_R_G_B},
+ { UNO_NAME_BACK_COLOR_TRANSPARENCY, RES_BACKGROUND, cppu::UnoType<sal_Int8>::get(), PROPERTY_NONE ,MID_BACK_COLOR_TRANSPARENCY},
+ { UNO_NAME_FRAME_INTEROP_GRAB_BAG, RES_FRMATR_GRABBAG, cppu::UnoType< cppu::UnoSequenceType<css::beans::PropertyValue> >::get(), PROPERTY_NONE, 0},
+ // { UNO_NAME_CHAIN_NEXT_NAME, RES_CHAIN, cppu::UnoType<OUString>::get(), PROPERTY_NONE ,MID_CHAIN_NEXTNAME},
+ // { UNO_NAME_CHAIN_PREV_NAME, RES_CHAIN, cppu::UnoType<OUString>::get(), PROPERTY_NONE ,MID_CHAIN_PREVNAME},
+ /*not impl*/ { UNO_NAME_CLIENT_MAP, RES_URL, cppu::UnoType<bool>::get(), PROPERTY_NONE ,MID_URL_CLIENTMAP },
+ { UNO_NAME_CONTENT_PROTECTED, RES_PROTECT, cppu::UnoType<bool>::get(), PROPERTY_NONE, MID_PROTECT_CONTENT },
+ { UNO_NAME_EDIT_IN_READONLY, RES_EDIT_IN_READONLY, cppu::UnoType<bool>::get(), PROPERTY_NONE, 0},
+ { UNO_NAME_BACK_GRAPHIC_URL, RES_BACKGROUND, cppu::UnoType<OUString>::get(), PROPERTY_NONE ,MID_GRAPHIC_URL },
+ { UNO_NAME_BACK_GRAPHIC, RES_BACKGROUND, cppu::UnoType<graphic::XGraphic>::get(), PROPERTY_NONE, MID_GRAPHIC },
+ { UNO_NAME_BACK_GRAPHIC_FILTER, RES_BACKGROUND, cppu::UnoType<OUString>::get(), PROPERTY_NONE ,MID_GRAPHIC_FILTER },
+ { UNO_NAME_BACK_GRAPHIC_LOCATION, RES_BACKGROUND, cppu::UnoType<css::style::GraphicLocation>::get(), PROPERTY_NONE ,MID_GRAPHIC_POSITION},
+ // #i50322# - add missing map entry for transparency of graphic background
+ { UNO_NAME_BACK_GRAPHIC_TRANSPARENCY, RES_BACKGROUND, cppu::UnoType<sal_Int8>::get(), PROPERTY_NONE ,MID_GRAPHIC_TRANSPARENCY},
+ { UNO_NAME_LEFT_MARGIN, RES_LR_SPACE, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE, MID_L_MARGIN|CONVERT_TWIPS},
+ { UNO_NAME_RIGHT_MARGIN, RES_LR_SPACE, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE, MID_R_MARGIN|CONVERT_TWIPS},
+ { UNO_NAME_HORI_ORIENT, RES_HORI_ORIENT, cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE ,MID_HORIORIENT_ORIENT },
+ { UNO_NAME_HORI_ORIENT_POSITION, RES_HORI_ORIENT, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE ,MID_HORIORIENT_POSITION|CONVERT_TWIPS },
+ { UNO_NAME_HORI_ORIENT_RELATION, RES_HORI_ORIENT, cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE ,MID_HORIORIENT_RELATION },
+ { UNO_NAME_HYPER_LINK_U_R_L, RES_URL, cppu::UnoType<OUString>::get(), PROPERTY_NONE ,MID_URL_URL},
+ { UNO_NAME_HYPER_LINK_TARGET, RES_URL, cppu::UnoType<OUString>::get(), PROPERTY_NONE ,MID_URL_TARGET},
+ { UNO_NAME_HYPER_LINK_NAME, RES_URL, cppu::UnoType<OUString>::get(), PROPERTY_NONE ,MID_URL_HYPERLINKNAME },
+ { UNO_NAME_OPAQUE, RES_OPAQUE, cppu::UnoType<bool>::get(), PROPERTY_NONE, 0},
+ { UNO_NAME_PAGE_TOGGLE, RES_HORI_ORIENT, cppu::UnoType<bool>::get(), PROPERTY_NONE ,MID_HORIORIENT_PAGETOGGLE },
+ { UNO_NAME_POSITION_PROTECTED, RES_PROTECT, cppu::UnoType<bool>::get(), PROPERTY_NONE, MID_PROTECT_POSITION},
+ { UNO_NAME_PRINT, RES_PRINT, cppu::UnoType<bool>::get(), PROPERTY_NONE, 0},
+ { UNO_NAME_WIDTH, RES_FRM_SIZE, cppu::UnoType<sal_Int32>::get() , PROPERTY_NONE, MID_FRMSIZE_WIDTH|CONVERT_TWIPS },
+ { UNO_NAME_HEIGHT, RES_FRM_SIZE, cppu::UnoType<sal_Int32>::get() , PROPERTY_NONE, MID_FRMSIZE_HEIGHT|CONVERT_TWIPS },
+ { UNO_NAME_RELATIVE_HEIGHT, RES_FRM_SIZE, cppu::UnoType<sal_Int16>::get() , PROPERTY_NONE, MID_FRMSIZE_REL_HEIGHT },
+ { UNO_NAME_RELATIVE_HEIGHT_RELATION, RES_FRM_SIZE, cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE, MID_FRMSIZE_REL_HEIGHT_RELATION },
+ { UNO_NAME_RELATIVE_WIDTH, RES_FRM_SIZE, cppu::UnoType<sal_Int16>::get() , PROPERTY_NONE, MID_FRMSIZE_REL_WIDTH },
+ { UNO_NAME_RELATIVE_WIDTH_RELATION, RES_FRM_SIZE, cppu::UnoType<sal_Int16>::get() , PROPERTY_NONE, MID_FRMSIZE_REL_WIDTH_RELATION },
+ { UNO_NAME_SIZE_TYPE, RES_FRM_SIZE, cppu::UnoType<sal_Int16>::get() , PROPERTY_NONE, MID_FRMSIZE_SIZE_TYPE },
+ { UNO_NAME_WIDTH_TYPE, RES_FRM_SIZE, cppu::UnoType<sal_Int16>::get() , PROPERTY_NONE, MID_FRMSIZE_WIDTH_TYPE },
+ { UNO_NAME_SIZE, RES_FRM_SIZE, cppu::UnoType<css::awt::Size>::get(), PROPERTY_NONE, MID_FRMSIZE_SIZE|CONVERT_TWIPS},
+ { UNO_NAME_IS_SYNC_WIDTH_TO_HEIGHT, RES_FRM_SIZE, cppu::UnoType<bool>::get() , PROPERTY_NONE, MID_FRMSIZE_IS_SYNC_WIDTH_TO_HEIGHT },
+ { UNO_NAME_IS_SYNC_HEIGHT_TO_WIDTH, RES_FRM_SIZE, cppu::UnoType<bool>::get() , PROPERTY_NONE, MID_FRMSIZE_IS_SYNC_HEIGHT_TO_WIDTH },
+ // { UNO_NAME_WIDTH, RES_FRM_SIZE, cppu::UnoType<sal_Int32>::get() , PROPERTY_NONE, MID_FRMSIZE_WIDTH },
+ { UNO_NAME_SHADOW_FORMAT, RES_SHADOW, cppu::UnoType<css::table::ShadowFormat>::get(), PROPERTY_NONE, CONVERT_TWIPS},
+ { UNO_NAME_SHADOW_TRANSPARENCE, RES_SHADOW, cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE, MID_SHADOW_TRANSPARENCE},
+ { UNO_NAME_SERVER_MAP, RES_URL, cppu::UnoType<bool>::get(), PROPERTY_NONE ,MID_URL_SERVERMAP },
+ { UNO_NAME_SIZE_PROTECTED, RES_PROTECT, cppu::UnoType<bool>::get(), PROPERTY_NONE, MID_PROTECT_SIZE },
+ // We keep Surround, as we delivered it with 5.1, although it's identical to text::WrapTextMode
+ { UNO_NAME_SURROUND, RES_SURROUND, cppu::UnoType<css::text::WrapTextMode>::get(), PROPERTY_NONE, MID_SURROUND_SURROUNDTYPE },
+ { UNO_NAME_TEXT_WRAP, RES_SURROUND, cppu::UnoType<css::text::WrapTextMode>::get(), PROPERTY_NONE, MID_SURROUND_SURROUNDTYPE },
+ { UNO_NAME_SURROUND_ANCHORONLY, RES_SURROUND, cppu::UnoType<bool>::get(), PROPERTY_NONE, MID_SURROUND_ANCHORONLY },
+ { UNO_NAME_SURROUND_CONTOUR, RES_SURROUND, cppu::UnoType<bool>::get(), PROPERTY_NONE, MID_SURROUND_CONTOUR },
+ { UNO_NAME_CONTOUR_OUTSIDE, RES_SURROUND, cppu::UnoType<bool>::get(), PROPERTY_NONE, MID_SURROUND_CONTOUROUTSIDE },
+ { UNO_NAME_TEXT_COLUMNS, RES_COL, cppu::UnoType<css::text::XTextColumns>::get(), PROPERTY_NONE, MID_COLUMNS},
+ { UNO_NAME_TOP_MARGIN, RES_UL_SPACE, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE, MID_UP_MARGIN|CONVERT_TWIPS},
+ { UNO_NAME_BOTTOM_MARGIN, RES_UL_SPACE, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE, MID_LO_MARGIN|CONVERT_TWIPS},
+ { UNO_NAME_BACK_TRANSPARENT, RES_BACKGROUND, cppu::UnoType<bool>::get(), PROPERTY_NONE ,MID_GRAPHIC_TRANSPARENT },
+ { UNO_NAME_VERT_ORIENT, RES_VERT_ORIENT, cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE ,MID_VERTORIENT_ORIENT },
+ { UNO_NAME_VERT_ORIENT_POSITION, RES_VERT_ORIENT, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE ,MID_VERTORIENT_POSITION|CONVERT_TWIPS },
+ { UNO_NAME_VERT_ORIENT_RELATION, RES_VERT_ORIENT, cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE ,MID_VERTORIENT_RELATION },
+ { UNO_NAME_LEFT_BORDER, RES_BOX, cppu::UnoType<css::table::BorderLine>::get(), 0, LEFT_BORDER |CONVERT_TWIPS },
+ { UNO_NAME_RIGHT_BORDER, RES_BOX, cppu::UnoType<css::table::BorderLine>::get(), 0, RIGHT_BORDER |CONVERT_TWIPS },
+ { UNO_NAME_TOP_BORDER, RES_BOX, cppu::UnoType<css::table::BorderLine>::get(), 0, TOP_BORDER |CONVERT_TWIPS },
+ { UNO_NAME_BOTTOM_BORDER, RES_BOX, cppu::UnoType<css::table::BorderLine>::get(), 0, BOTTOM_BORDER|CONVERT_TWIPS },
+ { UNO_NAME_BORDER_DISTANCE, RES_BOX, cppu::UnoType<sal_Int32>::get(), 0, BORDER_DISTANCE|CONVERT_TWIPS },
+ { UNO_NAME_LEFT_BORDER_DISTANCE, RES_BOX, cppu::UnoType<sal_Int32>::get(), 0, LEFT_BORDER_DISTANCE |CONVERT_TWIPS },
+ { UNO_NAME_RIGHT_BORDER_DISTANCE, RES_BOX, cppu::UnoType<sal_Int32>::get(), 0, RIGHT_BORDER_DISTANCE |CONVERT_TWIPS },
+ { UNO_NAME_TOP_BORDER_DISTANCE, RES_BOX, cppu::UnoType<sal_Int32>::get(), 0, TOP_BORDER_DISTANCE |CONVERT_TWIPS },
+ { UNO_NAME_BOTTOM_BORDER_DISTANCE, RES_BOX, cppu::UnoType<sal_Int32>::get(), 0, BOTTOM_BORDER_DISTANCE|CONVERT_TWIPS },
+ { UNO_NAME_BORDER_LEFT_COMPLEX_COLOR, RES_BOX, cppu::UnoType<css::util::XComplexColor>::get(), 0, MID_BORDER_LEFT_COLOR },
+ { UNO_NAME_BORDER_RIGHT_COMPLEX_COLOR, RES_BOX, cppu::UnoType<css::util::XComplexColor>::get(), 0, MID_BORDER_RIGHT_COLOR },
+ { UNO_NAME_BORDER_TOP_COMPLEX_COLOR, RES_BOX, cppu::UnoType<css::util::XComplexColor>::get(), 0, MID_BORDER_TOP_COLOR },
+ { UNO_NAME_BORDER_BOTTOM_COMPLEX_COLOR, RES_BOX, cppu::UnoType<css::util::XComplexColor>::get(), 0, MID_BORDER_BOTTOM_COLOR },
+ { UNO_NAME_USER_DEFINED_ATTRIBUTES, RES_UNKNOWNATR_CONTAINER, cppu::UnoType<css::container::XNameContainer>::get(), PropertyAttribute::MAYBEVOID, 0 },
+ { UNO_NAME_IS_PHYSICAL, FN_UNO_IS_PHYSICAL, cppu::UnoType<bool>::get(), PropertyAttribute::READONLY, 0},
+ { UNO_NAME_IS_AUTO_UPDATE, FN_UNO_IS_AUTO_UPDATE, cppu::UnoType<bool>::get(), PROPERTY_NONE, 0},
+ { UNO_NAME_DISPLAY_NAME, FN_UNO_DISPLAY_NAME, cppu::UnoType<OUString>::get(), PropertyAttribute::READONLY, 0},
+ // #i18732#
+ { UNO_NAME_IS_FOLLOWING_TEXT_FLOW, RES_FOLLOW_TEXT_FLOW, cppu::UnoType<bool>::get(), PROPERTY_NONE, MID_FOLLOW_TEXT_FLOW},
+ // #i28701#
+ { UNO_NAME_WRAP_INFLUENCE_ON_POSITION, RES_WRAP_INFLUENCE_ON_OBJPOS, cppu::UnoType<sal_Int8>::get(), PROPERTY_NONE, MID_WRAP_INFLUENCE},
+ { UNO_NAME_ALLOW_OVERLAP, RES_WRAP_INFLUENCE_ON_OBJPOS, cppu::UnoType<bool>::get(), PROPERTY_NONE, MID_ALLOW_OVERLAP},
+ { UNO_NAME_WRITING_MODE, RES_FRAMEDIR, cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE, 0 },
+ { UNO_NAME_HIDDEN, FN_UNO_HIDDEN, cppu::UnoType<bool>::get(), PROPERTY_NONE, 0},
+ { u"Decorative"_ustr, RES_DECORATIVE, cppu::UnoType<bool>::get(), PROPERTY_NONE, 0 },
+ { UNO_NAME_TEXT_VERT_ADJUST, RES_TEXT_VERT_ADJUST, cppu::UnoType<css::drawing::TextVerticalAdjust>::get(), PROPERTY_NONE ,0},
+
+ // added FillProperties for SW, same as FILL_PROPERTIES in svx
+ // but need own defines in Writer due to later association of strings
+ // and uno types (see loop at end of this method and definition of SW_PROP_NMID)
+ // This entry is for adding that properties to style import/export
+ FILL_PROPERTIES_SW
+ };
+
+ return aFrameStyleMap;
+}
+
+std::span<const SfxItemPropertyMapEntry> SwUnoPropertyMapProvider::GetPageStylePropertyMap()
+{
+ static SfxItemPropertyMapEntry const aPageStyleMap [] =
+ {
+ { UNO_NAME_BACK_COLOR, RES_BACKGROUND, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE, MID_BACK_COLOR },
+ { UNO_NAME_BACKGROUND_COMPLEX_COLOR, RES_BACKGROUND, cppu::UnoType<css::util::XComplexColor>::get(), PROPERTY_NONE, MID_BACKGROUND_COMPLEX_COLOR },
+ { UNO_NAME_BACK_GRAPHIC_URL, RES_BACKGROUND, cppu::UnoType<OUString>::get(), PROPERTY_NONE ,MID_GRAPHIC_URL },
+ { UNO_NAME_BACK_GRAPHIC, RES_BACKGROUND, cppu::UnoType<graphic::XGraphic>::get(), PROPERTY_NONE, MID_GRAPHIC },
+ { UNO_NAME_BACK_GRAPHIC_FILTER, RES_BACKGROUND, cppu::UnoType<OUString>::get(), PROPERTY_NONE ,MID_GRAPHIC_FILTER },
+ { UNO_NAME_BACK_GRAPHIC_LOCATION, RES_BACKGROUND, cppu::UnoType<css::style::GraphicLocation>::get(), PROPERTY_NONE ,MID_GRAPHIC_POSITION},
+ { UNO_NAME_LEFT_MARGIN, RES_LR_SPACE, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE, MID_L_MARGIN|CONVERT_TWIPS},
+ { UNO_NAME_RIGHT_MARGIN, RES_LR_SPACE, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE, MID_R_MARGIN|CONVERT_TWIPS},
+ { UNO_NAME_GUTTER_MARGIN, RES_LR_SPACE, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE, MID_GUTTER_MARGIN | CONVERT_TWIPS},
+ { UNO_NAME_BACK_TRANSPARENT, RES_BACKGROUND, cppu::UnoType<bool>::get(), PROPERTY_NONE ,MID_GRAPHIC_TRANSPARENT },
+ { UNO_NAME_LEFT_BORDER, RES_BOX, cppu::UnoType<css::table::BorderLine>::get(), 0, LEFT_BORDER |CONVERT_TWIPS },
+ { UNO_NAME_RIGHT_BORDER, RES_BOX, cppu::UnoType<css::table::BorderLine>::get(), 0, RIGHT_BORDER |CONVERT_TWIPS },
+ { UNO_NAME_TOP_BORDER, RES_BOX, cppu::UnoType<css::table::BorderLine>::get(), 0, TOP_BORDER |CONVERT_TWIPS },
+ { UNO_NAME_BOTTOM_BORDER, RES_BOX, cppu::UnoType<css::table::BorderLine>::get(), 0, BOTTOM_BORDER|CONVERT_TWIPS },
+ { UNO_NAME_BORDER_DISTANCE, RES_BOX, cppu::UnoType<sal_Int32>::get(), 0, BORDER_DISTANCE|CONVERT_TWIPS },
+ { UNO_NAME_LEFT_BORDER_DISTANCE, RES_BOX, cppu::UnoType<sal_Int32>::get(), 0, LEFT_BORDER_DISTANCE |CONVERT_TWIPS },
+ { UNO_NAME_RIGHT_BORDER_DISTANCE, RES_BOX, cppu::UnoType<sal_Int32>::get(), 0, RIGHT_BORDER_DISTANCE |CONVERT_TWIPS },
+ { UNO_NAME_TOP_BORDER_DISTANCE, RES_BOX, cppu::UnoType<sal_Int32>::get(), 0, TOP_BORDER_DISTANCE |CONVERT_TWIPS },
+ { UNO_NAME_BOTTOM_BORDER_DISTANCE, RES_BOX, cppu::UnoType<sal_Int32>::get(), 0, BOTTOM_BORDER_DISTANCE|CONVERT_TWIPS },
+ { UNO_NAME_BORDER_LEFT_COMPLEX_COLOR, RES_BOX, cppu::UnoType<css::util::XComplexColor>::get(), 0, MID_BORDER_LEFT_COLOR },
+ { UNO_NAME_BORDER_RIGHT_COMPLEX_COLOR, RES_BOX, cppu::UnoType<css::util::XComplexColor>::get(), 0, MID_BORDER_RIGHT_COLOR },
+ { UNO_NAME_BORDER_TOP_COMPLEX_COLOR, RES_BOX, cppu::UnoType<css::util::XComplexColor>::get(), 0, MID_BORDER_TOP_COLOR },
+ { UNO_NAME_BORDER_BOTTOM_COMPLEX_COLOR, RES_BOX, cppu::UnoType<css::util::XComplexColor>::get(), 0, MID_BORDER_BOTTOM_COLOR },
+ { UNO_NAME_SHADOW_FORMAT, RES_SHADOW, cppu::UnoType<css::table::ShadowFormat>::get(), PROPERTY_NONE, CONVERT_TWIPS},
+ { UNO_NAME_SHADOW_TRANSPARENCE, RES_SHADOW, cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE, MID_SHADOW_TRANSPARENCE},
+
+ //UUU use real WhichIDs for Header, no longer use extra-defined WhichIDs which make handling harder as needed.
+ // The implementation will decide if these are part of Header/Footer or PageStyle depending on the SlotName,
+ // more precisely on the first characters. Thus it is necessary that these are 'Header' for the Header slots
+ { UNO_NAME_HEADER_BACK_COLOR, RES_BACKGROUND, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE ,MID_BACK_COLOR },
+ { UNO_NAME_HEADER_GRAPHIC_URL, RES_BACKGROUND, cppu::UnoType<OUString>::get(), PROPERTY_NONE ,MID_GRAPHIC_URL },
+ { UNO_NAME_HEADER_GRAPHIC, RES_BACKGROUND, cppu::UnoType<graphic::XGraphic>::get(), PROPERTY_NONE, MID_GRAPHIC },
+ { UNO_NAME_HEADER_GRAPHIC_FILTER, RES_BACKGROUND, cppu::UnoType<OUString>::get(), PROPERTY_NONE ,MID_GRAPHIC_FILTER },
+ { UNO_NAME_HEADER_GRAPHIC_LOCATION, RES_BACKGROUND, cppu::UnoType<css::style::GraphicLocation>::get(), PROPERTY_NONE ,MID_GRAPHIC_POSITION},
+ { UNO_NAME_HEADER_LEFT_MARGIN, RES_LR_SPACE, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE, MID_L_MARGIN|CONVERT_TWIPS},
+ { UNO_NAME_HEADER_RIGHT_MARGIN, RES_LR_SPACE, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE, MID_R_MARGIN|CONVERT_TWIPS},
+ { UNO_NAME_HEADER_BACK_TRANSPARENT, RES_BACKGROUND, cppu::UnoType<bool>::get(), PROPERTY_NONE ,MID_GRAPHIC_TRANSPARENT },
+ { UNO_NAME_HEADER_LEFT_BORDER, RES_BOX, cppu::UnoType<css::table::BorderLine>::get(), 0, LEFT_BORDER |CONVERT_TWIPS },
+ { UNO_NAME_HEADER_RIGHT_BORDER, RES_BOX, cppu::UnoType<css::table::BorderLine>::get(), 0, RIGHT_BORDER |CONVERT_TWIPS },
+ { UNO_NAME_HEADER_TOP_BORDER, RES_BOX, cppu::UnoType<css::table::BorderLine>::get(), 0, TOP_BORDER |CONVERT_TWIPS },
+ { UNO_NAME_HEADER_BOTTOM_BORDER, RES_BOX, cppu::UnoType<css::table::BorderLine>::get(), 0, BOTTOM_BORDER|CONVERT_TWIPS },
+ { UNO_NAME_HEADER_BORDER_DISTANCE, RES_BOX, cppu::UnoType<sal_Int32>::get(), PropertyAttribute::MAYBEVOID, BORDER_DISTANCE|CONVERT_TWIPS },
+ { UNO_NAME_HEADER_LEFT_BORDER_DISTANCE, RES_BOX, cppu::UnoType<sal_Int32>::get(), 0, LEFT_BORDER_DISTANCE |CONVERT_TWIPS },
+ { UNO_NAME_HEADER_RIGHT_BORDER_DISTANCE, RES_BOX, cppu::UnoType<sal_Int32>::get(), 0, RIGHT_BORDER_DISTANCE |CONVERT_TWIPS },
+ { UNO_NAME_HEADER_TOP_BORDER_DISTANCE, RES_BOX, cppu::UnoType<sal_Int32>::get(), 0, TOP_BORDER_DISTANCE |CONVERT_TWIPS },
+ { UNO_NAME_HEADER_BOTTOM_BORDER_DISTANCE, RES_BOX, cppu::UnoType<sal_Int32>::get(), 0, BOTTOM_BORDER_DISTANCE|CONVERT_TWIPS },
+ { UNO_NAME_HEADER_SHADOW_FORMAT, RES_SHADOW, cppu::UnoType<css::table::ShadowFormat>::get(), PROPERTY_NONE, CONVERT_TWIPS},
+ { UNO_NAME_HEADER_BODY_DISTANCE, RES_UL_SPACE, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE ,MID_LO_MARGIN|CONVERT_TWIPS },
+ { UNO_NAME_HEADER_IS_DYNAMIC_HEIGHT, SID_ATTR_PAGE_DYNAMIC, cppu::UnoType<bool>::get(), PROPERTY_NONE ,0 },
+ { UNO_NAME_HEADER_IS_SHARED, SID_ATTR_PAGE_SHARED, cppu::UnoType<bool>::get(), PROPERTY_NONE ,0 },
+ { UNO_NAME_HEADER_HEIGHT, SID_ATTR_PAGE_SIZE, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE ,MID_SIZE_HEIGHT|CONVERT_TWIPS },
+ { UNO_NAME_HEADER_IS_ON, SID_ATTR_PAGE_ON, cppu::UnoType<bool>::get(), PROPERTY_NONE ,0 },
+ { UNO_NAME_HEADER_DYNAMIC_SPACING, RES_HEADER_FOOTER_EAT_SPACING, cppu::UnoType<bool>::get(), PropertyAttribute::MAYBEVOID ,0 },
+
+
+ { UNO_NAME_FIRST_IS_SHARED, SID_ATTR_PAGE_SHARED_FIRST, cppu::UnoType<bool>::get(), PROPERTY_NONE, 0 },
+
+ //UUU use real WhichIDs for Footer, see Header (above) for more infos
+ { UNO_NAME_FOOTER_BACK_COLOR, RES_BACKGROUND, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE ,MID_BACK_COLOR },
+ { UNO_NAME_FOOTER_GRAPHIC_URL, RES_BACKGROUND, cppu::UnoType<OUString>::get(), PROPERTY_NONE ,MID_GRAPHIC_URL },
+ { UNO_NAME_FOOTER_GRAPHIC, RES_BACKGROUND, cppu::UnoType<graphic::XGraphic>::get(), PROPERTY_NONE, MID_GRAPHIC },
+ { UNO_NAME_FOOTER_GRAPHIC_FILTER, RES_BACKGROUND, cppu::UnoType<OUString>::get(), PROPERTY_NONE ,MID_GRAPHIC_FILTER },
+ { UNO_NAME_FOOTER_GRAPHIC_LOCATION, RES_BACKGROUND, cppu::UnoType<css::style::GraphicLocation>::get(), PROPERTY_NONE ,MID_GRAPHIC_POSITION},
+ { UNO_NAME_FOOTER_LEFT_MARGIN, RES_LR_SPACE, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE, MID_L_MARGIN|CONVERT_TWIPS},
+ { UNO_NAME_FOOTER_RIGHT_MARGIN, RES_LR_SPACE, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE, MID_R_MARGIN|CONVERT_TWIPS},
+ { UNO_NAME_FOOTER_BACK_TRANSPARENT, RES_BACKGROUND, cppu::UnoType<bool>::get(), PROPERTY_NONE ,MID_GRAPHIC_TRANSPARENT },
+ { UNO_NAME_FOOTER_LEFT_BORDER, RES_BOX, cppu::UnoType<css::table::BorderLine>::get(), 0, LEFT_BORDER |CONVERT_TWIPS },
+ { UNO_NAME_FOOTER_RIGHT_BORDER, RES_BOX, cppu::UnoType<css::table::BorderLine>::get(), 0, RIGHT_BORDER |CONVERT_TWIPS },
+ { UNO_NAME_FOOTER_TOP_BORDER, RES_BOX, cppu::UnoType<css::table::BorderLine>::get(), 0, TOP_BORDER |CONVERT_TWIPS },
+ { UNO_NAME_FOOTER_BOTTOM_BORDER, RES_BOX, cppu::UnoType<css::table::BorderLine>::get(), 0, BOTTOM_BORDER|CONVERT_TWIPS },
+ { UNO_NAME_FOOTER_BORDER_DISTANCE, RES_BOX, cppu::UnoType<sal_Int32>::get(), PropertyAttribute::MAYBEVOID, BORDER_DISTANCE|CONVERT_TWIPS },
+ { UNO_NAME_FOOTER_LEFT_BORDER_DISTANCE, RES_BOX, cppu::UnoType<sal_Int32>::get(), 0, LEFT_BORDER_DISTANCE |CONVERT_TWIPS },
+ { UNO_NAME_FOOTER_RIGHT_BORDER_DISTANCE, RES_BOX, cppu::UnoType<sal_Int32>::get(), 0, RIGHT_BORDER_DISTANCE |CONVERT_TWIPS },
+ { UNO_NAME_FOOTER_TOP_BORDER_DISTANCE, RES_BOX, cppu::UnoType<sal_Int32>::get(), 0, TOP_BORDER_DISTANCE |CONVERT_TWIPS },
+ { UNO_NAME_FOOTER_BOTTOM_BORDER_DISTANCE, RES_BOX, cppu::UnoType<sal_Int32>::get(), 0, BOTTOM_BORDER_DISTANCE|CONVERT_TWIPS },
+ { UNO_NAME_FOOTER_SHADOW_FORMAT, RES_SHADOW, cppu::UnoType<css::table::ShadowFormat>::get(), PROPERTY_NONE, CONVERT_TWIPS},
+ { UNO_NAME_FOOTER_BODY_DISTANCE, RES_UL_SPACE, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE ,MID_UP_MARGIN|CONVERT_TWIPS },
+ { UNO_NAME_FOOTER_IS_DYNAMIC_HEIGHT, SID_ATTR_PAGE_DYNAMIC, cppu::UnoType<bool>::get(), PROPERTY_NONE ,0 },
+ { UNO_NAME_FOOTER_IS_SHARED, SID_ATTR_PAGE_SHARED, cppu::UnoType<bool>::get(), PROPERTY_NONE ,0 },
+ { UNO_NAME_FOOTER_HEIGHT, SID_ATTR_PAGE_SIZE, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE ,MID_SIZE_HEIGHT|CONVERT_TWIPS },
+ { UNO_NAME_FOOTER_IS_ON, SID_ATTR_PAGE_ON, cppu::UnoType<bool>::get(), PROPERTY_NONE ,0 },
+ { UNO_NAME_FOOTER_DYNAMIC_SPACING, RES_HEADER_FOOTER_EAT_SPACING, cppu::UnoType<bool>::get(), PropertyAttribute::MAYBEVOID ,0 },
+
+ { UNO_NAME_IS_LANDSCAPE, SID_ATTR_PAGE, cppu::UnoType<bool>::get(), PROPERTY_NONE ,MID_PAGE_ORIENTATION },
+ { UNO_NAME_NUMBERING_TYPE, SID_ATTR_PAGE, cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE , MID_PAGE_NUMTYPE },
+ { UNO_NAME_PAGE_STYLE_LAYOUT, SID_ATTR_PAGE, cppu::UnoType<css::style::PageStyleLayout>::get(), PROPERTY_NONE ,MID_PAGE_LAYOUT },
+ { UNO_NAME_PRINTER_PAPER_TRAY, RES_PAPER_BIN, cppu::UnoType<OUString>::get(), PROPERTY_NONE , 0 },
+// { UNO_NAME_REGISTER_MODE_ACTIVE, SID_SWREGISTER_MODE, cppu::UnoType<bool>::get(), PROPERTY_NONE , 0 },
+ { UNO_NAME_REGISTER_PARAGRAPH_STYLE, SID_SWREGISTER_COLLECTION, cppu::UnoType<OUString>::get(), PROPERTY_NONE , 0 },
+ { UNO_NAME_SIZE, SID_ATTR_PAGE_SIZE, cppu::UnoType<css::awt::Size>::get(), PROPERTY_NONE, MID_SIZE_SIZE|CONVERT_TWIPS},
+ { UNO_NAME_WIDTH, SID_ATTR_PAGE_SIZE, cppu::UnoType<sal_Int32>::get() , PROPERTY_NONE, MID_SIZE_WIDTH|CONVERT_TWIPS},
+ { UNO_NAME_HEIGHT, SID_ATTR_PAGE_SIZE, cppu::UnoType<sal_Int32>::get() , PROPERTY_NONE, MID_SIZE_HEIGHT|CONVERT_TWIPS },
+ { UNO_NAME_TEXT_VERT_ADJUST, RES_TEXT_VERT_ADJUST, cppu::UnoType<css::drawing::TextVerticalAdjust>::get(), PROPERTY_NONE, 0 },
+ { UNO_NAME_TEXT_COLUMNS, RES_COL, cppu::UnoType<css::text::XTextColumns>::get(), PROPERTY_NONE, MID_COLUMNS},
+ { UNO_NAME_TOP_MARGIN, RES_UL_SPACE, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE, MID_UP_MARGIN|CONVERT_TWIPS},
+ { UNO_NAME_BOTTOM_MARGIN, RES_UL_SPACE, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE, MID_LO_MARGIN|CONVERT_TWIPS},
+ { UNO_NAME_HEADER_TEXT, FN_UNO_HEADER, cppu::UnoType<css::text::XText>::get(), PropertyAttribute::MAYBEVOID|PropertyAttribute::READONLY, 0},
+ { UNO_NAME_HEADER_TEXT_LEFT, FN_UNO_HEADER_LEFT, cppu::UnoType<css::text::XText>::get(), PropertyAttribute::MAYBEVOID|PropertyAttribute::READONLY, 0},
+ { UNO_NAME_HEADER_TEXT_RIGHT, FN_UNO_HEADER_RIGHT, cppu::UnoType<css::text::XText>::get(), PropertyAttribute::MAYBEVOID|PropertyAttribute::READONLY, 0},
+ { UNO_NAME_HEADER_TEXT_FIRST, FN_UNO_HEADER_FIRST, cppu::UnoType<css::text::XText>::get(), PropertyAttribute::MAYBEVOID|PropertyAttribute::READONLY, 0},
+ { UNO_NAME_FOOTER_TEXT, FN_UNO_FOOTER, cppu::UnoType<css::text::XText>::get(), PropertyAttribute::MAYBEVOID|PropertyAttribute::READONLY, 0},
+ { UNO_NAME_FOOTER_TEXT_LEFT, FN_UNO_FOOTER_LEFT, cppu::UnoType<css::text::XText>::get(), PropertyAttribute::MAYBEVOID|PropertyAttribute::READONLY, 0},
+ { UNO_NAME_FOOTER_TEXT_RIGHT, FN_UNO_FOOTER_RIGHT, cppu::UnoType<css::text::XText>::get(), PropertyAttribute::MAYBEVOID|PropertyAttribute::READONLY, 0},
+ { UNO_NAME_FOOTER_TEXT_FIRST, FN_UNO_FOOTER_FIRST, cppu::UnoType<css::text::XText>::get(), PropertyAttribute::MAYBEVOID|PropertyAttribute::READONLY, 0},
+ { UNO_NAME_FOLLOW_STYLE, FN_UNO_FOLLOW_STYLE, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ { UNO_NAME_USER_DEFINED_ATTRIBUTES, RES_UNKNOWNATR_CONTAINER, cppu::UnoType<css::container::XNameContainer>::get(), PropertyAttribute::MAYBEVOID, 0 },
+ { UNO_NAME_IS_PHYSICAL, FN_UNO_IS_PHYSICAL, cppu::UnoType<bool>::get(), PropertyAttribute::READONLY, 0},
+ { UNO_NAME_DISPLAY_NAME, FN_UNO_DISPLAY_NAME, cppu::UnoType<OUString>::get(), PropertyAttribute::READONLY, 0},
+ { UNO_NAME_FOOTNOTE_HEIGHT, FN_PARAM_FTN_INFO, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE , MID_FTN_HEIGHT|CONVERT_TWIPS},
+ { UNO_NAME_FOOTNOTE_LINE_WEIGHT, FN_PARAM_FTN_INFO, cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE , MID_LINE_WEIGHT|CONVERT_TWIPS},
+ { UNO_NAME_FOOTNOTE_LINE_COLOR, FN_PARAM_FTN_INFO, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE , MID_LINE_COLOR},
+ { UNO_NAME_FOOTNOTE_LINE_STYLE, FN_PARAM_FTN_INFO, cppu::UnoType<sal_Int8>::get(), PROPERTY_NONE , MID_FTN_LINE_STYLE},
+ { UNO_NAME_FOOTNOTE_LINE_RELATIVE_WIDTH, FN_PARAM_FTN_INFO, cppu::UnoType<sal_Int8>::get(), PROPERTY_NONE , MID_LINE_RELWIDTH },
+ { UNO_NAME_FOOTNOTE_LINE_ADJUST, FN_PARAM_FTN_INFO, cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE , MID_LINE_ADJUST },
+ { UNO_NAME_FOOTNOTE_LINE_TEXT_DISTANCE, FN_PARAM_FTN_INFO, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE , MID_LINE_TEXT_DIST |CONVERT_TWIPS },
+ { UNO_NAME_FOOTNOTE_LINE_DISTANCE, FN_PARAM_FTN_INFO, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE , MID_LINE_FOOTNOTE_DIST|CONVERT_TWIPS},
+ { UNO_NAME_WRITING_MODE, RES_FRAMEDIR, cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE, 0 },
+ // writing grid
+ { UNO_NAME_GRID_COLOR, RES_TEXTGRID, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE, MID_GRID_COLOR},
+ { UNO_NAME_GRID_LINES, RES_TEXTGRID, cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE, MID_GRID_LINES},
+ { UNO_NAME_GRID_BASE_HEIGHT, RES_TEXTGRID, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE, MID_GRID_BASEHEIGHT|CONVERT_TWIPS},
+ { UNO_NAME_GRID_RUBY_HEIGHT, RES_TEXTGRID, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE, MID_GRID_RUBYHEIGHT|CONVERT_TWIPS},
+ { UNO_NAME_GRID_MODE, RES_TEXTGRID, cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE, MID_GRID_TYPE},
+ { UNO_NAME_GRID_RUBY_BELOW, RES_TEXTGRID, cppu::UnoType<bool>::get(), PROPERTY_NONE, MID_GRID_RUBY_BELOW},
+ { UNO_NAME_GRID_PRINT, RES_TEXTGRID, cppu::UnoType<bool>::get(), PROPERTY_NONE, MID_GRID_PRINT},
+ { UNO_NAME_GRID_DISPLAY, RES_TEXTGRID, cppu::UnoType<bool>::get(), PROPERTY_NONE, MID_GRID_DISPLAY},
+ { UNO_NAME_GRID_BASE_WIDTH, RES_TEXTGRID, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE, MID_GRID_BASEWIDTH|CONVERT_TWIPS},
+ { UNO_NAME_GRID_SNAP_TO_CHARS, RES_TEXTGRID, cppu::UnoType<bool>::get(), PROPERTY_NONE, MID_GRID_SNAPTOCHARS},
+ { UNO_NAME_GRID_STANDARD_PAGE_MODE, RES_TEXTGRID, cppu::UnoType<bool>::get(), PROPERTY_NONE, MID_GRID_STANDARD_MODE},
+ { UNO_NAME_HIDDEN, FN_UNO_HIDDEN, cppu::UnoType<bool>::get(), PROPERTY_NONE, 0},
+
+ // added FillProperties for SW, same as FILL_PROPERTIES in svx
+ // but need own defines in Writer due to later association of strings
+ // and uno types (see loop at end of this method and definition of SW_PROP_NMID)
+ // This entry is for adding that properties to style import/export
+ FILL_PROPERTIES_SW
+ { u"BackgroundFullSize"_ustr, RES_BACKGROUND_FULL_SIZE, cppu::UnoType<bool>::get(), PROPERTY_NONE, 0 },
+ { u"RtlGutter"_ustr, RES_RTL_GUTTER, cppu::UnoType<bool>::get(), PROPERTY_NONE, 0 },
+
+ // Added DrawingLayer FillStyle Properties for Header. These need an own unique name,
+ // but reuse the same WhichIDs as the regular fill. The implementation will decide to which
+ // group of fill properties it belongs based on the start of the name (was already done in
+ // the implementation partially), thus all SlotNames *have* to start with 'Header'
+ { UNO_NAME_HEADER_FILLBMP_LOGICAL_SIZE, XATTR_FILLBMP_SIZELOG, cppu::UnoType<bool>::get() , 0, 0},
+ { UNO_NAME_HEADER_FILLBMP_OFFSET_X, XATTR_FILLBMP_TILEOFFSETX, cppu::UnoType<sal_Int32>::get() , 0, 0},
+ { UNO_NAME_HEADER_FILLBMP_OFFSET_Y, XATTR_FILLBMP_TILEOFFSETY, cppu::UnoType<sal_Int32>::get() , 0, 0},
+ { UNO_NAME_HEADER_FILLBMP_POSITION_OFFSET_X, XATTR_FILLBMP_POSOFFSETX, cppu::UnoType<sal_Int32>::get() , 0, 0},
+ { UNO_NAME_HEADER_FILLBMP_POSITION_OFFSET_Y, XATTR_FILLBMP_POSOFFSETY, cppu::UnoType<sal_Int32>::get() , 0, 0},
+ { UNO_NAME_HEADER_FILLBMP_RECTANGLE_POINT, XATTR_FILLBMP_POS, cppu::UnoType<css::drawing::RectanglePoint>::get() , 0, 0},
+ { UNO_NAME_HEADER_FILLBMP_SIZE_X, XATTR_FILLBMP_SIZEX, cppu::UnoType<sal_Int32>::get() , 0, 0, PropertyMoreFlags::METRIC_ITEM},
+ { UNO_NAME_HEADER_FILLBMP_SIZE_Y, XATTR_FILLBMP_SIZEY, cppu::UnoType<sal_Int32>::get() , 0, 0, PropertyMoreFlags::METRIC_ITEM},
+ { UNO_NAME_HEADER_FILLBMP_STRETCH, XATTR_FILLBMP_STRETCH, cppu::UnoType<bool>::get() , 0, 0},
+ { UNO_NAME_HEADER_FILLBMP_TILE, XATTR_FILLBMP_TILE, cppu::UnoType<bool>::get() , 0, 0},
+ { UNO_NAME_HEADER_FILLBMP_MODE, OWN_ATTR_FILLBMP_MODE, cppu::UnoType<css::drawing::BitmapMode>::get(), 0, 0},
+ { UNO_NAME_HEADER_FILLCOLOR, XATTR_FILLCOLOR, cppu::UnoType<sal_Int32>::get(), 0, 0},
+ { UNO_NAME_HEADER_FILLBACKGROUND, XATTR_FILLBACKGROUND, cppu::UnoType<bool>::get(), 0, 0},
+ { UNO_NAME_HEADER_FILLBITMAP, XATTR_FILLBITMAP, cppu::UnoType<css::awt::XBitmap>::get(), 0, MID_BITMAP},
+ { UNO_NAME_HEADER_FILLBITMAPNAME, XATTR_FILLBITMAP, cppu::UnoType<OUString>::get(), 0, MID_NAME },
+ { UNO_NAME_HEADER_FILLGRADIENTSTEPCOUNT, XATTR_GRADIENTSTEPCOUNT, cppu::UnoType<sal_Int16>::get(), 0, 0},
+ { UNO_NAME_HEADER_FILLGRADIENT, XATTR_FILLGRADIENT, cppu::UnoType<css::awt::Gradient>::get(), 0, MID_FILLGRADIENT},
+ { UNO_NAME_HEADER_FILLGRADIENTNAME, XATTR_FILLGRADIENT, cppu::UnoType<OUString>::get(), 0, MID_NAME },
+ { UNO_NAME_HEADER_FILLHATCH, XATTR_FILLHATCH, cppu::UnoType<css::drawing::Hatch>::get(), 0, MID_FILLHATCH},
+ { UNO_NAME_HEADER_FILLHATCHNAME, XATTR_FILLHATCH, cppu::UnoType<OUString>::get(), 0, MID_NAME },
+ { UNO_NAME_HEADER_FILLSTYLE, XATTR_FILLSTYLE, cppu::UnoType<css::drawing::FillStyle>::get(), 0, 0},
+ { UNO_NAME_HEADER_FILL_TRANSPARENCE, XATTR_FILLTRANSPARENCE, cppu::UnoType<sal_Int16>::get(), 0, 0},
+ { UNO_NAME_HEADER_FILLTRANSPARENCEGRADIENT, XATTR_FILLFLOATTRANSPARENCE, cppu::UnoType<css::awt::Gradient>::get(), 0, MID_FILLGRADIENT},
+ { UNO_NAME_HEADER_FILLTRANSPARENCEGRADIENTNAME, XATTR_FILLFLOATTRANSPARENCE, cppu::UnoType<OUString>::get(), 0, MID_NAME },
+ { UNO_NAME_HEADER_FILLCOLOR_2, XATTR_SECONDARYFILLCOLOR, cppu::UnoType<sal_Int32>::get(), 0, 0},
+
+ // Added DrawingLayer FillStyle Properties for Footer, similar as for Header (see there)
+ { UNO_NAME_FOOTER_FILLBMP_LOGICAL_SIZE, XATTR_FILLBMP_SIZELOG, cppu::UnoType<bool>::get() , 0, 0},
+ { UNO_NAME_FOOTER_FILLBMP_OFFSET_X, XATTR_FILLBMP_TILEOFFSETX, cppu::UnoType<sal_Int32>::get() , 0, 0},
+ { UNO_NAME_FOOTER_FILLBMP_OFFSET_Y, XATTR_FILLBMP_TILEOFFSETY, cppu::UnoType<sal_Int32>::get() , 0, 0},
+ { UNO_NAME_FOOTER_FILLBMP_POSITION_OFFSET_X, XATTR_FILLBMP_POSOFFSETX, cppu::UnoType<sal_Int32>::get() , 0, 0},
+ { UNO_NAME_FOOTER_FILLBMP_POSITION_OFFSET_Y, XATTR_FILLBMP_POSOFFSETY, cppu::UnoType<sal_Int32>::get() , 0, 0},
+ { UNO_NAME_FOOTER_FILLBMP_RECTANGLE_POINT, XATTR_FILLBMP_POS, cppu::UnoType<css::drawing::RectanglePoint>::get() , 0, 0},
+ { UNO_NAME_FOOTER_FILLBMP_SIZE_X, XATTR_FILLBMP_SIZEX, cppu::UnoType<sal_Int32>::get() , 0, 0, PropertyMoreFlags::METRIC_ITEM},
+ { UNO_NAME_FOOTER_FILLBMP_SIZE_Y, XATTR_FILLBMP_SIZEY, cppu::UnoType<sal_Int32>::get() , 0, 0, PropertyMoreFlags::METRIC_ITEM},
+ { UNO_NAME_FOOTER_FILLBMP_STRETCH, XATTR_FILLBMP_STRETCH, cppu::UnoType<bool>::get() , 0, 0},
+ { UNO_NAME_FOOTER_FILLBMP_TILE, XATTR_FILLBMP_TILE, cppu::UnoType<bool>::get() , 0, 0},
+ { UNO_NAME_FOOTER_FILLBMP_MODE, OWN_ATTR_FILLBMP_MODE, cppu::UnoType<css::drawing::BitmapMode>::get(), 0, 0},
+ { UNO_NAME_FOOTER_FILLCOLOR, XATTR_FILLCOLOR, cppu::UnoType<sal_Int32>::get(), 0, 0},
+ { UNO_NAME_FOOTER_FILLBACKGROUND, XATTR_FILLBACKGROUND, cppu::UnoType<bool>::get(), 0, 0},
+ { UNO_NAME_FOOTER_FILLBITMAP, XATTR_FILLBITMAP, cppu::UnoType<css::awt::XBitmap>::get(), 0, MID_BITMAP},
+ { UNO_NAME_FOOTER_FILLBITMAPNAME, XATTR_FILLBITMAP, cppu::UnoType<OUString>::get(), 0, MID_NAME },
+ { UNO_NAME_FOOTER_FILLGRADIENTSTEPCOUNT, XATTR_GRADIENTSTEPCOUNT, cppu::UnoType<sal_Int16>::get(), 0, 0},
+ { UNO_NAME_FOOTER_FILLGRADIENT, XATTR_FILLGRADIENT, cppu::UnoType<css::awt::Gradient>::get(), 0, MID_FILLGRADIENT},
+ { UNO_NAME_FOOTER_FILLGRADIENTNAME, XATTR_FILLGRADIENT, cppu::UnoType<OUString>::get(), 0, MID_NAME },
+ { UNO_NAME_FOOTER_FILLHATCH, XATTR_FILLHATCH, cppu::UnoType<css::drawing::Hatch>::get(), 0, MID_FILLHATCH},
+ { UNO_NAME_FOOTER_FILLHATCHNAME, XATTR_FILLHATCH, cppu::UnoType<OUString>::get(), 0, MID_NAME },
+ { UNO_NAME_FOOTER_FILLSTYLE, XATTR_FILLSTYLE, cppu::UnoType<css::drawing::FillStyle>::get(), 0, 0},
+ { UNO_NAME_FOOTER_FILL_TRANSPARENCE, XATTR_FILLTRANSPARENCE, cppu::UnoType<sal_Int16>::get(), 0, 0},
+ { UNO_NAME_FOOTER_FILLTRANSPARENCEGRADIENT, XATTR_FILLFLOATTRANSPARENCE, cppu::UnoType<css::awt::Gradient>::get(), 0, MID_FILLGRADIENT},
+ { UNO_NAME_FOOTER_FILLTRANSPARENCEGRADIENTNAME, XATTR_FILLFLOATTRANSPARENCE, cppu::UnoType<OUString>::get(), 0, MID_NAME },
+ { UNO_NAME_FOOTER_FILLCOLOR_2, XATTR_SECONDARYFILLCOLOR, cppu::UnoType<sal_Int32>::get(), 0, 0},
+
+ };
+
+ return aPageStyleMap;
+}
+
+std::span<const SfxItemPropertyMapEntry> SwUnoPropertyMapProvider::GetTablePropertyMap()
+{
+ static SfxItemPropertyMapEntry const aTablePropertyMap_Impl[] =
+ {
+ { UNO_NAME_BACK_COLOR, RES_BACKGROUND, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE,MID_BACK_COLOR },
+ { UNO_NAME_BACKGROUND_COMPLEX_COLOR, RES_BACKGROUND, cppu::UnoType<css::util::XComplexColor>::get(), PROPERTY_NONE, MID_BACKGROUND_COMPLEX_COLOR},
+ { UNO_NAME_BREAK_TYPE, RES_BREAK, cppu::UnoType<css::style::BreakType>::get(), PROPERTY_NONE, 0},
+ { UNO_NAME_BACK_GRAPHIC_URL, RES_BACKGROUND, cppu::UnoType<OUString>::get(), PROPERTY_NONE ,MID_GRAPHIC_URL },
+ { UNO_NAME_BACK_GRAPHIC, RES_BACKGROUND, cppu::UnoType<graphic::XGraphic>::get(), PROPERTY_NONE, MID_GRAPHIC },
+ { UNO_NAME_BACK_GRAPHIC_FILTER, RES_BACKGROUND, cppu::UnoType<OUString>::get(), PROPERTY_NONE ,MID_GRAPHIC_FILTER },
+ { UNO_NAME_BACK_GRAPHIC_LOCATION, RES_BACKGROUND, cppu::UnoType<css::style::GraphicLocation>::get(), PROPERTY_NONE ,MID_GRAPHIC_POSITION},
+ { UNO_NAME_LEFT_MARGIN, RES_LR_SPACE, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE, MID_L_MARGIN|CONVERT_TWIPS},
+ { UNO_NAME_RIGHT_MARGIN, RES_LR_SPACE, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE, MID_R_MARGIN|CONVERT_TWIPS},
+ { UNO_NAME_HORI_ORIENT, RES_HORI_ORIENT, cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE ,MID_HORIORIENT_ORIENT },
+ { UNO_NAME_KEEP_TOGETHER, RES_KEEP, cppu::UnoType<bool>::get() , PROPERTY_NONE, 0},
+ { UNO_NAME_SPLIT, RES_LAYOUT_SPLIT, cppu::UnoType<bool>::get() , PROPERTY_NONE, 0},
+ { UNO_NAME_PAGE_NUMBER_OFFSET, RES_PAGEDESC, cppu::UnoType<sal_Int16>::get(), PropertyAttribute::MAYBEVOID, MID_PAGEDESC_PAGENUMOFFSET},
+ { UNO_NAME_PAGE_DESC_NAME, RES_PAGEDESC, cppu::UnoType<OUString>::get(), PropertyAttribute::MAYBEVOID, 0xbf},
+ { UNO_NAME_RELATIVE_WIDTH, FN_TABLE_RELATIVE_WIDTH,cppu::UnoType<sal_Int16>::get() , PROPERTY_NONE, 0xbf },
+ { UNO_NAME_REPEAT_HEADLINE, FN_TABLE_HEADLINE_REPEAT,cppu::UnoType<bool>::get(), PROPERTY_NONE, 0xbf},
+ { UNO_NAME_HEADER_ROW_COUNT, FN_TABLE_HEADLINE_COUNT, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE, 0xbf},
+ { UNO_NAME_SHADOW_FORMAT, RES_SHADOW, cppu::UnoType<css::table::ShadowFormat>::get(), PROPERTY_NONE, 0},
+ { UNO_NAME_SHADOW_TRANSPARENCE, RES_SHADOW, cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE, MID_SHADOW_TRANSPARENCE},
+ { UNO_NAME_TOP_MARGIN, RES_UL_SPACE, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE, MID_UP_MARGIN|CONVERT_TWIPS},
+ { UNO_NAME_BOTTOM_MARGIN, RES_UL_SPACE, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE, MID_LO_MARGIN|CONVERT_TWIPS},
+ { UNO_NAME_BACK_TRANSPARENT, RES_BACKGROUND, cppu::UnoType<bool>::get(), PROPERTY_NONE ,MID_GRAPHIC_TRANSPARENT },
+ { UNO_NAME_WIDTH, FN_TABLE_WIDTH, cppu::UnoType<sal_Int32>::get() , PROPERTY_NONE, 0xbf},
+ { UNO_NAME_IS_WIDTH_RELATIVE, FN_TABLE_IS_RELATIVE_WIDTH, cppu::UnoType<bool>::get() , PROPERTY_NONE, 0xbf},
+ { UNO_NAME_CHART_ROW_AS_LABEL, FN_UNO_RANGE_ROW_LABEL, cppu::UnoType<bool>::get(), PROPERTY_NONE, 0},
+ { UNO_NAME_CHART_COLUMN_AS_LABEL, FN_UNO_RANGE_COL_LABEL, cppu::UnoType<bool>::get() , PROPERTY_NONE, 0},
+ { UNO_NAME_TABLE_BORDER, FN_UNO_TABLE_BORDER, cppu::UnoType<css::table::TableBorder>::get(), PropertyAttribute::MAYBEVOID, CONVERT_TWIPS },
+ { UNO_NAME_TABLE_BORDER2, FN_UNO_TABLE_BORDER2, cppu::UnoType<css::table::TableBorder2>::get(), PropertyAttribute::MAYBEVOID, CONVERT_TWIPS },
+ { UNO_NAME_TABLE_BORDER_DISTANCES, FN_UNO_TABLE_BORDER_DISTANCES, cppu::UnoType<css::table::TableBorderDistances>::get(), PropertyAttribute::MAYBEVOID, CONVERT_TWIPS },
+ { UNO_NAME_TABLE_COLUMN_SEPARATORS, FN_UNO_TABLE_COLUMN_SEPARATORS, cppu::UnoType< cppu::UnoSequenceType<css::text::TableColumnSeparator> >::get(), PropertyAttribute::MAYBEVOID, 0 },
+ { UNO_NAME_TABLE_COLUMN_RELATIVE_SUM, FN_UNO_TABLE_COLUMN_RELATIVE_SUM, cppu::UnoType<sal_Int16>::get(), PropertyAttribute::READONLY, 0 },
+ COMMON_TEXT_CONTENT_PROPERTIES
+ { UNO_LINK_DISPLAY_NAME, FN_PARAM_LINK_DISPLAY_NAME, cppu::UnoType<OUString>::get(), PropertyAttribute::READONLY, 0xbf},
+ { UNO_NAME_USER_DEFINED_ATTRIBUTES, RES_UNKNOWNATR_CONTAINER, cppu::UnoType<css::container::XNameContainer>::get(), PropertyAttribute::MAYBEVOID, 0 },
+ { UNO_NAME_TEXT_SECTION, FN_UNO_TEXT_SECTION, cppu::UnoType<css::text::XTextSection>::get(), PropertyAttribute::MAYBEVOID|PropertyAttribute::READONLY ,0 },
+ { UNO_NAME_WRITING_MODE, RES_FRAMEDIR, cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE, 0 },
+ { UNO_NAME_TABLE_NAME, FN_UNO_TABLE_NAME, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0 },
+ { UNO_NAME_PAGE_STYLE_NAME, RES_PAGEDESC, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ { UNO_NAME_TABLE_TEMPLATE_NAME, FN_UNO_TABLE_TEMPLATE_NAME, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0 },
+ // #i29550#
+ { UNO_NAME_COLLAPSING_BORDERS, RES_COLLAPSING_BORDERS, cppu::UnoType<bool>::get(), PROPERTY_NONE, 0},
+ REDLINE_NODE_PROPERTIES
+ { UNO_NAME_TABLE_INTEROP_GRAB_BAG, RES_FRMATR_GRABBAG, cppu::UnoType< cppu::UnoSequenceType<css::beans::PropertyValue> >::get(), PROPERTY_NONE, 0 },
+ };
+
+ return aTablePropertyMap_Impl;
+}
+
+std::span<const SfxItemPropertyMapEntry> SwUnoPropertyMapProvider::GetRangePropertyMap()
+{
+ static SfxItemPropertyMapEntry const aRangePropertyMap_Impl[] =
+ {
+ COMMON_CRSR_PARA_PROPERTIES_WITHOUT_FN_01
+ TABSTOPS_MAP_ENTRY
+ { UNO_NAME_BACK_COLOR, FN_UNO_TABLE_CELL_BACKGROUND, cppu::UnoType<sal_Int32>::get(), PropertyAttribute::MAYBEVOID, MID_BACK_COLOR },
+ { UNO_NAME_BACKGROUND_COMPLEX_COLOR, FN_UNO_TABLE_CELL_BACKGROUND, cppu::UnoType<sal_Int32>::get(), PropertyAttribute::MAYBEVOID, MID_BACKGROUND_COMPLEX_COLOR },
+ { UNO_NAME_BACK_GRAPHIC_URL, RES_BACKGROUND, cppu::UnoType<OUString>::get(), PropertyAttribute::MAYBEVOID ,MID_GRAPHIC_URL },
+ { UNO_NAME_BACK_GRAPHIC, RES_BACKGROUND, cppu::UnoType<graphic::XGraphic>::get(), PROPERTY_NONE, MID_GRAPHIC },
+ { UNO_NAME_BACK_GRAPHIC_FILTER, RES_BACKGROUND, cppu::UnoType<OUString>::get(), PropertyAttribute::MAYBEVOID ,MID_GRAPHIC_FILTER },
+ { UNO_NAME_BACK_GRAPHIC_LOCATION, FN_UNO_TABLE_CELL_BACKGROUND, cppu::UnoType<css::style::GraphicLocation>::get(), PropertyAttribute::MAYBEVOID, MID_GRAPHIC_POSITION},
+ { UNO_NAME_BACK_TRANSPARENT, FN_UNO_TABLE_CELL_BACKGROUND, cppu::UnoType<bool>::get(), PropertyAttribute::MAYBEVOID, MID_GRAPHIC_TRANSPARENT },
+ { UNO_NAME_NUMBER_FORMAT, RES_BOXATR_FORMAT, cppu::UnoType<sal_Int32>::get(), PropertyAttribute::MAYBEVOID ,0 },
+ { UNO_NAME_VERT_ORIENT, RES_VERT_ORIENT, cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE ,MID_VERTORIENT_ORIENT },
+ { UNO_NAME_CHART_ROW_AS_LABEL, FN_UNO_RANGE_ROW_LABEL, cppu::UnoType<bool>::get(), PropertyAttribute::MAYBEVOID, 0},
+ { UNO_NAME_CHART_COLUMN_AS_LABEL, FN_UNO_RANGE_COL_LABEL, cppu::UnoType<bool>::get() , PropertyAttribute::MAYBEVOID, 0},
+ };
+
+ return aRangePropertyMap_Impl;
+}
+
+std::span<const SfxItemPropertyMapEntry> SwUnoPropertyMapProvider::GetSectionPropertyMap()
+{
+ static SfxItemPropertyMapEntry const aSectionPropertyMap_Impl[] =
+ {
+ { UNO_NAME_CONDITION, WID_SECT_CONDITION, cppu::UnoType<OUString>::get() , PROPERTY_NONE, 0},
+ { UNO_NAME_DDE_COMMAND_FILE, WID_SECT_DDE_TYPE, cppu::UnoType<OUString>::get() , PROPERTY_NONE, 0},
+ { UNO_NAME_DDE_COMMAND_TYPE, WID_SECT_DDE_FILE, cppu::UnoType<OUString>::get() , PROPERTY_NONE, 0},
+ { UNO_NAME_DDE_COMMAND_ELEMENT, WID_SECT_DDE_ELEMENT, cppu::UnoType<OUString>::get() , PROPERTY_NONE, 0},
+ { UNO_NAME_IS_AUTOMATIC_UPDATE, WID_SECT_DDE_AUTOUPDATE, cppu::UnoType<bool>::get(), PROPERTY_NONE, 0},
+ { UNO_NAME_FILE_LINK, WID_SECT_LINK , cppu::UnoType<css::text::SectionFileLink>::get(), PROPERTY_NONE, 0},
+ { UNO_NAME_IS_VISIBLE, WID_SECT_VISIBLE , cppu::UnoType<bool>::get(), PROPERTY_NONE, 0},
+ { UNO_NAME_IS_PROTECTED, WID_SECT_PROTECTED, cppu::UnoType<bool>::get(), PROPERTY_NONE, 0},
+ { UNO_NAME_EDIT_IN_READONLY, WID_SECT_EDIT_IN_READONLY, cppu::UnoType<bool>::get(), PROPERTY_NONE, 0},
+ { UNO_NAME_LINK_REGION, WID_SECT_REGION , cppu::UnoType<OUString>::get() , PROPERTY_NONE, 0},
+ { UNO_NAME_TEXT_COLUMNS, RES_COL, cppu::UnoType<css::text::XTextColumns>::get(), PROPERTY_NONE, MID_COLUMNS},
+ { UNO_NAME_BACK_GRAPHIC_URL, RES_BACKGROUND, cppu::UnoType<OUString>::get(), PROPERTY_NONE ,MID_GRAPHIC_URL },
+ { UNO_NAME_BACK_GRAPHIC, RES_BACKGROUND, cppu::UnoType<graphic::XGraphic>::get(), PROPERTY_NONE, MID_GRAPHIC },
+ { UNO_NAME_BACK_GRAPHIC_FILTER, RES_BACKGROUND, cppu::UnoType<OUString>::get(), PROPERTY_NONE ,MID_GRAPHIC_FILTER },
+ { UNO_NAME_BACK_GRAPHIC_LOCATION, RES_BACKGROUND, cppu::UnoType<css::style::GraphicLocation>::get(), PROPERTY_NONE ,MID_GRAPHIC_POSITION},
+ { UNO_NAME_BACK_COLOR, RES_BACKGROUND, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE ,MID_BACK_COLOR },
+ { UNO_NAME_BACKGROUND_COMPLEX_COLOR, RES_BACKGROUND, cppu::UnoType<css::util::XComplexColor>::get(), PROPERTY_NONE, MID_BACKGROUND_COMPLEX_COLOR },
+ { UNO_NAME_BACK_TRANSPARENT, RES_BACKGROUND, cppu::UnoType<bool>::get(), PROPERTY_NONE ,MID_GRAPHIC_TRANSPARENT },
+ { UNO_LINK_DISPLAY_NAME, FN_PARAM_LINK_DISPLAY_NAME, cppu::UnoType<OUString>::get(), PropertyAttribute::READONLY, 0xbf},
+ { UNO_NAME_USER_DEFINED_ATTRIBUTES, RES_UNKNOWNATR_CONTAINER, cppu::UnoType<css::container::XNameContainer>::get(), PropertyAttribute::MAYBEVOID, 0 },
+ { UNO_NAME_FOOTNOTE_IS_COLLECT_AT_TEXT_END, RES_FTN_AT_TXTEND, cppu::UnoType<bool>::get(), PROPERTY_NONE ,MID_COLLECT },
+ { UNO_NAME_FOOTNOTE_IS_RESTART_NUMBERING, RES_FTN_AT_TXTEND, cppu::UnoType<bool>::get(), PROPERTY_NONE , MID_RESTART_NUM },
+ { UNO_NAME_FOOTNOTE_RESTART_NUMBERING_AT, RES_FTN_AT_TXTEND, cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE , MID_NUM_START_AT},
+ { UNO_NAME_FOOTNOTE_IS_OWN_NUMBERING, RES_FTN_AT_TXTEND, cppu::UnoType<bool>::get(), PROPERTY_NONE , MID_OWN_NUM },
+ { UNO_NAME_FOOTNOTE_NUMBERING_TYPE, RES_FTN_AT_TXTEND, cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE , MID_NUM_TYPE },
+ { UNO_NAME_FOOTNOTE_NUMBERING_PREFIX, RES_FTN_AT_TXTEND, cppu::UnoType<OUString>::get() , PROPERTY_NONE, MID_PREFIX },
+ { UNO_NAME_FOOTNOTE_NUMBERING_SUFFIX, RES_FTN_AT_TXTEND, cppu::UnoType<OUString>::get() , PROPERTY_NONE, MID_SUFFIX },
+ { UNO_NAME_ENDNOTE_IS_COLLECT_AT_TEXT_END, RES_END_AT_TXTEND, cppu::UnoType<bool>::get(), PROPERTY_NONE , MID_COLLECT },
+ { UNO_NAME_ENDNOTE_IS_RESTART_NUMBERING, RES_END_AT_TXTEND, cppu::UnoType<bool>::get(), PROPERTY_NONE , MID_RESTART_NUM },
+ { UNO_NAME_ENDNOTE_RESTART_NUMBERING_AT, RES_END_AT_TXTEND, cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE , MID_NUM_START_AT },
+ { UNO_NAME_ENDNOTE_IS_OWN_NUMBERING, RES_END_AT_TXTEND, cppu::UnoType<bool>::get(), PROPERTY_NONE , MID_OWN_NUM },
+ { UNO_NAME_ENDNOTE_NUMBERING_TYPE, RES_END_AT_TXTEND, cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE ,MID_NUM_TYPE },
+ { UNO_NAME_ENDNOTE_NUMBERING_PREFIX, RES_END_AT_TXTEND, cppu::UnoType<OUString>::get() , PROPERTY_NONE, MID_PREFIX },
+ { UNO_NAME_ENDNOTE_NUMBERING_SUFFIX, RES_END_AT_TXTEND, cppu::UnoType<OUString>::get() , PROPERTY_NONE, MID_SUFFIX },
+ { UNO_NAME_DOCUMENT_INDEX, WID_SECT_DOCUMENT_INDEX, cppu::UnoType<css::text::XDocumentIndex>::get(), PropertyAttribute::READONLY | PropertyAttribute::MAYBEVOID, 0 },
+ { UNO_NAME_IS_GLOBAL_DOCUMENT_SECTION, WID_SECT_IS_GLOBAL_DOC_SECTION, cppu::UnoType<bool>::get(), PropertyAttribute::READONLY, 0 },
+ { UNO_NAME_PROTECTION_KEY, WID_SECT_PASSWORD, cppu::UnoType< cppu::UnoSequenceType<sal_Int8> >::get(), PROPERTY_NONE, 0 },
+ { UNO_NAME_DONT_BALANCE_TEXT_COLUMNS, RES_COLUMNBALANCE, cppu::UnoType<bool>::get(), PROPERTY_NONE, 0 },
+ COMMON_TEXT_CONTENT_PROPERTIES
+ REDLINE_NODE_PROPERTIES
+ { UNO_NAME_IS_CURRENTLY_VISIBLE, WID_SECT_CURRENTLY_VISIBLE, cppu::UnoType<bool>::get(), PROPERTY_NONE, 0},
+ { UNO_NAME_WRITING_MODE, RES_FRAMEDIR, cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE, 0 },
+ { UNO_NAME_SECT_LEFT_MARGIN, RES_LR_SPACE, cppu::UnoType<sal_Int32>::get(), PropertyAttribute::MAYBEVOID, MID_L_MARGIN|CONVERT_TWIPS},
+ { UNO_NAME_SECT_RIGHT_MARGIN, RES_LR_SPACE, cppu::UnoType<sal_Int32>::get(), PropertyAttribute::MAYBEVOID, MID_R_MARGIN|CONVERT_TWIPS},
+ };
+
+ return aSectionPropertyMap_Impl;
+}
+
+std::span<const SfxItemPropertyMapEntry> SwUnoPropertyMapProvider::GetFramePropertyMap()
+{
+ static SfxItemPropertyMapEntry const aFramePropertyMap_Impl[] =
+ { //
+ // TODO: We should consider completely removing SvxBrushItem() stuff
+ // add support for XATTR_FILL_FIRST, XATTR_FILL_LAST
+ // COMMON_FRAME_PROPERTIES currently hosts the RES_BACKGROUND entries from SvxBrushItem
+ COMMON_FRAME_PROPERTIES
+ REDLINE_NODE_PROPERTIES
+ { UNO_NAME_CHAIN_NEXT_NAME, RES_CHAIN, cppu::UnoType<OUString>::get(), PropertyAttribute::MAYBEVOID ,MID_CHAIN_NEXTNAME},
+ { UNO_NAME_CHAIN_PREV_NAME, RES_CHAIN, cppu::UnoType<OUString>::get(), PropertyAttribute::MAYBEVOID ,MID_CHAIN_PREVNAME},
+ /*not impl*/ { UNO_NAME_CLIENT_MAP, RES_URL, cppu::UnoType<bool>::get(), PROPERTY_NONE ,MID_URL_CLIENTMAP },
+ { UNO_NAME_EDIT_IN_READONLY, RES_EDIT_IN_READONLY, cppu::UnoType<bool>::get(), PROPERTY_NONE, 0},
+ { UNO_NAME_TEXT_COLUMNS, RES_COL, cppu::UnoType<css::text::XTextColumns>::get(), PROPERTY_NONE, MID_COLUMNS},
+ //next elements are part of the service description
+ { UNO_NAME_FRAME_HEIGHT_ABSOLUTE, RES_FRM_SIZE, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE, MID_FRMSIZE_HEIGHT|CONVERT_TWIPS },
+ { UNO_NAME_FRAME_HEIGHT_PERCENT, RES_FRM_SIZE, cppu::UnoType<sal_Int8>::get(), PROPERTY_NONE, MID_FRMSIZE_REL_HEIGHT },
+ { UNO_NAME_FRAME_ISAUTOMATIC_HEIGHT, RES_FRM_SIZE, cppu::UnoType<bool>::get(), PROPERTY_NONE, MID_FRMSIZE_IS_AUTO_HEIGHT },
+ { UNO_NAME_FRAME_WIDTH_ABSOLUTE, RES_FRM_SIZE, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE, MID_FRMSIZE_WIDTH|CONVERT_TWIPS },
+ { UNO_NAME_FRAME_WIDTH_PERCENT, RES_FRM_SIZE, cppu::UnoType<sal_Int8>::get(), PROPERTY_NONE, MID_FRMSIZE_REL_WIDTH },
+ { UNO_NAME_SIZE_TYPE, RES_FRM_SIZE, cppu::UnoType<sal_Int16>::get() , PROPERTY_NONE, MID_FRMSIZE_SIZE_TYPE },
+ { UNO_NAME_WIDTH_TYPE, RES_FRM_SIZE, cppu::UnoType<sal_Int16>::get() , PROPERTY_NONE, MID_FRMSIZE_WIDTH_TYPE },
+ { UNO_NAME_WRITING_MODE, RES_FRAMEDIR, cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE, 0 },
+ { UNO_NAME_IS_SPLIT_ALLOWED, RES_FLY_SPLIT, cppu::UnoType<bool>::get(), PropertyAttribute::MAYBEVOID, 0 },
+ { UNO_NAME_WRAP_TEXT_AT_FLY_START, RES_WRAP_TEXT_AT_FLY_START, cppu::UnoType<bool>::get(), PropertyAttribute::MAYBEVOID, 0 },
+
+ // added FillProperties for SW, same as FILL_PROPERTIES in svx
+ // but need own defines in Writer due to later association of strings
+ // and uno types (see loop at end of this method and definition of SW_PROP_NMID)
+ // This entry is for adding that properties to FlyFrame import/export
+ FILL_PROPERTIES_SW
+ };
+
+ return aFramePropertyMap_Impl;
+}
+
+std::span<const SfxItemPropertyMapEntry> SwUnoPropertyMapProvider::GetGraphicPropertyMap()
+{
+ static SfxItemPropertyMapEntry const aGraphicPropertyMap_Impl[] =
+ {
+ // TODO: We should consider completely removing SvxBrushItem() stuff
+ // add support for XATTR_FILL_FIRST, XATTR_FILL_LAST
+ // COMMON_FRAME_PROPERTIES currently hosts the RES_BACKGROUND entries from SvxBrushItem
+ COMMON_FRAME_PROPERTIES
+ { UNO_NAME_SURROUND_CONTOUR, RES_SURROUND, cppu::UnoType<bool>::get(), PROPERTY_NONE, MID_SURROUND_CONTOUR },
+ { UNO_NAME_CONTOUR_OUTSIDE, RES_SURROUND, cppu::UnoType<bool>::get(), PROPERTY_NONE, MID_SURROUND_CONTOUROUTSIDE },
+ { UNO_NAME_GRAPHIC_CROP, RES_GRFATR_CROPGRF, cppu::UnoType<css::text::GraphicCrop>::get(), PROPERTY_NONE, CONVERT_TWIPS },
+ { UNO_NAME_HORI_MIRRORED_ON_EVEN_PAGES, RES_GRFATR_MIRRORGRF, cppu::UnoType<bool>::get(), PROPERTY_NONE, MID_MIRROR_HORZ_EVEN_PAGES },
+ { UNO_NAME_HORI_MIRRORED_ON_ODD_PAGES, RES_GRFATR_MIRRORGRF, cppu::UnoType<bool>::get(), PROPERTY_NONE, MID_MIRROR_HORZ_ODD_PAGES },
+ { UNO_NAME_VERT_MIRRORED, RES_GRFATR_MIRRORGRF, cppu::UnoType<bool>::get(), PROPERTY_NONE, MID_MIRROR_VERT },
+ { UNO_NAME_REPLACEMENT_GRAPHIC, FN_UNO_REPLACEMENT_GRAPHIC, cppu::UnoType<css::graphic::XGraphic>::get(), 0, 0 },
+ { UNO_NAME_GRAPHIC_FILTER, FN_UNO_GRAPHIC_FILTER, cppu::UnoType<OUString>::get(), 0, 0 },
+ { UNO_NAME_GRAPHIC, FN_UNO_GRAPHIC, cppu::UnoType<css::graphic::XGraphic>::get(), 0, 0 },
+ { UNO_NAME_GRAPHIC_URL, FN_UNO_GRAPHIC_URL, cppu::UnoType<css::uno::Any>::get(), 0, 0 },
+ { UNO_NAME_TRANSFORMED_GRAPHIC, FN_UNO_TRANSFORMED_GRAPHIC, cppu::UnoType<css::graphic::XGraphic>::get(), 0, 0 },
+ { UNO_NAME_GRAPHIC_PREVIEW, FN_UNO_GRAPHIC_PREVIEW, cppu::UnoType<css::graphic::XGraphic>::get(), 0, 0 },
+ { UNO_NAME_ACTUAL_SIZE, FN_UNO_ACTUAL_SIZE, cppu::UnoType<css::awt::Size>::get(), PropertyAttribute::READONLY, CONVERT_TWIPS},
+ { UNO_NAME_CONTOUR_POLY_POLYGON, FN_PARAM_CONTOUR_PP, cppu::UnoType<css::drawing::PointSequenceSequence>::get(), PropertyAttribute::MAYBEVOID, 0 },
+ { UNO_NAME_IS_PIXEL_CONTOUR, FN_UNO_IS_PIXEL_CONTOUR, cppu::UnoType<bool>::get(), PROPERTY_NONE, 0 },
+ { UNO_NAME_IS_AUTOMATIC_CONTOUR, FN_UNO_IS_AUTOMATIC_CONTOUR , cppu::UnoType<bool>::get(), PROPERTY_NONE, 0 },
+ { UNO_NAME_GRAPHIC_ROTATION, RES_GRFATR_ROTATION, cppu::UnoType<sal_Int16>::get(), 0, 0},
+ { UNO_NAME_ADJUST_LUMINANCE, RES_GRFATR_LUMINANCE, cppu::UnoType<sal_Int16>::get(), 0, 0},
+ { UNO_NAME_ADJUST_CONTRAST, RES_GRFATR_CONTRAST, cppu::UnoType<sal_Int16>::get(), 0, 0},
+ { UNO_NAME_ADJUST_RED, RES_GRFATR_CHANNELR, cppu::UnoType<sal_Int16>::get(), 0, 0},
+ { UNO_NAME_ADJUST_GREEN, RES_GRFATR_CHANNELG, cppu::UnoType<sal_Int16>::get(), 0, 0},
+ { UNO_NAME_ADJUST_BLUE, RES_GRFATR_CHANNELB, cppu::UnoType<sal_Int16>::get(), 0, 0},
+ { UNO_NAME_GAMMA, RES_GRFATR_GAMMA, cppu::UnoType<double>::get(), 0, 0},
+ { UNO_NAME_GRAPHIC_IS_INVERTED, RES_GRFATR_INVERT, cppu::UnoType<bool>::get(), 0, 0},
+ { UNO_NAME_TRANSPARENCY, RES_GRFATR_TRANSPARENCY, cppu::UnoType<sal_Int16>::get(), 0, 0},
+ { UNO_NAME_GRAPHIC_COLOR_MODE, RES_GRFATR_DRAWMODE, cppu::UnoType<css::drawing::ColorMode>::get(), 0, 0},
+
+ // added FillProperties for SW, same as FILL_PROPERTIES in svx
+ // but need own defines in Writer due to later association of strings
+ // and uno types (see loop at end of this method and definition of SW_PROP_NMID)
+ // This entry is for adding that properties to Writer GraphicObject import/export
+ FILL_PROPERTIES_SW
+ };
+
+ return aGraphicPropertyMap_Impl;
+}
+
+std::span<const SfxItemPropertyMapEntry> SwUnoPropertyMapProvider::GetEmbeddedPropertyMap()
+{
+ static SfxItemPropertyMapEntry const aEmbeddedPropertyMap_Impl[] =
+ { //
+ // TODO: We should consider completely removing SvxBrushItem() stuff
+ // add support for XATTR_FILL_FIRST, XATTR_FILL_LAST
+ // COMMON_FRAME_PROPERTIES currently hosts the RES_BACKGROUND entries from SvxBrushItem
+ COMMON_FRAME_PROPERTIES
+ { UNO_NAME_SURROUND_CONTOUR, RES_SURROUND, cppu::UnoType<bool>::get(), PROPERTY_NONE, MID_SURROUND_CONTOUR },
+ { UNO_NAME_CONTOUR_OUTSIDE, RES_SURROUND, cppu::UnoType<bool>::get(), PROPERTY_NONE, MID_SURROUND_CONTOUROUTSIDE},
+ { UNO_NAME_CONTOUR_POLY_POLYGON, FN_PARAM_CONTOUR_PP, cppu::UnoType<css::drawing::PointSequenceSequence>::get(), PropertyAttribute::MAYBEVOID, 0 },
+ { UNO_NAME_IS_PIXEL_CONTOUR, FN_UNO_IS_PIXEL_CONTOUR, cppu::UnoType<bool>::get(), PROPERTY_NONE, 0 },
+ { UNO_NAME_IS_AUTOMATIC_CONTOUR, FN_UNO_IS_AUTOMATIC_CONTOUR , cppu::UnoType<bool>::get(), PROPERTY_NONE, 0 },
+ { UNO_NAME_CLSID, FN_UNO_CLSID, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0 },
+ { UNO_NAME_STREAM_NAME, FN_UNO_STREAM_NAME, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0 },
+ { UNO_NAME_MODEL, FN_UNO_MODEL, cppu::UnoType<css::frame::XModel>::get(), PropertyAttribute::READONLY|PropertyAttribute::MAYBEVOID, 0},
+ { UNO_NAME_GRAPHIC_URL, FN_UNO_REPLACEMENT_GRAPHIC_URL, cppu::UnoType<OUString>::get(), PropertyAttribute::MAYBEVOID, 0 },
+ { UNO_NAME_GRAPHIC, FN_UNO_REPLACEMENT_GRAPHIC, cppu::UnoType<css::graphic::XGraphic>::get(), PropertyAttribute::MAYBEVOID, 0 },
+ { UNO_NAME_COMPONENT,FN_UNO_COMPONENT, cppu::UnoType<css::lang::XComponent>::get(), PropertyAttribute::READONLY, 0},
+ { UNO_NAME_EMBEDDED_OBJECT,FN_EMBEDDED_OBJECT, cppu::UnoType<css::embed::XEmbeddedObject>::get(), PROPERTY_NONE, 0},
+ { UNO_NAME_DRAW_ASPECT,FN_UNO_DRAW_ASPECT, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0 },
+ { UNO_NAME_VISIBLE_AREA_WIDTH,FN_UNO_VISIBLE_AREA_WIDTH, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0 },
+ { UNO_NAME_VISIBLE_AREA_HEIGHT,FN_UNO_VISIBLE_AREA_HEIGHT, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0 },
+ // added FillProperties for SW, same as FILL_PROPERTIES in svx
+ // but need own defines in Writer due to later association of strings
+ // and uno types (see loop at end of this method and definition of SW_PROP_NMID)
+ // This entry is for adding that properties to OLE/EmbeddedObject import/export
+ FILL_PROPERTIES_SW
+ };
+
+ return aEmbeddedPropertyMap_Impl;
+}
+
+std::span<const SfxItemPropertyMapEntry> SwUnoPropertyMapProvider::GetIndexMarkPropertyMap()
+{
+ static SfxItemPropertyMapEntry const aIdxMarkMap_Impl[] =
+ {
+ { UNO_NAME_ALTERNATIVE_TEXT, WID_ALT_TEXT, cppu::UnoType<OUString>::get() , PROPERTY_NONE, 0},
+ { UNO_NAME_PRIMARY_KEY, WID_PRIMARY_KEY, cppu::UnoType<OUString>::get() , PROPERTY_NONE, 0},
+ { UNO_NAME_SECONDARY_KEY, WID_SECONDARY_KEY, cppu::UnoType<OUString>::get() , PROPERTY_NONE, 0},
+ { UNO_NAME_TEXT_READING, WID_TEXT_READING, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ { UNO_NAME_PRIMARY_KEY_READING, WID_PRIMARY_KEY_READING, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ { UNO_NAME_SECONDARY_KEY_READING, WID_SECONDARY_KEY_READING, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ { UNO_NAME_IS_MAIN_ENTRY, WID_MAIN_ENTRY, cppu::UnoType<bool>::get() , PROPERTY_NONE, 0},
+ COMMON_TEXT_CONTENT_PROPERTIES
+ };
+
+ return aIdxMarkMap_Impl;
+}
+
+std::span<const SfxItemPropertyMapEntry> SwUnoPropertyMapProvider::GetContentMarkPropertyMap()
+{
+ static SfxItemPropertyMapEntry const aContentMarkMap_Impl[] =
+ {
+ { UNO_NAME_ALTERNATIVE_TEXT, WID_ALT_TEXT, cppu::UnoType<OUString>::get() , PROPERTY_NONE, 0},
+ { UNO_NAME_LEVEL, WID_LEVEL , cppu::UnoType<sal_Int16>::get() , PROPERTY_NONE, 0},
+ COMMON_TEXT_CONTENT_PROPERTIES
+ };
+
+ return aContentMarkMap_Impl;
+}
+
+std::span<const SfxItemPropertyMapEntry> SwUnoPropertyMapProvider::GetUserMarkPropertyMap()
+{
+ static SfxItemPropertyMapEntry const aUserMarkMap_Impl[] =
+ {
+ { UNO_NAME_ALTERNATIVE_TEXT, WID_ALT_TEXT, cppu::UnoType<OUString>::get() , PROPERTY_NONE, 0},
+ { UNO_NAME_LEVEL, WID_LEVEL , cppu::UnoType<sal_Int16>::get() , PROPERTY_NONE, 0},
+ { UNO_NAME_USER_INDEX_NAME, WID_USER_IDX_NAME, cppu::UnoType<OUString>::get() , PROPERTY_NONE, 0},
+ COMMON_TEXT_CONTENT_PROPERTIES
+ };
+
+ return aUserMarkMap_Impl;
+}
+
+std::span<const SfxItemPropertyMapEntry> SwUnoPropertyMapProvider::GetTextTableCursorPropertyMap()
+{
+ // The PropertySet corresponds to the Range without Chart properties
+ static SfxItemPropertyMapEntry const aTableCursorPropertyMap_Impl [] =
+ {
+ COMMON_CRSR_PARA_PROPERTIES_WITHOUT_FN_01
+ TABSTOPS_MAP_ENTRY
+
+ // attributes from PROPERTY_MAP_TABLE_CELL:
+ { UNO_NAME_BACK_COLOR, FN_UNO_TABLE_CELL_BACKGROUND, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE , MID_BACK_COLOR },
+ { UNO_NAME_BACKGROUND_COMPLEX_COLOR, FN_UNO_TABLE_CELL_BACKGROUND, cppu::UnoType<css::util::XComplexColor>::get(), PROPERTY_NONE , MID_BACKGROUND_COMPLEX_COLOR },
+ { UNO_NAME_BACK_GRAPHIC_URL, RES_BACKGROUND, cppu::UnoType<OUString>::get(), PROPERTY_NONE ,MID_GRAPHIC_URL },
+ { UNO_NAME_BACK_GRAPHIC, RES_BACKGROUND, cppu::UnoType<graphic::XGraphic>::get(), PROPERTY_NONE, MID_GRAPHIC },
+ { UNO_NAME_BACK_GRAPHIC_FILTER, RES_BACKGROUND, cppu::UnoType<OUString>::get(), PROPERTY_NONE ,MID_GRAPHIC_FILTER },
+ { UNO_NAME_BACK_GRAPHIC_LOCATION, FN_UNO_TABLE_CELL_BACKGROUND, cppu::UnoType<css::style::GraphicLocation>::get(), PROPERTY_NONE ,MID_GRAPHIC_POSITION},
+ { UNO_NAME_NUMBER_FORMAT, RES_BOXATR_FORMAT, cppu::UnoType<sal_Int32>::get(), PropertyAttribute::MAYBEVOID ,0 },
+ { UNO_NAME_BACK_TRANSPARENT, FN_UNO_TABLE_CELL_BACKGROUND, cppu::UnoType<bool>::get(), PROPERTY_NONE , MID_GRAPHIC_TRANSPARENT },
+ { UNO_NAME_USER_DEFINED_ATTRIBUTES, RES_UNKNOWNATR_CONTAINER, cppu::UnoType<css::container::XNameContainer>::get(), PropertyAttribute::MAYBEVOID, 0 },
+ { UNO_NAME_TEXT_SECTION, FN_UNO_TEXT_SECTION, cppu::UnoType<css::text::XTextSection>::get(), PropertyAttribute::MAYBEVOID|PropertyAttribute::READONLY ,0 },
+ { UNO_NAME_IS_PROTECTED, RES_PROTECT, cppu::UnoType<bool>::get(), 0, MID_PROTECT_CONTENT},
+ { UNO_NAME_VERT_ORIENT, RES_VERT_ORIENT, cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE ,MID_VERTORIENT_ORIENT },
+ };
+
+ return aTableCursorPropertyMap_Impl;
+}
+
+std::span<const SfxItemPropertyMapEntry> SwUnoPropertyMapProvider::GetBookmarkPropertyMap()
+{
+ static SfxItemPropertyMapEntry const aBookmarkPropertyMap_Impl [] =
+ {
+ { UNO_LINK_DISPLAY_NAME, FN_PARAM_LINK_DISPLAY_NAME, cppu::UnoType<OUString>::get(), PropertyAttribute::READONLY, 0xbf},
+ COMMON_TEXT_CONTENT_PROPERTIES
+ { UNO_NAME_BOOKMARK_HIDDEN, FN_BOOKMARK_HIDDEN, cppu::UnoType<bool>::get(), PROPERTY_NONE, 0 },
+ { UNO_NAME_BOOKMARK_CONDITION, FN_BOOKMARK_CONDITION, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0 },
+ };
+
+ return aBookmarkPropertyMap_Impl;
+}
+
+std::span<const SfxItemPropertyMapEntry> SwUnoPropertyMapProvider::GetParagraphExtensionsPropertyMap()
+{
+ static SfxItemPropertyMapEntry const aParagraphExtensionsMap_Impl[] =
+ {
+ COMMON_TEXT_CONTENT_PROPERTIES
+ };
+
+ return aParagraphExtensionsMap_Impl;
+}
+
+std::span<const SfxItemPropertyMapEntry> SwUnoPropertyMapProvider::GetTextPortionExtensionPropertyMap()
+{
+ static SfxItemPropertyMapEntry const aTextPortionExtensionMap_Impl[] =
+ {
+ COMPLETE_TEXT_CURSOR_MAP
+ {UNO_NAME_BOOKMARK, FN_UNO_BOOKMARK, cppu::UnoType<css::text::XTextContent>::get(), PropertyAttribute::MAYBEVOID|PropertyAttribute::READONLY ,0 },
+ {UNO_NAME_CONTROL_CHARACTER, FN_UNO_CONTROL_CHARACTER, cppu::UnoType<sal_Int16>::get(), PropertyAttribute::MAYBEVOID|PropertyAttribute::READONLY, MID_HYPHEN_MIN_LEAD },
+ {UNO_NAME_IS_COLLAPSED, FN_UNO_IS_COLLAPSED, cppu::UnoType<bool>::get(), PropertyAttribute::MAYBEVOID|PropertyAttribute::READONLY, 0 },
+ {UNO_NAME_IS_START, FN_UNO_IS_START, cppu::UnoType<bool>::get(), PropertyAttribute::MAYBEVOID|PropertyAttribute::READONLY, 0 },
+ //REDLINE_PROPERTIES
+ {UNO_NAME_TEXT_PORTION_TYPE, FN_UNO_TEXT_PORTION_TYPE, cppu::UnoType<OUString>::get(), PropertyAttribute::READONLY, 0},
+ {UNO_NAME_META, FN_UNO_META, cppu::UnoType<css::text::XTextContent>::get(), PropertyAttribute::MAYBEVOID|PropertyAttribute::READONLY, 0 },
+ {UNO_NAME_LINEBREAK, FN_UNO_LINEBREAK, cppu::UnoType<css::text::XTextContent>::get(), PropertyAttribute::MAYBEVOID|PropertyAttribute::READONLY ,0 },
+ {UNO_NAME_CONTENT_CONTROL, FN_UNO_CONTENT_CONTROL, cppu::UnoType<css::text::XTextContent>::get(), PropertyAttribute::MAYBEVOID|PropertyAttribute::READONLY, 0 },
+ };
+
+ return aTextPortionExtensionMap_Impl;
+}
+
+std::span<const SfxItemPropertyMapEntry> SwUnoPropertyMapProvider::GetFootnotePropertyMap()
+{
+ static SfxItemPropertyMapEntry const aFootnoteMap_Impl[] =
+ {
+ {UNO_NAME_REFERENCE_ID, 0, cppu::UnoType<sal_Int16>::get(),PropertyAttribute::READONLY|PropertyAttribute::MAYBEVOID, 0},
+ COMMON_TEXT_CONTENT_PROPERTIES
+ REDLINE_NODE_PROPERTIES
+ };
+
+ return aFootnoteMap_Impl;
+}
+
+std::span<const SfxItemPropertyMapEntry> SwUnoPropertyMapProvider::GetLineBreakPropertyMap()
+{
+ static SfxItemPropertyMapEntry const aLineBreakMap_Impl[] =
+ {
+ { UNO_NAME_CLEAR, 0, cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE, 0 },
+ COMMON_TEXT_CONTENT_PROPERTIES
+ };
+
+ return aLineBreakMap_Impl;
+}
+
+std::span<const SfxItemPropertyMapEntry> SwUnoPropertyMapProvider::GetContentControlPropertyMap()
+{
+ static SfxItemPropertyMapEntry const aContentControlMap_Impl[] =
+ {
+ { UNO_NAME_SHOWING_PLACE_HOLDER, 0, cppu::UnoType<bool>::get(), PROPERTY_NONE, 0 },
+ { UNO_NAME_CHECKBOX, 0, cppu::UnoType<bool>::get(), PROPERTY_NONE, 0 },
+ { UNO_NAME_CHECKED, 0, cppu::UnoType<bool>::get(), PROPERTY_NONE, 0 },
+ { UNO_NAME_CHECKED_STATE, 0, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0 },
+ { UNO_NAME_UNCHECKED_STATE, 0, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0 },
+ { UNO_NAME_LIST_ITEMS, 0, cppu::UnoType<uno::Sequence<uno::Sequence<beans::PropertyValue>>>::get(), PROPERTY_NONE, 0 },
+ { UNO_NAME_PICTURE, 0, cppu::UnoType<bool>::get(), PROPERTY_NONE, 0 },
+ { UNO_NAME_DATE, 0, cppu::UnoType<bool>::get(), PROPERTY_NONE, 0 },
+ { UNO_NAME_DATE_FORMAT, 0, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0 },
+ { UNO_NAME_DATE_LANGUAGE, 0, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0 },
+ { UNO_NAME_CURRENT_DATE, 0, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0 },
+ { UNO_NAME_PLAIN_TEXT, 0, cppu::UnoType<bool>::get(), PROPERTY_NONE, 0 },
+ { UNO_NAME_COMBO_BOX, 0, cppu::UnoType<bool>::get(), PROPERTY_NONE, 0 },
+ { UNO_NAME_DROP_DOWN, 0, cppu::UnoType<bool>::get(), PROPERTY_NONE, 0 },
+ { UNO_NAME_PLACEHOLDER_DOC_PART, 0, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0 },
+ { UNO_NAME_DATA_BINDING_PREFIX_MAPPINGS, 0, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0 },
+ { UNO_NAME_DATA_BINDING_XPATH, 0, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0 },
+ { UNO_NAME_DATA_BINDING_STORE_ITEM_ID, 0, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0 },
+ { UNO_NAME_COLOR, 0, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0 },
+ { UNO_NAME_APPEARANCE, 0, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0 },
+ { UNO_NAME_ALIAS, 0, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0 },
+ { UNO_NAME_TAG, 0, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0 },
+ { UNO_NAME_ID, 0, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE, 0 },
+ { UNO_NAME_TAB_INDEX, 0, cppu::UnoType<sal_uInt32>::get(), PROPERTY_NONE, 0 },
+ { UNO_NAME_LOCK, 0, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0 },
+ { UNO_NAME_MULTILINE, 0, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0 },
+ { UNO_NAME_DATE_STRING, 0, cppu::UnoType<OUString>::get(), PropertyAttribute::READONLY, 0 },
+ };
+
+ return aContentControlMap_Impl;
+}
+
+std::span<const SfxItemPropertyMapEntry> SwUnoPropertyMapProvider::GetRedlinePropertyMap()
+{
+ static SfxItemPropertyMapEntry const aRedlineMap_Impl[] =
+ {
+ REDLINE_PROPERTIES(PropertyAttribute::READONLY)
+ REDLINE_NODE_PROPERTIES
+ {UNO_NAME_REDLINE_START, 0, cppu::UnoType<css::uno::XInterface>::get(), PropertyAttribute::READONLY, 0},
+ {UNO_NAME_REDLINE_END, 0, cppu::UnoType<css::uno::XInterface>::get(), PropertyAttribute::MAYBEVOID|PropertyAttribute::READONLY, 0},
+ };
+
+ return aRedlineMap_Impl;
+}
+
+std::span<SfxItemPropertyMapEntry> SwUnoPropertyMapProvider::GetTextDefaultPropertyMap()
+{
+ static SfxItemPropertyMapEntry aTextDefaultMap_Impl[] =
+ {
+ { UNO_NAME_TAB_STOP_DISTANCE, RES_PARATR_TABSTOP, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE, MID_STD_TAB | CONVERT_TWIPS},
+ COMMON_CRSR_PARA_PROPERTIES_WITHOUT_FN
+ COMMON_HYPERLINK_PROPERTIES
+ { UNO_NAME_CHAR_STYLE_NAME, RES_TXTATR_CHARFMT, cppu::UnoType<OUString>::get(), PropertyAttribute::MAYBEVOID, 0},
+ { UNO_NAME_IS_SPLIT_ALLOWED, RES_ROW_SPLIT, cppu::UnoType<bool>::get() , PropertyAttribute::MAYBEVOID, 0},
+ // #i29550#
+ { UNO_NAME_COLLAPSING_BORDERS, RES_COLLAPSING_BORDERS, cppu::UnoType<bool>::get(), PROPERTY_NONE, 0},
+
+ //text grid enhancement for better CJK support. 2007-04-01
+ //just export the default page mode property, other properties are not handled in this version
+ { UNO_NAME_GRID_STANDARD_PAGE_MODE, RES_TEXTGRID, cppu::UnoType<bool>::get(), PROPERTY_NONE, MID_GRID_STANDARD_MODE},
+ };
+
+ return aTextDefaultMap_Impl;
+}
+
+std::span<const SfxItemPropertyMapEntry> SwUnoPropertyMapProvider::GetRedlinePortionPropertyMap()
+{
+ static SfxItemPropertyMapEntry const aRedlinePortionMap_Impl[] =
+ {
+ COMPLETE_TEXT_CURSOR_MAP
+ {UNO_NAME_BOOKMARK, FN_UNO_BOOKMARK, cppu::UnoType<css::text::XTextContent>::get(), PropertyAttribute::MAYBEVOID|PropertyAttribute::READONLY ,0 },
+ {UNO_NAME_CONTROL_CHARACTER, FN_UNO_CONTROL_CHARACTER, cppu::UnoType<sal_Int16>::get(), PropertyAttribute::MAYBEVOID|PropertyAttribute::READONLY, MID_HYPHEN_MIN_LEAD },
+ {UNO_NAME_IS_COLLAPSED, FN_UNO_IS_COLLAPSED, cppu::UnoType<bool>::get(), PropertyAttribute::MAYBEVOID|PropertyAttribute::READONLY, 0 },
+ {UNO_NAME_IS_START, FN_UNO_IS_START, cppu::UnoType<bool>::get(), PropertyAttribute::MAYBEVOID|PropertyAttribute::READONLY, 0 },
+ REDLINE_PROPERTIES(0)
+ {UNO_NAME_TEXT_PORTION_TYPE, FN_UNO_TEXT_PORTION_TYPE, cppu::UnoType<OUString>::get(), PropertyAttribute::READONLY, 0},
+ };
+
+ return aRedlinePortionMap_Impl;
+}
+
+const SfxItemPropertySet* SwUnoPropertyMapProvider::GetPropertySet( sal_uInt16 nPropertyId)
+{
+ if( !m_aPropertySetArr[nPropertyId] )
+ {
+ std::span<const SfxItemPropertyMapEntry> pEntries = GetPropertyMapEntries(nPropertyId);
+ switch( nPropertyId )
+ {
+ case PROPERTY_MAP_TEXT_CURSOR:
+ {
+ static SfxItemPropertySet aPROPERTY_MAP_TEXT_CURSOR(pEntries);
+ m_aPropertySetArr[nPropertyId] = &aPROPERTY_MAP_TEXT_CURSOR;
+ }
+ break;
+ case PROPERTY_MAP_CHAR_STYLE:
+ {
+ static SfxItemPropertySet aPROPERTY_MAP_CHAR_STYLE(pEntries);
+ m_aPropertySetArr[nPropertyId] = &aPROPERTY_MAP_CHAR_STYLE;
+ }
+ break;
+ case PROPERTY_MAP_PARA_STYLE:
+ {
+ static SfxItemPropertySet aPROPERTY_MAP_PARA_STYLE(pEntries);
+ m_aPropertySetArr[nPropertyId] = &aPROPERTY_MAP_PARA_STYLE;
+ }
+ break;
+ case PROPERTY_MAP_FRAME_STYLE:
+ {
+ static SfxItemPropertySet aPROPERTY_MAP_FRAME_STYLE(pEntries);
+ m_aPropertySetArr[nPropertyId] = &aPROPERTY_MAP_FRAME_STYLE;
+ }
+ break;
+ case PROPERTY_MAP_PAGE_STYLE:
+ {
+ static SfxItemPropertySet aPROPERTY_MAP_PAGE_STYLE(pEntries);
+ m_aPropertySetArr[nPropertyId] = &aPROPERTY_MAP_PAGE_STYLE;
+ }
+ break;
+ case PROPERTY_MAP_NUM_STYLE:
+ {
+ static SfxItemPropertySet aPROPERTY_MAP_NUM_STYLE(pEntries);
+ m_aPropertySetArr[nPropertyId] = &aPROPERTY_MAP_NUM_STYLE;
+ }
+ break;
+ case PROPERTY_MAP_SECTION:
+ {
+ static SfxItemPropertySet aPROPERTY_MAP_SECTION(pEntries);
+ m_aPropertySetArr[nPropertyId] = &aPROPERTY_MAP_SECTION;
+ }
+ break;
+ case PROPERTY_MAP_TEXT_TABLE:
+ {
+ static SfxItemPropertySet aPROPERTY_MAP_TEXT_TABLE(pEntries);
+ m_aPropertySetArr[nPropertyId] = &aPROPERTY_MAP_TEXT_TABLE;
+ }
+ break;
+ case PROPERTY_MAP_TABLE_CELL:
+ {
+ static SfxItemPropertySet aPROPERTY_MAP_TABLE_CELL(pEntries);
+ m_aPropertySetArr[nPropertyId] = &aPROPERTY_MAP_TABLE_CELL;
+ }
+ break;
+ case PROPERTY_MAP_TABLE_RANGE:
+ {
+ static SfxItemPropertySet aPROPERTY_MAP_TABLE_RANGE(pEntries);
+ m_aPropertySetArr[nPropertyId] = &aPROPERTY_MAP_TABLE_RANGE;
+ }
+ break;
+ case PROPERTY_MAP_TEXT_SEARCH:
+ {
+ static SfxItemPropertySet aPROPERTY_MAP_TEXT_SEARCH(pEntries);
+ m_aPropertySetArr[nPropertyId] = &aPROPERTY_MAP_TEXT_SEARCH;
+ }
+ break;
+ case PROPERTY_MAP_TEXT_FRAME:
+ {
+ static SfxItemPropertySet aPROPERTY_MAP_TEXT_FRAME(pEntries);
+ m_aPropertySetArr[nPropertyId] = &aPROPERTY_MAP_TEXT_FRAME;
+ }
+ break;
+ case PROPERTY_MAP_TEXT_GRAPHIC:
+ {
+ static SfxItemPropertySet aPROPERTY_MAP_TEXT_GRAPHIC(pEntries);
+ m_aPropertySetArr[nPropertyId] = &aPROPERTY_MAP_TEXT_GRAPHIC;
+ }
+ break;
+ case PROPERTY_MAP_TEXT_PAGE:
+ {
+ static SfxItemPropertySet aPROPERTY_MAP_TEXT_PAGE(pEntries);
+ m_aPropertySetArr[nPropertyId] = &aPROPERTY_MAP_TEXT_PAGE;
+ }
+ break;
+ case PROPERTY_MAP_TEXT_SHAPE:
+ {
+ static SfxItemPropertySet aPROPERTY_MAP_TEXT_SHAPE(pEntries);
+ m_aPropertySetArr[nPropertyId] = &aPROPERTY_MAP_TEXT_SHAPE;
+ }
+ break;
+ case PROPERTY_MAP_INDEX_USER:
+ {
+ static SfxItemPropertySet aPROPERTY_MAP_INDEX_USER(pEntries);
+ m_aPropertySetArr[nPropertyId] = &aPROPERTY_MAP_INDEX_USER;
+ }
+ break;
+ case PROPERTY_MAP_INDEX_CNTNT:
+ {
+ static SfxItemPropertySet aPROPERTY_MAP_INDEX_CNTNT(pEntries);
+ m_aPropertySetArr[nPropertyId] = &aPROPERTY_MAP_INDEX_CNTNT;
+ }
+ break;
+ case PROPERTY_MAP_INDEX_IDX:
+ {
+ static SfxItemPropertySet aPROPERTY_MAP_INDEX_IDX(pEntries);
+ m_aPropertySetArr[nPropertyId] = &aPROPERTY_MAP_INDEX_IDX;
+ }
+ break;
+ case PROPERTY_MAP_USER_MARK:
+ {
+ static SfxItemPropertySet aPROPERTY_MAP_USER_MARK(pEntries);
+ m_aPropertySetArr[nPropertyId] = &aPROPERTY_MAP_USER_MARK;
+ }
+ break;
+ case PROPERTY_MAP_CNTIDX_MARK:
+ {
+ static SfxItemPropertySet aPROPERTY_MAP_CNTIDX_MARK(pEntries);
+ m_aPropertySetArr[nPropertyId] = &aPROPERTY_MAP_CNTIDX_MARK;
+ }
+ break;
+ case PROPERTY_MAP_INDEX_MARK:
+ {
+ static SfxItemPropertySet aPROPERTY_MAP_INDEX_MARK(pEntries);
+ m_aPropertySetArr[nPropertyId] = &aPROPERTY_MAP_INDEX_MARK;
+ }
+ break;
+ case PROPERTY_MAP_TEXT_TABLE_ROW:
+ {
+ static SfxItemPropertySet aPROPERTY_MAP_TEXT_TABLE_ROW(pEntries);
+ m_aPropertySetArr[nPropertyId] = &aPROPERTY_MAP_TEXT_TABLE_ROW;
+ }
+ break;
+ case PROPERTY_MAP_TEXT_SHAPE_DESCRIPTOR:
+ {
+ static SfxItemPropertySet aPROPERTY_MAP_TEXT_SHAPE_DESCRIPTOR(pEntries);
+ m_aPropertySetArr[nPropertyId] = &aPROPERTY_MAP_TEXT_SHAPE_DESCRIPTOR;
+ }
+ break;
+ case PROPERTY_MAP_TEXT_TABLE_CURSOR:
+ {
+ static SfxItemPropertySet aPROPERTY_MAP_TEXT_TABLE_CURSOR(pEntries);
+ m_aPropertySetArr[nPropertyId] = &aPROPERTY_MAP_TEXT_TABLE_CURSOR;
+ }
+ break;
+ case PROPERTY_MAP_BOOKMARK:
+ {
+ static SfxItemPropertySet aPROPERTY_MAP_BOOKMARK(pEntries);
+ 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);
+ m_aPropertySetArr[nPropertyId] = &aPROPERTY_MAP_PARAGRAPH_EXTENSIONS;
+ }
+ break;
+ case PROPERTY_MAP_INDEX_ILLUSTRATIONS:
+ {
+ static SfxItemPropertySet aPROPERTY_MAP_INDEX_ILLUSTRATIONS(pEntries);
+ m_aPropertySetArr[nPropertyId] = &aPROPERTY_MAP_INDEX_ILLUSTRATIONS;
+ }
+ break;
+ case PROPERTY_MAP_INDEX_OBJECTS:
+ {
+ static SfxItemPropertySet aPROPERTY_MAP_INDEX_OBJECTS(pEntries);
+ m_aPropertySetArr[nPropertyId] = &aPROPERTY_MAP_INDEX_OBJECTS;
+ }
+ break;
+ case PROPERTY_MAP_INDEX_TABLES:
+ {
+ static SfxItemPropertySet aPROPERTY_MAP_INDEX_TABLES(pEntries);
+ m_aPropertySetArr[nPropertyId] = &aPROPERTY_MAP_INDEX_TABLES;
+ }
+ break;
+ case PROPERTY_MAP_BIBLIOGRAPHY :
+ {
+ static SfxItemPropertySet aPROPERTY_MAP_BIBLIOGRAPHY(pEntries);
+ m_aPropertySetArr[nPropertyId] = &aPROPERTY_MAP_BIBLIOGRAPHY;
+ }
+ break;
+ case PROPERTY_MAP_TEXT_DOCUMENT:
+ {
+ static SfxItemPropertySet aPROPERTY_MAP_TEXT_DOCUMENT(pEntries);
+ m_aPropertySetArr[nPropertyId] = &aPROPERTY_MAP_TEXT_DOCUMENT;
+ }
+ break;
+ case PROPERTY_MAP_LINK_TARGET :
+ {
+ static SfxItemPropertySet aPROPERTY_MAP_LINK_TARGET(pEntries);
+ m_aPropertySetArr[nPropertyId] = &aPROPERTY_MAP_LINK_TARGET;
+ }
+ break;
+ case PROPERTY_MAP_AUTO_TEXT_GROUP :
+ {
+ static SfxItemPropertySet aPROPERTY_MAP_AUTO_TEXT_GROUP(pEntries);
+ m_aPropertySetArr[nPropertyId] = &aPROPERTY_MAP_AUTO_TEXT_GROUP;
+ }
+ break;
+ case PROPERTY_MAP_TEXTPORTION_EXTENSIONS :
+ {
+ static SfxItemPropertySet aPROPERTY_MAP_TEXTPORTION_EXTENSIONS(pEntries);
+ m_aPropertySetArr[nPropertyId] = &aPROPERTY_MAP_TEXTPORTION_EXTENSIONS;
+ }
+ break;
+ case PROPERTY_MAP_FOOTNOTE :
+ {
+ static SfxItemPropertySet aPROPERTY_MAP_FOOTNOTE(pEntries);
+ m_aPropertySetArr[nPropertyId] = &aPROPERTY_MAP_FOOTNOTE;
+ }
+ break;
+ case PROPERTY_MAP_PARAGRAPH :
+ {
+ static SfxItemPropertySet aPROPERTY_MAP_PARAGRAPH(pEntries);
+ m_aPropertySetArr[nPropertyId] = &aPROPERTY_MAP_PARAGRAPH;
+ }
+ break;
+ case PROPERTY_MAP_EMBEDDED_OBJECT :
+ {
+ static SfxItemPropertySet aPROPERTY_MAP_EMBEDDED_OBJECT(pEntries);
+ m_aPropertySetArr[nPropertyId] = &aPROPERTY_MAP_EMBEDDED_OBJECT;
+ }
+ break;
+ case PROPERTY_MAP_REDLINE :
+ {
+ static SfxItemPropertySet aPROPERTY_MAP_REDLINE(pEntries);
+ m_aPropertySetArr[nPropertyId] = &aPROPERTY_MAP_REDLINE;
+ }
+ break;
+ case PROPERTY_MAP_TEXT_DEFAULT :
+ {
+ static SfxItemPropertySet aPROPERTY_MAP_TEXT_DEFAULT(pEntries);
+ m_aPropertySetArr[nPropertyId] = &aPROPERTY_MAP_TEXT_DEFAULT;
+ }
+ break;
+ case PROPERTY_MAP_FLDTYP_DATETIME:
+ {
+ static SfxItemPropertySet aPROPERTY_MAP_FLDTYP_DATETIME(pEntries);
+ m_aPropertySetArr[nPropertyId] = &aPROPERTY_MAP_FLDTYP_DATETIME;
+ }
+ break;
+ case PROPERTY_MAP_FLDTYP_USER:
+ {
+ static SfxItemPropertySet aPROPERTY_MAP_FLDTYP_USER(pEntries);
+ m_aPropertySetArr[nPropertyId] = &aPROPERTY_MAP_FLDTYP_USER;
+ }
+ break;
+ case PROPERTY_MAP_FLDTYP_SET_EXP:
+ {
+ static SfxItemPropertySet aPROPERTY_MAP_FLDTYP_SET_EXP(pEntries);
+ m_aPropertySetArr[nPropertyId] = &aPROPERTY_MAP_FLDTYP_SET_EXP;
+ }
+ break;
+ case PROPERTY_MAP_FLDTYP_GET_EXP:
+ {
+ static SfxItemPropertySet aPROPERTY_MAP_FLDTYP_GET_EXP(pEntries);
+ m_aPropertySetArr[nPropertyId] = &aPROPERTY_MAP_FLDTYP_GET_EXP;
+ }
+ break;
+ case PROPERTY_MAP_FLDTYP_FILE_NAME:
+ {
+ static SfxItemPropertySet aPROPERTY_MAP_FLDTYP_FILE_NAME(pEntries);
+ m_aPropertySetArr[nPropertyId] = &aPROPERTY_MAP_FLDTYP_FILE_NAME;
+ }
+ break;
+ case PROPERTY_MAP_FLDTYP_PAGE_NUM:
+ {
+ static SfxItemPropertySet aPROPERTY_MAP_FLDTYP_PAGE_NUM(pEntries);
+ m_aPropertySetArr[nPropertyId] = &aPROPERTY_MAP_FLDTYP_PAGE_NUM;
+ }
+ break;
+ case PROPERTY_MAP_FLDTYP_AUTHOR:
+ {
+ static SfxItemPropertySet aPROPERTY_MAP_FLDTYP_AUTHOR(pEntries);
+ m_aPropertySetArr[nPropertyId] = &aPROPERTY_MAP_FLDTYP_AUTHOR;
+ }
+ break;
+ case PROPERTY_MAP_FLDTYP_CHAPTER:
+ {
+ static SfxItemPropertySet aPROPERTY_MAP_FLDTYP_CHAPTER(pEntries);
+ m_aPropertySetArr[nPropertyId] = &aPROPERTY_MAP_FLDTYP_CHAPTER;
+ }
+ break;
+ case PROPERTY_MAP_FLDTYP_GET_REFERENCE:
+ {
+ static SfxItemPropertySet aPROPERTY_MAP_FLDTYP_GET_REFERENCE(pEntries);
+ m_aPropertySetArr[nPropertyId] = &aPROPERTY_MAP_FLDTYP_GET_REFERENCE;
+ }
+ break;
+ case PROPERTY_MAP_FLDTYP_CONDITIONED_TEXT:
+ {
+ static SfxItemPropertySet aPROPERTY_MAP_FLDTYP_CONDITIONED_TEXT(pEntries);
+ m_aPropertySetArr[nPropertyId] = &aPROPERTY_MAP_FLDTYP_CONDITIONED_TEXT;
+ }
+ break;
+ case PROPERTY_MAP_FLDTYP_HIDDEN_TEXT:
+ {
+ static SfxItemPropertySet aPROPERTY_MAP_FLDTYP_HIDDEN_TEXT(pEntries);
+ m_aPropertySetArr[nPropertyId] = &aPROPERTY_MAP_FLDTYP_HIDDEN_TEXT;
+ }
+ break;
+ case PROPERTY_MAP_FLDTYP_ANNOTATION :
+ {
+ static SfxItemPropertySet aPROPERTY_MAP_FLDTYP_ANNOTATION(pEntries);
+ m_aPropertySetArr[nPropertyId] = &aPROPERTY_MAP_FLDTYP_ANNOTATION;
+ }
+ break;
+ case PROPERTY_MAP_FLDTYP_INPUT:
+ {
+ static SfxItemPropertySet aPROPERTY_MAP_FLDTYP_INPUT(pEntries);
+ m_aPropertySetArr[nPropertyId] = &aPROPERTY_MAP_FLDTYP_INPUT;
+ }
+ break;
+ case PROPERTY_MAP_FLDTYP_MACRO:
+ {
+ static SfxItemPropertySet aPROPERTY_MAP_FLDTYP_MACRO(pEntries);
+ m_aPropertySetArr[nPropertyId] = &aPROPERTY_MAP_FLDTYP_MACRO;
+ }
+ break;
+ case PROPERTY_MAP_FLDTYP_DDE:
+ {
+ static SfxItemPropertySet aPROPERTY_MAP_FLDTYP_DDE(pEntries);
+ m_aPropertySetArr[nPropertyId] = &aPROPERTY_MAP_FLDTYP_DDE;
+ }
+ break;
+ case PROPERTY_MAP_FLDTYP_HIDDEN_PARA:
+ {
+ static SfxItemPropertySet aPROPERTY_MAP_FLDTYP_HIDDEN_PARA(pEntries);
+ m_aPropertySetArr[nPropertyId] = &aPROPERTY_MAP_FLDTYP_HIDDEN_PARA;
+ }
+ break;
+ case PROPERTY_MAP_FLDTYP_DOC_INFO :
+ {
+ static SfxItemPropertySet aPROPERTY_MAP_FLDTYP_DOC_INFO(pEntries);
+ m_aPropertySetArr[nPropertyId] = &aPROPERTY_MAP_FLDTYP_DOC_INFO;
+ }
+ break;
+ case PROPERTY_MAP_FLDTYP_TEMPLATE_NAME:
+ {
+ static SfxItemPropertySet aPROPERTY_MAP_FLDTYP_TEMPLATE_NAME(pEntries);
+ m_aPropertySetArr[nPropertyId] = &aPROPERTY_MAP_FLDTYP_TEMPLATE_NAME;
+ }
+ break;
+ case PROPERTY_MAP_FLDTYP_USER_EXT :
+ {
+ static SfxItemPropertySet aPROPERTY_MAP_FLDTYP_USER_EXT(pEntries);
+ m_aPropertySetArr[nPropertyId] = &aPROPERTY_MAP_FLDTYP_USER_EXT;
+ }
+ break;
+ case PROPERTY_MAP_FLDTYP_REF_PAGE_SET:
+ {
+ static SfxItemPropertySet aPROPERTY_MAP_FLDTYP_REF_PAGE_SET(pEntries);
+ m_aPropertySetArr[nPropertyId] = &aPROPERTY_MAP_FLDTYP_REF_PAGE_SET;
+ }
+ break;
+ case PROPERTY_MAP_FLDTYP_REF_PAGE_GET:
+ {
+ static SfxItemPropertySet aPROPERTY_MAP_FLDTYP_REF_PAGE_GET(pEntries);
+ m_aPropertySetArr[nPropertyId] = &aPROPERTY_MAP_FLDTYP_REF_PAGE_GET;
+ }
+ break;
+ case PROPERTY_MAP_FLDTYP_JUMP_EDIT:
+ {
+ static SfxItemPropertySet aPROPERTY_MAP_FLDTYP_JUMP_EDIT(pEntries);
+ m_aPropertySetArr[nPropertyId] = &aPROPERTY_MAP_FLDTYP_JUMP_EDIT;
+ }
+ break;
+ case PROPERTY_MAP_FLDTYP_SCRIPT:
+ {
+ static SfxItemPropertySet aPROPERTY_MAP_FLDTYP_SCRIPT(pEntries);
+ m_aPropertySetArr[nPropertyId] = &aPROPERTY_MAP_FLDTYP_SCRIPT;
+ }
+ break;
+ case PROPERTY_MAP_FLDTYP_DATABASE_NEXT_SET:
+ {
+ static SfxItemPropertySet aPROPERTY_MAP_FLDTYP_DATABASE_NEXT_SET(pEntries);
+ m_aPropertySetArr[nPropertyId] = &aPROPERTY_MAP_FLDTYP_DATABASE_NEXT_SET;
+ }
+ break;
+ case PROPERTY_MAP_FLDTYP_DATABASE_NUM_SET:
+ {
+ static SfxItemPropertySet aPROPERTY_MAP_FLDTYP_DATABASE_NUM_SET(pEntries);
+ m_aPropertySetArr[nPropertyId] = &aPROPERTY_MAP_FLDTYP_DATABASE_NUM_SET;
+ }
+ break;
+ case PROPERTY_MAP_FLDTYP_DATABASE_SET_NUM:
+ {
+ static SfxItemPropertySet aPROPERTY_MAP_FLDTYP_DATABASE_SET_NUM(pEntries);
+ m_aPropertySetArr[nPropertyId] = &aPROPERTY_MAP_FLDTYP_DATABASE_SET_NUM;
+ }
+ break;
+ case PROPERTY_MAP_FLDTYP_DATABASE:
+ {
+ static SfxItemPropertySet aPROPERTY_MAP_FLDTYP_DATABASE(pEntries);
+ m_aPropertySetArr[nPropertyId] = &aPROPERTY_MAP_FLDTYP_DATABASE;
+ }
+ break;
+ case PROPERTY_MAP_FLDTYP_DATABASE_NAME:
+ {
+ static SfxItemPropertySet aPROPERTY_MAP_FLDTYP_DATABASE_NAME(pEntries);
+ m_aPropertySetArr[nPropertyId] = &aPROPERTY_MAP_FLDTYP_DATABASE_NAME;
+ }
+ break;
+ case PROPERTY_MAP_FLDTYP_DOCSTAT:
+ {
+ static SfxItemPropertySet aPROPERTY_MAP_FLDTYP_DOCSTAT(pEntries);
+ m_aPropertySetArr[nPropertyId] = &aPROPERTY_MAP_FLDTYP_DOCSTAT;
+ }
+ break;
+ case PROPERTY_MAP_FLDTYP_DOCINFO_AUTHOR:
+ {
+ static SfxItemPropertySet aPROPERTY_MAP_FLDTYP_DOCINFO_AUTHOR(pEntries);
+ m_aPropertySetArr[nPropertyId] = &aPROPERTY_MAP_FLDTYP_DOCINFO_AUTHOR;
+ }
+ break;
+ case PROPERTY_MAP_FLDTYP_DOCINFO_DATE_TIME:
+ {
+ static SfxItemPropertySet aPROPERTY_MAP_FLDTYP_DOCINFO_DATE_TIME(pEntries);
+ m_aPropertySetArr[nPropertyId] = &aPROPERTY_MAP_FLDTYP_DOCINFO_DATE_TIME;
+ }
+ break;
+ case PROPERTY_MAP_FLDTYP_DOCINFO_CHANGE_DATE_TIME:
+ {
+ static SfxItemPropertySet aPROPERTY_MAP_FLDTYP_DOCINFO_CHANGE_DATE_TIME(pEntries);
+ m_aPropertySetArr[nPropertyId] = &aPROPERTY_MAP_FLDTYP_DOCINFO_CHANGE_DATE_TIME;
+ }
+ break;
+ case PROPERTY_MAP_FLDTYP_DOCINFO_CREATE_DATE_TIME:
+ {
+ static SfxItemPropertySet aPROPERTY_MAP_FLDTYP_DOCINFO_CREATE_DATE_TIME(pEntries);
+ m_aPropertySetArr[nPropertyId] = &aPROPERTY_MAP_FLDTYP_DOCINFO_CREATE_DATE_TIME;
+ }
+ break;
+ case PROPERTY_MAP_FLDTYP_DOCINFO_EDIT_TIME:
+ {
+ static SfxItemPropertySet aPROPERTY_MAP_FLDTYP_DOCINFO_EDIT_TIME(pEntries);
+ m_aPropertySetArr[nPropertyId] = &aPROPERTY_MAP_FLDTYP_DOCINFO_EDIT_TIME;
+ }
+ break;
+ case PROPERTY_MAP_FLDTYP_DOCINFO_MISC :
+ {
+ static SfxItemPropertySet aPROPERTY_MAP_FLDTYP_DOCINFO_MISC(pEntries);
+ m_aPropertySetArr[nPropertyId] = &aPROPERTY_MAP_FLDTYP_DOCINFO_MISC;
+ }
+ break;
+ case PROPERTY_MAP_FLDTYP_DOCINFO_REVISION:
+ {
+ static SfxItemPropertySet aPROPERTY_MAP_FLDTYP_DOCINFO_REVISION(pEntries);
+ m_aPropertySetArr[nPropertyId] = &aPROPERTY_MAP_FLDTYP_DOCINFO_REVISION;
+ }
+ break;
+ case PROPERTY_MAP_FLDTYP_COMBINED_CHARACTERS:
+ {
+ static SfxItemPropertySet aPROPERTY_MAP_FLDTYP_COMBINED_CHARACTERS(pEntries);
+ m_aPropertySetArr[nPropertyId] = &aPROPERTY_MAP_FLDTYP_COMBINED_CHARACTERS;
+ }
+ break;
+ case PROPERTY_MAP_FLDTYP_DUMMY_0:
+ {
+ static SfxItemPropertySet aPROPERTY_MAP_FLDTYP_DUMMY_0(pEntries);
+ m_aPropertySetArr[nPropertyId] = &aPROPERTY_MAP_FLDTYP_DUMMY_0;
+ }
+ break;
+ case PROPERTY_MAP_FLDTYP_TABLE_FORMULA:
+ {
+ static SfxItemPropertySet aPROPERTY_MAP_FLDTYP_TABLE_FORMULA(pEntries);
+ m_aPropertySetArr[nPropertyId] = &aPROPERTY_MAP_FLDTYP_TABLE_FORMULA;
+ }
+ break;
+ case PROPERTY_MAP_FLDMSTR_USER:
+ {
+ static SfxItemPropertySet aPROPERTY_MAP_FLDMSTR_USER(pEntries);
+ m_aPropertySetArr[nPropertyId] = &aPROPERTY_MAP_FLDMSTR_USER;
+ }
+ break;
+ case PROPERTY_MAP_FLDMSTR_DDE:
+ {
+ static SfxItemPropertySet aPROPERTY_MAP_FLDMSTR_DDE(pEntries);
+ m_aPropertySetArr[nPropertyId] = &aPROPERTY_MAP_FLDMSTR_DDE;
+ }
+ break;
+ case PROPERTY_MAP_FLDMSTR_SET_EXP:
+ {
+ static SfxItemPropertySet aPROPERTY_MAP_FLDMSTR_SET_EXP(pEntries);
+ m_aPropertySetArr[nPropertyId] = &aPROPERTY_MAP_FLDMSTR_SET_EXP;
+ }
+ break;
+ case PROPERTY_MAP_FLDMSTR_DATABASE:
+ {
+ static SfxItemPropertySet aPROPERTY_MAP_FLDMSTR_DATABASE(pEntries);
+ m_aPropertySetArr[nPropertyId] = &aPROPERTY_MAP_FLDMSTR_DATABASE;
+ }
+ break;
+ case PROPERTY_MAP_FLDMSTR_DUMMY0:
+ {
+ static SfxItemPropertySet aPROPERTY_MAP_FLDMSTR_DUMMY0(pEntries);
+ m_aPropertySetArr[nPropertyId] = &aPROPERTY_MAP_FLDMSTR_DUMMY0;
+ }
+ break;
+ case PROPERTY_MAP_FLDTYP_BIBLIOGRAPHY:
+ {
+ static SfxItemPropertySet aPROPERTY_MAP_FLDTYP_BIBLIOGRAPHY(pEntries);
+ m_aPropertySetArr[nPropertyId] = &aPROPERTY_MAP_FLDTYP_BIBLIOGRAPHY;
+ }
+ break;
+ case PROPERTY_MAP_FLDMSTR_BIBLIOGRAPHY:
+ {
+ static SfxItemPropertySet aPROPERTY_MAP_FLDMSTR_BIBLIOGRAPHY(pEntries);
+ m_aPropertySetArr[nPropertyId] = &aPROPERTY_MAP_FLDMSTR_BIBLIOGRAPHY;
+ }
+ break;
+ case PROPERTY_MAP_TEXT:
+ {
+ static SfxItemPropertySet aPROPERTY_MAP_TEXT(pEntries);
+ m_aPropertySetArr[nPropertyId] = &aPROPERTY_MAP_TEXT;
+ }
+ break;
+ case PROPERTY_MAP_REDLINE_PORTION:
+ {
+ static SfxItemPropertySet aPROPERTY_MAP_REDLINE_PORTION(pEntries);
+ m_aPropertySetArr[nPropertyId] = &aPROPERTY_MAP_REDLINE_PORTION;
+ }
+ break;
+ case PROPERTY_MAP_MAILMERGE:
+ {
+ static SfxItemPropertySet aPROPERTY_MAP_MAILMERGE(pEntries);
+ m_aPropertySetArr[nPropertyId] = &aPROPERTY_MAP_MAILMERGE;
+ }
+ break;
+ case PROPERTY_MAP_FLDTYP_DROPDOWN:
+ {
+ static SfxItemPropertySet aPROPERTY_MAP_FLDTYP_DROPDOWN(pEntries);
+ m_aPropertySetArr[nPropertyId] = &aPROPERTY_MAP_FLDTYP_DROPDOWN;
+ }
+ break;
+ case PROPERTY_MAP_CHART2_DATA_SEQUENCE:
+ {
+ static SfxItemPropertySet aPROPERTY_MAP_CHART2_DATA_SEQUENCE(pEntries);
+ m_aPropertySetArr[nPropertyId] = &aPROPERTY_MAP_CHART2_DATA_SEQUENCE;
+ }
+ break;
+ case PROPERTY_MAP_TEXT_VIEW:
+ {
+ static SfxItemPropertySet aPROPERTY_MAP_TEXT_VIEW(pEntries);
+ m_aPropertySetArr[nPropertyId] = &aPROPERTY_MAP_TEXT_VIEW;
+ }
+ break;
+ case PROPERTY_MAP_CONDITIONAL_PARA_STYLE:
+ {
+ static SfxItemPropertySet aPROPERTY_MAP_CONDITIONAL_PARA_STYLE(pEntries);
+ m_aPropertySetArr[nPropertyId] = &aPROPERTY_MAP_CONDITIONAL_PARA_STYLE;
+ }
+ break;
+ case PROPERTY_MAP_CHAR_AUTO_STYLE:
+ {
+ static SfxItemPropertySet aPROPERTY_MAP_CHAR_AUTO_STYLE(pEntries);
+ m_aPropertySetArr[nPropertyId] = &aPROPERTY_MAP_CHAR_AUTO_STYLE;
+ }
+ break;
+ case PROPERTY_MAP_RUBY_AUTO_STYLE:
+ {
+ static SfxItemPropertySet aPROPERTY_MAP_RUBY_AUTO_STYLE(pEntries);
+ m_aPropertySetArr[nPropertyId] = &aPROPERTY_MAP_RUBY_AUTO_STYLE;
+ }
+ break;
+ case PROPERTY_MAP_PARA_AUTO_STYLE:
+ {
+ static SfxItemPropertySet aPROPERTY_MAP_PARA_AUTO_STYLE(pEntries);
+ m_aPropertySetArr[nPropertyId] = &aPROPERTY_MAP_PARA_AUTO_STYLE;
+ }
+ break;
+ case PROPERTY_MAP_FLDTYP_DOCINFO_CUSTOM:
+ {
+ static SfxItemPropertySet aPROPERTY_MAP_FLDTYP_DOCINFO_CUSTOM(pEntries);
+ m_aPropertySetArr[nPropertyId] = &aPROPERTY_MAP_FLDTYP_DOCINFO_CUSTOM;
+ }
+ break;
+ case PROPERTY_MAP_METAFIELD:
+ {
+ static SfxItemPropertySet aPROPERTY_MAP_METAFIELD(pEntries);
+ m_aPropertySetArr[nPropertyId] = &aPROPERTY_MAP_METAFIELD;
+ }
+ break;
+ case PROPERTY_MAP_TABLE_STYLE:
+ {
+ static SfxItemPropertySet aPROPERTY_MAP_TABLE_STYLE(pEntries);
+ m_aPropertySetArr[nPropertyId] = &aPROPERTY_MAP_TABLE_STYLE;
+ }
+ break;
+ case PROPERTY_MAP_CELL_STYLE:
+ {
+ static SfxItemPropertySet aPROPERTY_MAP_CELL_STYLE(pEntries);
+ m_aPropertySetArr[nPropertyId] = &aPROPERTY_MAP_CELL_STYLE;
+ }
+ break;
+ case PROPERTY_MAP_LINEBREAK:
+ {
+ static SfxItemPropertySet aPROPERTY_MAP_LINEBREAK(pEntries);
+ m_aPropertySetArr[nPropertyId] = &aPROPERTY_MAP_LINEBREAK;
+ }
+ break;
+ case PROPERTY_MAP_CONTENTCONTROL:
+ {
+ static SfxItemPropertySet aPROPERTY_MAP_CONTENTCONTROL(pEntries);
+ m_aPropertySetArr[nPropertyId] = &aPROPERTY_MAP_CONTENTCONTROL;
+ }
+ break;
+ }
+ }
+ return m_aPropertySetArr[nPropertyId];
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/core/unocore/unomapproperties.hxx b/sw/source/core/unocore/unomapproperties.hxx
new file mode 100644
index 0000000000..2330ba8608
--- /dev/null
+++ b/sw/source/core/unocore/unomapproperties.hxx
@@ -0,0 +1,584 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+#ifndef INCLUDED_SW_INC_UNOMAPPROPERTIES_HXX
+#define INCLUDED_SW_INC_UNOMAPPROPERTIES_HXX
+
+// These are the unomap common properties used by unomap?.cxx
+
+#ifndef MID_TXT_LMARGIN
+#define MID_TXT_LMARGIN 11
+#endif
+
+#define STANDARD_FONT_PROPERTIES \
+ { UNO_NAME_CHAR_HEIGHT, RES_CHRATR_FONTSIZE , cppu::UnoType<float>::get(), PropertyAttribute::MAYBEVOID, MID_FONTHEIGHT|CONVERT_TWIPS}, \
+ { UNO_NAME_CHAR_WEIGHT, RES_CHRATR_WEIGHT , cppu::UnoType<float>::get(), PropertyAttribute::MAYBEVOID, MID_WEIGHT}, \
+ { UNO_NAME_CHAR_FONT_NAME, RES_CHRATR_FONT, cppu::UnoType<OUString>::get(), PropertyAttribute::MAYBEVOID, MID_FONT_FAMILY_NAME }, \
+ { UNO_NAME_CHAR_FONT_STYLE_NAME, RES_CHRATR_FONT, cppu::UnoType<OUString>::get(), PropertyAttribute::MAYBEVOID, MID_FONT_STYLE_NAME }, \
+ { UNO_NAME_CHAR_FONT_FAMILY, RES_CHRATR_FONT, cppu::UnoType<sal_Int16>::get(), PropertyAttribute::MAYBEVOID, MID_FONT_FAMILY }, \
+ { UNO_NAME_CHAR_FONT_CHAR_SET, RES_CHRATR_FONT, cppu::UnoType<sal_Int16>::get(), PropertyAttribute::MAYBEVOID, MID_FONT_CHAR_SET }, \
+ { UNO_NAME_CHAR_FONT_PITCH, RES_CHRATR_FONT, cppu::UnoType<sal_Int16>::get(), PropertyAttribute::MAYBEVOID, MID_FONT_PITCH }, \
+ { UNO_NAME_CHAR_POSTURE, RES_CHRATR_POSTURE , cppu::UnoType<css::awt::FontSlant>::get(), PropertyAttribute::MAYBEVOID, MID_POSTURE}, \
+ { UNO_NAME_RSID, RES_CHRATR_RSID, cppu::UnoType<sal_Int32>::get(), PropertyAttribute::MAYBEVOID, 0 }, \
+ { UNO_NAME_CHAR_LOCALE, RES_CHRATR_LANGUAGE, cppu::UnoType<css::lang::Locale>::get(), PropertyAttribute::MAYBEVOID, MID_LANG_LOCALE }, \
+ { UNO_NAME_CHAR_INTEROP_GRAB_BAG, RES_CHRATR_GRABBAG, cppu::UnoType< cppu::UnoSequenceType<css::beans::PropertyValue> >::get(), PROPERTY_NONE, 0 }, \
+
+#define CJK_FONT_PROPERTIES \
+ { UNO_NAME_CHAR_HEIGHT_ASIAN, RES_CHRATR_CJK_FONTSIZE , cppu::UnoType<float>::get(), PropertyAttribute::MAYBEVOID, MID_FONTHEIGHT|CONVERT_TWIPS}, \
+ { UNO_NAME_CHAR_WEIGHT_ASIAN, RES_CHRATR_CJK_WEIGHT , cppu::UnoType<float>::get(), PropertyAttribute::MAYBEVOID, MID_WEIGHT}, \
+ { UNO_NAME_CHAR_FONT_NAME_ASIAN, RES_CHRATR_CJK_FONT, cppu::UnoType<OUString>::get(), PropertyAttribute::MAYBEVOID, MID_FONT_FAMILY_NAME }, \
+ { UNO_NAME_CHAR_FONT_STYLE_NAME_ASIAN, RES_CHRATR_CJK_FONT, cppu::UnoType<OUString>::get(), PropertyAttribute::MAYBEVOID, MID_FONT_STYLE_NAME }, \
+ { UNO_NAME_CHAR_FONT_FAMILY_ASIAN, RES_CHRATR_CJK_FONT, cppu::UnoType<sal_Int16>::get(), PropertyAttribute::MAYBEVOID, MID_FONT_FAMILY }, \
+ { UNO_NAME_CHAR_FONT_CHAR_SET_ASIAN, RES_CHRATR_CJK_FONT, cppu::UnoType<sal_Int16>::get(), PropertyAttribute::MAYBEVOID, MID_FONT_CHAR_SET }, \
+ { UNO_NAME_CHAR_FONT_PITCH_ASIAN, RES_CHRATR_CJK_FONT, cppu::UnoType<sal_Int16>::get(), PropertyAttribute::MAYBEVOID, MID_FONT_PITCH }, \
+ { UNO_NAME_CHAR_POSTURE_ASIAN, RES_CHRATR_CJK_POSTURE , cppu::UnoType<css::awt::FontSlant>::get(), PropertyAttribute::MAYBEVOID, MID_POSTURE}, \
+ { UNO_NAME_CHAR_LOCALE_ASIAN, RES_CHRATR_CJK_LANGUAGE , cppu::UnoType<css::lang::Locale>::get() , PropertyAttribute::MAYBEVOID, MID_LANG_LOCALE },
+
+#define CTL_FONT_PROPERTIES \
+ { UNO_NAME_CHAR_HEIGHT_COMPLEX, RES_CHRATR_CTL_FONTSIZE , cppu::UnoType<float>::get(), PropertyAttribute::MAYBEVOID, MID_FONTHEIGHT|CONVERT_TWIPS},\
+ { UNO_NAME_CHAR_WEIGHT_COMPLEX, RES_CHRATR_CTL_WEIGHT , cppu::UnoType<float>::get(), PropertyAttribute::MAYBEVOID, MID_WEIGHT}, \
+ { UNO_NAME_CHAR_FONT_NAME_COMPLEX, RES_CHRATR_CTL_FONT, cppu::UnoType<OUString>::get(), PropertyAttribute::MAYBEVOID, MID_FONT_FAMILY_NAME }, \
+ { UNO_NAME_CHAR_FONT_STYLE_NAME_COMPLEX, RES_CHRATR_CTL_FONT, cppu::UnoType<OUString>::get(), PropertyAttribute::MAYBEVOID, MID_FONT_STYLE_NAME }, \
+ { UNO_NAME_CHAR_FONT_FAMILY_COMPLEX, RES_CHRATR_CTL_FONT, cppu::UnoType<sal_Int16>::get(), PropertyAttribute::MAYBEVOID, MID_FONT_FAMILY }, \
+ { UNO_NAME_CHAR_FONT_CHAR_SET_COMPLEX, RES_CHRATR_CTL_FONT, cppu::UnoType<sal_Int16>::get(), PropertyAttribute::MAYBEVOID, MID_FONT_CHAR_SET }, \
+ { UNO_NAME_CHAR_FONT_PITCH_COMPLEX, RES_CHRATR_CTL_FONT, cppu::UnoType<sal_Int16>::get(), PropertyAttribute::MAYBEVOID, MID_FONT_PITCH }, \
+ { UNO_NAME_CHAR_POSTURE_COMPLEX, RES_CHRATR_CTL_POSTURE , cppu::UnoType<css::awt::FontSlant>::get(), PropertyAttribute::MAYBEVOID, MID_POSTURE}, \
+ { UNO_NAME_CHAR_LOCALE_COMPLEX, RES_CHRATR_CTL_LANGUAGE , cppu::UnoType<css::lang::Locale>::get() , PropertyAttribute::MAYBEVOID, MID_LANG_LOCALE },
+
+#define REDLINE_NODE_PROPERTIES \
+ { UNO_NAME_START_REDLINE, FN_UNO_REDLINE_NODE_START , cppu::UnoType< cppu::UnoSequenceType<css::beans::PropertyValue> >::get(), PropertyAttribute::MAYBEVOID|PropertyAttribute::READONLY, 0xbf }, \
+ { UNO_NAME_END_REDLINE, FN_UNO_REDLINE_NODE_END , cppu::UnoType< cppu::UnoSequenceType<css::beans::PropertyValue> >::get(), PropertyAttribute::MAYBEVOID|PropertyAttribute::READONLY, 0xbf },
+
+#define REDLINE_PROPERTIES(readonly) \
+ { UNO_NAME_REDLINE_AUTHOR, 0, cppu::UnoType<OUString>::get(), PropertyAttribute::MAYBEVOID|PropertyAttribute::READONLY, 0},\
+ { UNO_NAME_REDLINE_DATE_TIME, 0, cppu::UnoType<css::util::DateTime>::get(), PropertyAttribute::MAYBEVOID|PropertyAttribute::READONLY, 0},\
+ { UNO_NAME_REDLINE_COMMENT, 0, cppu::UnoType<OUString>::get(), PropertyAttribute::MAYBEVOID|readonly, 0},\
+ { UNO_NAME_REDLINE_DESCRIPTION, 0, cppu::UnoType<OUString>::get(), PropertyAttribute::MAYBEVOID | PropertyAttribute::READONLY, 0}, \
+ { UNO_NAME_REDLINE_TYPE, 0, cppu::UnoType<OUString>::get(), PropertyAttribute::MAYBEVOID|PropertyAttribute::READONLY, 0},\
+ { UNO_NAME_REDLINE_SUCCESSOR_DATA, 0, cppu::UnoType< cppu::UnoSequenceType<css::beans::PropertyValue> >::get(), PropertyAttribute::MAYBEVOID|PropertyAttribute::READONLY, 0},\
+ { UNO_NAME_REDLINE_IDENTIFIER, 0, cppu::UnoType<OUString>::get(), PropertyAttribute::MAYBEVOID|PropertyAttribute::READONLY, 0},\
+ { UNO_NAME_IS_IN_HEADER_FOOTER, 0, cppu::UnoType<bool>::get(), PropertyAttribute::MAYBEVOID|PropertyAttribute::READONLY, 0},\
+ { UNO_NAME_REDLINE_TEXT, 0, cppu::UnoType<css::text::XText>::get(), PropertyAttribute::MAYBEVOID|PropertyAttribute::READONLY, 0},\
+ { UNO_NAME_MERGE_LAST_PARA, 0, cppu::UnoType<bool>::get(), PropertyAttribute::MAYBEVOID|PropertyAttribute::READONLY, 0},
+
+#define COMMON_CRSR_PARA_PROPERTIES_FN_ONLY \
+ { UNO_NAME_PARA_STYLE_NAME, FN_UNO_PARA_STYLE, cppu::UnoType<OUString>::get(), PropertyAttribute::MAYBEVOID, 0}, \
+ { UNO_NAME_PAGE_STYLE_NAME, FN_UNO_PAGE_STYLE, cppu::UnoType<OUString>::get(), PropertyAttribute::MAYBEVOID|PropertyAttribute::READONLY, 0}, \
+ { UNO_NAME_NUMBERING_IS_NUMBER, FN_UNO_IS_NUMBER, cppu::UnoType<bool>::get() , PropertyAttribute::MAYBEVOID, 0}, \
+ { UNO_NAME_NUMBERING_LEVEL, FN_UNO_NUM_LEVEL, cppu::UnoType<sal_Int16>::get(), PropertyAttribute::MAYBEVOID, 0}, \
+ { UNO_NAME_NUMBERING_RULES, FN_UNO_NUM_RULES, cppu::UnoType<css::container::XIndexReplace>::get(), PropertyAttribute::MAYBEVOID, CONVERT_TWIPS}, \
+ { UNO_NAME_NUMBERING_START_VALUE, FN_UNO_NUM_START_VALUE, cppu::UnoType<sal_Int16>::get(), PropertyAttribute::MAYBEVOID, CONVERT_TWIPS}, \
+ { UNO_NAME_DOCUMENT_INDEX, FN_UNO_DOCUMENT_INDEX, cppu::UnoType<css::text::XDocumentIndex>::get(), PropertyAttribute::MAYBEVOID|PropertyAttribute::READONLY ,0 }, \
+ { UNO_NAME_TEXT_TABLE, FN_UNO_TEXT_TABLE, cppu::UnoType<css::text::XTextTable>::get(), PropertyAttribute::MAYBEVOID|PropertyAttribute::READONLY ,0 }, \
+ { UNO_NAME_CELL, FN_UNO_CELL, cppu::UnoType<css::table::XCell>::get(), PropertyAttribute::MAYBEVOID|PropertyAttribute::READONLY ,0 }, \
+ { UNO_NAME_TEXT_FRAME, FN_UNO_TEXT_FRAME, cppu::UnoType<css::text::XTextFrame>::get(), PropertyAttribute::MAYBEVOID|PropertyAttribute::READONLY ,0 }, \
+ { UNO_NAME_TEXT_SECTION, FN_UNO_TEXT_SECTION, cppu::UnoType<css::text::XTextSection>::get(), PropertyAttribute::MAYBEVOID|PropertyAttribute::READONLY ,0 }, \
+ { UNO_NAME_TEXT_PARAGRAPH, FN_UNO_TEXT_PARAGRAPH, cppu::UnoType<css::text::XTextContent>::get(), PropertyAttribute::MAYBEVOID|PropertyAttribute::READONLY ,0 }, \
+ { UNO_NAME_SORTED_TEXT_ID, FN_UNO_SORTED_TEXT_ID, cppu::UnoType<sal_Int32>::get(), PropertyAttribute::MAYBEVOID|PropertyAttribute::READONLY ,0 }, \
+ { UNO_NAME_PARA_CHAPTER_NUMBERING_LEVEL, FN_UNO_PARA_CHAPTER_NUMBERING_LEVEL,cppu::UnoType<sal_Int8>::get(), PropertyAttribute::MAYBEVOID, 0}, \
+ { UNO_NAME_PARA_CONDITIONAL_STYLE_NAME, FN_UNO_PARA_CONDITIONAL_STYLE_NAME, cppu::UnoType<OUString>::get(), PropertyAttribute::READONLY, 0}, \
+ { UNO_NAME_LIST_ID, FN_UNO_LIST_ID, cppu::UnoType<OUString>::get(), PropertyAttribute::MAYBEVOID, 0}, \
+ { UNO_NAME_PARA_IS_NUMBERING_RESTART, FN_NUMBER_NEWSTART, cppu::UnoType<bool>::get(), PropertyAttribute::MAYBEVOID, 0 }, \
+ { UNO_NAME_PARA_CONTINUEING_PREVIOUS_SUB_TREE, FN_UNO_PARA_CONT_PREV_SUBTREE, cppu::UnoType<bool>::get(), PropertyAttribute::READONLY, 0 }, \
+ { UNO_NAME_PARA_LIST_LABEL_STRING, FN_UNO_PARA_NUM_STRING, cppu::UnoType<OUString>::get(), PropertyAttribute::READONLY, 0 }, \
+ { UNO_NAME_PARA_LIST_AUTO_FORMAT, FN_UNO_PARA_NUM_AUTO_FORMAT, cppu::UnoType<cppu::UnoSequenceType<css::beans::NamedValue>>::get(), PropertyAttribute::MAYBEVOID, 0 }, \
+ { UNO_NAME_OUTLINE_LEVEL, RES_PARATR_OUTLINELEVEL, cppu::UnoType<sal_Int16>::get(), PropertyAttribute::MAYBEVOID, 0}, \
+ { UNO_NAME_OUTLINE_CONTENT_VISIBLE, RES_PARATR_GRABBAG, cppu::UnoType<bool>::get(), PropertyAttribute::MAYBEVOID, 0 },
+
+#define COMMON_HYPERLINK_PROPERTIES \
+ { UNO_NAME_HYPER_LINK_U_R_L, RES_TXTATR_INETFMT, cppu::UnoType<OUString>::get(), PropertyAttribute::MAYBEVOID ,MID_URL_URL}, \
+ { UNO_NAME_HYPER_LINK_TARGET, RES_TXTATR_INETFMT, cppu::UnoType<OUString>::get(), PropertyAttribute::MAYBEVOID ,MID_URL_TARGET}, \
+ { UNO_NAME_HYPER_LINK_NAME, RES_TXTATR_INETFMT, cppu::UnoType<OUString>::get(), PropertyAttribute::MAYBEVOID ,MID_URL_HYPERLINKNAME }, \
+ { UNO_NAME_UNVISITED_CHAR_STYLE_NAME, RES_TXTATR_INETFMT, cppu::UnoType<OUString>::get(), PropertyAttribute::MAYBEVOID ,MID_URL_UNVISITED_FMT }, \
+ { UNO_NAME_VISITED_CHAR_STYLE_NAME, RES_TXTATR_INETFMT, cppu::UnoType<OUString>::get(), PropertyAttribute::MAYBEVOID ,MID_URL_VISITED_FMT },
+
+// same as COMMON_CRSR_PARA_PROPERTIES_WITHOUT_FN but without
+// UNO_NAME_BREAK_TYPE and UNO_NAME_PAGE_DESC_NAME which can not be used
+// by the SwXTextTableCursor
+#define COMMON_CRSR_PARA_PROPERTIES_WITHOUT_FN_01 \
+ { UNO_NAME_PARRSID, RES_PARATR_RSID, cppu::UnoType<sal_Int32>::get(), PropertyAttribute::MAYBEVOID, 0 }, \
+ { UNO_NAME_PARA_IS_HYPHENATION, RES_PARATR_HYPHENZONE, cppu::UnoType<bool>::get(), PropertyAttribute::MAYBEVOID, MID_IS_HYPHEN }, \
+ { UNO_NAME_PARA_HYPHENATION_NO_CAPS, RES_PARATR_HYPHENZONE, cppu::UnoType<bool>::get(), PropertyAttribute::MAYBEVOID, MID_HYPHEN_NO_CAPS }, \
+ { UNO_NAME_PARA_HYPHENATION_NO_LAST_WORD, RES_PARATR_HYPHENZONE, cppu::UnoType<bool>::get(), PropertyAttribute::MAYBEVOID, MID_HYPHEN_NO_LAST_WORD }, \
+ { UNO_NAME_PARA_HYPHENATION_MAX_LEADING_CHARS, RES_PARATR_HYPHENZONE, cppu::UnoType<sal_Int16>::get(), PropertyAttribute::MAYBEVOID, MID_HYPHEN_MIN_LEAD }, \
+ { UNO_NAME_PARA_HYPHENATION_MAX_TRAILING_CHARS, RES_PARATR_HYPHENZONE, cppu::UnoType<sal_Int16>::get(), PropertyAttribute::MAYBEVOID, MID_HYPHEN_MIN_TRAIL }, \
+ { UNO_NAME_PARA_HYPHENATION_MAX_HYPHENS, RES_PARATR_HYPHENZONE, cppu::UnoType<sal_Int16>::get(), PropertyAttribute::MAYBEVOID, MID_HYPHEN_MAX_HYPHENS }, \
+ { UNO_NAME_PARA_HYPHENATION_MIN_WORD_LENGTH, RES_PARATR_HYPHENZONE, cppu::UnoType<sal_Int16>::get(), PropertyAttribute::MAYBEVOID, MID_HYPHEN_MIN_WORD_LENGTH }, \
+ { UNO_NAME_PARA_HYPHENATION_ZONE, RES_PARATR_HYPHENZONE, cppu::UnoType<sal_Int16>::get(), PropertyAttribute::MAYBEVOID, MID_HYPHEN_ZONE}, \
+ { UNO_NAME_CHAR_AUTO_KERNING, RES_CHRATR_AUTOKERN, cppu::UnoType<bool>::get(), PropertyAttribute::MAYBEVOID, 0 }, \
+ { UNO_NAME_CHAR_BACK_COLOR, RES_CHRATR_BACKGROUND, cppu::UnoType<sal_Int32>::get(), PropertyAttribute::MAYBEVOID, MID_BACK_COLOR }, \
+ { UNO_NAME_CHAR_BACKGROUND_COMPLEX_COLOR, RES_CHRATR_BACKGROUND, cppu::UnoType<css::util::XComplexColor>::get(), PROPERTY_NONE, MID_BACKGROUND_COMPLEX_COLOR },\
+ { UNO_NAME_CHAR_HIGHLIGHT, RES_CHRATR_HIGHLIGHT, cppu::UnoType<sal_Int32>::get(), PropertyAttribute::MAYBEVOID, MID_BACK_COLOR }, \
+ { UNO_NAME_PARA_BACK_COLOR, RES_BACKGROUND, cppu::UnoType<sal_Int32>::get(), PropertyAttribute::MAYBEVOID, MID_BACK_COLOR }, \
+ { UNO_NAME_PARA_BACKGROUND_COMPLEX_COLOR, RES_BACKGROUND, cppu::UnoType<css::util::XComplexColor>::get(), PROPERTY_NONE , MID_BACKGROUND_COMPLEX_COLOR },\
+ { UNO_NAME_CHAR_CASE_MAP, RES_CHRATR_CASEMAP, cppu::UnoType<sal_Int16>::get(), PropertyAttribute::MAYBEVOID, 0 }, \
+ { UNO_NAME_CHAR_COLOR, RES_CHRATR_COLOR, cppu::UnoType<sal_Int32>::get(), PropertyAttribute::MAYBEVOID, 0 }, \
+ { UNO_NAME_CHAR_COLOR_THEME, RES_CHRATR_COLOR, cppu::UnoType<sal_Int16>::get(), PropertyAttribute::MAYBEVOID, MID_COLOR_THEME_INDEX }, \
+ { UNO_NAME_CHAR_COLOR_TINT_OR_SHADE, RES_CHRATR_COLOR, cppu::UnoType<sal_Int16>::get(), PropertyAttribute::MAYBEVOID, MID_COLOR_TINT_OR_SHADE }, \
+ { UNO_NAME_CHAR_COMPLEX_COLOR , RES_CHRATR_COLOR, cppu::UnoType<css::util::XComplexColor>::get(), PropertyAttribute::MAYBEVOID, MID_COMPLEX_COLOR }, \
+ { UNO_NAME_CHAR_TRANSPARENCE, RES_CHRATR_COLOR, cppu::UnoType<sal_Int16>::get(), PropertyAttribute::MAYBEVOID, MID_COLOR_ALPHA }, \
+ { UNO_NAME_CHAR_STRIKEOUT, RES_CHRATR_CROSSEDOUT, cppu::UnoType<sal_Int16>::get(), PropertyAttribute::MAYBEVOID, MID_CROSS_OUT }, \
+ { UNO_NAME_CHAR_CROSSED_OUT, RES_CHRATR_CROSSEDOUT, cppu::UnoType<bool>::get(), PropertyAttribute::MAYBEVOID, MID_CROSSED_OUT }, \
+ { UNO_NAME_CHAR_ESCAPEMENT, RES_CHRATR_ESCAPEMENT, cppu::UnoType<sal_Int16>::get(), PropertyAttribute::MAYBEVOID, MID_ESC }, \
+ { UNO_NAME_CHAR_ESCAPEMENT_HEIGHT, RES_CHRATR_ESCAPEMENT, cppu::UnoType<sal_Int8>::get(), PropertyAttribute::MAYBEVOID, MID_ESC_HEIGHT }, \
+ { UNO_NAME_CHAR_AUTO_ESCAPEMENT, RES_CHRATR_ESCAPEMENT, cppu::UnoType<bool>::get(), PropertyAttribute::MAYBEVOID, MID_AUTO_ESC }, \
+ { UNO_NAME_CHAR_FLASH, RES_CHRATR_BLINK, cppu::UnoType<bool>::get(), PropertyAttribute::MAYBEVOID, 0 }, \
+ { UNO_NAME_CHAR_HIDDEN, RES_CHRATR_HIDDEN, cppu::UnoType<bool>::get(), PropertyAttribute::MAYBEVOID, 0 }, \
+ { UNO_NAME_CHAR_UNDERLINE, RES_CHRATR_UNDERLINE, cppu::UnoType<sal_Int16>::get(), PropertyAttribute::MAYBEVOID, MID_TL_STYLE }, \
+ { UNO_NAME_CHAR_UNDERLINE_COLOR, RES_CHRATR_UNDERLINE, cppu::UnoType<sal_Int32>::get(), PropertyAttribute::MAYBEVOID, MID_TL_COLOR }, \
+ { UNO_NAME_CHAR_UNDERLINE_COMPLEX_COLOR, RES_CHRATR_UNDERLINE, cppu::UnoType<css::util::XComplexColor>::get(), PropertyAttribute::MAYBEVOID, MID_TL_COMPLEX_COLOR }, \
+ { UNO_NAME_CHAR_UNDERLINE_HAS_COLOR, RES_CHRATR_UNDERLINE, cppu::UnoType<bool>::get(), PropertyAttribute::MAYBEVOID, MID_TL_HASCOLOR }, \
+ { UNO_NAME_CHAR_OVERLINE, RES_CHRATR_OVERLINE, cppu::UnoType<sal_Int16>::get(), PropertyAttribute::MAYBEVOID, MID_TL_STYLE }, \
+ { UNO_NAME_CHAR_OVERLINE_COLOR, RES_CHRATR_OVERLINE, cppu::UnoType<sal_Int32>::get(), PropertyAttribute::MAYBEVOID, MID_TL_COLOR }, \
+ { UNO_NAME_CHAR_OVERLINE_COMPLEX_COLOR, RES_CHRATR_OVERLINE, cppu::UnoType<css::util::XComplexColor>::get(), PropertyAttribute::MAYBEVOID, MID_TL_COMPLEX_COLOR }, \
+ { UNO_NAME_CHAR_OVERLINE_HAS_COLOR, RES_CHRATR_OVERLINE, cppu::UnoType<bool>::get(), PropertyAttribute::MAYBEVOID, MID_TL_HASCOLOR }, \
+ { UNO_NAME_PARA_GRAPHIC_URL, RES_BACKGROUND, cppu::UnoType<OUString>::get(), PropertyAttribute::MAYBEVOID, MID_GRAPHIC_URL }, \
+ { UNO_NAME_PARA_GRAPHIC, RES_BACKGROUND, cppu::UnoType<css::graphic::XGraphic>::get(), PropertyAttribute::MAYBEVOID, MID_GRAPHIC }, \
+ { UNO_NAME_PARA_GRAPHIC_FILTER, RES_BACKGROUND, cppu::UnoType<OUString>::get(), PropertyAttribute::MAYBEVOID, MID_GRAPHIC_FILTER }, \
+ { UNO_NAME_PARA_GRAPHIC_LOCATION, RES_BACKGROUND, cppu::UnoType<css::style::GraphicLocation>::get(), PropertyAttribute::MAYBEVOID, MID_GRAPHIC_POSITION }, \
+ { UNO_NAME_PARA_LEFT_MARGIN, RES_MARGIN_TEXTLEFT, cppu::UnoType<sal_Int32>::get(), PropertyAttribute::MAYBEVOID, MID_TXT_LMARGIN | CONVERT_TWIPS }, \
+ { UNO_NAME_PARA_RIGHT_MARGIN, RES_MARGIN_RIGHT, cppu::UnoType<sal_Int32>::get(), PropertyAttribute::MAYBEVOID, MID_R_MARGIN | CONVERT_TWIPS }, \
+ { UNO_NAME_PARA_IS_AUTO_FIRST_LINE_INDENT, RES_MARGIN_FIRSTLINE, cppu::UnoType<bool>::get(), PropertyAttribute::MAYBEVOID, MID_FIRST_AUTO }, \
+ { UNO_NAME_PARA_FIRST_LINE_INDENT, RES_MARGIN_FIRSTLINE, cppu::UnoType<sal_Int32>::get(), PropertyAttribute::MAYBEVOID, MID_FIRST_LINE_INDENT | CONVERT_TWIPS }, \
+ STANDARD_FONT_PROPERTIES \
+ CJK_FONT_PROPERTIES \
+ CTL_FONT_PROPERTIES \
+ { UNO_NAME_CHAR_KERNING, RES_CHRATR_KERNING, cppu::UnoType<sal_Int16>::get(), PropertyAttribute::MAYBEVOID, CONVERT_TWIPS }, \
+ { UNO_NAME_CHAR_NO_HYPHENATION, RES_CHRATR_NOHYPHEN, cppu::UnoType<bool>::get(), PropertyAttribute::MAYBEVOID, 0 }, \
+ { UNO_NAME_CHAR_SHADOWED, RES_CHRATR_SHADOWED, cppu::UnoType<bool>::get(), PropertyAttribute::MAYBEVOID, 0 }, \
+ { UNO_NAME_CHAR_CONTOURED, RES_CHRATR_CONTOUR, cppu::UnoType<bool>::get(), PropertyAttribute::MAYBEVOID, 0 }, \
+ { UNO_NAME_DROP_CAP_FORMAT, RES_PARATR_DROP, cppu::UnoType<css::style::DropCapFormat>::get(), PropertyAttribute::MAYBEVOID, MID_DROPCAP_FORMAT | CONVERT_TWIPS }, \
+ { UNO_NAME_DROP_CAP_WHOLE_WORD, RES_PARATR_DROP, cppu::UnoType<bool>::get(), PropertyAttribute::MAYBEVOID, MID_DROPCAP_WHOLE_WORD }, \
+ { UNO_NAME_DROP_CAP_CHAR_STYLE_NAME, RES_PARATR_DROP, cppu::UnoType<OUString>::get(), PropertyAttribute::MAYBEVOID, MID_DROPCAP_CHAR_STYLE_NAME }, \
+ { UNO_NAME_PARA_KEEP_TOGETHER, RES_KEEP, cppu::UnoType<bool>::get(), PropertyAttribute::MAYBEVOID, 0 }, \
+ { UNO_NAME_PARA_SPLIT, RES_PARATR_SPLIT, cppu::UnoType<bool>::get(), PropertyAttribute::MAYBEVOID, 0 }, \
+ { UNO_NAME_PARA_WIDOWS, RES_PARATR_WIDOWS, cppu::UnoType<sal_Int8>::get(), PropertyAttribute::MAYBEVOID, 0 }, \
+ { UNO_NAME_PARA_ORPHANS, RES_PARATR_ORPHANS, cppu::UnoType<sal_Int8>::get(), PropertyAttribute::MAYBEVOID, 0 }, \
+ { UNO_NAME_PAGE_NUMBER_OFFSET, RES_PAGEDESC, cppu::UnoType<sal_Int16>::get(), PropertyAttribute::MAYBEVOID, MID_PAGEDESC_PAGENUMOFFSET }, \
+ { UNO_NAME_PARA_ADJUST, RES_PARATR_ADJUST, cppu::UnoType<sal_Int16>::get(), PropertyAttribute::MAYBEVOID, MID_PARA_ADJUST }, \
+ { UNO_NAME_PARA_EXPAND_SINGLE_WORD, RES_PARATR_ADJUST, cppu::UnoType<bool>::get(), PropertyAttribute::MAYBEVOID, MID_EXPAND_SINGLE }, \
+ { UNO_NAME_PARA_LAST_LINE_ADJUST, RES_PARATR_ADJUST, cppu::UnoType<sal_Int16>::get(), PropertyAttribute::MAYBEVOID, MID_LAST_LINE_ADJUST }, \
+ { UNO_NAME_PARA_LINE_NUMBER_COUNT, RES_LINENUMBER, cppu::UnoType<bool>::get(), PropertyAttribute::MAYBEVOID, MID_LINENUMBER_COUNT }, \
+ { UNO_NAME_PARA_LINE_NUMBER_START_VALUE, RES_LINENUMBER, cppu::UnoType<sal_Int32>::get(), PropertyAttribute::MAYBEVOID, MID_LINENUMBER_STARTVALUE }, \
+ { UNO_NAME_PARA_LINE_SPACING, RES_PARATR_LINESPACING, cppu::UnoType<css::style::LineSpacing>::get(), PropertyAttribute::MAYBEVOID, CONVERT_TWIPS }, \
+ { UNO_NAME_PARA_REGISTER_MODE_ACTIVE, RES_PARATR_REGISTER, cppu::UnoType<bool>::get(), PropertyAttribute::MAYBEVOID, 0 }, \
+ { UNO_NAME_PARA_TOP_MARGIN, RES_UL_SPACE, cppu::UnoType<sal_Int32>::get(), PropertyAttribute::MAYBEVOID, MID_UP_MARGIN | CONVERT_TWIPS }, \
+ { UNO_NAME_PARA_BOTTOM_MARGIN, RES_UL_SPACE, cppu::UnoType<sal_Int32>::get(), PropertyAttribute::MAYBEVOID, MID_LO_MARGIN | CONVERT_TWIPS }, \
+ { UNO_NAME_PARA_CONTEXT_MARGIN, RES_UL_SPACE, cppu::UnoType<bool>::get(), PropertyAttribute::MAYBEVOID, MID_CTX_MARGIN }, \
+ { UNO_NAME_CHAR_BACK_TRANSPARENT, RES_CHRATR_BACKGROUND, cppu::UnoType<bool>::get(), PropertyAttribute::MAYBEVOID, MID_GRAPHIC_TRANSPARENT }, \
+ { UNO_NAME_PARA_BACK_TRANSPARENT, RES_BACKGROUND, cppu::UnoType<bool>::get(), PropertyAttribute::MAYBEVOID, MID_GRAPHIC_TRANSPARENT }, \
+ { UNO_NAME_NUMBERING_STYLE_NAME, RES_PARATR_NUMRULE, cppu::UnoType<OUString>::get(), PropertyAttribute::MAYBEVOID, 0 }, \
+ { UNO_NAME_CHAR_WORD_MODE, RES_CHRATR_WORDLINEMODE, cppu::UnoType<bool>::get(), PropertyAttribute::MAYBEVOID, 0 }, \
+ { UNO_NAME_CHAR_LEFT_BORDER, RES_CHRATR_BOX, cppu::UnoType<css::table::BorderLine>::get(), PropertyAttribute::MAYBEVOID, LEFT_BORDER | CONVERT_TWIPS }, \
+ { UNO_NAME_CHAR_RIGHT_BORDER, RES_CHRATR_BOX, cppu::UnoType<css::table::BorderLine>::get(), PropertyAttribute::MAYBEVOID, RIGHT_BORDER | CONVERT_TWIPS }, \
+ { UNO_NAME_CHAR_TOP_BORDER, RES_CHRATR_BOX, cppu::UnoType<css::table::BorderLine>::get(), PropertyAttribute::MAYBEVOID, TOP_BORDER | CONVERT_TWIPS }, \
+ { UNO_NAME_CHAR_BOTTOM_BORDER, RES_CHRATR_BOX, cppu::UnoType<css::table::BorderLine>::get(), PropertyAttribute::MAYBEVOID, BOTTOM_BORDER | CONVERT_TWIPS }, \
+ { UNO_NAME_CHAR_BORDER_DISTANCE, RES_CHRATR_BOX, cppu::UnoType<sal_Int32>::get(), PropertyAttribute::MAYBEVOID, BORDER_DISTANCE | CONVERT_TWIPS }, \
+ { UNO_NAME_CHAR_LEFT_BORDER_DISTANCE, RES_CHRATR_BOX, cppu::UnoType<sal_Int32>::get(), PropertyAttribute::MAYBEVOID, LEFT_BORDER_DISTANCE | CONVERT_TWIPS }, \
+ { UNO_NAME_CHAR_RIGHT_BORDER_DISTANCE, RES_CHRATR_BOX, cppu::UnoType<sal_Int32>::get(), PropertyAttribute::MAYBEVOID, RIGHT_BORDER_DISTANCE | CONVERT_TWIPS }, \
+ { UNO_NAME_CHAR_TOP_BORDER_DISTANCE, RES_CHRATR_BOX, cppu::UnoType<sal_Int32>::get(), PropertyAttribute::MAYBEVOID, TOP_BORDER_DISTANCE | CONVERT_TWIPS }, \
+ { UNO_NAME_CHAR_BOTTOM_BORDER_DISTANCE, RES_CHRATR_BOX, cppu::UnoType<sal_Int32>::get(), PropertyAttribute::MAYBEVOID, BOTTOM_BORDER_DISTANCE | CONVERT_TWIPS }, \
+ { UNO_NAME_CHAR_BORDER_LEFT_COMPLEX_COLOR, RES_CHRATR_BOX, cppu::UnoType<css::util::XComplexColor>::get(), PropertyAttribute::MAYBEVOID, MID_BORDER_LEFT_COLOR }, \
+ { UNO_NAME_CHAR_BORDER_RIGHT_COMPLEX_COLOR, RES_CHRATR_BOX, cppu::UnoType<css::util::XComplexColor>::get(), PropertyAttribute::MAYBEVOID, MID_BORDER_RIGHT_COLOR }, \
+ { UNO_NAME_CHAR_BORDER_TOP_COMPLEX_COLOR, RES_CHRATR_BOX, cppu::UnoType<css::util::XComplexColor>::get(), PropertyAttribute::MAYBEVOID, MID_BORDER_TOP_COLOR }, \
+ { UNO_NAME_CHAR_BORDER_BOTTOM_COMPLEX_COLOR, RES_CHRATR_BOX, cppu::UnoType<css::util::XComplexColor>::get(), PropertyAttribute::MAYBEVOID, MID_BORDER_BOTTOM_COLOR }, \
+ { UNO_NAME_CHAR_SHADOW_FORMAT, RES_CHRATR_SHADOW, cppu::UnoType<css::table::ShadowFormat>::get(), PropertyAttribute::MAYBEVOID, CONVERT_TWIPS }, \
+ { UNO_NAME_LEFT_BORDER, RES_BOX, cppu::UnoType<css::table::BorderLine>::get(), PropertyAttribute::MAYBEVOID, LEFT_BORDER | CONVERT_TWIPS }, \
+ { UNO_NAME_RIGHT_BORDER, RES_BOX, cppu::UnoType<css::table::BorderLine>::get(), PropertyAttribute::MAYBEVOID, RIGHT_BORDER | CONVERT_TWIPS }, \
+ { UNO_NAME_TOP_BORDER, RES_BOX, cppu::UnoType<css::table::BorderLine>::get(), PropertyAttribute::MAYBEVOID, TOP_BORDER | CONVERT_TWIPS }, \
+ { UNO_NAME_BOTTOM_BORDER, RES_BOX, cppu::UnoType<css::table::BorderLine>::get(), PropertyAttribute::MAYBEVOID, BOTTOM_BORDER | CONVERT_TWIPS }, \
+ { UNO_NAME_BORDER_DISTANCE, RES_BOX, cppu::UnoType<sal_Int32>::get(), PropertyAttribute::MAYBEVOID, BORDER_DISTANCE | CONVERT_TWIPS }, \
+ { UNO_NAME_LEFT_BORDER_DISTANCE, RES_BOX, cppu::UnoType<sal_Int32>::get(), PropertyAttribute::MAYBEVOID, LEFT_BORDER_DISTANCE | CONVERT_TWIPS }, \
+ { UNO_NAME_RIGHT_BORDER_DISTANCE, RES_BOX, cppu::UnoType<sal_Int32>::get(), PropertyAttribute::MAYBEVOID, RIGHT_BORDER_DISTANCE | CONVERT_TWIPS }, \
+ { UNO_NAME_TOP_BORDER_DISTANCE, RES_BOX, cppu::UnoType<sal_Int32>::get(), PropertyAttribute::MAYBEVOID, TOP_BORDER_DISTANCE | CONVERT_TWIPS }, \
+ { UNO_NAME_BOTTOM_BORDER_DISTANCE, RES_BOX, cppu::UnoType<sal_Int32>::get(), PropertyAttribute::MAYBEVOID, BOTTOM_BORDER_DISTANCE | CONVERT_TWIPS }, \
+ { UNO_NAME_BORDER_LEFT_COMPLEX_COLOR, RES_BOX, cppu::UnoType<css::util::XComplexColor>::get(), PropertyAttribute::MAYBEVOID, MID_BORDER_LEFT_COLOR }, \
+ { UNO_NAME_BORDER_RIGHT_COMPLEX_COLOR, RES_BOX, cppu::UnoType<css::util::XComplexColor>::get(), PropertyAttribute::MAYBEVOID, MID_BORDER_RIGHT_COLOR }, \
+ { UNO_NAME_BORDER_TOP_COMPLEX_COLOR, RES_BOX, cppu::UnoType<css::util::XComplexColor>::get(), PropertyAttribute::MAYBEVOID, MID_BORDER_TOP_COLOR }, \
+ { UNO_NAME_BORDER_BOTTOM_COMPLEX_COLOR, RES_BOX, cppu::UnoType<css::util::XComplexColor>::get(), PropertyAttribute::MAYBEVOID, MID_BORDER_BOTTOM_COLOR }, \
+ { UNO_NAME_PARA_USER_DEFINED_ATTRIBUTES, RES_UNKNOWNATR_CONTAINER, cppu::UnoType<css::container::XNameContainer>::get(), PropertyAttribute::MAYBEVOID, 0 }, \
+ { UNO_NAME_TEXT_USER_DEFINED_ATTRIBUTES, RES_TXTATR_UNKNOWN_CONTAINER, cppu::UnoType<css::container::XNameContainer>::get(), PropertyAttribute::MAYBEVOID, 0 }, \
+ { UNO_NAME_PARA_SHADOW_FORMAT, RES_SHADOW, cppu::UnoType<css::table::ShadowFormat>::get(), PROPERTY_NONE, CONVERT_TWIPS }, \
+ { UNO_NAME_CHAR_COMBINE_IS_ON, RES_CHRATR_TWO_LINES, cppu::UnoType<bool>::get(), PropertyAttribute::MAYBEVOID, MID_TWOLINES }, \
+ { UNO_NAME_CHAR_COMBINE_PREFIX, RES_CHRATR_TWO_LINES, cppu::UnoType<OUString>::get(), PropertyAttribute::MAYBEVOID, MID_START_BRACKET }, \
+ { UNO_NAME_CHAR_COMBINE_SUFFIX, RES_CHRATR_TWO_LINES, cppu::UnoType<OUString>::get(), PropertyAttribute::MAYBEVOID, MID_END_BRACKET }, \
+ { UNO_NAME_CHAR_EMPHASIS, RES_CHRATR_EMPHASIS_MARK, cppu::UnoType<sal_Int16>::get(), PropertyAttribute::MAYBEVOID, MID_EMPHASIS }, \
+ { UNO_NAME_PARA_IS_HANGING_PUNCTUATION, RES_PARATR_HANGINGPUNCTUATION, cppu::UnoType<bool>::get(), PropertyAttribute::MAYBEVOID, 0 }, \
+ { UNO_NAME_PARA_IS_CHARACTER_DISTANCE, RES_PARATR_SCRIPTSPACE, cppu::UnoType<bool>::get(), PropertyAttribute::MAYBEVOID, 0 }, \
+ { UNO_NAME_PARA_IS_FORBIDDEN_RULES, RES_PARATR_FORBIDDEN_RULES, cppu::UnoType<bool>::get(), PropertyAttribute::MAYBEVOID, 0 }, \
+ { UNO_NAME_PARA_VERT_ALIGNMENT, RES_PARATR_VERTALIGN, cppu::UnoType<sal_Int16>::get(), PropertyAttribute::MAYBEVOID, 0 }, \
+ { UNO_NAME_CHAR_ROTATION, RES_CHRATR_ROTATE, cppu::UnoType<sal_Int16>::get(), PropertyAttribute::MAYBEVOID, MID_ROTATE }, \
+ { UNO_NAME_CHAR_ROTATION_IS_FIT_TO_LINE, RES_CHRATR_ROTATE, cppu::UnoType<bool>::get(), PropertyAttribute::MAYBEVOID, MID_FITTOLINE }, \
+ { UNO_NAME_CHAR_SCALE_WIDTH, RES_CHRATR_SCALEW, cppu::UnoType<sal_Int16>::get(), PropertyAttribute::MAYBEVOID, 0 }, \
+ { UNO_NAME_RUBY_TEXT, RES_TXTATR_CJK_RUBY, cppu::UnoType<OUString>::get(), PropertyAttribute::MAYBEVOID, MID_RUBY_TEXT }, \
+ { UNO_NAME_RUBY_ADJUST, RES_TXTATR_CJK_RUBY, cppu::UnoType<sal_Int16>::get(), PropertyAttribute::MAYBEVOID, MID_RUBY_ADJUST }, \
+ { UNO_NAME_RUBY_CHAR_STYLE_NAME, RES_TXTATR_CJK_RUBY, cppu::UnoType<OUString>::get(), PropertyAttribute::MAYBEVOID, MID_RUBY_CHARSTYLE }, \
+ { UNO_NAME_RUBY_POSITION, RES_TXTATR_CJK_RUBY, cppu::UnoType<sal_Int16>::get(), PropertyAttribute::MAYBEVOID, MID_RUBY_POSITION}, \
+ { UNO_NAME_RUBY_IS_ABOVE, RES_TXTATR_CJK_RUBY, cppu::UnoType<bool>::get(), PropertyAttribute::MAYBEVOID, MID_RUBY_ABOVE }, \
+ { UNO_NAME_CHAR_RELIEF, RES_CHRATR_RELIEF, cppu::UnoType<sal_Int16>::get(), PropertyAttribute::MAYBEVOID, MID_RELIEF }, \
+ { UNO_NAME_SNAP_TO_GRID, RES_PARATR_SNAPTOGRID, cppu::UnoType<bool>::get(), PropertyAttribute::MAYBEVOID, 0 }, \
+ { UNO_NAME_PARA_IS_CONNECT_BORDER, RES_PARATR_CONNECT_BORDER, cppu::UnoType<bool>::get(), PropertyAttribute::MAYBEVOID, 0 }, \
+ { UNO_NAME_WRITING_MODE, RES_FRAMEDIR, cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE, 0 }, \
+ { UNO_NAME_CHAR_SHADING_VALUE, RES_CHRATR_BACKGROUND, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE, MID_SHADING_VALUE }, \
+ { UNO_NAME_PARA_INTEROP_GRAB_BAG, RES_PARATR_GRABBAG, cppu::UnoType< cppu::UnoSequenceType<css::beans::PropertyValue> >::get(), PROPERTY_NONE, 0 }, \
+
+#define COMMON_CRSR_PARA_PROPERTIES_WITHOUT_FN \
+ COMMON_CRSR_PARA_PROPERTIES_WITHOUT_FN_01 \
+ { UNO_NAME_BREAK_TYPE, RES_BREAK, cppu::UnoType<css::style::BreakType>::get(), PropertyAttribute::MAYBEVOID, 0}, \
+ { UNO_NAME_PAGE_DESC_NAME, RES_PAGEDESC, cppu::UnoType<OUString>::get(), PropertyAttribute::MAYBEVOID, MID_PAGEDESC_PAGEDESCNAME },
+
+#define TABSTOPS_MAP_ENTRY { UNO_NAME_TABSTOPS, RES_PARATR_TABSTOP, cppu::UnoType< cppu::UnoSequenceType<css::style::TabStop> >::get(), PropertyAttribute::MAYBEVOID, CONVERT_TWIPS},
+
+#define COMMON_CRSR_PARA_PROPERTIES \
+ COMMON_CRSR_PARA_PROPERTIES_FN_ONLY \
+ COMMON_CRSR_PARA_PROPERTIES_WITHOUT_FN \
+ COMMON_HYPERLINK_PROPERTIES \
+ { UNO_NAME_CHAR_STYLE_NAME, RES_TXTATR_CHARFMT, cppu::UnoType<OUString>::get(), PropertyAttribute::MAYBEVOID, 0},\
+ { UNO_NAME_CHAR_STYLE_NAMES, FN_UNO_CHARFMT_SEQUENCE, cppu::UnoType< cppu::UnoSequenceType<OUString> >::get(), PropertyAttribute::MAYBEVOID, 0}, \
+ { UNO_NAME_CHAR_AUTO_STYLE_NAME, RES_TXTATR_AUTOFMT, cppu::UnoType<OUString>::get(), PropertyAttribute::MAYBEVOID, 0},\
+ { UNO_NAME_PARA_AUTO_STYLE_NAME, RES_AUTO_STYLE, cppu::UnoType<OUString>::get(), PropertyAttribute::MAYBEVOID, 0},
+
+#define COMMON_CRSR_PARA_PROPERTIES_2 \
+ COMMON_CRSR_PARA_PROPERTIES_FN_ONLY \
+ COMMON_CRSR_PARA_PROPERTIES_WITHOUT_FN
+
+#define COMPLETE_TEXT_CURSOR_MAP\
+ COMMON_CRSR_PARA_PROPERTIES\
+ { UNO_NAME_DOCUMENT_INDEX_MARK, FN_UNO_DOCUMENT_INDEX_MARK, cppu::UnoType<css::text::XDocumentIndexMark>::get(), PropertyAttribute::MAYBEVOID|PropertyAttribute::READONLY ,0 },\
+ { UNO_NAME_TEXT_FIELD, FN_UNO_TEXT_FIELD, cppu::UnoType<css::text::XTextField>::get(), PropertyAttribute::MAYBEVOID|PropertyAttribute::READONLY ,0 },\
+ { UNO_NAME_REFERENCE_MARK, FN_UNO_REFERENCE_MARK, cppu::UnoType<css::text::XTextContent>::get(), PropertyAttribute::MAYBEVOID|PropertyAttribute::READONLY, 0 },\
+ { UNO_NAME_FOOTNOTE, FN_UNO_FOOTNOTE, cppu::UnoType<css::text::XFootnote>::get(), PropertyAttribute::MAYBEVOID|PropertyAttribute::READONLY ,0 },\
+ { UNO_NAME_ENDNOTE, FN_UNO_ENDNOTE, cppu::UnoType<css::text::XFootnote>::get(), PropertyAttribute::MAYBEVOID|PropertyAttribute::READONLY ,0 },\
+ { UNO_NAME_HYPER_LINK_EVENTS, RES_TXTATR_INETFMT, cppu::UnoType<css::container::XNameReplace>::get(), PropertyAttribute::MAYBEVOID, MID_URL_HYPERLINKEVENTS},\
+ { UNO_NAME_NESTED_TEXT_CONTENT, FN_UNO_NESTED_TEXT_CONTENT, cppu::UnoType<css::text::XTextContent>::get(), PropertyAttribute::MAYBEVOID|PropertyAttribute::READONLY, 0 },\
+ TABSTOPS_MAP_ENTRY
+
+#define BASE_INDEX_PROPERTIES_\
+ { UNO_NAME_TITLE, WID_IDX_TITLE, cppu::UnoType<OUString>::get() , PROPERTY_NONE, 0},\
+ { UNO_NAME_NAME, WID_IDX_NAME, cppu::UnoType<OUString>::get() , PROPERTY_NONE, 0},\
+ { UNO_NAME_CONTENT_SECTION, WID_IDX_CONTENT_SECTION, cppu::UnoType<css::text::XTextSection>::get() , PropertyAttribute::READONLY, 0},\
+ { UNO_NAME_HEADER_SECTION, WID_IDX_HEADER_SECTION, cppu::UnoType<css::text::XTextSection>::get() , PropertyAttribute::MAYBEVOID|PropertyAttribute::READONLY, 0},\
+
+#define ANCHOR_TYPES_PROPERTY { UNO_NAME_ANCHOR_TYPES, FN_UNO_ANCHOR_TYPES, cppu::UnoType< cppu::UnoSequenceType<css::text::TextContentAnchorType> >::get(),PropertyAttribute::READONLY, 0xbf},
+
+// #i18732# #i28701# #i73249#
+// all users of COMMON_FRAME_PROPERTIES add the new XATTR_FILL_FIRST, XATTR_FILL_LAST FillStyle,
+// thus it may be possible to remove the RES_BACKGROUND entries from SvxBrushItem completely (this includes
+// all using UNO_NAME_BACK_* slots) in the future
+#define COMMON_FRAME_PROPERTIES \
+ { UNO_NAME_ANCHOR_PAGE_NO, RES_ANCHOR, cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE, MID_ANCHOR_PAGENUM }, \
+ { UNO_NAME_ANCHOR_TYPE, RES_ANCHOR, cppu::UnoType<css::text::TextContentAnchorType>::get(), PROPERTY_NONE, MID_ANCHOR_ANCHORTYPE}, \
+ { UNO_NAME_ANCHOR_FRAME, RES_ANCHOR, cppu::UnoType<css::text::XTextFrame>::get(), PropertyAttribute::MAYBEVOID, MID_ANCHOR_ANCHORFRAME}, \
+ ANCHOR_TYPES_PROPERTY\
+ { UNO_NAME_BACK_COLOR, RES_BACKGROUND, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE ,MID_BACK_COLOR }, \
+ { UNO_NAME_BACKGROUND_COMPLEX_COLOR, RES_BACKGROUND, cppu::UnoType<css::util::XComplexColor>::get(), PROPERTY_NONE ,MID_BACKGROUND_COMPLEX_COLOR }, \
+ { UNO_NAME_BACK_COLOR_R_G_B, RES_BACKGROUND, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE ,MID_BACK_COLOR_R_G_B}, \
+ { UNO_NAME_BACK_COLOR_TRANSPARENCY, RES_BACKGROUND, cppu::UnoType<sal_Int8>::get(), PROPERTY_NONE ,MID_BACK_COLOR_TRANSPARENCY}, \
+ { UNO_NAME_FRAME_INTEROP_GRAB_BAG, RES_FRMATR_GRABBAG, cppu::UnoType< cppu::UnoSequenceType<css::beans::PropertyValue> >::get(), PROPERTY_NONE, 0}, \
+ { UNO_NAME_CONTENT_PROTECTED, RES_PROTECT, cppu::UnoType<bool>::get(), PROPERTY_NONE, MID_PROTECT_CONTENT }, \
+ { UNO_NAME_FRAME_STYLE_NAME, FN_UNO_FRAME_STYLE_NAME,cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0}, \
+ { UNO_NAME_BACK_GRAPHIC_URL, RES_BACKGROUND, cppu::UnoType<OUString>::get(), PROPERTY_NONE ,MID_GRAPHIC_URL }, \
+ { UNO_NAME_BACK_GRAPHIC, RES_BACKGROUND, cppu::UnoType<css::graphic::XGraphic>::get(), PROPERTY_NONE, MID_GRAPHIC }, \
+ { UNO_NAME_BACK_GRAPHIC_FILTER, RES_BACKGROUND, cppu::UnoType<OUString>::get(), PROPERTY_NONE ,MID_GRAPHIC_FILTER }, \
+ { UNO_NAME_BACK_GRAPHIC_LOCATION, RES_BACKGROUND, cppu::UnoType<css::style::GraphicLocation>::get(), PROPERTY_NONE ,MID_GRAPHIC_POSITION}, \
+ { UNO_NAME_BACK_GRAPHIC_TRANSPARENCY, RES_BACKGROUND, cppu::UnoType<sal_Int8>::get(), PROPERTY_NONE ,MID_GRAPHIC_TRANSPARENCY}, \
+ { UNO_NAME_LEFT_MARGIN, RES_LR_SPACE, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE, MID_L_MARGIN|CONVERT_TWIPS}, \
+ { UNO_NAME_RIGHT_MARGIN, RES_LR_SPACE, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE, MID_R_MARGIN|CONVERT_TWIPS}, \
+ { UNO_NAME_WIDTH, RES_FRM_SIZE, cppu::UnoType<sal_Int32>::get() , PROPERTY_NONE, MID_FRMSIZE_WIDTH|CONVERT_TWIPS},\
+ { UNO_NAME_HEIGHT, RES_FRM_SIZE, cppu::UnoType<sal_Int32>::get() , PROPERTY_NONE, MID_FRMSIZE_HEIGHT|CONVERT_TWIPS},\
+ { UNO_NAME_HORI_ORIENT, RES_HORI_ORIENT, cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE ,MID_HORIORIENT_ORIENT }, \
+ { UNO_NAME_HORI_ORIENT_POSITION, RES_HORI_ORIENT, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE ,MID_HORIORIENT_POSITION|CONVERT_TWIPS }, \
+ { UNO_NAME_HORI_ORIENT_RELATION, RES_HORI_ORIENT, cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE ,MID_HORIORIENT_RELATION }, \
+ { UNO_NAME_HYPER_LINK_U_R_L, RES_URL, cppu::UnoType<OUString>::get(), PROPERTY_NONE ,MID_URL_URL}, \
+ { UNO_NAME_HYPER_LINK_TARGET, RES_URL, cppu::UnoType<OUString>::get(), PROPERTY_NONE ,MID_URL_TARGET}, \
+ { UNO_NAME_HYPER_LINK_NAME, RES_URL, cppu::UnoType<OUString>::get(), PROPERTY_NONE ,MID_URL_HYPERLINKNAME }, \
+ { UNO_NAME_OPAQUE, RES_OPAQUE, cppu::UnoType<bool>::get(), PROPERTY_NONE, 0}, \
+ { UNO_NAME_PAGE_TOGGLE, RES_HORI_ORIENT, cppu::UnoType<bool>::get(), PROPERTY_NONE ,MID_HORIORIENT_PAGETOGGLE }, \
+ { UNO_NAME_POSITION_PROTECTED, RES_PROTECT, cppu::UnoType<bool>::get(), PROPERTY_NONE, MID_PROTECT_POSITION}, \
+ { UNO_NAME_PRINT, RES_PRINT, cppu::UnoType<bool>::get(), PROPERTY_NONE, 0}, \
+ { UNO_NAME_RELATIVE_HEIGHT, RES_FRM_SIZE, cppu::UnoType<sal_Int16>::get() , PROPERTY_NONE, MID_FRMSIZE_REL_HEIGHT }, \
+ { UNO_NAME_RELATIVE_HEIGHT_RELATION, RES_FRM_SIZE, cppu::UnoType<sal_Int16>::get() , PROPERTY_NONE, MID_FRMSIZE_REL_HEIGHT_RELATION }, \
+ { UNO_NAME_RELATIVE_WIDTH, RES_FRM_SIZE, cppu::UnoType<sal_Int16>::get() , PROPERTY_NONE, MID_FRMSIZE_REL_WIDTH }, \
+ { UNO_NAME_RELATIVE_WIDTH_RELATION, RES_FRM_SIZE, cppu::UnoType<sal_Int16>::get() , PROPERTY_NONE, MID_FRMSIZE_REL_WIDTH_RELATION }, \
+ { UNO_NAME_SHADOW_FORMAT, RES_SHADOW, cppu::UnoType<css::table::ShadowFormat>::get(), PROPERTY_NONE, CONVERT_TWIPS}, \
+ { UNO_NAME_SHADOW_TRANSPARENCE, RES_SHADOW, cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE, MID_SHADOW_TRANSPARENCE}, \
+ { UNO_NAME_IMAGE_MAP, RES_URL, cppu::UnoType<css::container::XIndexContainer>::get(), PROPERTY_NONE, MID_URL_CLIENTMAP}, \
+ { UNO_NAME_SERVER_MAP, RES_URL, cppu::UnoType<bool>::get(), PROPERTY_NONE ,MID_URL_SERVERMAP }, \
+ { UNO_NAME_SIZE, RES_FRM_SIZE, cppu::UnoType<css::awt::Size>::get(), PROPERTY_NONE, MID_FRMSIZE_SIZE|CONVERT_TWIPS}, \
+ { UNO_NAME_SIZE_PROTECTED, RES_PROTECT, cppu::UnoType<bool>::get(), PROPERTY_NONE, MID_PROTECT_SIZE }, \
+ { UNO_NAME_IS_SYNC_WIDTH_TO_HEIGHT, RES_FRM_SIZE, cppu::UnoType<bool>::get() , PROPERTY_NONE, MID_FRMSIZE_IS_SYNC_WIDTH_TO_HEIGHT }, \
+ { UNO_NAME_IS_SYNC_HEIGHT_TO_WIDTH, RES_FRM_SIZE, cppu::UnoType<bool>::get() , PROPERTY_NONE, MID_FRMSIZE_IS_SYNC_HEIGHT_TO_WIDTH }, \
+ { UNO_NAME_TEXT_WRAP, RES_SURROUND, cppu::UnoType<css::text::WrapTextMode>::get(), PROPERTY_NONE, MID_SURROUND_SURROUNDTYPE }, \
+ { UNO_NAME_SURROUND, RES_SURROUND, cppu::UnoType<css::text::WrapTextMode>::get(), PROPERTY_NONE, MID_SURROUND_SURROUNDTYPE }, \
+ { UNO_NAME_SURROUND_ANCHORONLY, RES_SURROUND, cppu::UnoType<bool>::get(), PROPERTY_NONE, MID_SURROUND_ANCHORONLY }, \
+ { UNO_NAME_TOP_MARGIN, RES_UL_SPACE, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE, MID_UP_MARGIN|CONVERT_TWIPS}, \
+ { UNO_NAME_BOTTOM_MARGIN, RES_UL_SPACE, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE, MID_LO_MARGIN|CONVERT_TWIPS}, \
+ { UNO_NAME_BACK_TRANSPARENT, RES_BACKGROUND, cppu::UnoType<bool>::get(), PROPERTY_NONE ,MID_GRAPHIC_TRANSPARENT }, \
+ { UNO_NAME_VERT_ORIENT, RES_VERT_ORIENT, cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE ,MID_VERTORIENT_ORIENT }, \
+ { UNO_NAME_VERT_ORIENT_POSITION, RES_VERT_ORIENT, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE ,MID_VERTORIENT_POSITION|CONVERT_TWIPS }, \
+ { UNO_NAME_VERT_ORIENT_RELATION, RES_VERT_ORIENT, cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE ,MID_VERTORIENT_RELATION }, \
+ { UNO_NAME_LEFT_BORDER, RES_BOX, cppu::UnoType<css::table::BorderLine>::get(), 0, LEFT_BORDER |CONVERT_TWIPS }, \
+ { UNO_NAME_RIGHT_BORDER, RES_BOX, cppu::UnoType<css::table::BorderLine>::get(), 0, RIGHT_BORDER |CONVERT_TWIPS }, \
+ { UNO_NAME_TOP_BORDER, RES_BOX, cppu::UnoType<css::table::BorderLine>::get(), 0, TOP_BORDER |CONVERT_TWIPS }, \
+ { UNO_NAME_BOTTOM_BORDER, RES_BOX, cppu::UnoType<css::table::BorderLine>::get(), 0, BOTTOM_BORDER|CONVERT_TWIPS }, \
+ { UNO_NAME_BORDER_DISTANCE, RES_BOX, cppu::UnoType<sal_Int32>::get(), 0, BORDER_DISTANCE|CONVERT_TWIPS }, \
+ { UNO_NAME_LEFT_BORDER_DISTANCE, RES_BOX, cppu::UnoType<sal_Int32>::get(), 0, LEFT_BORDER_DISTANCE |CONVERT_TWIPS }, \
+ { UNO_NAME_RIGHT_BORDER_DISTANCE, RES_BOX, cppu::UnoType<sal_Int32>::get(), 0, RIGHT_BORDER_DISTANCE |CONVERT_TWIPS }, \
+ { UNO_NAME_TOP_BORDER_DISTANCE, RES_BOX, cppu::UnoType<sal_Int32>::get(), 0, TOP_BORDER_DISTANCE |CONVERT_TWIPS }, \
+ { UNO_NAME_BOTTOM_BORDER_DISTANCE, RES_BOX, cppu::UnoType<sal_Int32>::get(), 0, BOTTOM_BORDER_DISTANCE|CONVERT_TWIPS }, \
+ { UNO_NAME_BORDER_LEFT_COMPLEX_COLOR, RES_BOX, cppu::UnoType<css::util::XComplexColor>::get(), 0, MID_BORDER_LEFT_COLOR }, \
+ { UNO_NAME_BORDER_RIGHT_COMPLEX_COLOR, RES_BOX, cppu::UnoType<css::util::XComplexColor>::get(), 0, MID_BORDER_RIGHT_COLOR }, \
+ { UNO_NAME_BORDER_TOP_COMPLEX_COLOR, RES_BOX, cppu::UnoType<css::util::XComplexColor>::get(), 0, MID_BORDER_TOP_COLOR }, \
+ { UNO_NAME_BORDER_BOTTOM_COMPLEX_COLOR, RES_BOX, cppu::UnoType<css::util::XComplexColor>::get(), 0, MID_BORDER_BOTTOM_COLOR }, \
+ { UNO_LINK_DISPLAY_NAME, FN_PARAM_LINK_DISPLAY_NAME, cppu::UnoType<OUString>::get(), PropertyAttribute::READONLY, 0xbf}, \
+ { UNO_NAME_USER_DEFINED_ATTRIBUTES, RES_UNKNOWNATR_CONTAINER, cppu::UnoType<css::container::XNameContainer>::get(), PropertyAttribute::MAYBEVOID, 0 },\
+ { UNO_NAME_Z_ORDER, FN_UNO_Z_ORDER, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE, 0}, \
+ { UNO_NAME_IS_FOLLOWING_TEXT_FLOW, RES_FOLLOW_TEXT_FLOW, cppu::UnoType<bool>::get(), PROPERTY_NONE, MID_FOLLOW_TEXT_FLOW}, \
+ { UNO_NAME_PARENT_TEXT, FN_UNO_PARENT_TEXT, cppu::UnoType<text::XText>::get(), PropertyAttribute::MAYBEVOID | PropertyAttribute::READONLY, 0 }, \
+ { UNO_NAME_WRAP_INFLUENCE_ON_POSITION, RES_WRAP_INFLUENCE_ON_OBJPOS, cppu::UnoType<sal_Int8>::get(), PROPERTY_NONE, MID_WRAP_INFLUENCE}, \
+ { UNO_NAME_ALLOW_OVERLAP, RES_WRAP_INFLUENCE_ON_OBJPOS, cppu::UnoType<bool>::get(), PROPERTY_NONE, MID_ALLOW_OVERLAP}, \
+ { UNO_NAME_TITLE, FN_UNO_TITLE, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0}, \
+ { UNO_NAME_TOOLTIP, FN_UNO_TOOLTIP, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0}, \
+ { UNO_NAME_DESCRIPTION, FN_UNO_DESCRIPTION, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0}, \
+ { UNO_NAME_LAYOUT_SIZE, WID_LAYOUT_SIZE, cppu::UnoType<css::awt::Size>::get(), PropertyAttribute::MAYBEVOID | PropertyAttribute::READONLY, 0 }, \
+ { UNO_NAME_LINE_STYLE, RES_BOX, cppu::UnoType<css::drawing::LineStyle>::get(), 0, LINE_STYLE }, \
+ { UNO_NAME_LINE_WIDTH, RES_BOX, cppu::UnoType<sal_Int32>::get(), 0, LINE_WIDTH |CONVERT_TWIPS }, \
+ { u"Decorative"_ustr, RES_DECORATIVE, cppu::UnoType<bool>::get(), PROPERTY_NONE, 0 }, \
+ { UNO_NAME_TEXT_VERT_ADJUST, RES_TEXT_VERT_ADJUST, cppu::UnoType<css::drawing::TextVerticalAdjust>::get(), PROPERTY_NONE ,0},
+
+#define COMMON_TEXT_CONTENT_PROPERTIES \
+ { UNO_NAME_ANCHOR_TYPE, FN_UNO_ANCHOR_TYPE, cppu::UnoType<css::text::TextContentAnchorType>::get(), PropertyAttribute::READONLY, MID_ANCHOR_ANCHORTYPE},\
+ ANCHOR_TYPES_PROPERTY\
+ { UNO_NAME_TEXT_WRAP, FN_UNO_TEXT_WRAP, cppu::UnoType<css::text::WrapTextMode>::get(), PropertyAttribute::READONLY, MID_SURROUND_SURROUNDTYPE },
+
+#define PROP_DIFF_FONTHEIGHT \
+ { UNO_NAME_CHAR_PROP_HEIGHT, RES_CHRATR_FONTSIZE , cppu::UnoType<float>::get(), PROPERTY_NONE , MID_FONTHEIGHT_PROP},\
+ { UNO_NAME_CHAR_DIFF_HEIGHT, RES_CHRATR_FONTSIZE , cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE , MID_FONTHEIGHT_DIFF|CONVERT_TWIPS},\
+ { UNO_NAME_CHAR_PROP_HEIGHT_ASIAN, RES_CHRATR_CJK_FONTSIZE , cppu::UnoType<float>::get(), PROPERTY_NONE , MID_FONTHEIGHT_PROP},\
+ { UNO_NAME_CHAR_DIFF_HEIGHT_ASIAN, RES_CHRATR_CJK_FONTSIZE , cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE , MID_FONTHEIGHT_DIFF|CONVERT_TWIPS},\
+ { UNO_NAME_CHAR_PROP_HEIGHT_COMPLEX, RES_CHRATR_CTL_FONTSIZE , cppu::UnoType<float>::get(), PROPERTY_NONE , MID_FONTHEIGHT_PROP},\
+ { UNO_NAME_CHAR_DIFF_HEIGHT_COMPLEX, RES_CHRATR_CTL_FONTSIZE , cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE , MID_FONTHEIGHT_DIFF|CONVERT_TWIPS},
+
+#define COMMON_PARA_STYLE_PROPERTIES \
+ { UNO_NAME_BREAK_TYPE, RES_BREAK, cppu::UnoType<css::style::BreakType>::get(), PROPERTY_NONE, 0},\
+ { UNO_NAME_PAGE_DESC_NAME, RES_PAGEDESC, cppu::UnoType<OUString>::get(), PropertyAttribute::MAYBEVOID, MID_PAGEDESC_PAGEDESCNAME },\
+ { UNO_NAME_PAGE_NUMBER_OFFSET, RES_PAGEDESC, cppu::UnoType<sal_Int16>::get(), PropertyAttribute::MAYBEVOID, MID_PAGEDESC_PAGENUMOFFSET},\
+ { UNO_NAME_CHAR_AUTO_KERNING, RES_CHRATR_AUTOKERN , cppu::UnoType<bool>::get() , PROPERTY_NONE, 0},\
+ { UNO_NAME_CHAR_BACK_TRANSPARENT, RES_CHRATR_BACKGROUND, cppu::UnoType<bool>::get(), PROPERTY_NONE ,MID_GRAPHIC_TRANSPARENT },\
+ { UNO_NAME_CHAR_BACK_COLOR, RES_CHRATR_BACKGROUND, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE ,MID_BACK_COLOR },\
+ { UNO_NAME_CHAR_BACKGROUND_COMPLEX_COLOR, RES_CHRATR_BACKGROUND, cppu::UnoType<css::util::XComplexColor>::get(), PROPERTY_NONE, MID_BACKGROUND_COMPLEX_COLOR },\
+ { UNO_NAME_CHAR_HIGHLIGHT, RES_CHRATR_HIGHLIGHT, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE ,MID_BACK_COLOR },\
+ { UNO_NAME_PARA_BACK_COLOR, RES_BACKGROUND, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE ,MID_BACK_COLOR },\
+ { UNO_NAME_PARA_BACKGROUND_COMPLEX_COLOR, RES_BACKGROUND, cppu::UnoType<css::util::XComplexColor>::get(), PROPERTY_NONE , MID_BACKGROUND_COMPLEX_COLOR },\
+ { UNO_NAME_PARA_BACK_TRANSPARENT, RES_BACKGROUND, cppu::UnoType<bool>::get(), PROPERTY_NONE ,MID_GRAPHIC_TRANSPARENT },\
+ { UNO_NAME_PARA_GRAPHIC_URL, RES_BACKGROUND, cppu::UnoType<OUString>::get(), PROPERTY_NONE ,MID_GRAPHIC_URL },\
+ { UNO_NAME_PARA_GRAPHIC, RES_BACKGROUND, cppu::UnoType<css::graphic::XGraphic>::get(), PROPERTY_NONE ,MID_GRAPHIC },\
+ { UNO_NAME_PARA_GRAPHIC_FILTER, RES_BACKGROUND, cppu::UnoType<OUString>::get(), PROPERTY_NONE ,MID_GRAPHIC_FILTER },\
+ { UNO_NAME_PARA_GRAPHIC_LOCATION, RES_BACKGROUND, cppu::UnoType<css::style::GraphicLocation>::get(), PROPERTY_NONE ,MID_GRAPHIC_POSITION}, \
+ { UNO_NAME_CHAR_CASE_MAP, RES_CHRATR_CASEMAP, cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE, 0},\
+ { UNO_NAME_CHAR_COLOR, RES_CHRATR_COLOR, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE, 0},\
+ { UNO_NAME_CHAR_COLOR_THEME, RES_CHRATR_COLOR, cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE, MID_COLOR_THEME_INDEX }, \
+ { UNO_NAME_CHAR_COLOR_TINT_OR_SHADE, RES_CHRATR_COLOR, cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE, MID_COLOR_TINT_OR_SHADE }, \
+ { UNO_NAME_CHAR_COMPLEX_COLOR, RES_CHRATR_COLOR, cppu::UnoType<css::util::XComplexColor>::get(), PropertyAttribute::MAYBEVOID, MID_COMPLEX_COLOR }, \
+ { UNO_NAME_CHAR_TRANSPARENCE, RES_CHRATR_COLOR, cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE, MID_COLOR_ALPHA},\
+ { UNO_NAME_CHAR_STRIKEOUT, RES_CHRATR_CROSSEDOUT, cppu::UnoType<sal_Int16>::get(), PropertyAttribute::MAYBEVOID, MID_CROSS_OUT},\
+ { UNO_NAME_CHAR_CROSSED_OUT, RES_CHRATR_CROSSEDOUT, cppu::UnoType<bool>::get() , PROPERTY_NONE, 0},\
+ { UNO_NAME_CHAR_ESCAPEMENT, RES_CHRATR_ESCAPEMENT, cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE, MID_ESC },\
+ { UNO_NAME_CHAR_ESCAPEMENT_HEIGHT, RES_CHRATR_ESCAPEMENT, cppu::UnoType<sal_Int8>::get() , PROPERTY_NONE, MID_ESC_HEIGHT},\
+ { UNO_NAME_CHAR_FLASH, RES_CHRATR_BLINK , cppu::UnoType<bool>::get() , PROPERTY_NONE, 0},\
+ { UNO_NAME_CHAR_HIDDEN, RES_CHRATR_HIDDEN, cppu::UnoType<bool>::get() , PROPERTY_NONE, 0},\
+ STANDARD_FONT_PROPERTIES\
+ CJK_FONT_PROPERTIES\
+ CTL_FONT_PROPERTIES\
+ { UNO_NAME_CHAR_UNDERLINE, RES_CHRATR_UNDERLINE , cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE, MID_TL_STYLE},\
+ { UNO_NAME_CHAR_UNDERLINE_COLOR, RES_CHRATR_UNDERLINE , cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE, MID_TL_COLOR},\
+ { UNO_NAME_CHAR_UNDERLINE_HAS_COLOR, RES_CHRATR_UNDERLINE , cppu::UnoType<bool>::get(), PROPERTY_NONE, MID_TL_HASCOLOR},\
+ { UNO_NAME_CHAR_UNDERLINE_COMPLEX_COLOR, RES_CHRATR_UNDERLINE, cppu::UnoType<css::util::XComplexColor>::get(), PropertyAttribute::MAYBEVOID, MID_TL_COMPLEX_COLOR }, \
+ { UNO_NAME_CHAR_OVERLINE, RES_CHRATR_OVERLINE , cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE, MID_TL_STYLE},\
+ { UNO_NAME_CHAR_OVERLINE_COLOR, RES_CHRATR_OVERLINE , cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE, MID_TL_COLOR},\
+ { UNO_NAME_CHAR_OVERLINE_HAS_COLOR, RES_CHRATR_OVERLINE , cppu::UnoType<bool>::get(), PROPERTY_NONE, MID_TL_HASCOLOR},\
+ { UNO_NAME_CHAR_OVERLINE_COMPLEX_COLOR, RES_CHRATR_OVERLINE, cppu::UnoType<css::util::XComplexColor>::get(), PropertyAttribute::MAYBEVOID, MID_TL_COMPLEX_COLOR }, \
+ { UNO_NAME_PARA_LEFT_MARGIN, RES_MARGIN_TEXTLEFT, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE, MID_TXT_LMARGIN|CONVERT_TWIPS},\
+ { UNO_NAME_PARA_RIGHT_MARGIN, RES_MARGIN_RIGHT, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE, MID_R_MARGIN|CONVERT_TWIPS},\
+ { UNO_NAME_PARA_LEFT_MARGIN_RELATIVE, RES_MARGIN_TEXTLEFT, cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE, MID_L_REL_MARGIN},\
+ { UNO_NAME_PARA_RIGHT_MARGIN_RELATIVE, RES_MARGIN_RIGHT, cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE, MID_R_REL_MARGIN},\
+ { UNO_NAME_PARA_IS_AUTO_FIRST_LINE_INDENT, RES_MARGIN_FIRSTLINE, cppu::UnoType<bool>::get(), PROPERTY_NONE, MID_FIRST_AUTO},\
+ { UNO_NAME_PARA_FIRST_LINE_INDENT, RES_MARGIN_FIRSTLINE, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE, MID_FIRST_LINE_INDENT|CONVERT_TWIPS},\
+ { UNO_NAME_PARA_FIRST_LINE_INDENT_RELATIVE, RES_MARGIN_FIRSTLINE, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE, MID_FIRST_LINE_REL_INDENT|CONVERT_TWIPS},\
+ { UNO_NAME_CHAR_KERNING, RES_CHRATR_KERNING , cppu::UnoType<sal_Int16>::get() , PROPERTY_NONE, CONVERT_TWIPS},\
+ { UNO_NAME_CHAR_NO_HYPHENATION, RES_CHRATR_NOHYPHEN , cppu::UnoType<bool>::get() , PROPERTY_NONE, 0},\
+ { UNO_NAME_CHAR_SHADOWED, RES_CHRATR_SHADOWED , cppu::UnoType<bool>::get() , PROPERTY_NONE, 0},\
+ { UNO_NAME_CHAR_CONTOURED, RES_CHRATR_CONTOUR, cppu::UnoType<bool>::get() , PROPERTY_NONE, 0},\
+ { UNO_NAME_DROP_CAP_FORMAT, RES_PARATR_DROP, cppu::UnoType<css::style::DropCapFormat>::get() , PROPERTY_NONE, MID_DROPCAP_FORMAT|CONVERT_TWIPS },\
+ { UNO_NAME_DROP_CAP_WHOLE_WORD, RES_PARATR_DROP, cppu::UnoType<bool>::get() , PROPERTY_NONE, MID_DROPCAP_WHOLE_WORD },\
+ { UNO_NAME_DROP_CAP_CHAR_STYLE_NAME, RES_PARATR_DROP, cppu::UnoType<OUString>::get() , PropertyAttribute::MAYBEVOID, MID_DROPCAP_CHAR_STYLE_NAME },\
+ { UNO_NAME_PARA_KEEP_TOGETHER, RES_KEEP, cppu::UnoType<bool>::get() , PROPERTY_NONE, 0},\
+ { UNO_NAME_PARA_SPLIT, RES_PARATR_SPLIT, cppu::UnoType<bool>::get() , PROPERTY_NONE, 0},\
+ { UNO_NAME_PARA_WIDOWS, RES_PARATR_WIDOWS, cppu::UnoType<sal_Int8>::get(),PropertyAttribute::MAYBEVOID, 0},\
+ { UNO_NAME_PARA_ORPHANS, RES_PARATR_ORPHANS, cppu::UnoType<sal_Int8>::get(),PropertyAttribute::MAYBEVOID, 0},\
+ { UNO_NAME_PARA_EXPAND_SINGLE_WORD, RES_PARATR_ADJUST, cppu::UnoType<bool>::get() , PROPERTY_NONE, MID_EXPAND_SINGLE },\
+ { UNO_NAME_PARA_LAST_LINE_ADJUST, RES_PARATR_ADJUST, cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE, MID_LAST_LINE_ADJUST},\
+ { UNO_NAME_PARA_LINE_NUMBER_COUNT, RES_LINENUMBER, cppu::UnoType<bool>::get(), PROPERTY_NONE ,MID_LINENUMBER_COUNT },\
+ { UNO_NAME_PARA_LINE_NUMBER_START_VALUE, RES_LINENUMBER, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE ,MID_LINENUMBER_STARTVALUE},\
+ { UNO_NAME_PARA_LINE_SPACING, RES_PARATR_LINESPACING, cppu::UnoType<css::style::LineSpacing>::get(),PROPERTY_NONE, CONVERT_TWIPS},\
+ { UNO_NAME_PARA_ADJUST, RES_PARATR_ADJUST, cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE, MID_PARA_ADJUST},\
+ { UNO_NAME_PARA_REGISTER_MODE_ACTIVE, RES_PARATR_REGISTER, cppu::UnoType<bool>::get() , PROPERTY_NONE, 0},\
+ { UNO_NAME_PARA_TOP_MARGIN, RES_UL_SPACE, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE, MID_UP_MARGIN|CONVERT_TWIPS},\
+ { UNO_NAME_PARA_BOTTOM_MARGIN, RES_UL_SPACE, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE, MID_LO_MARGIN|CONVERT_TWIPS},\
+ { UNO_NAME_PARA_CONTEXT_MARGIN, RES_UL_SPACE, cppu::UnoType<bool>::get(), PROPERTY_NONE, MID_CTX_MARGIN},\
+ { UNO_NAME_PARA_TOP_MARGIN_RELATIVE, RES_UL_SPACE, cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE, MID_UP_REL_MARGIN},\
+ { UNO_NAME_PARA_BOTTOM_MARGIN_RELATIVE, RES_UL_SPACE, cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE, MID_LO_REL_MARGIN},\
+ TABSTOPS_MAP_ENTRY\
+ { UNO_NAME_CHAR_WORD_MODE, RES_CHRATR_WORDLINEMODE,cppu::UnoType<bool>::get() , PROPERTY_NONE, 0},\
+ { UNO_NAME_CHAR_SHADING_VALUE, RES_CHRATR_BACKGROUND, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE, MID_SHADING_VALUE }, \
+ { UNO_NAME_CHAR_LEFT_BORDER, RES_CHRATR_BOX, cppu::UnoType<css::table::BorderLine>::get(), PROPERTY_NONE, LEFT_BORDER |CONVERT_TWIPS },\
+ { UNO_NAME_CHAR_RIGHT_BORDER, RES_CHRATR_BOX, cppu::UnoType<css::table::BorderLine>::get(), PROPERTY_NONE, RIGHT_BORDER |CONVERT_TWIPS },\
+ { UNO_NAME_CHAR_TOP_BORDER, RES_CHRATR_BOX, cppu::UnoType<css::table::BorderLine>::get(), PROPERTY_NONE, TOP_BORDER |CONVERT_TWIPS },\
+ { UNO_NAME_CHAR_BOTTOM_BORDER, RES_CHRATR_BOX, cppu::UnoType<css::table::BorderLine>::get(), PROPERTY_NONE, BOTTOM_BORDER |CONVERT_TWIPS },\
+ { UNO_NAME_CHAR_BORDER_DISTANCE, RES_CHRATR_BOX, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE, BORDER_DISTANCE |CONVERT_TWIPS },\
+ { UNO_NAME_CHAR_LEFT_BORDER_DISTANCE, RES_CHRATR_BOX, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE, LEFT_BORDER_DISTANCE |CONVERT_TWIPS },\
+ { UNO_NAME_CHAR_RIGHT_BORDER_DISTANCE, RES_CHRATR_BOX, cppu::UnoType<sal_Int32>::get(),PROPERTY_NONE, RIGHT_BORDER_DISTANCE |CONVERT_TWIPS },\
+ { UNO_NAME_CHAR_TOP_BORDER_DISTANCE, RES_CHRATR_BOX, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE, TOP_BORDER_DISTANCE |CONVERT_TWIPS },\
+ { UNO_NAME_CHAR_BOTTOM_BORDER_DISTANCE, RES_CHRATR_BOX, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE, BOTTOM_BORDER_DISTANCE|CONVERT_TWIPS },\
+ { UNO_NAME_CHAR_BORDER_LEFT_COMPLEX_COLOR, RES_CHRATR_BOX, cppu::UnoType<css::util::XComplexColor>::get(), PropertyAttribute::MAYBEVOID, MID_BORDER_LEFT_COLOR }, \
+ { UNO_NAME_CHAR_BORDER_RIGHT_COMPLEX_COLOR, RES_CHRATR_BOX, cppu::UnoType<css::util::XComplexColor>::get(), PropertyAttribute::MAYBEVOID, MID_BORDER_RIGHT_COLOR }, \
+ { UNO_NAME_CHAR_BORDER_TOP_COMPLEX_COLOR, RES_CHRATR_BOX, cppu::UnoType<css::util::XComplexColor>::get(), PropertyAttribute::MAYBEVOID, MID_BORDER_TOP_COLOR }, \
+ { UNO_NAME_CHAR_BORDER_BOTTOM_COMPLEX_COLOR, RES_CHRATR_BOX, cppu::UnoType<css::util::XComplexColor>::get(), PropertyAttribute::MAYBEVOID, MID_BORDER_BOTTOM_COLOR }, \
+ { UNO_NAME_CHAR_SHADOW_FORMAT, RES_CHRATR_SHADOW, cppu::UnoType<css::table::ShadowFormat>::get(), PROPERTY_NONE, CONVERT_TWIPS},\
+ { UNO_NAME_LEFT_BORDER, RES_BOX, cppu::UnoType<css::table::BorderLine>::get(), 0, LEFT_BORDER |CONVERT_TWIPS },\
+ { UNO_NAME_RIGHT_BORDER, RES_BOX, cppu::UnoType<css::table::BorderLine>::get(), 0, RIGHT_BORDER |CONVERT_TWIPS },\
+ { UNO_NAME_TOP_BORDER, RES_BOX, cppu::UnoType<css::table::BorderLine>::get(), 0, TOP_BORDER |CONVERT_TWIPS },\
+ { UNO_NAME_BOTTOM_BORDER, RES_BOX, cppu::UnoType<css::table::BorderLine>::get(), 0, BOTTOM_BORDER|CONVERT_TWIPS },\
+ { UNO_NAME_BORDER_DISTANCE, RES_BOX, cppu::UnoType<sal_Int32>::get(), 0, BORDER_DISTANCE|CONVERT_TWIPS },\
+ { UNO_NAME_LEFT_BORDER_DISTANCE, RES_BOX, cppu::UnoType<sal_Int32>::get(), 0, LEFT_BORDER_DISTANCE |CONVERT_TWIPS },\
+ { UNO_NAME_RIGHT_BORDER_DISTANCE, RES_BOX, cppu::UnoType<sal_Int32>::get(), 0, RIGHT_BORDER_DISTANCE |CONVERT_TWIPS },\
+ { UNO_NAME_TOP_BORDER_DISTANCE, RES_BOX, cppu::UnoType<sal_Int32>::get(), 0, TOP_BORDER_DISTANCE |CONVERT_TWIPS },\
+ { UNO_NAME_BOTTOM_BORDER_DISTANCE, RES_BOX, cppu::UnoType<sal_Int32>::get(), 0, BOTTOM_BORDER_DISTANCE|CONVERT_TWIPS },\
+ { UNO_NAME_BORDER_LEFT_COMPLEX_COLOR, RES_BOX, cppu::UnoType<css::util::XComplexColor>::get(), 0, MID_BORDER_LEFT_COLOR }, \
+ { UNO_NAME_BORDER_RIGHT_COMPLEX_COLOR, RES_BOX, cppu::UnoType<css::util::XComplexColor>::get(), 0, MID_BORDER_RIGHT_COLOR }, \
+ { UNO_NAME_BORDER_TOP_COMPLEX_COLOR, RES_BOX, cppu::UnoType<css::util::XComplexColor>::get(), 0, MID_BORDER_TOP_COLOR }, \
+ { UNO_NAME_BORDER_BOTTOM_COMPLEX_COLOR, RES_BOX, cppu::UnoType<css::util::XComplexColor>::get(), 0, MID_BORDER_BOTTOM_COLOR }, \
+ { UNO_NAME_PARA_IS_HYPHENATION, RES_PARATR_HYPHENZONE, cppu::UnoType<bool>::get(), PropertyAttribute::MAYBEVOID, MID_IS_HYPHEN },\
+ { UNO_NAME_PARA_HYPHENATION_NO_CAPS, RES_PARATR_HYPHENZONE, cppu::UnoType<bool>::get(), PropertyAttribute::MAYBEVOID, MID_HYPHEN_NO_CAPS },\
+ { UNO_NAME_PARA_HYPHENATION_NO_LAST_WORD, RES_PARATR_HYPHENZONE, cppu::UnoType<bool>::get(), PropertyAttribute::MAYBEVOID, MID_HYPHEN_NO_LAST_WORD },\
+ { UNO_NAME_PARA_HYPHENATION_MAX_LEADING_CHARS, RES_PARATR_HYPHENZONE, cppu::UnoType<sal_Int16>::get(), PropertyAttribute::MAYBEVOID, MID_HYPHEN_MIN_LEAD },\
+ { UNO_NAME_PARA_HYPHENATION_MAX_TRAILING_CHARS, RES_PARATR_HYPHENZONE, cppu::UnoType<sal_Int16>::get(), PropertyAttribute::MAYBEVOID, MID_HYPHEN_MIN_TRAIL },\
+ { UNO_NAME_PARA_HYPHENATION_MAX_HYPHENS, RES_PARATR_HYPHENZONE, cppu::UnoType<sal_Int16>::get(), PropertyAttribute::MAYBEVOID, MID_HYPHEN_MAX_HYPHENS},\
+ { UNO_NAME_PARA_HYPHENATION_MIN_WORD_LENGTH, RES_PARATR_HYPHENZONE, cppu::UnoType<sal_Int16>::get(), PropertyAttribute::MAYBEVOID, MID_HYPHEN_MIN_WORD_LENGTH},\
+ { UNO_NAME_PARA_HYPHENATION_ZONE, RES_PARATR_HYPHENZONE, cppu::UnoType<sal_Int16>::get(), PropertyAttribute::MAYBEVOID, MID_HYPHEN_ZONE},\
+ { UNO_NAME_NUMBERING_STYLE_NAME, RES_PARATR_NUMRULE, cppu::UnoType<OUString>::get(), PropertyAttribute::MAYBEVOID, 0},\
+ { UNO_NAME_NUMBERING_LEVEL, RES_PARATR_LIST_LEVEL, cppu::UnoType<sal_Int16>::get(), PropertyAttribute::MAYBEVOID, 0},\
+ { UNO_NAME_PARA_USER_DEFINED_ATTRIBUTES, RES_UNKNOWNATR_CONTAINER, cppu::UnoType<css::container::XNameContainer>::get(), PropertyAttribute::MAYBEVOID, 0 },\
+ { UNO_NAME_PARA_SHADOW_FORMAT, RES_SHADOW, cppu::UnoType<css::table::ShadowFormat>::get(), PROPERTY_NONE, CONVERT_TWIPS},\
+ { UNO_NAME_CHAR_COMBINE_IS_ON, RES_CHRATR_TWO_LINES, cppu::UnoType<bool>::get(), PROPERTY_NONE, MID_TWOLINES},\
+ { UNO_NAME_CHAR_COMBINE_PREFIX, RES_CHRATR_TWO_LINES, cppu::UnoType<OUString>::get(), PROPERTY_NONE, MID_START_BRACKET},\
+ { UNO_NAME_CHAR_COMBINE_SUFFIX, RES_CHRATR_TWO_LINES, cppu::UnoType<OUString>::get(), PROPERTY_NONE, MID_END_BRACKET},\
+ { UNO_NAME_CHAR_EMPHASIS, RES_CHRATR_EMPHASIS_MARK, cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE, MID_EMPHASIS},\
+ { UNO_NAME_PARA_IS_HANGING_PUNCTUATION, RES_PARATR_HANGINGPUNCTUATION, cppu::UnoType<bool>::get(), PROPERTY_NONE ,0 },\
+ { UNO_NAME_PARA_IS_CHARACTER_DISTANCE, RES_PARATR_SCRIPTSPACE, cppu::UnoType<bool>::get(), PROPERTY_NONE ,0 },\
+ { UNO_NAME_PARA_IS_FORBIDDEN_RULES, RES_PARATR_FORBIDDEN_RULES, cppu::UnoType<bool>::get(), PROPERTY_NONE ,0 },\
+ { UNO_NAME_PARA_VERT_ALIGNMENT, RES_PARATR_VERTALIGN, cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE , 0 },\
+ { UNO_NAME_CHAR_ROTATION, RES_CHRATR_ROTATE, cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE, MID_ROTATE },\
+ { UNO_NAME_CHAR_ROTATION_IS_FIT_TO_LINE, RES_CHRATR_ROTATE, cppu::UnoType<bool>::get(), PROPERTY_NONE, MID_FITTOLINE },\
+ { UNO_NAME_CHAR_SCALE_WIDTH, RES_CHRATR_SCALEW, cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE, 0 },\
+ { UNO_NAME_CHAR_RELIEF, RES_CHRATR_RELIEF, cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE, MID_RELIEF },\
+ PROP_DIFF_FONTHEIGHT\
+ { UNO_NAME_FOLLOW_STYLE, FN_UNO_FOLLOW_STYLE, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},\
+ { UNO_NAME_LINK_STYLE, FN_UNO_LINK_STYLE, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},\
+ { UNO_NAME_IS_PHYSICAL, FN_UNO_IS_PHYSICAL, cppu::UnoType<bool>::get(), PropertyAttribute::READONLY, 0},\
+ { UNO_NAME_IS_AUTO_UPDATE, FN_UNO_IS_AUTO_UPDATE, cppu::UnoType<bool>::get(), PROPERTY_NONE, 0},\
+ { UNO_NAME_DISPLAY_NAME, FN_UNO_DISPLAY_NAME, cppu::UnoType<OUString>::get(), PropertyAttribute::READONLY, 0},\
+ { UNO_NAME_CATEGORY, FN_UNO_CATEGORY, cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE , 0 },\
+ { UNO_NAME_WRITING_MODE, RES_FRAMEDIR, cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE, 0 },\
+ { UNO_NAME_PARA_IS_CONNECT_BORDER, RES_PARATR_CONNECT_BORDER, cppu::UnoType<bool>::get(), PropertyAttribute::MAYBEVOID, 0},\
+ { UNO_NAME_SNAP_TO_GRID, RES_PARATR_SNAPTOGRID, cppu::UnoType<bool>::get(), PropertyAttribute::MAYBEVOID, 0 }, \
+ { UNO_NAME_OUTLINE_LEVEL, RES_PARATR_OUTLINELEVEL,cppu::UnoType<sal_Int16>::get(), PropertyAttribute::MAYBEVOID, 0}, \
+ { UNO_NAME_HIDDEN, FN_UNO_HIDDEN, cppu::UnoType<bool>::get(), PROPERTY_NONE, 0}, \
+ { UNO_NAME_STYLE_INTEROP_GRAB_BAG, FN_UNO_STYLE_INTEROP_GRAB_BAG, cppu::UnoType< cppu::UnoSequenceType<css::beans::PropertyValue> >::get(), PROPERTY_NONE, 0}, \
+ { UNO_NAME_PARA_INTEROP_GRAB_BAG, RES_PARATR_GRABBAG, cppu::UnoType< cppu::UnoSequenceType<css::beans::PropertyValue> >::get(), PROPERTY_NONE, 0},
+
+#define COMMON_ACCESSIBILITY_TEXT_ATTRIBUTE \
+ { UNO_NAME_CHAR_BACK_COLOR, RES_CHRATR_BACKGROUND, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE ,MID_BACK_COLOR }, \
+ { UNO_NAME_CHAR_BACKGROUND_COMPLEX_COLOR, RES_CHRATR_BACKGROUND, cppu::UnoType<css::util::XComplexColor>::get(), PROPERTY_NONE, MID_BACKGROUND_COMPLEX_COLOR },\
+ { UNO_NAME_CHAR_COLOR, RES_CHRATR_COLOR, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE, 0}, \
+ { UNO_NAME_CHAR_COLOR_THEME, RES_CHRATR_COLOR, cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE, MID_COLOR_THEME_INDEX }, \
+ { UNO_NAME_CHAR_COLOR_TINT_OR_SHADE, RES_CHRATR_COLOR, cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE, MID_COLOR_TINT_OR_SHADE }, \
+ { UNO_NAME_CHAR_COMPLEX_COLOR, RES_CHRATR_COLOR, cppu::UnoType<css::util::XComplexColor>::get(), PropertyAttribute::MAYBEVOID, MID_COMPLEX_COLOR }, \
+ { UNO_NAME_CHAR_TRANSPARENCE, RES_CHRATR_COLOR, cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE, MID_COLOR_ALPHA }, \
+ { UNO_NAME_CHAR_CONTOURED, RES_CHRATR_CONTOUR, cppu::UnoType<bool>::get() , PROPERTY_NONE, 0}, \
+ { UNO_NAME_CHAR_EMPHASIS, RES_CHRATR_EMPHASIS_MARK, cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE, MID_EMPHASIS}, \
+ { UNO_NAME_CHAR_ESCAPEMENT, RES_CHRATR_ESCAPEMENT, cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE, MID_ESC }, \
+ { UNO_NAME_CHAR_FONT_NAME, RES_CHRATR_FONT, cppu::UnoType<OUString>::get(), PropertyAttribute::MAYBEVOID, MID_FONT_FAMILY_NAME }, \
+ { UNO_NAME_CHAR_HEIGHT, RES_CHRATR_FONTSIZE , cppu::UnoType<float>::get(), PropertyAttribute::MAYBEVOID, MID_FONTHEIGHT|CONVERT_TWIPS}, \
+ { UNO_NAME_CHAR_POSTURE, RES_CHRATR_POSTURE , cppu::UnoType<css::awt::FontSlant>::get(), PropertyAttribute::MAYBEVOID, MID_POSTURE}, \
+ { UNO_NAME_CHAR_SHADOWED, RES_CHRATR_SHADOWED , cppu::UnoType<bool>::get() , PROPERTY_NONE, 0}, \
+ { UNO_NAME_CHAR_STRIKEOUT, RES_CHRATR_CROSSEDOUT, cppu::UnoType<sal_Int16>::get(), PropertyAttribute::MAYBEVOID, MID_CROSS_OUT}, \
+ { UNO_NAME_CHAR_UNDERLINE_COLOR, RES_CHRATR_UNDERLINE , cppu::UnoType<sal_Int32>::get(), PropertyAttribute::MAYBEVOID, MID_TL_COLOR}, \
+ { UNO_NAME_CHAR_UNDERLINE_COLOR, RES_CHRATR_UNDERLINE , cppu::UnoType<sal_Int32>::get(), PropertyAttribute::MAYBEVOID, MID_TL_COLOR}, \
+ { UNO_NAME_CHAR_UNDERLINE_COMPLEX_COLOR, RES_CHRATR_UNDERLINE, cppu::UnoType<css::util::XComplexColor>::get(), PropertyAttribute::MAYBEVOID, MID_TL_COMPLEX_COLOR}, \
+ { UNO_NAME_CHAR_WEIGHT, RES_CHRATR_WEIGHT , cppu::UnoType<float>::get(), PropertyAttribute::MAYBEVOID, MID_WEIGHT}, \
+ { UNO_NAME_NUMBERING_LEVEL, RES_PARATR_LIST_LEVEL,cppu::UnoType<sal_Int16>::get(), PropertyAttribute::MAYBEVOID, 0}, \
+ { UNO_NAME_NUMBERING, RES_PARATR_LIST_ISCOUNTED, cppu::UnoType<bool>::get(), PropertyAttribute::MAYBEVOID, 0}, \
+ { UNO_NAME_CHAR_UNDERLINE, RES_CHRATR_UNDERLINE , cppu::UnoType<sal_Int16>::get(), PropertyAttribute::MAYBEVOID, MID_TL_STYLE}, \
+ { UNO_NAME_NUMBERING_RULES, RES_PARATR_NUMRULE,cppu::UnoType<sal_Int16>::get(), PropertyAttribute::MAYBEVOID, CONVERT_TWIPS}, \
+ { UNO_NAME_PARA_ADJUST, RES_PARATR_ADJUST, cppu::UnoType<sal_Int16>::get(), PropertyAttribute::MAYBEVOID, MID_PARA_ADJUST}, \
+ { UNO_NAME_PARA_BOTTOM_MARGIN, RES_UL_SPACE, cppu::UnoType<sal_Int32>::get(), PropertyAttribute::MAYBEVOID, MID_LO_MARGIN|CONVERT_TWIPS}, \
+ { UNO_NAME_PARA_FIRST_LINE_INDENT, RES_MARGIN_FIRSTLINE, cppu::UnoType<sal_Int32>::get(), PropertyAttribute::MAYBEVOID, MID_FIRST_LINE_INDENT|CONVERT_TWIPS}, \
+ { UNO_NAME_PARA_LEFT_MARGIN, RES_MARGIN_TEXTLEFT, cppu::UnoType<sal_Int32>::get(), PropertyAttribute::MAYBEVOID, MID_TXT_LMARGIN|CONVERT_TWIPS}, \
+ { UNO_NAME_PARA_LINE_SPACING, RES_PARATR_LINESPACING, cppu::UnoType<css::style::LineSpacing>::get(), PropertyAttribute::MAYBEVOID, CONVERT_TWIPS}, \
+ { UNO_NAME_PARA_RIGHT_MARGIN, RES_MARGIN_RIGHT, cppu::UnoType<sal_Int32>::get(), PropertyAttribute::MAYBEVOID, MID_R_MARGIN|CONVERT_TWIPS}, \
+ { UNO_NAME_TABSTOPS, RES_PARATR_TABSTOP, cppu::UnoType< cppu::UnoSequenceType<css::style::TabStop> >::get(), PropertyAttribute::MAYBEVOID, CONVERT_TWIPS}, \
+
+#define FILL_PROPERTIES_SW_BMP \
+ { UNO_NAME_FILLBMP_LOGICAL_SIZE, XATTR_FILLBMP_SIZELOG, cppu::UnoType<bool>::get(), 0, 0}, \
+ { UNO_NAME_FILLBMP_OFFSET_X, XATTR_FILLBMP_TILEOFFSETX, cppu::UnoType<sal_Int32>::get(), 0, 0}, \
+ { UNO_NAME_FILLBMP_OFFSET_Y, XATTR_FILLBMP_TILEOFFSETY, cppu::UnoType<sal_Int32>::get(), 0, 0}, \
+ { UNO_NAME_FILLBMP_POSITION_OFFSET_X, XATTR_FILLBMP_POSOFFSETX, cppu::UnoType<sal_Int32>::get(), 0, 0}, \
+ { UNO_NAME_FILLBMP_POSITION_OFFSET_Y, XATTR_FILLBMP_POSOFFSETY, cppu::UnoType<sal_Int32>::get(), 0, 0}, \
+ { UNO_NAME_FILLBMP_RECTANGLE_POINT, XATTR_FILLBMP_POS, cppu::UnoType<css::drawing::RectanglePoint>::get(), 0, 0}, \
+ { UNO_NAME_FILLBMP_SIZE_X, XATTR_FILLBMP_SIZEX, cppu::UnoType<sal_Int32>::get(), 0, 0, PropertyMoreFlags::METRIC_ITEM}, \
+ { UNO_NAME_FILLBMP_SIZE_Y, XATTR_FILLBMP_SIZEY, cppu::UnoType<sal_Int32>::get(), 0, 0, PropertyMoreFlags::METRIC_ITEM}, \
+ { UNO_NAME_FILLBMP_STRETCH, XATTR_FILLBMP_STRETCH, cppu::UnoType<bool>::get(), 0, 0}, \
+ { UNO_NAME_FILLBMP_TILE, XATTR_FILLBMP_TILE, cppu::UnoType<bool>::get(), 0, 0},\
+ { UNO_NAME_FILLBMP_MODE, OWN_ATTR_FILLBMP_MODE, cppu::UnoType<drawing::BitmapMode>::get(), 0, 0}, \
+
+#define FILL_PROPERTIES_SW_DEFAULTS \
+ { UNO_NAME_FILLCOLOR, XATTR_FILLCOLOR, cppu::UnoType<sal_Int32>::get(), 0, 0}, \
+
+#define FILL_PROPERTIES_SW \
+ FILL_PROPERTIES_SW_BMP \
+ FILL_PROPERTIES_SW_DEFAULTS \
+ { UNO_NAME_FILLBACKGROUND, XATTR_FILLBACKGROUND, cppu::UnoType<bool>::get(), 0, 0}, \
+ { UNO_NAME_FILLBITMAP, XATTR_FILLBITMAP, cppu::UnoType<css::awt::XBitmap>::get(), 0, MID_BITMAP}, \
+ { UNO_NAME_FILLBITMAPURL, XATTR_FILLBITMAP, cppu::UnoType<OUString>::get(), 0, MID_BITMAP }, \
+ { UNO_NAME_FILLBITMAPNAME, XATTR_FILLBITMAP, cppu::UnoType<OUString>::get(), 0, MID_NAME }, \
+ { UNO_NAME_FILLGRADIENTSTEPCOUNT, XATTR_GRADIENTSTEPCOUNT, cppu::UnoType<sal_Int16>::get(), 0, 0}, \
+ { UNO_NAME_FILLGRADIENT, XATTR_FILLGRADIENT, cppu::UnoType<css::awt::Gradient>::get(), 0, MID_FILLGRADIENT}, \
+ { UNO_NAME_FILLGRADIENTNAME, XATTR_FILLGRADIENT, cppu::UnoType<OUString>::get(), 0, MID_NAME }, \
+ { UNO_NAME_FILLHATCH, XATTR_FILLHATCH, cppu::UnoType<css::drawing::Hatch>::get(), 0, MID_FILLHATCH}, \
+ { UNO_NAME_FILLHATCHNAME, XATTR_FILLHATCH, cppu::UnoType<OUString>::get(), 0, MID_NAME }, \
+ { UNO_NAME_FILLSTYLE, XATTR_FILLSTYLE, cppu::UnoType<css::drawing::FillStyle>::get(), 0, 0}, \
+ { UNO_NAME_FILL_TRANSPARENCE, XATTR_FILLTRANSPARENCE, cppu::UnoType<sal_Int16>::get(), 0, 0}, \
+ { UNO_NAME_FILLTRANSPARENCEGRADIENT, XATTR_FILLFLOATTRANSPARENCE, cppu::UnoType<css::awt::Gradient>::get(), 0, MID_FILLGRADIENT}, \
+ { UNO_NAME_FILLTRANSPARENCEGRADIENTNAME, XATTR_FILLFLOATTRANSPARENCE, cppu::UnoType<OUString>::get(), 0, MID_NAME }, \
+ { UNO_NAME_FILLCOLOR_2, XATTR_SECONDARYFILLCOLOR, cppu::UnoType<sal_Int32>::get(), 0, 0}, \
+ { UNO_NAME_FILL_COMPLEX_COLOR, XATTR_FILLCOLOR, cppu::UnoType<css::util::XComplexColor>::get(), 0, MID_COMPLEX_COLOR}, \
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/core/unocore/unoobj.cxx b/sw/source/core/unocore/unoobj.cxx
new file mode 100644
index 0000000000..b2f83fee30
--- /dev/null
+++ b/sw/source/core/unocore/unoobj.cxx
@@ -0,0 +1,3123 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <com/sun/star/table/TableSortField.hpp>
+#include <cppuhelper/exc_hlp.hxx>
+#include <cppuhelper/supportsservice.hxx>
+#include <svl/itemprop.hxx>
+#include <o3tl/any.hxx>
+#include <o3tl/safeint.hxx>
+#include <osl/endian.h>
+#include <unotools/collatorwrapper.hxx>
+
+#include <autostyle_helper.hxx>
+#include <swtypes.hxx>
+#include <hintids.hxx>
+#include <cmdid.h>
+#include <unomid.h>
+#include <hints.hxx>
+#include <doc.hxx>
+#include <IDocumentUndoRedo.hxx>
+#include <istyleaccess.hxx>
+#include <ndtxt.hxx>
+#include <unocrsr.hxx>
+#include <unocrsrhelper.hxx>
+#include <unoport.hxx>
+#include <swundo.hxx>
+#include <rootfrm.hxx>
+#include <paratr.hxx>
+#include <pam.hxx>
+#include <shellio.hxx>
+#include <unotbl.hxx>
+#include <fmtruby.hxx>
+#include <docsh.hxx>
+#include <docstyle.hxx>
+#include <fmtpdsc.hxx>
+#include <pagedesc.hxx>
+#include <edimp.hxx>
+#include <fchrfmt.hxx>
+#include <fmtautofmt.hxx>
+#include <unotextrange.hxx>
+#include <unotextcursor.hxx>
+#include <unomap.hxx>
+#include <unoprnms.hxx>
+#include <unometa.hxx>
+#include <unocontentcontrol.hxx>
+#include <unotext.hxx>
+#include <com/sun/star/text/TextMarkupType.hpp>
+#include <utility>
+#include <vcl/svapp.hxx>
+#include <unotools/syslocale.hxx>
+#include <i18nlangtag/languagetag.hxx>
+#include <SwStyleNameMapper.hxx>
+#include <sortopt.hxx>
+#include <com/sun/star/beans/PropertyAttribute.hpp>
+#include <com/sun/star/beans/NamedValue.hpp>
+#include <com/sun/star/i18n/WordType.hpp>
+#include <memory>
+#include <unoparaframeenum.hxx>
+#include <unoparagraph.hxx>
+#include <iodetect.hxx>
+#include <comphelper/propertyvalue.hxx>
+#include <comphelper/servicehelper.hxx>
+#include <comphelper/profilezone.hxx>
+#include <comphelper/flagguard.hxx>
+#include <swmodule.hxx>
+
+using namespace ::com::sun::star;
+
+// Helper classes
+SwUnoInternalPaM::SwUnoInternalPaM(SwDoc& rDoc) :
+ SwPaM(rDoc.GetNodes())
+{
+}
+
+SwUnoInternalPaM::~SwUnoInternalPaM()
+{
+ while( GetNext() != this)
+ {
+ // coverity[deref_arg] - the delete moves a new entry into GetNext()
+ delete GetNext();
+ }
+}
+
+SwUnoInternalPaM& SwUnoInternalPaM::operator=(const SwPaM& rPaM)
+{
+ const SwPaM* pTmp = &rPaM;
+ *GetPoint() = *rPaM.GetPoint();
+ if(rPaM.HasMark())
+ {
+ SetMark();
+ *GetMark() = *rPaM.GetMark();
+ }
+ else
+ DeleteMark();
+ while(&rPaM != (pTmp = pTmp->GetNext()))
+ {
+ if(pTmp->HasMark())
+ new SwPaM(*pTmp->GetMark(), *pTmp->GetPoint(), this);
+ else
+ new SwPaM(*pTmp->GetPoint(), this);
+ }
+ return *this;
+}
+
+void SwUnoCursorHelper::SelectPam(SwPaM & rPam, const bool bExpand)
+{
+ if (bExpand)
+ {
+ if (!rPam.HasMark())
+ {
+ rPam.SetMark();
+ }
+ }
+ else if (rPam.HasMark())
+ {
+ rPam.DeleteMark();
+ }
+}
+
+void SwUnoCursorHelper::GetTextFromPam(SwPaM & rPam, OUString & rBuffer,
+ SwRootFrame const*const pLayout)
+{
+ if (!rPam.HasMark())
+ {
+ return;
+ }
+ SvMemoryStream aStream;
+#ifdef OSL_BIGENDIAN
+ aStream.SetEndian( SvStreamEndian::BIG );
+#else
+ aStream.SetEndian( SvStreamEndian::LITTLE );
+#endif
+ WriterRef xWrt;
+ // TODO/MBA: looks like a BaseURL doesn't make sense here
+ SwReaderWriter::GetWriter( FILTER_TEXT_DLG, OUString(), xWrt );
+ if( !xWrt.is() )
+ return;
+
+ SwWriter aWriter( aStream, rPam );
+ xWrt->m_bASCII_NoLastLineEnd = true;
+ xWrt->m_bExportParagraphNumbering = false;
+ SwAsciiOptions aOpt = xWrt->GetAsciiOptions();
+ aOpt.SetCharSet( RTL_TEXTENCODING_UNICODE );
+ xWrt->SetAsciiOptions( aOpt );
+ xWrt->m_bUCS2_WithStartChar = false;
+ // #i68522#
+ const bool bOldShowProgress = xWrt->m_bShowProgress;
+ xWrt->m_bShowProgress = false;
+ xWrt->m_bHideDeleteRedlines = pLayout && pLayout->IsHideRedlines();
+ // tdf#155951 SwWriter::Write calls EndAllAction, and that
+ // called SelectShell(), triggering selection change event, which
+ // resulted infinite recursion, if selectionChanged() calls
+ // XTextRange::getString() e.g. on the selected range.
+ ::comphelper::FlagRestorationGuard g(g_bNoInterrupt, true);
+
+ if( ! aWriter.Write( xWrt ).IsError() )
+ {
+ const sal_uInt64 lUniLen = aStream.GetSize()/sizeof( sal_Unicode );
+ if (lUniLen < o3tl::make_unsigned(SAL_MAX_INT32-1))
+ {
+ aStream.WriteUInt16( '\0' );
+
+ aStream.Seek( 0 );
+ aStream.ResetError();
+
+ rtl_uString *pStr = rtl_uString_alloc(lUniLen);
+ aStream.ReadBytes(pStr->buffer, lUniLen * sizeof(sal_Unicode));
+ rBuffer = OUString(pStr, SAL_NO_ACQUIRE);
+ }
+ }
+ xWrt->m_bShowProgress = bOldShowProgress;
+
+}
+
+/// @throws lang::IllegalArgumentException
+/// @throws uno::RuntimeException
+static void
+lcl_setCharStyle(SwDoc& rDoc, const uno::Any & rValue, SfxItemSet & rSet)
+{
+ SwDocShell *const pDocSh = rDoc.GetDocShell();
+ if(!pDocSh)
+ return;
+
+ OUString uStyle;
+ if (!(rValue >>= uStyle))
+ {
+ throw lang::IllegalArgumentException();
+ }
+ OUString sStyle;
+ SwStyleNameMapper::FillUIName(uStyle, sStyle,
+ SwGetPoolIdFromName::ChrFmt);
+ SwDocStyleSheet *const pStyle = static_cast<SwDocStyleSheet*>(
+ pDocSh->GetStyleSheetPool()->Find(sStyle, SfxStyleFamily::Char));
+ if (!pStyle)
+ {
+ throw lang::IllegalArgumentException();
+ }
+ const SwFormatCharFormat aFormat(pStyle->GetCharFormat());
+ rSet.Put(aFormat);
+};
+
+/// @throws lang::IllegalArgumentException
+static void
+lcl_setAutoStyle(IStyleAccess & rStyleAccess, const uno::Any & rValue,
+ SfxItemSet & rSet, const bool bPara)
+{
+ OUString uStyle;
+ if (!(rValue >>= uStyle))
+ {
+ throw lang::IllegalArgumentException();
+ }
+ std::shared_ptr<SfxItemSet> pStyle = bPara ?
+ rStyleAccess.getByName(uStyle, IStyleAccess::AUTO_STYLE_PARA ):
+ rStyleAccess.getByName(uStyle, IStyleAccess::AUTO_STYLE_CHAR );
+ if(!pStyle)
+ {
+ throw lang::IllegalArgumentException();
+ }
+
+ SwFormatAutoFormat aFormat( bPara
+ ? sal::static_int_cast< sal_uInt16 >(RES_AUTO_STYLE)
+ : sal::static_int_cast< sal_uInt16 >(RES_TXTATR_AUTOFMT) );
+ aFormat.SetStyleHandle( pStyle );
+ rSet.Put(aFormat);
+};
+
+void
+SwUnoCursorHelper::SetTextFormatColl(const uno::Any & rAny, SwPaM & rPaM)
+{
+ SwDoc& rDoc = rPaM.GetDoc();
+ SwDocShell *const pDocSh = rDoc.GetDocShell();
+ if(!pDocSh)
+ return;
+ OUString uStyle;
+ rAny >>= uStyle;
+ OUString sStyle;
+ SwStyleNameMapper::FillUIName(uStyle, sStyle,
+ SwGetPoolIdFromName::TxtColl );
+ SwDocStyleSheet *const pStyle = static_cast<SwDocStyleSheet*>(
+ pDocSh->GetStyleSheetPool()->Find(sStyle, SfxStyleFamily::Para));
+ if (!pStyle)
+ {
+ throw lang::IllegalArgumentException();
+ }
+
+ SwTextFormatColl *const pLocal = pStyle->GetCollection();
+ UnoActionContext aAction(&rDoc);
+ rDoc.GetIDocumentUndoRedo().StartUndo( SwUndoId::START, nullptr );
+ SwPaM *pTmpCursor = &rPaM;
+ do {
+ rDoc.SetTextFormatColl(*pTmpCursor, pLocal);
+ pTmpCursor = pTmpCursor->GetNext();
+ } while ( pTmpCursor != &rPaM );
+ rDoc.GetIDocumentUndoRedo().EndUndo( SwUndoId::END, nullptr );
+}
+
+bool
+SwUnoCursorHelper::SetPageDesc(
+ const uno::Any& rValue, SwDoc & rDoc, SfxItemSet & rSet)
+{
+ OUString uDescName;
+ if (!(rValue >>= uDescName))
+ {
+ return false;
+ }
+ std::unique_ptr<SwFormatPageDesc> pNewDesc;
+ if(const SwFormatPageDesc* pItem = rSet.GetItemIfSet( RES_PAGEDESC ))
+ {
+ pNewDesc.reset(new SwFormatPageDesc(*pItem));
+ }
+ if (!pNewDesc)
+ {
+ pNewDesc.reset(new SwFormatPageDesc());
+ }
+ OUString sDescName;
+ SwStyleNameMapper::FillUIName(uDescName, sDescName,
+ SwGetPoolIdFromName::PageDesc);
+ if (!pNewDesc->GetPageDesc() ||
+ (pNewDesc->GetPageDesc()->GetName() != sDescName))
+ {
+ bool bPut = false;
+ if (!sDescName.isEmpty())
+ {
+ SwPageDesc *const pPageDesc = SwPageDesc::GetByName(rDoc, sDescName);
+ if (!pPageDesc)
+ {
+ throw lang::IllegalArgumentException();
+ }
+ pNewDesc->RegisterToPageDesc(*pPageDesc);
+ bPut = true;
+ }
+ if(!bPut)
+ {
+ rSet.ClearItem(RES_BREAK);
+ rSet.Put(SwFormatPageDesc());
+ }
+ else
+ {
+ rSet.Put(std::move(pNewDesc));
+ }
+ }
+ return true;
+}
+
+static void
+lcl_SetNodeNumStart(SwPaM & rCursor, uno::Any const& rValue)
+{
+ sal_Int16 nTmp = 1;
+ rValue >>= nTmp;
+ sal_uInt16 nStt = (nTmp < 0 ? USHRT_MAX : o3tl::narrowing<sal_uInt16>(nTmp));
+ SwDoc& rDoc = rCursor.GetDoc();
+ UnoActionContext aAction(&rDoc);
+
+ if( rCursor.GetNext() != &rCursor ) // MultiSelection?
+ {
+ rDoc.GetIDocumentUndoRedo().StartUndo( SwUndoId::START, nullptr );
+ SwPamRanges aRangeArr( rCursor );
+ SwPaM aPam( *rCursor.GetPoint() );
+ for( size_t n = 0; n < aRangeArr.Count(); ++n )
+ {
+ rDoc.SetNumRuleStart(*aRangeArr.SetPam( n, aPam ).GetPoint());
+ rDoc.SetNodeNumStart(*aRangeArr.SetPam( n, aPam ).GetPoint(),
+ nStt );
+ }
+ rDoc.GetIDocumentUndoRedo().EndUndo( SwUndoId::END, nullptr );
+ }
+ else
+ {
+ rDoc.SetNumRuleStart( *rCursor.GetPoint());
+ rDoc.SetNodeNumStart( *rCursor.GetPoint(), nStt );
+ }
+}
+
+static bool
+lcl_setCharFormatSequence(SwPaM & rPam, uno::Any const& rValue)
+{
+ uno::Sequence<OUString> aCharStyles;
+ if (!(rValue >>= aCharStyles))
+ {
+ return false;
+ }
+
+ for (sal_Int32 nStyle = 0; nStyle < aCharStyles.getLength(); nStyle++)
+ {
+ uno::Any aStyle;
+ rPam.GetDoc().GetIDocumentUndoRedo().StartUndo(SwUndoId::START, nullptr);
+ aStyle <<= aCharStyles.getConstArray()[nStyle];
+ // create a local set and apply each format directly
+ SfxItemSetFixed<RES_TXTATR_CHARFMT, RES_TXTATR_CHARFMT> aSet(rPam.GetDoc().GetAttrPool());
+ lcl_setCharStyle(rPam.GetDoc(), aStyle, aSet);
+ // the first style should replace the current attributes,
+ // all other have to be added
+ SwUnoCursorHelper::SetCursorAttr(rPam, aSet, nStyle
+ ? SetAttrMode::DONTREPLACE
+ : SetAttrMode::DEFAULT);
+ rPam.GetDoc().GetIDocumentUndoRedo().EndUndo(SwUndoId::START, nullptr);
+ }
+ return true;
+}
+
+static void
+lcl_setDropcapCharStyle(SwPaM const & rPam, SfxItemSet & rItemSet,
+ uno::Any const& rValue)
+{
+ OUString uStyle;
+ if (!(rValue >>= uStyle))
+ {
+ throw lang::IllegalArgumentException();
+ }
+ OUString sStyle;
+ SwStyleNameMapper::FillUIName(uStyle, sStyle,
+ SwGetPoolIdFromName::ChrFmt);
+ SwDoc& rDoc = rPam.GetDoc();
+ //default character style must not be set as default format
+ SwDocStyleSheet *const pStyle = static_cast<SwDocStyleSheet*>(
+ rDoc.GetDocShell()
+ ->GetStyleSheetPool()->Find(sStyle, SfxStyleFamily::Char));
+ if (!pStyle || pStyle->GetCharFormat() == rDoc.GetDfltCharFormat())
+ {
+ throw lang::IllegalArgumentException();
+ }
+ std::unique_ptr<SwFormatDrop> pDrop;
+ if (const SwFormatDrop* pItem = rItemSet.GetItemIfSet(RES_PARATR_DROP))
+ {
+ pDrop.reset(new SwFormatDrop(*pItem));
+ }
+ if (!pDrop)
+ {
+ pDrop.reset(new SwFormatDrop);
+ }
+ const rtl::Reference<SwDocStyleSheet> xStyle(new SwDocStyleSheet(*pStyle));
+ pDrop->SetCharFormat(xStyle->GetCharFormat());
+ rItemSet.Put(std::move(pDrop));
+}
+
+static void
+lcl_setRubyCharstyle(SfxItemSet & rItemSet, uno::Any const& rValue)
+{
+ OUString sTmp;
+ if (!(rValue >>= sTmp))
+ {
+ throw lang::IllegalArgumentException();
+ }
+
+ std::unique_ptr<SwFormatRuby> pRuby;
+ if (const SwFormatRuby* pItem = rItemSet.GetItemIfSet(RES_TXTATR_CJK_RUBY))
+ {
+ pRuby.reset(new SwFormatRuby(*pItem));
+ }
+ if (!pRuby)
+ {
+ pRuby.reset(new SwFormatRuby(OUString()));
+ }
+ OUString sStyle;
+ SwStyleNameMapper::FillUIName(sTmp, sStyle,
+ SwGetPoolIdFromName::ChrFmt);
+ pRuby->SetCharFormatName(sStyle);
+ pRuby->SetCharFormatId(0);
+ if (!sStyle.isEmpty())
+ {
+ const sal_uInt16 nId = SwStyleNameMapper::GetPoolIdFromUIName(
+ sStyle, SwGetPoolIdFromName::ChrFmt);
+ pRuby->SetCharFormatId(nId);
+ }
+ rItemSet.Put(std::move(pRuby));
+}
+
+bool
+SwUnoCursorHelper::SetCursorPropertyValue(
+ SfxItemPropertyMapEntry const& rEntry, const uno::Any& rValue,
+ SwPaM & rPam, SfxItemSet & rItemSet)
+{
+ if (!(rEntry.nFlags & beans::PropertyAttribute::MAYBEVOID) &&
+ (rValue.getValueType() == cppu::UnoType<void>::get()))
+ {
+ return false;
+ }
+ bool bRet = true;
+ switch (rEntry.nWID)
+ {
+ case RES_TXTATR_CHARFMT:
+ lcl_setCharStyle(rPam.GetDoc(), rValue, rItemSet);
+ break;
+ case RES_TXTATR_AUTOFMT:
+ lcl_setAutoStyle(rPam.GetDoc().GetIStyleAccess(),
+ rValue, rItemSet, false);
+ break;
+ case FN_UNO_CHARFMT_SEQUENCE:
+ lcl_setCharFormatSequence(rPam, rValue);
+ break;
+ case FN_UNO_PARA_STYLE :
+ SwUnoCursorHelper::SetTextFormatColl(rValue, rPam);
+ break;
+ case RES_AUTO_STYLE:
+ lcl_setAutoStyle(rPam.GetDoc().GetIStyleAccess(),
+ rValue, rItemSet, true);
+ break;
+ case FN_UNO_PAGE_STYLE:
+ //FIXME nothing here?
+ break;
+ case FN_UNO_NUM_START_VALUE:
+ lcl_SetNodeNumStart( rPam, rValue );
+ break;
+ case FN_UNO_NUM_LEVEL:
+ // #i91601#
+ case FN_UNO_LIST_ID:
+ case FN_UNO_IS_NUMBER:
+ case FN_UNO_PARA_NUM_AUTO_FORMAT:
+ {
+ // multi selection is not considered
+ SwTextNode *const pTextNd = rPam.GetPointNode().GetTextNode();
+ if (!pTextNd)
+ {
+ throw lang::IllegalArgumentException();
+ }
+ if (FN_UNO_NUM_LEVEL == rEntry.nWID)
+ {
+ sal_Int16 nLevel = 0;
+ if (rValue >>= nLevel)
+ {
+ if (nLevel < 0 || MAXLEVEL <= nLevel)
+ {
+ throw lang::IllegalArgumentException(
+ "invalid NumberingLevel", nullptr, 0);
+ }
+ pTextNd->SetAttrListLevel(nLevel);
+ }
+ }
+ // #i91601#
+ else if (FN_UNO_LIST_ID == rEntry.nWID)
+ {
+ OUString sListId;
+ if (rValue >>= sListId)
+ {
+ pTextNd->SetListId( sListId );
+ }
+ }
+ else if (FN_UNO_IS_NUMBER == rEntry.nWID)
+ {
+ bool bIsNumber(false);
+ if ((rValue >>= bIsNumber) && !bIsNumber)
+ {
+ pTextNd->SetCountedInList( false );
+ }
+ }
+ else if (FN_UNO_PARA_NUM_AUTO_FORMAT == rEntry.nWID)
+ {
+ std::shared_ptr<SfxItemSet> pAutoStyle;
+ if (uno::Sequence<beans::NamedValue> props; rValue >>= props)
+ {
+ // TODO create own map for this, it contains UNO_NAME_DISPLAY_NAME? or make property readable so ODF export can map it to a automatic style?
+ SfxItemPropertySet const& rPropSet(*aSwMapProvider.GetPropertySet(PROPERTY_MAP_CHAR_AUTO_STYLE));
+ SfxItemPropertyMap const& rMap(rPropSet.getPropertyMap());
+ SfxItemSetFixed
+ <RES_CHRATR_BEGIN, RES_CHRATR_END-1,
+ RES_TXTATR_CHARFMT, RES_TXTATR_CHARFMT,
+ RES_UNKNOWNATR_BEGIN, RES_UNKNOWNATR_END-1>
+ items( rPam.GetDoc().GetAttrPool() );
+
+ for (beans::NamedValue const & prop : std::as_const(props))
+ {
+ SfxItemPropertyMapEntry const*const pEntry =
+ rMap.getByName(prop.Name);
+ if (!pEntry)
+ {
+ if (prop.Name == "CharStyleName")
+ {
+ lcl_setCharStyle(rPam.GetDoc(), prop.Value, items);
+ continue;
+ }
+ throw beans::UnknownPropertyException(
+ "Unknown property: " + prop.Name);
+ }
+ if (pEntry->nFlags & beans::PropertyAttribute::READONLY)
+ {
+ throw beans::PropertyVetoException(
+ "Property is read-only: " + prop.Name);
+ }
+ rPropSet.setPropertyValue(*pEntry, prop.Value, items);
+ }
+
+ IStyleAccess& rStyleAccess = rPam.GetDoc().GetIStyleAccess();
+ // Add it to the autostyle pool, needed by the ODT export.
+ pAutoStyle = rStyleAccess.getAutomaticStyle(items, IStyleAccess::AUTO_STYLE_CHAR);
+ }
+ else if (OUString styleName; rValue >>= styleName)
+ {
+ IStyleAccess& rStyleAccess = rPam.GetDoc().GetIStyleAccess();
+ pAutoStyle = rStyleAccess.getByName(styleName, IStyleAccess::AUTO_STYLE_CHAR);
+ }
+ if (pAutoStyle)
+ {
+ SwFormatAutoFormat item(RES_PARATR_LIST_AUTOFMT);
+ // note: paragraph auto styles have ParaStyleName property for the parent style; character auto styles currently do not because there's a separate hint, but for this it would be a good way to add it in order to export it as style:parent-style-name, see XMLTextParagraphExport::Add()
+ item.SetStyleHandle(pAutoStyle);
+ pTextNd->SetAttr(item);
+ }
+ }
+ //PROPERTY_MAYBEVOID!
+ }
+ break;
+ case FN_NUMBER_NEWSTART:
+ {
+ bool bVal = false;
+ if (!(rValue >>= bVal))
+ {
+ throw lang::IllegalArgumentException();
+ }
+ rPam.GetDoc().SetNumRuleStart(*rPam.GetPoint(), bVal);
+ }
+ break;
+ case FN_UNO_NUM_RULES:
+ SwUnoCursorHelper::setNumberingProperty(rValue, rPam);
+ break;
+ case RES_PARATR_DROP:
+ {
+ if (MID_DROPCAP_CHAR_STYLE_NAME == rEntry.nMemberId)
+ {
+ lcl_setDropcapCharStyle(rPam, rItemSet, rValue);
+ }
+ else
+ {
+ bRet = false;
+ }
+ }
+ break;
+ case RES_TXTATR_CJK_RUBY:
+ {
+ if (MID_RUBY_CHARSTYLE == rEntry.nMemberId)
+ {
+ lcl_setRubyCharstyle(rItemSet, rValue);
+ }
+ else
+ {
+ bRet = false;
+ }
+ }
+ break;
+ case RES_PAGEDESC:
+ {
+ if (MID_PAGEDESC_PAGEDESCNAME == rEntry.nMemberId)
+ {
+ SwUnoCursorHelper::SetPageDesc(
+ rValue, rPam.GetDoc(), rItemSet);
+ }
+ else
+ {
+ bRet = false;
+ }
+ }
+ break;
+ default:
+ bRet = false;
+ }
+ return bRet;
+}
+
+SwFormatColl *
+SwUnoCursorHelper::GetCurTextFormatColl(SwPaM & rPaM, const bool bConditional)
+{
+ static const sal_uLong nMaxLookup = 1000;
+ SwFormatColl *pFormat = nullptr;
+ bool bError = false;
+ SwPaM *pTmpCursor = &rPaM;
+ do
+ {
+ const SwNodeOffset nSttNd = pTmpCursor->Start()->GetNodeIndex();
+ const SwNodeOffset nEndNd = pTmpCursor->End()->GetNodeIndex();
+
+ if( nEndNd - nSttNd >= SwNodeOffset(nMaxLookup) )
+ {
+ pFormat = nullptr;
+ break;
+ }
+
+ const SwNodes& rNds = rPaM.GetDoc().GetNodes();
+ for( SwNodeOffset n = nSttNd; n <= nEndNd; ++n )
+ {
+ SwTextNode const*const pNd = rNds[ n ]->GetTextNode();
+ if( pNd )
+ {
+ SwFormatColl *const pNdFormat = bConditional
+ ? pNd->GetFormatColl() : &pNd->GetAnyFormatColl();
+ if( !pFormat )
+ {
+ pFormat = pNdFormat;
+ }
+ else if( pFormat != pNdFormat )
+ {
+ bError = true;
+ break;
+ }
+ }
+ }
+
+ pTmpCursor = pTmpCursor->GetNext();
+ } while ( pTmpCursor != &rPaM );
+ return bError ? nullptr : pFormat;
+}
+
+SwUnoCursor& SwXTextCursor::GetCursor()
+ { return *m_pUnoCursor; }
+
+SwPaM const* SwXTextCursor::GetPaM() const
+ { return m_pUnoCursor.get(); }
+
+SwPaM* SwXTextCursor::GetPaM()
+ { return m_pUnoCursor.get(); }
+
+SwDoc const* SwXTextCursor::GetDoc() const
+ { return m_pUnoCursor ? &m_pUnoCursor->GetDoc() : nullptr; }
+
+SwDoc* SwXTextCursor::GetDoc()
+ { return m_pUnoCursor ? &m_pUnoCursor->GetDoc() : nullptr; }
+
+SwXTextCursor::SwXTextCursor(
+ SwDoc & rDoc,
+ uno::Reference< text::XText > xParent,
+ const CursorType eType,
+ const SwPosition& rPos,
+ SwPosition const*const pMark)
+ : m_rPropSet(*aSwMapProvider.GetPropertySet(PROPERTY_MAP_TEXT_CURSOR))
+ , m_eType(eType)
+ , m_xParentText(std::move(xParent))
+ , m_pUnoCursor(rDoc.CreateUnoCursor(rPos))
+{
+ if (pMark)
+ {
+ m_pUnoCursor->SetMark();
+ *m_pUnoCursor->GetMark() = *pMark;
+ }
+}
+
+SwXTextCursor::SwXTextCursor(uno::Reference< text::XText > xParent,
+ SwPaM const& rSourceCursor, const CursorType eType)
+ : m_rPropSet(*aSwMapProvider.GetPropertySet(PROPERTY_MAP_TEXT_CURSOR))
+ , m_eType(eType)
+ , m_xParentText(std::move(xParent))
+ , m_pUnoCursor(rSourceCursor.GetDoc().CreateUnoCursor(*rSourceCursor.GetPoint()))
+{
+ if (rSourceCursor.HasMark())
+ {
+ m_pUnoCursor->SetMark();
+ *m_pUnoCursor->GetMark() = *rSourceCursor.GetMark();
+ }
+}
+
+SwXTextCursor::~SwXTextCursor()
+{
+ SolarMutexGuard g; // #i105557#: call dtor with locked solar mutex
+ m_pUnoCursor.reset(nullptr); // need to delete this with SolarMutex held
+}
+
+void SwXTextCursor::DeleteAndInsert(std::u16string_view aText,
+ ::sw::DeleteAndInsertMode const eMode)
+{
+ auto pUnoCursor = static_cast<SwCursor*>(m_pUnoCursor.get());
+ if (!pUnoCursor)
+ return;
+
+ // Start/EndAction
+ SwDoc& rDoc = pUnoCursor->GetDoc();
+ UnoActionContext aAction(&rDoc);
+ const sal_Int32 nTextLen = aText.size();
+ rDoc.GetIDocumentUndoRedo().StartUndo(SwUndoId::INSERT, nullptr);
+ auto pCurrent = pUnoCursor;
+ do
+ {
+ if (pCurrent->HasMark())
+ {
+ rDoc.getIDocumentContentOperations().DeleteAndJoin(*pCurrent,
+ // is it "delete" or "replace"?
+ (nTextLen != 0 || eMode & ::sw::DeleteAndInsertMode::ForceReplace) ? SwDeleteFlags::ArtificialSelection : SwDeleteFlags::Default);
+ }
+ if(nTextLen)
+ {
+ const bool bSuccess(
+ SwUnoCursorHelper::DocInsertStringSplitCR(
+ rDoc, *pCurrent, aText, bool(eMode & ::sw::DeleteAndInsertMode::ForceExpandHints)));
+ OSL_ENSURE( bSuccess, "Doc->Insert(Str) failed." );
+
+ SwUnoCursorHelper::SelectPam(*pUnoCursor, true);
+ pCurrent->Left(aText.size());
+ }
+ pCurrent = pCurrent->GetNext();
+ } while (pCurrent != pUnoCursor);
+ rDoc.GetIDocumentUndoRedo().EndUndo(SwUndoId::INSERT, nullptr);
+}
+
+namespace {
+
+enum ForceIntoMetaMode { META_CHECK_BOTH, META_INIT_START, META_INIT_END };
+
+enum ForceIntoContentControlMode
+{
+ CONTENT_CONTROL_CHECK_BOTH,
+ CONTENT_CONTROL_INIT_START,
+ CONTENT_CONTROL_INIT_END
+};
+}
+
+static bool
+lcl_ForceIntoMeta(SwPaM & rCursor,
+ uno::Reference<text::XText> const & xParentText,
+ const enum ForceIntoMetaMode eMode)
+{
+ bool bRet( true ); // means not forced in META_CHECK_BOTH
+ SwXMeta const * const pXMeta( dynamic_cast<SwXMeta*>(xParentText.get()) );
+ OSL_ENSURE(pXMeta, "no parent?");
+ if (!pXMeta)
+ throw uno::RuntimeException();
+ SwTextNode * pTextNode;
+ sal_Int32 nStart;
+ sal_Int32 nEnd;
+ const bool bSuccess( pXMeta->SetContentRange(pTextNode, nStart, nEnd) );
+ OSL_ENSURE(bSuccess, "no pam?");
+ if (!bSuccess)
+ throw uno::RuntimeException();
+ // force the cursor back into the meta if it has moved outside
+ SwPosition start(*pTextNode, nStart);
+ SwPosition end(*pTextNode, nEnd);
+ switch (eMode)
+ {
+ case META_INIT_START:
+ *rCursor.GetPoint() = start;
+ break;
+ case META_INIT_END:
+ *rCursor.GetPoint() = end;
+ break;
+ case META_CHECK_BOTH:
+ if (*rCursor.Start() < start)
+ {
+ *rCursor.Start() = start;
+ bRet = false;
+ }
+ if (*rCursor.End() > end)
+ {
+ *rCursor.End() = end;
+ bRet = false;
+ }
+ break;
+ }
+ return bRet;
+}
+
+namespace
+{
+bool lcl_ForceIntoContentControl(SwPaM& rCursor, const uno::Reference<text::XText>& xParentText,
+ ForceIntoContentControlMode eMode)
+{
+ bool bRet = true; // means not forced in CONTENT_CONTROL_CHECK_BOTH
+ auto pXContentControl = dynamic_cast<SwXContentControl*>(xParentText.get());
+ if (!pXContentControl)
+ {
+ SAL_WARN("sw.core", "lcl_ForceIntoContentControl: no parent text");
+ throw uno::RuntimeException();
+ }
+
+ SwTextNode* pTextNode;
+ sal_Int32 nStart;
+ sal_Int32 nEnd;
+ bool bSuccess = pXContentControl->SetContentRange(pTextNode, nStart, nEnd);
+ if (!bSuccess)
+ {
+ SAL_WARN("sw.core", "lcl_ForceIntoContentControl: SetContentRange() failed");
+ throw uno::RuntimeException();
+ }
+
+ // Force the cursor back into the content control if it has moved outside.
+ SwPosition aStart(*pTextNode, nStart);
+ SwPosition aEnd(*pTextNode, nEnd);
+ switch (eMode)
+ {
+ case CONTENT_CONTROL_INIT_START:
+ *rCursor.GetPoint() = aStart;
+ break;
+
+ case CONTENT_CONTROL_INIT_END:
+ *rCursor.GetPoint() = aEnd;
+ break;
+
+ case CONTENT_CONTROL_CHECK_BOTH:
+ if (*rCursor.Start() < aStart)
+ {
+ *rCursor.Start() = aStart;
+ bRet = false;
+ }
+
+ if (*rCursor.End() > aEnd)
+ {
+ *rCursor.End() = aEnd;
+ bRet = false;
+ }
+ break;
+ }
+
+ return bRet;
+}
+}
+
+bool SwXTextCursor::IsAtEndOfMeta() const
+{
+ if (CursorType::Meta == m_eType)
+ {
+ auto pCursor( m_pUnoCursor );
+ SwXMeta const*const pXMeta(
+ dynamic_cast<SwXMeta*>(m_xParentText.get()) );
+ OSL_ENSURE(pXMeta, "no meta?");
+ if (pCursor && pXMeta)
+ {
+ SwTextNode * pTextNode;
+ sal_Int32 nStart;
+ sal_Int32 nEnd;
+ const bool bSuccess(
+ pXMeta->SetContentRange(pTextNode, nStart, nEnd) );
+ OSL_ENSURE(bSuccess, "no pam?");
+ if (bSuccess)
+ {
+ const SwPosition end(*pTextNode, nEnd);
+ if ( (*pCursor->GetPoint() == end)
+ || (*pCursor->GetMark() == end))
+ {
+ return true;
+ }
+ }
+ }
+ }
+ return false;
+}
+
+bool SwXTextCursor::IsAtEndOfContentControl() const
+{
+ if (CursorType::ContentControl == m_eType)
+ {
+ auto pCursor( m_pUnoCursor );
+ auto pXContentControl(
+ dynamic_cast<SwXContentControl*>(m_xParentText.get()) );
+ if (!pXContentControl)
+ {
+ SAL_WARN("sw.core", "SwXTextCursor::IsAtEndOfContentControl: no content control");
+ }
+ if (pCursor && pXContentControl)
+ {
+ SwTextNode * pTextNode;
+ sal_Int32 nStart;
+ sal_Int32 nEnd;
+ const bool bSuccess(
+ pXContentControl->SetContentRange(pTextNode, nStart, nEnd) );
+ if (!bSuccess)
+ {
+ SAL_WARN("sw.core", "SwXTextCursor::IsAtEndOfContentControl: no pam");
+ }
+ else
+ {
+ const SwPosition end(*pTextNode, nEnd);
+ if ( (*pCursor->GetPoint() == end)
+ || (*pCursor->GetMark() == end))
+ {
+ return true;
+ }
+ }
+ }
+ }
+ return false;
+}
+
+OUString SwXTextCursor::getImplementationName()
+{
+ return "SwXTextCursor";
+}
+
+sal_Bool SAL_CALL SwXTextCursor::supportsService(const OUString& rServiceName)
+{
+ return cppu::supportsService(this, rServiceName);
+}
+
+uno::Sequence< OUString > SAL_CALL
+SwXTextCursor::getSupportedServiceNames()
+{
+ return {
+ "com.sun.star.text.TextCursor",
+ "com.sun.star.style.CharacterProperties",
+ "com.sun.star.style.CharacterPropertiesAsian",
+ "com.sun.star.style.CharacterPropertiesComplex",
+ "com.sun.star.style.ParagraphProperties",
+ "com.sun.star.style.ParagraphPropertiesAsian",
+ "com.sun.star.style.ParagraphPropertiesComplex",
+ "com.sun.star.text.TextSortable"
+ };
+}
+
+void SAL_CALL SwXTextCursor::collapseToStart()
+{
+ SolarMutexGuard aGuard;
+
+ SwUnoCursor & rUnoCursor( GetCursorOrThrow() );
+
+ if (rUnoCursor.HasMark())
+ {
+ if (*rUnoCursor.GetPoint() > *rUnoCursor.GetMark())
+ {
+ rUnoCursor.Exchange();
+ }
+ rUnoCursor.DeleteMark();
+ }
+}
+
+void SAL_CALL SwXTextCursor::collapseToEnd()
+{
+ SolarMutexGuard aGuard;
+
+ SwUnoCursor & rUnoCursor( GetCursorOrThrow() );
+
+ if (rUnoCursor.HasMark())
+ {
+ if (*rUnoCursor.GetPoint() < *rUnoCursor.GetMark())
+ {
+ rUnoCursor.Exchange();
+ }
+ rUnoCursor.DeleteMark();
+ }
+}
+
+sal_Bool SAL_CALL SwXTextCursor::isCollapsed()
+{
+ SolarMutexGuard aGuard;
+
+ bool bRet = true;
+ auto pUnoCursor(m_pUnoCursor);
+ if(pUnoCursor && pUnoCursor->GetMark())
+ {
+ bRet = (*pUnoCursor->GetPoint() == *pUnoCursor->GetMark());
+ }
+ return bRet;
+}
+
+sal_Bool SAL_CALL
+SwXTextCursor::goLeft(sal_Int16 nCount, sal_Bool Expand)
+{
+ SolarMutexGuard aGuard;
+
+ SwUnoCursor & rUnoCursor( GetCursorOrThrow() );
+
+ SwUnoCursorHelper::SelectPam(rUnoCursor, Expand);
+ bool bRet = rUnoCursor.Left( nCount);
+ if (CursorType::Meta == m_eType)
+ {
+ bRet = lcl_ForceIntoMeta(rUnoCursor, m_xParentText,
+ META_CHECK_BOTH)
+ && bRet;
+ }
+ else if (m_eType == CursorType::ContentControl)
+ {
+ bRet = lcl_ForceIntoContentControl(rUnoCursor, m_xParentText, CONTENT_CONTROL_CHECK_BOTH)
+ && bRet;
+ }
+ return bRet;
+}
+
+sal_Bool SAL_CALL
+SwXTextCursor::goRight(sal_Int16 nCount, sal_Bool Expand)
+{
+ SolarMutexGuard aGuard;
+
+ SwUnoCursor & rUnoCursor( GetCursorOrThrow() );
+
+ SwUnoCursorHelper::SelectPam(rUnoCursor, Expand);
+ bool bRet = rUnoCursor.Right(nCount);
+ if (CursorType::Meta == m_eType)
+ {
+ bRet = lcl_ForceIntoMeta(rUnoCursor, m_xParentText,
+ META_CHECK_BOTH)
+ && bRet;
+ }
+ else if (m_eType == CursorType::ContentControl)
+ {
+ bRet = lcl_ForceIntoContentControl(rUnoCursor, m_xParentText, CONTENT_CONTROL_CHECK_BOTH)
+ && bRet;
+ }
+ return bRet;
+}
+
+void SAL_CALL
+SwXTextCursor::gotoStart(sal_Bool Expand)
+{
+ SolarMutexGuard aGuard;
+ comphelper::ProfileZone aZone("gotoStart");
+
+ SwUnoCursor & rUnoCursor( GetCursorOrThrow() );
+
+ SwUnoCursorHelper::SelectPam(rUnoCursor, Expand);
+ if (CursorType::Body == m_eType)
+ {
+ rUnoCursor.Move( fnMoveBackward, GoInDoc );
+ //check, that the cursor is not in a table
+ SwTableNode * pTableNode = rUnoCursor.GetPointNode().FindTableNode();
+ while (pTableNode)
+ {
+ rUnoCursor.GetPoint()->Assign( *pTableNode->EndOfSectionNode() );
+ SwContentNode* pCNode = GetDoc()->GetNodes().GoNext(rUnoCursor.GetPoint());
+ pTableNode = pCNode ? pCNode->FindTableNode() : nullptr;
+ }
+ SwStartNode const*const pTmp =
+ rUnoCursor.GetPointNode().StartOfSectionNode();
+ if (pTmp->IsSectionNode())
+ {
+ SwSectionNode const*const pSectionStartNode =
+ static_cast<SwSectionNode const*>(pTmp);
+ if (pSectionStartNode->GetSection().IsHiddenFlag())
+ {
+ GetDoc()->GetNodes().GoNextSection(
+ rUnoCursor.GetPoint(), true, false);
+ }
+ }
+ }
+ else if ( (CursorType::Frame == m_eType)
+ || (CursorType::TableText == m_eType)
+ || (CursorType::Header == m_eType)
+ || (CursorType::Footer == m_eType)
+ || (CursorType::Footnote== m_eType)
+ || (CursorType::Redline == m_eType))
+ {
+ rUnoCursor.MoveSection(GoCurrSection, fnSectionStart);
+ }
+ else if (CursorType::Meta == m_eType)
+ {
+ lcl_ForceIntoMeta(rUnoCursor, m_xParentText, META_INIT_START);
+ }
+ else if (m_eType == CursorType::ContentControl)
+ {
+ lcl_ForceIntoContentControl(rUnoCursor, m_xParentText, CONTENT_CONTROL_INIT_START);
+ }
+}
+
+void SAL_CALL
+SwXTextCursor::gotoEnd(sal_Bool Expand)
+{
+ SolarMutexGuard aGuard;
+ comphelper::ProfileZone aZone("gotoEnd");
+
+ SwUnoCursor & rUnoCursor( GetCursorOrThrow() );
+
+ SwUnoCursorHelper::SelectPam(rUnoCursor, Expand);
+ if (CursorType::Body == m_eType)
+ {
+ rUnoCursor.Move( fnMoveForward, GoInDoc );
+ }
+ else if ( (CursorType::Frame == m_eType)
+ || (CursorType::TableText == m_eType)
+ || (CursorType::Header == m_eType)
+ || (CursorType::Footer == m_eType)
+ || (CursorType::Footnote== m_eType)
+ || (CursorType::Redline == m_eType))
+ {
+ rUnoCursor.MoveSection( GoCurrSection, fnSectionEnd);
+ }
+ else if (CursorType::Meta == m_eType)
+ {
+ lcl_ForceIntoMeta(rUnoCursor, m_xParentText, META_INIT_END);
+ }
+ else if (m_eType == CursorType::ContentControl)
+ {
+ lcl_ForceIntoContentControl(rUnoCursor, m_xParentText, CONTENT_CONTROL_INIT_END);
+ }
+}
+
+void SAL_CALL
+SwXTextCursor::gotoRange(
+ const uno::Reference< text::XTextRange > & xRange, sal_Bool bExpand)
+{
+ SolarMutexGuard aGuard;
+
+ if (!xRange.is())
+ {
+ throw uno::RuntimeException();
+ }
+
+ SwUnoCursor & rOwnCursor( GetCursorOrThrow() );
+
+ SwXTextRange* pRange = dynamic_cast<SwXTextRange*>(xRange.get());
+ OTextCursorHelper* pCursor = dynamic_cast<OTextCursorHelper*>(xRange.get());
+
+ if (!pRange && !pCursor)
+ {
+ throw uno::RuntimeException();
+ }
+
+ SwPaM aPam(GetDoc()->GetNodes());
+ const SwPaM * pPam(nullptr);
+ if (pCursor)
+ {
+ pPam = pCursor->GetPaM();
+ }
+ else if (pRange)
+ {
+ if (pRange->GetPositions(aPam))
+ {
+ pPam = & aPam;
+ }
+ }
+
+ if (!pPam)
+ {
+ throw uno::RuntimeException();
+ }
+
+ {
+ SwStartNodeType eSearchNodeType = SwNormalStartNode;
+ switch (m_eType)
+ {
+ case CursorType::Frame: eSearchNodeType = SwFlyStartNode; break;
+ case CursorType::TableText: eSearchNodeType = SwTableBoxStartNode; break;
+ case CursorType::Footnote: eSearchNodeType = SwFootnoteStartNode; break;
+ case CursorType::Header: eSearchNodeType = SwHeaderStartNode; break;
+ case CursorType::Footer: eSearchNodeType = SwFooterStartNode; break;
+ //case CURSOR_INVALID:
+ //case CursorType::Body:
+ default:
+ ;
+ }
+
+ const SwStartNode* pOwnStartNode = rOwnCursor.GetPointNode().FindSttNodeByType(eSearchNodeType);
+ while ( pOwnStartNode != nullptr
+ && pOwnStartNode->IsSectionNode())
+ {
+ pOwnStartNode = pOwnStartNode->StartOfSectionNode();
+ }
+
+ const SwStartNode* pTmp =
+ pPam->GetPointNode().FindSttNodeByType(eSearchNodeType);
+ while ( pTmp != nullptr
+ && pTmp->IsSectionNode() )
+ {
+ pTmp = pTmp->StartOfSectionNode();
+ }
+
+ if ( eSearchNodeType == SwTableBoxStartNode )
+ {
+ if (!pOwnStartNode || !pTmp)
+ {
+ throw uno::RuntimeException();
+ }
+
+ if ( pOwnStartNode->FindTableNode() != pTmp->FindTableNode() )
+ {
+ throw uno::RuntimeException();
+ }
+ }
+ else
+ {
+ if ( pOwnStartNode != pTmp )
+ {
+ throw uno::RuntimeException();
+ }
+ }
+ }
+
+ if (CursorType::Meta == m_eType)
+ {
+ SwPaM CopyPam(*pPam->GetMark(), *pPam->GetPoint());
+ const bool bNotForced( lcl_ForceIntoMeta(
+ CopyPam, m_xParentText, META_CHECK_BOTH) );
+ if (!bNotForced)
+ {
+ throw uno::RuntimeException(
+ "gotoRange: parameter range not contained in nesting"
+ " text content for which this cursor was created",
+ static_cast<text::XWordCursor*>(this));
+ }
+ }
+ else if (m_eType == CursorType::ContentControl)
+ {
+ SwPaM aPaM(*pPam->GetMark(), *pPam->GetPoint());
+ if (!lcl_ForceIntoContentControl(aPaM, m_xParentText, CONTENT_CONTROL_CHECK_BOTH))
+ {
+ throw uno::RuntimeException("gotoRange: xRange is out of bounds of the content control",
+ static_cast<text::XWordCursor*>(this));
+ }
+ }
+
+ // selection has to be expanded here
+ if(bExpand)
+ {
+ // cursor should include its previous range plus the given range
+ const SwPosition aOwnLeft(*rOwnCursor.Start());
+ const SwPosition aOwnRight(*rOwnCursor.End());
+ SwPosition const& rParamLeft = *pPam->Start();
+ SwPosition const& rParamRight = *pPam->End();
+
+ // now there are four SwPositions,
+ // two of them are going to be used, but which ones?
+ if (aOwnRight > rParamRight)
+ *rOwnCursor.GetPoint() = aOwnRight;
+ else
+ *rOwnCursor.GetPoint() = rParamRight;
+ rOwnCursor.SetMark();
+ if (aOwnLeft < rParamLeft)
+ *rOwnCursor.GetMark() = aOwnLeft;
+ else
+ *rOwnCursor.GetMark() = rParamLeft;
+ }
+ else
+ {
+ // cursor should be the given range
+ *rOwnCursor.GetPoint() = *pPam->GetPoint();
+ if (pPam->HasMark())
+ {
+ rOwnCursor.SetMark();
+ *rOwnCursor.GetMark() = *pPam->GetMark();
+ }
+ else
+ {
+ rOwnCursor.DeleteMark();
+ }
+ }
+}
+
+sal_Bool SAL_CALL SwXTextCursor::isStartOfWord()
+{
+ SolarMutexGuard aGuard;
+
+ SwUnoCursor & rUnoCursor( GetCursorOrThrow() );
+
+ const bool bRet =
+ rUnoCursor.IsStartWordWT( i18n::WordType::DICTIONARY_WORD );
+ return bRet;
+}
+
+sal_Bool SAL_CALL SwXTextCursor::isEndOfWord()
+{
+ SolarMutexGuard aGuard;
+
+ SwUnoCursor & rUnoCursor( GetCursorOrThrow() );
+
+ const bool bRet =
+ rUnoCursor.IsEndWordWT( i18n::WordType::DICTIONARY_WORD );
+ return bRet;
+}
+
+sal_Bool SAL_CALL
+SwXTextCursor::gotoNextWord(sal_Bool Expand)
+{
+ SolarMutexGuard aGuard;
+
+ SwUnoCursor & rUnoCursor( GetCursorOrThrow() );
+
+ // problems arise when a paragraph starts with something other than a word
+ bool bRet = false;
+ // remember old position to check if cursor has moved
+ // since the called functions are sometimes a bit unreliable
+ // in specific cases...
+ SwPosition *const pPoint = rUnoCursor.GetPoint();
+ SwNode *const pOldNode = &pPoint->GetNode();
+ sal_Int32 const nOldIndex = pPoint->GetContentIndex();
+
+ SwUnoCursorHelper::SelectPam(rUnoCursor, Expand);
+ // end of paragraph
+ if (rUnoCursor.GetPointContentNode() &&
+ (pPoint->GetContentIndex() == rUnoCursor.GetPointContentNode()->Len()))
+ {
+ rUnoCursor.Right(1);
+ }
+ else
+ {
+ const bool bTmp =
+ rUnoCursor.GoNextWordWT( i18n::WordType::DICTIONARY_WORD );
+ // if there is no next word within the current paragraph
+ // try to go to the start of the next paragraph
+ if (!bTmp)
+ {
+ rUnoCursor.MovePara(GoNextPara, fnParaStart);
+ }
+ }
+
+ // return true if cursor has moved
+ bRet = (&pPoint->GetNode() != pOldNode) ||
+ (pPoint->GetContentIndex() != nOldIndex);
+ if (bRet && (CursorType::Meta == m_eType))
+ {
+ bRet = lcl_ForceIntoMeta(rUnoCursor, m_xParentText,
+ META_CHECK_BOTH);
+ }
+ else if (bRet && m_eType == CursorType::ContentControl)
+ {
+ bRet = lcl_ForceIntoContentControl(rUnoCursor, m_xParentText, CONTENT_CONTROL_CHECK_BOTH);
+ }
+
+ return bRet;
+}
+
+sal_Bool SAL_CALL
+SwXTextCursor::gotoPreviousWord(sal_Bool Expand)
+{
+ SolarMutexGuard aGuard;
+
+ SwUnoCursor & rUnoCursor( GetCursorOrThrow() );
+
+ // white spaces create problems on the paragraph start
+ bool bRet = false;
+ SwPosition *const pPoint = rUnoCursor.GetPoint();
+ SwNode *const pOldNode = &pPoint->GetNode();
+ sal_Int32 const nOldIndex = pPoint->GetContentIndex();
+
+ SwUnoCursorHelper::SelectPam(rUnoCursor, Expand);
+ // start of paragraph?
+ if (pPoint->GetContentIndex() == 0)
+ {
+ rUnoCursor.Left(1);
+ }
+ else
+ {
+ rUnoCursor.GoPrevWordWT( i18n::WordType::DICTIONARY_WORD );
+ if (pPoint->GetContentIndex() == 0)
+ {
+ rUnoCursor.Left(1);
+ }
+ }
+
+ // return true if cursor has moved
+ bRet = (&pPoint->GetNode() != pOldNode) ||
+ (pPoint->GetContentIndex() != nOldIndex);
+ if (bRet && (CursorType::Meta == m_eType))
+ {
+ bRet = lcl_ForceIntoMeta(rUnoCursor, m_xParentText,
+ META_CHECK_BOTH);
+ }
+ else if (bRet && m_eType == CursorType::ContentControl)
+ {
+ bRet = lcl_ForceIntoContentControl(rUnoCursor, m_xParentText, CONTENT_CONTROL_CHECK_BOTH);
+ }
+
+ return bRet;
+}
+
+sal_Bool SAL_CALL
+SwXTextCursor::gotoEndOfWord(sal_Bool Expand)
+{
+ SolarMutexGuard aGuard;
+
+ SwUnoCursor & rUnoCursor( GetCursorOrThrow() );
+
+ bool bRet = false;
+ SwPosition *const pPoint = rUnoCursor.GetPoint();
+ SwNode & rOldNode = pPoint->GetNode();
+ sal_Int32 const nOldIndex = pPoint->GetContentIndex();
+
+ const sal_Int16 nWordType = i18n::WordType::DICTIONARY_WORD;
+ SwUnoCursorHelper::SelectPam(rUnoCursor, Expand);
+ if (!rUnoCursor.IsEndWordWT( nWordType ))
+ {
+ rUnoCursor.GoEndWordWT( nWordType );
+ }
+
+ // restore old cursor if we are not at the end of a word by now
+ // otherwise use current one
+ bRet = rUnoCursor.IsEndWordWT( nWordType );
+ if (!bRet)
+ {
+ pPoint->Assign(rOldNode, nOldIndex);
+ }
+ else if (CursorType::Meta == m_eType)
+ {
+ bRet = lcl_ForceIntoMeta(rUnoCursor, m_xParentText,
+ META_CHECK_BOTH);
+ }
+ else if (m_eType == CursorType::ContentControl)
+ {
+ bRet = lcl_ForceIntoContentControl(rUnoCursor, m_xParentText, CONTENT_CONTROL_CHECK_BOTH);
+ }
+
+ return bRet;
+}
+
+sal_Bool SAL_CALL
+SwXTextCursor::gotoStartOfWord(sal_Bool Expand)
+{
+ SolarMutexGuard aGuard;
+
+ SwUnoCursor & rUnoCursor( GetCursorOrThrow() );
+
+ bool bRet = false;
+ SwPosition *const pPoint = rUnoCursor.GetPoint();
+ SwNode & rOldNode = pPoint->GetNode();
+ sal_Int32 const nOldIndex = pPoint->GetContentIndex();
+
+ const sal_Int16 nWordType = i18n::WordType::DICTIONARY_WORD;
+ SwUnoCursorHelper::SelectPam(rUnoCursor, Expand);
+ if (!rUnoCursor.IsStartWordWT( nWordType ))
+ {
+ rUnoCursor.GoStartWordWT( nWordType );
+ }
+
+ // restore old cursor if we are not at the start of a word by now
+ // otherwise use current one
+ bRet = rUnoCursor.IsStartWordWT( nWordType );
+ if (!bRet)
+ {
+ pPoint->Assign(rOldNode, nOldIndex);
+ }
+ else if (CursorType::Meta == m_eType)
+ {
+ bRet = lcl_ForceIntoMeta(rUnoCursor, m_xParentText,
+ META_CHECK_BOTH);
+ }
+ else if (m_eType == CursorType::ContentControl)
+ {
+ bRet = lcl_ForceIntoContentControl(rUnoCursor, m_xParentText, CONTENT_CONTROL_CHECK_BOTH);
+ }
+
+ return bRet;
+}
+
+sal_Bool SAL_CALL
+SwXTextCursor::isStartOfSentence()
+{
+ SolarMutexGuard aGuard;
+
+ SwUnoCursor & rUnoCursor( GetCursorOrThrow() );
+
+ // start of paragraph?
+ bool bRet = rUnoCursor.GetPoint()->GetContentIndex() == 0;
+ // with mark ->no sentence start
+ // (check if cursor is no selection, i.e. it does not have
+ // a mark or else point and mark are identical)
+ if (!bRet && (!rUnoCursor.HasMark() ||
+ *rUnoCursor.GetPoint() == *rUnoCursor.GetMark()))
+ {
+ SwCursor aCursor(*rUnoCursor.GetPoint(),nullptr);
+ SwPosition aOrigPos = *aCursor.GetPoint();
+ aCursor.GoSentence(SwCursor::START_SENT );
+ bRet = aOrigPos == *aCursor.GetPoint();
+ }
+ return bRet;
+}
+
+sal_Bool SAL_CALL
+SwXTextCursor::isEndOfSentence()
+{
+ SolarMutexGuard aGuard;
+
+ SwUnoCursor & rUnoCursor( GetCursorOrThrow() );
+
+ // end of paragraph?
+ bool bRet = rUnoCursor.GetPointContentNode() &&
+ (rUnoCursor.GetPoint()->GetContentIndex() == rUnoCursor.GetPointContentNode()->Len());
+ // with mark->no sentence end
+ // (check if cursor is no selection, i.e. it does not have
+ // a mark or else point and mark are identical)
+ if (!bRet && (!rUnoCursor.HasMark() ||
+ *rUnoCursor.GetPoint() == *rUnoCursor.GetMark()))
+ {
+ SwCursor aCursor(*rUnoCursor.GetPoint(), nullptr);
+ SwPosition aOrigPos = *aCursor.GetPoint();
+ aCursor.GoSentence(SwCursor::END_SENT);
+ bRet = aOrigPos == *aCursor.GetPoint();
+ }
+ return bRet;
+}
+
+sal_Bool SAL_CALL
+SwXTextCursor::gotoNextSentence(sal_Bool Expand)
+{
+ SolarMutexGuard aGuard;
+
+ SwUnoCursor & rUnoCursor( GetCursorOrThrow() );
+
+ const bool bWasEOS = isEndOfSentence();
+ SwUnoCursorHelper::SelectPam(rUnoCursor, Expand);
+ bool bRet = rUnoCursor.GoSentence(SwCursor::NEXT_SENT);
+ if (!bRet)
+ {
+ bRet = rUnoCursor.MovePara(GoNextPara, fnParaStart);
+ }
+
+ // if at the end of the sentence (i.e. at the space after the '.')
+ // advance to next word in order for GoSentence to work properly
+ // next time and have isStartOfSentence return true after this call
+ if (!rUnoCursor.IsStartWordWT(css::i18n::WordType::ANYWORD_IGNOREWHITESPACES))
+ {
+ const bool bNextWord = rUnoCursor.GoNextWordWT(i18n::WordType::ANYWORD_IGNOREWHITESPACES);
+ if (bWasEOS && !bNextWord)
+ {
+ bRet = false;
+ }
+ }
+ if (CursorType::Meta == m_eType)
+ {
+ bRet = lcl_ForceIntoMeta(rUnoCursor, m_xParentText,
+ META_CHECK_BOTH)
+ && bRet;
+ }
+ else if (m_eType == CursorType::ContentControl)
+ {
+ bRet = lcl_ForceIntoContentControl(rUnoCursor, m_xParentText, CONTENT_CONTROL_CHECK_BOTH)
+ && bRet;
+ }
+ return bRet;
+}
+
+sal_Bool SAL_CALL
+SwXTextCursor::gotoPreviousSentence(sal_Bool Expand)
+{
+ SolarMutexGuard aGuard;
+
+ SwUnoCursor & rUnoCursor( GetCursorOrThrow() );
+
+ SwUnoCursorHelper::SelectPam(rUnoCursor, Expand);
+ bool bRet = rUnoCursor.GoSentence(SwCursor::PREV_SENT);
+ if (!bRet)
+ {
+ bRet = rUnoCursor.MovePara(GoPrevPara, fnParaStart);
+ if (bRet)
+ {
+ rUnoCursor.MovePara(GoCurrPara, fnParaEnd);
+ // at the end of a paragraph move to the sentence end again
+ rUnoCursor.GoSentence(SwCursor::PREV_SENT);
+ }
+ }
+ if (CursorType::Meta == m_eType)
+ {
+ bRet = lcl_ForceIntoMeta(rUnoCursor, m_xParentText,
+ META_CHECK_BOTH)
+ && bRet;
+ }
+ else if (m_eType == CursorType::ContentControl)
+ {
+ bRet = lcl_ForceIntoContentControl(rUnoCursor, m_xParentText, CONTENT_CONTROL_CHECK_BOTH)
+ && bRet;
+ }
+ return bRet;
+}
+
+sal_Bool SAL_CALL
+SwXTextCursor::gotoStartOfSentence(sal_Bool Expand)
+{
+ SolarMutexGuard aGuard;
+
+ SwUnoCursor & rUnoCursor( GetCursorOrThrow() );
+
+ SwUnoCursorHelper::SelectPam(rUnoCursor, Expand);
+ // if we're at the para start then we won't move
+ // but bRet is also true if GoSentence failed but
+ // the start of the sentence is reached
+ bool bRet = SwUnoCursorHelper::IsStartOfPara(rUnoCursor)
+ || rUnoCursor.GoSentence(SwCursor::START_SENT)
+ || SwUnoCursorHelper::IsStartOfPara(rUnoCursor);
+ if (CursorType::Meta == m_eType)
+ {
+ bRet = lcl_ForceIntoMeta(rUnoCursor, m_xParentText,
+ META_CHECK_BOTH)
+ && bRet;
+ }
+ else if (m_eType == CursorType::ContentControl)
+ {
+ bRet = lcl_ForceIntoContentControl(rUnoCursor, m_xParentText, CONTENT_CONTROL_CHECK_BOTH)
+ && bRet;
+ }
+ return bRet;
+}
+
+sal_Bool SAL_CALL
+SwXTextCursor::gotoEndOfSentence(sal_Bool Expand)
+{
+ SolarMutexGuard aGuard;
+
+ SwUnoCursor & rUnoCursor( GetCursorOrThrow() );
+
+ SwUnoCursorHelper::SelectPam(rUnoCursor, Expand);
+ // bRet is true if GoSentence() succeeded or if the
+ // MovePara() succeeded while the end of the para is
+ // not reached already
+ bool bAlreadyParaEnd = SwUnoCursorHelper::IsEndOfPara(rUnoCursor);
+ bool bRet = !bAlreadyParaEnd
+ && (rUnoCursor.GoSentence(SwCursor::END_SENT)
+ || rUnoCursor.MovePara(GoCurrPara, fnParaEnd));
+ if (CursorType::Meta == m_eType)
+ {
+ bRet = lcl_ForceIntoMeta(rUnoCursor, m_xParentText,
+ META_CHECK_BOTH)
+ && bRet;
+ }
+ else if (m_eType == CursorType::ContentControl)
+ {
+ bRet = lcl_ForceIntoContentControl(rUnoCursor, m_xParentText, CONTENT_CONTROL_CHECK_BOTH)
+ && bRet;
+ }
+ return bRet;
+}
+
+sal_Bool SAL_CALL
+SwXTextCursor::isStartOfParagraph()
+{
+ SolarMutexGuard aGuard;
+
+ SwUnoCursor & rUnoCursor( GetCursorOrThrow() );
+
+ const bool bRet = SwUnoCursorHelper::IsStartOfPara(rUnoCursor);
+ return bRet;
+}
+
+sal_Bool SAL_CALL
+SwXTextCursor::isEndOfParagraph()
+{
+ SolarMutexGuard aGuard;
+
+ SwUnoCursor & rUnoCursor( GetCursorOrThrow() );
+
+ const bool bRet = SwUnoCursorHelper::IsEndOfPara(rUnoCursor);
+ return bRet;
+}
+
+sal_Bool SAL_CALL
+SwXTextCursor::gotoStartOfParagraph(sal_Bool Expand)
+{
+ SolarMutexGuard aGuard;
+
+ SwUnoCursor & rUnoCursor( GetCursorOrThrow() );
+
+ if (CursorType::Meta == m_eType)
+ {
+ return false;
+ }
+ SwUnoCursorHelper::SelectPam(rUnoCursor, Expand);
+ bool bRet = SwUnoCursorHelper::IsStartOfPara(rUnoCursor);
+ if (!bRet)
+ {
+ bRet = rUnoCursor.MovePara(GoCurrPara, fnParaStart);
+ }
+
+ // since MovePara(GoCurrPara, fnParaStart) only returns false
+ // if we were already at the start of the paragraph this function
+ // should always complete successfully.
+ OSL_ENSURE( bRet, "gotoStartOfParagraph failed" );
+ return bRet;
+}
+
+sal_Bool SAL_CALL
+SwXTextCursor::gotoEndOfParagraph(sal_Bool Expand)
+{
+ SolarMutexGuard aGuard;
+
+ SwUnoCursor & rUnoCursor( GetCursorOrThrow() );
+
+ if (CursorType::Meta == m_eType)
+ {
+ return false;
+ }
+ SwUnoCursorHelper::SelectPam(rUnoCursor, Expand);
+ bool bRet = SwUnoCursorHelper::IsEndOfPara(rUnoCursor);
+ if (!bRet)
+ {
+ bRet = rUnoCursor.MovePara(GoCurrPara, fnParaEnd);
+ }
+
+ // since MovePara(GoCurrPara, fnParaEnd) only returns false
+ // if we were already at the end of the paragraph this function
+ // should always complete successfully.
+ OSL_ENSURE( bRet, "gotoEndOfParagraph failed" );
+ return bRet;
+}
+
+sal_Bool SAL_CALL
+SwXTextCursor::gotoNextParagraph(sal_Bool Expand)
+{
+ SolarMutexGuard aGuard;
+
+ SwUnoCursor & rUnoCursor( GetCursorOrThrow() );
+
+ if (CursorType::Meta == m_eType)
+ {
+ return false;
+ }
+ SwUnoCursorHelper::SelectPam(rUnoCursor, Expand);
+ const bool bRet = rUnoCursor.MovePara(GoNextPara, fnParaStart);
+ return bRet;
+}
+
+sal_Bool SAL_CALL
+SwXTextCursor::gotoPreviousParagraph(sal_Bool Expand)
+{
+ SolarMutexGuard aGuard;
+
+ SwUnoCursor & rUnoCursor( GetCursorOrThrow() );
+
+ if (CursorType::Meta == m_eType)
+ {
+ return false;
+ }
+ SwUnoCursorHelper::SelectPam(rUnoCursor, Expand);
+ const bool bRet = rUnoCursor.MovePara(GoPrevPara, fnParaStart);
+ return bRet;
+}
+
+uno::Reference< text::XText > SAL_CALL
+SwXTextCursor::getText()
+{
+ SolarMutexGuard g;
+
+ return m_xParentText;
+}
+
+uno::Reference< text::XTextRange > SAL_CALL
+SwXTextCursor::getStart()
+{
+ SolarMutexGuard aGuard;
+
+ SwUnoCursor & rUnoCursor( GetCursorOrThrow() );
+
+ uno::Reference< text::XTextRange > xRet;
+ SwPaM aPam(*rUnoCursor.Start());
+ const uno::Reference< text::XText > xParent = getText();
+ if (CursorType::Meta == m_eType)
+ {
+ // return cursor to prevent modifying SwXTextRange for META
+ rtl::Reference<SwXTextCursor> pXCursor(
+ new SwXTextCursor(rUnoCursor.GetDoc(), xParent, CursorType::Meta,
+ *rUnoCursor.GetPoint()) );
+ pXCursor->gotoStart(false);
+ xRet = static_cast<text::XWordCursor*>(pXCursor.get());
+ }
+ else
+ {
+ xRet = new SwXTextRange(aPam, xParent);
+ }
+ return xRet;
+}
+
+uno::Reference< text::XTextRange > SAL_CALL
+SwXTextCursor::getEnd()
+{
+ SolarMutexGuard aGuard;
+
+ SwUnoCursor & rUnoCursor( GetCursorOrThrow() );
+
+ uno::Reference< text::XTextRange > xRet;
+ SwPaM aPam(*rUnoCursor.End());
+ const uno::Reference< text::XText > xParent = getText();
+ if (CursorType::Meta == m_eType)
+ {
+ // return cursor to prevent modifying SwXTextRange for META
+ rtl::Reference<SwXTextCursor> pXCursor(
+ new SwXTextCursor(rUnoCursor.GetDoc(), xParent, CursorType::Meta,
+ *rUnoCursor.GetPoint()) );
+ pXCursor->gotoEnd(false);
+ xRet = static_cast<text::XWordCursor*>(pXCursor.get());
+ }
+ else
+ {
+ xRet = new SwXTextRange(aPam, xParent);
+ }
+ return xRet;
+}
+
+OUString SAL_CALL SwXTextCursor::getString()
+{
+ SolarMutexGuard aGuard;
+
+ SwUnoCursor & rUnoCursor( GetCursorOrThrow() );
+
+ OUString aText;
+ SwUnoCursorHelper::GetTextFromPam(rUnoCursor, aText);
+ return aText;
+}
+
+void SAL_CALL
+SwXTextCursor::setString(const OUString& aString)
+{
+ SolarMutexGuard aGuard;
+
+ GetCursorOrThrow(); // just to check if valid
+
+ const bool bForceExpandHints( (CursorType::Meta == m_eType)
+ && dynamic_cast<SwXMeta&>(*m_xParentText)
+ .CheckForOwnMemberMeta(*GetPaM(), true) );
+ DeleteAndInsert(aString, bForceExpandHints ? ::sw::DeleteAndInsertMode::ForceExpandHints : ::sw::DeleteAndInsertMode::Default);
+}
+
+uno::Any SwUnoCursorHelper::GetPropertyValue(
+ SwPaM& rPaM, const SfxItemPropertySet& rPropSet,
+ std::u16string_view rPropertyName)
+{
+ uno::Any aAny;
+ SfxItemPropertyMapEntry const*const pEntry =
+ rPropSet.getPropertyMap().getByName(rPropertyName);
+
+ if (!pEntry)
+ {
+ throw beans::UnknownPropertyException(
+ OUString::Concat("Unknown property: ") + rPropertyName);
+ }
+
+ beans::PropertyState eTemp;
+ const bool bDone = SwUnoCursorHelper::getCursorPropertyValue(
+ *pEntry, rPaM, &aAny, eTemp );
+
+ if (!bDone)
+ {
+ SfxItemSetFixed<
+ RES_CHRATR_BEGIN, RES_FRMATR_END - 1,
+ RES_UNKNOWNATR_CONTAINER, RES_UNKNOWNATR_CONTAINER>
+ aSet(rPaM.GetDoc().GetAttrPool());
+
+ SwUnoCursorHelper::GetCursorAttr(rPaM, aSet);
+
+ rPropSet.getPropertyValue(*pEntry, aSet, aAny);
+ }
+
+ return aAny;
+}
+
+void SwUnoCursorHelper::SetPropertyValue(
+ SwPaM& rPaM, const SfxItemPropertySet& rPropSet,
+ const OUString& rPropertyName,
+ const uno::Any& rValue,
+ const SetAttrMode nAttrMode)
+{
+ beans::PropertyValue aVal { comphelper::makePropertyValue(rPropertyName, rValue) };
+ SetPropertyValues(rPaM, rPropSet, std::span<beans::PropertyValue>(&aVal, 1), nAttrMode);
+}
+
+// FN_UNO_PARA_STYLE is known to set attributes for nodes, inside
+// SwUnoCursorHelper::SetTextFormatColl, instead of extending item set.
+// We need to get them from nodes in next call to GetCursorAttr.
+// The rest could cause similar problems in theory, so we just list them here.
+static bool propertyCausesSideEffectsInNodes(sal_uInt16 nWID)
+{
+ return nWID == FN_UNO_PARA_STYLE ||
+ nWID == FN_UNO_CHARFMT_SEQUENCE ||
+ nWID == FN_UNO_NUM_START_VALUE ||
+ nWID == FN_UNO_NUM_RULES;
+}
+
+void SwUnoCursorHelper::SetPropertyValues(
+ SwPaM& rPaM, const SfxItemPropertySet& rPropSet,
+ const uno::Sequence< beans::PropertyValue > &rPropertyValues,
+ const SetAttrMode nAttrMode)
+{
+ SetPropertyValues(rPaM, rPropSet,
+ std::span<const beans::PropertyValue>(rPropertyValues.getConstArray(), rPropertyValues.getLength()),
+ nAttrMode);
+}
+
+void SwUnoCursorHelper::SetPropertyValues(
+ SwPaM& rPaM, const SfxItemPropertySet& rPropSet,
+ std::span< const beans::PropertyValue > aPropertyValues,
+ const SetAttrMode nAttrMode)
+{
+ if (aPropertyValues.empty())
+ return;
+
+ SwDoc& rDoc = rPaM.GetDoc();
+ OUString aUnknownExMsg, aPropertyVetoExMsg;
+
+ // Build set of attributes we want to fetch
+ WhichRangesContainer aRanges;
+ std::vector<std::pair<const SfxItemPropertyMapEntry*, const uno::Any&>> aSideEffectsEntries;
+ std::vector<std::pair<const SfxItemPropertyMapEntry*, const uno::Any&>> aEntries;
+ aEntries.reserve(aPropertyValues.size());
+ for (const auto& rPropVal : aPropertyValues)
+ {
+ const OUString &rPropertyName = rPropVal.Name;
+
+ SfxItemPropertyMapEntry const* pEntry =
+ rPropSet.getPropertyMap().getByName(rPropertyName);
+
+ // Queue up any exceptions until the end ...
+ if (!pEntry)
+ {
+ aUnknownExMsg += "Unknown property: '" + rPropertyName + "' ";
+ continue;
+ }
+ else if (pEntry->nFlags & beans::PropertyAttribute::READONLY)
+ {
+ aPropertyVetoExMsg += "Property is read-only: '" + rPropertyName + "' ";
+ continue;
+ }
+ if (propertyCausesSideEffectsInNodes(pEntry->nWID))
+ {
+ aSideEffectsEntries.emplace_back(pEntry, rPropVal.Value);
+ }
+ else
+ {
+ aRanges = aRanges.MergeRange(pEntry->nWID, pEntry->nWID);
+ aEntries.emplace_back(pEntry, rPropVal.Value);
+ }
+ }
+
+ // Entries with side effects first, using dedicated one-element SfxItemSet for each
+ for (const auto& [pEntry, rValue] : aSideEffectsEntries)
+ {
+ SfxItemSet aItemSet(rDoc.GetAttrPool(), pEntry->nWID, pEntry->nWID);
+ // we need to get up-to-date item set from nodes
+ SwUnoCursorHelper::GetCursorAttr(rPaM, aItemSet);
+ // this can set some attributes in nodes' mpAttrSet
+ if (!SwUnoCursorHelper::SetCursorPropertyValue(*pEntry, rValue, rPaM, aItemSet))
+ rPropSet.setPropertyValue(*pEntry, rValue, aItemSet);
+ SwUnoCursorHelper::SetCursorAttr(rPaM, aItemSet, nAttrMode, false /*bTableMode*/);
+ }
+
+ if (!aEntries.empty())
+ {
+ // Fetch, overwrite, and re-set the attributes from the core
+ SfxItemSet aItemSet(rDoc.GetAttrPool(), std::move(aRanges));
+ // we need to get up-to-date item set from nodes
+ SwUnoCursorHelper::GetCursorAttr(rPaM, aItemSet);
+
+ for (const auto& [pEntry, rValue] : aEntries)
+ {
+ // this can set some attributes in nodes' mpAttrSet
+ if (!SwUnoCursorHelper::SetCursorPropertyValue(*pEntry, rValue, rPaM, aItemSet))
+ rPropSet.setPropertyValue(*pEntry, rValue, aItemSet);
+ }
+
+ SwUnoCursorHelper::SetCursorAttr(rPaM, aItemSet, nAttrMode, false /*bTableMode*/);
+ }
+
+ if (!aUnknownExMsg.isEmpty())
+ throw beans::UnknownPropertyException(aUnknownExMsg);
+ if (!aPropertyVetoExMsg.isEmpty())
+ throw beans::PropertyVetoException(aPropertyVetoExMsg);
+}
+
+namespace
+{
+ bool NotInRange(sal_uInt16 nWID, sal_uInt16 nStart, sal_uInt16 nEnd)
+ {
+ return nWID < nStart || nWID > nEnd;
+ }
+}
+
+uno::Sequence< beans::PropertyState >
+SwUnoCursorHelper::GetPropertyStates(
+ SwPaM& rPaM, const SfxItemPropertySet& rPropSet,
+ const uno::Sequence< OUString >& rPropertyNames,
+ const SwGetPropertyStatesCaller eCaller)
+{
+ const OUString* pNames = rPropertyNames.getConstArray();
+ uno::Sequence< beans::PropertyState > aRet(rPropertyNames.getLength());
+ beans::PropertyState* pStates = aRet.getArray();
+ const SfxItemPropertyMap &rMap = rPropSet.getPropertyMap();
+ std::optional<SfxItemSet> oSet;
+ std::optional<SfxItemSet> oSetParent;
+
+ for (sal_Int32 i = 0, nEnd = rPropertyNames.getLength(); i < nEnd; i++)
+ {
+ SfxItemPropertyMapEntry const*const pEntry =
+ rMap.getByName( pNames[i] );
+ if(!pEntry)
+ {
+ if (pNames[i] == UNO_NAME_IS_SKIP_HIDDEN_TEXT ||
+ pNames[i] == UNO_NAME_IS_SKIP_PROTECTED_TEXT ||
+ pNames[i] == UNO_NAME_NO_FORMAT_ATTR)
+ {
+ pStates[i] = beans::PropertyState_DEFAULT_VALUE;
+ continue;
+ }
+ else if (SW_PROPERTY_STATE_CALLER_SWX_TEXT_PORTION_TOLERANT ==
+ eCaller)
+ {
+ //this values marks the element as unknown property
+ pStates[i] = beans::PropertyState::PropertyState_MAKE_FIXED_SIZE;
+ continue;
+ }
+ else
+ {
+ throw beans::UnknownPropertyException(
+ "Unknown property: " + pNames[i]);
+ }
+ }
+ if (((SW_PROPERTY_STATE_CALLER_SWX_TEXT_PORTION == eCaller) ||
+ (SW_PROPERTY_STATE_CALLER_SWX_TEXT_PORTION_TOLERANT == eCaller)) &&
+ NotInRange(pEntry->nWID, FN_UNO_RANGE_BEGIN, FN_UNO_RANGE_END) &&
+ NotInRange(pEntry->nWID, RES_CHRATR_BEGIN, RES_TXTATR_END) )
+ {
+ pStates[i] = beans::PropertyState_DEFAULT_VALUE;
+ }
+ else
+ {
+ if ( pEntry->nWID >= FN_UNO_RANGE_BEGIN &&
+ pEntry->nWID <= FN_UNO_RANGE_END )
+ {
+ (void)SwUnoCursorHelper::getCursorPropertyValue(
+ *pEntry, rPaM, nullptr, pStates[i] );
+ }
+ else
+ {
+ if (!oSet)
+ {
+ switch ( eCaller )
+ {
+ case SW_PROPERTY_STATE_CALLER_SWX_TEXT_PORTION_TOLERANT:
+ case SW_PROPERTY_STATE_CALLER_SWX_TEXT_PORTION:
+ oSet.emplace( rPaM.GetDoc().GetAttrPool(),
+ svl::Items<RES_CHRATR_BEGIN, RES_TXTATR_END> );
+ break;
+ case SW_PROPERTY_STATE_CALLER_SINGLE_VALUE_ONLY:
+ oSet.emplace( rPaM.GetDoc().GetAttrPool(),
+ pEntry->nWID, pEntry->nWID );
+ break;
+ default:
+ oSet.emplace(
+ rPaM.GetDoc().GetAttrPool(),
+ svl::Items<
+ RES_CHRATR_BEGIN, RES_FRMATR_END - 1,
+ RES_UNKNOWNATR_CONTAINER,
+ RES_UNKNOWNATR_CONTAINER>);
+ }
+ // #i63870#
+ SwUnoCursorHelper::GetCursorAttr( rPaM, *oSet );
+ }
+
+ pStates[i] = ( oSet->Count() )
+ ? rPropSet.getPropertyState( *pEntry, *oSet )
+ : beans::PropertyState_DEFAULT_VALUE;
+
+ //try again to find out if a value has been inherited
+ if( beans::PropertyState_DIRECT_VALUE == pStates[i] )
+ {
+ if (!oSetParent)
+ {
+ oSetParent.emplace(oSet->CloneAsValue( false ));
+ // #i63870#
+ SwUnoCursorHelper::GetCursorAttr(
+ rPaM, *oSetParent, true, false );
+ }
+
+ pStates[i] = ( oSetParent->Count() )
+ ? rPropSet.getPropertyState( *pEntry, *oSetParent )
+ : beans::PropertyState_DEFAULT_VALUE;
+ }
+ }
+ }
+ }
+ return aRet;
+}
+
+beans::PropertyState SwUnoCursorHelper::GetPropertyState(
+ SwPaM& rPaM, const SfxItemPropertySet& rPropSet,
+ const OUString& rPropertyName)
+{
+ uno::Sequence< OUString > aStrings { rPropertyName };
+ uno::Sequence< beans::PropertyState > aSeq =
+ GetPropertyStates(rPaM, rPropSet, aStrings,
+ SW_PROPERTY_STATE_CALLER_SINGLE_VALUE_ONLY );
+ return aSeq[0];
+}
+
+static void
+lcl_SelectParaAndReset( SwPaM &rPaM, SwDoc & rDoc,
+ o3tl::sorted_vector<sal_uInt16> const &rWhichIds )
+{
+ // if we are resetting paragraph attributes, we need to select the full paragraph first
+ SwPosition aStart = *rPaM.Start();
+ SwPosition aEnd = *rPaM.End();
+ auto pTemp ( rDoc.CreateUnoCursor(aStart) );
+ if(!SwUnoCursorHelper::IsStartOfPara(*pTemp))
+ {
+ pTemp->MovePara(GoCurrPara, fnParaStart);
+ }
+ pTemp->SetMark();
+ *pTemp->GetPoint() = aEnd;
+ SwUnoCursorHelper::SelectPam(*pTemp, true);
+ if(!SwUnoCursorHelper::IsEndOfPara(*pTemp))
+ {
+ pTemp->MovePara(GoCurrPara, fnParaEnd);
+ }
+ rDoc.ResetAttrs(*pTemp, true, rWhichIds);
+}
+
+void SwUnoCursorHelper::SetPropertyToDefault(
+ SwPaM& rPaM, const SfxItemPropertySet& rPropSet,
+ std::u16string_view rPropertyName)
+{
+ SwDoc& rDoc = rPaM.GetDoc();
+ SfxItemPropertyMapEntry const*const pEntry =
+ rPropSet.getPropertyMap().getByName(rPropertyName);
+ if (!pEntry)
+ {
+ throw beans::UnknownPropertyException(
+ OUString::Concat("Unknown property: ") + rPropertyName);
+ }
+
+ if (pEntry->nFlags & beans::PropertyAttribute::READONLY)
+ {
+ throw uno::RuntimeException(
+ OUString::Concat("setPropertyToDefault: property is read-only: ")
+ + rPropertyName, nullptr);
+ }
+
+ if (pEntry->nWID < RES_FRMATR_END)
+ {
+ const o3tl::sorted_vector<sal_uInt16> aWhichIds{ pEntry->nWID };
+ if (pEntry->nWID < RES_PARATR_BEGIN)
+ {
+ rDoc.ResetAttrs(rPaM, true, aWhichIds);
+ }
+ else
+ {
+ lcl_SelectParaAndReset ( rPaM, rDoc, aWhichIds );
+ }
+ }
+ else
+ {
+ SwUnoCursorHelper::resetCursorPropertyValue(*pEntry, rPaM);
+ }
+}
+
+uno::Any SwUnoCursorHelper::GetPropertyDefault(
+ SwPaM const & rPaM, const SfxItemPropertySet& rPropSet,
+ std::u16string_view rPropertyName)
+{
+ SfxItemPropertyMapEntry const*const pEntry =
+ rPropSet.getPropertyMap().getByName(rPropertyName);
+ if (!pEntry)
+ {
+ throw beans::UnknownPropertyException(
+ OUString::Concat("Unknown property: ") + rPropertyName);
+ }
+
+ uno::Any aRet;
+ if (pEntry->nWID < RES_FRMATR_END)
+ {
+ SwDoc& rDoc = rPaM.GetDoc();
+ const SfxPoolItem& rDefItem =
+ rDoc.GetAttrPool().GetDefaultItem(pEntry->nWID);
+ rDefItem.QueryValue(aRet, pEntry->nMemberId);
+ }
+ return aRet;
+}
+
+uno::Reference< beans::XPropertySetInfo > SAL_CALL
+SwXTextCursor::getPropertySetInfo()
+{
+ SolarMutexGuard g;
+
+ static uno::Reference< beans::XPropertySetInfo > xRef = [&]()
+ {
+ static SfxItemPropertyMapEntry const aCursorExtMap_Impl[] =
+ {
+ { UNO_NAME_IS_SKIP_HIDDEN_TEXT, FN_SKIP_HIDDEN_TEXT, cppu::UnoType<bool>::get(), PROPERTY_NONE, 0},
+ { UNO_NAME_IS_SKIP_PROTECTED_TEXT, FN_SKIP_PROTECTED_TEXT, cppu::UnoType<bool>::get(), PROPERTY_NONE, 0},
+ { UNO_NAME_NO_FORMAT_ATTR, 0, cppu::UnoType<bool>::get(), PROPERTY_NONE, 0},
+ };
+ const uno::Reference< beans::XPropertySetInfo > xInfo =
+ m_rPropSet.getPropertySetInfo();
+ // extend PropertySetInfo!
+ const uno::Sequence<beans::Property> aPropSeq = xInfo->getProperties();
+ return rtl::Reference<SfxExtItemPropertySetInfo>(new SfxExtItemPropertySetInfo(
+ aCursorExtMap_Impl,
+ aPropSeq ));
+ }();
+ return xRef;
+}
+
+void SAL_CALL
+SwXTextCursor::setPropertyValue(
+ const OUString& rPropertyName, const uno::Any& rValue)
+{
+ SolarMutexGuard aGuard;
+
+ SwUnoCursor & rUnoCursor( GetCursorOrThrow() );
+
+ if (rPropertyName == UNO_NAME_IS_SKIP_HIDDEN_TEXT)
+ {
+ bool bSet(false);
+ if (!(rValue >>= bSet))
+ {
+ throw lang::IllegalArgumentException();
+ }
+ rUnoCursor.SetSkipOverHiddenSections(bSet);
+ }
+ else if (rPropertyName == UNO_NAME_IS_SKIP_PROTECTED_TEXT)
+ {
+ bool bSet(false);
+ if (!(rValue >>= bSet))
+ {
+ throw lang::IllegalArgumentException();
+ }
+ rUnoCursor.SetSkipOverProtectSections(bSet);
+ }
+ else if (rPropertyName == UNO_NAME_NO_FORMAT_ATTR)
+ {
+ bool bSet(false);
+ if (!(rValue >>= bSet))
+ {
+ throw lang::IllegalArgumentException();
+ }
+ if (bSet)
+ {
+ m_nAttrMode = SetAttrMode::NOFORMATATTR;
+ }
+ else
+ {
+ m_nAttrMode = SetAttrMode::DEFAULT;
+ }
+ }
+ else if (rPropertyName == "ParaAutoStyleDef")
+ {
+ // Create an autostyle from passed definition (sequence of PropertyValue, same
+ // as in XAutoStyleFamily::insertStyle), using the currently applied properties
+ // from the paragraph to not lose their values when creating complex properties
+ // like SvxULSpaceItem, when only part of the properties stored there is passed;
+ // and apply it to the paragraph.
+ uno::Sequence<beans::PropertyValue> def;
+ if (!(rValue >>= def))
+ throw lang::IllegalArgumentException();
+
+ // See SwUnoCursorHelper::SetPropertyValues
+
+ auto pPropSet = aSwMapProvider.GetPropertySet(PROPERTY_MAP_PARA_AUTO_STYLE);
+
+ // Build set of attributes we want to fetch
+ WhichRangesContainer aRanges;
+ for (auto& rPropVal : def)
+ {
+ SfxItemPropertyMapEntry const* pEntry =
+ pPropSet->getPropertyMap().getByName(rPropVal.Name);
+ if (!pEntry)
+ continue; // PropValuesToAutoStyleItemSet ignores invalid names
+
+ aRanges = aRanges.MergeRange(pEntry->nWID, pEntry->nWID);
+ }
+
+ if (!aRanges.empty())
+ {
+ SwAttrSet aAutoStyleItemSet(rUnoCursor.GetDoc().GetAttrPool(), std::move(aRanges));
+ // we need to get up-to-date item set: this makes sure that the complex properties,
+ // that are only partially defined by passed definition, do not lose the rest of
+ // their already present data (which will become part of the autostyle, too).
+ SwUnoCursorHelper::GetCursorAttr(rUnoCursor, aAutoStyleItemSet);
+ // Set normal set ranges before putting into autostyle, to the same ranges
+ // that are used for paragraph autostyle in SwXAutoStyleFamily::insertStyle
+ aAutoStyleItemSet.SetRanges(aTextNodeSetRange);
+
+ // Fill the prepared item set, containing current paragraph property values,
+ // with the passed definition, and create the autostyle.
+ auto pStyle = PropValuesToAutoStyleItemSet(
+ rUnoCursor.GetDoc(), IStyleAccess::AUTO_STYLE_PARA, def, aAutoStyleItemSet);
+
+ SwFormatAutoFormat aFormat(RES_AUTO_STYLE);
+ aFormat.SetStyleHandle(pStyle);
+ SfxItemSet rSet(rUnoCursor.GetDoc().GetAttrPool(), RES_AUTO_STYLE, RES_AUTO_STYLE);
+ rSet.Put(aFormat);
+ SwUnoCursorHelper::SetCursorAttr(rUnoCursor, rSet, m_nAttrMode);
+ }
+ }
+ else
+ {
+ SwUnoCursorHelper::SetPropertyValue(rUnoCursor,
+ m_rPropSet, rPropertyName, rValue, m_nAttrMode);
+ }
+}
+
+uno::Any SAL_CALL
+SwXTextCursor::getPropertyValue(const OUString& rPropertyName)
+{
+ SolarMutexGuard aGuard;
+
+ SwUnoCursor & rUnoCursor( GetCursorOrThrow() );
+
+ uno::Any aAny;
+ if (rPropertyName == UNO_NAME_IS_SKIP_HIDDEN_TEXT)
+ {
+ const bool bSet = rUnoCursor.IsSkipOverHiddenSections();
+ aAny <<= bSet;
+ }
+ else if (rPropertyName == UNO_NAME_IS_SKIP_PROTECTED_TEXT)
+ {
+ const bool bSet = rUnoCursor.IsSkipOverProtectSections();
+ aAny <<= bSet;
+ }
+ else
+ {
+ aAny = SwUnoCursorHelper::GetPropertyValue(rUnoCursor,
+ m_rPropSet, rPropertyName);
+ }
+ return aAny;
+}
+
+void SAL_CALL
+SwXTextCursor::addPropertyChangeListener(
+ const OUString& /*rPropertyName*/,
+ const uno::Reference< beans::XPropertyChangeListener >& /*xListener*/)
+{
+ OSL_FAIL("SwXTextCursor::addPropertyChangeListener(): not implemented");
+}
+
+void SAL_CALL
+SwXTextCursor::removePropertyChangeListener(
+ const OUString& /*rPropertyName*/,
+ const uno::Reference< beans::XPropertyChangeListener >& /*xListener*/)
+{
+ OSL_FAIL("SwXTextCursor::removePropertyChangeListener(): not implemented");
+}
+
+void SAL_CALL
+SwXTextCursor::addVetoableChangeListener(
+ const OUString& /*rPropertyName*/,
+ const uno::Reference< beans::XVetoableChangeListener >& /*xListener*/)
+{
+ OSL_FAIL("SwXTextCursor::addVetoableChangeListener(): not implemented");
+}
+
+void SAL_CALL
+SwXTextCursor::removeVetoableChangeListener(
+ const OUString& /*rPropertyName*/,
+ const uno::Reference< beans::XVetoableChangeListener >& /*xListener*/)
+{
+ OSL_FAIL("SwXTextCursor::removeVetoableChangeListener(): not implemented");
+}
+
+beans::PropertyState SAL_CALL
+SwXTextCursor::getPropertyState(const OUString& rPropertyName)
+{
+ SolarMutexGuard aGuard;
+
+ SwUnoCursor & rUnoCursor( GetCursorOrThrow() );
+
+ const beans::PropertyState eRet = SwUnoCursorHelper::GetPropertyState(
+ rUnoCursor, m_rPropSet, rPropertyName);
+ return eRet;
+}
+
+uno::Sequence< beans::PropertyState > SAL_CALL
+SwXTextCursor::getPropertyStates(
+ const uno::Sequence< OUString >& rPropertyNames)
+{
+ SolarMutexGuard aGuard;
+
+ SwUnoCursor & rUnoCursor( GetCursorOrThrow() );
+
+ return SwUnoCursorHelper::GetPropertyStates(
+ rUnoCursor, m_rPropSet, rPropertyNames);
+}
+
+void SAL_CALL
+SwXTextCursor::setPropertyToDefault(const OUString& rPropertyName)
+{
+ // forward: need no solar mutex here
+ uno::Sequence < OUString > aSequence ( &rPropertyName, 1 );
+ setPropertiesToDefault ( aSequence );
+}
+
+uno::Any SAL_CALL
+SwXTextCursor::getPropertyDefault(const OUString& rPropertyName)
+{
+ // forward: need no solar mutex here
+ const uno::Sequence < OUString > aSequence ( &rPropertyName, 1 );
+ return getPropertyDefaults ( aSequence ).getConstArray()[0];
+}
+
+void SAL_CALL SwXTextCursor::setPropertyValues(
+ const uno::Sequence< OUString >& aPropertyNames,
+ const uno::Sequence< uno::Any >& aValues )
+{
+ if( aValues.getLength() != aPropertyNames.getLength() )
+ {
+ OSL_FAIL( "mis-matched property value sequences" );
+ throw lang::IllegalArgumentException();
+ }
+
+ SolarMutexGuard aGuard;
+
+ SwUnoCursor & rUnoCursor( GetCursorOrThrow() );
+
+ // a little lame to have to copy into this.
+ uno::Sequence< beans::PropertyValue > aPropertyValues( aValues.getLength() );
+ auto aPropertyValuesRange = asNonConstRange(aPropertyValues);
+ for ( sal_Int32 i = 0; i < aPropertyNames.getLength(); i++ )
+ {
+ if ( aPropertyNames[ i ] == UNO_NAME_IS_SKIP_HIDDEN_TEXT ||
+ aPropertyNames[ i ] == UNO_NAME_IS_SKIP_PROTECTED_TEXT )
+ {
+ // the behaviour of these is hard to model in a group
+ OSL_FAIL("invalid property name for batch setting");
+ throw lang::IllegalArgumentException();
+ }
+ aPropertyValuesRange[ i ].Name = aPropertyNames[ i ];
+ aPropertyValuesRange[ i ].Value = aValues[ i ];
+ }
+ try
+ {
+ SwUnoCursorHelper::SetPropertyValues( rUnoCursor, m_rPropSet, aPropertyValues );
+ }
+ catch (const css::beans::UnknownPropertyException& e)
+ {
+ uno::Any a(cppu::getCaughtException());
+ throw lang::WrappedTargetException(
+ "wrapped Exception " + e.Message,
+ uno::Reference<uno::XInterface>(), a);
+ }
+}
+
+uno::Sequence< uno::Any > SAL_CALL
+SwXTextCursor::getPropertyValues( const uno::Sequence< OUString >& aPropertyNames )
+{
+ // a banal implementation for now
+ uno::Sequence< uno::Any > aValues( aPropertyNames.getLength() );
+ std::transform(aPropertyNames.begin(), aPropertyNames.end(), aValues.getArray(),
+ [this](const OUString& rName) -> uno::Any { return getPropertyValue( rName ); });
+ return aValues;
+}
+
+void SAL_CALL SwXTextCursor::addPropertiesChangeListener(
+ const uno::Sequence< OUString >& /* aPropertyNames */,
+ const uno::Reference< css::beans::XPropertiesChangeListener >& /* xListener */ )
+{
+ OSL_FAIL("SwXTextCursor::addPropertiesChangeListener(): not implemented");
+}
+void SAL_CALL SwXTextCursor::removePropertiesChangeListener(
+ const uno::Reference< css::beans::XPropertiesChangeListener >& /* xListener */ )
+{
+ OSL_FAIL("SwXTextCursor::removePropertiesChangeListener(): not implemented");
+}
+
+void SAL_CALL SwXTextCursor::firePropertiesChangeEvent(
+ const uno::Sequence< OUString >& /* aPropertyNames */,
+ const uno::Reference< css::beans::XPropertiesChangeListener >& /* xListener */ )
+{
+ OSL_FAIL("SwXTextCursor::firePropertiesChangeEvent(): not implemented");
+}
+
+// para specific attribute ranges
+static sal_uInt16 g_ParaResetableSetRange[] = {
+ RES_FRMATR_BEGIN, RES_FRMATR_END-1,
+ RES_PARATR_BEGIN, RES_PARATR_END-1,
+ RES_PARATR_LIST_BEGIN, RES_PARATR_LIST_END-1,
+ RES_UNKNOWNATR_BEGIN, RES_UNKNOWNATR_END-1,
+ 0
+};
+
+// selection specific attribute ranges
+static sal_uInt16 g_ResetableSetRange[] = {
+ RES_CHRATR_BEGIN, RES_CHRATR_END-1,
+ RES_TXTATR_INETFMT, RES_TXTATR_INETFMT,
+ RES_TXTATR_CHARFMT, RES_TXTATR_CHARFMT,
+ RES_TXTATR_CJK_RUBY, RES_TXTATR_CJK_RUBY,
+ RES_TXTATR_UNKNOWN_CONTAINER, RES_TXTATR_UNKNOWN_CONTAINER,
+ 0
+};
+
+static void
+lcl_EnumerateIds(sal_uInt16 const* pIdRange, o3tl::sorted_vector<sal_uInt16> &rWhichIds)
+{
+ while (*pIdRange)
+ {
+ const sal_uInt16 nStart = *pIdRange++;
+ const sal_uInt16 nEnd = *pIdRange++;
+ for (sal_uInt16 nId = nStart + 1; nId <= nEnd; ++nId)
+ {
+ rWhichIds.insert( nId );
+ }
+ }
+}
+
+void SAL_CALL
+SwXTextCursor::setAllPropertiesToDefault()
+{
+ SolarMutexGuard aGuard;
+
+ SwUnoCursor & rUnoCursor( GetCursorOrThrow() );
+
+ o3tl::sorted_vector<sal_uInt16> aParaWhichIds;
+ o3tl::sorted_vector<sal_uInt16> aWhichIds;
+ lcl_EnumerateIds(g_ParaResetableSetRange, aParaWhichIds);
+ lcl_EnumerateIds(g_ResetableSetRange, aWhichIds);
+ if (!aParaWhichIds.empty())
+ {
+ lcl_SelectParaAndReset(rUnoCursor, rUnoCursor.GetDoc(),
+ aParaWhichIds);
+ }
+ if (!aWhichIds.empty())
+ {
+ rUnoCursor.GetDoc().ResetAttrs(rUnoCursor, true, aWhichIds);
+ }
+}
+
+void SAL_CALL
+SwXTextCursor::setPropertiesToDefault(
+ const uno::Sequence< OUString >& rPropertyNames)
+{
+ SolarMutexGuard aGuard;
+
+ SwUnoCursor & rUnoCursor( GetCursorOrThrow() );
+
+ if ( !rPropertyNames.hasElements() )
+ return;
+
+ SwDoc& rDoc = rUnoCursor.GetDoc();
+ o3tl::sorted_vector<sal_uInt16> aWhichIds;
+ o3tl::sorted_vector<sal_uInt16> aParaWhichIds;
+ for (const OUString& rName : rPropertyNames)
+ {
+ SfxItemPropertyMapEntry const*const pEntry =
+ m_rPropSet.getPropertyMap().getByName( rName );
+ if (!pEntry)
+ {
+ if (rName == UNO_NAME_IS_SKIP_HIDDEN_TEXT ||
+ rName == UNO_NAME_IS_SKIP_PROTECTED_TEXT)
+ {
+ continue;
+ }
+ throw beans::UnknownPropertyException(
+ "Unknown property: " + rName,
+ getXWeak());
+ }
+ if (pEntry->nFlags & beans::PropertyAttribute::READONLY)
+ {
+ throw uno::RuntimeException(
+ "setPropertiesToDefault: property is read-only: " + rName,
+ getXWeak());
+ }
+
+ if (pEntry->nWID < RES_FRMATR_END)
+ {
+ if (pEntry->nWID < RES_PARATR_BEGIN)
+ {
+ aWhichIds.insert( pEntry->nWID );
+ }
+ else
+ {
+ aParaWhichIds.insert( pEntry->nWID );
+ }
+ }
+ else if (pEntry->nWID == FN_UNO_NUM_START_VALUE)
+ {
+ SwUnoCursorHelper::resetCursorPropertyValue(*pEntry, rUnoCursor);
+ }
+ }
+
+ if (!aParaWhichIds.empty())
+ {
+ lcl_SelectParaAndReset(rUnoCursor, rDoc, aParaWhichIds);
+ }
+ if (!aWhichIds.empty())
+ {
+ rDoc.ResetAttrs(rUnoCursor, true, aWhichIds);
+ }
+}
+
+uno::Sequence< uno::Any > SAL_CALL
+SwXTextCursor::getPropertyDefaults(
+ const uno::Sequence< OUString >& rPropertyNames)
+{
+ SolarMutexGuard aGuard;
+
+ SwUnoCursor & rUnoCursor( GetCursorOrThrow() );
+
+ const sal_Int32 nCount = rPropertyNames.getLength();
+ uno::Sequence< uno::Any > aRet(nCount);
+ if ( nCount )
+ {
+ SwDoc& rDoc = rUnoCursor.GetDoc();
+ const OUString *pNames = rPropertyNames.getConstArray();
+ uno::Any *pAny = aRet.getArray();
+ for (sal_Int32 i = 0; i < nCount; i++)
+ {
+ SfxItemPropertyMapEntry const*const pEntry =
+ m_rPropSet.getPropertyMap().getByName( pNames[i] );
+ if (!pEntry)
+ {
+ if (pNames[i] == UNO_NAME_IS_SKIP_HIDDEN_TEXT ||
+ pNames[i] == UNO_NAME_IS_SKIP_PROTECTED_TEXT ||
+ pNames[i] == UNO_NAME_NO_FORMAT_ATTR)
+ {
+ continue;
+ }
+ throw beans::UnknownPropertyException(
+ "Unknown property: " + pNames[i]);
+ }
+ if (pEntry->nWID < RES_FRMATR_END)
+ {
+ const SfxPoolItem& rDefItem =
+ rDoc.GetAttrPool().GetDefaultItem(pEntry->nWID);
+ rDefItem.QueryValue(pAny[i], pEntry->nMemberId);
+ }
+ }
+ }
+ return aRet;
+}
+
+void SAL_CALL SwXTextCursor::invalidateMarkings(::sal_Int32 nType)
+{
+ SolarMutexGuard aGuard;
+
+ SwUnoCursor & rUnoCursor( GetCursorOrThrow() );
+
+ SwNode& node = rUnoCursor.GetPointNode();
+
+ SwTextNode* txtNode = node.GetTextNode();
+
+ if (txtNode == nullptr) return;
+
+ if ( text::TextMarkupType::SPELLCHECK == nType )
+ {
+ txtNode->SetWrongDirty(sw::WrongState::TODO);
+ txtNode->ClearWrong();
+ }
+ else if( text::TextMarkupType::PROOFREADING == nType )
+ {
+ txtNode->SetGrammarCheckDirty(true);
+ txtNode->ClearGrammarCheck();
+ }
+ else if ( text::TextMarkupType::SMARTTAG == nType )
+ {
+ txtNode->SetSmartTagDirty(true);
+ txtNode->ClearSmartTags();
+ }
+ else return;
+
+ SwFormatColl* fmtColl=txtNode->GetFormatColl();
+
+ if (fmtColl == nullptr) return;
+
+ SwFormatChg aNew( fmtColl );
+ txtNode->CallSwClientNotify(sw::LegacyModifyHint(nullptr, &aNew));
+}
+
+void SAL_CALL
+SwXTextCursor::makeRedline(
+ const OUString& rRedlineType,
+ const uno::Sequence< beans::PropertyValue >& rRedlineProperties)
+{
+ SolarMutexGuard aGuard;
+
+ SwUnoCursor & rUnoCursor( GetCursorOrThrow() );
+
+ SwUnoCursorHelper::makeRedline(rUnoCursor, rRedlineType, rRedlineProperties);
+}
+
+void SAL_CALL SwXTextCursor::insertDocumentFromURL(const OUString& rURL,
+ const uno::Sequence< beans::PropertyValue >& rOptions)
+{
+ SolarMutexGuard aGuard;
+
+ SwUnoCursor & rUnoCursor( GetCursorOrThrow() );
+
+ SwUnoCursorHelper::InsertFile(&rUnoCursor, rURL, rOptions);
+}
+
+uno::Sequence< beans::PropertyValue >
+SwUnoCursorHelper::CreateSortDescriptor(const bool bFromTable)
+{
+ uno::Sequence< beans::PropertyValue > aRet(5);
+ beans::PropertyValue* pArray = aRet.getArray();
+
+ uno::Any aVal;
+ aVal <<= bFromTable;
+ pArray[0] = beans::PropertyValue("IsSortInTable", -1, aVal,
+ beans::PropertyState_DIRECT_VALUE);
+
+ aVal <<= u' ';
+ pArray[1] = beans::PropertyValue("Delimiter", -1, aVal,
+ beans::PropertyState_DIRECT_VALUE);
+
+ aVal <<= false;
+ pArray[2] = beans::PropertyValue("IsSortColumns", -1, aVal,
+ beans::PropertyState_DIRECT_VALUE);
+
+ aVal <<= sal_Int32(3);
+ pArray[3] = beans::PropertyValue("MaxSortFieldsCount", -1, aVal,
+ beans::PropertyState_DIRECT_VALUE);
+
+ lang::Locale aLang( SvtSysLocale().GetLanguageTag().getLocale());
+ // get collator algorithm to be used for the locale
+ uno::Sequence< OUString > aSeq(
+ GetAppCollator().listCollatorAlgorithms( aLang ) );
+ const bool bHasElements = aSeq.hasElements();
+ OSL_ENSURE( bHasElements, "list of collator algorithms is empty!");
+ OUString aCollAlg;
+ if (bHasElements)
+ {
+ aCollAlg = aSeq.getConstArray()[0];
+ }
+
+ uno::Sequence< table::TableSortField > aFields
+ {
+ // Field, IsAscending, IsCaseSensitive, FieldType, CollatorLocale, CollatorAlgorithm
+ { 1, true, false, table::TableSortFieldType_ALPHANUMERIC, aLang, aCollAlg },
+ { 1, true, false, table::TableSortFieldType_ALPHANUMERIC, aLang, aCollAlg },
+ { 1, true, false, table::TableSortFieldType_ALPHANUMERIC, aLang, aCollAlg }
+ };
+
+ aVal <<= aFields;
+ pArray[4] = beans::PropertyValue("SortFields", -1, aVal,
+ beans::PropertyState_DIRECT_VALUE);
+
+ return aRet;
+}
+
+uno::Sequence< beans::PropertyValue > SAL_CALL
+SwXTextCursor::createSortDescriptor()
+{
+ SolarMutexGuard aGuard;
+
+ return SwUnoCursorHelper::CreateSortDescriptor(false);
+}
+
+bool SwUnoCursorHelper::ConvertSortProperties(
+ const uno::Sequence< beans::PropertyValue >& rDescriptor,
+ SwSortOptions& rSortOpt)
+{
+ bool bRet = true;
+
+ rSortOpt.bTable = false;
+ rSortOpt.cDeli = ' ';
+ rSortOpt.eDirection = SwSortDirection::Columns; //!! UI text may be contrary though !!
+
+ SwSortKey aKey1;
+ aKey1.nColumnId = USHRT_MAX;
+ aKey1.bIsNumeric = true;
+ aKey1.eSortOrder = SwSortOrder::Ascending;
+
+ SwSortKey aKey2;
+ aKey2.nColumnId = USHRT_MAX;
+ aKey2.bIsNumeric = true;
+ aKey2.eSortOrder = SwSortOrder::Ascending;
+
+ SwSortKey aKey3;
+ aKey3.nColumnId = USHRT_MAX;
+ aKey3.bIsNumeric = true;
+ aKey3.eSortOrder = SwSortOrder::Ascending;
+ SwSortKey* aKeys[3] = {&aKey1, &aKey2, &aKey3};
+
+ bool bOldSortdescriptor(false);
+ bool bNewSortdescriptor(false);
+
+ for (const beans::PropertyValue& rProperty : rDescriptor)
+ {
+ uno::Any aValue( rProperty.Value );
+ const OUString& rPropName = rProperty.Name;
+
+ // old and new sortdescriptor
+ if ( rPropName == "IsSortInTable" )
+ {
+ if (auto b = o3tl::tryAccess<bool>(aValue))
+ {
+ rSortOpt.bTable = *b;
+ }
+ else
+ {
+ bRet = false;
+ }
+ }
+ else if ( rPropName == "Delimiter" )
+ {
+ sal_Unicode uChar;
+ sal_uInt16 nChar;
+ if (aValue >>= uChar)
+ {
+ rSortOpt.cDeli = uChar;
+ }
+ else if (aValue >>= nChar)
+ {
+ // For compatibility with BASIC, also accept an ANY containing
+ // an UNSIGNED SHORT:
+ rSortOpt.cDeli = nChar;
+ }
+ else
+ {
+ bRet = false;
+ }
+ }
+ // old sortdescriptor
+ else if ( rPropName == "SortColumns" )
+ {
+ bOldSortdescriptor = true;
+ bool bTemp(false);
+ if (aValue >>= bTemp)
+ {
+ rSortOpt.eDirection = bTemp ? SwSortDirection::Columns : SwSortDirection::Rows;
+ }
+ else
+ {
+ bRet = false;
+ }
+ }
+ else if ( rPropName == "IsCaseSensitive" )
+ {
+ bOldSortdescriptor = true;
+ bool bTemp(false);
+ if (aValue >>= bTemp)
+ {
+ rSortOpt.bIgnoreCase = !bTemp;
+ }
+ else
+ {
+ bRet = false;
+ }
+ }
+ else if ( rPropName == "CollatorLocale" )
+ {
+ bOldSortdescriptor = true;
+ lang::Locale aLocale;
+ if (aValue >>= aLocale)
+ {
+ rSortOpt.nLanguage = LanguageTag::convertToLanguageType( aLocale);
+ }
+ else
+ {
+ bRet = false;
+ }
+ }
+ else if (rPropName.startsWith("CollatorAlgorithm") &&
+ rPropName.getLength() == 18 &&
+ (rPropName[17] >= '0' && rPropName[17] <= '9'))
+ {
+ bOldSortdescriptor = true;
+ sal_uInt16 nIndex = rPropName[17];
+ nIndex -= '0';
+ OUString aText;
+ if ((aValue >>= aText) && nIndex < 3)
+ {
+ aKeys[nIndex]->sSortType = aText;
+ }
+ else
+ {
+ bRet = false;
+ }
+ }
+ else if (rPropName.startsWith("SortRowOrColumnNo") &&
+ rPropName.getLength() == 18 &&
+ (rPropName[17] >= '0' && rPropName[17] <= '9'))
+ {
+ bOldSortdescriptor = true;
+ sal_uInt16 nIndex = rPropName[17];
+ nIndex -= '0';
+ sal_Int16 nCol = -1;
+ if (aValue.getValueType() == ::cppu::UnoType<sal_Int16>::get()
+ && nIndex < 3)
+ {
+ aValue >>= nCol;
+ }
+ if (nCol >= 0)
+ {
+ aKeys[nIndex]->nColumnId = nCol;
+ }
+ else
+ {
+ bRet = false;
+ }
+ }
+ else if (rPropName.startsWith("IsSortNumeric") &&
+ rPropName.getLength() == 14 &&
+ (rPropName[13] >= '0' && rPropName[13] <= '9'))
+ {
+ bOldSortdescriptor = true;
+ sal_uInt16 nIndex = rPropName[13];
+ nIndex = nIndex - '0';
+ std::optional<const bool> bTemp = o3tl::tryAccess<bool>(aValue);
+ if (bTemp.has_value() && nIndex < 3)
+ {
+ aKeys[nIndex]->bIsNumeric = *bTemp;
+ }
+ else
+ {
+ bRet = false;
+ }
+ }
+ else if (rPropName.startsWith("IsSortAscending") &&
+ rPropName.getLength() == 16 &&
+ (rPropName[15] >= '0' && rPropName[15] <= '9'))
+ {
+ bOldSortdescriptor = true;
+ sal_uInt16 nIndex = rPropName[15];
+ nIndex -= '0';
+ std::optional<const bool> bTemp = o3tl::tryAccess<bool>(aValue);
+ if (bTemp.has_value() && nIndex < 3)
+ {
+ aKeys[nIndex]->eSortOrder = (*bTemp)
+ ? SwSortOrder::Ascending : SwSortOrder::Descending;
+ }
+ else
+ {
+ bRet = false;
+ }
+ }
+ // new sortdescriptor
+ else if ( rPropName == "IsSortColumns" )
+ {
+ bNewSortdescriptor = true;
+ if (auto bTemp = o3tl::tryAccess<bool>(aValue))
+ {
+ rSortOpt.eDirection = *bTemp ? SwSortDirection::Columns : SwSortDirection::Rows;
+ }
+ else
+ {
+ bRet = false;
+ }
+ }
+ else if ( rPropName == "SortFields" )
+ {
+ bNewSortdescriptor = true;
+ uno::Sequence < table::TableSortField > aFields;
+ if (aValue >>= aFields)
+ {
+ sal_Int32 nCount(aFields.getLength());
+ if (nCount <= 3)
+ {
+ table::TableSortField* pFields = aFields.getArray();
+ for (sal_Int32 i = 0; i < nCount; ++i)
+ {
+ rSortOpt.bIgnoreCase = !pFields[i].IsCaseSensitive;
+ rSortOpt.nLanguage =
+ LanguageTag::convertToLanguageType( pFields[i].CollatorLocale );
+ aKeys[i]->sSortType = pFields[i].CollatorAlgorithm;
+ aKeys[i]->nColumnId =
+ o3tl::narrowing<sal_uInt16>(pFields[i].Field);
+ aKeys[i]->bIsNumeric = (pFields[i].FieldType ==
+ table::TableSortFieldType_NUMERIC);
+ aKeys[i]->eSortOrder = (pFields[i].IsAscending)
+ ? SwSortOrder::Ascending : SwSortOrder::Descending;
+ }
+ }
+ else
+ {
+ bRet = false;
+ }
+ }
+ else
+ {
+ bRet = false;
+ }
+ }
+ }
+
+ if (bNewSortdescriptor && bOldSortdescriptor)
+ {
+ OSL_FAIL("someone tried to set the old deprecated and "
+ "the new sortdescriptor");
+ bRet = false;
+ }
+
+ if (aKey1.nColumnId != USHRT_MAX)
+ {
+ rSortOpt.aKeys.push_back(aKey1);
+ }
+ if (aKey2.nColumnId != USHRT_MAX)
+ {
+ rSortOpt.aKeys.push_back(aKey2);
+ }
+ if (aKey3.nColumnId != USHRT_MAX)
+ {
+ rSortOpt.aKeys.push_back(aKey3);
+ }
+
+ return bRet && !rSortOpt.aKeys.empty();
+}
+
+void SAL_CALL
+SwXTextCursor::sort(const uno::Sequence< beans::PropertyValue >& rDescriptor)
+{
+ SolarMutexGuard aGuard;
+
+ SwUnoCursor & rUnoCursor( GetCursorOrThrow() );
+
+ if (!rUnoCursor.HasMark())
+ return;
+
+ SwSortOptions aSortOpt;
+ if (!SwUnoCursorHelper::ConvertSortProperties(rDescriptor, aSortOpt))
+ {
+ throw uno::RuntimeException("Bad sort properties");
+ }
+ UnoActionContext aContext( &rUnoCursor.GetDoc() );
+
+ SwPosition & rStart = *rUnoCursor.Start();
+ SwPosition & rEnd = *rUnoCursor.End();
+
+ SwNodeIndex aPrevIdx( rStart.GetNode(), -1 );
+ const SwNodeOffset nOffset = rEnd.GetNodeIndex() - rStart.GetNodeIndex();
+ const sal_Int32 nCntStt = rStart.GetContentIndex();
+
+ rUnoCursor.GetDoc().SortText(rUnoCursor, aSortOpt);
+
+ // update selection
+ rUnoCursor.DeleteMark();
+ rUnoCursor.GetPoint()->Assign( aPrevIdx.GetNode(), SwNodeOffset(1) );
+ SwContentNode *const pCNd = rUnoCursor.GetPointContentNode();
+ sal_Int32 nLen = pCNd->Len();
+ if (nLen > nCntStt)
+ {
+ nLen = nCntStt;
+ }
+ rUnoCursor.GetPoint()->SetContent( nLen );
+ rUnoCursor.SetMark();
+
+ rUnoCursor.GetPoint()->Adjust(nOffset);
+ SwContentNode *const pCNd2 = rUnoCursor.GetPointContentNode();
+ rUnoCursor.GetPoint()->SetContent( pCNd2->Len() );
+
+}
+
+uno::Reference< container::XEnumeration > SAL_CALL
+SwXTextCursor::createContentEnumeration(const OUString& rServiceName)
+{
+ SolarMutexGuard g;
+ if (rServiceName != "com.sun.star.text.TextContent")
+ throw uno::RuntimeException();
+ SwUnoCursor& rUnoCursor( GetCursorOrThrow() );
+ return SwXParaFrameEnumeration::Create(rUnoCursor, PARAFRAME_PORTION_TEXTRANGE);
+}
+
+uno::Reference< container::XEnumeration > SAL_CALL
+SwXTextCursor::createEnumeration()
+{
+ SolarMutexGuard g;
+
+ SwUnoCursor & rUnoCursor( GetCursorOrThrow() );
+
+ SwXText* pParentText = dynamic_cast<SwXText*>(m_xParentText.get());
+ OSL_ENSURE(pParentText, "parent is not a SwXText");
+ if (!pParentText)
+ {
+ throw uno::RuntimeException();
+ }
+
+ auto pNewCursor(rUnoCursor.GetDoc().CreateUnoCursor(*rUnoCursor.GetPoint()) );
+ if (rUnoCursor.HasMark())
+ {
+ pNewCursor->SetMark();
+ *pNewCursor->GetMark() = *rUnoCursor.GetMark();
+ }
+ const CursorType eSetType = (CursorType::TableText == m_eType)
+ ? CursorType::SelectionInTable : CursorType::Selection;
+ return SwXParagraphEnumeration::Create(pParentText, pNewCursor, eSetType);
+}
+
+uno::Type SAL_CALL
+SwXTextCursor::getElementType()
+{
+ return cppu::UnoType<text::XTextRange>::get();
+}
+
+sal_Bool SAL_CALL SwXTextCursor::hasElements()
+{
+ return true;
+}
+
+uno::Sequence< OUString > SAL_CALL
+SwXTextCursor::getAvailableServiceNames()
+{
+ uno::Sequence<OUString> aRet { "com.sun.star.text.TextContent" };
+ return aRet;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/core/unocore/unoobj2.cxx b/sw/source/core/unocore/unoobj2.cxx
new file mode 100644
index 0000000000..7614f0a314
--- /dev/null
+++ b/sw/source/core/unocore/unoobj2.cxx
@@ -0,0 +1,1860 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <sal/config.h>
+
+#include <comphelper/servicehelper.hxx>
+#include <cppuhelper/supportsservice.hxx>
+#include <o3tl/safeint.hxx>
+#include <svl/listener.hxx>
+#include <svx/svdobj.hxx>
+#include <utility>
+#include <vcl/svapp.hxx>
+
+#include <anchoredobject.hxx>
+#include <swtypes.hxx>
+#include <hintids.hxx>
+#include <IMark.hxx>
+#include <frmfmt.hxx>
+#include <doc.hxx>
+#include <IDocumentUndoRedo.hxx>
+#include <IDocumentLayoutAccess.hxx>
+#include <IDocumentMarkAccess.hxx>
+#include <textboxhelper.hxx>
+#include <ndtxt.hxx>
+#include <unocrsr.hxx>
+#include <unotextcursor.hxx>
+#include <swundo.hxx>
+#include <rootfrm.hxx>
+#include <ftnidx.hxx>
+#include <pam.hxx>
+#include <swtblfmt.hxx>
+#include <docsh.hxx>
+#include <pagedesc.hxx>
+#include <cntfrm.hxx>
+#include <flyfrm.hxx>
+#include <flyfrms.hxx>
+#include <unoparaframeenum.hxx>
+#include <unofootnote.hxx>
+#include <unotextbodyhf.hxx>
+#include <unotextrange.hxx>
+#include <unoparagraph.hxx>
+#include <unomap.hxx>
+#include <unoport.hxx>
+#include <unocrsrhelper.hxx>
+#include <unotbl.hxx>
+#include <fmtanchr.hxx>
+#include <flypos.hxx>
+#include <txtftn.hxx>
+#include <fmtftn.hxx>
+#include <fmtcntnt.hxx>
+#include <com/sun/star/text/XTextDocument.hpp>
+#include <com/sun/star/lang/IndexOutOfBoundsException.hpp>
+#include <unoframe.hxx>
+#include <fmthdft.hxx>
+#include <fmtflcnt.hxx>
+#include <vector>
+#include <sortedobjs.hxx>
+#include <frameformats.hxx>
+#include <algorithm>
+#include <iterator>
+
+using namespace ::com::sun::star;
+
+namespace sw {
+
+void DeepCopyPaM(SwPaM const & rSource, SwPaM & rTarget)
+{
+ rTarget = rSource;
+
+ if (rSource.GetNext() == &rSource)
+ return;
+
+ SwPaM *pPam = const_cast<SwPaM*>(rSource.GetNext());
+ do
+ {
+ // create new PaM
+ SwPaM *const pNew = new SwPaM(*pPam, nullptr);
+ // insert into ring
+ pNew->MoveTo(&rTarget);
+ pPam = pPam->GetNext();
+ }
+ while (pPam != &rSource);
+}
+
+} // namespace sw
+
+namespace {
+
+struct FrameClientSortListLess
+{
+ bool operator() (FrameClientSortListEntry const& r1,
+ FrameClientSortListEntry const& r2) const
+ {
+ return (r1.nIndex < r2.nIndex)
+ || ((r1.nIndex == r2.nIndex) && (r1.nOrder < r2.nOrder));
+ }
+};
+
+ void lcl_CollectFrameAtNodeWithLayout(const SwContentFrame* pCFrame,
+ FrameClientSortList_t& rFrames,
+ const RndStdIds nAnchorType)
+ {
+ auto pObjs = pCFrame->GetDrawObjs();
+ if(!pObjs)
+ return;
+ for(const auto pAnchoredObj : *pObjs)
+ {
+ SwFrameFormat& rFormat = pAnchoredObj->GetFrameFormat();
+ // Filter out textboxes, which are not interesting at a UNO level.
+ if(SwTextBoxHelper::isTextBox(&rFormat, RES_FLYFRMFMT))
+ continue;
+
+ if (nAnchorType == RndStdIds::FLY_AT_PARA)
+ {
+ auto pFlyAtContentFrame = dynamic_cast<SwFlyAtContentFrame*>(pAnchoredObj);
+ if (pFlyAtContentFrame && pFlyAtContentFrame->IsFollow())
+ {
+ // We're collecting frame formats, ignore non-master fly frames to prevent
+ // duplication.
+ continue;
+ }
+ }
+
+ if(rFormat.GetAnchor().GetAnchorId() == nAnchorType)
+ {
+ const sal_Int32 nIdx = rFormat.GetAnchor().GetAnchorContentOffset();
+ const auto nOrder = rFormat.GetAnchor().GetOrder();
+ rFrames.emplace_back(nIdx, nOrder, std::make_unique<sw::FrameClient>(&rFormat));
+ }
+ }
+ }
+}
+
+
+void CollectFrameAtNode( const SwNode& rNd,
+ FrameClientSortList_t& rFrames,
+ const bool bAtCharAnchoredObjs )
+{
+ // _bAtCharAnchoredObjs:
+ // <true>: at-character anchored objects are collected
+ // <false>: at-paragraph anchored objects are collected
+
+ // search all borders, images, and OLEs that are connected to the paragraph
+ const SwDoc& rDoc = rNd.GetDoc();
+
+ const auto nChkType = bAtCharAnchoredObjs ? RndStdIds::FLY_AT_CHAR : RndStdIds::FLY_AT_PARA;
+ const SwContentFrame* pCFrame;
+ const SwContentNode* pCNd;
+ if( rDoc.getIDocumentLayoutAccess().GetCurrentViewShell() &&
+ nullptr != (pCNd = rNd.GetContentNode()) &&
+ nullptr != (pCFrame = pCNd->getLayoutFrame( rDoc.getIDocumentLayoutAccess().GetCurrentLayout())) )
+ {
+ lcl_CollectFrameAtNodeWithLayout(pCFrame, rFrames, nChkType);
+ }
+ else
+ {
+ for(sw::SpzFrameFormat* pSpz: *rDoc.GetSpzFrameFormats())
+ {
+ const SwFormatAnchor& rAnchor = pSpz->GetAnchor();
+ const SwNode* pAnchorNode;
+ if( rAnchor.GetAnchorId() == nChkType &&
+ nullptr != (pAnchorNode = rAnchor.GetAnchorNode()) &&
+ *pAnchorNode == rNd )
+ {
+
+ // OD 2004-05-07 #i28701# - determine insert position for
+ // sorted <rFrameArr>
+ const sal_Int32 nIndex = rAnchor.GetAnchorContentOffset();
+ sal_uInt32 nOrder = rAnchor.GetOrder();
+
+ rFrames.emplace_back(nIndex, nOrder, std::make_unique<sw::FrameClient>(pSpz));
+ }
+ }
+ std::sort(rFrames.begin(), rFrames.end(), FrameClientSortListLess());
+ }
+}
+
+UnoActionContext::UnoActionContext(SwDoc *const pDoc)
+ : m_pDoc(pDoc)
+{
+ SwRootFrame *const pRootFrame = m_pDoc->getIDocumentLayoutAccess().GetCurrentLayout();
+ if (pRootFrame)
+ {
+ pRootFrame->StartAllAction();
+ }
+}
+
+UnoActionContext::~UnoActionContext() COVERITY_NOEXCEPT_FALSE
+{
+ // Doc may already have been removed here
+ if (m_pDoc)
+ {
+ SwRootFrame *const pRootFrame = m_pDoc->getIDocumentLayoutAccess().GetCurrentLayout();
+ if (pRootFrame)
+ {
+ pRootFrame->EndAllAction();
+ }
+ }
+}
+
+static void lcl_RemoveImpl(SwDoc *const pDoc)
+{
+ assert(pDoc);
+ SwRootFrame *const pRootFrame = pDoc->getIDocumentLayoutAccess().GetCurrentLayout();
+ if (pRootFrame)
+ {
+ pRootFrame->UnoRemoveAllActions();
+ }
+}
+
+UnoActionRemoveContext::UnoActionRemoveContext(SwDoc *const pDoc)
+ : m_pDoc(pDoc)
+{
+ lcl_RemoveImpl(m_pDoc);
+}
+
+static SwDoc * lcl_IsNewStyleTable(SwUnoTableCursor const& rCursor)
+{
+ SwTableNode *const pTableNode = rCursor.GetPointNode().FindTableNode();
+ return (pTableNode && !pTableNode->GetTable().IsNewModel())
+ ? &rCursor.GetDoc()
+ : nullptr;
+}
+
+UnoActionRemoveContext::UnoActionRemoveContext(SwUnoTableCursor const& rCursor)
+ : m_pDoc(lcl_IsNewStyleTable(rCursor))
+{
+ // this insanity is only necessary for old-style tables
+ // because SwRootFrame::MakeTableCursors() creates the table cursor for these
+ if (m_pDoc)
+ {
+ lcl_RemoveImpl(m_pDoc);
+ }
+}
+
+UnoActionRemoveContext::~UnoActionRemoveContext() COVERITY_NOEXCEPT_FALSE
+{
+ if (m_pDoc)
+ {
+ SwRootFrame *const pRootFrame = m_pDoc->getIDocumentLayoutAccess().GetCurrentLayout();
+ if (pRootFrame)
+ {
+ pRootFrame->UnoRestoreAllActions();
+ }
+ }
+}
+
+void SwUnoCursorHelper::SetCursorAttr(SwPaM & rPam,
+ const SfxItemSet& rSet,
+ const SetAttrMode nAttrMode, const bool bTableMode)
+{
+ const SetAttrMode nFlags = nAttrMode | SetAttrMode::APICALL;
+ SwDoc& rDoc = rPam.GetDoc();
+ //StartEndAction
+ UnoActionContext aAction(&rDoc);
+ if (rPam.GetNext() != &rPam) // Ring of Cursors
+ {
+ rDoc.GetIDocumentUndoRedo().StartUndo(SwUndoId::INSATTR, nullptr);
+
+ for(SwPaM& rCurrent : rPam.GetRingContainer())
+ {
+ if (rCurrent.HasMark() &&
+ ( bTableMode ||
+ (*rCurrent.GetPoint() != *rCurrent.GetMark()) ))
+ {
+ rDoc.getIDocumentContentOperations().InsertItemSet(rCurrent, rSet, nFlags);
+ }
+ }
+
+ rDoc.GetIDocumentUndoRedo().EndUndo(SwUndoId::INSATTR, nullptr);
+ }
+ else
+ {
+ rDoc.getIDocumentContentOperations().InsertItemSet( rPam, rSet, nFlags );
+ }
+
+ if( rSet.GetItemState( RES_PARATR_OUTLINELEVEL, false ) >= SfxItemState::DEFAULT )
+ {
+ SwTextNode * pTmpNode = rPam.GetPointNode().GetTextNode();
+ if ( pTmpNode )
+ {
+ rPam.GetDoc().GetNodes().UpdateOutlineNode( *pTmpNode );
+ }
+ }
+}
+
+// #i63870#
+// split third parameter <bCurrentAttrOnly> into new parameters <bOnlyTextAttr>
+// and <bGetFromChrFormat> to get better control about resulting <SfxItemSet>
+void SwUnoCursorHelper::GetCursorAttr(SwPaM & rPam,
+ SfxItemSet & rSet, const bool bOnlyTextAttr, const bool bGetFromChrFormat)
+{
+ static const sal_uLong nMaxLookup = 1000;
+ SfxItemSet aSet( *rSet.GetPool(), rSet.GetRanges() );
+ SfxItemSet *pSet = &rSet;
+ for(SwPaM& rCurrent : rPam.GetRingContainer())
+ {
+ SwPosition const & rStart( *rCurrent.Start() );
+ SwPosition const & rEnd( *rCurrent.End() );
+ const SwNodeOffset nSttNd = rStart.GetNodeIndex();
+ const SwNodeOffset nEndNd = rEnd .GetNodeIndex();
+
+ if (nEndNd - nSttNd >= SwNodeOffset(nMaxLookup))
+ {
+ rSet.ClearItem();
+ rSet.InvalidateAllItems();
+ return;// uno::Any();
+ }
+
+ // the first node inserts the values into the get set
+ // all other nodes merge their values into the get set
+ for (SwNodeOffset n = nSttNd; n <= nEndNd; ++n)
+ {
+ SwNode *const pNd = rPam.GetDoc().GetNodes()[ n ];
+ switch (pNd->GetNodeType())
+ {
+ case SwNodeType::Text:
+ {
+ const sal_Int32 nStart = (n == nSttNd)
+ ? rStart.GetContentIndex() : 0;
+ const sal_Int32 nEnd = (n == nEndNd)
+ ? rEnd.GetContentIndex()
+ : pNd->GetTextNode()->GetText().getLength();
+ pNd->GetTextNode()->GetParaAttr(*pSet, nStart, nEnd, bOnlyTextAttr, bGetFromChrFormat);
+ }
+ break;
+
+ case SwNodeType::Grf:
+ case SwNodeType::Ole:
+ static_cast<SwContentNode*>(pNd)->GetAttr( *pSet );
+ break;
+
+ default:
+ continue; // skip this node
+ }
+
+ if (pSet != &rSet)
+ {
+ rSet.MergeValues( aSet );
+ }
+ else
+ {
+ pSet = &aSet;
+ }
+
+ if (aSet.Count())
+ {
+ aSet.ClearItem();
+ }
+ }
+ }
+}
+
+namespace {
+
+struct SwXParagraphEnumerationImpl final : public SwXParagraphEnumeration
+{
+ uno::Reference< text::XText > const m_xParentText;
+ const CursorType m_eCursorType;
+ /// Start node of the cell _or_ table the enumeration belongs to.
+ /// Used to restrict the movement of the UNO cursor to the cell and its
+ /// embedded tables.
+ SwStartNode const*const m_pOwnStartNode;
+ SwTable const*const m_pOwnTable;
+ const SwNodeOffset m_nEndIndex;
+ sal_Int32 m_nFirstParaStart;
+ sal_Int32 m_nLastParaEnd;
+ bool m_bFirstParagraph;
+ uno::Reference< text::XTextContent > m_xNextPara;
+ sw::UnoCursorPointer m_pCursor;
+
+ SwXParagraphEnumerationImpl(
+ uno::Reference< text::XText > xParent,
+ const std::shared_ptr<SwUnoCursor>& pCursor,
+ const CursorType eType,
+ SwStartNode const*const pStartNode, SwTable const*const pTable)
+ : m_xParentText(std::move( xParent ))
+ , m_eCursorType( eType )
+ // remember table and start node for later travelling
+ // (used in export of tables in tables)
+ , m_pOwnStartNode( pStartNode )
+ // for import of tables in tables we have to remember the actual
+ // table and start node of the current position in the enumeration.
+ , m_pOwnTable( pTable )
+ , m_nEndIndex( pCursor->End()->GetNodeIndex() )
+ , m_nFirstParaStart( -1 )
+ , m_nLastParaEnd( -1 )
+ , m_bFirstParagraph( true )
+ , m_pCursor(pCursor)
+ {
+ OSL_ENSURE(m_xParentText.is(), "SwXParagraphEnumeration: no parent?");
+ assert( !((CursorType::SelectionInTable == eType)
+ || (CursorType::TableText == eType))
+ || (m_pOwnTable && m_pOwnStartNode));
+
+ if ((CursorType::Selection == m_eCursorType) ||
+ (CursorType::SelectionInTable == m_eCursorType))
+ {
+ SwUnoCursor & rCursor = GetCursor();
+ rCursor.Normalize();
+ m_nFirstParaStart = rCursor.GetPoint()->GetContentIndex();
+ m_nLastParaEnd = rCursor.GetMark()->GetContentIndex();
+ rCursor.DeleteMark();
+ }
+ }
+
+ virtual ~SwXParagraphEnumerationImpl() override
+ { m_pCursor.reset(nullptr); }
+ virtual void SAL_CALL release() noexcept override
+ {
+ SolarMutexGuard g;
+ OWeakObject::release();
+ }
+
+ // XServiceInfo
+ virtual OUString SAL_CALL getImplementationName() override
+ { return "SwXParagraphEnumeration"; }
+ virtual sal_Bool SAL_CALL supportsService( const OUString& rServiceName) override
+ { return cppu::supportsService(this, rServiceName); };
+ virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() override
+ { return {"com.sun.star.text.ParagraphEnumeration"}; };
+
+ // XEnumeration
+ virtual sal_Bool SAL_CALL hasMoreElements() override;
+ virtual css::uno::Any SAL_CALL nextElement() override;
+
+ SwUnoCursor& GetCursor()
+ { return *m_pCursor; }
+ /// @throws container::NoSuchElementException
+ /// @throws lang::WrappedTargetException
+ /// @throws uno::RuntimeException
+ uno::Reference< text::XTextContent > NextElement_Impl();
+
+ /**
+ * Determines if the last element in the enumeration should be ignored or
+ * not.
+ */
+ bool IgnoreLastElement(SwUnoCursor& rCursor, bool bMovedFromTable);
+};
+
+}
+
+rtl::Reference<SwXParagraphEnumeration> SwXParagraphEnumeration::Create(
+ uno::Reference< text::XText > const& xParent,
+ const std::shared_ptr<SwUnoCursor>& pCursor,
+ const CursorType eType,
+ SwTableBox const*const pTableBox)
+{
+ SwStartNode const* pStartNode(nullptr);
+ SwTable const* pTable(nullptr);
+ assert((eType == CursorType::TableText) == (pTableBox != nullptr));
+ switch (eType)
+ {
+ case CursorType::TableText:
+ {
+ pStartNode = pTableBox->GetSttNd();
+ pTable = & pStartNode->FindTableNode()->GetTable();
+ break;
+ }
+ case CursorType::SelectionInTable:
+ {
+ SwTableNode const*const pTableNode(
+ pCursor->GetPoint()->GetNode().FindTableNode());
+ pStartNode = pTableNode;
+ pTable = & pTableNode->GetTable();
+ break;
+ }
+ default:
+ break;
+ }
+ return new SwXParagraphEnumerationImpl(xParent, pCursor, eType, pStartNode, pTable);
+}
+
+sal_Bool SAL_CALL
+SwXParagraphEnumerationImpl::hasMoreElements()
+{
+ SolarMutexGuard aGuard;
+ return m_bFirstParagraph || m_xNextPara.is();
+}
+
+//!! compare to SwShellTableCursor::FillRects() in viscrs.cxx
+static SwTableNode *
+lcl_FindTopLevelTable(
+ SwTableNode *const pTableNode, SwTable const*const pOwnTable)
+{
+ // find top-most table in current context (section) level
+
+ SwTableNode * pLast = pTableNode;
+ for (SwTableNode* pTmp = pLast;
+ pTmp != nullptr && &pTmp->GetTable() != pOwnTable; /* we must not go up higher than the own table! */
+ pTmp = pTmp->StartOfSectionNode()->FindTableNode() )
+ {
+ pLast = pTmp;
+ }
+ return pLast;
+}
+
+static bool
+lcl_CursorIsInSection(
+ SwUnoCursor const*const pUnoCursor, SwStartNode const*const pOwnStartNode)
+{
+ // returns true if the cursor is in the section (or in a sub section!)
+ // represented by pOwnStartNode
+
+ bool bRes = true;
+ if (pUnoCursor && pOwnStartNode)
+ {
+ const SwEndNode * pOwnEndNode = pOwnStartNode->EndOfSectionNode();
+ bRes = pOwnStartNode->GetIndex() <= pUnoCursor->Start()->GetNodeIndex() &&
+ pUnoCursor->End()->GetNodeIndex() <= pOwnEndNode->GetIndex();
+ }
+ return bRes;
+}
+
+bool SwXParagraphEnumerationImpl::IgnoreLastElement(SwUnoCursor& rCursor, bool bMovedFromTable)
+{
+ // Ignore the last element of a selection enumeration if this is a stub
+ // paragraph (directly after table, selection ends at paragraph start).
+
+ if (rCursor.Start()->GetNodeIndex() != m_nEndIndex)
+ return false;
+
+ if (m_eCursorType != CursorType::Selection)
+ return false;
+
+ if (!bMovedFromTable)
+ return false;
+
+ return m_nLastParaEnd == 0;
+}
+
+uno::Reference< text::XTextContent >
+SwXParagraphEnumerationImpl::NextElement_Impl()
+{
+ SwUnoCursor& rUnoCursor = GetCursor();
+
+ // check for exceeding selections
+ if (!m_bFirstParagraph &&
+ ((CursorType::Selection == m_eCursorType) ||
+ (CursorType::SelectionInTable == m_eCursorType)))
+ {
+ SwPosition* pStart = rUnoCursor.Start();
+ auto aNewCursor(rUnoCursor.GetDoc().CreateUnoCursor(*pStart));
+ // one may also go into tables here
+ if (CursorType::SelectionInTable != m_eCursorType)
+ {
+ aNewCursor->SetRemainInSection( false );
+ }
+
+ // os 2005-01-14: This part is only necessary to detect movements out
+ // of a selection; if there is no selection we don't have to care
+ SwTableNode *const pTableNode = aNewCursor->GetPointNode().FindTableNode();
+ bool bMovedFromTable = false;
+ if (CursorType::SelectionInTable != m_eCursorType && pTableNode)
+ {
+ aNewCursor->GetPoint()->Assign( pTableNode->EndOfSectionIndex() );
+ aNewCursor->Move(fnMoveForward, GoInNode);
+ bMovedFromTable = true;
+ }
+ else
+ {
+ aNewCursor->MovePara(GoNextPara, fnParaStart);
+ }
+ if (m_nEndIndex < aNewCursor->Start()->GetNodeIndex())
+ {
+ return nullptr;
+ }
+
+ if (IgnoreLastElement(*aNewCursor, bMovedFromTable))
+ {
+ return nullptr;
+ }
+ }
+
+ bool bInTable = false;
+ if (!m_bFirstParagraph)
+ {
+ rUnoCursor.SetRemainInSection( false );
+ // what to do if already in a table?
+ SwTableNode * pTableNode = rUnoCursor.GetPointNode().FindTableNode();
+ pTableNode = lcl_FindTopLevelTable( pTableNode, m_pOwnTable );
+ if (pTableNode && (&pTableNode->GetTable() != m_pOwnTable))
+ {
+ // this is a foreign table: go to end
+ rUnoCursor.GetPoint()->Assign( pTableNode->EndOfSectionIndex() );
+ if (!rUnoCursor.Move(fnMoveForward, GoInNode))
+ {
+ return nullptr;
+ }
+ bInTable = true;
+ }
+ }
+
+ uno::Reference< text::XTextContent > xRef;
+ // the cursor must remain in the current section or a subsection
+ // before AND after the movement...
+ if (lcl_CursorIsInSection( &rUnoCursor, m_pOwnStartNode ) &&
+ (m_bFirstParagraph || bInTable ||
+ (rUnoCursor.MovePara(GoNextPara, fnParaStart) &&
+ lcl_CursorIsInSection( &rUnoCursor, m_pOwnStartNode ))))
+ {
+ if (m_eCursorType == CursorType::Selection || m_eCursorType == CursorType::SelectionInTable)
+ {
+ // This is a selection, check if the cursor would go past the end
+ // of the selection.
+ if (rUnoCursor.Start()->GetNodeIndex() > m_nEndIndex)
+ return nullptr;
+ }
+
+ SwPosition* pStart = rUnoCursor.Start();
+ const sal_Int32 nFirstContent =
+ m_bFirstParagraph ? m_nFirstParaStart : -1;
+ const sal_Int32 nLastContent =
+ (m_nEndIndex == pStart->GetNodeIndex()) ? m_nLastParaEnd : -1;
+
+ // position in a table, or in a simple paragraph?
+ SwTableNode * pTableNode = rUnoCursor.GetPointNode().FindTableNode();
+ pTableNode = lcl_FindTopLevelTable( pTableNode, m_pOwnTable );
+ if (/*CursorType::TableText != eCursorType && CursorType::SelectionInTable != eCursorType && */
+ pTableNode && (&pTableNode->GetTable() != m_pOwnTable))
+ {
+ // this is a foreign table
+ SwFrameFormat* pTableFormat = pTableNode->GetTable().GetFrameFormat();
+ xRef = SwXTextTable::CreateXTextTable(pTableFormat);
+ }
+ else
+ {
+ text::XText *const pText = m_xParentText.get();
+ xRef = SwXParagraph::CreateXParagraph(rUnoCursor.GetDoc(),
+ pStart->GetNode().GetTextNode(),
+ static_cast<SwXText*>(pText), nFirstContent, nLastContent);
+ }
+ }
+
+ return xRef;
+}
+
+uno::Any SAL_CALL SwXParagraphEnumerationImpl::nextElement()
+{
+ SolarMutexGuard aGuard;
+ if (m_bFirstParagraph)
+ {
+ m_xNextPara = NextElement_Impl();
+ m_bFirstParagraph = false;
+ }
+ const uno::Reference< text::XTextContent > xRef = m_xNextPara;
+ if (!xRef.is())
+ {
+ throw container::NoSuchElementException();
+ }
+ m_xNextPara = NextElement_Impl();
+
+ uno::Any aRet;
+ aRet <<= xRef;
+ return aRet;
+}
+
+class SwXTextRange::Impl
+ : public SvtListener
+{
+public:
+ const SfxItemPropertySet& m_rPropSet;
+ const enum RangePosition m_eRangePosition;
+ SwDoc& m_rDoc;
+ uno::Reference<text::XText> m_xParentText;
+ const SwFrameFormat* m_pTableOrSectionFormat;
+ const ::sw::mark::IMark* m_pMark;
+
+ Impl(SwDoc& rDoc, const enum RangePosition eRange,
+ SwFrameFormat* const pTableOrSectionFormat,
+ uno::Reference<text::XText> xParent = nullptr)
+ : m_rPropSet(*aSwMapProvider.GetPropertySet(PROPERTY_MAP_TEXT_CURSOR))
+ , m_eRangePosition(eRange)
+ , m_rDoc(rDoc)
+ , m_xParentText(std::move(xParent))
+ , m_pTableOrSectionFormat(pTableOrSectionFormat)
+ , m_pMark(nullptr)
+ {
+ if (m_pTableOrSectionFormat)
+ {
+ assert(m_eRangePosition == RANGE_IS_TABLE || m_eRangePosition == RANGE_IS_SECTION);
+ StartListening(pTableOrSectionFormat->GetNotifier());
+ }
+ else
+ {
+ assert(m_eRangePosition != RANGE_IS_TABLE && m_eRangePosition != RANGE_IS_SECTION);
+ }
+ }
+
+ virtual ~Impl() override
+ {
+ // Impl owns the bookmark; delete it here: SolarMutex is locked
+ Invalidate();
+ }
+
+ void Invalidate()
+ {
+ if (m_pMark)
+ {
+ m_rDoc.getIDocumentMarkAccess()->deleteMark(m_pMark);
+ m_pMark = nullptr;
+ }
+ m_pTableOrSectionFormat = nullptr;
+ EndListeningAll();
+ }
+
+ const ::sw::mark::IMark* GetBookmark() const { return m_pMark; }
+ void SetMark(::sw::mark::IMark& rMark)
+ {
+ EndListeningAll();
+ m_pTableOrSectionFormat = nullptr;
+ m_pMark = &rMark;
+ StartListening(rMark.GetNotifier());
+ }
+
+protected:
+ virtual void Notify(const SfxHint&) override;
+};
+
+void SwXTextRange::Impl::Notify(const SfxHint& rHint)
+{
+ if(rHint.GetId() == SfxHintId::Dying)
+ {
+ EndListeningAll();
+ m_pTableOrSectionFormat = nullptr;
+ m_pMark = nullptr;
+ }
+}
+
+SwXTextRange::SwXTextRange(SwPaM const & rPam,
+ const uno::Reference< text::XText > & xParent,
+ const enum RangePosition eRange)
+ : m_pImpl( new SwXTextRange::Impl(rPam.GetDoc(), eRange, nullptr, xParent) )
+{
+ SetPositions(rPam);
+}
+
+SwXTextRange::SwXTextRange(SwTableFormat& rTableFormat)
+ : m_pImpl(
+ new SwXTextRange::Impl(*rTableFormat.GetDoc(), RANGE_IS_TABLE, &rTableFormat) )
+{
+ SwTable *const pTable = SwTable::FindTable( &rTableFormat );
+ SwTableNode *const pTableNode = pTable->GetTableNode();
+ SwPaM aPam( *pTableNode );
+
+ SetPositions( aPam );
+}
+
+SwXTextRange::SwXTextRange(SwSectionFormat& rSectionFormat)
+ : m_pImpl(
+ new SwXTextRange::Impl(*rSectionFormat.GetDoc(), RANGE_IS_SECTION, &rSectionFormat) )
+{
+ // no SetPositions here for now
+}
+
+SwXTextRange::~SwXTextRange()
+{
+}
+
+const SwDoc& SwXTextRange::GetDoc() const
+{
+ return m_pImpl->m_rDoc;
+}
+
+SwDoc& SwXTextRange::GetDoc()
+{
+ return m_pImpl->m_rDoc;
+}
+
+void SwXTextRange::Invalidate()
+{
+ m_pImpl->Invalidate();
+}
+
+void SwXTextRange::SetPositions(const SwPaM& rPam)
+{
+ m_pImpl->Invalidate();
+ IDocumentMarkAccess* const pMA = m_pImpl->m_rDoc.getIDocumentMarkAccess();
+ auto pMark = pMA->makeMark(rPam, OUString(), IDocumentMarkAccess::MarkType::UNO_BOOKMARK, sw::mark::InsertMode::New);
+ if (pMark)
+ m_pImpl->SetMark(*pMark);
+}
+
+static void DeleteTable(SwDoc & rDoc, SwTable& rTable)
+{
+ SwSelBoxes aSelBoxes;
+ for (auto& rBox : rTable.GetTabSortBoxes())
+ {
+ aSelBoxes.insert(rBox);
+ }
+ // note: if the table is the content in the section, this will create
+ // a new text node - that's desirable here
+ rDoc.DeleteRowCol(aSelBoxes, SwDoc::RowColMode::DeleteProtected);
+}
+
+void SwXTextRange::DeleteAndInsert(
+ std::u16string_view aText, ::sw::DeleteAndInsertMode const eMode)
+{
+ if (RANGE_IS_TABLE == m_pImpl->m_eRangePosition)
+ {
+ // setString on table not allowed
+ throw uno::RuntimeException("not possible for table");
+ }
+
+ const SwPosition aPos(GetDoc().GetNodes().GetEndOfContent());
+ SwCursor aCursor(aPos, nullptr);
+
+ UnoActionContext aAction(& m_pImpl->m_rDoc);
+
+ if (RANGE_IS_SECTION == m_pImpl->m_eRangePosition)
+ {
+ SwSectionNode const* pSectionNode = m_pImpl->m_pTableOrSectionFormat ?
+ static_cast<SwSectionFormat const*>(m_pImpl->m_pTableOrSectionFormat)->GetSectionNode() :
+ nullptr;
+ if (!pSectionNode)
+ {
+ throw uno::RuntimeException("disposed?");
+ }
+ m_pImpl->m_rDoc.GetIDocumentUndoRedo().StartUndo(SwUndoId::INSERT, nullptr);
+ SwNodeIndex const start(*pSectionNode);
+ SwNodeIndex const end(*start.GetNode().EndOfSectionNode());
+
+ // delete tables at start
+ for (SwNodeIndex i = start; i < end; )
+ {
+ SwNode & rNode(i.GetNode());
+ if (rNode.IsSectionNode())
+ {
+ ++i;
+ continue;
+ }
+ else if (SwTableNode *const pTableNode = rNode.GetTableNode())
+ {
+ DeleteTable(m_pImpl->m_rDoc, pTableNode->GetTable());
+ // where does that leave index? presumably behind?
+ }
+ else
+ {
+ assert(rNode.IsTextNode());
+ break;
+ }
+ }
+ // delete tables at end
+ for (SwNodeIndex i = end; start <= i; )
+ {
+ --i;
+ SwNode & rNode(i.GetNode());
+ if (rNode.IsEndNode())
+ {
+ if (SwTableNode *const pTableNode = rNode.StartOfSectionNode()->GetTableNode())
+ {
+ DeleteTable(m_pImpl->m_rDoc, pTableNode->GetTable());
+ }
+ else
+ {
+ assert(rNode.StartOfSectionNode()->IsSectionNode());
+ continue;
+ }
+ }
+ else
+ {
+ assert(rNode.IsTextNode());
+ break;
+ }
+ }
+ // now there should be a text node at the start and end of it!
+ aCursor.GetPoint()->Assign(start);
+ aCursor.Move( fnMoveForward, GoInContent );
+ assert(aCursor.GetPoint()->GetNode() <= end.GetNode());
+ aCursor.SetMark();
+ aCursor.GetPoint()->Assign(end);
+ aCursor.Move( fnMoveBackward, GoInContent );
+ assert(start <= aCursor.GetPoint()->GetNode());
+ }
+ else
+ {
+ if (!GetPositions(aCursor))
+ return;
+ m_pImpl->m_rDoc.GetIDocumentUndoRedo().StartUndo(SwUndoId::INSERT, nullptr);
+ }
+
+ if (aCursor.HasMark())
+ {
+ m_pImpl->m_rDoc.getIDocumentContentOperations().DeleteAndJoin(aCursor,
+ (!aText.empty() || eMode & ::sw::DeleteAndInsertMode::ForceReplace) ? SwDeleteFlags::ArtificialSelection : SwDeleteFlags::Default);
+ }
+
+ if (!aText.empty())
+ {
+ SwUnoCursorHelper::DocInsertStringSplitCR(
+ m_pImpl->m_rDoc, aCursor, aText, bool(eMode & ::sw::DeleteAndInsertMode::ForceExpandHints));
+
+ SwUnoCursorHelper::SelectPam(aCursor, true);
+ aCursor.Left(aText.size());
+ }
+ SetPositions(aCursor);
+ m_pImpl->m_rDoc.GetIDocumentUndoRedo().EndUndo(SwUndoId::INSERT, nullptr);
+}
+
+OUString SAL_CALL
+SwXTextRange::getImplementationName()
+{
+ return "SwXTextRange";
+}
+
+sal_Bool SAL_CALL SwXTextRange::supportsService(const OUString& rServiceName)
+{
+ return cppu::supportsService(this, rServiceName);
+}
+
+uno::Sequence< OUString > SAL_CALL
+SwXTextRange::getSupportedServiceNames()
+{
+ return {
+ "com.sun.star.text.TextRange",
+ "com.sun.star.style.CharacterProperties",
+ "com.sun.star.style.CharacterPropertiesAsian",
+ "com.sun.star.style.CharacterPropertiesComplex",
+ "com.sun.star.style.ParagraphProperties",
+ "com.sun.star.style.ParagraphPropertiesAsian",
+ "com.sun.star.style.ParagraphPropertiesComplex"
+ };
+}
+
+uno::Reference< text::XText > SAL_CALL
+SwXTextRange::getText()
+{
+ SolarMutexGuard aGuard;
+
+ if (!m_pImpl->m_xParentText.is() && m_pImpl->m_pTableOrSectionFormat)
+ {
+ std::optional<SwPosition> oPosition;
+ if (m_pImpl->m_eRangePosition == RANGE_IS_TABLE)
+ {
+ SwTable const*const pTable = SwTable::FindTable( m_pImpl->m_pTableOrSectionFormat );
+ SwTableNode const*const pTableNode = pTable->GetTableNode();
+ oPosition.emplace(*pTableNode);
+ }
+ else
+ {
+ assert(m_pImpl->m_eRangePosition == RANGE_IS_SECTION);
+ auto const pSectFormat(static_cast<SwSectionFormat const*>(m_pImpl->m_pTableOrSectionFormat));
+ oPosition.emplace(pSectFormat->GetContent().GetContentIdx()->GetNode());
+ }
+ m_pImpl->m_xParentText =
+ ::sw::CreateParentXText(m_pImpl->m_rDoc, *oPosition);
+ }
+ OSL_ENSURE(m_pImpl->m_xParentText.is(), "SwXTextRange::getText: no text");
+ return m_pImpl->m_xParentText;
+}
+
+uno::Reference< text::XTextRange > SAL_CALL
+SwXTextRange::getStart()
+{
+ SolarMutexGuard aGuard;
+
+ uno::Reference< text::XTextRange > xRet;
+ ::sw::mark::IMark const * const pBkmk = m_pImpl->GetBookmark();
+ if (!m_pImpl->m_xParentText.is())
+ {
+ getText();
+ }
+ if(pBkmk)
+ {
+ SwPaM aPam(pBkmk->GetMarkStart());
+ xRet = new SwXTextRange(aPam, m_pImpl->m_xParentText);
+ }
+ else if (RANGE_IS_TABLE == m_pImpl->m_eRangePosition)
+ {
+ // start and end are this, if it's a table
+ xRet = this;
+ }
+ else if (RANGE_IS_SECTION == m_pImpl->m_eRangePosition
+ && m_pImpl->m_pTableOrSectionFormat)
+ {
+ auto const pSectFormat(static_cast<SwSectionFormat const*>(m_pImpl->m_pTableOrSectionFormat));
+ SwPaM aPaM(*pSectFormat->GetContent().GetContentIdx());
+ aPaM.Move( fnMoveForward, GoInContent );
+ assert(aPaM.GetPoint()->GetNode() < *pSectFormat->GetContent().GetContentIdx()->GetNode().EndOfSectionNode());
+ xRet = new SwXTextRange(aPaM, m_pImpl->m_xParentText);
+ }
+ else
+ {
+ throw uno::RuntimeException("disposed?");
+ }
+ return xRet;
+}
+
+uno::Reference< text::XTextRange > SAL_CALL
+SwXTextRange::getEnd()
+{
+ SolarMutexGuard aGuard;
+
+ uno::Reference< text::XTextRange > xRet;
+ ::sw::mark::IMark const * const pBkmk = m_pImpl->GetBookmark();
+ if (!m_pImpl->m_xParentText.is())
+ {
+ getText();
+ }
+ if(pBkmk)
+ {
+ SwPaM aPam(pBkmk->GetMarkEnd());
+ xRet = new SwXTextRange(aPam, m_pImpl->m_xParentText);
+ }
+ else if (RANGE_IS_TABLE == m_pImpl->m_eRangePosition)
+ {
+ // start and end are this, if it's a table
+ xRet = this;
+ }
+ else if (RANGE_IS_SECTION == m_pImpl->m_eRangePosition
+ && m_pImpl->m_pTableOrSectionFormat)
+ {
+ auto const pSectFormat(static_cast<SwSectionFormat const*>(m_pImpl->m_pTableOrSectionFormat));
+ SwPaM aPaM(*pSectFormat->GetContent().GetContentIdx()->GetNode().EndOfSectionNode());
+ aPaM.Move( fnMoveBackward, GoInContent );
+ assert(*pSectFormat->GetContent().GetContentIdx() < aPaM.GetPoint()->GetNode());
+ xRet = new SwXTextRange(aPaM, m_pImpl->m_xParentText);
+ }
+ else
+ {
+ throw uno::RuntimeException("disposed?");
+ }
+ return xRet;
+}
+
+OUString SAL_CALL SwXTextRange::getString()
+{
+ SolarMutexGuard aGuard;
+
+ OUString sRet;
+ // for tables there is no bookmark, thus also no text
+ // one could export the table as ASCII here maybe?
+ SwPaM aPaM(GetDoc().GetNodes());
+ if (GetPositions(aPaM, sw::TextRangeMode::AllowNonTextNode) && aPaM.HasMark())
+ {
+ SwUnoCursorHelper::GetTextFromPam(aPaM, sRet);
+ }
+ return sRet;
+}
+
+void SAL_CALL SwXTextRange::setString(const OUString& rString)
+{
+ SolarMutexGuard aGuard;
+
+ DeleteAndInsert(rString, ::sw::DeleteAndInsertMode::Default);
+}
+
+bool SwXTextRange::GetPositions(SwPaM& rToFill, ::sw::TextRangeMode const eMode) const
+{
+ if (RANGE_IS_SECTION == m_pImpl->m_eRangePosition)
+ {
+ if (auto const pSectFormat = static_cast<SwSectionFormat const*>(m_pImpl->m_pTableOrSectionFormat))
+ {
+ if (eMode == ::sw::TextRangeMode::AllowNonTextNode)
+ {
+ SwNodeIndex const*const pSectionNode(pSectFormat->GetContent().GetContentIdx());
+ assert(pSectionNode);
+ assert(pSectionNode->GetNodes().IsDocNodes());
+ rToFill.GetPoint()->Assign( pSectionNode->GetNode(), SwNodeOffset(1) );
+ rToFill.SetMark();
+ rToFill.GetMark()->Assign( *pSectionNode->GetNode().EndOfSectionNode(), SwNodeOffset(-1) );
+ if (const SwContentNode* pCNd = rToFill.GetMark()->GetContentNode())
+ rToFill.GetMark()->AssignEndIndex(*pCNd);
+ return true;
+ }
+ else
+ {
+ SwPaM aPaM(*pSectFormat->GetContent().GetContentIdx());
+ aPaM.Move(fnMoveForward, GoInContent);
+ assert(aPaM.GetPoint()->GetNode() < *pSectFormat->GetContent().GetContentIdx()->GetNode().EndOfSectionNode());
+ aPaM.SetMark();
+ *aPaM.GetPoint() = SwPosition(*pSectFormat->GetContent().GetContentIdx()->GetNode().EndOfSectionNode());
+ aPaM.Move(fnMoveBackward, GoInContent);
+ assert(*pSectFormat->GetContent().GetContentIdx() < aPaM.GetPoint()->GetNode());
+ // tdf#149555 if there is no table involved, only nested
+ // sections, then PaM is valid
+ if (aPaM.GetPoint()->GetNode().FindTableNode()
+ == aPaM.GetMark()->GetNode().FindTableNode())
+ {
+ rToFill = aPaM;
+ return true;
+ }
+ }
+ }
+ }
+ ::sw::mark::IMark const * const pBkmk = m_pImpl->GetBookmark();
+ if(pBkmk)
+ {
+ *rToFill.GetPoint() = pBkmk->GetMarkPos();
+ if(pBkmk->IsExpanded())
+ {
+ rToFill.SetMark();
+ *rToFill.GetMark() = pBkmk->GetOtherMarkPos();
+ }
+ else
+ {
+ rToFill.DeleteMark();
+ }
+ return true;
+ }
+ return false;
+}
+
+namespace sw {
+
+bool XTextRangeToSwPaM( SwUnoInternalPaM & rToFill,
+ const uno::Reference<text::XTextRange> & xTextRange,
+ ::sw::TextRangeMode const eMode)
+{
+ bool bRet = false;
+
+ SwXHeadFootText* pHeadText
+ = eMode == TextRangeMode::AllowTableNode ? dynamic_cast<SwXHeadFootText*>(xTextRange.get()) : nullptr;
+
+ // if it's a text then create a temporary cursor there and re-use
+ // the pCursor variable
+ // #i108489#: Reference in outside scope to keep cursor alive
+ rtl::Reference< SwXTextCursor > xTextCursor;
+ OTextCursorHelper* pCursor;
+ if (pHeadText)
+ {
+ // if it is a header / footer text, and eMode == TextRangeMode::AllowTableNode
+ // then set the cursor to the beginning of the text
+ // if it is started with a table then set into the table
+ xTextCursor = pHeadText->CreateTextCursor(true);
+ xTextCursor->gotoEnd(true);
+ pCursor = xTextCursor.get();
+ pCursor->GetPaM()->Normalize();
+ }
+ else if (SwXText* pText = dynamic_cast<SwXText*>(xTextRange.get()))
+ {
+ xTextCursor = pText->createXTextCursor();
+ xTextCursor->gotoEnd(true);
+ pCursor = xTextCursor.get();
+ }
+ else
+ {
+ pCursor = dynamic_cast<OTextCursorHelper*>(xTextRange.get());
+ }
+
+ SwXTextRange* pRange = dynamic_cast<SwXTextRange*>(xTextRange.get());
+ if(pRange && &pRange->GetDoc() == &rToFill.GetDoc())
+ {
+ bRet = pRange->GetPositions(rToFill, eMode);
+ }
+ else if (SwXParagraph* pPara = dynamic_cast<SwXParagraph*>(xTextRange.get()))
+ {
+ bRet = pPara->SelectPaM(rToFill);
+ }
+ else
+ {
+ SwDoc* pDoc = nullptr;
+ const SwPaM* pUnoCursor = nullptr;
+ if (pCursor)
+ {
+ pDoc = pCursor->GetDoc();
+ pUnoCursor = pCursor->GetPaM();
+ }
+ else if (SwXTextPortion* pPortion = dynamic_cast<SwXTextPortion*>(xTextRange.get()))
+ {
+ pDoc = &pPortion->GetCursor().GetDoc();
+ pUnoCursor = &pPortion->GetCursor();
+ }
+ if (pUnoCursor && pDoc == &rToFill.GetDoc())
+ {
+ OSL_ENSURE(!pUnoCursor->IsMultiSelection(),
+ "what to do about rings?");
+ bRet = true;
+ *rToFill.GetPoint() = *pUnoCursor->GetPoint();
+ if (pUnoCursor->HasMark())
+ {
+ rToFill.SetMark();
+ *rToFill.GetMark() = *pUnoCursor->GetMark();
+ }
+ else
+ rToFill.DeleteMark();
+ }
+ }
+ return bRet;
+}
+
+static bool
+lcl_IsStartNodeInFormat(const bool bHeader, SwStartNode const *const pSttNode,
+ SwFrameFormat const*const pFrameFormat, SwFrameFormat*& rpFormat)
+{
+ bool bRet = false;
+ const SfxItemSet& rSet = pFrameFormat->GetAttrSet();
+ const SfxPoolItem* pItem;
+ if (SfxItemState::SET == rSet.GetItemState(
+ bHeader ? sal_uInt16(RES_HEADER) : sal_uInt16(RES_FOOTER),
+ true, &pItem))
+ {
+ SfxPoolItem *const pItemNonConst(const_cast<SfxPoolItem *>(pItem));
+ SwFrameFormat *const pHeadFootFormat = bHeader ?
+ static_cast<SwFormatHeader*>(pItemNonConst)->GetHeaderFormat() :
+ static_cast<SwFormatFooter*>(pItemNonConst)->GetFooterFormat();
+ if (pHeadFootFormat)
+ {
+ const SwFormatContent& rFlyContent = pHeadFootFormat->GetContent();
+ // tdf#146248 avoid Undo crash at shared first page
+ if ( !rFlyContent.GetContentIdx() )
+ return false;
+ const SwNode& rNode = rFlyContent.GetContentIdx()->GetNode();
+ SwStartNode const*const pCurSttNode = rNode.FindSttNodeByType(
+ bHeader ? SwHeaderStartNode : SwFooterStartNode);
+ if (pCurSttNode && (pCurSttNode == pSttNode))
+ {
+ rpFormat = pHeadFootFormat;
+ bRet = true;
+ }
+ }
+ }
+ return bRet;
+}
+
+} // namespace sw
+
+rtl::Reference< SwXTextRange >
+SwXTextRange::CreateXTextRange(
+ SwDoc & rDoc, const SwPosition& rPos, const SwPosition *const pMark)
+{
+ const uno::Reference<text::XText> xParentText(
+ ::sw::CreateParentXText(rDoc, rPos));
+ const auto pNewCursor(rDoc.CreateUnoCursor(rPos));
+ if(pMark)
+ {
+ pNewCursor->SetMark();
+ *pNewCursor->GetMark() = *pMark;
+ }
+ const bool isCell( dynamic_cast<SwXCell*>(xParentText.get()) );
+ return new SwXTextRange(*pNewCursor, xParentText,
+ isCell ? RANGE_IN_CELL : RANGE_IN_TEXT);
+}
+
+namespace sw {
+
+css::uno::Reference< SwXText >
+CreateParentXText(SwDoc & rDoc, const SwPosition& rPos)
+{
+ css::uno::Reference< SwXText > xParentText;
+ SwStartNode* pSttNode = rPos.GetNode().StartOfSectionNode();
+ while(pSttNode && pSttNode->IsSectionNode())
+ {
+ pSttNode = pSttNode->StartOfSectionNode();
+ }
+ SwStartNodeType eType = pSttNode ? pSttNode->GetStartNodeType() : SwNormalStartNode;
+ switch(eType)
+ {
+ case SwTableBoxStartNode:
+ {
+ SwTableNode const*const pTableNode = pSttNode->FindTableNode();
+ SwFrameFormat *const pTableFormat =
+ pTableNode->GetTable().GetFrameFormat();
+ SwTableBox *const pBox = pSttNode->GetTableBox();
+
+ xParentText = pBox
+ ? SwXCell::CreateXCell( pTableFormat, pBox )
+ : new SwXCell( pTableFormat, *pSttNode );
+ }
+ break;
+ case SwFlyStartNode:
+ {
+ SwFrameFormat *const pFormat = pSttNode->GetFlyFormat();
+ if (nullptr != pFormat)
+ {
+ xParentText = SwXTextFrame::CreateXTextFrame(rDoc, pFormat);
+ }
+ }
+ break;
+ case SwHeaderStartNode:
+ case SwFooterStartNode:
+ {
+ const bool bHeader = (SwHeaderStartNode == eType);
+ const size_t nPDescCount = rDoc.GetPageDescCnt();
+ for(size_t i = 0; i < nPDescCount; i++)
+ {
+ const SwPageDesc& rDesc = rDoc.GetPageDesc( i );
+
+ const SwFrameFormat* pFrameFormatMaster = &rDesc.GetMaster();
+ const SwFrameFormat* pFrameFormatLeft = &rDesc.GetLeft();
+ const SwFrameFormat* pFrameFormatFirstMaster = &rDesc.GetFirstMaster();
+ const SwFrameFormat* pFrameFormatFirstLeft = &rDesc.GetFirstLeft();
+
+ SwFrameFormat* pHeadFootFormat = nullptr;
+ if (!lcl_IsStartNodeInFormat(bHeader, pSttNode, pFrameFormatMaster,
+ pHeadFootFormat))
+ {
+ if (!lcl_IsStartNodeInFormat(bHeader, pSttNode, pFrameFormatLeft,
+ pHeadFootFormat))
+ {
+ if (!lcl_IsStartNodeInFormat(bHeader, pSttNode, pFrameFormatFirstMaster,
+ pHeadFootFormat))
+ {
+ lcl_IsStartNodeInFormat(bHeader, pSttNode, pFrameFormatFirstLeft, pHeadFootFormat);
+ }
+ }
+ }
+
+ if (pHeadFootFormat)
+ {
+ xParentText = SwXHeadFootText::CreateXHeadFootText(
+ *pHeadFootFormat, bHeader);
+ }
+ }
+ }
+ break;
+ case SwFootnoteStartNode:
+ {
+ const size_t nFootnoteCnt = rDoc.GetFootnoteIdxs().size();
+ for (size_t n = 0; n < nFootnoteCnt; ++n )
+ {
+ const SwTextFootnote* pTextFootnote = rDoc.GetFootnoteIdxs()[ n ];
+ const SwFormatFootnote& rFootnote = pTextFootnote->GetFootnote();
+ pTextFootnote = rFootnote.GetTextFootnote();
+
+ if (pSttNode == pTextFootnote->GetStartNode()->GetNode().
+ FindSttNodeByType(SwFootnoteStartNode))
+ {
+ xParentText = SwXFootnote::CreateXFootnote(rDoc,
+ &const_cast<SwFormatFootnote&>(rFootnote));
+ break;
+ }
+ }
+ }
+ break;
+ default:
+ {
+ if (SwDocShell *const pDocSh = rDoc.GetDocShell())
+ {
+ // then it is the body text
+ const uno::Reference<frame::XModel> xModel = pDocSh->GetBaseModel();
+ const uno::Reference< text::XTextDocument > xDoc(
+ xModel, uno::UNO_QUERY);
+ xParentText = dynamic_cast<SwXText*>(xDoc->getText().get());
+ }
+ }
+ }
+ OSL_ENSURE(xParentText.is(), "no parent text?");
+ return xParentText;
+}
+
+} // namespace sw
+
+uno::Reference< container::XEnumeration > SAL_CALL
+SwXTextRange::createContentEnumeration(const OUString& rServiceName)
+{
+ SolarMutexGuard g;
+
+ if ( rServiceName != "com.sun.star.text.TextContent" )
+ {
+ throw uno::RuntimeException("unsupported service");
+ }
+
+ if (!m_pImpl->GetBookmark())
+ {
+ throw uno::RuntimeException("range has no mark (table?)");
+ }
+ const SwPosition aPos(GetDoc().GetNodes().GetEndOfContent());
+ const auto pNewCursor(m_pImpl->m_rDoc.CreateUnoCursor(aPos));
+ if (!GetPositions(*pNewCursor))
+ {
+ throw uno::RuntimeException("range has no positions");
+ }
+
+ return SwXParaFrameEnumeration::Create(*pNewCursor, PARAFRAME_PORTION_TEXTRANGE);
+}
+
+uno::Reference< container::XEnumeration > SAL_CALL
+SwXTextRange::createEnumeration()
+{
+ SolarMutexGuard g;
+
+ if (!m_pImpl->GetBookmark())
+ {
+ throw uno::RuntimeException("range has no mark (table?)");
+ }
+ const SwPosition aPos(GetDoc().GetNodes().GetEndOfContent());
+ auto pNewCursor(m_pImpl->m_rDoc.CreateUnoCursor(aPos));
+ if (!GetPositions(*pNewCursor))
+ {
+ throw uno::RuntimeException("range has no positions");
+ }
+ if (!m_pImpl->m_xParentText.is())
+ {
+ getText();
+ }
+
+ const CursorType eSetType = (RANGE_IN_CELL == m_pImpl->m_eRangePosition)
+ ? CursorType::SelectionInTable : CursorType::Selection;
+ return SwXParagraphEnumeration::Create(m_pImpl->m_xParentText, pNewCursor, eSetType);
+}
+
+uno::Type SAL_CALL SwXTextRange::getElementType()
+{
+ return cppu::UnoType<text::XTextRange>::get();
+}
+
+sal_Bool SAL_CALL SwXTextRange::hasElements()
+{
+ return true;
+}
+
+uno::Sequence< OUString > SAL_CALL
+SwXTextRange::getAvailableServiceNames()
+{
+ uno::Sequence<OUString> aRet { "com.sun.star.text.TextContent" };
+ return aRet;
+}
+
+uno::Reference< beans::XPropertySetInfo > SAL_CALL
+SwXTextRange::getPropertySetInfo()
+{
+ SolarMutexGuard aGuard;
+
+ static uno::Reference< beans::XPropertySetInfo > xRef =
+ m_pImpl->m_rPropSet.getPropertySetInfo();
+ return xRef;
+}
+
+void SAL_CALL
+SwXTextRange::setPropertyValue(
+ const OUString& rPropertyName, const uno::Any& rValue)
+{
+ SolarMutexGuard aGuard;
+
+ if (!m_pImpl->GetBookmark())
+ {
+ throw uno::RuntimeException("range has no mark (table?)");
+ }
+ SwPaM aPaM(GetDoc().GetNodes());
+ GetPositions(aPaM);
+ SwUnoCursorHelper::SetPropertyValue(aPaM, m_pImpl->m_rPropSet,
+ rPropertyName, rValue);
+}
+
+uno::Any SAL_CALL
+SwXTextRange::getPropertyValue(const OUString& rPropertyName)
+{
+ SolarMutexGuard aGuard;
+
+ if (!m_pImpl->GetBookmark())
+ {
+ throw uno::RuntimeException("range has no mark (table?)");
+ }
+ SwPaM aPaM(GetDoc().GetNodes());
+ GetPositions(aPaM);
+ return SwUnoCursorHelper::GetPropertyValue(aPaM, m_pImpl->m_rPropSet,
+ rPropertyName);
+}
+
+void SAL_CALL
+SwXTextRange::addPropertyChangeListener(
+ const OUString& /*rPropertyName*/,
+ const uno::Reference< beans::XPropertyChangeListener >& /*xListener*/)
+{
+ OSL_FAIL("SwXTextRange::addPropertyChangeListener(): not implemented");
+}
+
+void SAL_CALL
+SwXTextRange::removePropertyChangeListener(
+ const OUString& /*rPropertyName*/,
+ const uno::Reference< beans::XPropertyChangeListener >& /*xListener*/)
+{
+ OSL_FAIL("SwXTextRange::removePropertyChangeListener(): not implemented");
+}
+
+void SAL_CALL
+SwXTextRange::addVetoableChangeListener(
+ const OUString& /*rPropertyName*/,
+ const uno::Reference< beans::XVetoableChangeListener >& /*xListener*/)
+{
+ OSL_FAIL("SwXTextRange::addVetoableChangeListener(): not implemented");
+}
+
+void SAL_CALL
+SwXTextRange::removeVetoableChangeListener(
+ const OUString& /*rPropertyName*/,
+ const uno::Reference< beans::XVetoableChangeListener >& /*xListener*/)
+{
+ OSL_FAIL("SwXTextRange::removeVetoableChangeListener(): not implemented");
+}
+
+beans::PropertyState SAL_CALL
+SwXTextRange::getPropertyState(const OUString& rPropertyName)
+{
+ SolarMutexGuard aGuard;
+
+ if (!m_pImpl->GetBookmark())
+ {
+ throw uno::RuntimeException("range has no mark (table?)");
+ }
+ SwPaM aPaM(GetDoc().GetNodes());
+ GetPositions(aPaM);
+ return SwUnoCursorHelper::GetPropertyState(aPaM, m_pImpl->m_rPropSet,
+ rPropertyName);
+}
+
+uno::Sequence< beans::PropertyState > SAL_CALL
+SwXTextRange::getPropertyStates(const uno::Sequence< OUString >& rPropertyName)
+{
+ SolarMutexGuard g;
+
+ if (!m_pImpl->GetBookmark())
+ {
+ throw uno::RuntimeException("range has no mark (table?)");
+ }
+ SwPaM aPaM(GetDoc().GetNodes());
+ GetPositions(aPaM);
+ return SwUnoCursorHelper::GetPropertyStates(aPaM, m_pImpl->m_rPropSet,
+ rPropertyName);
+}
+
+void SAL_CALL SwXTextRange::setPropertyToDefault(const OUString& rPropertyName)
+{
+ SolarMutexGuard aGuard;
+
+ if (!m_pImpl->GetBookmark())
+ {
+ throw uno::RuntimeException("range has no mark (table?)");
+ }
+ SwPaM aPaM(GetDoc().GetNodes());
+ GetPositions(aPaM);
+ SwUnoCursorHelper::SetPropertyToDefault(aPaM, m_pImpl->m_rPropSet,
+ rPropertyName);
+}
+
+uno::Any SAL_CALL
+SwXTextRange::getPropertyDefault(const OUString& rPropertyName)
+{
+ SolarMutexGuard aGuard;
+
+ if (!m_pImpl->GetBookmark())
+ {
+ throw uno::RuntimeException("range has no mark (table?)");
+ }
+ SwPaM aPaM(GetDoc().GetNodes());
+ GetPositions(aPaM);
+ return SwUnoCursorHelper::GetPropertyDefault(aPaM, m_pImpl->m_rPropSet,
+ rPropertyName);
+}
+
+void SAL_CALL
+SwXTextRange::makeRedline(
+ const OUString& rRedlineType,
+ const uno::Sequence< beans::PropertyValue >& rRedlineProperties )
+{
+ SolarMutexGuard aGuard;
+
+ if (!m_pImpl->GetBookmark())
+ {
+ throw uno::RuntimeException("range has no mark (table?)");
+ }
+ SwPaM aPaM(GetDoc().GetNodes());
+ SwXTextRange::GetPositions(aPaM);
+ SwUnoCursorHelper::makeRedline( aPaM, rRedlineType, rRedlineProperties );
+}
+
+namespace {
+
+struct SwXTextRangesImpl final : public SwXTextRanges
+{
+
+ // XServiceInfo
+ virtual OUString SAL_CALL getImplementationName() override
+ { return "SwXTextRanges"; };
+ virtual sal_Bool SAL_CALL supportsService( const OUString& rServiceName) override
+ { return cppu::supportsService(this, rServiceName); };
+ virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() override
+ { return { "com.sun.star.text.TextRanges" }; };
+
+ // XElementAccess
+ virtual css::uno::Type SAL_CALL getElementType() override
+ { return cppu::UnoType<text::XTextRange>::get(); };
+ virtual sal_Bool SAL_CALL hasElements() override
+ { return getCount() > 0; };
+ // XIndexAccess
+ virtual sal_Int32 SAL_CALL getCount() override;
+ virtual css::uno::Any SAL_CALL getByIndex(sal_Int32 nIndex) override;
+
+ explicit SwXTextRangesImpl(SwPaM *const pPaM)
+ {
+ if (pPaM)
+ {
+ m_pUnoCursor.reset(pPaM->GetDoc().CreateUnoCursor(*pPaM->GetPoint()));
+ ::sw::DeepCopyPaM(*pPaM, *GetCursor());
+ }
+ MakeRanges();
+ }
+ virtual void SAL_CALL release() noexcept override
+ {
+ SolarMutexGuard g;
+ OWeakObject::release();
+ }
+ virtual SwUnoCursor* GetCursor() override
+ { return &(*m_pUnoCursor); };
+ void MakeRanges();
+ std::vector< rtl::Reference<SwXTextRange> > m_Ranges;
+ sw::UnoCursorPointer m_pUnoCursor;
+};
+
+}
+
+void SwXTextRangesImpl::MakeRanges()
+{
+ if (!GetCursor())
+ return;
+
+ for(SwPaM& rTmpCursor : GetCursor()->GetRingContainer())
+ {
+ const rtl::Reference<SwXTextRange> xRange(
+ SwXTextRange::CreateXTextRange(
+ rTmpCursor.GetDoc(),
+ *rTmpCursor.GetPoint(), rTmpCursor.GetMark()));
+ if (xRange.is())
+ {
+ m_Ranges.push_back(xRange);
+ }
+ }
+}
+
+rtl::Reference<SwXTextRanges> SwXTextRanges::Create(SwPaM *const pPaM)
+ { return new SwXTextRangesImpl(pPaM); }
+
+/*
+ * Text positions
+ * Up to the first access to a text position, only a SwCursor is stored.
+ * Afterwards, an array with uno::Reference<XTextPosition> will be created.
+ */
+
+sal_Int32 SAL_CALL SwXTextRangesImpl::getCount()
+{
+ SolarMutexGuard aGuard;
+ return static_cast<sal_Int32>(m_Ranges.size());
+}
+
+uno::Any SAL_CALL SwXTextRangesImpl::getByIndex(sal_Int32 nIndex)
+{
+ SolarMutexGuard aGuard;
+ if ((nIndex < 0) || (o3tl::make_unsigned(nIndex) >= m_Ranges.size()))
+ throw lang::IndexOutOfBoundsException();
+ uno::Any ret(uno::Reference<text::XTextRange>(m_Ranges.at(nIndex)));
+ return ret;
+}
+
+void SwUnoCursorHelper::SetString(SwCursor & rCursor, std::u16string_view aString)
+{
+ // Start/EndAction
+ SwDoc& rDoc = rCursor.GetDoc();
+ UnoActionContext aAction(&rDoc);
+ rDoc.GetIDocumentUndoRedo().StartUndo(SwUndoId::INSERT, nullptr);
+ if (rCursor.HasMark())
+ {
+ rDoc.getIDocumentContentOperations().DeleteAndJoin(rCursor);
+ }
+ if (!aString.empty())
+ {
+ const bool bSuccess( SwUnoCursorHelper::DocInsertStringSplitCR(
+ rDoc, rCursor, aString, false ) );
+ OSL_ENSURE( bSuccess, "DocInsertStringSplitCR" );
+ SwUnoCursorHelper::SelectPam(rCursor, true);
+ rCursor.Left(aString.size());
+ }
+ rDoc.GetIDocumentUndoRedo().EndUndo(SwUndoId::INSERT, nullptr);
+}
+
+namespace {
+
+struct SwXParaFrameEnumerationImpl final : public SwXParaFrameEnumeration
+{
+ // XServiceInfo
+ virtual OUString SAL_CALL getImplementationName() override
+ { return "SwXParaFrameEnumeration"; };
+ virtual sal_Bool SAL_CALL supportsService(const OUString& rServiceName) override
+ { return cppu::supportsService(this, rServiceName); };
+ virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() override
+ { return {"com.sun.star.util.ContentEnumeration"}; };
+
+ // XEnumeration
+ virtual sal_Bool SAL_CALL hasMoreElements() override;
+ virtual css::uno::Any SAL_CALL nextElement() override;
+
+ SwXParaFrameEnumerationImpl(const SwPaM& rPaM, const enum ParaFrameMode eParaFrameMode, SwFrameFormat* const pFormat);
+ virtual void SAL_CALL release() noexcept override
+ {
+ SolarMutexGuard g;
+ OWeakObject::release();
+ }
+ SwUnoCursor& GetCursor()
+ { return *m_pUnoCursor; }
+ void PurgeFrameClients()
+ {
+ if(!m_pUnoCursor)
+ {
+ m_vFrames.clear();
+ m_xNextObject = nullptr;
+ }
+ else
+ {
+ // removing orphaned Clients
+ std::erase_if(m_vFrames,
+ [] (std::unique_ptr<sw::FrameClient>& rEntry) -> bool { return !rEntry->GetRegisteredIn(); });
+ }
+ }
+ void FillFrame();
+ bool CreateNextObject();
+ uno::Reference< text::XTextContent > m_xNextObject;
+ std::deque< std::unique_ptr<sw::FrameClient> > m_vFrames;
+ ::sw::UnoCursorPointer m_pUnoCursor;
+};
+
+}
+
+rtl::Reference<SwXParaFrameEnumeration> SwXParaFrameEnumeration::Create(const SwPaM& rPaM, const enum ParaFrameMode eParaFrameMode, SwFrameFormat* const pFormat)
+ { return new SwXParaFrameEnumerationImpl(rPaM, eParaFrameMode, pFormat); }
+
+SwXParaFrameEnumerationImpl::SwXParaFrameEnumerationImpl(
+ const SwPaM& rPaM, const enum ParaFrameMode eParaFrameMode,
+ SwFrameFormat* const pFormat)
+ : m_pUnoCursor(rPaM.GetDoc().CreateUnoCursor(*rPaM.GetPoint()))
+{
+ if (rPaM.HasMark())
+ {
+ GetCursor().SetMark();
+ *GetCursor().GetMark() = *rPaM.GetMark();
+ }
+ if (PARAFRAME_PORTION_PARAGRAPH == eParaFrameMode)
+ {
+ FrameClientSortList_t vFrames;
+ ::CollectFrameAtNode(rPaM.GetPoint()->GetNode(), vFrames, false);
+ std::transform(vFrames.begin(), vFrames.end(),
+ std::back_inserter(m_vFrames),
+ [] (FrameClientSortListEntry& rEntry) { return std::move(rEntry.pFrameClient); });
+ }
+ else if (pFormat)
+ {
+ m_vFrames.push_back(std::make_unique<sw::FrameClient>(pFormat));
+ }
+ else if ((PARAFRAME_PORTION_CHAR == eParaFrameMode) ||
+ (PARAFRAME_PORTION_TEXTRANGE == eParaFrameMode))
+ {
+ if (PARAFRAME_PORTION_TEXTRANGE == eParaFrameMode)
+ {
+ //get all frames that are bound at paragraph or at character
+ for(const SwPosFlyFrame& rFlyFrame : rPaM.GetDoc().GetAllFlyFormats(&GetCursor(), false, true))
+ {
+ const auto pFrameFormat = const_cast<SwFrameFormat*>(&rFlyFrame.GetFormat());
+ m_vFrames.push_back(std::make_unique<sw::FrameClient>(pFrameFormat));
+ }
+ }
+ FillFrame();
+ }
+}
+
+// Search for a FLYCNT text attribute at the cursor point and fill the frame
+// into the array
+void SwXParaFrameEnumerationImpl::FillFrame()
+{
+ if(!m_pUnoCursor->GetPointNode().IsTextNode())
+ return;
+ // search for objects at the cursor - anchored at/as char
+ const auto pTextAttr = m_pUnoCursor->GetPointNode().GetTextNode()->GetTextAttrForCharAt(
+ m_pUnoCursor->GetPoint()->GetContentIndex(), RES_TXTATR_FLYCNT);
+ if(!pTextAttr)
+ return;
+ const SwFormatFlyCnt& rFlyCnt = pTextAttr->GetFlyCnt();
+ SwFrameFormat* const pFrameFormat = rFlyCnt.GetFrameFormat();
+ m_vFrames.push_back(std::make_unique<sw::FrameClient>(pFrameFormat));
+}
+
+bool SwXParaFrameEnumerationImpl::CreateNextObject()
+{
+ if (m_vFrames.empty())
+ return false;
+
+ m_xNextObject.set(FrameClientToXTextContent(m_vFrames.front().get()));
+ m_vFrames.pop_front();
+ return m_xNextObject.is();
+}
+
+uno::Reference<text::XTextContent> FrameClientToXTextContent(sw::FrameClient* pClient)
+{
+ assert(pClient);
+
+ uno::Reference<text::XTextContent> xRet;
+ SwFrameFormat* const pFormat = static_cast<SwFrameFormat*>(pClient->GetRegisteredIn());
+ // the format should be valid here, otherwise the client
+ // would have been removed by PurgeFrameClients
+ // check for a shape first
+ if(pFormat->Which() == RES_DRAWFRMFMT)
+ {
+ SdrObject* pObject(nullptr);
+ pFormat->CallSwClientNotify(sw::FindSdrObjectHint(pObject));
+ if(pObject)
+ xRet.set(pObject->getUnoShape(), uno::UNO_QUERY);
+ }
+ else
+ {
+ const SwNodeIndex* pIdx = pFormat->GetContent().GetContentIdx();
+ OSL_ENSURE(pIdx, "where is the index?");
+ SwNode const* const pNd = pIdx->GetNodes()[pIdx->GetIndex() + 1];
+
+ if (!pNd->IsNoTextNode())
+ {
+ xRet = static_cast<SwXFrame*>(SwXTextFrame::CreateXTextFrame(
+ *pFormat->GetDoc(), pFormat).get());
+ }
+ else if (pNd->IsGrfNode())
+ {
+ xRet.set(SwXTextGraphicObject::CreateXTextGraphicObject(
+ *pFormat->GetDoc(), pFormat));
+ }
+ else
+ {
+ assert(pNd->IsOLENode());
+ xRet.set(SwXTextEmbeddedObject::CreateXTextEmbeddedObject(
+ *pFormat->GetDoc(), pFormat));
+ }
+ }
+ return xRet;
+}
+
+sal_Bool SAL_CALL
+SwXParaFrameEnumerationImpl::hasMoreElements()
+{
+ SolarMutexGuard aGuard;
+ PurgeFrameClients();
+ return m_xNextObject.is() || CreateNextObject();
+}
+
+uno::Any SAL_CALL SwXParaFrameEnumerationImpl::nextElement()
+{
+ SolarMutexGuard aGuard;
+ PurgeFrameClients();
+ if (!m_xNextObject.is() && !m_vFrames.empty())
+ CreateNextObject();
+ if (!m_xNextObject.is())
+ throw container::NoSuchElementException();
+ uno::Any aRet;
+ aRet <<= m_xNextObject;
+ m_xNextObject = nullptr;
+ return aRet;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/core/unocore/unoparagraph.cxx b/sw/source/core/unocore/unoparagraph.cxx
new file mode 100644
index 0000000000..dab5270588
--- /dev/null
+++ b/sw/source/core/unocore/unoparagraph.cxx
@@ -0,0 +1,1457 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <unoparagraph.hxx>
+
+#include <comphelper/interfacecontainer4.hxx>
+#include <cppuhelper/exc_hlp.hxx>
+#include <cppuhelper/supportsservice.hxx>
+#include <osl/diagnose.h>
+#include <comphelper/diagnose_ex.hxx>
+
+#include <cmdid.h>
+#include <fmtautofmt.hxx>
+#include <unomid.h>
+#include <unoparaframeenum.hxx>
+#include <unotext.hxx>
+#include <unotextrange.hxx>
+#include <unoport.hxx>
+#include <unomap.hxx>
+#include <unocrsr.hxx>
+#include <unoprnms.hxx>
+#include <unocrsrhelper.hxx>
+#include <doc.hxx>
+#include <ndtxt.hxx>
+#include <algorithm>
+#include <utility>
+#include <vcl/svapp.hxx>
+#include <docsh.hxx>
+#include <swunohelper.hxx>
+
+#include <com/sun/star/beans/SetPropertyTolerantFailed.hpp>
+#include <com/sun/star/beans/GetPropertyTolerantResult.hpp>
+#include <com/sun/star/beans/TolerantPropertySetResultType.hpp>
+#include <com/sun/star/beans/PropertyAttribute.hpp>
+#include <com/sun/star/lang/WrappedTargetRuntimeException.hpp>
+#include <com/sun/star/text/WrapTextMode.hpp>
+#include <com/sun/star/text/TextContentAnchorType.hpp>
+
+#include <com/sun/star/drawing/BitmapMode.hpp>
+#include <comphelper/propertyvalue.hxx>
+#include <comphelper/sequence.hxx>
+#include <comphelper/servicehelper.hxx>
+#include <editeng/unoipset.hxx>
+#include <svl/listener.hxx>
+#include <svx/unobrushitemhelper.hxx>
+#include <svx/xflbmtit.hxx>
+#include <svx/xflbstit.hxx>
+
+using namespace ::com::sun::star;
+
+namespace {
+
+class SwParaSelection
+{
+ SwCursor & m_rCursor;
+public:
+ explicit SwParaSelection(SwCursor & rCursor);
+ ~SwParaSelection();
+};
+
+}
+
+SwParaSelection::SwParaSelection(SwCursor & rCursor)
+ : m_rCursor(rCursor)
+{
+ if (m_rCursor.HasMark())
+ {
+ m_rCursor.DeleteMark();
+ }
+ // is it at the start?
+ if (m_rCursor.GetPoint()->GetContentIndex() != 0)
+ {
+ m_rCursor.MovePara(GoCurrPara, fnParaStart);
+ }
+ // or at the end already?
+ if (m_rCursor.GetPoint()->GetContentIndex() != m_rCursor.GetPointContentNode()->Len())
+ {
+ m_rCursor.SetMark();
+ m_rCursor.MovePara(GoCurrPara, fnParaEnd);
+ }
+}
+
+SwParaSelection::~SwParaSelection()
+{
+ if (m_rCursor.GetPoint()->GetContentIndex() != 0)
+ {
+ m_rCursor.DeleteMark();
+ m_rCursor.MovePara(GoCurrPara, fnParaStart);
+ }
+}
+
+/// @throws beans::UnknownPropertyException
+/// @throws uno::RuntimeException
+static beans::PropertyState lcl_SwXParagraph_getPropertyState(
+ const SwTextNode& rTextNode,
+ const SwAttrSet** ppSet,
+ const SfxItemPropertyMapEntry& rEntry,
+ bool &rAttrSetFetched );
+
+class SwXParagraph::Impl
+ : public SvtListener
+{
+public:
+ SwXParagraph& m_rThis;
+ unotools::WeakReference<SwXParagraph> m_wThis;
+ std::mutex m_Mutex; // just for OInterfaceContainerHelper4
+ ::comphelper::OInterfaceContainerHelper4<css::lang::XEventListener> m_EventListeners;
+ SfxItemPropertySet const& m_rPropSet;
+ bool m_bIsDescriptor;
+ sal_Int32 m_nSelectionStartPos;
+ sal_Int32 m_nSelectionEndPos;
+ OUString m_sText;
+ css::uno::Reference<SwXText> m_xParentText;
+ SwTextNode* m_pTextNode;
+
+ Impl(SwXParagraph& rThis,
+ SwTextNode* const pTextNode = nullptr, css::uno::Reference<SwXText> xParent = nullptr,
+ const sal_Int32 nSelStart = -1, const sal_Int32 nSelEnd = -1)
+ : m_rThis(rThis)
+ , m_rPropSet(*aSwMapProvider.GetPropertySet(PROPERTY_MAP_PARAGRAPH))
+ , m_bIsDescriptor(nullptr == pTextNode)
+ , m_nSelectionStartPos(nSelStart)
+ , m_nSelectionEndPos(nSelEnd)
+ , m_xParentText(std::move(xParent))
+ , m_pTextNode(pTextNode)
+ {
+ m_pTextNode && StartListening(m_pTextNode->GetNotifier());
+ }
+
+ SwTextNode* GetTextNode() {
+ return m_pTextNode;
+ }
+
+ SwTextNode& GetTextNodeOrThrow() {
+ if (!m_pTextNode) {
+ throw uno::RuntimeException("SwXParagraph: disposed or invalid", nullptr);
+ }
+ return *m_pTextNode;
+ }
+
+ bool IsDescriptor() const { return m_bIsDescriptor; }
+
+ /// @throws beans::UnknownPropertyException
+ /// @throws beans::PropertyVetoException
+ /// @throws lang::IllegalArgumentException
+ /// @throws lang::WrappedTargetException
+ /// @throws uno::RuntimeException
+ void SetPropertyValues_Impl(
+ const uno::Sequence< OUString >& rPropertyNames,
+ const uno::Sequence< uno::Any >& rValues);
+
+ /// @throws beans::UnknownPropertyException
+ /// @throws lang::WrappedTargetException
+ /// @throws uno::RuntimeException
+ uno::Sequence< uno::Any >
+ GetPropertyValues_Impl(
+ const uno::Sequence< OUString >& rPropertyNames);
+
+ /// @throws uno::RuntimeException
+ void GetSinglePropertyValue_Impl(
+ const SfxItemPropertyMapEntry& rEntry,
+ const SfxItemSet& rSet,
+ uno::Any& rAny ) const;
+
+ /// @throws uno::RuntimeException
+ uno::Sequence< beans::GetDirectPropertyTolerantResult >
+ GetPropertyValuesTolerant_Impl(
+ const uno::Sequence< OUString >& rPropertyNames,
+ bool bDirectValuesOnly);
+protected:
+ virtual void Notify(const SfxHint& rHint) override;
+
+};
+
+void SwXParagraph::Impl::Notify(const SfxHint& rHint)
+{
+ if(rHint.GetId() == SfxHintId::Dying)
+ {
+ m_pTextNode = nullptr;
+ std::unique_lock aGuard(m_Mutex);
+ if (m_EventListeners.getLength(aGuard) != 0)
+ {
+ // fdo#72695: if UNO object is already dead, don't revive it with event
+ // The specific pattern we are guarding against is this:
+ // [1] Thread1 takes the SolarMutex
+ // [2] Thread2 decrements the SwXParagraph reference count, and calls the
+ // SwXParagraph destructor, which tries to take the SolarMutex, and blocks
+ // [3] Thread1 destroys a SwTextNode, which calls this Notify event, which results
+ // in a double-free if we construct the xThis object.
+ uno::Reference<uno::XInterface> const xThis(m_wThis);
+ if (!xThis.is())
+ { // fdo#72695: if UNO object is already dead, don't revive it with event
+ return;
+ }
+ lang::EventObject const ev(xThis);
+ m_EventListeners.disposeAndClear(aGuard, ev);
+ }
+ }
+}
+
+SwXParagraph::SwXParagraph()
+ : m_pImpl( new SwXParagraph::Impl(*this) )
+{
+}
+
+SwXParagraph::SwXParagraph(
+ css::uno::Reference< SwXText > const & xParent,
+ SwTextNode & rTextNode,
+ const sal_Int32 nSelStart, const sal_Int32 nSelEnd)
+ : m_pImpl(
+ new SwXParagraph::Impl(*this, &rTextNode, xParent, nSelStart, nSelEnd))
+{
+}
+
+SwXParagraph::~SwXParagraph()
+{
+}
+
+const SwTextNode * SwXParagraph::GetTextNode() const
+{
+ return m_pImpl->GetTextNode();
+}
+
+bool SwXParagraph::IsDescriptor() const
+{
+ return m_pImpl->IsDescriptor();
+}
+
+rtl::Reference<SwXParagraph>
+SwXParagraph::CreateXParagraph(SwDoc & rDoc, SwTextNode *const pTextNode,
+ css::uno::Reference< SwXText> const& i_xParent,
+ const sal_Int32 nSelStart, const sal_Int32 nSelEnd)
+{
+ // re-use existing SwXParagraph
+ // #i105557#: do not iterate over the registered clients: race condition
+ rtl::Reference<SwXParagraph> xParagraph;
+ if (pTextNode && (-1 == nSelStart) && (-1 == nSelEnd))
+ { // only use cache if no selection!
+ xParagraph = pTextNode->GetXParagraph();
+ }
+ if (xParagraph.is())
+ {
+ return xParagraph;
+ }
+
+ // create new SwXParagraph
+ css::uno::Reference<SwXText> xParentText(i_xParent);
+ if (!xParentText.is() && pTextNode)
+ {
+ SwPosition Pos(*pTextNode);
+ xParentText = ::sw::CreateParentXText( rDoc, Pos );
+ }
+ SwXParagraph *const pXPara( pTextNode
+ ? new SwXParagraph(xParentText, *pTextNode, nSelStart, nSelEnd)
+ : new SwXParagraph);
+ // this is why the constructor is private: need to acquire pXPara here
+ xParagraph.set(pXPara);
+ // in order to initialize the weak pointer cache in the core object
+ if (pTextNode && (-1 == nSelStart) && (-1 == nSelEnd))
+ {
+ pTextNode->SetXParagraph(xParagraph);
+ }
+ // need a permanent Reference to initialize m_wThis
+ pXPara->m_pImpl->m_wThis = xParagraph.get();
+ return xParagraph;
+}
+
+bool SwXParagraph::SelectPaM(SwPaM & rPaM)
+{
+ SwTextNode const*const pTextNode( GetTextNode() );
+
+ if (!pTextNode)
+ {
+ return false;
+ }
+
+ rPaM.GetPoint()->Assign( *pTextNode );
+ // set selection to the whole paragraph
+ rPaM.SetMark();
+ rPaM.GetMark()->SetContent( pTextNode->GetText().getLength() );
+ return true;
+}
+
+OUString SAL_CALL
+SwXParagraph::getImplementationName()
+{
+ return "SwXParagraph";
+}
+
+sal_Bool SAL_CALL
+SwXParagraph::supportsService(const OUString& rServiceName)
+{
+ return cppu::supportsService(this, rServiceName);
+}
+
+uno::Sequence< OUString > SAL_CALL
+SwXParagraph::getSupportedServiceNames()
+{
+ return {
+ "com.sun.star.text.TextContent",
+ "com.sun.star.text.Paragraph",
+ "com.sun.star.style.CharacterProperties",
+ "com.sun.star.style.CharacterPropertiesAsian",
+ "com.sun.star.style.CharacterPropertiesComplex",
+ "com.sun.star.style.ParagraphProperties",
+ "com.sun.star.style.ParagraphPropertiesAsian",
+ "com.sun.star.style.ParagraphPropertiesComplex"
+ };
+}
+
+void
+SwXParagraph::attachToText(SwXText & rParent, SwTextNode & rTextNode)
+{
+ OSL_ENSURE(m_pImpl->m_bIsDescriptor, "Paragraph is not a descriptor");
+ if (!m_pImpl->m_bIsDescriptor)
+ return;
+
+ m_pImpl->m_bIsDescriptor = false;
+ m_pImpl->EndListeningAll();
+ m_pImpl->StartListening(rTextNode.GetNotifier());
+ rTextNode.SetXParagraph(this);
+ m_pImpl->m_xParentText = &rParent;
+ if (!m_pImpl->m_sText.isEmpty())
+ {
+ try { setString(m_pImpl->m_sText); }
+ catch(...){}
+ m_pImpl->m_sText.clear();
+ }
+}
+
+uno::Reference< beans::XPropertySetInfo > SAL_CALL
+SwXParagraph::getPropertySetInfo()
+{
+ SolarMutexGuard g;
+
+ static uno::Reference< beans::XPropertySetInfo > xRef =
+ m_pImpl->m_rPropSet.getPropertySetInfo();
+ return xRef;
+}
+
+void SAL_CALL
+SwXParagraph::setPropertyValue(const OUString& rPropertyName,
+ const uno::Any& rValue)
+{
+ SolarMutexGuard aGuard;
+ m_pImpl->SetPropertyValues_Impl( { rPropertyName }, { rValue } );
+}
+
+uno::Any
+SwXParagraph::getPropertyValue(const OUString& rPropertyName)
+{
+ SolarMutexGuard aGuard;
+ uno::Sequence<OUString> aPropertyNames { rPropertyName };
+ const uno::Sequence< uno::Any > aRet =
+ m_pImpl->GetPropertyValues_Impl(aPropertyNames);
+ return aRet.getConstArray()[0];
+}
+
+void SwXParagraph::Impl::SetPropertyValues_Impl(
+ const uno::Sequence< OUString >& rPropertyNames,
+ const uno::Sequence< uno::Any >& rValues )
+{
+ SwTextNode & rTextNode(GetTextNodeOrThrow());
+
+ SwPosition aPos( rTextNode );
+ SwCursor aCursor( aPos, nullptr );
+ SwParaSelection aParaSel( aCursor );
+
+ uno::Sequence< beans::PropertyValue > aValues( rPropertyNames.getLength() );
+ std::transform(
+ rPropertyNames.begin(), rPropertyNames.end(), rValues.begin(), aValues.getArray(),
+ [&rMap = m_rPropSet.getPropertyMap(), this](const OUString& name, const uno::Any& value)
+ {
+ if (SfxItemPropertyMapEntry const* const pEntry = rMap.getByName(name); !pEntry)
+ {
+ throw beans::UnknownPropertyException("Unknown property: " + name,
+ m_rThis.getXWeak());
+ }
+ else if (pEntry->nFlags & beans::PropertyAttribute::READONLY)
+ {
+ throw beans::PropertyVetoException("Property is read-only: " + name,
+ m_rThis.getXWeak());
+ }
+ return comphelper::makePropertyValue(name, value);
+ });
+ SwUnoCursorHelper::SetPropertyValues(aCursor, m_rPropSet, aValues);
+}
+
+void SAL_CALL SwXParagraph::setPropertyValues(
+ const uno::Sequence< OUString >& rPropertyNames,
+ const uno::Sequence< uno::Any >& rValues )
+{
+ if (rPropertyNames.getLength() != rValues.getLength())
+ throw lang::IllegalArgumentException("lengths do not match",
+ getXWeak(), -1);
+
+ SolarMutexGuard aGuard;
+
+ // workaround for bad designed API
+ try
+ {
+ m_pImpl->SetPropertyValues_Impl( rPropertyNames, rValues );
+ }
+ catch (const beans::UnknownPropertyException &rException)
+ {
+ // wrap the original (here not allowed) exception in
+ // a lang::WrappedTargetException that gets thrown instead.
+ lang::WrappedTargetException aWExc;
+ aWExc.TargetException <<= rException;
+ throw aWExc;
+ }
+}
+
+// Support for DrawingLayer FillStyles for GetPropertyValue() usages
+void SwXParagraph::Impl::GetSinglePropertyValue_Impl(
+ const SfxItemPropertyMapEntry& rEntry,
+ const SfxItemSet& rSet,
+ uno::Any& rAny ) const
+{
+ bool bDone(false);
+
+ switch(rEntry.nWID)
+ {
+ case RES_BACKGROUND:
+ {
+ const std::unique_ptr<SvxBrushItem> aOriginalBrushItem(getSvxBrushItemFromSourceSet(rSet, RES_BACKGROUND));
+
+ if(!aOriginalBrushItem->QueryValue(rAny, rEntry.nMemberId))
+ {
+ OSL_ENSURE(false, "Error getting attribute from RES_BACKGROUND (!)");
+ }
+
+ bDone = true;
+ break;
+ }
+ case OWN_ATTR_FILLBMP_MODE:
+ {
+ if (rSet.Get(XATTR_FILLBMP_TILE).GetValue())
+ {
+ rAny <<= drawing::BitmapMode_REPEAT;
+ }
+ else if (rSet.Get(XATTR_FILLBMP_STRETCH).GetValue())
+ {
+ rAny <<= drawing::BitmapMode_STRETCH;
+ }
+ else
+ {
+ rAny <<= drawing::BitmapMode_NO_REPEAT;
+ }
+
+ bDone = true;
+ break;
+ }
+ default: break;
+ }
+
+ if(bDone)
+ return;
+
+ // fallback to standard get value implementation used before this helper was created
+ m_rPropSet.getPropertyValue(rEntry, rSet, rAny);
+
+ if(rEntry.aType == cppu::UnoType<sal_Int16>::get() && rEntry.aType != rAny.getValueType())
+ {
+ // since the sfx uInt16 item now exports a sal_Int32, we may have to fix this here
+ sal_Int32 nValue(0);
+
+ if (rAny >>= nValue)
+ {
+ rAny <<= static_cast<sal_Int16>(nValue);
+ }
+ }
+
+ // check for needed metric translation
+ if(!(rEntry.nMoreFlags & PropertyMoreFlags::METRIC_ITEM))
+ return;
+
+ bool bDoIt(true);
+
+ if(XATTR_FILLBMP_SIZEX == rEntry.nWID || XATTR_FILLBMP_SIZEY == rEntry.nWID)
+ {
+ // exception: If these ItemTypes are used, do not convert when these are negative
+ // since this means they are intended as percent values
+ sal_Int32 nValue = 0;
+
+ if(rAny >>= nValue)
+ {
+ bDoIt = nValue > 0;
+ }
+ }
+
+ if(bDoIt)
+ {
+ const MapUnit eMapUnit(rSet.GetPool()->GetMetric(rEntry.nWID));
+
+ if(eMapUnit != MapUnit::Map100thMM)
+ {
+ SvxUnoConvertToMM(eMapUnit, rAny);
+ }
+ }
+}
+
+uno::Sequence< uno::Any > SwXParagraph::Impl::GetPropertyValues_Impl(
+ const uno::Sequence< OUString > & rPropertyNames )
+{
+ SwTextNode & rTextNode(GetTextNodeOrThrow());
+
+ uno::Sequence< uno::Any > aValues(rPropertyNames.getLength());
+ SwPaM aPam( rTextNode );
+ uno::Any* pValues = aValues.getArray();
+ const OUString* pPropertyNames = rPropertyNames.getConstArray();
+ const SfxItemPropertyMap &rMap = m_rPropSet.getPropertyMap();
+ const SwAttrSet& rAttrSet( rTextNode.GetSwAttrSet() );
+ for (sal_Int32 nProp = 0; nProp < rPropertyNames.getLength(); nProp++)
+ {
+ if (pPropertyNames[nProp] == "ParaMarkerAutoStyleSpan")
+ {
+ // A hack to tunnel the fake text span to ODF export
+ // see XMLTextParagraphExport::exportParagraph
+ if (rTextNode.GetAttr(RES_PARATR_LIST_AUTOFMT).GetStyleHandle())
+ {
+ SwUnoCursor aEndCursor(*aPam.GetMark());
+ css::uno::Reference<css::beans::XPropertySet> xFakeSpan(
+ new SwXTextPortion(&aEndCursor, {}, PORTION_LIST_AUTOFMT));
+ pValues[nProp] <<= xFakeSpan;
+ }
+ continue;
+ }
+
+ if (pPropertyNames[nProp] == "ODFExport_NodeIndex")
+ {
+ // A hack to avoid writing random list ids to ODF when they are not referred later
+ // see XMLTextParagraphExport::DocumentListNodes::ShouldSkipListId
+ pValues[nProp] <<= rTextNode.GetIndex().get();
+ continue;
+ }
+
+ if (pPropertyNames[nProp] == "OOXMLImport_AnchoredShapes")
+ {
+ // A hack to provide list of anchored objects fast
+ // See reanchorObjects in writerfilter/source/dmapper/DomainMapper_Impl.cxx
+ FrameClientSortList_t aFrames;
+ CollectFrameAtNode(rTextNode, aFrames, false); // Frames anchored to paragraph
+ CollectFrameAtNode(rTextNode, aFrames, true); // Frames anchored to character
+ std::vector<uno::Reference<text::XTextContent>> aRet;
+ aRet.reserve(aFrames.size());
+ for (const auto& rFrame : aFrames)
+ if (auto xContent = FrameClientToXTextContent(rFrame.pFrameClient.get()))
+ aRet.push_back(xContent);
+
+ pValues[nProp] <<= comphelper::containerToSequence(aRet);
+ continue;
+ }
+
+ SfxItemPropertyMapEntry const*const pEntry =
+ rMap.getByName( pPropertyNames[nProp] );
+ if (!pEntry)
+ {
+ throw beans::UnknownPropertyException(
+ "Unknown property: " + pPropertyNames[nProp],
+ m_rThis.getXWeak());
+ }
+ if (! ::sw::GetDefaultTextContentValue(
+ pValues[nProp], pPropertyNames[nProp], pEntry->nWID))
+ {
+ beans::PropertyState eTemp;
+ const bool bDone = SwUnoCursorHelper::getCursorPropertyValue(
+ *pEntry, aPam, &(pValues[nProp]), eTemp, &rTextNode );
+ if (!bDone)
+ {
+ GetSinglePropertyValue_Impl(*pEntry, rAttrSet, pValues[nProp]);
+ }
+ }
+ }
+ return aValues;
+}
+
+uno::Sequence< uno::Any > SAL_CALL
+SwXParagraph::getPropertyValues(const uno::Sequence< OUString >& rPropertyNames)
+{
+ SolarMutexGuard aGuard;
+ uno::Sequence< uno::Any > aValues;
+
+ // workaround for bad designed API
+ try
+ {
+ aValues = m_pImpl->GetPropertyValues_Impl( rPropertyNames );
+ }
+ catch (beans::UnknownPropertyException &)
+ {
+ css::uno::Any anyEx = cppu::getCaughtException();
+ throw css::lang::WrappedTargetRuntimeException("Unknown property exception caught",
+ getXWeak(), anyEx );
+ }
+ catch (lang::WrappedTargetException &)
+ {
+ css::uno::Any anyEx = cppu::getCaughtException();
+ throw css::lang::WrappedTargetRuntimeException("WrappedTargetException caught",
+ getXWeak(), anyEx );
+ }
+
+ return aValues;
+}
+
+void SAL_CALL SwXParagraph::addPropertiesChangeListener(
+ const uno::Sequence< OUString >& /*aPropertyNames*/,
+ const uno::Reference< beans::XPropertiesChangeListener >& /*xListener*/ )
+{
+ OSL_FAIL("SwXParagraph::addPropertiesChangeListener(): not implemented");
+}
+
+void SAL_CALL SwXParagraph::removePropertiesChangeListener(
+ const uno::Reference< beans::XPropertiesChangeListener >& /*xListener*/ )
+{
+ OSL_FAIL("SwXParagraph::removePropertiesChangeListener(): not implemented");
+}
+
+void SAL_CALL SwXParagraph::firePropertiesChangeEvent(
+ const uno::Sequence< OUString >& /*aPropertyNames*/,
+ const uno::Reference< beans::XPropertiesChangeListener >& /*xListener*/ )
+{
+ OSL_FAIL("SwXParagraph::firePropertiesChangeEvent(): not implemented");
+}
+
+/* disabled for #i46921# */
+
+uno::Sequence< beans::SetPropertyTolerantFailed > SAL_CALL
+SwXParagraph::setPropertyValuesTolerant(
+ const uno::Sequence< OUString >& rPropertyNames,
+ const uno::Sequence< uno::Any >& rValues )
+{
+ SolarMutexGuard aGuard;
+
+ if (rPropertyNames.getLength() != rValues.getLength())
+ {
+ throw lang::IllegalArgumentException();
+ }
+
+ SwTextNode & rTextNode(m_pImpl->GetTextNodeOrThrow());
+
+ //SwNode& rTextNode = pUnoCursor->GetPoint()->GetNode();
+ //const SwAttrSet& rAttrSet = static_cast<SwTextNode&>(rTextNode).GetSwAttrSet();
+ //sal_uInt16 nAttrCount = rAttrSet.Count();
+
+ const sal_Int32 nProps = rPropertyNames.getLength();
+ const OUString *pProp = rPropertyNames.getConstArray();
+
+ //sal_Int32 nVals = rValues.getLength();
+ const uno::Any *pValue = rValues.getConstArray();
+
+ sal_Int32 nFailed = 0;
+ uno::Sequence< beans::SetPropertyTolerantFailed > aFailed( nProps );
+ beans::SetPropertyTolerantFailed *pFailed = aFailed.getArray();
+
+ // get entry to start with
+ const SfxItemPropertyMap &rPropMap =
+ m_pImpl->m_rPropSet.getPropertyMap();
+
+ SwPosition aPos( rTextNode );
+ SwCursor aCursor( aPos, nullptr );
+ SwParaSelection aParaSel( aCursor );
+ for (sal_Int32 i = 0; i < nProps; ++i)
+ {
+ try
+ {
+ pFailed[ nFailed ].Name = pProp[i];
+
+ SfxItemPropertyMapEntry const*const pEntry =
+ rPropMap.getByName( pProp[i] );
+ if (!pEntry)
+ {
+ pFailed[ nFailed++ ].Result =
+ beans::TolerantPropertySetResultType::UNKNOWN_PROPERTY;
+ }
+ else
+ {
+ // set property value
+ // (compare to SwXParagraph::setPropertyValues)
+ if (pEntry->nFlags & beans::PropertyAttribute::READONLY)
+ {
+ pFailed[ nFailed++ ].Result =
+ beans::TolerantPropertySetResultType::PROPERTY_VETO;
+ }
+ else
+ {
+ SwUnoCursorHelper::SetPropertyValue(
+ aCursor, m_pImpl->m_rPropSet, pProp[i], pValue[i]);
+ }
+ }
+ }
+ catch (beans::UnknownPropertyException &)
+ {
+ // should not occur because property was searched for before
+ TOOLS_WARN_EXCEPTION( "sw", "unexpected exception caught" );
+ pFailed[ nFailed++ ].Result =
+ beans::TolerantPropertySetResultType::UNKNOWN_PROPERTY;
+ }
+ catch (lang::IllegalArgumentException &)
+ {
+ pFailed[ nFailed++ ].Result =
+ beans::TolerantPropertySetResultType::ILLEGAL_ARGUMENT;
+ }
+ catch (beans::PropertyVetoException &)
+ {
+ pFailed[ nFailed++ ].Result =
+ beans::TolerantPropertySetResultType::PROPERTY_VETO;
+ }
+ catch (lang::WrappedTargetException &)
+ {
+ pFailed[ nFailed++ ].Result =
+ beans::TolerantPropertySetResultType::WRAPPED_TARGET;
+ }
+ }
+
+ aFailed.realloc( nFailed );
+ return aFailed;
+}
+
+uno::Sequence< beans::GetPropertyTolerantResult > SAL_CALL
+SwXParagraph::getPropertyValuesTolerant(
+ const uno::Sequence< OUString >& rPropertyNames )
+{
+ SolarMutexGuard aGuard;
+
+ const uno::Sequence< beans::GetDirectPropertyTolerantResult > aTmpRes(
+ m_pImpl->GetPropertyValuesTolerant_Impl( rPropertyNames, false ) );
+
+ // copy temporary result to final result type
+ const sal_Int32 nLen = aTmpRes.getLength();
+ uno::Sequence< beans::GetPropertyTolerantResult > aRes( nLen );
+ std::copy(aTmpRes.begin(), aTmpRes.end(), aRes.getArray());
+ return aRes;
+}
+
+uno::Sequence< beans::GetDirectPropertyTolerantResult > SAL_CALL
+SwXParagraph::getDirectPropertyValuesTolerant(
+ const uno::Sequence< OUString >& rPropertyNames )
+{
+ SolarMutexGuard aGuard;
+
+ return m_pImpl->GetPropertyValuesTolerant_Impl( rPropertyNames, true );
+}
+
+uno::Sequence< beans::GetDirectPropertyTolerantResult >
+SwXParagraph::Impl::GetPropertyValuesTolerant_Impl(
+ const uno::Sequence< OUString >& rPropertyNames,
+ bool bDirectValuesOnly )
+{
+ SolarMutexGuard aGuard;
+
+ SwTextNode & rTextNode(GetTextNodeOrThrow());
+
+ // #i46786# Use SwAttrSet pointer for determining the state.
+ // Use the value SwAttrSet (from the paragraph OR the style)
+ // for determining the actual value(s).
+ const SwAttrSet* pAttrSet = rTextNode.GetpSwAttrSet();
+ const SwAttrSet& rValueAttrSet = rTextNode.GetSwAttrSet();
+
+ sal_Int32 nProps = rPropertyNames.getLength();
+
+ uno::Sequence< beans::GetDirectPropertyTolerantResult > aResult( nProps );
+ beans::GetDirectPropertyTolerantResult *pResult = aResult.getArray();
+ sal_Int32 nIdx = 0;
+
+ // get entry to start with
+ const SfxItemPropertyMap &rPropMap = m_rPropSet.getPropertyMap();
+
+ for (const OUString& rProp : rPropertyNames)
+ {
+ OSL_ENSURE( nIdx < nProps, "index out of bounds" );
+ beans::GetDirectPropertyTolerantResult &rResult = pResult[nIdx];
+
+ try
+ {
+ rResult.Name = rProp;
+
+ SfxItemPropertyMapEntry const*const pEntry =
+ rPropMap.getByName( rProp );
+ if (!pEntry) // property available?
+ {
+ rResult.Result =
+ beans::TolerantPropertySetResultType::UNKNOWN_PROPERTY;
+ }
+ else
+ {
+ // get property state
+ // (compare to SwXParagraph::getPropertyState)
+ bool bAttrSetFetched = true;
+ beans::PropertyState eState = lcl_SwXParagraph_getPropertyState(
+ rTextNode, &pAttrSet, *pEntry, bAttrSetFetched );
+ rResult.State = eState;
+
+ rResult.Result = beans::TolerantPropertySetResultType::UNKNOWN_FAILURE;
+ if (!bDirectValuesOnly ||
+ (beans::PropertyState_DIRECT_VALUE == eState))
+ {
+ // get property value
+ // (compare to SwXParagraph::getPropertyValue(s))
+ uno::Any aValue;
+ if (! ::sw::GetDefaultTextContentValue(
+ aValue, rProp, pEntry->nWID ) )
+ {
+ SwPaM aPam( rTextNode );
+ // handle properties that are not part of the attribute
+ // and thus only pretended to be paragraph attributes
+ beans::PropertyState eTemp;
+ const bool bDone =
+ SwUnoCursorHelper::getCursorPropertyValue(
+ *pEntry, aPam, &aValue, eTemp, &rTextNode );
+
+ // if not found try the real paragraph attributes...
+ if (!bDone)
+ {
+ GetSinglePropertyValue_Impl(*pEntry, rValueAttrSet, aValue);
+ }
+ }
+
+ rResult.Value = aValue;
+ rResult.Result = beans::TolerantPropertySetResultType::SUCCESS;
+
+ nIdx++;
+ }
+ // this assertion should never occur!
+ OSL_ENSURE( nIdx < 1 || pResult[nIdx - 1].Result != beans::TolerantPropertySetResultType::UNKNOWN_FAILURE,
+ "unknown failure while retrieving property" );
+
+ }
+ }
+ catch (beans::UnknownPropertyException &)
+ {
+ // should not occur because property was searched for before
+ TOOLS_WARN_EXCEPTION( "sw", "unexpected exception caught" );
+ rResult.Result = beans::TolerantPropertySetResultType::UNKNOWN_PROPERTY;
+ }
+ catch (lang::IllegalArgumentException &)
+ {
+ rResult.Result = beans::TolerantPropertySetResultType::ILLEGAL_ARGUMENT;
+ }
+ catch (beans::PropertyVetoException &)
+ {
+ rResult.Result = beans::TolerantPropertySetResultType::PROPERTY_VETO;
+ }
+ catch (lang::WrappedTargetException &)
+ {
+ rResult.Result = beans::TolerantPropertySetResultType::WRAPPED_TARGET;
+ }
+ }
+
+ // resize to actually used size
+ aResult.realloc( nIdx );
+
+ return aResult;
+}
+
+bool ::sw::GetDefaultTextContentValue(
+ uno::Any& rAny, std::u16string_view rPropertyName, sal_uInt16 nWID)
+{
+ if(!nWID)
+ {
+ if(rPropertyName == UNO_NAME_ANCHOR_TYPE)
+ nWID = FN_UNO_ANCHOR_TYPE;
+ else if(rPropertyName == UNO_NAME_ANCHOR_TYPES)
+ nWID = FN_UNO_ANCHOR_TYPES;
+ else if(rPropertyName == UNO_NAME_TEXT_WRAP)
+ nWID = FN_UNO_TEXT_WRAP;
+ else
+ return false;
+ }
+
+ switch(nWID)
+ {
+ case FN_UNO_TEXT_WRAP: rAny <<= text::WrapTextMode_NONE; break;
+ case FN_UNO_ANCHOR_TYPE: rAny <<= text::TextContentAnchorType_AT_PARAGRAPH; break;
+ case FN_UNO_ANCHOR_TYPES:
+ { uno::Sequence<text::TextContentAnchorType> aTypes { text::TextContentAnchorType_AT_PARAGRAPH };
+ rAny <<= aTypes;
+ }
+ break;
+ default:
+ return false;
+ }
+ return true;
+}
+
+void SAL_CALL
+SwXParagraph::addPropertyChangeListener(
+ const OUString& /*rPropertyName*/,
+ const uno::Reference< beans::XPropertyChangeListener >& /*xListener*/)
+{
+ OSL_FAIL("SwXParagraph::addPropertyChangeListener(): not implemented");
+}
+
+void SAL_CALL
+SwXParagraph::removePropertyChangeListener(
+ const OUString& /*rPropertyName*/,
+ const uno::Reference< beans::XPropertyChangeListener >& /*xListener*/)
+{
+ OSL_FAIL("SwXParagraph::removePropertyChangeListener(): not implemented");
+}
+
+void SAL_CALL
+SwXParagraph::addVetoableChangeListener(
+ const OUString& /*rPropertyName*/,
+ const uno::Reference< beans::XVetoableChangeListener >& /*xListener*/)
+{
+ OSL_FAIL("SwXParagraph::addVetoableChangeListener(): not implemented");
+}
+
+void SAL_CALL
+SwXParagraph::removeVetoableChangeListener(
+ const OUString& /*rPropertyName*/,
+ const uno::Reference< beans::XVetoableChangeListener >& /*xListener*/)
+{
+ OSL_FAIL("SwXParagraph::removeVetoableChangeListener(): not implemented");
+}
+
+static beans::PropertyState lcl_SwXParagraph_getPropertyState(
+ const SwTextNode& rTextNode,
+ const SwAttrSet** ppSet,
+ const SfxItemPropertyMapEntry& rEntry,
+ bool &rAttrSetFetched)
+{
+ beans::PropertyState eRet(beans::PropertyState_DEFAULT_VALUE);
+
+ if(!(*ppSet) && !rAttrSetFetched)
+ {
+ (*ppSet) = rTextNode.GetpSwAttrSet();
+ rAttrSetFetched = true;
+ }
+
+ SwPosition aPos(rTextNode);
+ SwPaM aPam(aPos);
+ bool bDone(false);
+
+ switch(rEntry.nWID)
+ {
+ case FN_UNO_NUM_RULES:
+ {
+ // if numbering is set, return it; else do nothing
+ SwUnoCursorHelper::getNumberingProperty(aPam,eRet,nullptr);
+ bDone = true;
+ break;
+ }
+ case FN_UNO_ANCHOR_TYPES:
+ {
+ bDone = true;
+ break;
+ }
+ case RES_ANCHOR:
+ {
+ bDone = (MID_SURROUND_SURROUNDTYPE == rEntry.nMemberId);
+ break;
+ }
+ case RES_SURROUND:
+ {
+ bDone = (MID_ANCHOR_ANCHORTYPE == rEntry.nMemberId);
+ break;
+ }
+ case FN_UNO_PARA_STYLE:
+ case FN_UNO_PARA_CONDITIONAL_STYLE_NAME:
+ {
+ SwFormatColl* pFormat = SwUnoCursorHelper::GetCurTextFormatColl(aPam,rEntry.nWID == FN_UNO_PARA_CONDITIONAL_STYLE_NAME);
+ eRet = pFormat ? beans::PropertyState_DIRECT_VALUE : beans::PropertyState_AMBIGUOUS_VALUE;
+ bDone = true;
+ break;
+ }
+ case FN_UNO_PAGE_STYLE:
+ {
+ OUString sVal;
+ SwUnoCursorHelper::GetCurPageStyle( aPam, sVal );
+ eRet = !sVal.isEmpty() ? beans::PropertyState_DIRECT_VALUE
+ : beans::PropertyState_AMBIGUOUS_VALUE;
+ bDone = true;
+ break;
+ }
+
+ // DrawingLayer PropertyStyle support
+ case OWN_ATTR_FILLBMP_MODE:
+ {
+ if(*ppSet)
+ {
+ if(SfxItemState::SET == (*ppSet)->GetItemState(XATTR_FILLBMP_STRETCH, false)
+ || SfxItemState::SET == (*ppSet)->GetItemState(XATTR_FILLBMP_TILE, false))
+ {
+ eRet = beans::PropertyState_DIRECT_VALUE;
+ }
+ else
+ {
+ eRet = beans::PropertyState_AMBIGUOUS_VALUE;
+ }
+
+ bDone = true;
+ }
+ break;
+ }
+ case RES_BACKGROUND:
+ {
+ if(*ppSet)
+ {
+ if (SWUnoHelper::needToMapFillItemsToSvxBrushItemTypes(**ppSet,
+ rEntry.nMemberId))
+ {
+ eRet = beans::PropertyState_DIRECT_VALUE;
+ }
+ bDone = true;
+ }
+ break;
+ }
+ }
+
+ if(!bDone)
+ {
+ if((*ppSet) && SfxItemState::SET == (*ppSet)->GetItemState(rEntry.nWID, false))
+ {
+ eRet = beans::PropertyState_DIRECT_VALUE;
+ }
+ }
+
+ return eRet;
+}
+
+beans::PropertyState SAL_CALL
+SwXParagraph::getPropertyState(const OUString& rPropertyName)
+{
+ SolarMutexGuard aGuard;
+
+ SwTextNode & rTextNode(m_pImpl->GetTextNodeOrThrow());
+
+ const SwAttrSet* pSet = nullptr;
+ SfxItemPropertyMapEntry const*const pEntry =
+ m_pImpl->m_rPropSet.getPropertyMap().getByName(rPropertyName);
+ if (!pEntry)
+ {
+ throw beans::UnknownPropertyException(
+ "Unknown property: " + rPropertyName,
+ getXWeak());
+ }
+ bool bDummy = false;
+ const beans::PropertyState eRet =
+ lcl_SwXParagraph_getPropertyState(rTextNode, &pSet, *pEntry, bDummy);
+ return eRet;
+}
+
+uno::Sequence< beans::PropertyState > SAL_CALL
+SwXParagraph::getPropertyStates(
+ const uno::Sequence< OUString >& PropertyNames)
+{
+ SolarMutexGuard aGuard;
+
+ SwTextNode & rTextNode(m_pImpl->GetTextNodeOrThrow());
+
+ const OUString* pNames = PropertyNames.getConstArray();
+ uno::Sequence< beans::PropertyState > aRet(PropertyNames.getLength());
+ beans::PropertyState* pStates = aRet.getArray();
+ const SfxItemPropertyMap &rMap = m_pImpl->m_rPropSet.getPropertyMap();
+ const SwAttrSet* pSet = nullptr;
+ bool bAttrSetFetched = false;
+
+ for (sal_Int32 i = 0, nEnd = PropertyNames.getLength(); i < nEnd;
+ ++i, ++pStates, ++pNames)
+ {
+ SfxItemPropertyMapEntry const*const pEntry =
+ rMap.getByName( *pNames );
+ if (!pEntry)
+ {
+ throw beans::UnknownPropertyException(
+ "Unknown property: " + *pNames,
+ getXWeak());
+ }
+
+ if (bAttrSetFetched && !pSet && isATR(pEntry->nWID))
+ {
+ *pStates = beans::PropertyState_DEFAULT_VALUE;
+ }
+ else
+ {
+ *pStates = lcl_SwXParagraph_getPropertyState(
+ rTextNode, &pSet, *pEntry, bAttrSetFetched );
+ }
+ }
+
+ return aRet;
+}
+
+void SAL_CALL
+SwXParagraph::setPropertyToDefault(const OUString& rPropertyName)
+{
+ SolarMutexGuard aGuard;
+
+ SwTextNode & rTextNode(m_pImpl->GetTextNodeOrThrow());
+
+ SwPosition aPos( rTextNode );
+ SwCursor aCursor( aPos, nullptr );
+ if (rPropertyName == UNO_NAME_ANCHOR_TYPE ||
+ rPropertyName == UNO_NAME_ANCHOR_TYPES ||
+ rPropertyName == UNO_NAME_TEXT_WRAP)
+ {
+ return;
+ }
+
+ // select paragraph
+ SwParaSelection aParaSel( aCursor );
+ SfxItemPropertyMapEntry const*const pEntry =
+ m_pImpl->m_rPropSet.getPropertyMap().getByName( rPropertyName );
+ if (!pEntry)
+ {
+ throw beans::UnknownPropertyException(
+ "Unknown property: " + rPropertyName,
+ getXWeak());
+ }
+
+ if (pEntry->nFlags & beans::PropertyAttribute::READONLY)
+ {
+ throw uno::RuntimeException(
+ "Property is read-only: " + rPropertyName,
+ getXWeak());
+ }
+
+ const bool bBelowFrameAtrEnd(pEntry->nWID < RES_FRMATR_END);
+ const bool bDrawingLayerRange(XATTR_FILL_FIRST <= pEntry->nWID && XATTR_FILL_LAST >= pEntry->nWID);
+
+ if(bBelowFrameAtrEnd || bDrawingLayerRange)
+ {
+ o3tl::sorted_vector<sal_uInt16> aWhichIds;
+
+ // For FillBitmapMode two IDs have to be reset (!)
+ if(OWN_ATTR_FILLBMP_MODE == pEntry->nWID)
+ {
+ aWhichIds.insert(XATTR_FILLBMP_STRETCH);
+ aWhichIds.insert(XATTR_FILLBMP_TILE);
+ }
+ else
+ {
+ aWhichIds.insert(pEntry->nWID);
+ }
+
+ if (pEntry->nWID < RES_PARATR_BEGIN)
+ {
+ aCursor.GetDoc().ResetAttrs(aCursor, true, aWhichIds);
+ }
+ else
+ {
+ // for paragraph attributes the selection must be extended
+ // to paragraph boundaries
+ SwPosition aStart( *aCursor.Start() );
+ SwPosition aEnd ( *aCursor.End() );
+ auto pTemp( aCursor.GetDoc().CreateUnoCursor(aStart) );
+ if(!SwUnoCursorHelper::IsStartOfPara(*pTemp))
+ {
+ pTemp->MovePara(GoCurrPara, fnParaStart);
+ }
+
+ pTemp->SetMark();
+ *pTemp->GetPoint() = aEnd;
+
+ SwUnoCursorHelper::SelectPam(*pTemp, true);
+
+ if (!SwUnoCursorHelper::IsEndOfPara(*pTemp))
+ {
+ pTemp->MovePara(GoCurrPara, fnParaEnd);
+ }
+
+
+ pTemp->GetDoc().ResetAttrs(*pTemp, true, aWhichIds);
+ }
+ }
+ else
+ {
+ SwUnoCursorHelper::resetCursorPropertyValue(*pEntry, aCursor);
+ }
+}
+
+uno::Any SAL_CALL
+SwXParagraph::getPropertyDefault(const OUString& rPropertyName)
+{
+ SolarMutexGuard g;
+
+ SwTextNode & rTextNode(m_pImpl->GetTextNodeOrThrow());
+
+ uno::Any aRet;
+ if (::sw::GetDefaultTextContentValue(aRet, rPropertyName))
+ {
+ return aRet;
+ }
+
+ SfxItemPropertyMapEntry const*const pEntry =
+ m_pImpl->m_rPropSet.getPropertyMap().getByName(rPropertyName);
+ if (!pEntry)
+ {
+ throw beans::UnknownPropertyException(
+ "Unknown property: " + rPropertyName,
+ getXWeak());
+ }
+
+ const bool bBelowFrameAtrEnd(pEntry->nWID < RES_FRMATR_END);
+ const bool bDrawingLayerRange(XATTR_FILL_FIRST <= pEntry->nWID && XATTR_FILL_LAST >= pEntry->nWID);
+
+ if(bBelowFrameAtrEnd || bDrawingLayerRange)
+ {
+ const SfxPoolItem& rDefItem = rTextNode.GetDoc().GetAttrPool().GetDefaultItem(pEntry->nWID);
+
+ rDefItem.QueryValue(aRet, pEntry->nMemberId);
+ }
+
+ return aRet;
+}
+
+void SAL_CALL
+SwXParagraph::attach(const uno::Reference< text::XTextRange > & /*xTextRange*/)
+{
+ // SwXParagraph will only created in order to be inserted by
+ // 'insertTextContentBefore' or 'insertTextContentAfter' therefore
+ // they cannot be attached
+ throw uno::RuntimeException();
+}
+
+uno::Reference< text::XTextRange > SAL_CALL
+SwXParagraph::getAnchor()
+{
+ SolarMutexGuard aGuard;
+
+ SwTextNode & rTextNode(m_pImpl->GetTextNodeOrThrow());
+
+ SwPosition aPos( rTextNode );
+ SwCursor aCursor( aPos, nullptr );
+ // select paragraph
+ SwParaSelection aParaSel( aCursor );
+ const uno::Reference< text::XTextRange > xRet =
+ new SwXTextRange(aCursor, m_pImpl->m_xParentText);
+ return xRet;
+}
+
+void SAL_CALL SwXParagraph::dispose()
+{
+ SolarMutexGuard aGuard;
+
+ SwTextNode *const pTextNode( m_pImpl->GetTextNode() );
+ if (pTextNode)
+ {
+ SwCursor aCursor( SwPosition( *pTextNode ), nullptr );
+ pTextNode->GetDoc().getIDocumentContentOperations().DelFullPara(aCursor);
+ lang::EventObject const ev(getXWeak());
+ std::unique_lock aGuard2(m_pImpl->m_Mutex);
+ m_pImpl->m_EventListeners.disposeAndClear(aGuard2, ev);
+ }
+}
+
+void SAL_CALL SwXParagraph::addEventListener(
+ const uno::Reference< lang::XEventListener > & xListener)
+{
+ // no need to lock here as m_pImpl is const and container threadsafe
+ std::unique_lock aGuard(m_pImpl->m_Mutex);
+ m_pImpl->m_EventListeners.addInterface(aGuard, xListener);
+}
+
+void SAL_CALL SwXParagraph::removeEventListener(
+ const uno::Reference< lang::XEventListener > & xListener)
+{
+ // no need to lock here as m_pImpl is const and container threadsafe
+ std::unique_lock aGuard(m_pImpl->m_Mutex);
+ m_pImpl->m_EventListeners.removeInterface(aGuard, xListener);
+}
+
+uno::Reference< container::XEnumeration > SAL_CALL
+SwXParagraph::createEnumeration()
+{
+ SolarMutexGuard aGuard;
+
+ SwTextNode & rTextNode(m_pImpl->GetTextNodeOrThrow());
+
+ SwPaM aPam ( rTextNode );
+ const uno::Reference< container::XEnumeration > xRef =
+ new SwXTextPortionEnumeration(aPam, m_pImpl->m_xParentText,
+ m_pImpl->m_nSelectionStartPos, m_pImpl->m_nSelectionEndPos);
+ return xRef;
+}
+
+ /// tries to return less data, but may return more than just text fields
+rtl::Reference< SwXTextPortionEnumeration >
+SwXParagraph::createTextFieldsEnumeration()
+{
+ SolarMutexGuard aGuard;
+
+ SwTextNode & rTextNode(m_pImpl->GetTextNodeOrThrow());
+ SwPaM aPam ( rTextNode );
+
+ return new SwXTextPortionEnumeration(aPam, m_pImpl->m_xParentText,
+ m_pImpl->m_nSelectionStartPos, m_pImpl->m_nSelectionEndPos, /*bOnlyTextFields*/true);
+}
+
+uno::Type SAL_CALL SwXParagraph::getElementType()
+{
+ return cppu::UnoType<text::XTextRange>::get();
+}
+
+sal_Bool SAL_CALL SwXParagraph::hasElements()
+{
+ SolarMutexGuard aGuard;
+ return GetTextNode() != nullptr;
+}
+
+uno::Reference< text::XText > SAL_CALL
+SwXParagraph::getText()
+{
+ SolarMutexGuard g;
+
+ return m_pImpl->m_xParentText;
+}
+
+uno::Reference< text::XTextRange > SAL_CALL
+SwXParagraph::getStart()
+{
+ SolarMutexGuard aGuard;
+
+ SwTextNode & rTextNode(m_pImpl->GetTextNodeOrThrow());
+
+ SwPosition aPos( rTextNode );
+ SwCursor aCursor( aPos, nullptr );
+ SwParaSelection aParaSel( aCursor );
+ SwPaM aPam( *aCursor.Start() );
+ uno::Reference< text::XText > xParent = getText();
+ const uno::Reference< text::XTextRange > xRet =
+ new SwXTextRange(aPam, xParent);
+ return xRet;
+}
+
+uno::Reference< text::XTextRange > SAL_CALL
+SwXParagraph::getEnd()
+{
+ SolarMutexGuard aGuard;
+
+ SwTextNode & rTextNode(m_pImpl->GetTextNodeOrThrow());
+
+ SwPosition aPos( rTextNode );
+ SwCursor aCursor( aPos, nullptr );
+ SwParaSelection aParaSel( aCursor );
+ SwPaM aPam( *aCursor.End() );
+ uno::Reference< text::XText > xParent = getText();
+ const uno::Reference< text::XTextRange > xRet =
+ new SwXTextRange(aPam, xParent);
+ return xRet;
+}
+
+OUString SAL_CALL SwXParagraph::getString()
+{
+ SolarMutexGuard aGuard;
+ OUString aRet;
+ SwTextNode const*const pTextNode( GetTextNode() );
+ if (pTextNode)
+ {
+ SwPosition aPos( *pTextNode );
+ SwCursor aCursor( aPos, nullptr );
+ SwParaSelection aParaSel( aCursor );
+ SwUnoCursorHelper::GetTextFromPam(aCursor, aRet);
+ }
+ else if (m_pImpl->IsDescriptor())
+ {
+ aRet = m_pImpl->m_sText;
+ }
+ else
+ {
+ // Seems object is being disposed or some other problem occurs.
+ // Anyway from user point of view object still exist, so on that level this is not an error
+ SAL_WARN("sw.uno", "getString() for invalid paragraph called. Returning empty string.");
+ }
+ return aRet;
+}
+
+void SAL_CALL SwXParagraph::setString(const OUString& aString)
+{
+ SolarMutexGuard aGuard;
+
+ SwTextNode const*const pTextNode( GetTextNode() );
+ if (pTextNode)
+ {
+ SwPosition aPos( *pTextNode );
+ SwCursor aCursor( aPos, nullptr );
+ if (!SwUnoCursorHelper::IsStartOfPara(aCursor)) {
+ aCursor.MovePara(GoCurrPara, fnParaStart);
+ }
+ SwUnoCursorHelper::SelectPam(aCursor, true);
+ if (pTextNode->GetText().getLength()) {
+ aCursor.MovePara(GoCurrPara, fnParaEnd);
+ }
+ SwUnoCursorHelper::SetString(aCursor, aString);
+ SwUnoCursorHelper::SelectPam(aCursor, false);
+ }
+ else if (m_pImpl->IsDescriptor())
+ {
+ m_pImpl->m_sText = aString;
+ }
+ else
+ {
+ throw uno::RuntimeException();
+ }
+}
+
+uno::Reference< container::XEnumeration > SAL_CALL
+SwXParagraph::createContentEnumeration(const OUString& rServiceName)
+{
+ SolarMutexGuard g;
+
+ if ( rServiceName != "com.sun.star.text.TextContent" )
+ {
+ throw uno::RuntimeException();
+ }
+
+ SwTextNode & rTextNode(m_pImpl->GetTextNodeOrThrow());
+
+ SwPaM aPam( rTextNode );
+ uno::Reference< container::XEnumeration > xRet =
+ SwXParaFrameEnumeration::Create(aPam, PARAFRAME_PORTION_PARAGRAPH);
+ return xRet;
+}
+
+uno::Sequence< OUString > SAL_CALL
+SwXParagraph::getAvailableServiceNames()
+{
+ uno::Sequence<OUString> aRet { "com.sun.star.text.TextContent" };
+ return aRet;
+}
+
+// MetadatableMixin
+::sfx2::Metadatable* SwXParagraph::GetCoreObject()
+{
+ SwTextNode *const pTextNode( m_pImpl->GetTextNode() );
+ return pTextNode;
+}
+
+uno::Reference<frame::XModel> SwXParagraph::GetModel()
+{
+ SwTextNode *const pTextNode( m_pImpl->GetTextNode() );
+ if (pTextNode)
+ {
+ SwDocShell const*const pShell( pTextNode->GetDoc().GetDocShell() );
+ return pShell ? pShell->GetModel() : nullptr;
+ }
+ return nullptr;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/core/unocore/unoport.cxx b/sw/source/core/unocore/unoport.cxx
new file mode 100644
index 0000000000..cfbe918ba2
--- /dev/null
+++ b/sw/source/core/unocore/unoport.cxx
@@ -0,0 +1,871 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <unoport.hxx>
+
+#include <cmdid.h>
+#include <cppuhelper/exc_hlp.hxx>
+#include <utility>
+#include <vcl/svapp.hxx>
+#include <svl/itemprop.hxx>
+#include <comphelper/diagnose_ex.hxx>
+
+#include <unocrsrhelper.hxx>
+#include <unoparaframeenum.hxx>
+#include <unotextrange.hxx>
+#include <unomap.hxx>
+#include <unoprnms.hxx>
+#include <unomid.h>
+#include <txtatr.hxx>
+#include <ndtxt.hxx>
+#include <doc.hxx>
+#include <frmfmt.hxx>
+
+#include <com/sun/star/beans/PropertyAttribute.hpp>
+#include <com/sun/star/beans/SetPropertyTolerantFailed.hpp>
+#include <com/sun/star/beans/GetPropertyTolerantResult.hpp>
+#include <com/sun/star/beans/TolerantPropertySetResultType.hpp>
+#include <com/sun/star/lang/WrappedTargetRuntimeException.hpp>
+#include <com/sun/star/text/XFootnote.hpp>
+#include <com/sun/star/text/XTextField.hpp>
+#include <comphelper/servicehelper.hxx>
+#include <cppuhelper/supportsservice.hxx>
+#include <comphelper/sequence.hxx>
+
+using namespace ::com::sun::star;
+
+void SwXTextPortion::init(const SwUnoCursor* pPortionCursor)
+{
+ m_pUnoCursor = pPortionCursor->GetDoc().CreateUnoCursor(*pPortionCursor->GetPoint());
+ if (pPortionCursor->HasMark())
+ {
+ m_pUnoCursor->SetMark();
+ *m_pUnoCursor->GetMark() = *pPortionCursor->GetMark();
+ }
+}
+
+SwXTextPortion::SwXTextPortion(
+ const SwUnoCursor* pPortionCursor,
+ uno::Reference< text::XText > xParent,
+ SwTextPortionType eType)
+ : m_pPropSet(aSwMapProvider.GetPropertySet(
+ (PORTION_REDLINE_START == eType ||
+ PORTION_REDLINE_END == eType)
+ ? PROPERTY_MAP_REDLINE_PORTION
+ : PROPERTY_MAP_TEXTPORTION_EXTENSIONS))
+ , m_xParentText(std::move(xParent))
+ , m_pFrameFormat(nullptr)
+ , m_ePortionType(eType != PORTION_LIST_AUTOFMT ? eType : PORTION_TEXT)
+ , m_bIsCollapsed(false)
+ , m_bIsListAutoFormat(false)
+{
+ if (eType == PORTION_LIST_AUTOFMT)
+ {
+ m_bIsListAutoFormat = true;
+ }
+ init( pPortionCursor);
+}
+
+SwXTextPortion::SwXTextPortion(
+ const SwUnoCursor* pPortionCursor,
+ uno::Reference< text::XText > xParent,
+ SwFrameFormat& rFormat )
+ : m_pPropSet(aSwMapProvider.GetPropertySet(
+ PROPERTY_MAP_TEXTPORTION_EXTENSIONS))
+ , m_xParentText(std::move(xParent))
+ , m_pFrameFormat(&rFormat)
+ , m_ePortionType(PORTION_FRAME)
+ , m_bIsCollapsed(false)
+ , m_bIsListAutoFormat(false)
+{
+ StartListening(rFormat.GetNotifier());
+ init( pPortionCursor);
+}
+
+SwXTextPortion::SwXTextPortion(
+ const SwUnoCursor* pPortionCursor,
+ SwTextRuby const& rAttr,
+ uno::Reference< text::XText > xParent,
+ bool bIsEnd )
+ : m_pPropSet(aSwMapProvider.GetPropertySet(
+ PROPERTY_MAP_TEXTPORTION_EXTENSIONS))
+ , m_xParentText(std::move(xParent))
+ , m_pFrameFormat(nullptr)
+ , m_ePortionType( bIsEnd ? PORTION_RUBY_END : PORTION_RUBY_START )
+ , m_bIsCollapsed(false)
+ , m_bIsListAutoFormat(false)
+{
+ if (!bIsEnd)
+ {
+ m_oRubyText.emplace();
+ m_oRubyStyle.emplace();
+ m_oRubyAdjust.emplace();
+ m_oRubyIsAbove.emplace();
+ m_oRubyPosition.emplace();
+ }
+ init( pPortionCursor);
+
+ if (!bIsEnd)
+ {
+ const SfxPoolItem& rItem = rAttr.GetAttr();
+ rItem.QueryValue(*m_oRubyText);
+ rItem.QueryValue(*m_oRubyStyle, MID_RUBY_CHARSTYLE);
+ rItem.QueryValue(*m_oRubyAdjust, MID_RUBY_ADJUST);
+ rItem.QueryValue(*m_oRubyIsAbove, MID_RUBY_ABOVE);
+ rItem.QueryValue(*m_oRubyPosition, MID_RUBY_POSITION);
+ }
+}
+
+SwXTextPortion::~SwXTextPortion()
+{
+ SolarMutexGuard aGuard;
+ m_pUnoCursor.reset(nullptr);
+ EndListeningAll();
+}
+
+uno::Reference< text::XText > SwXTextPortion::getText()
+{
+ return m_xParentText;
+}
+
+uno::Reference< text::XTextRange > SwXTextPortion::getStart()
+{
+ SolarMutexGuard aGuard;
+ uno::Reference< text::XTextRange > xRet;
+ SwUnoCursor& rUnoCursor = GetCursor();
+
+ SwPaM aPam(*rUnoCursor.Start());
+ uno::Reference< text::XText > xParent = getText();
+ xRet = new SwXTextRange(aPam, xParent);
+ return xRet;
+}
+
+uno::Reference< text::XTextRange > SwXTextPortion::getEnd()
+{
+ SolarMutexGuard aGuard;
+ uno::Reference< text::XTextRange > xRet;
+ SwUnoCursor& rUnoCursor = GetCursor();
+
+ SwPaM aPam(*rUnoCursor.End());
+ uno::Reference< text::XText > xParent = getText();
+ xRet = new SwXTextRange(aPam, xParent);
+ return xRet;
+}
+
+OUString SwXTextPortion::getString()
+{
+ SolarMutexGuard aGuard;
+ OUString aText;
+ SwUnoCursor& rUnoCursor = GetCursor();
+
+ // TextPortions are always within a paragraph
+ SwTextNode* pTextNd = rUnoCursor.GetPointNode().GetTextNode();
+ if ( pTextNd )
+ {
+ const sal_Int32 nStt = rUnoCursor.Start()->GetContentIndex();
+ aText = pTextNd->GetExpandText(nullptr, nStt,
+ rUnoCursor.End()->GetContentIndex() - nStt,
+ false, false, false, ExpandMode::ExpandFootnote);
+ }
+ return aText;
+}
+
+void SwXTextPortion::setString(const OUString& aString)
+{
+ SolarMutexGuard aGuard;
+ SwUnoCursor& rUnoCursor = GetCursor();
+
+ SwUnoCursorHelper::SetString(rUnoCursor, aString);
+}
+
+uno::Reference< beans::XPropertySetInfo > SwXTextPortion::getPropertySetInfo()
+{
+ SolarMutexGuard aGuard;
+ //! PropertySetInfo for text portion extensions
+ static uno::Reference< beans::XPropertySetInfo >
+ xTextPorExtRef = aSwMapProvider.GetPropertySet(
+ PROPERTY_MAP_TEXTPORTION_EXTENSIONS)->getPropertySetInfo();
+ //! PropertySetInfo for redline portions
+ static uno::Reference< beans::XPropertySetInfo >
+ xRedlPorRef = aSwMapProvider.GetPropertySet(
+ PROPERTY_MAP_REDLINE_PORTION)->getPropertySetInfo();
+
+ return (PORTION_REDLINE_START == m_ePortionType ||
+ PORTION_REDLINE_END == m_ePortionType) ? xRedlPorRef : xTextPorExtRef;
+}
+
+void SwXTextPortion::setPropertyValue(const OUString& rPropertyName,
+ const uno::Any& aValue)
+{
+ SolarMutexGuard aGuard;
+ SwUnoCursor& rUnoCursor = GetCursor();
+
+ SwUnoCursorHelper::SetPropertyValue(rUnoCursor, *m_pPropSet,
+ rPropertyName, aValue);
+}
+
+void SwXTextPortion::GetPropertyValue(
+ uno::Any &rVal,
+ const SfxItemPropertyMapEntry& rEntry,
+ SwUnoCursor *pUnoCursor,
+ std::unique_ptr<SfxItemSet> &pSet )
+{
+ static constexpr OUStringLiteral TEXT = u"Text";
+ static constexpr OUStringLiteral TEXTFIELD = u"TextField";
+ static constexpr OUStringLiteral FRAME = u"Frame";
+ static constexpr OUStringLiteral FOOTNOTE = u"Footnote";
+ static constexpr OUStringLiteral REDLINE = u"Redline";
+ static constexpr OUStringLiteral RUBY = u"Ruby";
+ static constexpr OUStringLiteral SOFTPAGEBREAK = u"SoftPageBreak";
+ static constexpr OUStringLiteral TEXTFIELDSTART = u"TextFieldStart";
+ static constexpr OUStringLiteral TEXTFIELDSEPARATOR = u"TextFieldSeparator";
+ static constexpr OUStringLiteral TEXTFIELDEND = u"TextFieldEnd";
+ static constexpr OUStringLiteral TEXTFIELDSTARTEND = u"TextFieldStartEnd";
+ static constexpr OUStringLiteral ANNOTATION = u"Annotation";
+ static constexpr OUStringLiteral ANNOTATIONEND = u"AnnotationEnd";
+ static constexpr OUStringLiteral LINEBREAK = u"LineBreak";
+
+ OSL_ENSURE( pUnoCursor, "UNO cursor missing" );
+ if (!pUnoCursor)
+ return;
+ switch(rEntry.nWID)
+ {
+ case FN_UNO_TEXT_PORTION_TYPE:
+ {
+ OUString sRet;
+ switch (m_ePortionType)
+ {
+ case PORTION_TEXT: sRet = TEXT; break;
+ case PORTION_FIELD: sRet = TEXTFIELD; break;
+ case PORTION_FRAME: sRet = FRAME; break;
+ case PORTION_FOOTNOTE: sRet = FOOTNOTE; break;
+ case PORTION_REFMARK_START:
+ case PORTION_REFMARK_END: sRet = UNO_NAME_REFERENCE_MARK; break;
+ case PORTION_TOXMARK_START:
+ case PORTION_TOXMARK_END: sRet = UNO_NAME_DOCUMENT_INDEX_MARK; break;
+ case PORTION_BOOKMARK_START:
+ case PORTION_BOOKMARK_END : sRet = UNO_NAME_BOOKMARK; break;
+ case PORTION_REDLINE_START:
+ case PORTION_REDLINE_END: sRet = REDLINE; break;
+ case PORTION_RUBY_START:
+ case PORTION_RUBY_END: sRet = RUBY; break;
+ case PORTION_SOFT_PAGEBREAK: sRet = SOFTPAGEBREAK; break;
+ case PORTION_META: sRet = UNO_NAME_META; break;
+ case PORTION_FIELD_START: sRet = TEXTFIELDSTART; break;
+ case PORTION_FIELD_SEP: sRet = TEXTFIELDSEPARATOR; break;
+ case PORTION_FIELD_END: sRet = TEXTFIELDEND; break;
+ case PORTION_FIELD_START_END:sRet = TEXTFIELDSTARTEND; break;
+ case PORTION_ANNOTATION: sRet = ANNOTATION; break;
+ case PORTION_ANNOTATION_END: sRet = ANNOTATIONEND; break;
+ case PORTION_LINEBREAK: sRet = LINEBREAK; break;
+ case PORTION_CONTENT_CONTROL:sRet = UNO_NAME_CONTENT_CONTROL; break;
+ default: break;
+ }
+
+ rVal <<= sRet;
+ }
+ break;
+ case FN_UNO_CONTROL_CHARACTER: // obsolete!
+ break;
+ case FN_UNO_DOCUMENT_INDEX_MARK:
+ rVal <<= m_xTOXMark;
+ break;
+ case FN_UNO_REFERENCE_MARK:
+ rVal <<= m_xRefMark;
+ break;
+ case FN_UNO_BOOKMARK:
+ rVal <<= m_xBookmark;
+ break;
+ case FN_UNO_FOOTNOTE:
+ rVal <<= m_xFootnote;
+ break;
+ case FN_UNO_TEXT_FIELD:
+ rVal <<= m_xTextField;
+ break;
+ case FN_UNO_META:
+ rVal <<= m_xMeta;
+ break;
+ case FN_UNO_LINEBREAK:
+ rVal <<= m_xLineBreak;
+ break;
+ case FN_UNO_CONTENT_CONTROL:
+ rVal <<= m_xContentControl;
+ break;
+ case FN_UNO_IS_COLLAPSED:
+ {
+ switch (m_ePortionType)
+ {
+ case PORTION_REFMARK_START:
+ case PORTION_BOOKMARK_START :
+ case PORTION_TOXMARK_START:
+ case PORTION_REFMARK_END:
+ case PORTION_TOXMARK_END:
+ case PORTION_BOOKMARK_END :
+ case PORTION_REDLINE_START :
+ case PORTION_REDLINE_END :
+ case PORTION_RUBY_START:
+ case PORTION_RUBY_END:
+ case PORTION_FIELD_START:
+ case PORTION_FIELD_SEP:
+ case PORTION_FIELD_END:
+ rVal <<= m_bIsCollapsed;
+ break;
+ default:
+ break;
+ }
+ }
+ break;
+ case FN_UNO_IS_START:
+ {
+ bool bStart = true, bPut = true;
+ switch (m_ePortionType)
+ {
+ case PORTION_REFMARK_START:
+ case PORTION_BOOKMARK_START:
+ case PORTION_TOXMARK_START:
+ case PORTION_REDLINE_START:
+ case PORTION_RUBY_START:
+ case PORTION_FIELD_START:
+ break;
+
+ case PORTION_REFMARK_END:
+ case PORTION_TOXMARK_END:
+ case PORTION_BOOKMARK_END:
+ case PORTION_REDLINE_END:
+ case PORTION_RUBY_END:
+ case PORTION_FIELD_SEP:
+ case PORTION_FIELD_END:
+ bStart = false;
+ break;
+ default:
+ bPut = false;
+ }
+ if(bPut)
+ rVal <<= bStart;
+ }
+ break;
+ case RES_TXTATR_CJK_RUBY:
+ {
+ const std::optional<uno::Any>* pToSet = nullptr;
+ switch(rEntry.nMemberId)
+ {
+ case MID_RUBY_TEXT : pToSet = &m_oRubyText; break;
+ case MID_RUBY_ADJUST : pToSet = &m_oRubyAdjust; break;
+ case MID_RUBY_CHARSTYLE:pToSet = &m_oRubyStyle; break;
+ case MID_RUBY_ABOVE : pToSet = &m_oRubyIsAbove;break;
+ case MID_RUBY_POSITION: pToSet = &m_oRubyPosition;break;
+ }
+ if(pToSet && *pToSet)
+ rVal = **pToSet;
+ }
+ break;
+ default:
+ beans::PropertyState eTemp;
+ bool bDone = false;
+ if (m_bIsListAutoFormat)
+ {
+ SwTextNode* pTextNode = pUnoCursor->GetPointNode().GetTextNode();
+ std::shared_ptr<SfxItemSet> pListSet
+ = pTextNode->GetAttr(RES_PARATR_LIST_AUTOFMT).GetStyleHandle();
+ if (pListSet)
+ {
+ m_pPropSet->getPropertyValue(rEntry, *pListSet, rVal);
+ bDone = true;
+ }
+ }
+ if (!bDone)
+ {
+ bDone = SwUnoCursorHelper::getCursorPropertyValue(
+ rEntry, *pUnoCursor, &rVal, eTemp );
+ }
+ if(!bDone)
+ {
+ if(!pSet)
+ {
+ pSet = std::make_unique<SfxItemSetFixed<
+ RES_CHRATR_BEGIN, RES_FRMATR_END - 1,
+ RES_UNKNOWNATR_CONTAINER,
+ RES_UNKNOWNATR_CONTAINER>>(pUnoCursor->GetDoc().GetAttrPool());
+ SwUnoCursorHelper::GetCursorAttr(*pUnoCursor, *pSet);
+ }
+ m_pPropSet->getPropertyValue(rEntry, *pSet, rVal);
+ }
+ }
+}
+
+uno::Sequence< uno::Any > SwXTextPortion::GetPropertyValues_Impl(
+ const uno::Sequence< OUString >& rPropertyNames )
+{
+ sal_Int32 nLength = rPropertyNames.getLength();
+ const OUString *pPropertyNames = rPropertyNames.getConstArray();
+ uno::Sequence< uno::Any > aValues(nLength);
+ uno::Any *pValues = aValues.getArray();
+ SwUnoCursor& rUnoCursor = GetCursor();
+
+ {
+ std::unique_ptr<SfxItemSet> pSet;
+ // get starting point for the look-up, either the provided one or else
+ // from the beginning of the map
+ const SfxItemPropertyMap& rMap = m_pPropSet->getPropertyMap();
+ for(sal_Int32 nProp = 0; nProp < nLength; nProp++)
+ {
+ const SfxItemPropertyMapEntry* pEntry = rMap.getByName(pPropertyNames[nProp]);
+ if(!pEntry)
+ throw beans::UnknownPropertyException( "Unknown property: " + pPropertyNames[nProp], getXWeak() );
+ GetPropertyValue( pValues[nProp], *pEntry, &rUnoCursor, pSet );
+ }
+ }
+ return aValues;
+}
+
+uno::Any SwXTextPortion::getPropertyValue(
+ const OUString& rPropertyName)
+{
+ SolarMutexGuard aGuard;
+ uno::Sequence< OUString > aPropertyNames { rPropertyName };
+ return GetPropertyValues_Impl(aPropertyNames).getConstArray()[0];
+}
+
+void SwXTextPortion::SetPropertyValues_Impl(
+ const uno::Sequence< OUString >& rPropertyNames,
+ const uno::Sequence< uno::Any >& rValues )
+{
+ if (rPropertyNames.getLength() != rValues.getLength())
+ throw lang::IllegalArgumentException("lengths do not match",
+ getXWeak(), -1);
+
+ SwUnoCursor& rUnoCursor = GetCursor();
+
+ {
+ const OUString* pPropertyNames = rPropertyNames.getConstArray();
+ const uno::Any* pValues = rValues.getConstArray();
+ const SfxItemPropertyMap& rMap = m_pPropSet->getPropertyMap();
+ uno::Sequence< beans::PropertyValue > aValues( rPropertyNames.getLength() );
+ auto aValuesRange = asNonConstRange(aValues);
+ for(sal_Int32 nProp = 0; nProp < rPropertyNames.getLength(); nProp++)
+ {
+ const SfxItemPropertyMapEntry* pEntry = rMap.getByName(pPropertyNames[nProp]);
+ if (!pEntry)
+ throw beans::UnknownPropertyException( "Unknown property: " + pPropertyNames[nProp], getXWeak() );
+ if ( pEntry->nFlags & beans::PropertyAttribute::READONLY)
+ throw beans::PropertyVetoException ("Property is read-only: " + pPropertyNames[nProp], getXWeak() );
+
+ aValuesRange[nProp].Name = pPropertyNames[nProp];
+ aValuesRange[nProp].Value = pValues[nProp];
+ }
+ SwUnoCursorHelper::SetPropertyValues( rUnoCursor, *m_pPropSet, aValues );
+ }
+}
+
+void SwXTextPortion::setPropertyValues(
+ const uno::Sequence< OUString >& rPropertyNames,
+ const uno::Sequence< uno::Any >& rValues )
+{
+ SolarMutexGuard aGuard;
+
+ // workaround for bad designed API
+ try
+ {
+ SetPropertyValues_Impl( rPropertyNames, rValues );
+ }
+ catch (const beans::UnknownPropertyException &rException)
+ {
+ // wrap the original (here not allowed) exception in
+ // a lang::WrappedTargetException that gets thrown instead.
+ lang::WrappedTargetException aWExc;
+ aWExc.TargetException <<= rException;
+ throw aWExc;
+ }
+}
+
+uno::Sequence< uno::Any > SwXTextPortion::getPropertyValues(
+ const uno::Sequence< OUString >& rPropertyNames )
+{
+ SolarMutexGuard aGuard;
+ uno::Sequence< uno::Any > aValues;
+
+ // workaround for bad designed API
+ try
+ {
+ aValues = GetPropertyValues_Impl( rPropertyNames );
+ }
+ catch (beans::UnknownPropertyException &)
+ {
+ css::uno::Any anyEx = cppu::getCaughtException();
+ throw lang::WrappedTargetRuntimeException("Unknown property exception caught",
+ getXWeak(), anyEx );
+ }
+ catch (lang::WrappedTargetException &)
+ {
+ css::uno::Any anyEx = cppu::getCaughtException();
+ throw lang::WrappedTargetRuntimeException("WrappedTargetException caught",
+ getXWeak(), anyEx );
+ }
+
+ return aValues;
+}
+
+/* disabled for #i46921# */
+uno::Sequence< beans::SetPropertyTolerantFailed > SAL_CALL SwXTextPortion::setPropertyValuesTolerant(
+ const uno::Sequence< OUString >& rPropertyNames,
+ const uno::Sequence< uno::Any >& rValues )
+{
+ SolarMutexGuard aGuard;
+
+ if (rPropertyNames.getLength() != rValues.getLength())
+ throw lang::IllegalArgumentException();
+ SwUnoCursor& rUnoCursor = GetCursor();
+
+ sal_Int32 nProps = rPropertyNames.getLength();
+ const OUString *pProp = rPropertyNames.getConstArray();
+
+ //sal_Int32 nVals = rValues.getLength();
+ const uno::Any *pValue = rValues.getConstArray();
+
+ sal_Int32 nFailed = 0;
+ uno::Sequence< beans::SetPropertyTolerantFailed > aFailed( nProps );
+ beans::SetPropertyTolerantFailed *pFailed = aFailed.getArray();
+
+ const SfxItemPropertyMap& rPropMap = m_pPropSet->getPropertyMap();
+
+ for (sal_Int32 i = 0; i < nProps; ++i)
+ {
+ try
+ {
+ pFailed[ nFailed ].Name = pProp[i];
+
+ const SfxItemPropertyMapEntry* pEntry = rPropMap.getByName( pProp[i] );
+ if (!pEntry)
+ pFailed[ nFailed++ ].Result = beans::TolerantPropertySetResultType::UNKNOWN_PROPERTY;
+ else
+ {
+ // set property value
+ // (compare to SwXTextPortion::setPropertyValues)
+ if (pEntry->nFlags & beans::PropertyAttribute::READONLY)
+ pFailed[ nFailed++ ].Result = beans::TolerantPropertySetResultType::PROPERTY_VETO;
+ else
+ {
+ SwUnoCursorHelper::SetPropertyValue(
+ rUnoCursor, *m_pPropSet, pProp[i], pValue[i] );
+ }
+ }
+ }
+ catch (beans::UnknownPropertyException &)
+ {
+ // should not occur because property was searched for before
+ TOOLS_WARN_EXCEPTION( "sw", "" );
+ pFailed[ nFailed++ ].Result = beans::TolerantPropertySetResultType::UNKNOWN_PROPERTY;
+ }
+ catch (lang::IllegalArgumentException &)
+ {
+ pFailed[ nFailed++ ].Result = beans::TolerantPropertySetResultType::ILLEGAL_ARGUMENT;
+ }
+ catch (beans::PropertyVetoException &)
+ {
+ pFailed[ nFailed++ ].Result = beans::TolerantPropertySetResultType::PROPERTY_VETO;
+ }
+ catch (lang::WrappedTargetException &)
+ {
+ pFailed[ nFailed++ ].Result = beans::TolerantPropertySetResultType::WRAPPED_TARGET;
+ }
+ }
+
+ aFailed.realloc( nFailed );
+ return aFailed;
+}
+
+uno::Sequence< beans::GetPropertyTolerantResult > SAL_CALL SwXTextPortion::getPropertyValuesTolerant(
+ const uno::Sequence< OUString >& rPropertyNames )
+{
+ SolarMutexGuard aGuard;
+
+ const uno::Sequence< beans::GetDirectPropertyTolerantResult > aTmpRes(
+ GetPropertyValuesTolerant_Impl( rPropertyNames, false ) );
+
+ // copy temporary result to final result type
+ sal_Int32 nLen = aTmpRes.getLength();
+ uno::Sequence< beans::GetPropertyTolerantResult > aRes( nLen );
+ std::copy(aTmpRes.begin(), aTmpRes.end(), aRes.getArray());
+ return aRes;
+}
+
+uno::Sequence< beans::GetDirectPropertyTolerantResult > SAL_CALL SwXTextPortion::getDirectPropertyValuesTolerant(
+ const uno::Sequence< OUString >& rPropertyNames )
+{
+ SolarMutexGuard aGuard;
+ return GetPropertyValuesTolerant_Impl( rPropertyNames, true );
+}
+
+uno::Sequence< beans::GetDirectPropertyTolerantResult > SwXTextPortion::GetPropertyValuesTolerant_Impl(
+ const uno::Sequence< OUString >& rPropertyNames,
+ bool bDirectValuesOnly )
+{
+ SolarMutexGuard aGuard;
+
+ SwUnoCursor& rUnoCursor = GetCursor();
+
+ std::vector< beans::GetDirectPropertyTolerantResult > aResultVector;
+
+ try
+ {
+ sal_Int32 nProps = rPropertyNames.getLength();
+ const OUString *pProp = rPropertyNames.getConstArray();
+
+ std::unique_ptr<SfxItemSet> pSet;
+
+ const SfxItemPropertyMap& rPropMap = m_pPropSet->getPropertyMap();
+
+
+ uno::Sequence< beans::PropertyState > aPropertyStates;
+ if (m_bIsListAutoFormat)
+ {
+ SwTextNode* pTextNode = rUnoCursor.GetPointNode().GetTextNode();
+ std::shared_ptr<SfxItemSet> pListSet
+ = pTextNode->GetAttr(RES_PARATR_LIST_AUTOFMT).GetStyleHandle();
+ if (pListSet)
+ {
+ std::vector<beans::PropertyState> aStates;
+ for (const auto& rPropertyName : rPropertyNames)
+ {
+ aStates.push_back(m_pPropSet->getPropertyState(rPropertyName, *pListSet));
+ }
+ aPropertyStates = comphelper::containerToSequence(aStates);
+ }
+ }
+ if (!aPropertyStates.hasElements())
+ {
+ aPropertyStates =
+ SwUnoCursorHelper::GetPropertyStates(
+ rUnoCursor, *m_pPropSet,
+ rPropertyNames,
+ SW_PROPERTY_STATE_CALLER_SWX_TEXT_PORTION_TOLERANT );
+ }
+ const beans::PropertyState* pPropertyStates = aPropertyStates.getConstArray();
+
+ for (sal_Int32 i = 0; i < nProps; ++i)
+ {
+ beans::GetDirectPropertyTolerantResult aResult;
+ try
+ {
+ aResult.Name = pProp[i];
+ if(pPropertyStates[i] == beans::PropertyState::PropertyState_MAKE_FIXED_SIZE) // property unknown?
+ {
+ if( bDirectValuesOnly )
+ continue;
+ else
+ aResult.Result = beans::TolerantPropertySetResultType::UNKNOWN_PROPERTY;
+ }
+ else
+ {
+ const SfxItemPropertyMapEntry* pEntry = rPropMap.getByName( pProp[i] );
+ if (!pEntry)
+ throw beans::UnknownPropertyException( "Unknown property: " + pProp[i], getXWeak() );
+ aResult.State = pPropertyStates[i];
+
+ aResult.Result = beans::TolerantPropertySetResultType::UNKNOWN_FAILURE;
+ //#i104499# ruby portion attributes need special handling:
+ if( pEntry->nWID == RES_TXTATR_CJK_RUBY &&
+ m_ePortionType == PORTION_RUBY_START )
+ {
+ aResult.State = beans::PropertyState_DIRECT_VALUE;
+ }
+ if (!bDirectValuesOnly || beans::PropertyState_DIRECT_VALUE == aResult.State)
+ {
+ // get property value
+ // (compare to SwXTextPortion::getPropertyValue(s))
+ GetPropertyValue( aResult.Value, *pEntry, &rUnoCursor, pSet );
+ aResult.Result = beans::TolerantPropertySetResultType::SUCCESS;
+ aResultVector.push_back( aResult );
+ }
+ }
+ }
+ catch (const beans::UnknownPropertyException &)
+ {
+ // should not occur because property was searched for before
+ TOOLS_WARN_EXCEPTION( "sw", "unexpected exception caught" );
+ aResult.Result = beans::TolerantPropertySetResultType::UNKNOWN_PROPERTY;
+ }
+ catch (const lang::IllegalArgumentException &)
+ {
+ aResult.Result = beans::TolerantPropertySetResultType::ILLEGAL_ARGUMENT;
+ }
+ catch (const beans::PropertyVetoException &)
+ {
+ aResult.Result = beans::TolerantPropertySetResultType::PROPERTY_VETO;
+ }
+ catch (const lang::WrappedTargetException &)
+ {
+ aResult.Result = beans::TolerantPropertySetResultType::WRAPPED_TARGET;
+ }
+ }
+ }
+ catch (const uno::RuntimeException&)
+ {
+ throw;
+ }
+ catch (const uno::Exception& e)
+ {
+ css::uno::Any a(cppu::getCaughtException());
+ throw css::lang::WrappedTargetRuntimeException(
+ "wrapped Exception " + e.Message,
+ css::uno::Reference<css::uno::XInterface>(), a);
+ }
+
+ return comphelper::containerToSequence(aResultVector);
+}
+
+void SwXTextPortion::addPropertiesChangeListener(
+ const uno::Sequence< OUString >& /*aPropertyNames*/,
+ const uno::Reference< beans::XPropertiesChangeListener >& /*xListener*/ )
+{}
+
+void SwXTextPortion::removePropertiesChangeListener(
+ const uno::Reference< beans::XPropertiesChangeListener >& /*xListener*/ )
+{}
+
+void SwXTextPortion::firePropertiesChangeEvent(
+ const uno::Sequence< OUString >& /*aPropertyNames*/,
+ const uno::Reference< beans::XPropertiesChangeListener >& /*xListener*/ )
+{}
+
+void SwXTextPortion::addPropertyChangeListener(
+ const OUString& /*PropertyName*/,
+ const uno::Reference< beans::XPropertyChangeListener > & /*xListener*/)
+{
+ OSL_FAIL("not implemented");
+}
+
+void SwXTextPortion::removePropertyChangeListener(const OUString& /*rPropertyName*/, const uno::Reference< beans::XPropertyChangeListener > & /*aListener*/)
+{
+ OSL_FAIL("not implemented");
+}
+
+void SwXTextPortion::addVetoableChangeListener(const OUString& /*rPropertyName*/, const uno::Reference< beans::XVetoableChangeListener > & /*aListener*/)
+{
+ OSL_FAIL("not implemented");
+}
+
+void SwXTextPortion::removeVetoableChangeListener(const OUString& /*rPropertyName*/, const uno::Reference< beans::XVetoableChangeListener > & /*aListener*/)
+{
+ OSL_FAIL("not implemented");
+}
+
+beans::PropertyState SwXTextPortion::getPropertyState(const OUString& rPropertyName)
+{
+ SolarMutexGuard aGuard;
+ beans::PropertyState eRet = beans::PropertyState_DEFAULT_VALUE;
+ SwUnoCursor& rUnoCursor = GetCursor();
+
+ if (GetTextPortionType() == PORTION_RUBY_START &&
+ rPropertyName.startsWith("Ruby"))
+ {
+ eRet = beans::PropertyState_DIRECT_VALUE;
+ }
+ else
+ {
+ eRet = SwUnoCursorHelper::GetPropertyState(rUnoCursor, *m_pPropSet,
+ rPropertyName);
+ }
+ return eRet;
+}
+
+uno::Sequence< beans::PropertyState > SwXTextPortion::getPropertyStates(
+ const uno::Sequence< OUString >& rPropertyNames)
+{
+ SolarMutexGuard aGuard;
+ SwUnoCursor& rUnoCursor = GetCursor();
+
+ uno::Sequence< beans::PropertyState > aRet =
+ SwUnoCursorHelper::GetPropertyStates(rUnoCursor, *m_pPropSet,
+ rPropertyNames, SW_PROPERTY_STATE_CALLER_SWX_TEXT_PORTION);
+
+ if(GetTextPortionType() == PORTION_RUBY_START)
+ {
+ const OUString* pNames = rPropertyNames.getConstArray();
+ beans::PropertyState* pStates = aRet.getArray();
+ for(sal_Int32 nProp = 0; nProp < rPropertyNames.getLength();nProp++)
+ {
+ if (pNames[nProp].startsWith("Ruby"))
+ pStates[nProp] = beans::PropertyState_DIRECT_VALUE;
+ }
+ }
+ return aRet;
+}
+
+void SwXTextPortion::setPropertyToDefault(const OUString& rPropertyName)
+{
+ SolarMutexGuard aGuard;
+ SwUnoCursor& rUnoCursor = GetCursor();
+
+ SwUnoCursorHelper::SetPropertyToDefault(
+ rUnoCursor, *m_pPropSet, rPropertyName);
+}
+
+uno::Any SwXTextPortion::getPropertyDefault(const OUString& rPropertyName)
+{
+ SolarMutexGuard aGuard;
+ uno::Any aRet;
+ SwUnoCursor& rUnoCursor = GetCursor();
+
+ aRet = SwUnoCursorHelper::GetPropertyDefault(rUnoCursor, *m_pPropSet,
+ rPropertyName);
+ return aRet;
+}
+
+uno::Reference< container::XEnumeration > SwXTextPortion::createContentEnumeration(const OUString& /*aServiceName*/)
+{
+ SolarMutexGuard aGuard;
+ SwUnoCursor& rUnoCursor = GetCursor();
+
+ return SwXParaFrameEnumeration::Create(rUnoCursor, PARAFRAME_PORTION_CHAR, m_pFrameFormat);
+}
+
+uno::Sequence< OUString > SwXTextPortion::getAvailableServiceNames()
+{
+ return { "com.sun.star.text.TextContent" };
+}
+
+OUString SwXTextPortion::getImplementationName()
+{
+ return { "SwXTextPortion" };
+}
+
+sal_Bool SwXTextPortion::supportsService(const OUString& rServiceName)
+{
+ return cppu::supportsService(this, rServiceName);
+}
+
+uno::Sequence< OUString > SwXTextPortion::getSupportedServiceNames()
+{
+ return { "com.sun.star.text.TextPortion",
+ "com.sun.star.style.CharacterProperties",
+ "com.sun.star.style.CharacterPropertiesAsian",
+ "com.sun.star.style.CharacterPropertiesComplex",
+ "com.sun.star.style.ParagraphProperties",
+ "com.sun.star.style.ParagraphPropertiesAsian",
+ "com.sun.star.style.ParagraphPropertiesComplex" };
+}
+
+void SwXTextPortion::Notify(const SfxHint& rHint)
+{
+ if(rHint.GetId() == SfxHintId::Dying)
+ m_pFrameFormat = nullptr;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/core/unocore/unoportenum.cxx b/sw/source/core/unocore/unoportenum.cxx
new file mode 100644
index 0000000000..4b50a72cf5
--- /dev/null
+++ b/sw/source/core/unocore/unoportenum.cxx
@@ -0,0 +1,1526 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <sal/config.h>
+#include <sal/log.hxx>
+
+#include <utility>
+
+#include <unoport.hxx>
+#include <unotext.hxx>
+#include <IMark.hxx>
+#include <crossrefbookmark.hxx>
+#include <annotationmark.hxx>
+#include <doc.hxx>
+#include <IDocumentRedlineAccess.hxx>
+#include <txatbase.hxx>
+#include <txtatr.hxx>
+#include <ndhints.hxx>
+#include <ndtxt.hxx>
+#include <unocrsr.hxx>
+#include <docary.hxx>
+#include <textboxhelper.hxx>
+#include <tox.hxx>
+#include <unoparaframeenum.hxx>
+#include <unocrsrhelper.hxx>
+#include <unorefmark.hxx>
+#include <unobookmark.hxx>
+#include <unofield.hxx>
+#include <unometa.hxx>
+#include <unolinebreak.hxx>
+#include <unocontentcontrol.hxx>
+#include <fmtfld.hxx>
+#include <fldbas.hxx>
+#include <fmtmeta.hxx>
+#include <fmtanchr.hxx>
+#include <fmtrfmrk.hxx>
+#include <frmfmt.hxx>
+#include <fmtflcnt.hxx>
+#include <unoidx.hxx>
+#include <unocoll.hxx>
+#include <redline.hxx>
+#include <txtannotationfld.hxx>
+#include <vcl/svapp.hxx>
+#include <comphelper/string.hxx>
+#include <comphelper/servicehelper.hxx>
+#include <cppuhelper/supportsservice.hxx>
+#include <com/sun/star/container/XEnumeration.hpp>
+#include <algorithm>
+#include <memory>
+#include <set>
+#include <stack>
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::text;
+
+typedef std::pair< TextRangeList_t * const, SwTextAttr const * const > PortionList_t;
+typedef std::stack< PortionList_t > PortionStack_t;
+
+static void lcl_CreatePortions(
+ TextRangeList_t & i_rPortions,
+ css::uno::Reference< SwXText > const& i_xParentText,
+ SwUnoCursor* pUnoCursor,
+ FrameClientSortList_t & i_rFrames,
+ const sal_Int32 i_nStartPos, const sal_Int32 i_nEndPos, bool bOnlyTextFields );
+
+namespace
+{
+ enum class BkmType {
+ Start, End, StartEnd
+ };
+
+ struct SwXBookmarkPortion_Impl
+ {
+ Reference<XTextContent> xBookmark;
+ BkmType nBkmType;
+ const SwPosition aPosition;
+
+ SwXBookmarkPortion_Impl(uno::Reference<text::XTextContent> xMark,
+ const BkmType nType, SwPosition _aPosition)
+ : xBookmark (std::move( xMark ))
+ , nBkmType ( nType )
+ , aPosition (std::move( _aPosition ))
+ {
+ }
+ sal_Int32 getIndex () const
+ {
+ return aPosition.GetContentIndex();
+ }
+ };
+ typedef std::shared_ptr < SwXBookmarkPortion_Impl > SwXBookmarkPortion_ImplSharedPtr;
+ struct BookmarkCompareStruct
+ {
+ bool operator () ( const SwXBookmarkPortion_ImplSharedPtr &r1,
+ const SwXBookmarkPortion_ImplSharedPtr &r2 ) const
+ {
+ // #i16896# for bookmark portions at the same position, the start should
+ // always precede the end. Hence compare positions, and use bookmark type
+ // as tie-breaker for same position.
+ // return ( r1->nIndex == r2->nIndex )
+ // ? ( r1->nBkmType < r2->nBkmType )
+ // : ( r1->nIndex < r2->nIndex );
+
+ // Note that the above code does not correctly handle
+ // the case when one bookmark ends, and another begins in the same
+ // position. When this occurs, the above code will return the
+ // start of the 2nd bookmark BEFORE the end of the first bookmark
+ // See bug #i58438# for more details. The below code is correct and
+ // fixes both #i58438 and #i16896#
+ return r1->aPosition < r2->aPosition;
+ }
+ };
+ typedef std::multiset < SwXBookmarkPortion_ImplSharedPtr, BookmarkCompareStruct > SwXBookmarkPortion_ImplList;
+
+ /// Inserts pBkmk to rBkmArr in case it starts or ends at rOwnNode
+ void lcl_FillBookmark(sw::mark::IMark* const pBkmk, const SwNode& rOwnNode, SwDoc& rDoc, SwXBookmarkPortion_ImplList& rBkmArr)
+ {
+ bool const hasOther = pBkmk->IsExpanded();
+
+ const SwPosition& rStartPos = pBkmk->GetMarkStart();
+ if(rStartPos.GetNode() == rOwnNode)
+ {
+ // #i109272#: cross reference marks: need special handling!
+ ::sw::mark::CrossRefBookmark *const pCrossRefMark(dynamic_cast< ::sw::mark::CrossRefBookmark*>(pBkmk));
+ BkmType const nType = (hasOther || pCrossRefMark)
+ ? BkmType::Start : BkmType::StartEnd;
+ rBkmArr.insert(std::make_shared<SwXBookmarkPortion_Impl>(
+ SwXBookmark::CreateXBookmark(rDoc, pBkmk),
+ nType, rStartPos));
+ }
+
+ const SwPosition& rEndPos = pBkmk->GetMarkEnd();
+ if(rEndPos.GetNode() != rOwnNode)
+ return;
+
+ std::optional<SwPosition> oCrossRefEndPos;
+ const SwPosition* pEndPos = nullptr;
+ ::sw::mark::CrossRefBookmark *const pCrossRefMark(dynamic_cast< ::sw::mark::CrossRefBookmark*>(pBkmk));
+ if(hasOther)
+ {
+ pEndPos = &rEndPos;
+ }
+ else if (pCrossRefMark)
+ {
+ // Crossrefbookmarks only remember the start position but have to span the whole paragraph
+ SwTextNode& rEndNd = *rEndPos.GetNode().GetTextNode();
+ oCrossRefEndPos.emplace(rEndNd, rEndNd.Len());
+ pEndPos = &*oCrossRefEndPos;
+ }
+ if(pEndPos)
+ {
+ rBkmArr.insert(std::make_shared<SwXBookmarkPortion_Impl>(
+ SwXBookmark::CreateXBookmark(rDoc, pBkmk),
+ BkmType::End, *pEndPos));
+ }
+ }
+
+ void lcl_FillBookmarkArray(SwDoc& rDoc, SwUnoCursor& rUnoCursor, SwXBookmarkPortion_ImplList& rBkmArr)
+ {
+ IDocumentMarkAccess* const pMarkAccess = rDoc.getIDocumentMarkAccess();
+ if(!pMarkAccess->getBookmarksCount())
+ return;
+
+ SwTextNode* pTextNode = rUnoCursor.GetPoint()->GetNode().GetTextNode();
+ assert(pTextNode);
+ // A text node already knows its marks via its SwIndexes.
+ o3tl::sorted_vector<const sw::mark::IMark*> aSeenMarks;
+ for (const SwContentIndex* pIndex = pTextNode->GetFirstIndex(); pIndex; pIndex = pIndex->GetNext())
+ {
+ // Need a non-cost mark here, as we'll create a UNO wrapper around it.
+ sw::mark::IMark* pBkmk = const_cast<sw::mark::IMark*>(pIndex->GetMark());
+ if (!pBkmk)
+ continue;
+ IDocumentMarkAccess::MarkType eType = IDocumentMarkAccess::GetType(*pBkmk);
+ // These are the types stored in the container otherwise accessible via getBookmarks*()
+ if (eType != IDocumentMarkAccess::MarkType::BOOKMARK && eType != IDocumentMarkAccess::MarkType::CROSSREF_NUMITEM_BOOKMARK &&
+ eType != IDocumentMarkAccess::MarkType::CROSSREF_HEADING_BOOKMARK)
+ continue;
+ // Only handle bookmarks once, if they start and end at this node as well.
+ if (!aSeenMarks.insert(pBkmk).second)
+ continue;
+ lcl_FillBookmark(pBkmk, *pTextNode, rDoc, rBkmArr);
+ }
+ }
+
+ struct SwAnnotationStartPortion_Impl
+ {
+
+ uno::Reference< text::XTextField > mxAnnotationField;
+ const SwPosition maPosition;
+
+ SwAnnotationStartPortion_Impl(
+ uno::Reference< text::XTextField > xAnnotationField,
+ SwPosition aPosition)
+ : mxAnnotationField (std::move( xAnnotationField ))
+ , maPosition (std::move( aPosition ))
+ {
+ }
+
+ sal_Int32 getIndex () const
+ {
+ return maPosition.GetContentIndex();
+ }
+ };
+ typedef std::shared_ptr < SwAnnotationStartPortion_Impl > SwAnnotationStartPortion_ImplSharedPtr;
+ struct AnnotationStartCompareStruct
+ {
+ bool operator () ( const SwAnnotationStartPortion_ImplSharedPtr &r1,
+ const SwAnnotationStartPortion_ImplSharedPtr &r2 )
+ const
+ {
+ return r1->maPosition < r2->maPosition;
+ }
+ };
+ typedef std::multiset < SwAnnotationStartPortion_ImplSharedPtr, AnnotationStartCompareStruct > SwAnnotationStartPortion_ImplList;
+
+ void lcl_FillAnnotationStartArray(
+ SwDoc& rDoc,
+ SwUnoCursor& rUnoCursor,
+ SwAnnotationStartPortion_ImplList& rAnnotationStartArr )
+ {
+ IDocumentMarkAccess* const pMarkAccess = rDoc.getIDocumentMarkAccess();
+ if ( pMarkAccess->getAnnotationMarksCount() == 0 )
+ {
+ return;
+ }
+
+ // no need to consider annotation marks starting after aEndOfPara
+ SwContentNode& rPtNd = *rUnoCursor.GetPoint()->GetNode().GetContentNode();
+ SwPosition aEndOfPara( rPtNd, rPtNd.Len() );
+ const IDocumentMarkAccess::const_iterator_t pCandidatesEnd =
+ pMarkAccess->findFirstAnnotationStartsAfter(aEndOfPara);
+
+ // search for all annotation marks that have its start position in this paragraph
+ const SwNode& rOwnNode = rUnoCursor.GetPoint()->GetNode();
+ for( IDocumentMarkAccess::const_iterator_t ppMark = pMarkAccess->getAnnotationMarksBegin();
+ ppMark != pCandidatesEnd;
+ ++ppMark )
+ {
+ ::sw::mark::AnnotationMark* const pAnnotationMark =
+ dynamic_cast< ::sw::mark::AnnotationMark* >(*ppMark);
+
+ if (!pAnnotationMark)
+ continue;
+
+ const SwPosition& rStartPos = pAnnotationMark->GetMarkStart();
+ if (rStartPos.GetNode() != rOwnNode)
+ continue;
+
+ const SwFormatField* pAnnotationFormatField = pAnnotationMark->GetAnnotationFormatField();
+ if (!pAnnotationFormatField)
+ {
+ SAL_WARN("sw.core", "missing annotation format field");
+ continue;
+ }
+
+ rAnnotationStartArr.insert(
+ std::make_shared<SwAnnotationStartPortion_Impl>(
+ SwXTextField::CreateXTextField(&rDoc,
+ pAnnotationFormatField),
+ rStartPos));
+ }
+ }
+}
+
+OUString SwXTextPortionEnumeration::getImplementationName()
+{
+ return "SwXTextPortionEnumeration";
+}
+
+sal_Bool
+SwXTextPortionEnumeration::supportsService(const OUString& rServiceName)
+{
+ return cppu::supportsService(this, rServiceName);
+}
+
+Sequence< OUString > SwXTextPortionEnumeration::getSupportedServiceNames()
+{
+ return { "com.sun.star.text.TextPortionEnumeration" };
+}
+
+SwXTextPortionEnumeration::SwXTextPortionEnumeration(
+ SwPaM& rParaCursor,
+ css::uno::Reference< SwXText > const & xParentText,
+ const sal_Int32 nStart,
+ const sal_Int32 nEnd,
+ bool bOnlyTextFields)
+{
+ m_pUnoCursor = rParaCursor.GetDoc().CreateUnoCursor(*rParaCursor.GetPoint());
+
+ OSL_ENSURE(nEnd == -1 || (nStart <= nEnd &&
+ nEnd <= m_pUnoCursor->Start()->GetNode().GetTextNode()->GetText().getLength()),
+ "start or end value invalid!");
+
+ // find all frames, graphics and OLEs that are bound AT character in para
+ FrameClientSortList_t frames;
+ ::CollectFrameAtNode(m_pUnoCursor->GetPoint()->GetNode(), frames, true);
+ lcl_CreatePortions(m_Portions, xParentText, &*m_pUnoCursor, frames, nStart, nEnd, bOnlyTextFields);
+}
+
+SwXTextPortionEnumeration::SwXTextPortionEnumeration(
+ SwPaM& rParaCursor,
+ TextRangeList_t && rPortions )
+ : m_Portions( std::move(rPortions) )
+{
+ m_pUnoCursor = rParaCursor.GetDoc().CreateUnoCursor(*rParaCursor.GetPoint());
+}
+
+SwXTextPortionEnumeration::~SwXTextPortionEnumeration()
+{
+ SolarMutexGuard aGuard;
+ if( m_pUnoCursor )
+ {
+ m_pUnoCursor->GetDoc().cleanupUnoCursorTable();
+ m_pUnoCursor.reset(nullptr);
+ }
+}
+
+sal_Bool SwXTextPortionEnumeration::hasMoreElements()
+{
+ SolarMutexGuard aGuard;
+
+ return !m_Portions.empty();
+}
+
+uno::Any SwXTextPortionEnumeration::nextElement()
+{
+ SolarMutexGuard aGuard;
+
+ if (m_Portions.empty())
+ throw container::NoSuchElementException();
+
+ Any any;
+ any <<= uno::Reference<XTextRange>(m_Portions.front());
+ m_Portions.pop_front();
+ return any;
+}
+
+static void
+lcl_FillFieldMarkArray(std::deque<sal_Int32> & rFieldMarks, SwUnoCursor const & rUnoCursor,
+ const sal_Int32 i_nStartPos)
+{
+ const SwTextNode * const pTextNode =
+ rUnoCursor.GetPoint()->GetNode().GetTextNode();
+ if (!pTextNode) return;
+
+ const sal_Unicode fld[] = {
+ CH_TXT_ATR_FIELDSTART, CH_TXT_ATR_FIELDSEP, CH_TXT_ATR_FIELDEND, CH_TXT_ATR_FORMELEMENT, 0 };
+ sal_Int32 pos = std::max(static_cast<sal_Int32>(0), i_nStartPos);
+ while ((pos = ::comphelper::string::indexOfAny(pTextNode->GetText(), fld, pos)) != -1)
+ {
+ rFieldMarks.push_back(pos);
+ ++pos;
+ }
+}
+
+static rtl::Reference<SwXTextPortion>
+lcl_ExportFieldMark(
+ uno::Reference< text::XText > const & i_xParentText,
+ SwUnoCursor * const pUnoCursor,
+ const SwTextNode * const pTextNode )
+{
+ rtl::Reference<SwXTextPortion> pPortion;
+ SwDoc& rDoc = pUnoCursor->GetDoc();
+ // maybe it's a good idea to add a special hint to the hints array and rely on the hint segmentation...
+ const sal_Int32 start = pUnoCursor->Start()->GetContentIndex();
+ OSL_ENSURE(pUnoCursor->End()->GetContentIndex() == start,
+ "hmm --- why is this different");
+
+ pUnoCursor->Right(1);
+ if ( *pUnoCursor->GetMark() == *pUnoCursor->GetPoint() )
+ {
+ OSL_FAIL("cannot move cursor?");
+ return nullptr;
+ }
+
+ const sal_Unicode Char = pTextNode->GetText()[start];
+ if (CH_TXT_ATR_FIELDSTART == Char)
+ {
+ ::sw::mark::IFieldmark* pFieldmark = nullptr;
+ pFieldmark = rDoc.getIDocumentMarkAccess()->
+ getFieldmarkAt(*pUnoCursor->GetMark());
+ pPortion = new SwXTextPortion(
+ pUnoCursor, i_xParentText, PORTION_FIELD_START);
+ if (pFieldmark)
+ {
+ pPortion->SetBookmark(
+ SwXFieldmark::CreateXFieldmark(rDoc, pFieldmark));
+ }
+ }
+ else if (CH_TXT_ATR_FIELDSEP == Char)
+ {
+ // TODO how to get the field?
+ pPortion = new SwXTextPortion(
+ pUnoCursor, i_xParentText, PORTION_FIELD_SEP);
+ }
+ else if (CH_TXT_ATR_FIELDEND == Char)
+ {
+ ::sw::mark::IFieldmark* pFieldmark = nullptr;
+ pFieldmark = rDoc.getIDocumentMarkAccess()->
+ getFieldmarkAt(*pUnoCursor->GetMark());
+ pPortion = new SwXTextPortion(
+ pUnoCursor, i_xParentText, PORTION_FIELD_END);
+ if (pFieldmark)
+ {
+ pPortion->SetBookmark(
+ SwXFieldmark::CreateXFieldmark(rDoc, pFieldmark));
+ }
+ }
+ else if (CH_TXT_ATR_FORMELEMENT == Char)
+ {
+ ::sw::mark::IFieldmark* pFieldmark =
+ rDoc.getIDocumentMarkAccess()->getFieldmarkAt(*pUnoCursor->GetMark());
+ pPortion = new SwXTextPortion(
+ pUnoCursor, i_xParentText, PORTION_FIELD_START_END);
+ if (pFieldmark)
+ {
+ pPortion->SetBookmark(
+ SwXFieldmark::CreateXFieldmark(rDoc, pFieldmark));
+ }
+ }
+ else
+ {
+ OSL_FAIL("no fieldmark found?");
+ }
+ return pPortion;
+}
+
+static rtl::Reference<SwXTextPortion>
+lcl_CreateRefMarkPortion(
+ Reference<XText> const& xParent,
+ const SwUnoCursor * const pUnoCursor,
+ const SwTextAttr & rAttr, const bool bEnd)
+{
+ SwDoc& rDoc = pUnoCursor->GetDoc();
+ SwFormatRefMark& rRefMark = const_cast<SwFormatRefMark&>(
+ static_cast<const SwFormatRefMark&>(rAttr.GetAttr()));
+ Reference<XTextContent> xContent;
+ if (!xContent.is())
+ {
+ xContent = SwXReferenceMark::CreateXReferenceMark(rDoc, &rRefMark);
+ }
+
+ rtl::Reference<SwXTextPortion> pPortion;
+ if (!bEnd)
+ {
+ pPortion = new SwXTextPortion(pUnoCursor, xParent, PORTION_REFMARK_START);
+ pPortion->SetRefMark(xContent);
+ pPortion->SetCollapsed(rAttr.End() == nullptr);
+ }
+ else
+ {
+ pPortion = new SwXTextPortion(pUnoCursor, xParent, PORTION_REFMARK_END);
+ pPortion->SetRefMark(xContent);
+ }
+ return pPortion;
+}
+
+static void
+lcl_InsertRubyPortion(
+ TextRangeList_t & rPortions,
+ Reference<XText> const& xParent,
+ const SwUnoCursor * const pUnoCursor,
+ const SwTextAttr & rAttr, const bool bEnd)
+{
+ rtl::Reference<SwXTextPortion> pPortion = new SwXTextPortion(pUnoCursor,
+ static_txtattr_cast<const SwTextRuby&>(rAttr), xParent, bEnd);
+ rPortions.emplace_back(pPortion);
+ pPortion->SetCollapsed(rAttr.End() == nullptr);
+}
+
+static rtl::Reference<SwXTextPortion>
+lcl_CreateTOXMarkPortion(
+ Reference<XText> const& xParent,
+ const SwUnoCursor * const pUnoCursor,
+ SwTextAttr & rAttr, const bool bEnd)
+{
+ SwDoc& rDoc = pUnoCursor->GetDoc();
+ SwTOXMark & rTOXMark = static_cast<SwTOXMark&>(rAttr.GetAttr());
+
+ const Reference<XTextContent> xContent =
+ SwXDocumentIndexMark::CreateXDocumentIndexMark(rDoc, & rTOXMark);
+
+ rtl::Reference<SwXTextPortion> pPortion;
+ if (!bEnd)
+ {
+ pPortion = new SwXTextPortion(pUnoCursor, xParent, PORTION_TOXMARK_START);
+ pPortion->SetTOXMark(xContent);
+ pPortion->SetCollapsed(rAttr.GetEnd() == nullptr);
+ }
+ else
+ {
+ pPortion = new SwXTextPortion(pUnoCursor, xParent, PORTION_TOXMARK_END);
+ pPortion->SetTOXMark(xContent);
+ }
+ return pPortion;
+}
+
+static rtl::Reference<SwXTextPortion>
+lcl_CreateMetaPortion(
+ css::uno::Reference<SwXText> const& xParent,
+ const SwUnoCursor * const pUnoCursor,
+ SwTextAttr & rAttr, std::unique_ptr<TextRangeList_t const> && pPortions)
+{
+ const rtl::Reference<SwXMeta> xMeta( SwXMeta::CreateXMeta(
+ *static_cast<SwFormatMeta &>(rAttr.GetAttr()).GetMeta(),
+ xParent, std::move(pPortions)));
+ rtl::Reference<SwXTextPortion> pPortion;
+ if (RES_TXTATR_META == rAttr.Which())
+ {
+ pPortion = new SwXTextPortion(pUnoCursor, xParent, PORTION_META);
+ pPortion->SetMeta(xMeta);
+ }
+ else
+ {
+ const uno::Reference<text::XTextField> xField(static_cast<cppu::OWeakObject*>(xMeta.get()), uno::UNO_QUERY);
+ pPortion = new SwXTextPortion(pUnoCursor, xParent, PORTION_FIELD);
+ pPortion->SetTextField(xField);
+ }
+ return pPortion;
+}
+
+/// Creates a text portion that has a non-empty ContentControl property.
+static rtl::Reference<SwXTextPortion>
+lcl_CreateContentControlPortion(const css::uno::Reference<SwXText>& xParent,
+ const SwUnoCursor* pUnoCursor, SwTextAttr& rAttr,
+ std::unique_ptr<const TextRangeList_t>&& pPortions)
+{
+ rtl::Reference<SwXContentControl> xContentControl = SwXContentControl::CreateXContentControl(
+ *static_cast<SwFormatContentControl&>(rAttr.GetAttr()).GetContentControl(), xParent,
+ std::move(pPortions));
+ rtl::Reference<SwXTextPortion> pPortion;
+ pPortion = new SwXTextPortion(pUnoCursor, xParent, PORTION_CONTENT_CONTROL);
+ pPortion->SetContentControl(xContentControl);
+ return pPortion;
+}
+
+/**
+ * Exports all bookmarks from rBkmArr into rPortions that have the same start
+ * or end position as nIndex.
+ *
+ * @param rBkmArr the array of bookmarks. If bOnlyFrameStarts is true, then
+ * this is only read, otherwise consumed entries are removed.
+ *
+ * @param rFramePositions the list of positions where there is an at-char /
+ * anchored frame.
+ *
+ * @param bOnlyFrameStarts If true: export only the start of the bookmarks
+ * which cover an at-char anchored frame. If false: export the end of the same
+ * bookmarks and everything else.
+ */
+static void lcl_ExportBookmark(
+ TextRangeList_t & rPortions,
+ Reference<XText> const& xParent,
+ const SwUnoCursor * const pUnoCursor,
+ SwXBookmarkPortion_ImplList& rBkmArr,
+ const sal_Int32 nIndex,
+ const o3tl::sorted_vector<sal_Int32>& rFramePositions,
+ bool bOnlyFrameStarts)
+{
+ for ( SwXBookmarkPortion_ImplList::iterator aIter = rBkmArr.begin(), aEnd = rBkmArr.end(); aIter != aEnd; )
+ {
+ const SwXBookmarkPortion_ImplSharedPtr& pPtr = *aIter;
+ if ( nIndex > pPtr->getIndex() )
+ {
+ if (bOnlyFrameStarts)
+ ++aIter;
+ else
+ aIter = rBkmArr.erase(aIter);
+ continue;
+ }
+ if ( nIndex < pPtr->getIndex() )
+ break;
+
+ if ((BkmType::Start == pPtr->nBkmType && bOnlyFrameStarts) ||
+ (BkmType::StartEnd == pPtr->nBkmType))
+ {
+ bool bFrameStart = rFramePositions.find(nIndex) != rFramePositions.end();
+ bool bEnd = pPtr->nBkmType == BkmType::StartEnd && bFrameStart && !bOnlyFrameStarts;
+ if (pPtr->nBkmType == BkmType::Start || bFrameStart || !bOnlyFrameStarts)
+ {
+ // At this we create a text portion, due to one of these
+ // reasons:
+ // - this is the real start of a non-collapsed bookmark
+ // - this is the real position of a collapsed bookmark
+ // - this is the start or end (depending on bOnlyFrameStarts)
+ // of a collapsed bookmark at the same position as an at-char
+ // anchored frame
+ rtl::Reference<SwXTextPortion> pPortion =
+ new SwXTextPortion(pUnoCursor, xParent, bEnd ? PORTION_BOOKMARK_END : PORTION_BOOKMARK_START);
+ rPortions.emplace_back(pPortion);
+ pPortion->SetBookmark(pPtr->xBookmark);
+ pPortion->SetCollapsed( BkmType::StartEnd == pPtr->nBkmType && !bFrameStart );
+ }
+ }
+ else if (BkmType::End == pPtr->nBkmType && !bOnlyFrameStarts)
+ {
+ rtl::Reference<SwXTextPortion> pPortion =
+ new SwXTextPortion(pUnoCursor, xParent, PORTION_BOOKMARK_END);
+ rPortions.emplace_back(pPortion);
+ pPortion->SetBookmark(pPtr->xBookmark);
+ }
+
+ // next bookmark
+ if (bOnlyFrameStarts)
+ ++aIter;
+ else
+ aIter = rBkmArr.erase(aIter);
+ }
+}
+
+static void lcl_ExportSoftPageBreak(
+ TextRangeList_t & rPortions,
+ Reference<XText> const& xParent,
+ const SwUnoCursor * const pUnoCursor,
+ SwSoftPageBreakList& rBreakArr,
+ const sal_Int32 nIndex)
+{
+ for ( auto aIter = rBreakArr.begin(); aIter != rBreakArr.end(); )
+ {
+ if ( nIndex > *aIter )
+ {
+ aIter = rBreakArr.erase(aIter);
+ continue;
+ }
+ if ( nIndex < *aIter )
+ break;
+
+ rPortions.push_back(
+ new SwXTextPortion(pUnoCursor, xParent, PORTION_SOFT_PAGEBREAK) );
+ aIter = rBreakArr.erase(aIter);
+ }
+}
+
+namespace {
+
+struct SwXRedlinePortion_Impl
+{
+ const SwRangeRedline* m_pRedline;
+ const bool m_bStart;
+
+ SwXRedlinePortion_Impl ( const SwRangeRedline* pRed, const bool bIsStart )
+ : m_pRedline(pRed)
+ , m_bStart(bIsStart)
+ {
+ }
+
+ sal_Int32 getRealIndex () const
+ {
+ return m_bStart ? m_pRedline->Start()->GetContentIndex()
+ : m_pRedline->End() ->GetContentIndex();
+ }
+};
+
+}
+
+typedef std::shared_ptr < SwXRedlinePortion_Impl >
+ SwXRedlinePortion_ImplSharedPtr;
+
+namespace {
+
+struct RedlineCompareStruct
+{
+ static const SwPosition& getPosition ( const SwXRedlinePortion_ImplSharedPtr &r )
+ {
+ return *(r->m_bStart ? r->m_pRedline->Start() : r->m_pRedline->End());
+ }
+
+ bool operator () ( const SwXRedlinePortion_ImplSharedPtr &r1,
+ const SwXRedlinePortion_ImplSharedPtr &r2 ) const
+ {
+ return getPosition ( r1 ) < getPosition ( r2 );
+ }
+};
+
+}
+
+typedef std::multiset < SwXRedlinePortion_ImplSharedPtr, RedlineCompareStruct >
+SwXRedlinePortion_ImplList;
+
+static rtl::Reference<SwXTextPortion>
+lcl_ExportHints(
+ PortionStack_t & rPortionStack,
+ const css::uno::Reference<SwXText> & xParent,
+ SwUnoCursor * const pUnoCursor,
+ SwpHints const * const pHints,
+ const sal_Int32 i_nStartPos,
+ const sal_Int32 i_nEndPos,
+ const sal_Int32 nCurrentIndex,
+ const bool bRightMoveForbidden,
+ bool & o_rbCursorMoved,
+ sal_Int32 & o_rNextAttrPosition)
+{
+ // if the attribute has a dummy character, then xRef is set (except META and CONTENT_CONTROL)
+ // otherwise, the portion for the attribute is inserted into rPortions!
+ rtl::Reference<SwXTextPortion> pPortion;
+ SwDoc& rDoc = pUnoCursor->GetDoc();
+ //search for special text attributes - first some ends
+ size_t nEndIndex = 0;
+ const auto nHintsCount = pHints->Count();
+ for (;;)
+ {
+ if (nEndIndex >= nHintsCount)
+ break;
+ SwTextAttr * const pAttr = pHints->GetSortedByEnd(nEndIndex);
+ const sal_Int32* pAttrEnd = pAttr->GetEnd();
+ sal_Int32 nNextEnd = 0;
+ if (pAttrEnd &&
+ nCurrentIndex < (nNextEnd = (*pAttrEnd)))
+ break;
+ if(pAttrEnd)
+ {
+ if (nNextEnd == nCurrentIndex)
+ {
+ const sal_uInt16 nWhich( pAttr->Which() );
+ switch (nWhich)
+ {
+ case RES_TXTATR_TOXMARK:
+ {
+ rtl::Reference<SwXTextPortion> xTmp = lcl_CreateTOXMarkPortion(
+ xParent, pUnoCursor, *pAttr, true);
+ rPortionStack.top().first->push_back(xTmp);
+ }
+ break;
+ case RES_TXTATR_REFMARK:
+ {
+ rtl::Reference<SwXTextPortion> xTmp = lcl_CreateRefMarkPortion(
+ xParent, pUnoCursor, *pAttr, true);
+ rPortionStack.top().first->push_back(xTmp);
+ }
+ break;
+ case RES_TXTATR_CJK_RUBY:
+ //#i91534# GetEnd() == 0 mixes the order of ruby start/end
+ if( *pAttr->GetEnd() == pAttr->GetStart())
+ {
+ lcl_InsertRubyPortion( *rPortionStack.top().first,
+ xParent, pUnoCursor, *pAttr, false);
+ }
+ lcl_InsertRubyPortion( *rPortionStack.top().first,
+ xParent, pUnoCursor, *pAttr, true);
+ break;
+ case RES_TXTATR_META:
+ case RES_TXTATR_METAFIELD:
+ {
+ OSL_ENSURE(pAttr->GetStart() != *pAttr->GetEnd(),
+ "empty meta?");
+ if ((i_nStartPos > 0) &&
+ (pAttr->GetStart() < i_nStartPos))
+ {
+ // force skip pAttr and rest of attribute ends
+ // at nCurrentIndex
+ // because they are not contained in the meta pAttr
+ // and the meta pAttr itself is outside selection!
+ // (necessary for SwXMeta::createEnumeration)
+ if (pAttr->GetStart() + 1 == i_nStartPos)
+ {
+ nEndIndex = pHints->Count() - 1;
+ }
+ break;
+ }
+ PortionList_t Top = rPortionStack.top();
+ if (Top.second != pAttr)
+ {
+ OSL_FAIL("ExportHints: stack error" );
+ }
+ else
+ {
+ std::unique_ptr<const TextRangeList_t>
+ pCurrentPortions(Top.first);
+ rPortionStack.pop();
+ rtl::Reference<SwXTextPortion> xPortion(
+ lcl_CreateMetaPortion(xParent, pUnoCursor,
+ *pAttr, std::move(pCurrentPortions)));
+ rPortionStack.top().first->push_back(xPortion);
+ }
+ }
+ break;
+ case RES_TXTATR_CONTENTCONTROL:
+ {
+ if (pAttr->GetStart() == *pAttr->GetEnd())
+ {
+ SAL_WARN("sw.core", "lcl_ExportHints: empty content control");
+ }
+ if ((i_nStartPos > 0) && (pAttr->GetStart() < i_nStartPos))
+ {
+ // If the start pos is the start of the content of the content control,
+ // skip it: it'll be handled in SwXContentControl::createEnumeration().
+ if (pAttr->GetStart() + 1 == i_nStartPos)
+ {
+ nEndIndex = pHints->Count() - 1;
+ }
+ break;
+ }
+ PortionList_t Top = rPortionStack.top();
+ if (Top.second != pAttr)
+ {
+ SAL_WARN("sw.core", "lcl_ExportHints: content control is not at the "
+ "top of the portion stack");
+ }
+ else
+ {
+ std::unique_ptr<const TextRangeList_t> pCurrentPortions(Top.first);
+ rPortionStack.pop();
+ rtl::Reference<SwXTextPortion> xPortion(
+ lcl_CreateContentControlPortion(xParent, pUnoCursor, *pAttr,
+ std::move(pCurrentPortions)));
+ rPortionStack.top().first->push_back(xPortion);
+ }
+ }
+ break;
+ }
+ }
+ }
+ nEndIndex++;
+ }
+
+ // then some starts
+ size_t nStartIndex = 0;
+ sal_Int32 nNextStart = 0;
+ while(nStartIndex < nHintsCount &&
+ nCurrentIndex >= (nNextStart = pHints->Get(nStartIndex)->GetStart()))
+ {
+ SwTextAttr * const pAttr = pHints->Get(nStartIndex);
+ sal_uInt16 nAttrWhich = pAttr->Which();
+ if (nNextStart == nCurrentIndex)
+ {
+ switch( nAttrWhich )
+ {
+ case RES_TXTATR_FIELD:
+ if(!bRightMoveForbidden)
+ {
+ pUnoCursor->Right(1);
+ if( *pUnoCursor->GetMark() == *pUnoCursor->GetPoint() )
+ break;
+ pPortion = new SwXTextPortion(
+ pUnoCursor, xParent, PORTION_FIELD);
+ Reference<XTextField> const xField =
+ SwXTextField::CreateXTextField(&rDoc,
+ &pAttr->GetFormatField());
+ pPortion->SetTextField(xField);
+ }
+ break;
+
+ case RES_TXTATR_ANNOTATION:
+ if(!bRightMoveForbidden)
+ {
+ pUnoCursor->Right(1);
+ if( *pUnoCursor->GetMark() == *pUnoCursor->GetPoint() )
+ break;
+
+ const SwTextAnnotationField* pTextAnnotationField = dynamic_cast<const SwTextAnnotationField*>( pAttr );
+ ::sw::mark::IMark* pAnnotationMark = pTextAnnotationField ? pTextAnnotationField->GetAnnotationMark() : nullptr;
+ if ( pAnnotationMark != nullptr )
+ {
+ pPortion = new SwXTextPortion( pUnoCursor, xParent, PORTION_ANNOTATION_END );
+ pPortion->SetBookmark(SwXBookmark::CreateXBookmark(
+ rDoc, pAnnotationMark));
+ }
+ else
+ {
+ pPortion = new SwXTextPortion( pUnoCursor, xParent, PORTION_ANNOTATION );
+ Reference<XTextField> xField =
+ SwXTextField::CreateXTextField(&rDoc,
+ &pAttr->GetFormatField());
+ pPortion->SetTextField(xField);
+ }
+ }
+ break;
+
+ case RES_TXTATR_INPUTFIELD:
+ if(!bRightMoveForbidden)
+ {
+
+ pUnoCursor->Right(
+ pAttr->GetFormatField().GetField()->ExpandField(true, nullptr).getLength() + 2 );
+ if( *pUnoCursor->GetMark() == *pUnoCursor->GetPoint() )
+ break;
+ pPortion = new SwXTextPortion( pUnoCursor, xParent, PORTION_FIELD);
+ Reference<XTextField> xField =
+ SwXTextField::CreateXTextField(&rDoc,
+ &pAttr->GetFormatField());
+ pPortion->SetTextField(xField);
+ }
+ break;
+
+ case RES_TXTATR_FLYCNT:
+ if(!bRightMoveForbidden)
+ {
+ pUnoCursor->Right(1);
+ if( *pUnoCursor->GetMark() == *pUnoCursor->GetPoint() )
+ break; // Robust #i81708# content in covered cells
+
+ // Do not expose inline anchored textboxes.
+ if (SwTextBoxHelper::isTextBox(pAttr->GetFlyCnt().GetFrameFormat(), RES_FLYFRMFMT))
+ break;
+
+ pUnoCursor->Exchange();
+ pPortion = new SwXTextPortion( pUnoCursor, xParent, PORTION_FRAME);
+ }
+ break;
+
+ case RES_TXTATR_FTN:
+ {
+ if(!bRightMoveForbidden)
+ {
+ pUnoCursor->Right(1);
+ if( *pUnoCursor->GetMark() == *pUnoCursor->GetPoint() )
+ break;
+ pPortion = new SwXTextPortion(
+ pUnoCursor, xParent, PORTION_FOOTNOTE);
+ Reference<XFootnote> xContent =
+ SwXFootnotes::GetObject(rDoc, pAttr->GetFootnote());
+ pPortion->SetFootnote(xContent);
+ }
+ }
+ break;
+
+ case RES_TXTATR_TOXMARK:
+ case RES_TXTATR_REFMARK:
+ {
+ bool bIsPoint = !(pAttr->GetEnd());
+ if (!bRightMoveForbidden || !bIsPoint)
+ {
+ if (bIsPoint)
+ {
+ pUnoCursor->Right(1);
+ }
+ rtl::Reference<SwXTextPortion> xTmp =
+ (RES_TXTATR_REFMARK == nAttrWhich)
+ ? lcl_CreateRefMarkPortion(
+ xParent, pUnoCursor, *pAttr, false)
+ : lcl_CreateTOXMarkPortion(
+ xParent, pUnoCursor, *pAttr, false);
+ if (bIsPoint) // consume CH_TXTATR!
+ {
+ pUnoCursor->Normalize(false);
+ pUnoCursor->DeleteMark();
+ pPortion = xTmp;
+ }
+ else // just insert it
+ {
+ rPortionStack.top().first->push_back(xTmp);
+ }
+ }
+ }
+ break;
+ case RES_TXTATR_CJK_RUBY:
+ //#i91534# GetEnd() == 0 mixes the order of ruby start/end
+ if(pAttr->GetEnd() && (*pAttr->GetEnd() != pAttr->GetStart()))
+ {
+ lcl_InsertRubyPortion( *rPortionStack.top().first,
+ xParent, pUnoCursor, *pAttr, false);
+ }
+ break;
+ case RES_TXTATR_META:
+ case RES_TXTATR_METAFIELD:
+ case RES_TXTATR_CONTENTCONTROL:
+ if (pAttr->GetStart() != *pAttr->GetEnd())
+ {
+ if (!bRightMoveForbidden)
+ {
+ pUnoCursor->Right(1);
+ o_rbCursorMoved = true;
+ // only if the end is included in selection!
+ if ((i_nEndPos < 0) ||
+ (*pAttr->GetEnd() <= i_nEndPos))
+ {
+ rPortionStack.push( std::make_pair(
+ new TextRangeList_t, pAttr ));
+ }
+ }
+ }
+ break;
+ case RES_TXTATR_LINEBREAK:
+ if (!bRightMoveForbidden)
+ {
+ pUnoCursor->Right(1);
+ if (*pUnoCursor->GetMark() == *pUnoCursor->GetPoint())
+ break;
+ pPortion = new SwXTextPortion(pUnoCursor, xParent, PORTION_LINEBREAK);
+ rtl::Reference<SwXLineBreak> xLineBreak
+ = SwXLineBreak::CreateXLineBreak(
+ &const_cast<SwFormatLineBreak&>(pAttr->GetLineBreak()));
+ pPortion->SetLineBreak(xLineBreak);
+ }
+ break;
+ case RES_TXTATR_AUTOFMT:
+ case RES_TXTATR_INETFMT:
+ case RES_TXTATR_CHARFMT:
+ break; // these are handled as properties of a "Text" portion
+ default:
+ OSL_FAIL("unknown attribute");
+ break;
+ }
+ }
+ nStartIndex++;
+ }
+
+ if (pPortion.is()) // implies that we have moved the cursor
+ {
+ o_rbCursorMoved = true;
+ }
+ if (!o_rbCursorMoved)
+ {
+ // search for attribute changes behind the current cursor position
+ // break up at frames, bookmarks, redlines
+
+ nStartIndex = 0;
+ nNextStart = 0;
+ while(nStartIndex < pHints->Count() &&
+ nCurrentIndex >= (nNextStart = pHints->Get(nStartIndex)->GetStart()))
+ nStartIndex++;
+
+ nEndIndex = 0;
+ sal_Int32 nNextEnd = 0;
+ while(nEndIndex < pHints->Count() &&
+ nCurrentIndex >= (nNextEnd = pHints->GetSortedByEnd(nEndIndex)->GetAnyEnd()))
+ nEndIndex++;
+
+ sal_Int32 nNextPos =
+ ((nNextStart > nCurrentIndex) && (nNextStart < nNextEnd))
+ ? nNextStart : nNextEnd;
+ if (nNextPos > nCurrentIndex)
+ {
+ o_rNextAttrPosition = nNextPos;
+ }
+ }
+ return pPortion;
+}
+
+static void lcl_MoveCursor( SwUnoCursor * const pUnoCursor,
+ const sal_Int32 nCurrentIndex,
+ const sal_Int32 nNextFrameIndex,
+ const sal_Int32 nNextPortionIndex,
+ const sal_Int32 nNextAttrIndex,
+ const sal_Int32 nNextMarkIndex,
+ const sal_Int32 nEndPos )
+{
+ sal_Int32 nMovePos = pUnoCursor->GetPointContentNode()->Len();
+
+ if ((nEndPos >= 0) && (nEndPos < nMovePos))
+ {
+ nMovePos = nEndPos;
+ }
+
+ if ((nNextFrameIndex >= 0) && (nNextFrameIndex < nMovePos))
+ {
+ nMovePos = nNextFrameIndex;
+ }
+
+ if ((nNextPortionIndex >= 0) && (nNextPortionIndex < nMovePos))
+ {
+ nMovePos = nNextPortionIndex;
+ }
+
+ if ((nNextAttrIndex >= 0) && (nNextAttrIndex < nMovePos))
+ {
+ nMovePos = nNextAttrIndex;
+ }
+
+ if ((nNextMarkIndex >= 0) && (nNextMarkIndex < nMovePos))
+ {
+ nMovePos = nNextMarkIndex;
+ }
+
+ if (nMovePos > nCurrentIndex)
+ {
+ pUnoCursor->GetPoint()->SetContent( nMovePos );
+ }
+}
+
+static void lcl_FillRedlineArray(
+ SwDoc const & rDoc,
+ SwUnoCursor const & rUnoCursor,
+ SwXRedlinePortion_ImplList& rRedArr )
+{
+ const SwRedlineTable& rRedTable = rDoc.getIDocumentRedlineAccess().GetRedlineTable();
+ const size_t nRedTableCount = rRedTable.size();
+
+ if ( nRedTableCount <= 0 )
+ return;
+
+ const SwPosition* pStart = rUnoCursor.GetPoint();
+ const SwNode& rOwnNode = pStart->GetNode();
+
+ SwRedlineTable::size_type nRed = rDoc.getIDocumentRedlineAccess().GetRedlinePos(rOwnNode, RedlineType::Any);
+ for(; nRed < nRedTableCount; ++nRed)
+ {
+ const SwRangeRedline* pRedline = rRedTable[nRed];
+ auto [pRedStart, pRedEnd]= pRedline->StartEnd();
+ if ( rOwnNode == pRedStart->GetNode() )
+ rRedArr.insert( std::make_shared<SwXRedlinePortion_Impl>(
+ pRedline, true ) );
+ if( pRedline->HasMark() && pRedEnd->GetNode() == rOwnNode )
+ rRedArr.insert( std::make_shared<SwXRedlinePortion_Impl>(
+ pRedline, false ) );
+ }
+}
+
+static void lcl_FillSoftPageBreakArray(
+ SwUnoCursor const & rUnoCursor,
+ SwSoftPageBreakList& rBreakArr )
+{
+ const SwTextNode *pTextNode =
+ rUnoCursor.GetPoint()->GetNode().GetTextNode();
+ if( pTextNode )
+ pTextNode->fillSoftPageBreakList( rBreakArr );
+}
+
+static void lcl_ExportRedline(
+ TextRangeList_t & rPortions,
+ Reference<XText> const& xParent,
+ const SwUnoCursor * const pUnoCursor,
+ SwXRedlinePortion_ImplList& rRedlineArr,
+ const sal_Int32 nIndex)
+{
+
+ // We want this loop to iterate over all red lines in this
+ // array. We will only insert the ones with index matches
+ for ( SwXRedlinePortion_ImplList::iterator aIter = rRedlineArr.begin(), aEnd = rRedlineArr.end();
+ aIter != aEnd; )
+ {
+ SwXRedlinePortion_ImplSharedPtr pPtr = *aIter;
+ sal_Int32 nRealIndex = pPtr->getRealIndex();
+ // If there are elements before nIndex, remove them
+ if ( nIndex > nRealIndex )
+ aIter = rRedlineArr.erase(aIter);
+ // If the elements match, and them to the list
+ else if ( nIndex == nRealIndex )
+ {
+ rPortions.push_back( new SwXRedlinePortion(
+ *pPtr->m_pRedline, pUnoCursor, xParent, pPtr->m_bStart));
+ aIter = rRedlineArr.erase(aIter);
+ }
+ // If we've iterated past nIndex, exit the loop
+ else
+ break;
+ }
+}
+
+static void lcl_ExportBkmAndRedline(
+ TextRangeList_t & rPortions,
+ Reference<XText> const & xParent,
+ const SwUnoCursor * const pUnoCursor,
+ SwXBookmarkPortion_ImplList& rBkmArr,
+ SwXRedlinePortion_ImplList& rRedlineArr,
+ SwSoftPageBreakList& rBreakArr,
+ const sal_Int32 nIndex,
+ const o3tl::sorted_vector<sal_Int32>& rFramePositions,
+ bool bOnlyFrameBookmarkStarts)
+{
+ if (!rBkmArr.empty())
+ lcl_ExportBookmark(rPortions, xParent, pUnoCursor, rBkmArr, nIndex, rFramePositions,
+ bOnlyFrameBookmarkStarts);
+
+ if (bOnlyFrameBookmarkStarts)
+ // Only exporting the start of some collapsed bookmarks: no export of
+ // other arrays.
+ return;
+
+ if (!rRedlineArr.empty())
+ lcl_ExportRedline(rPortions, xParent, pUnoCursor, rRedlineArr, nIndex);
+
+ if (!rBreakArr.empty())
+ lcl_ExportSoftPageBreak(rPortions, xParent, pUnoCursor, rBreakArr, nIndex);
+}
+
+/**
+ * Exports all start annotation marks from rAnnotationStartArr into rPortions that have the same
+ * start position as nIndex.
+ *
+ * @param rAnnotationStartArr the array of annotation marks. Consumed entries are removed.
+ *
+ * @param rFramePositions the list of positions where there is an at-char anchored frame.
+ *
+ * @param bOnlyFrame If true: export only the start of annotation marks which cover an at-char
+ * anchored frame. If false: export everything else.
+ */
+static void lcl_ExportAnnotationStarts(
+ TextRangeList_t & rPortions,
+ Reference<XText> const & xParent,
+ const SwUnoCursor * const pUnoCursor,
+ SwAnnotationStartPortion_ImplList& rAnnotationStartArr,
+ const sal_Int32 nIndex,
+ const o3tl::sorted_vector<sal_Int32>& rFramePositions,
+ bool bOnlyFrame)
+{
+ for ( SwAnnotationStartPortion_ImplList::iterator aIter = rAnnotationStartArr.begin(), aEnd = rAnnotationStartArr.end();
+ aIter != aEnd; )
+ {
+ SwAnnotationStartPortion_ImplSharedPtr pPtr = *aIter;
+ if ( nIndex > pPtr->getIndex() )
+ {
+ aIter = rAnnotationStartArr.erase(aIter);
+ continue;
+ }
+ if ( pPtr->getIndex() > nIndex )
+ {
+ break;
+ }
+
+ bool bFrameStart = rFramePositions.find(nIndex) != rFramePositions.end();
+ if (bFrameStart || !bOnlyFrame)
+ {
+ rtl::Reference<SwXTextPortion> pPortion =
+ new SwXTextPortion( pUnoCursor, xParent, PORTION_ANNOTATION );
+ pPortion->SetTextField( pPtr->mxAnnotationField );
+ rPortions.emplace_back(pPortion);
+
+ aIter = rAnnotationStartArr.erase(aIter);
+ }
+ else
+ ++aIter;
+ }
+}
+
+/// Fills character positions from rFrames into rFramePositions.
+static void lcl_ExtractFramePositions(FrameClientSortList_t& rFrames, sal_Int32 nCurrentIndex,
+ o3tl::sorted_vector<sal_Int32>& rFramePositions)
+{
+ for (const auto& rFrame : rFrames)
+ {
+ if (rFrame.nIndex < nCurrentIndex)
+ continue;
+
+ if (rFrame.nIndex > nCurrentIndex)
+ break;
+
+ const auto pFrame = static_cast<const SwFrameFormat*>(rFrame.pFrameClient->GetRegisteredIn());
+ if (!pFrame)
+ continue;
+
+ auto& rFormat = *const_cast<SwFrameFormat*>(pFrame);
+ const SwFormatAnchor& rAnchor = rFormat.GetAnchor();
+ if (!rAnchor.GetAnchorNode())
+ continue;
+
+ rFramePositions.insert(rAnchor.GetAnchorContentOffset());
+ }
+}
+
+/**
+ * Exports at-char anchored frames.
+ *
+ * @param i_rFrames the frames for this paragraph, frames at <= i_nCurrentIndex
+ * are removed from the container.
+ */
+static sal_Int32 lcl_ExportFrames(
+ TextRangeList_t & rPortions,
+ Reference<XText> const & i_xParent,
+ SwUnoCursor const * const i_pUnoCursor,
+ FrameClientSortList_t & i_rFrames,
+ sal_Int32 const i_nCurrentIndex)
+{
+ // Ignore frames which are not exported, as we are exporting a selection
+ // and they are anchored before the start of the selection.
+ while (!i_rFrames.empty() && i_rFrames.front().nIndex < i_nCurrentIndex)
+ i_rFrames.pop_front();
+
+ // find first Frame in (sorted) i_rFrames at current position
+ while (!i_rFrames.empty() && (i_rFrames.front().nIndex == i_nCurrentIndex))
+ // do not check for i_nEnd here; this is done implicitly by lcl_MoveCursor
+ {
+ auto pFrame = static_cast<SwFrameFormat*>(i_rFrames.front().pFrameClient->GetRegisteredIn());
+ if (pFrame) // Frame could be disposed
+ {
+ rtl::Reference<SwXTextPortion> pPortion = new SwXTextPortion(i_pUnoCursor, i_xParent, *pFrame );
+ rPortions.emplace_back(pPortion);
+ }
+ i_rFrames.pop_front();
+ }
+
+ return !i_rFrames.empty() ? i_rFrames.front().nIndex : -1;
+}
+
+static sal_Int32 lcl_GetNextIndex(
+ SwXBookmarkPortion_ImplList const & rBkmArr,
+ SwXRedlinePortion_ImplList const & rRedlineArr,
+ SwSoftPageBreakList const & rBreakArr )
+{
+ sal_Int32 nRet = -1;
+ if(!rBkmArr.empty())
+ {
+ SwXBookmarkPortion_ImplSharedPtr pPtr = *rBkmArr.begin();
+ nRet = pPtr->getIndex();
+ }
+ if(!rRedlineArr.empty())
+ {
+ SwXRedlinePortion_ImplSharedPtr pPtr = *rRedlineArr.begin();
+ sal_Int32 nTmp = pPtr->getRealIndex();
+ if(nRet < 0 || nTmp < nRet)
+ nRet = nTmp;
+ }
+ if(!rBreakArr.empty())
+ {
+ if(nRet < 0 || *rBreakArr.begin() < nRet)
+ nRet = *rBreakArr.begin();
+ }
+ return nRet;
+};
+
+static void lcl_CreatePortions(
+ TextRangeList_t & i_rPortions,
+ css::uno::Reference< SwXText > const & i_xParentText,
+ SwUnoCursor * const pUnoCursor,
+ FrameClientSortList_t & i_rFrames,
+ const sal_Int32 i_nStartPos,
+ const sal_Int32 i_nEndPos,
+ bool bOnlyTextFields )
+{
+ if (!pUnoCursor)
+ return;
+
+ // set the start if a selection should be exported
+ if ((i_nStartPos > 0) &&
+ (pUnoCursor->Start()->GetContentIndex() != i_nStartPos))
+ {
+ pUnoCursor->DeleteMark();
+ OSL_ENSURE(pUnoCursor->Start()->GetNode().GetTextNode() &&
+ (i_nStartPos <= pUnoCursor->Start()->GetNode().GetTextNode()->
+ GetText().getLength()), "Incorrect start position" );
+ // ??? should this be i_nStartPos - current position ?
+ pUnoCursor->Right(i_nStartPos);
+ }
+
+ SwDoc& rDoc = pUnoCursor->GetDoc();
+
+ std::deque<sal_Int32> FieldMarks;
+ if (!bOnlyTextFields)
+ lcl_FillFieldMarkArray(FieldMarks, *pUnoCursor, i_nStartPos);
+
+ SwXBookmarkPortion_ImplList Bookmarks;
+ if (!bOnlyTextFields)
+ lcl_FillBookmarkArray(rDoc, *pUnoCursor, Bookmarks);
+
+ SwXRedlinePortion_ImplList Redlines;
+ if (!bOnlyTextFields)
+ lcl_FillRedlineArray(rDoc, *pUnoCursor, Redlines);
+
+ SwSoftPageBreakList SoftPageBreaks;
+ if (!bOnlyTextFields)
+ lcl_FillSoftPageBreakArray(*pUnoCursor, SoftPageBreaks);
+
+ SwAnnotationStartPortion_ImplList AnnotationStarts;
+ if (!bOnlyTextFields)
+ lcl_FillAnnotationStartArray( rDoc, *pUnoCursor, AnnotationStarts );
+
+ PortionStack_t PortionStack;
+ PortionStack.push( PortionList_t(&i_rPortions, nullptr) );
+
+ bool bAtEnd( false );
+ while (!bAtEnd) // every iteration consumes at least current character!
+ {
+ if (pUnoCursor->HasMark())
+ {
+ pUnoCursor->Normalize(false);
+ pUnoCursor->DeleteMark();
+ }
+
+ SwTextNode * const pTextNode = pUnoCursor->GetPointNode().GetTextNode();
+ if (!pTextNode)
+ {
+ OSL_FAIL("lcl_CreatePortions: no TextNode - what now ?");
+ return;
+ }
+
+ SwpHints * const pHints = pTextNode->GetpSwpHints();
+ const sal_Int32 nCurrentIndex =
+ pUnoCursor->GetPoint()->GetContentIndex();
+ // this contains the portion which consumes the character in the
+ // text at nCurrentIndex; i.e. it must be set _once_ per iteration
+ rtl::Reference<SwXTextPortion> xRef;
+
+ SwUnoCursorHelper::SelectPam(*pUnoCursor, true); // set mark
+
+ // First remember the frame positions.
+ o3tl::sorted_vector<sal_Int32> aFramePositions;
+ lcl_ExtractFramePositions(i_rFrames, nCurrentIndex, aFramePositions);
+
+ // Then export start of collapsed bookmarks which "cover" at-char
+ // anchored frames.
+ lcl_ExportBkmAndRedline( *PortionStack.top().first, i_xParentText,
+ pUnoCursor, Bookmarks, Redlines, SoftPageBreaks, nCurrentIndex, aFramePositions, /*bOnlyFrameBookmarkStarts=*/true );
+
+ lcl_ExportAnnotationStarts(
+ *PortionStack.top().first,
+ i_xParentText,
+ pUnoCursor,
+ AnnotationStarts,
+ nCurrentIndex,
+ aFramePositions,
+ /*bOnlyFrame=*/true );
+
+ const sal_Int32 nFirstFrameIndex =
+ lcl_ExportFrames( *PortionStack.top().first,
+ i_xParentText, pUnoCursor, i_rFrames, nCurrentIndex);
+
+ // Export ends of the previously started collapsed bookmarks + all
+ // other bookmarks, redlines, etc.
+ lcl_ExportBkmAndRedline( *PortionStack.top().first, i_xParentText,
+ pUnoCursor, Bookmarks, Redlines, SoftPageBreaks, nCurrentIndex, aFramePositions, /*bOnlyFrameBookmarkStarts=*/false );
+
+ lcl_ExportAnnotationStarts(
+ *PortionStack.top().first,
+ i_xParentText,
+ pUnoCursor,
+ AnnotationStarts,
+ nCurrentIndex,
+ aFramePositions,
+ /*bOnlyFrame=*/false );
+
+ bool bCursorMoved( false );
+ sal_Int32 nNextAttrIndex = -1;
+ // #111716# the cursor must not move right at the
+ // end position of a selection!
+ bAtEnd = ((i_nEndPos >= 0) && (nCurrentIndex >= i_nEndPos))
+ || (nCurrentIndex >= pTextNode->Len());
+ if (pHints)
+ {
+ // N.B.: side-effects nNextAttrIndex, bCursorMoved; may move cursor
+ xRef = lcl_ExportHints(PortionStack, i_xParentText, pUnoCursor,
+ pHints, i_nStartPos, i_nEndPos, nCurrentIndex, bAtEnd,
+ bCursorMoved, nNextAttrIndex);
+ if (PortionStack.empty())
+ {
+ OSL_FAIL("CreatePortions: stack underflow");
+ return;
+ }
+ }
+
+ if (!xRef.is() && !bCursorMoved)
+ {
+ if (!bAtEnd &&
+ !FieldMarks.empty() && (FieldMarks.front() == nCurrentIndex))
+ {
+ // moves cursor
+ xRef = lcl_ExportFieldMark(i_xParentText, pUnoCursor, pTextNode);
+ FieldMarks.pop_front();
+ }
+ }
+ else
+ {
+ OSL_ENSURE(FieldMarks.empty() ||
+ (FieldMarks.front() != nCurrentIndex),
+ "fieldmark and hint with CH_TXTATR at same pos?");
+ }
+
+ if (!bAtEnd && !xRef.is() && !bCursorMoved)
+ {
+ const sal_Int32 nNextPortionIndex =
+ lcl_GetNextIndex(Bookmarks, Redlines, SoftPageBreaks);
+
+ sal_Int32 nNextMarkIndex = ( !FieldMarks.empty() ? FieldMarks.front() : -1 );
+ if ( !AnnotationStarts.empty()
+ && ( nNextMarkIndex == -1
+ || (*AnnotationStarts.begin())->getIndex() < nNextMarkIndex ) )
+ {
+ nNextMarkIndex = (*AnnotationStarts.begin())->getIndex();
+ }
+
+ lcl_MoveCursor(
+ pUnoCursor,
+ nCurrentIndex,
+ nFirstFrameIndex,
+ nNextPortionIndex,
+ nNextAttrIndex,
+ nNextMarkIndex,
+ i_nEndPos );
+
+ xRef = new SwXTextPortion(pUnoCursor, i_xParentText, PORTION_TEXT);
+ }
+ else if (bAtEnd && !xRef.is() && !pTextNode->Len())
+ {
+ // special case: for an empty paragraph, we better put out a
+ // text portion because there may be a hyperlink attribute
+ xRef = new SwXTextPortion(pUnoCursor, i_xParentText, PORTION_TEXT);
+ }
+ else if (bAtEnd && !xRef.is() && pHints)
+ {
+ // See if there is an empty autofmt at the paragraph end. If so, export it, since that
+ // affects the formatting of number portions.
+ for (size_t i = 0; i < pHints->Count(); ++i)
+ {
+ const SwTextAttr* pHint = pHints->GetSortedByEnd(i);
+ if (pHint->GetStart() < pTextNode->Len())
+ {
+ break;
+ }
+ if (pHint->Which() == RES_TXTATR_AUTOFMT && pHint->GetEnd()
+ && pHint->GetStart() == *pHint->GetEnd()
+ && pHint->GetStart() == pTextNode->Len())
+ {
+ xRef = new SwXTextPortion(pUnoCursor, i_xParentText, PORTION_TEXT);
+ break;
+ }
+ }
+ }
+
+ if (xRef.is())
+ {
+ PortionStack.top().first->push_back(xRef);
+ }
+ }
+
+ OSL_ENSURE((PortionStack.size() == 1) && !PortionStack.top().second,
+ "CreatePortions: stack error" );
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/core/unocore/unoredline.cxx b/sw/source/core/unocore/unoredline.cxx
new file mode 100644
index 0000000000..feeceec92b
--- /dev/null
+++ b/sw/source/core/unocore/unoredline.cxx
@@ -0,0 +1,581 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <sal/config.h>
+#include <sal/log.hxx>
+#include <com/sun/star/text/XTextSection.hpp>
+#include <comphelper/propertyvalue.hxx>
+#include <cppuhelper/typeprovider.hxx>
+#include <vcl/svapp.hxx>
+
+#include <pagedesc.hxx>
+#include <poolfmt.hxx>
+#include <redline.hxx>
+#include <section.hxx>
+#include <unoprnms.hxx>
+#include <unotextrange.hxx>
+#include <unotextcursor.hxx>
+#include <unoparagraph.hxx>
+#include <unocoll.hxx>
+#include <unomap.hxx>
+#include <unocrsr.hxx>
+#include <unoport.hxx>
+#include <unoredline.hxx>
+#include <doc.hxx>
+#include <IDocumentRedlineAccess.hxx>
+#include <IDocumentStylePoolAccess.hxx>
+#include <docary.hxx>
+
+using namespace ::com::sun::star;
+
+SwXRedlineText::SwXRedlineText(SwDoc* _pDoc, const SwNodeIndex& aIndex) :
+ SwXText(_pDoc, CursorType::Redline),
+ m_aNodeIndex(aIndex)
+{
+}
+
+const SwStartNode* SwXRedlineText::GetStartNode() const
+{
+ return m_aNodeIndex.GetNode().GetStartNode();
+}
+
+uno::Any SwXRedlineText::queryInterface( const uno::Type& rType )
+{
+ uno::Any aRet;
+
+ if (cppu::UnoType<container::XEnumerationAccess>::get()== rType)
+ {
+ uno::Reference<container::XEnumerationAccess> aAccess = this;
+ aRet <<= aAccess;
+ }
+ else
+ {
+ // delegate to SwXText and OWeakObject
+ aRet = SwXText::queryInterface(rType);
+ if(!aRet.hasValue())
+ {
+ aRet = OWeakObject::queryInterface(rType);
+ }
+ }
+
+ return aRet;
+}
+
+uno::Sequence<uno::Type> SwXRedlineText::getTypes()
+{
+ return cppu::OTypeCollection(
+ cppu::UnoType<container::XEnumerationAccess>::get(),
+ SwXText::getTypes()
+ ).getTypes();
+}
+
+uno::Sequence<sal_Int8> SwXRedlineText::getImplementationId()
+{
+ return css::uno::Sequence<sal_Int8>();
+}
+
+rtl::Reference< SwXTextCursor > SwXRedlineText::createXTextCursor()
+{
+ SolarMutexGuard aGuard;
+
+ SwPosition aPos(m_aNodeIndex);
+ rtl::Reference<SwXTextCursor> pXCursor =
+ new SwXTextCursor(*GetDoc(), this, CursorType::Redline, aPos);
+ auto& rUnoCursor(pXCursor->GetCursor());
+ rUnoCursor.Move(fnMoveForward, GoInNode);
+
+ // #101929# prevent a newly created text cursor from running inside a table
+ // because table cells have their own XText.
+ // Patterned after SwXTextFrame::createTextCursor().
+
+ // skip all tables at the beginning
+ SwTableNode* pTableNode = rUnoCursor.GetPointNode().FindTableNode();
+ bool bTable = pTableNode != nullptr;
+ while( pTableNode != nullptr )
+ {
+ rUnoCursor.GetPoint()->Assign( *pTableNode->EndOfSectionNode() );
+ SwContentNode* pContentNode = GetDoc()->GetNodes().GoNext(rUnoCursor.GetPoint());
+ pTableNode = pContentNode->FindTableNode();
+ }
+ if( bTable && rUnoCursor.GetPointNode().FindSttNodeByType( SwNormalStartNode )
+ != GetStartNode() )
+ {
+ // We have gone too far and have left our own redline. This means that
+ // no content node outside of a table could be found, and therefore we
+ // except.
+ throw uno::RuntimeException(
+ "No content node found that is inside this change section "
+ "but outside of a table");
+ }
+
+ return pXCursor;
+}
+
+rtl::Reference< SwXTextCursor > SwXRedlineText::createXTextCursorByRange(
+ const uno::Reference<text::XTextRange> & aTextRange)
+{
+ rtl::Reference< SwXTextCursor > xCursor = createXTextCursor();
+ xCursor->gotoRange(aTextRange->getStart(), false);
+ xCursor->gotoRange(aTextRange->getEnd(), true);
+ return xCursor;
+}
+
+uno::Reference<container::XEnumeration> SwXRedlineText::createEnumeration()
+{
+ SolarMutexGuard aGuard;
+ SwPaM aPam(m_aNodeIndex);
+ aPam.Move(fnMoveForward, GoInNode);
+ auto pUnoCursor(GetDoc()->CreateUnoCursor(*aPam.Start()));
+ return SwXParagraphEnumeration::Create(this, pUnoCursor, CursorType::Redline);
+}
+
+uno::Type SwXRedlineText::getElementType( )
+{
+ return cppu::UnoType<text::XTextRange>::get();
+}
+
+sal_Bool SwXRedlineText::hasElements( )
+{
+ return true; // we always have a content index
+}
+
+SwXRedlinePortion::SwXRedlinePortion(SwRangeRedline const& rRedline,
+ SwUnoCursor const*const pPortionCursor,
+ uno::Reference< text::XText > const& xParent, bool const bStart)
+ : SwXTextPortion(pPortionCursor, xParent,
+ bStart ? PORTION_REDLINE_START : PORTION_REDLINE_END)
+ , m_rRedline(rRedline)
+{
+ SetCollapsed(!m_rRedline.HasMark());
+}
+
+SwXRedlinePortion::~SwXRedlinePortion()
+{
+}
+
+static uno::Sequence<beans::PropertyValue> lcl_GetSuccessorProperties(const SwRangeRedline& rRedline)
+{
+ const SwRedlineData* pNext = rRedline.GetRedlineData().Next();
+ if(pNext)
+ {
+ return
+ {
+ // GetAuthorString(n) walks the SwRedlineData* chain;
+ // here we always need element 1
+ comphelper::makePropertyValue(UNO_NAME_REDLINE_AUTHOR, rRedline.GetAuthorString(1)),
+ comphelper::makePropertyValue(UNO_NAME_REDLINE_DATE_TIME, pNext->GetTimeStamp().GetUNODateTime()),
+ comphelper::makePropertyValue(UNO_NAME_REDLINE_COMMENT, pNext->GetComment()),
+ comphelper::makePropertyValue(UNO_NAME_REDLINE_TYPE, SwRedlineTypeToOUString(pNext->GetType()))
+ };
+ }
+ return uno::Sequence<beans::PropertyValue>(4);
+}
+
+uno::Any SwXRedlinePortion::getPropertyValue( const OUString& rPropertyName )
+{
+ SolarMutexGuard aGuard;
+ if (!Validate())
+ {
+ return uno::Any();
+ }
+ uno::Any aRet;
+ if(rPropertyName == UNO_NAME_REDLINE_TEXT)
+ {
+ const SwNodeIndex* pNodeIdx = m_rRedline.GetContentIdx();
+ if(pNodeIdx )
+ {
+ if ( SwNodeOffset(1) < ( pNodeIdx->GetNode().EndOfSectionIndex() - pNodeIdx->GetNode().GetIndex() ) )
+ {
+ SwUnoCursor& rUnoCursor = GetCursor();
+ uno::Reference<text::XText> xRet = new SwXRedlineText(&rUnoCursor.GetDoc(), *pNodeIdx);
+ aRet <<= xRet;
+ }
+ else {
+ OSL_FAIL("Empty section in redline portion! (end node immediately follows start node)");
+ }
+ }
+ }
+ else
+ {
+ aRet = GetPropertyValue(rPropertyName, m_rRedline);
+ if(!aRet.hasValue() &&
+ rPropertyName != UNO_NAME_REDLINE_SUCCESSOR_DATA)
+ aRet = SwXTextPortion::getPropertyValue(rPropertyName);
+ }
+ return aRet;
+}
+
+bool SwXRedlinePortion::Validate()
+{
+ SwUnoCursor& rUnoCursor = GetCursor();
+ //search for the redline
+ SwDoc& rDoc = rUnoCursor.GetDoc();
+ const SwRedlineTable& rRedTable = rDoc.getIDocumentRedlineAccess().GetRedlineTable();
+ bool bFound = false;
+ for(size_t nRed = 0; nRed < rRedTable.size() && !bFound; nRed++)
+ {
+ bFound = &m_rRedline == rRedTable[nRed];
+ }
+ return bFound;
+ // don't throw; the only caller can return void instead
+}
+
+uno::Sequence< sal_Int8 > SAL_CALL SwXRedlinePortion::getImplementationId( )
+{
+ return css::uno::Sequence<sal_Int8>();
+}
+
+uno::Any SwXRedlinePortion::GetPropertyValue( std::u16string_view rPropertyName, const SwRangeRedline& rRedline )
+{
+ uno::Any aRet;
+ if(rPropertyName == UNO_NAME_REDLINE_AUTHOR)
+ aRet <<= rRedline.GetAuthorString();
+ else if(rPropertyName == UNO_NAME_REDLINE_DATE_TIME)
+ {
+ aRet <<= rRedline.GetTimeStamp().GetUNODateTime();
+ }
+ else if (rPropertyName == UNO_NAME_REDLINE_MOVED_ID)
+ aRet <<= rRedline.GetMovedID();
+ else if (rPropertyName == UNO_NAME_REDLINE_COMMENT)
+ aRet <<= rRedline.GetComment();
+ else if(rPropertyName == UNO_NAME_REDLINE_DESCRIPTION)
+ aRet <<= const_cast<SwRangeRedline&>(rRedline).GetDescr();
+ else if(rPropertyName == UNO_NAME_REDLINE_TYPE)
+ {
+ aRet <<= SwRedlineTypeToOUString(rRedline.GetType());
+ }
+ else if(rPropertyName == UNO_NAME_REDLINE_SUCCESSOR_DATA)
+ {
+ if(rRedline.GetRedlineData().Next())
+ aRet <<= lcl_GetSuccessorProperties(rRedline);
+ }
+ else if (rPropertyName == UNO_NAME_REDLINE_IDENTIFIER)
+ {
+ aRet <<= OUString::number(
+ sal::static_int_cast< sal_Int64 >( reinterpret_cast< sal_IntPtr >(&rRedline) ) );
+ }
+ else if (rPropertyName == UNO_NAME_IS_IN_HEADER_FOOTER)
+ {
+ aRet <<= rRedline.GetDoc().IsInHeaderFooter( rRedline.GetPoint()->GetNode() );
+ }
+ else if (rPropertyName == UNO_NAME_MERGE_LAST_PARA)
+ {
+ aRet <<= !rRedline.IsDelLastPara();
+ }
+ return aRet;
+}
+
+uno::Sequence< beans::PropertyValue > SwXRedlinePortion::CreateRedlineProperties(
+ const SwRangeRedline& rRedline, bool bIsStart )
+{
+ uno::Sequence< beans::PropertyValue > aRet(12);
+ const SwRedlineData* pNext = rRedline.GetRedlineData().Next();
+ beans::PropertyValue* pRet = aRet.getArray();
+
+ sal_Int32 nPropIdx = 0;
+ pRet[nPropIdx].Name = UNO_NAME_REDLINE_AUTHOR;
+ pRet[nPropIdx++].Value <<= rRedline.GetAuthorString();
+ pRet[nPropIdx].Name = UNO_NAME_REDLINE_DATE_TIME;
+ pRet[nPropIdx++].Value <<= rRedline.GetTimeStamp().GetUNODateTime();
+ pRet[nPropIdx].Name = UNO_NAME_REDLINE_COMMENT;
+ pRet[nPropIdx++].Value <<= rRedline.GetComment();
+ pRet[nPropIdx].Name = UNO_NAME_REDLINE_DESCRIPTION;
+ pRet[nPropIdx++].Value <<= const_cast<SwRangeRedline&>(rRedline).GetDescr();
+ pRet[nPropIdx].Name = UNO_NAME_REDLINE_TYPE;
+ pRet[nPropIdx++].Value <<= SwRedlineTypeToOUString(rRedline.GetType());
+ pRet[nPropIdx].Name = UNO_NAME_REDLINE_IDENTIFIER;
+ pRet[nPropIdx++].Value <<= OUString::number(
+ sal::static_int_cast< sal_Int64 >( reinterpret_cast< sal_IntPtr >(&rRedline) ) );
+ pRet[nPropIdx].Name = UNO_NAME_IS_COLLAPSED;
+ pRet[nPropIdx++].Value <<= !rRedline.HasMark();
+
+ pRet[nPropIdx].Name = UNO_NAME_IS_START;
+ pRet[nPropIdx++].Value <<= bIsStart;
+
+ pRet[nPropIdx].Name = UNO_NAME_MERGE_LAST_PARA;
+ pRet[nPropIdx++].Value <<= !rRedline.IsDelLastPara();
+
+ const SwNodeIndex* pNodeIdx = rRedline.GetContentIdx();
+ if(pNodeIdx )
+ {
+ if ( SwNodeOffset(1) < ( pNodeIdx->GetNode().EndOfSectionIndex() - pNodeIdx->GetNode().GetIndex() ) )
+ {
+ uno::Reference<text::XText> xRet = new SwXRedlineText(&rRedline.GetDoc(), *pNodeIdx);
+ pRet[nPropIdx].Name = UNO_NAME_REDLINE_TEXT;
+ pRet[nPropIdx++].Value <<= xRet;
+ }
+ else {
+ OSL_FAIL("Empty section in redline portion! (end node immediately follows start node)");
+ }
+ }
+ if(pNext)
+ {
+ pRet[nPropIdx].Name = UNO_NAME_REDLINE_SUCCESSOR_DATA;
+ pRet[nPropIdx++].Value <<= lcl_GetSuccessorProperties(rRedline);
+ }
+ aRet.realloc(nPropIdx);
+ return aRet;
+}
+
+SwXRedline::SwXRedline(SwRangeRedline& rRedline, SwDoc& rDoc) :
+ SwXText(&rDoc, CursorType::Redline),
+ m_pDoc(&rDoc),
+ m_pRedline(&rRedline)
+{
+ StartListening(m_pDoc->getIDocumentStylePoolAccess().GetPageDescFromPool(RES_POOLPAGE_STANDARD)->GetNotifier());
+}
+
+SwXRedline::~SwXRedline()
+{
+}
+
+uno::Reference< beans::XPropertySetInfo > SwXRedline::getPropertySetInfo( )
+{
+ static uno::Reference< beans::XPropertySetInfo > xRef =
+ aSwMapProvider.GetPropertySet(PROPERTY_MAP_REDLINE)->getPropertySetInfo();
+ return xRef;
+}
+
+void SwXRedline::setPropertyValue( const OUString& rPropertyName, const uno::Any& aValue )
+{
+ SolarMutexGuard aGuard;
+ if(!m_pDoc)
+ throw uno::RuntimeException();
+ if(rPropertyName == UNO_NAME_REDLINE_AUTHOR)
+ {
+ OSL_FAIL("currently not available");
+ }
+ else if(rPropertyName == UNO_NAME_REDLINE_DATE_TIME)
+ {
+ OSL_FAIL("currently not available");
+ }
+ else if(rPropertyName == UNO_NAME_REDLINE_COMMENT)
+ {
+ OUString sTmp; aValue >>= sTmp;
+ m_pRedline->SetComment(sTmp);
+ }
+ else if(rPropertyName == UNO_NAME_REDLINE_DESCRIPTION)
+ {
+ SAL_WARN("sw.uno", "SwXRedline::setPropertyValue: can't set Description");
+ }
+ else if(rPropertyName == UNO_NAME_REDLINE_TYPE)
+ {
+ OSL_FAIL("currently not available");
+ OUString sTmp; aValue >>= sTmp;
+ if(sTmp.isEmpty())
+ throw lang::IllegalArgumentException();
+ }
+ else if(rPropertyName == UNO_NAME_REDLINE_SUCCESSOR_DATA)
+ {
+ OSL_FAIL("currently not available");
+ }
+ else
+ {
+ throw lang::IllegalArgumentException();
+ }
+}
+
+uno::Any SwXRedline::getPropertyValue( const OUString& rPropertyName )
+{
+ SolarMutexGuard aGuard;
+ if(!m_pDoc)
+ throw uno::RuntimeException();
+ uno::Any aRet;
+ bool bStart = rPropertyName == UNO_NAME_REDLINE_START;
+ if(bStart ||
+ rPropertyName == UNO_NAME_REDLINE_END)
+ {
+ uno::Reference<XInterface> xRet;
+ SwNode* pNode = &m_pRedline->GetPointNode();
+ if(!bStart && m_pRedline->HasMark())
+ pNode = &m_pRedline->GetMarkNode();
+ switch(pNode->GetNodeType())
+ {
+ case SwNodeType::Section:
+ {
+ SwSectionNode* pSectNode = pNode->GetSectionNode();
+ OSL_ENSURE(pSectNode, "No section node!");
+ xRet = SwXTextSections::GetObject( *pSectNode->GetSection().GetFormat() );
+ }
+ break;
+ case SwNodeType::Table :
+ {
+ SwTableNode* pTableNode = pNode->GetTableNode();
+ OSL_ENSURE(pTableNode, "No table node!");
+ SwTable& rTable = pTableNode->GetTable();
+ SwFrameFormat* pTableFormat = rTable.GetFrameFormat();
+ xRet = SwXTextTables::GetObject( *pTableFormat );
+ }
+ break;
+ case SwNodeType::Text :
+ {
+ SwPosition* pPoint = nullptr;
+ if(bStart || !m_pRedline->HasMark())
+ pPoint = m_pRedline->GetPoint();
+ else
+ pPoint = m_pRedline->GetMark();
+ const rtl::Reference<SwXTextRange> xRange =
+ SwXTextRange::CreateXTextRange(*m_pDoc, *pPoint, nullptr);
+ xRet = uno::Reference<text::XTextRange>(xRange);
+ }
+ break;
+ default:
+ OSL_FAIL("illegal node type");
+ }
+ aRet <<= xRet;
+ }
+ else if(rPropertyName == UNO_NAME_REDLINE_TEXT)
+ {
+ const SwNodeIndex* pNodeIdx = m_pRedline->GetContentIdx();
+ if( pNodeIdx )
+ {
+ if ( SwNodeOffset(1) < ( pNodeIdx->GetNode().EndOfSectionIndex() - pNodeIdx->GetNode().GetIndex() ) )
+ {
+ uno::Reference<text::XText> xRet = new SwXRedlineText(m_pDoc, *pNodeIdx);
+ aRet <<= xRet;
+ }
+ else {
+ OSL_FAIL("Empty section in redline portion! (end node immediately follows start node)");
+ }
+ }
+ }
+ else
+ aRet = SwXRedlinePortion::GetPropertyValue(rPropertyName, *m_pRedline);
+ return aRet;
+}
+
+void SwXRedline::addPropertyChangeListener(
+ const OUString& /*aPropertyName*/,
+ const uno::Reference< beans::XPropertyChangeListener >& /*xListener*/ )
+{
+}
+
+void SwXRedline::removePropertyChangeListener(
+ const OUString& /*aPropertyName*/, const uno::Reference< beans::XPropertyChangeListener >& /*aListener*/ )
+{
+}
+
+void SwXRedline::addVetoableChangeListener(
+ const OUString& /*PropertyName*/, const uno::Reference< beans::XVetoableChangeListener >& /*aListener*/ )
+{
+}
+
+void SwXRedline::removeVetoableChangeListener(
+ const OUString& /*PropertyName*/, const uno::Reference< beans::XVetoableChangeListener >& /*aListener*/ )
+{
+}
+
+void SwXRedline::Notify( const SfxHint& rHint )
+{
+ if(rHint.GetId() == SfxHintId::Dying)
+ {
+ m_pDoc = nullptr;
+ m_pRedline = nullptr;
+ } else if(auto pHint = dynamic_cast<const sw::FindRedlineHint*>(&rHint)) {
+ if(!*pHint->m_ppXRedline && &pHint->m_rRedline == GetRedline())
+ *pHint->m_ppXRedline = this;
+ }
+}
+
+uno::Reference< container::XEnumeration > SwXRedline::createEnumeration()
+{
+ SolarMutexGuard aGuard;
+ if(!m_pDoc)
+ throw uno::RuntimeException();
+
+ const SwNodeIndex* pNodeIndex = m_pRedline->GetContentIdx();
+ if(!pNodeIndex)
+ return nullptr;
+ SwPaM aPam(*pNodeIndex);
+ aPam.Move(fnMoveForward, GoInNode);
+ auto pUnoCursor(GetDoc()->CreateUnoCursor(*aPam.Start()));
+ return SwXParagraphEnumeration::Create(this, pUnoCursor, CursorType::Redline);
+}
+
+uno::Type SwXRedline::getElementType( )
+{
+ return cppu::UnoType<text::XTextRange>::get();
+}
+
+sal_Bool SwXRedline::hasElements( )
+{
+ if(!m_pDoc)
+ throw uno::RuntimeException();
+ return nullptr != m_pRedline->GetContentIdx();
+}
+
+rtl::Reference< SwXTextCursor > SwXRedline::createXTextCursor()
+{
+ if(!m_pDoc)
+ throw uno::RuntimeException();
+
+ const SwNodeIndex* pNodeIndex = m_pRedline->GetContentIdx();
+ if(!pNodeIndex)
+ {
+ throw uno::RuntimeException();
+ }
+
+ SwPosition aPos(*pNodeIndex);
+ rtl::Reference<SwXTextCursor> pXCursor =
+ new SwXTextCursor(*m_pDoc, this, CursorType::Redline, aPos);
+ auto& rUnoCursor(pXCursor->GetCursor());
+ rUnoCursor.Move(fnMoveForward, GoInNode);
+
+ // is here a table?
+ SwTableNode* pTableNode = rUnoCursor.GetPointNode().FindTableNode();
+ while( pTableNode )
+ {
+ rUnoCursor.GetPoint()->Assign( *pTableNode->EndOfSectionNode() );
+ SwContentNode* pCont = GetDoc()->GetNodes().GoNext(rUnoCursor.GetPoint());
+ pTableNode = pCont->FindTableNode();
+ }
+
+ return pXCursor;
+}
+
+rtl::Reference< SwXTextCursor > SwXRedline::createXTextCursorByRange(
+ const uno::Reference< text::XTextRange > & /*aTextPosition*/)
+{
+ throw uno::RuntimeException();
+}
+
+uno::Any SwXRedline::queryInterface( const uno::Type& rType )
+{
+ uno::Any aRet = SwXText::queryInterface(rType);
+ if(!aRet.hasValue())
+ {
+ aRet = SwXRedlineBaseClass::queryInterface(rType);
+ }
+ return aRet;
+}
+
+uno::Sequence<uno::Type> SwXRedline::getTypes()
+{
+ return comphelper::concatSequences(
+ SwXText::getTypes(),
+ SwXRedlineBaseClass::getTypes()
+ );
+}
+
+uno::Sequence<sal_Int8> SwXRedline::getImplementationId()
+{
+ return css::uno::Sequence<sal_Int8>();
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/core/unocore/unoredlines.cxx b/sw/source/core/unocore/unoredlines.cxx
new file mode 100644
index 0000000000..315513632d
--- /dev/null
+++ b/sw/source/core/unocore/unoredlines.cxx
@@ -0,0 +1,162 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/lang/IndexOutOfBoundsException.hpp>
+#include <cppuhelper/supportsservice.hxx>
+
+#include <vcl/svapp.hxx>
+#include <o3tl/safeint.hxx>
+#include <osl/diagnose.h>
+
+#include <unoredlines.hxx>
+#include <unoredline.hxx>
+#include <pagedesc.hxx>
+#include <poolfmt.hxx>
+#include <doc.hxx>
+#include <IDocumentRedlineAccess.hxx>
+#include <IDocumentStylePoolAccess.hxx>
+#include <docary.hxx>
+#include <redline.hxx>
+
+using namespace ::com::sun::star;
+
+SwXRedlines::SwXRedlines(SwDoc* _pDoc) :
+ SwUnoCollection(_pDoc)
+{
+}
+
+SwXRedlines::~SwXRedlines()
+{
+}
+
+sal_Int32 SwXRedlines::getCount( )
+{
+ SolarMutexGuard aGuard;
+ const SwRedlineTable& rRedTable = GetDoc().getIDocumentRedlineAccess().GetRedlineTable();
+ return rRedTable.size();
+}
+
+uno::Any SwXRedlines::getByIndex(sal_Int32 nIndex)
+{
+ SolarMutexGuard aGuard;
+ auto& rDoc = GetDoc();
+ const SwRedlineTable& rRedTable = rDoc.getIDocumentRedlineAccess().GetRedlineTable();
+ if ((nIndex < 0) || (rRedTable.size() <= o3tl::make_unsigned(nIndex)))
+ throw lang::IndexOutOfBoundsException();
+
+ uno::Reference<beans::XPropertySet> xRet = SwXRedlines::GetObject(*rRedTable[nIndex], rDoc);
+ return uno::Any(xRet);
+}
+
+uno::Reference< container::XEnumeration > SwXRedlines::createEnumeration()
+{
+ SolarMutexGuard aGuard;
+ return uno::Reference< container::XEnumeration >(new SwXRedlineEnumeration(GetDoc()));
+}
+
+uno::Type SwXRedlines::getElementType( )
+{
+ return cppu::UnoType<beans::XPropertySet>::get();
+}
+
+sal_Bool SwXRedlines::hasElements( )
+{
+ SolarMutexGuard aGuard;
+ const SwRedlineTable& rRedTable = GetDoc().getIDocumentRedlineAccess().GetRedlineTable();
+ return !rRedTable.empty();
+}
+
+OUString SwXRedlines::getImplementationName()
+{
+ return "SwXRedlines";
+}
+
+sal_Bool SwXRedlines::supportsService(const OUString& ServiceName)
+{
+ return cppu::supportsService(this, ServiceName);
+}
+
+uno::Sequence< OUString > SwXRedlines::getSupportedServiceNames()
+{
+ OSL_FAIL("not implemented");
+ return uno::Sequence< OUString >();
+}
+
+beans::XPropertySet* SwXRedlines::GetObject( SwRangeRedline& rRedline, SwDoc& rDoc )
+{
+ SwXRedline* pXRedline(nullptr);
+ sw::FindRedlineHint aHint(rRedline, &pXRedline);
+ rDoc.getIDocumentStylePoolAccess().GetPageDescFromPool(RES_POOLPAGE_STANDARD)->GetNotifier().Broadcast(aHint);
+ return pXRedline ? pXRedline : new SwXRedline(rRedline, rDoc);
+}
+
+SwXRedlineEnumeration::SwXRedlineEnumeration(SwDoc& rDoc) :
+ m_pDoc(&rDoc),
+ m_nCurrentIndex(0)
+{
+ StartListening(m_pDoc->getIDocumentStylePoolAccess().GetPageDescFromPool(RES_POOLPAGE_STANDARD)->GetNotifier());
+}
+
+SwXRedlineEnumeration::~SwXRedlineEnumeration()
+{
+}
+
+sal_Bool SwXRedlineEnumeration::hasMoreElements()
+{
+ if(!m_pDoc)
+ throw uno::RuntimeException();
+ return m_pDoc->getIDocumentRedlineAccess().GetRedlineTable().size() > m_nCurrentIndex;
+}
+
+uno::Any SwXRedlineEnumeration::nextElement()
+{
+ if(!m_pDoc)
+ throw uno::RuntimeException();
+ const SwRedlineTable& rRedTable = m_pDoc->getIDocumentRedlineAccess().GetRedlineTable();
+ if( rRedTable.size() <= m_nCurrentIndex )
+ throw container::NoSuchElementException();
+ uno::Reference <beans::XPropertySet> xRet = SwXRedlines::GetObject( *rRedTable[m_nCurrentIndex++], *m_pDoc );
+ uno::Any aRet;
+ aRet <<= xRet;
+ return aRet;
+}
+
+OUString SwXRedlineEnumeration::getImplementationName()
+{
+ return "SwXRedlineEnumeration";
+}
+
+sal_Bool SwXRedlineEnumeration::supportsService(const OUString& ServiceName)
+{
+ return cppu::supportsService(this, ServiceName);
+}
+
+uno::Sequence< OUString > SwXRedlineEnumeration::getSupportedServiceNames()
+{
+ return uno::Sequence< OUString >();
+}
+
+void SwXRedlineEnumeration::Notify( const SfxHint& rHint )
+{
+ if(rHint.GetId() == SfxHintId::Dying)
+ m_pDoc = nullptr;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/core/unocore/unorefmk.cxx b/sw/source/core/unocore/unorefmk.cxx
new file mode 100644
index 0000000000..43b0690ecb
--- /dev/null
+++ b/sw/source/core/unocore/unorefmk.cxx
@@ -0,0 +1,1475 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <memory>
+#include <utility>
+
+#include <comphelper/interfacecontainer4.hxx>
+#include <comphelper/processfactory.hxx>
+#include <comphelper/servicehelper.hxx>
+#include <cppuhelper/exc_hlp.hxx>
+#include <cppuhelper/supportsservice.hxx>
+#include <cppuhelper/weak.hxx>
+#include <sal/config.h>
+#include <svl/listener.hxx>
+#include <vcl/svapp.hxx>
+#include <sal/log.hxx>
+
+#include <unotextrange.hxx>
+#include <unorefmark.hxx>
+#include <unotextcursor.hxx>
+#include <unomap.hxx>
+#include <unocrsrhelper.hxx>
+#include <doc.hxx>
+#include <ndtxt.hxx>
+#include <fmtrfmrk.hxx>
+#include <txtrfmrk.hxx>
+#include <unometa.hxx>
+#include <unotext.hxx>
+#include <unoport.hxx>
+#include <txtatr.hxx>
+#include <fmtmeta.hxx>
+#include <docsh.hxx>
+
+#include <com/sun/star/frame/XModel.hpp>
+#include <com/sun/star/lang/NoSupportException.hpp>
+#include <com/sun/star/lang/WrappedTargetRuntimeException.hpp>
+#include <com/sun/star/rdf/Statement.hpp>
+#include <com/sun/star/rdf/URI.hpp>
+#include <com/sun/star/rdf/URIs.hpp>
+#include <com/sun/star/rdf/XLiteral.hpp>
+#include <com/sun/star/rdf/XRepositorySupplier.hpp>
+#include <com/sun/star/lang/DisposedException.hpp>
+
+using namespace ::com::sun::star;
+
+class SwXReferenceMark::Impl
+ : public SvtListener
+{
+public:
+ unotools::WeakReference<SwXReferenceMark> m_wThis;
+ std::mutex m_Mutex; // just for OInterfaceContainerHelper4
+ ::comphelper::OInterfaceContainerHelper4<css::lang::XEventListener> m_EventListeners;
+ bool m_bIsDescriptor;
+ SwDoc* m_pDoc;
+ const SwFormatRefMark* m_pMarkFormat;
+ OUString m_sMarkName;
+
+ Impl(SwDoc* const pDoc, SwFormatRefMark* const pRefMark)
+ : m_bIsDescriptor(nullptr == pRefMark)
+ , m_pDoc(pDoc)
+ , m_pMarkFormat(pRefMark)
+ {
+ if (pRefMark)
+ {
+ StartListening(pRefMark->GetNotifier());
+ m_sMarkName = pRefMark->GetRefName();
+ }
+ }
+
+ bool IsValid() const { return m_pMarkFormat; }
+ void InsertRefMark( SwPaM & rPam, SwXTextCursor const*const pCursor );
+ void Invalidate();
+protected:
+ virtual void Notify(const SfxHint&) override;
+
+};
+
+void SwXReferenceMark::Impl::Invalidate()
+{
+ EndListeningAll();
+ m_pDoc = nullptr;
+ m_pMarkFormat = nullptr;
+ uno::Reference<uno::XInterface> const xThis(m_wThis);
+ if (!xThis.is())
+ { // fdo#72695: if UNO object is already dead, don't revive it with event
+ return;
+ }
+ lang::EventObject const ev(xThis);
+ std::unique_lock aGuard(m_Mutex);
+ m_EventListeners.disposeAndClear(aGuard, ev);
+}
+
+void SwXReferenceMark::Impl::Notify(const SfxHint& rHint)
+{
+ if(rHint.GetId() == SfxHintId::Dying)
+ Invalidate();
+}
+
+SwXReferenceMark::SwXReferenceMark(
+ SwDoc *const pDoc, SwFormatRefMark *const pRefMark)
+ : m_pImpl( new SwXReferenceMark::Impl(pDoc, pRefMark) )
+{
+}
+
+SwXReferenceMark::~SwXReferenceMark()
+{
+}
+
+rtl::Reference<SwXReferenceMark>
+SwXReferenceMark::CreateXReferenceMark(
+ SwDoc & rDoc, SwFormatRefMark *const pMarkFormat)
+{
+ // i#105557: do not iterate over the registered clients: race condition
+ rtl::Reference<SwXReferenceMark> xMark;
+ if (pMarkFormat)
+ {
+ xMark = pMarkFormat->GetXRefMark();
+ }
+ if (!xMark.is())
+ {
+ xMark = new SwXReferenceMark(&rDoc, pMarkFormat);
+ if (pMarkFormat)
+ {
+ pMarkFormat->SetXRefMark(xMark);
+ }
+ // need a permanent Reference to initialize m_wThis
+ xMark->m_pImpl->m_wThis = xMark.get();
+ }
+ return xMark;
+}
+
+OUString SAL_CALL SwXReferenceMark::getImplementationName()
+{
+ return "SwXReferenceMark";
+}
+
+sal_Bool SAL_CALL
+SwXReferenceMark::supportsService(const OUString& rServiceName)
+{
+ return cppu::supportsService(this, rServiceName);
+}
+
+uno::Sequence< OUString > SAL_CALL
+SwXReferenceMark::getSupportedServiceNames()
+{
+ return {
+ "com.sun.star.text.TextContent",
+ "com.sun.star.text.ReferenceMark"
+ };
+}
+
+namespace {
+
+template<typename T> struct NotContainedIn
+{
+ std::vector<T> const& m_rVector;
+ explicit NotContainedIn(std::vector<T> const& rVector)
+ : m_rVector(rVector) { }
+ bool operator() (T const& rT) {
+ return std::find(m_rVector.begin(), m_rVector.end(), rT)
+ == m_rVector.end();
+ }
+};
+
+}
+
+void SwXReferenceMark::Impl::InsertRefMark(SwPaM& rPam,
+ SwXTextCursor const*const pCursor)
+{
+ //! in some cases when this function is called the pDoc pointer member may have become
+ //! invalid/deleted thus we obtain the document pointer from rPaM where it should always
+ //! be valid.
+ SwDoc& rDoc2 = rPam.GetDoc();
+
+ UnoActionContext aCont(&rDoc2);
+ SwFormatRefMark aRefMark(m_sMarkName);
+ bool bMark = *rPam.GetPoint() != *rPam.GetMark();
+
+ const bool bForceExpandHints( !bMark && pCursor && pCursor->IsAtEndOfMeta() );
+ const SetAttrMode nInsertFlags = bForceExpandHints
+ ? ( SetAttrMode::FORCEHINTEXPAND
+ | SetAttrMode::DONTEXPAND)
+ : SetAttrMode::DONTEXPAND;
+
+ std::vector<SwTextAttr *> oldMarks;
+ if (bMark)
+ {
+ oldMarks = rPam.GetPointNode().GetTextNode()->GetTextAttrsAt(
+ rPam.GetPoint()->GetContentIndex(), RES_TXTATR_REFMARK);
+ }
+
+ rDoc2.getIDocumentContentOperations().InsertPoolItem( rPam, aRefMark, nInsertFlags );
+
+ if( bMark && *rPam.GetPoint() > *rPam.GetMark())
+ {
+ rPam.Exchange();
+ }
+
+ // aRefMark was copied into the document pool; now retrieve real format...
+ SwTextAttr * pTextAttr(nullptr);
+ if (bMark)
+ {
+ // #i107672#
+ // ensure that we do not retrieve a different mark at the same position
+ std::vector<SwTextAttr *> const newMarks(
+ rPam.GetPointNode().GetTextNode()->GetTextAttrsAt(
+ rPam.GetPoint()->GetContentIndex(), RES_TXTATR_REFMARK));
+ std::vector<SwTextAttr *>::const_iterator const iter(
+ std::find_if(newMarks.begin(), newMarks.end(),
+ NotContainedIn<SwTextAttr *>(oldMarks)));
+ assert(newMarks.end() != iter);
+ if (newMarks.end() != iter)
+ {
+ pTextAttr = *iter;
+ }
+ }
+ else
+ {
+ SwTextNode *pTextNd = rPam.GetPointNode().GetTextNode();
+ assert(pTextNd);
+ pTextAttr = pTextNd ? rPam.GetPointNode().GetTextNode()->GetTextAttrForCharAt(
+ rPam.GetPoint()->GetContentIndex() - 1, RES_TXTATR_REFMARK) : nullptr;
+ }
+
+ if (!pTextAttr)
+ {
+ throw uno::RuntimeException(
+ "SwXReferenceMark::InsertRefMark(): cannot insert attribute", nullptr);
+ }
+
+ m_pMarkFormat = &pTextAttr->GetRefMark();
+ EndListeningAll();
+ StartListening(const_cast<SwFormatRefMark*>(m_pMarkFormat)->GetNotifier());
+}
+
+void SAL_CALL
+SwXReferenceMark::attach(const uno::Reference< text::XTextRange > & xTextRange)
+{
+ SolarMutexGuard aGuard;
+
+ if (!m_pImpl->m_bIsDescriptor)
+ {
+ throw uno::RuntimeException();
+ }
+ SwXTextRange* pRange = dynamic_cast<SwXTextRange*>(xTextRange.get());
+ OTextCursorHelper* pCursor = dynamic_cast<OTextCursorHelper*>(xTextRange.get());
+ SwDoc *const pDocument =
+ pRange ? &pRange->GetDoc() : (pCursor ? pCursor->GetDoc() : nullptr);
+ if (!pDocument)
+ {
+ throw lang::IllegalArgumentException();
+ }
+
+ SwUnoInternalPaM aPam(*pDocument);
+ // this now needs to return TRUE
+ ::sw::XTextRangeToSwPaM(aPam, xTextRange);
+ m_pImpl->InsertRefMark(aPam, dynamic_cast<SwXTextCursor*>(pCursor));
+ m_pImpl->m_bIsDescriptor = false;
+ m_pImpl->m_pDoc = pDocument;
+}
+
+uno::Reference< text::XTextRange > SAL_CALL
+SwXReferenceMark::getAnchor()
+{
+ SolarMutexGuard aGuard;
+
+ if (m_pImpl->IsValid())
+ {
+ SwFormatRefMark const*const pNewMark =
+ m_pImpl->m_pDoc->GetRefMark(m_pImpl->m_sMarkName);
+ if (pNewMark && SfxPoolItem::areSame(pNewMark, m_pImpl->m_pMarkFormat))
+ {
+ SwTextRefMark const*const pTextMark =
+ m_pImpl->m_pMarkFormat->GetTextRefMark();
+ if (pTextMark &&
+ (&pTextMark->GetTextNode().GetNodes() ==
+ &m_pImpl->m_pDoc->GetNodes()))
+ {
+ SwTextNode const& rTextNode = pTextMark->GetTextNode();
+ std::optional<SwPaM> pPam;
+ if ( pTextMark->End() )
+ pPam.emplace( rTextNode, *pTextMark->End(),
+ rTextNode, pTextMark->GetStart());
+ else
+ pPam.emplace( rTextNode, pTextMark->GetStart());
+
+ return SwXTextRange::CreateXTextRange(
+ *m_pImpl->m_pDoc, *pPam->Start(), pPam->End());
+ }
+ }
+ }
+ return nullptr;
+}
+
+void SAL_CALL SwXReferenceMark::dispose()
+{
+ SolarMutexGuard aGuard;
+ if (m_pImpl->IsValid())
+ {
+ SwFormatRefMark const*const pNewMark =
+ m_pImpl->m_pDoc->GetRefMark(m_pImpl->m_sMarkName);
+ if (pNewMark && SfxPoolItem::areSame(pNewMark, m_pImpl->m_pMarkFormat))
+ {
+ SwTextRefMark const*const pTextMark =
+ m_pImpl->m_pMarkFormat->GetTextRefMark();
+ if (pTextMark &&
+ (&pTextMark->GetTextNode().GetNodes() ==
+ &m_pImpl->m_pDoc->GetNodes()))
+ {
+ SwTextNode const& rTextNode = pTextMark->GetTextNode();
+ const sal_Int32 nStt = pTextMark->GetStart();
+ const sal_Int32 nEnd = pTextMark->End()
+ ? *pTextMark->End()
+ : nStt + 1;
+
+ SwPaM aPam( rTextNode, nStt, rTextNode, nEnd );
+ m_pImpl->m_pDoc->getIDocumentContentOperations().DeleteAndJoin( aPam );
+ }
+ }
+ }
+ else if (m_pImpl->m_bIsDescriptor)
+ {
+ m_pImpl->Invalidate();
+ }
+}
+
+void SAL_CALL SwXReferenceMark::addEventListener(
+ const uno::Reference< lang::XEventListener > & xListener)
+{
+ // no need to lock here as m_pImpl is const and container threadsafe
+ std::unique_lock aGuard(m_pImpl->m_Mutex);
+ m_pImpl->m_EventListeners.addInterface(aGuard, xListener);
+}
+
+void SAL_CALL SwXReferenceMark::removeEventListener(
+ const uno::Reference< lang::XEventListener > & xListener)
+{
+ // no need to lock here as m_pImpl is const and container threadsafe
+ std::unique_lock aGuard(m_pImpl->m_Mutex);
+ m_pImpl->m_EventListeners.removeInterface(aGuard, xListener);
+}
+
+OUString SAL_CALL SwXReferenceMark::getName()
+{
+ SolarMutexGuard aGuard;
+ if (!m_pImpl->IsValid() ||
+ !m_pImpl->m_pDoc->GetRefMark(m_pImpl->m_sMarkName))
+ {
+ throw uno::RuntimeException();
+ }
+ return m_pImpl->m_sMarkName;
+}
+
+void SAL_CALL SwXReferenceMark::setName(const OUString& rName)
+{
+ SolarMutexGuard aGuard;
+ if (m_pImpl->m_bIsDescriptor)
+ {
+ m_pImpl->m_sMarkName = rName;
+ }
+ else
+ {
+ if (!m_pImpl->IsValid()
+ || !m_pImpl->m_pDoc->GetRefMark(m_pImpl->m_sMarkName)
+ || m_pImpl->m_pDoc->GetRefMark(rName))
+ {
+ throw uno::RuntimeException();
+ }
+ SwFormatRefMark const*const pCurMark =
+ m_pImpl->m_pDoc->GetRefMark(m_pImpl->m_sMarkName);
+ if ((rName != m_pImpl->m_sMarkName)
+ && pCurMark && SfxPoolItem::areSame(pCurMark, m_pImpl->m_pMarkFormat))
+ {
+ const UnoActionContext aCont(m_pImpl->m_pDoc);
+ SwTextRefMark const*const pTextMark =
+ m_pImpl->m_pMarkFormat->GetTextRefMark();
+ if (pTextMark &&
+ (&pTextMark->GetTextNode().GetNodes() ==
+ &m_pImpl->m_pDoc->GetNodes()))
+ {
+ SwTextNode const& rTextNode = pTextMark->GetTextNode();
+ const sal_Int32 nStt = pTextMark->GetStart();
+ const sal_Int32 nEnd = pTextMark->End()
+ ? *pTextMark->End()
+ : nStt + 1;
+
+ SwPaM aPam( rTextNode, nStt, rTextNode, nEnd );
+ // deletes the m_pImpl->m_pDoc member in the SwXReferenceMark!
+ m_pImpl->m_pDoc->getIDocumentContentOperations().DeleteAndJoin( aPam );
+ // The aPam will keep the correct and functional doc though
+
+ m_pImpl->m_sMarkName = rName;
+ //create a new one
+ m_pImpl->InsertRefMark( aPam, nullptr );
+ m_pImpl->m_pDoc = &aPam.GetDoc();
+ }
+ }
+ }
+}
+
+uno::Reference< beans::XPropertySetInfo > SAL_CALL
+SwXReferenceMark::getPropertySetInfo()
+{
+ SolarMutexGuard g;
+
+ static uno::Reference< beans::XPropertySetInfo > xRef =
+ aSwMapProvider.GetPropertySet(PROPERTY_MAP_PARAGRAPH_EXTENSIONS)
+ ->getPropertySetInfo();
+ return xRef;
+}
+
+void SAL_CALL SwXReferenceMark::setPropertyValue(
+ const OUString& /*rPropertyName*/, const uno::Any& /*rValue*/ )
+{
+ throw lang::IllegalArgumentException();
+}
+
+uno::Any SAL_CALL
+SwXReferenceMark::getPropertyValue(const OUString& rPropertyName)
+{
+ // does not seem to need SolarMutex
+ uno::Any aRet;
+ if (! ::sw::GetDefaultTextContentValue(aRet, rPropertyName))
+ {
+ throw beans::UnknownPropertyException(rPropertyName);
+ }
+ return aRet;
+}
+
+void SAL_CALL SwXReferenceMark::addPropertyChangeListener(
+ const OUString& /*rPropertyName*/,
+ const uno::Reference< beans::XPropertyChangeListener >& /*xListener*/)
+{
+ OSL_FAIL("SwXReferenceMark::addPropertyChangeListener(): not implemented");
+}
+
+void SAL_CALL SwXReferenceMark::removePropertyChangeListener(
+ const OUString& /*rPropertyName*/,
+ const uno::Reference< beans::XPropertyChangeListener >& /*xListener*/)
+{
+ OSL_FAIL("SwXReferenceMark::removePropertyChangeListener(): not implemented");
+}
+
+void SAL_CALL SwXReferenceMark::addVetoableChangeListener(
+ const OUString& /*rPropertyName*/,
+ const uno::Reference< beans::XVetoableChangeListener >& /*xListener*/)
+{
+ OSL_FAIL("SwXReferenceMark::addVetoableChangeListener(): not implemented");
+}
+
+void SAL_CALL SwXReferenceMark::removeVetoableChangeListener(
+ const OUString& /*rPropertyName*/,
+ const uno::Reference< beans::XVetoableChangeListener >& /*xListener*/)
+{
+ OSL_FAIL("SwXReferenceMark::removeVetoableChangeListener(): not implemented");
+}
+
+namespace {
+
+class SwXMetaText : public cppu::OWeakObject, public SwXText
+{
+private:
+ SwXMeta & m_rMeta;
+
+ virtual void PrepareForAttach(uno::Reference< text::XTextRange > & xRange,
+ const SwPaM & rPam) override;
+
+ virtual bool CheckForOwnMemberMeta(const SwPaM & rPam, const bool bAbsorb) override;
+
+protected:
+ virtual const SwStartNode *GetStartNode() const override;
+
+public:
+ SwXMetaText(SwDoc & rDoc, SwXMeta & rMeta);
+
+ /// make available for SwXMeta
+ using SwXText::Invalidate;
+
+ // XInterface
+ virtual void SAL_CALL acquire() noexcept override { cppu::OWeakObject::acquire(); }
+ virtual void SAL_CALL release() noexcept override { cppu::OWeakObject::release(); }
+
+ // XTypeProvider
+ virtual uno::Sequence< sal_Int8 > SAL_CALL
+ getImplementationId() override;
+
+ // XText
+ virtual rtl::Reference< SwXTextCursor > createXTextCursor() override;
+ virtual rtl::Reference< SwXTextCursor > createXTextCursorByRange(
+ const ::css::uno::Reference< ::css::text::XTextRange >& aTextPosition ) override;
+};
+
+}
+
+SwXMetaText::SwXMetaText(SwDoc & rDoc, SwXMeta & rMeta)
+ : SwXText(&rDoc, CursorType::Meta)
+ , m_rMeta(rMeta)
+{
+}
+
+const SwStartNode *SwXMetaText::GetStartNode() const
+{
+ SwXText const * const pParent = m_rMeta.GetParentText().get();
+ return pParent ? pParent->GetStartNode() : nullptr;
+}
+
+void SwXMetaText::PrepareForAttach( uno::Reference<text::XTextRange> & xRange,
+ const SwPaM & rPam)
+{
+ // create a new cursor to prevent modifying SwXTextRange
+ xRange = static_cast<text::XWordCursor*>(
+ new SwXTextCursor(*GetDoc(), &m_rMeta, CursorType::Meta, *rPam.GetPoint(),
+ (rPam.HasMark()) ? rPam.GetMark() : nullptr));
+}
+
+bool SwXMetaText::CheckForOwnMemberMeta(const SwPaM & rPam, const bool bAbsorb)
+{
+ return m_rMeta.CheckForOwnMemberMeta(rPam, bAbsorb);
+}
+
+rtl::Reference< SwXTextCursor > SwXMetaText::createXTextCursor()
+{
+ rtl::Reference< SwXTextCursor > xRet;
+ if (IsValid())
+ {
+ SwTextNode * pTextNode;
+ sal_Int32 nMetaStart;
+ sal_Int32 nMetaEnd;
+ const bool bSuccess(
+ m_rMeta.SetContentRange(pTextNode, nMetaStart, nMetaEnd) );
+ if (bSuccess)
+ {
+ SwPosition aPos(*pTextNode, nMetaStart);
+ xRet = new SwXTextCursor(*GetDoc(), &m_rMeta, CursorType::Meta, aPos);
+ }
+ }
+ return xRet;
+}
+
+uno::Sequence<sal_Int8> SAL_CALL
+SwXMetaText::getImplementationId()
+{
+ return css::uno::Sequence<sal_Int8>();
+}
+
+// XText
+
+rtl::Reference< SwXTextCursor >
+SwXMetaText::createXTextCursorByRange(
+ const uno::Reference<text::XTextRange> & xTextPosition)
+{
+ const rtl::Reference< SwXTextCursor > xCursor( createXTextCursor() );
+ xCursor->gotoRange(xTextPosition, false);
+ return xCursor;
+}
+
+/**
+ * the Meta has a cached list of text portions for its contents
+ * this list is created by SwXTextPortionEnumeration
+ * the Meta listens at the SwTextNode and throws away the cache when it changes
+ *
+ * This inner part of SwXMeta is deleted with a locked SolarMutex.
+ */
+class SwXMeta::Impl : public SvtListener
+{
+public:
+ unotools::WeakReference<SwXMeta> m_wThis;
+ std::mutex m_Mutex; // just for OInterfaceContainerHelper4
+ ::comphelper::OInterfaceContainerHelper4<css::lang::XEventListener> m_EventListeners;
+ std::unique_ptr<const TextRangeList_t> m_pTextPortions;
+ // 3 possible states: not attached, attached, disposed
+ bool m_bIsDisposed;
+ bool m_bIsDescriptor;
+ css::uno::Reference<SwXText> m_xParentText;
+ rtl::Reference<SwXMetaText> m_xText;
+ sw::Meta* m_pMeta;
+
+ Impl(SwXMeta& rThis, SwDoc& rDoc,
+ ::sw::Meta* const pMeta,
+ css::uno::Reference<SwXText> xParentText,
+ std::unique_ptr<TextRangeList_t const> pPortions)
+ : m_pTextPortions(std::move(pPortions))
+ , m_bIsDisposed(false)
+ , m_bIsDescriptor(nullptr == pMeta)
+ , m_xParentText(std::move(xParentText))
+ , m_xText(new SwXMetaText(rDoc, rThis))
+ , m_pMeta(pMeta)
+ {
+ !m_bIsDescriptor && StartListening(m_pMeta->GetNotifier());
+ }
+
+ inline const ::sw::Meta* GetMeta() const;
+ // only for SwXMetaField!
+ inline const ::sw::MetaField* GetMetaField() const;
+protected:
+ virtual void Notify(const SfxHint& rHint) override;
+
+};
+
+inline const ::sw::Meta* SwXMeta::Impl::GetMeta() const
+{
+ return m_pMeta;
+}
+
+// sw::BroadcastingModify
+void SwXMeta::Impl::Notify(const SfxHint& rHint)
+{
+ m_pTextPortions.reset(); // throw away cache (SwTextNode changed)
+ if(rHint.GetId() != SfxHintId::Dying && rHint.GetId() != SfxHintId::Deinitializing)
+ return;
+
+ m_bIsDisposed = true;
+ m_pMeta = nullptr;
+ m_xText->Invalidate();
+ uno::Reference<uno::XInterface> const xThis(m_wThis);
+ if (!xThis.is())
+ { // fdo#72695: if UNO object is already dead, don't revive it with event
+ return;
+ }
+ lang::EventObject const ev(xThis);
+ std::unique_lock aGuard(m_Mutex);
+ m_EventListeners.disposeAndClear(aGuard, ev);
+}
+
+css::uno::Reference<SwXText> const & SwXMeta::GetParentText() const
+{
+ return m_pImpl->m_xParentText;
+}
+
+SwXMeta::SwXMeta(SwDoc *const pDoc, ::sw::Meta *const pMeta,
+ css::uno::Reference<SwXText> const& xParentText,
+ std::unique_ptr<TextRangeList_t const> pPortions)
+ : m_pImpl( new SwXMeta::Impl(*this, *pDoc, pMeta, xParentText, std::move(pPortions)) )
+{
+}
+
+SwXMeta::SwXMeta(SwDoc *const pDoc)
+ : m_pImpl( new SwXMeta::Impl(*this, *pDoc, nullptr, nullptr, nullptr) )
+{
+}
+
+SwXMeta::~SwXMeta()
+{
+}
+
+rtl::Reference<SwXMeta>
+SwXMeta::CreateXMeta(SwDoc & rDoc, bool const isField)
+{
+ // this is why the constructor is private: need to acquire pXMeta here
+ rtl::Reference<SwXMeta> xMeta(isField
+ ? new SwXMetaField(& rDoc) : new SwXMeta(& rDoc));
+ // need a permanent Reference to initialize m_wThis
+ xMeta->m_pImpl->m_wThis = xMeta.get();
+ return xMeta;
+}
+
+rtl::Reference<SwXMeta>
+SwXMeta::CreateXMeta(::sw::Meta & rMeta,
+ css::uno::Reference<SwXText> i_xParent,
+ std::unique_ptr<TextRangeList_t const> && pPortions)
+{
+ // re-use existing SwXMeta
+ // #i105557#: do not iterate over the registered clients: race condition
+ rtl::Reference<SwXMeta> xMeta(rMeta.GetXMeta());
+ if (xMeta.is())
+ {
+ if (pPortions) // set cache in the XMeta to the given portions
+ {
+ // NB: the meta must always be created with the complete content
+ // if SwXTextPortionEnumeration is created for a selection,
+ // it must be checked that the Meta is contained in the selection!
+ xMeta->m_pImpl->m_pTextPortions = std::move(pPortions);
+ // ??? is this necessary?
+ if (xMeta->m_pImpl->m_xParentText.get() != i_xParent.get())
+ {
+ SAL_WARN("sw.uno", "SwXMeta with different parent?");
+ xMeta->m_pImpl->m_xParentText = i_xParent;
+ }
+ }
+ return xMeta;
+ }
+
+ // create new SwXMeta
+ SwTextNode * const pTextNode( rMeta.GetTextNode() );
+ SAL_WARN_IF(!pTextNode, "sw.uno", "CreateXMeta: no text node?");
+ if (!pTextNode) { return nullptr; }
+ css::uno::Reference<SwXText> xParentText(i_xParent);
+ if (!xParentText.is())
+ {
+ SwTextMeta * const pTextAttr( rMeta.GetTextAttr() );
+ SAL_WARN_IF(!pTextAttr, "sw.uno", "CreateXMeta: no text attr?");
+ if (!pTextAttr) { return nullptr; }
+ const SwPosition aPos(*pTextNode, pTextAttr->GetStart());
+ xParentText = ::sw::CreateParentXText(pTextNode->GetDoc(), aPos);
+ }
+ if (!xParentText.is()) { return nullptr; }
+ // this is why the constructor is private: need to acquire pXMeta here
+ xMeta = (RES_TXTATR_META == rMeta.GetFormatMeta()->Which())
+ ? new SwXMeta (&pTextNode->GetDoc(), &rMeta, xParentText,
+ std::move(pPortions))
+ : new SwXMetaField(&pTextNode->GetDoc(), &rMeta, xParentText,
+ std::move(pPortions));
+ // in order to initialize the weak pointer cache in the core object
+ rMeta.SetXMeta(xMeta);
+ // need a permanent Reference to initialize m_wThis
+ xMeta->m_pImpl->m_wThis = xMeta.get();
+ return xMeta;
+}
+
+bool SwXMeta::SetContentRange(
+ SwTextNode *& rpNode, sal_Int32 & rStart, sal_Int32 & rEnd ) const
+{
+ ::sw::Meta const * const pMeta( m_pImpl->GetMeta() );
+ if (pMeta)
+ {
+ SwTextMeta const * const pTextAttr( pMeta->GetTextAttr() );
+ if (pTextAttr)
+ {
+ rpNode = pMeta->GetTextNode();
+ if (rpNode)
+ {
+ // rStart points at the first position _within_ the meta!
+ rStart = pTextAttr->GetStart() + 1;
+ rEnd = *pTextAttr->End();
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
+bool SwXMeta::CheckForOwnMemberMeta(const SwPaM & rPam, const bool bAbsorb)
+{
+ SwTextNode * pTextNode;
+ sal_Int32 nMetaStart;
+ sal_Int32 nMetaEnd;
+ const bool bSuccess( SetContentRange(pTextNode, nMetaStart, nMetaEnd) );
+ OSL_ENSURE(bSuccess, "no pam?");
+ if (!bSuccess)
+ throw lang::DisposedException();
+
+ SwPosition const * const pStartPos( rPam.Start() );
+ if (&pStartPos->GetNode() != pTextNode)
+ {
+ throw lang::IllegalArgumentException(
+ "trying to insert into a nesting text content, but start "
+ "of text range not in same paragraph as text content",
+ nullptr, 0);
+ }
+ bool bForceExpandHints(false);
+ const sal_Int32 nStartPos(pStartPos->GetContentIndex());
+ // not <= but < because nMetaStart is behind dummy char!
+ // not >= but > because == means insert at end!
+ if ((nStartPos < nMetaStart) || (nStartPos > nMetaEnd))
+ {
+ throw lang::IllegalArgumentException(
+ "trying to insert into a nesting text content, but start "
+ "of text range not inside text content",
+ nullptr, 0);
+ }
+ else if (nStartPos == nMetaEnd)
+ {
+ bForceExpandHints = true;
+ }
+ if (rPam.HasMark() && bAbsorb)
+ {
+ SwPosition const * const pEndPos( rPam.End() );
+ if (&pEndPos->GetNode() != pTextNode)
+ {
+ throw lang::IllegalArgumentException(
+ "trying to insert into a nesting text content, but end "
+ "of text range not in same paragraph as text content",
+ nullptr, 0);
+ }
+ const sal_Int32 nEndPos(pEndPos->GetContentIndex());
+ // not <= but < because nMetaStart is behind dummy char!
+ // not >= but > because == means insert at end!
+ if ((nEndPos < nMetaStart) || (nEndPos > nMetaEnd))
+ {
+ throw lang::IllegalArgumentException(
+ "trying to insert into a nesting text content, but end "
+ "of text range not inside text content",
+ nullptr, 0);
+ }
+ else if (nEndPos == nMetaEnd)
+ {
+ bForceExpandHints = true;
+ }
+ }
+ return bForceExpandHints;
+}
+
+// XServiceInfo
+OUString SAL_CALL
+SwXMeta::getImplementationName()
+{
+ return "SwXMeta";
+}
+
+sal_Bool SAL_CALL
+SwXMeta::supportsService(const OUString& rServiceName)
+{
+ return cppu::supportsService(this, rServiceName);
+}
+
+uno::Sequence< OUString > SAL_CALL
+SwXMeta::getSupportedServiceNames()
+{
+ return {
+ "com.sun.star.text.TextContent",
+ "com.sun.star.text.InContentMetadata"
+ };
+}
+
+// XComponent
+void SAL_CALL
+SwXMeta::addEventListener(
+ uno::Reference< lang::XEventListener> const & xListener )
+{
+ // no need to lock here as m_pImpl is const and container threadsafe
+ std::unique_lock aGuard(m_pImpl->m_Mutex);
+ m_pImpl->m_EventListeners.addInterface(aGuard, xListener);
+}
+
+void SAL_CALL
+SwXMeta::removeEventListener(
+ uno::Reference< lang::XEventListener> const & xListener )
+{
+ // no need to lock here as m_pImpl is const and container threadsafe
+ std::unique_lock aGuard(m_pImpl->m_Mutex);
+ m_pImpl->m_EventListeners.removeInterface(aGuard, xListener);
+}
+
+void SAL_CALL
+SwXMeta::dispose()
+{
+ SolarMutexGuard g;
+
+ if (m_pImpl->m_bIsDescriptor)
+ {
+ m_pImpl->m_pTextPortions.reset();
+ lang::EventObject const ev(getXWeak());
+ std::unique_lock aGuard(m_pImpl->m_Mutex);
+ m_pImpl->m_EventListeners.disposeAndClear(aGuard, ev);
+ m_pImpl->m_bIsDisposed = true;
+ m_pImpl->m_xText->Invalidate();
+ }
+ else if (!m_pImpl->m_bIsDisposed)
+ {
+ SwTextNode * pTextNode;
+ sal_Int32 nMetaStart;
+ sal_Int32 nMetaEnd;
+ const bool bSuccess(SetContentRange(pTextNode, nMetaStart, nMetaEnd));
+ OSL_ENSURE(bSuccess, "no pam?");
+ if (bSuccess)
+ {
+ // -1 because of CH_TXTATR
+ SwPaM aPam( *pTextNode, nMetaStart - 1, *pTextNode, nMetaEnd );
+ SwDoc& rDoc( pTextNode->GetDoc() );
+ rDoc.getIDocumentContentOperations().DeleteAndJoin( aPam );
+
+ // removal should call Modify and do the dispose
+ assert(m_pImpl->m_bIsDisposed);
+ }
+ }
+}
+
+void
+SwXMeta::AttachImpl(const uno::Reference< text::XTextRange > & i_xTextRange,
+ const sal_uInt16 i_nWhich)
+{
+ SolarMutexGuard g;
+
+ if (m_pImpl->m_bIsDisposed)
+ {
+ throw lang::DisposedException();
+ }
+ if (!m_pImpl->m_bIsDescriptor)
+ {
+ throw uno::RuntimeException(
+ "SwXMeta::attach(): already attached",
+ getXWeak());
+ }
+
+ SwXTextRange *const pRange(dynamic_cast<SwXTextRange*>(i_xTextRange.get()));
+ OTextCursorHelper *const pCursor(dynamic_cast<OTextCursorHelper*>(i_xTextRange.get()));
+ if (!pRange && !pCursor)
+ {
+ throw lang::IllegalArgumentException(
+ "SwXMeta::attach(): argument not supported type",
+ getXWeak(), 0);
+ }
+
+ SwDoc * const pDoc(
+ pRange ? &pRange->GetDoc() : pCursor->GetDoc());
+ if (!pDoc)
+ {
+ throw lang::IllegalArgumentException(
+ "SwXMeta::attach(): argument has no SwDoc",
+ getXWeak(), 0);
+ }
+
+ SwUnoInternalPaM aPam(*pDoc);
+ ::sw::XTextRangeToSwPaM(aPam, i_xTextRange);
+
+ UnoActionContext aContext(pDoc);
+
+ SwXTextCursor const*const pTextCursor(
+ dynamic_cast<SwXTextCursor*>(pCursor));
+ const bool bForceExpandHints(pTextCursor && pTextCursor->IsAtEndOfMeta());
+ const SetAttrMode nInsertFlags( bForceExpandHints
+ ? ( SetAttrMode::FORCEHINTEXPAND
+ | SetAttrMode::DONTEXPAND)
+ : SetAttrMode::DONTEXPAND );
+
+ const std::shared_ptr< ::sw::Meta> pMeta( (RES_TXTATR_META == i_nWhich)
+ ? std::make_shared< ::sw::Meta>( nullptr )
+ : std::shared_ptr< ::sw::Meta>(
+ pDoc->GetMetaFieldManager().makeMetaField()) );
+ SwFormatMeta meta(pMeta, i_nWhich); // this is cloned by Insert!
+ const bool bSuccess( pDoc->getIDocumentContentOperations().InsertPoolItem( aPam, meta, nInsertFlags ) );
+ SwTextAttr * const pTextAttr( pMeta->GetTextAttr() );
+ if (!bSuccess)
+ {
+ throw lang::IllegalArgumentException(
+ "SwXMeta::attach(): cannot create meta: range invalid?",
+ getXWeak(), 1);
+ }
+ if (!pTextAttr)
+ {
+ OSL_FAIL("meta inserted, but has no text attribute?");
+ throw uno::RuntimeException(
+ "SwXMeta::attach(): cannot create meta",
+ getXWeak());
+ }
+
+ m_pImpl->EndListeningAll();
+ m_pImpl->m_pMeta = pMeta.get();
+ m_pImpl->StartListening(pMeta->GetNotifier());
+ pMeta->SetXMeta(this);
+
+ m_pImpl->m_xParentText = ::sw::CreateParentXText(*pDoc, *aPam.GetPoint());
+
+ m_pImpl->m_bIsDescriptor = false;
+}
+
+// XTextContent
+void SAL_CALL
+SwXMeta::attach(const uno::Reference< text::XTextRange > & i_xTextRange)
+{
+ return SwXMeta::AttachImpl(i_xTextRange, RES_TXTATR_META);
+}
+
+uno::Reference< text::XTextRange > SAL_CALL
+SwXMeta::getAnchor()
+{
+ SolarMutexGuard g;
+
+ if (m_pImpl->m_bIsDisposed)
+ {
+ throw lang::DisposedException();
+ }
+ if (m_pImpl->m_bIsDescriptor)
+ {
+ throw uno::RuntimeException(
+ "SwXMeta::getAnchor(): not inserted",
+ getXWeak());
+ }
+
+ SwTextNode * pTextNode;
+ sal_Int32 nMetaStart;
+ sal_Int32 nMetaEnd;
+ const bool bSuccess(SetContentRange(pTextNode, nMetaStart, nMetaEnd));
+ OSL_ENSURE(bSuccess, "no pam?");
+ if (!bSuccess)
+ {
+ throw lang::DisposedException(
+ "SwXMeta::getAnchor(): not attached",
+ getXWeak());
+ }
+
+ const SwPosition start(*pTextNode, nMetaStart - 1); // -1 due to CH_TXTATR
+ const SwPosition end(*pTextNode, nMetaEnd);
+ return SwXTextRange::CreateXTextRange(pTextNode->GetDoc(), start, &end);
+}
+
+// XTextRange
+uno::Reference< text::XText > SAL_CALL
+SwXMeta::getText()
+{
+ return this;
+}
+
+uno::Reference< text::XTextRange > SAL_CALL
+SwXMeta::getStart()
+{
+ SolarMutexGuard g;
+ return m_pImpl->m_xText->getStart();
+}
+
+uno::Reference< text::XTextRange > SAL_CALL
+SwXMeta::getEnd()
+{
+ SolarMutexGuard g;
+ return m_pImpl->m_xText->getEnd();
+}
+
+OUString SAL_CALL
+SwXMeta::getString()
+{
+ SolarMutexGuard g;
+ return m_pImpl->m_xText->getString();
+}
+
+void SAL_CALL
+SwXMeta::setString(const OUString& rString)
+{
+ SolarMutexGuard g;
+ return m_pImpl->m_xText->setString(rString);
+}
+
+// XSimpleText
+uno::Reference< text::XTextCursor > SAL_CALL
+SwXMeta::createTextCursor()
+{
+ SolarMutexGuard g;
+ return m_pImpl->m_xText->createTextCursor();
+}
+
+uno::Reference< text::XTextCursor > SAL_CALL
+SwXMeta::createTextCursorByRange(
+ const uno::Reference<text::XTextRange> & xTextPosition)
+{
+ SolarMutexGuard g;
+ return m_pImpl->m_xText->createTextCursorByRange(xTextPosition);
+}
+
+void SAL_CALL
+SwXMeta::insertString(const uno::Reference<text::XTextRange> & xRange,
+ const OUString& rString, sal_Bool bAbsorb)
+{
+ SolarMutexGuard g;
+ return m_pImpl->m_xText->insertString(xRange, rString, bAbsorb);
+}
+
+void SAL_CALL
+SwXMeta::insertControlCharacter(const uno::Reference<text::XTextRange> & xRange,
+ sal_Int16 nControlCharacter, sal_Bool bAbsorb)
+{
+ SolarMutexGuard g;
+ return m_pImpl->m_xText->insertControlCharacter(xRange, nControlCharacter,
+ bAbsorb);
+}
+
+// XText
+void SAL_CALL
+SwXMeta::insertTextContent( const uno::Reference<text::XTextRange> & xRange,
+ const uno::Reference<text::XTextContent> & xContent, sal_Bool bAbsorb)
+{
+ SolarMutexGuard g;
+ return m_pImpl->m_xText->insertTextContent(xRange, xContent, bAbsorb);
+}
+
+void SAL_CALL
+SwXMeta::removeTextContent(
+ const uno::Reference< text::XTextContent > & xContent)
+{
+ SolarMutexGuard g;
+ return m_pImpl->m_xText->removeTextContent(xContent);
+}
+
+// XChild
+uno::Reference< uno::XInterface > SAL_CALL
+SwXMeta::getParent()
+{
+ SolarMutexGuard g;
+ SwTextNode * pTextNode;
+ sal_Int32 nMetaStart;
+ sal_Int32 nMetaEnd;
+ bool const bSuccess( SetContentRange(pTextNode, nMetaStart, nMetaEnd) );
+ OSL_ENSURE(bSuccess, "no pam?");
+ if (!bSuccess) { throw lang::DisposedException(); }
+ // in order to prevent getting this meta, subtract 1 from nMetaStart;
+ // so we get the index of the dummy character, and we exclude it
+ // by calling GetTextAttrAt(_, _, PARENT) in GetNestedTextContent
+ uno::Reference<text::XTextContent> const xRet(
+ SwUnoCursorHelper::GetNestedTextContent(*pTextNode, nMetaStart - 1,
+ true) );
+ return xRet;
+}
+
+void SAL_CALL
+SwXMeta::setParent(uno::Reference< uno::XInterface > const& /*xParent*/)
+{
+ throw lang::NoSupportException("setting parent not supported", *this);
+}
+
+// XElementAccess
+uno::Type SAL_CALL
+SwXMeta::getElementType()
+{
+ return cppu::UnoType<text::XTextRange>::get();
+}
+
+sal_Bool SAL_CALL SwXMeta::hasElements()
+{
+ SolarMutexGuard g;
+ return m_pImpl->m_pMeta != nullptr;
+}
+
+// XEnumerationAccess
+uno::Reference< container::XEnumeration > SAL_CALL
+SwXMeta::createEnumeration()
+{
+ SolarMutexGuard g;
+
+ if (m_pImpl->m_bIsDisposed)
+ {
+ throw lang::DisposedException();
+ }
+ if (m_pImpl->m_bIsDescriptor)
+ {
+ throw uno::RuntimeException(
+ "createEnumeration(): not inserted",
+ getXWeak());
+ }
+
+ SwTextNode * pTextNode;
+ sal_Int32 nMetaStart;
+ sal_Int32 nMetaEnd;
+ const bool bSuccess(SetContentRange(pTextNode, nMetaStart, nMetaEnd));
+ OSL_ENSURE(bSuccess, "no pam?");
+ if (!bSuccess)
+ throw lang::DisposedException();
+
+ SwPaM aPam(*pTextNode, nMetaStart);
+
+ if (!m_pImpl->m_pTextPortions)
+ {
+ return new SwXTextPortionEnumeration(
+ aPam, GetParentText(), nMetaStart, nMetaEnd);
+ }
+ else // cached!
+ {
+ return new SwXTextPortionEnumeration(aPam, std::deque(*m_pImpl->m_pTextPortions));
+ }
+}
+
+// MetadatableMixin
+::sfx2::Metadatable* SwXMeta::GetCoreObject()
+{
+ return const_cast< ::sw::Meta * >(m_pImpl->GetMeta());
+}
+
+uno::Reference<frame::XModel> SwXMeta::GetModel()
+{
+ ::sw::Meta const * const pMeta( m_pImpl->GetMeta() );
+ if (pMeta)
+ {
+ SwTextNode const * const pTextNode( pMeta->GetTextNode() );
+ if (pTextNode)
+ {
+ SwDocShell const * const pShell(pTextNode->GetDoc().GetDocShell());
+ return pShell ? pShell->GetModel() : nullptr;
+ }
+ }
+ return nullptr;
+}
+
+inline const ::sw::MetaField* SwXMeta::Impl::GetMetaField() const
+{
+ return dynamic_cast<sw::MetaField*>(m_pMeta);
+}
+
+SwXMetaField::SwXMetaField(SwDoc *const pDoc, ::sw::Meta *const pMeta,
+ css::uno::Reference<SwXText> const& xParentText,
+ std::unique_ptr<TextRangeList_t const> pPortions)
+ : SwXMetaField_Base(pDoc, pMeta, xParentText, std::move(pPortions))
+{
+ assert(dynamic_cast< ::sw::MetaField* >(pMeta) && "SwXMetaField created for wrong hint!");
+}
+
+SwXMetaField::SwXMetaField(SwDoc *const pDoc)
+ : SwXMetaField_Base(pDoc)
+{
+}
+
+SwXMetaField::~SwXMetaField()
+{
+}
+
+// XServiceInfo
+OUString SAL_CALL
+SwXMetaField::getImplementationName()
+{
+ return "SwXMetaField";
+}
+
+sal_Bool SAL_CALL
+SwXMetaField::supportsService(const OUString& rServiceName)
+{
+ return cppu::supportsService(this, rServiceName);
+}
+
+uno::Sequence< OUString > SAL_CALL
+SwXMetaField::getSupportedServiceNames()
+{
+ return {
+ "com.sun.star.text.TextContent",
+ "com.sun.star.text.TextField",
+ "com.sun.star.text.textfield.MetadataField"
+ };
+}
+
+// XComponent
+void SAL_CALL
+SwXMetaField::addEventListener(
+ uno::Reference< lang::XEventListener> const & xListener )
+{
+ return SwXMeta::addEventListener(xListener);
+}
+
+void SAL_CALL
+SwXMetaField::removeEventListener(
+ uno::Reference< lang::XEventListener> const & xListener )
+{
+ return SwXMeta::removeEventListener(xListener);
+}
+
+void SAL_CALL
+SwXMetaField::dispose()
+{
+ return SwXMeta::dispose();
+}
+
+// XTextContent
+void SAL_CALL
+SwXMetaField::attach(const uno::Reference< text::XTextRange > & i_xTextRange)
+{
+ return SwXMeta::AttachImpl(i_xTextRange, RES_TXTATR_METAFIELD);
+}
+
+uno::Reference< text::XTextRange > SAL_CALL
+SwXMetaField::getAnchor()
+{
+ return SwXMeta::getAnchor();
+}
+
+// XPropertySet
+uno::Reference< beans::XPropertySetInfo > SAL_CALL
+SwXMetaField::getPropertySetInfo()
+{
+ SolarMutexGuard g;
+
+ static uno::Reference< beans::XPropertySetInfo > xRef(
+ aSwMapProvider.GetPropertySet(PROPERTY_MAP_METAFIELD)
+ ->getPropertySetInfo() );
+ return xRef;
+}
+
+void SAL_CALL
+SwXMetaField::setPropertyValue(
+ const OUString& rPropertyName, const uno::Any& rValue)
+{
+ SolarMutexGuard g;
+
+ ::sw::MetaField * const pMeta(
+ const_cast< ::sw::MetaField * >(m_pImpl->GetMetaField()) );
+ if (!pMeta)
+ throw lang::DisposedException();
+
+ if ( rPropertyName == "NumberFormat" )
+ {
+ sal_Int32 nNumberFormat(0);
+ if (rValue >>= nNumberFormat)
+ {
+ pMeta->SetNumberFormat(static_cast<sal_uInt32>(nNumberFormat));
+ }
+ }
+ else if ( rPropertyName == "IsFixedLanguage" )
+ {
+ bool b(false);
+ if (rValue >>= b)
+ {
+ pMeta->SetIsFixedLanguage(b);
+ }
+ }
+ else
+ {
+ throw beans::UnknownPropertyException(rPropertyName);
+ }
+}
+
+uno::Any SAL_CALL
+SwXMetaField::getPropertyValue(const OUString& rPropertyName)
+{
+ SolarMutexGuard g;
+
+ ::sw::MetaField const * const pMeta( m_pImpl->GetMetaField() );
+ if (!pMeta)
+ throw lang::DisposedException();
+
+ uno::Any any;
+
+ if ( rPropertyName == "NumberFormat" )
+ {
+ const OUString text( getPresentation(false) );
+ any <<= static_cast<sal_Int32>(pMeta->GetNumberFormat(text));
+ }
+ else if ( rPropertyName == "IsFixedLanguage" )
+ {
+ any <<= pMeta->IsFixedLanguage();
+ }
+ else
+ {
+ throw beans::UnknownPropertyException(rPropertyName);
+ }
+
+ return any;
+}
+
+void SAL_CALL
+SwXMetaField::addPropertyChangeListener(
+ const OUString& /*rPropertyName*/,
+ const uno::Reference< beans::XPropertyChangeListener >& /*xListener*/)
+{
+ OSL_FAIL("SwXMetaField::addPropertyChangeListener(): not implemented");
+}
+
+void SAL_CALL
+SwXMetaField::removePropertyChangeListener(
+ const OUString& /*rPropertyName*/,
+ const uno::Reference< beans::XPropertyChangeListener >& /*xListener*/)
+{
+ OSL_FAIL("SwXMetaField::removePropertyChangeListener(): not implemented");
+}
+
+void SAL_CALL
+SwXMetaField::addVetoableChangeListener(
+ const OUString& /*rPropertyName*/,
+ const uno::Reference< beans::XVetoableChangeListener >& /*xListener*/)
+{
+ OSL_FAIL("SwXMetaField::addVetoableChangeListener(): not implemented");
+}
+
+void SAL_CALL
+SwXMetaField::removeVetoableChangeListener(
+ const OUString& /*rPropertyName*/,
+ const uno::Reference< beans::XVetoableChangeListener >& /*xListener*/)
+{
+ OSL_FAIL("SwXMetaField::removeVetoableChangeListener(): not implemented");
+}
+
+static uno::Reference<rdf::XURI> const&
+lcl_getURI(const sal_Int16 eKnown)
+{
+ static uno::Reference< uno::XComponentContext > xContext(
+ ::comphelper::getProcessComponentContext());
+ static uno::Reference< rdf::XURI > xOdfPrefix(
+ rdf::URI::createKnown(xContext, rdf::URIs::ODF_PREFIX),
+ uno::UNO_SET_THROW);
+ static uno::Reference< rdf::XURI > xOdfSuffix(
+ rdf::URI::createKnown(xContext, rdf::URIs::ODF_SUFFIX),
+ uno::UNO_SET_THROW);
+ static uno::Reference< rdf::XURI > xOdfShading(
+ rdf::URI::createKnown(xContext, rdf::URIs::LO_EXT_SHADING),
+ uno::UNO_SET_THROW);
+ switch (eKnown)
+ {
+ case rdf::URIs::ODF_PREFIX:
+ return xOdfPrefix;
+ case rdf::URIs::ODF_SUFFIX:
+ return xOdfSuffix;
+ default:
+ return xOdfShading;
+ }
+}
+
+static OUString
+lcl_getPrefixOrSuffix(
+ uno::Reference<rdf::XRepository> const & xRepository,
+ uno::Reference<rdf::XResource> const & xMetaField,
+ uno::Reference<rdf::XURI> const & xPredicate)
+{
+ const uno::Reference<container::XEnumeration> xEnum(
+ xRepository->getStatements(xMetaField, xPredicate, nullptr),
+ uno::UNO_SET_THROW);
+ while (xEnum->hasMoreElements()) {
+ rdf::Statement stmt;
+ if (!(xEnum->nextElement() >>= stmt)) {
+ throw uno::RuntimeException();
+ }
+ const uno::Reference<rdf::XLiteral> xObject(stmt.Object,
+ uno::UNO_QUERY);
+ if (!xObject.is()) continue;
+ if (xEnum->hasMoreElements()) {
+ SAL_INFO("sw.uno", "ignoring other odf:Prefix/odf:Suffix statements");
+ }
+ return xObject->getValue();
+ }
+ return OUString();
+}
+
+void
+getPrefixAndSuffix(
+ const uno::Reference<frame::XModel>& xModel,
+ const uno::Reference<rdf::XMetadatable>& xMetaField,
+ OUString *const o_pPrefix, OUString *const o_pSuffix, OUString *const o_pShadingColor)
+{
+ try {
+ const uno::Reference<rdf::XRepositorySupplier> xRS(
+ xModel, uno::UNO_QUERY_THROW);
+ const uno::Reference<rdf::XRepository> xRepo(
+ xRS->getRDFRepository(), uno::UNO_SET_THROW);
+ const uno::Reference<rdf::XResource> xMeta(
+ xMetaField, uno::UNO_QUERY_THROW);
+ if (o_pPrefix)
+ {
+ *o_pPrefix = lcl_getPrefixOrSuffix(xRepo, xMeta, lcl_getURI(rdf::URIs::ODF_PREFIX));
+ }
+ if (o_pSuffix)
+ {
+ *o_pSuffix = lcl_getPrefixOrSuffix(xRepo, xMeta, lcl_getURI(rdf::URIs::ODF_SUFFIX));
+ }
+ if (o_pShadingColor)
+ {
+ *o_pShadingColor = lcl_getPrefixOrSuffix(xRepo, xMeta, lcl_getURI(rdf::URIs::LO_EXT_SHADING));
+ }
+ } catch (uno::RuntimeException &) {
+ throw;
+ } catch (const uno::Exception &) {
+ css::uno::Any anyEx = cppu::getCaughtException();
+ throw lang::WrappedTargetRuntimeException("getPrefixAndSuffix: exception", nullptr, anyEx);
+ }
+}
+
+// XTextField
+OUString SAL_CALL
+SwXMetaField::getPresentation(sal_Bool bShowCommand)
+{
+ SolarMutexGuard g;
+
+ if (bShowCommand)
+ {
+//FIXME ?
+ return OUString();
+ }
+ else
+ {
+ // getString should check if this is invalid
+ const OUString content( getString() );
+ OUString prefix;
+ OUString suffix;
+ getPrefixAndSuffix(GetModel(), this, &prefix, &suffix, nullptr);
+ return prefix + content + suffix;
+ }
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/core/unocore/unosect.cxx b/sw/source/core/unocore/unosect.cxx
new file mode 100644
index 0000000000..4439862002
--- /dev/null
+++ b/sw/source/core/unocore/unosect.cxx
@@ -0,0 +1,1730 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <memory>
+#include <unosection.hxx>
+#include <unotext.hxx>
+
+#include <com/sun/star/beans/PropertyAttribute.hpp>
+#include <com/sun/star/lang/WrappedTargetRuntimeException.hpp>
+#include <com/sun/star/text/SectionFileLink.hpp>
+
+#include <comphelper/interfacecontainer4.hxx>
+#include <cppuhelper/exc_hlp.hxx>
+#include <cppuhelper/supportsservice.hxx>
+
+#include <cmdid.h>
+#include <hintids.hxx>
+#include <svl/urihelper.hxx>
+#include <svl/listener.hxx>
+#include <editeng/brushitem.hxx>
+#include <editeng/xmlcnitm.hxx>
+#include <sfx2/linkmgr.hxx>
+#include <sfx2/lnkbase.hxx>
+#include <osl/diagnose.h>
+#include <vcl/svapp.hxx>
+#include <fmtclds.hxx>
+#include <unotextrange.hxx>
+#include <TextCursorHelper.hxx>
+#include <unoport.hxx>
+#include <redline.hxx>
+#include <unomap.hxx>
+#include <section.hxx>
+#include <doc.hxx>
+#include <IDocumentRedlineAccess.hxx>
+#include <IDocumentUndoRedo.hxx>
+#include <docsh.hxx>
+#include <sfx2/docfile.hxx>
+#include <docary.hxx>
+#include <swundo.hxx>
+#include <tox.hxx>
+#include <unoidx.hxx>
+#include <doctxm.hxx>
+#include <fmtftntx.hxx>
+#include <fmtclbl.hxx>
+#include <editeng/frmdiritem.hxx>
+#include <fmtcntnt.hxx>
+#include <editeng/lrspitem.hxx>
+#include <comphelper/servicehelper.hxx>
+#include <comphelper/string.hxx>
+#include <o3tl/string_view.hxx>
+
+using namespace ::com::sun::star;
+
+namespace {
+
+struct SwTextSectionProperties_Impl
+{
+ uno::Sequence<sal_Int8> m_Password;
+ OUString m_sCondition;
+ OUString m_sLinkFileName;
+ OUString m_sSectionFilter;
+ OUString m_sSectionRegion;
+
+ std::unique_ptr<SwFormatCol> m_pColItem;
+ std::unique_ptr<SvxBrushItem> m_pBrushItem;
+ std::unique_ptr<SwFormatFootnoteAtTextEnd> m_pFootnoteItem;
+ std::unique_ptr<SwFormatEndAtTextEnd> m_pEndItem;
+ std::unique_ptr<SvXMLAttrContainerItem> m_pXMLAttr;
+ std::unique_ptr<SwFormatNoBalancedColumns> m_pNoBalanceItem;
+ std::unique_ptr<SvxFrameDirectionItem> m_pFrameDirItem;
+ std::unique_ptr<SvxLRSpaceItem> m_pLRSpaceItem;
+
+ bool m_bDDE;
+ bool m_bHidden;
+ bool m_bCondHidden;
+ bool m_bProtect;
+ bool m_bEditInReadonly;
+ bool m_bUpdateType;
+
+ SwTextSectionProperties_Impl()
+ : m_bDDE(false)
+ , m_bHidden(false)
+ , m_bCondHidden(false)
+ , m_bProtect(false)
+ , m_bEditInReadonly(false)
+ , m_bUpdateType(true)
+ {
+ }
+
+};
+
+}
+
+class SwXTextSection::Impl
+ : public SvtListener
+{
+public:
+ SwXTextSection & m_rThis;
+ unotools::WeakReference<SwXTextSection> m_wThis;
+ const SfxItemPropertySet & m_rPropSet;
+ std::mutex m_Mutex; // just for OInterfaceContainerHelper4
+ ::comphelper::OInterfaceContainerHelper4<css::lang::XEventListener> m_EventListeners;
+ const bool m_bIndexHeader;
+ bool m_bIsDescriptor;
+ OUString m_sName;
+ std::unique_ptr<SwTextSectionProperties_Impl> m_pProps;
+ SwSectionFormat* m_pFormat;
+
+ Impl( SwXTextSection& rThis,
+ SwSectionFormat* const pFormat, const bool bIndexHeader)
+ : m_rThis(rThis)
+ , m_rPropSet(*aSwMapProvider.GetPropertySet(PROPERTY_MAP_SECTION))
+ , m_bIndexHeader(bIndexHeader)
+ , m_bIsDescriptor(nullptr == pFormat)
+ , m_pProps(pFormat ? nullptr : new SwTextSectionProperties_Impl())
+ , m_pFormat(pFormat)
+ {
+ if(m_pFormat)
+ StartListening(m_pFormat->GetNotifier());
+ }
+
+ void Attach(SwSectionFormat* pFormat)
+ {
+ EndListeningAll();
+ StartListening(pFormat->GetNotifier());
+ m_pFormat = pFormat;
+ }
+
+ SwSectionFormat* GetSectionFormat() const
+ { return m_pFormat; }
+
+ SwSectionFormat & GetSectionFormatOrThrow() const {
+ SwSectionFormat *const pFormat( GetSectionFormat() );
+ if (!pFormat) {
+ throw uno::RuntimeException("SwXTextSection: disposed or invalid", nullptr);
+ }
+ return *pFormat;
+ }
+
+ /// @throws beans::UnknownPropertyException
+ /// @throws beans::PropertyVetoException,
+ /// @throws lang::IllegalArgumentException
+ /// @throws lang::WrappedTargetException,
+ /// @throws uno::RuntimeException
+ void SetPropertyValues_Impl(
+ const uno::Sequence< OUString >& rPropertyNames,
+ const uno::Sequence< uno::Any >& aValues);
+ /// @throws beans::UnknownPropertyException
+ /// @throws lang::WrappedTargetException,
+ /// @throws uno::RuntimeException
+ uno::Sequence< uno::Any >
+ GetPropertyValues_Impl(
+ const uno::Sequence< OUString >& rPropertyNames);
+ virtual void Notify(const SfxHint& rHint) override;
+};
+
+void SwXTextSection::Impl::Notify(const SfxHint& rHint)
+{
+ if(rHint.GetId() == SfxHintId::Dying)
+ {
+ m_pFormat = nullptr;
+ uno::Reference<uno::XInterface> const xThis(m_wThis);
+ if (!xThis.is())
+ { // fdo#72695: if UNO object is already dead, don't revive it with event
+ return;
+ }
+ lang::EventObject const ev(xThis);
+ std::unique_lock aGuard(m_Mutex);
+ m_EventListeners.disposeAndClear(aGuard, ev);
+ }
+}
+
+SwSectionFormat * SwXTextSection::GetFormat() const
+{
+ return m_pImpl->GetSectionFormat();
+}
+
+rtl::Reference< SwXTextSection >
+SwXTextSection::CreateXTextSection(
+ SwSectionFormat *const pFormat, const bool bIndexHeader)
+{
+ // re-use existing SwXTextSection
+ // #i105557#: do not iterate over the registered clients: race condition
+ rtl::Reference< SwXTextSection > xSection;
+ if (pFormat)
+ {
+ xSection = pFormat->GetXTextSection();
+ }
+ if ( !xSection.is() )
+ {
+ rtl::Reference<SwXTextSection> pNew = new SwXTextSection(pFormat, bIndexHeader);
+ xSection = pNew;
+ if (pFormat)
+ {
+ pFormat->SetXTextSection(xSection);
+ }
+ // need a permanent Reference to initialize m_wThis
+ pNew->m_pImpl->m_wThis = xSection.get();
+ }
+ return xSection;
+}
+
+SwXTextSection::SwXTextSection(
+ SwSectionFormat *const pFormat, const bool bIndexHeader)
+ : m_pImpl( new SwXTextSection::Impl(*this, pFormat, bIndexHeader) )
+{
+}
+
+SwXTextSection::~SwXTextSection()
+{
+}
+
+uno::Reference< text::XTextSection > SAL_CALL
+SwXTextSection::getParentSection()
+{
+ SolarMutexGuard aGuard;
+
+ SwSectionFormat & rSectionFormat( m_pImpl->GetSectionFormatOrThrow() );
+
+ SwSectionFormat *const pParentFormat = rSectionFormat.GetParent();
+ const uno::Reference< text::XTextSection > xRet =
+ pParentFormat ? CreateXTextSection(pParentFormat) : nullptr;
+ return xRet;
+}
+
+uno::Sequence< uno::Reference< text::XTextSection > > SAL_CALL
+SwXTextSection::getChildSections()
+{
+ SolarMutexGuard aGuard;
+
+ SwSectionFormat & rSectionFormat( m_pImpl->GetSectionFormatOrThrow() );
+
+ SwSections aChildren;
+ rSectionFormat.GetChildSections(aChildren, SectionSort::Not, false);
+ uno::Sequence<uno::Reference<text::XTextSection> > aSeq(aChildren.size());
+ uno::Reference< text::XTextSection > * pArray = aSeq.getArray();
+ for (size_t i = 0; i < aChildren.size(); ++i)
+ {
+ SwSectionFormat *const pChild = aChildren[i]->GetFormat();
+ pArray[i] = CreateXTextSection(pChild);
+ }
+ return aSeq;
+}
+
+void SAL_CALL
+SwXTextSection::attach(const uno::Reference< text::XTextRange > & xTextRange)
+{
+ SolarMutexGuard g;
+
+ if (!m_pImpl->m_bIsDescriptor)
+ {
+ throw uno::RuntimeException();
+ }
+
+ SwXTextRange* pRange = dynamic_cast<SwXTextRange*>(xTextRange.get());
+ OTextCursorHelper* pCursor = dynamic_cast<OTextCursorHelper*>(xTextRange.get());
+
+ SwDoc *const pDoc =
+ pRange ? &pRange->GetDoc() : (pCursor ? pCursor->GetDoc() : nullptr);
+ if (!pDoc)
+ {
+ throw lang::IllegalArgumentException();
+ }
+
+ SwUnoInternalPaM aPam(*pDoc);
+ // this has to return true now
+ ::sw::XTextRangeToSwPaM(aPam, xTextRange);
+ UnoActionContext aCont(pDoc);
+ pDoc->GetIDocumentUndoRedo().StartUndo( SwUndoId::INSSECTION, nullptr );
+
+ if (m_pImpl->m_sName.isEmpty())
+ {
+ m_pImpl->m_sName = "TextSection";
+ }
+ SectionType eType(SectionType::FileLink);
+ if( m_pImpl->m_pProps->m_bDDE )
+ eType = SectionType::DdeLink;
+ else if( m_pImpl->m_pProps->m_sLinkFileName.isEmpty() && m_pImpl->m_pProps->m_sSectionRegion.isEmpty() )
+ eType = SectionType::Content;
+ // index header section?
+ if (m_pImpl->m_bIndexHeader)
+ {
+ // caller wants an index header section, but will only
+ // give him one if a) we are inside an index, and b) said
+ // index doesn't yet have a header section.
+ const SwTOXBase* pBase = SwDoc::GetCurTOX(*aPam.Start());
+
+ // are we inside an index?
+ if (pBase)
+ {
+ // get all child sections
+ SwSections aSectionsArr;
+ static_cast<const SwTOXBaseSection*>(pBase)->GetFormat()->
+ GetChildSections(aSectionsArr);
+
+ // and search for current header section
+ const size_t nCount = aSectionsArr.size();
+ bool bHeaderPresent = false;
+ for(size_t i = 0; i < nCount; ++i)
+ {
+ if (aSectionsArr[i]->GetType() == SectionType::ToxHeader)
+ bHeaderPresent = true;
+ }
+ if (! bHeaderPresent)
+ {
+ eType = SectionType::ToxHeader;
+ }
+ }
+ }
+
+ SwSectionData aSect(eType, pDoc->GetUniqueSectionName(&m_pImpl->m_sName));
+ aSect.SetCondition(m_pImpl->m_pProps->m_sCondition);
+ aSect.SetLinkFileName(m_pImpl->m_pProps->m_sLinkFileName +
+ OUStringChar(sfx2::cTokenSeparator) +
+ m_pImpl->m_pProps->m_sSectionFilter +
+ OUStringChar(sfx2::cTokenSeparator) +
+ m_pImpl->m_pProps->m_sSectionRegion);
+
+ aSect.SetHidden(m_pImpl->m_pProps->m_bHidden);
+ aSect.SetProtectFlag(m_pImpl->m_pProps->m_bProtect);
+ aSect.SetEditInReadonlyFlag(m_pImpl->m_pProps->m_bEditInReadonly);
+
+ SfxItemSetFixed<
+ RES_LR_SPACE, RES_LR_SPACE,
+ RES_BACKGROUND, RES_BACKGROUND,
+ RES_COL, RES_COL,
+ RES_FTN_AT_TXTEND, RES_FRAMEDIR,
+ RES_UNKNOWNATR_CONTAINER,RES_UNKNOWNATR_CONTAINER>
+ aSet(pDoc->GetAttrPool());
+ if (m_pImpl->m_pProps->m_pBrushItem)
+ {
+ aSet.Put(*m_pImpl->m_pProps->m_pBrushItem);
+ }
+ if (m_pImpl->m_pProps->m_pColItem)
+ {
+ aSet.Put(*m_pImpl->m_pProps->m_pColItem);
+ }
+ if (m_pImpl->m_pProps->m_pFootnoteItem)
+ {
+ aSet.Put(*m_pImpl->m_pProps->m_pFootnoteItem);
+ }
+ if (m_pImpl->m_pProps->m_pEndItem)
+ {
+ aSet.Put(*m_pImpl->m_pProps->m_pEndItem);
+ }
+ if (m_pImpl->m_pProps->m_pXMLAttr)
+ {
+ aSet.Put(*m_pImpl->m_pProps->m_pXMLAttr);
+ }
+ if (m_pImpl->m_pProps->m_pNoBalanceItem)
+ {
+ aSet.Put(*m_pImpl->m_pProps->m_pNoBalanceItem);
+ }
+ if (m_pImpl->m_pProps->m_pFrameDirItem)
+ {
+ aSet.Put(*m_pImpl->m_pProps->m_pFrameDirItem);
+ }
+ if (m_pImpl->m_pProps->m_pLRSpaceItem)
+ {
+ aSet.Put(*m_pImpl->m_pProps->m_pLRSpaceItem);
+ }
+ // section password
+ if (m_pImpl->m_pProps->m_Password.hasElements())
+ {
+ aSect.SetPassword(m_pImpl->m_pProps->m_Password);
+ }
+
+ SwSection *const pRet =
+ pDoc->InsertSwSection( aPam, aSect, nullptr, aSet.Count() ? &aSet : nullptr );
+ if (!pRet) // fdo#42450 text range could partially overlap existing section
+ {
+ // shouldn't have created an undo object yet
+ pDoc->GetIDocumentUndoRedo().EndUndo( SwUndoId::INSSECTION, nullptr );
+ throw lang::IllegalArgumentException(
+ "SwXTextSection::attach(): invalid TextRange",
+ getXWeak(), 0);
+ }
+ m_pImpl->Attach(pRet->GetFormat());
+ pRet->GetFormat()->SetXObject(getXWeak());
+
+ // XML import must hide sections depending on their old
+ // condition status
+ if (!m_pImpl->m_pProps->m_sCondition.isEmpty())
+ {
+ pRet->SetCondHidden(m_pImpl->m_pProps->m_bCondHidden);
+ }
+
+ // set update type if DDE link (and connect, if necessary)
+ if (m_pImpl->m_pProps->m_bDDE)
+ {
+ if (! pRet->IsConnected())
+ {
+ pRet->CreateLink(LinkCreateType::Connect);
+ }
+ pRet->SetUpdateType( m_pImpl->m_pProps->m_bUpdateType ?
+ SfxLinkUpdateMode::ALWAYS : SfxLinkUpdateMode::ONCALL );
+ }
+
+ // end the Undo bracketing here
+ pDoc->GetIDocumentUndoRedo().EndUndo( SwUndoId::INSSECTION, nullptr );
+ m_pImpl->m_pProps.reset();
+ m_pImpl->m_bIsDescriptor = false;
+}
+
+uno::Reference< text::XTextRange > SAL_CALL
+SwXTextSection::getAnchor()
+{
+ SolarMutexGuard aGuard;
+
+ rtl::Reference<SwXTextRange> xRet;
+ SwSectionFormat *const pSectFormat = m_pImpl->GetSectionFormat();
+ if(pSectFormat)
+ {
+ const SwNodeIndex* pIdx;
+ if( nullptr != ( pSectFormat->GetSection() ) &&
+ nullptr != ( pIdx = pSectFormat->GetContent().GetContentIdx() ) &&
+ pIdx->GetNode().GetNodes().IsDocNodes() )
+ {
+ bool isMoveIntoTable(false);
+ SwPaM aPaM(*pIdx);
+ aPaM.Move( fnMoveForward, GoInContent );
+ assert(pIdx->GetNode().IsSectionNode());
+ if (aPaM.GetPoint()->GetNode().FindTableNode() != pIdx->GetNode().FindTableNode()
+ || aPaM.GetPoint()->GetNode().FindSectionNode() != &pIdx->GetNode())
+ {
+ isMoveIntoTable = true;
+ }
+
+ const SwEndNode* pEndNode = pIdx->GetNode().EndOfSectionNode();
+ SwPaM aEnd(*pEndNode);
+ aEnd.Move( fnMoveBackward, GoInContent );
+ if (aEnd.GetPoint()->GetNode().FindTableNode() != pIdx->GetNode().FindTableNode()
+ || aEnd.GetPoint()->GetNode().FindSectionNode() != &pIdx->GetNode())
+ {
+ isMoveIntoTable = true;
+ }
+ if (isMoveIntoTable)
+ {
+ css::uno::Reference<SwXText> const xParentText =
+ ::sw::CreateParentXText(*pSectFormat->GetDoc(), SwPosition(*pIdx));
+ xRet = new SwXTextRange(*pSectFormat);
+ }
+ else // for compatibility, keep the old way in this case
+ {
+ xRet = SwXTextRange::CreateXTextRange(*pSectFormat->GetDoc(),
+ *aPaM.Start(), aEnd.Start());
+ }
+ }
+ }
+ return xRet;
+}
+
+void SAL_CALL SwXTextSection::dispose()
+{
+ SolarMutexGuard aGuard;
+
+ SwSectionFormat *const pSectFormat = m_pImpl->GetSectionFormat();
+ if (pSectFormat)
+ {
+ pSectFormat->GetDoc()->DelSectionFormat( pSectFormat );
+ }
+}
+
+void SAL_CALL SwXTextSection::addEventListener(
+ const uno::Reference< lang::XEventListener > & xListener)
+{
+ // no need to lock here as m_pImpl is const and container threadsafe
+ std::unique_lock aGuard(m_pImpl->m_Mutex);
+ m_pImpl->m_EventListeners.addInterface(aGuard, xListener);
+}
+
+void SAL_CALL SwXTextSection::removeEventListener(
+ const uno::Reference< lang::XEventListener > & xListener)
+{
+ // no need to lock here as m_pImpl is const and container threadsafe
+ std::unique_lock aGuard(m_pImpl->m_Mutex);
+ m_pImpl->m_EventListeners.removeInterface(aGuard, xListener);
+}
+
+uno::Reference< beans::XPropertySetInfo > SAL_CALL
+SwXTextSection::getPropertySetInfo()
+{
+ SolarMutexGuard g;
+ return m_pImpl->m_rPropSet.getPropertySetInfo();
+}
+
+static void
+lcl_UpdateLinkType(SwSection & rSection, bool const bLinkUpdateAlways)
+{
+ if (rSection.GetType() == SectionType::DdeLink)
+ {
+ // set update type; needs an established link
+ if (!rSection.IsConnected())
+ {
+ rSection.CreateLink(LinkCreateType::Connect);
+ }
+ rSection.SetUpdateType( bLinkUpdateAlways
+ ? SfxLinkUpdateMode::ALWAYS : SfxLinkUpdateMode::ONCALL );
+ }
+}
+
+static void
+lcl_UpdateSection(SwSectionFormat *const pFormat,
+ std::unique_ptr<SwSectionData> const& pSectionData,
+ std::optional<SfxItemSet> const& oItemSet,
+ bool const bLinkModeChanged, bool const bLinkUpdateAlways = true)
+{
+ if (!pFormat)
+ return;
+
+ SwSection & rSection = *pFormat->GetSection();
+ SwDoc *const pDoc = pFormat->GetDoc();
+ SwSectionFormats const& rFormats = pDoc->GetSections();
+ UnoActionContext aContext(pDoc);
+ for (size_t i = 0; i < rFormats.size(); ++i)
+ {
+ if (rFormats[i]->GetSection()->GetSectionName()
+ == rSection.GetSectionName())
+ {
+ pDoc->UpdateSection(i, *pSectionData, oItemSet ? &*oItemSet : nullptr,
+ pDoc->IsInReading());
+ {
+ // temporarily remove actions to allow cursor update
+ // TODO: why? no table cursor here!
+ UnoActionRemoveContext aRemoveContext( pDoc );
+ }
+
+ if (bLinkModeChanged)
+ {
+ lcl_UpdateLinkType(rSection, bLinkUpdateAlways);
+ }
+ // section found and processed: break from loop
+ break;
+ }
+ }
+}
+
+void SwXTextSection::Impl::SetPropertyValues_Impl(
+ const uno::Sequence< OUString >& rPropertyNames,
+ const uno::Sequence< uno::Any >& rValues)
+{
+ if(rPropertyNames.getLength() != rValues.getLength())
+ {
+ throw lang::IllegalArgumentException();
+ }
+ SwSectionFormat *const pFormat = GetSectionFormat();
+ if (!pFormat && !m_bIsDescriptor)
+ {
+ throw uno::RuntimeException();
+ }
+
+ std::unique_ptr<SwSectionData> const pSectionData(
+ pFormat ? new SwSectionData(*pFormat->GetSection()) : nullptr);
+
+ OUString const*const pPropertyNames = rPropertyNames.getConstArray();
+ uno::Any const*const pValues = rValues.getConstArray();
+ std::optional<SfxItemSet> oItemSet;
+ bool bLinkModeChanged = false;
+ bool bLinkMode = false;
+
+ for (sal_Int32 nProperty = 0; nProperty < rPropertyNames.getLength();
+ nProperty++)
+ {
+ SfxItemPropertyMapEntry const*const pEntry =
+ m_rPropSet.getPropertyMap().getByName(pPropertyNames[nProperty]);
+ if (!pEntry)
+ {
+ throw beans::UnknownPropertyException(
+ "Unknown property: " + pPropertyNames[nProperty],
+ m_rThis.getXWeak());
+ }
+ if (pEntry->nFlags & beans::PropertyAttribute::READONLY)
+ {
+ throw beans::PropertyVetoException(
+ "Property is read-only: " + pPropertyNames[nProperty],
+ m_rThis.getXWeak());
+ }
+ switch (pEntry->nWID)
+ {
+ case WID_SECT_CONDITION:
+ {
+ OUString uTmp;
+ pValues[nProperty] >>= uTmp;
+ if (m_bIsDescriptor)
+ {
+ m_pProps->m_sCondition = uTmp;
+ }
+ else
+ {
+ pSectionData->SetCondition(uTmp);
+ }
+ }
+ break;
+ case WID_SECT_DDE_TYPE:
+ case WID_SECT_DDE_FILE:
+ case WID_SECT_DDE_ELEMENT:
+ {
+ OUString sTmp;
+ pValues[nProperty] >>= sTmp;
+ if (m_bIsDescriptor)
+ {
+ if (!m_pProps->m_bDDE)
+ {
+ m_pProps->m_sLinkFileName =
+ OUStringChar(sfx2::cTokenSeparator) + OUStringChar(sfx2::cTokenSeparator);
+ m_pProps->m_bDDE = true;
+ }
+ m_pProps->m_sLinkFileName = comphelper::string::setToken(
+ m_pProps->m_sLinkFileName,
+ pEntry->nWID - WID_SECT_DDE_TYPE, sfx2::cTokenSeparator, sTmp);
+ }
+ else
+ {
+ OUString sLinkFileName(pSectionData->GetLinkFileName());
+ if (pSectionData->GetType() != SectionType::DdeLink)
+ {
+ sLinkFileName = OUStringChar(sfx2::cTokenSeparator) + OUStringChar(sfx2::cTokenSeparator);
+ pSectionData->SetType(SectionType::DdeLink);
+ }
+ sLinkFileName = comphelper::string::setToken(sLinkFileName,
+ pEntry->nWID - WID_SECT_DDE_TYPE,
+ sfx2::cTokenSeparator, sTmp);
+ pSectionData->SetLinkFileName(sLinkFileName);
+ }
+ }
+ break;
+ case WID_SECT_DDE_AUTOUPDATE:
+ {
+ bool bVal(false);
+ if (!(pValues[nProperty] >>= bVal))
+ {
+ throw lang::IllegalArgumentException();
+ }
+ if (m_bIsDescriptor)
+ {
+ m_pProps->m_bUpdateType = bVal;
+ }
+ else
+ {
+ bLinkModeChanged = true;
+ bLinkMode = bVal;
+ }
+ }
+ break;
+ case WID_SECT_LINK:
+ {
+ text::SectionFileLink aLink;
+ if (!(pValues[nProperty] >>= aLink))
+ {
+ throw lang::IllegalArgumentException();
+ }
+ if (m_bIsDescriptor)
+ {
+ m_pProps->m_bDDE = false;
+ m_pProps->m_sLinkFileName = aLink.FileURL;
+ m_pProps->m_sSectionFilter = aLink.FilterName;
+ }
+ else
+ {
+ if (pSectionData->GetType() != SectionType::FileLink &&
+ !aLink.FileURL.isEmpty())
+ {
+ pSectionData->SetType(SectionType::FileLink);
+ }
+ const OUString sTmp(!aLink.FileURL.isEmpty()
+ ? URIHelper::SmartRel2Abs(
+ pFormat->GetDoc()->GetDocShell()->GetMedium()->GetURLObject(),
+ aLink.FileURL, URIHelper::GetMaybeFileHdl())
+ : OUString());
+ const OUString sFileName(
+ sTmp + OUStringChar(sfx2::cTokenSeparator) +
+ aLink.FilterName + OUStringChar(sfx2::cTokenSeparator) +
+ o3tl::getToken(pSectionData->GetLinkFileName(), 2, sfx2::cTokenSeparator));
+ pSectionData->SetLinkFileName(sFileName);
+ if (sFileName.getLength() < 3)
+ {
+ pSectionData->SetType(SectionType::Content);
+ }
+ }
+ }
+ break;
+ case WID_SECT_REGION:
+ {
+ OUString sLink;
+ pValues[nProperty] >>= sLink;
+ if (m_bIsDescriptor)
+ {
+ m_pProps->m_bDDE = false;
+ m_pProps->m_sSectionRegion = sLink;
+ }
+ else
+ {
+ if (pSectionData->GetType() != SectionType::FileLink &&
+ !sLink.isEmpty())
+ {
+ pSectionData->SetType(SectionType::FileLink);
+ }
+ OUString sSectLink(pSectionData->GetLinkFileName());
+ for (sal_Int32 i = comphelper::string::getTokenCount(sSectLink, sfx2::cTokenSeparator);
+ i < 3; ++i)
+ {
+ sSectLink += OUStringChar(sfx2::cTokenSeparator);
+ }
+ sSectLink = comphelper::string::setToken(sSectLink, 2, sfx2::cTokenSeparator, sLink);
+ pSectionData->SetLinkFileName(sSectLink);
+ if (sSectLink.getLength() < 3)
+ {
+ pSectionData->SetType(SectionType::Content);
+ }
+ }
+ }
+ break;
+ case WID_SECT_VISIBLE:
+ {
+ bool bVal(false);
+ if (!(pValues[nProperty] >>= bVal))
+ {
+ throw lang::IllegalArgumentException();
+ }
+ if (m_bIsDescriptor)
+ {
+ m_pProps->m_bHidden = !bVal;
+ }
+ else
+ {
+ pSectionData->SetHidden(!bVal);
+ }
+ }
+ break;
+ case WID_SECT_CURRENTLY_VISIBLE:
+ {
+ bool bVal(false);
+ if (!(pValues[nProperty] >>= bVal))
+ {
+ throw lang::IllegalArgumentException();
+ }
+ if (m_bIsDescriptor)
+ {
+ m_pProps->m_bCondHidden = !bVal;
+ }
+ else
+ {
+ if (!pSectionData->GetCondition().isEmpty())
+ {
+ pSectionData->SetCondHidden(!bVal);
+ }
+ }
+ }
+ break;
+ case WID_SECT_PROTECTED:
+ {
+ bool bVal(false);
+ if (!(pValues[nProperty] >>= bVal))
+ {
+ throw lang::IllegalArgumentException();
+ }
+ if (m_bIsDescriptor)
+ {
+ m_pProps->m_bProtect = bVal;
+ }
+ else
+ {
+ pSectionData->SetProtectFlag(bVal);
+ }
+ }
+ break;
+ case WID_SECT_EDIT_IN_READONLY:
+ {
+ bool bVal(false);
+ if (!(pValues[nProperty] >>= bVal))
+ {
+ throw lang::IllegalArgumentException();
+ }
+ if (m_bIsDescriptor)
+ {
+ m_pProps->m_bEditInReadonly = bVal;
+ }
+ else
+ {
+ pSectionData->SetEditInReadonlyFlag(bVal);
+ }
+ }
+ break;
+ case WID_SECT_PASSWORD:
+ {
+ uno::Sequence<sal_Int8> aSeq;
+ pValues[nProperty] >>= aSeq;
+ if (m_bIsDescriptor)
+ {
+ m_pProps->m_Password = aSeq;
+ }
+ else
+ {
+ pSectionData->SetPassword(aSeq);
+ }
+ }
+ break;
+ default:
+ {
+ if (pFormat)
+ {
+ const SfxItemSet& rOldAttrSet = pFormat->GetAttrSet();
+ oItemSet.emplace(*rOldAttrSet.GetPool(), pEntry->nWID, pEntry->nWID);
+ oItemSet->Put(rOldAttrSet);
+ m_rPropSet.setPropertyValue(*pEntry,
+ pValues[nProperty], *oItemSet);
+ }
+ else
+ {
+ SfxPoolItem* pPutItem = nullptr;
+ if (RES_COL == pEntry->nWID)
+ {
+ if (!m_pProps->m_pColItem)
+ {
+ m_pProps->m_pColItem.reset(new SwFormatCol);
+ }
+ pPutItem = m_pProps->m_pColItem.get();
+ }
+ else if (RES_BACKGROUND == pEntry->nWID)
+ {
+ if (!m_pProps->m_pBrushItem)
+ {
+ m_pProps->m_pBrushItem.reset(
+ new SvxBrushItem(RES_BACKGROUND));
+ }
+ pPutItem = m_pProps->m_pBrushItem.get();
+ }
+ else if (RES_FTN_AT_TXTEND == pEntry->nWID)
+ {
+ if (!m_pProps->m_pFootnoteItem)
+ {
+ m_pProps->m_pFootnoteItem.reset(new SwFormatFootnoteAtTextEnd);
+ }
+ pPutItem = m_pProps->m_pFootnoteItem.get();
+ }
+ else if (RES_END_AT_TXTEND == pEntry->nWID)
+ {
+ if (!m_pProps->m_pEndItem)
+ {
+ m_pProps->m_pEndItem.reset(new SwFormatEndAtTextEnd);
+ }
+ pPutItem = m_pProps->m_pEndItem.get();
+ }
+ else if (RES_UNKNOWNATR_CONTAINER== pEntry->nWID)
+ {
+ if (!m_pProps->m_pXMLAttr)
+ {
+ m_pProps->m_pXMLAttr.reset(
+ new SvXMLAttrContainerItem(
+ RES_UNKNOWNATR_CONTAINER));
+ }
+ pPutItem = m_pProps->m_pXMLAttr.get();
+ }
+ else if (RES_COLUMNBALANCE== pEntry->nWID)
+ {
+ if (!m_pProps->m_pNoBalanceItem)
+ {
+ m_pProps->m_pNoBalanceItem.reset(
+ new SwFormatNoBalancedColumns(true));
+ }
+ pPutItem = m_pProps->m_pNoBalanceItem.get();
+ }
+ else if (RES_FRAMEDIR == pEntry->nWID)
+ {
+ if (!m_pProps->m_pFrameDirItem)
+ {
+ m_pProps->m_pFrameDirItem.reset(
+ new SvxFrameDirectionItem(
+ SvxFrameDirection::Horizontal_LR_TB, RES_FRAMEDIR));
+ }
+ pPutItem = m_pProps->m_pFrameDirItem.get();
+ }
+ else if (RES_LR_SPACE == pEntry->nWID)
+ {
+ if (!m_pProps->m_pLRSpaceItem)
+ {
+ m_pProps->m_pLRSpaceItem.reset(
+ new SvxLRSpaceItem( RES_LR_SPACE ));
+ }
+ pPutItem = m_pProps->m_pLRSpaceItem.get();
+ }
+ if (pPutItem)
+ {
+ pPutItem->PutValue(pValues[nProperty],
+ pEntry->nMemberId);
+ }
+ }
+ }
+ }
+ }
+
+ lcl_UpdateSection(pFormat, pSectionData, oItemSet, bLinkModeChanged,
+ bLinkMode);
+}
+
+void SAL_CALL
+SwXTextSection::setPropertyValues(
+ const uno::Sequence< OUString >& rPropertyNames,
+ const uno::Sequence< uno::Any >& rValues)
+{
+ SolarMutexGuard aGuard;
+
+ // workaround for bad designed API
+ try
+ {
+ m_pImpl->SetPropertyValues_Impl( rPropertyNames, rValues );
+ }
+ catch (const beans::UnknownPropertyException &rException)
+ {
+ // wrap the original (here not allowed) exception in
+ // a WrappedTargetException that gets thrown instead.
+ lang::WrappedTargetException aWExc;
+ aWExc.TargetException <<= rException;
+ throw aWExc;
+ }
+}
+
+void SwXTextSection::setPropertyValue(
+ const OUString& rPropertyName, const uno::Any& rValue)
+{
+ SolarMutexGuard aGuard;
+
+ m_pImpl->SetPropertyValues_Impl( { rPropertyName } , { rValue } );
+}
+
+uno::Sequence< uno::Any >
+SwXTextSection::Impl::GetPropertyValues_Impl(
+ const uno::Sequence< OUString > & rPropertyNames )
+{
+ SwSectionFormat *const pFormat = GetSectionFormat();
+ if (!pFormat && !m_bIsDescriptor)
+ {
+ throw uno::RuntimeException( "non-descriptor section without format");
+ }
+
+ uno::Sequence< uno::Any > aRet(rPropertyNames.getLength());
+ uno::Any* pRet = aRet.getArray();
+ SwSection *const pSect = pFormat ? pFormat->GetSection() : nullptr;
+ const OUString* pPropertyNames = rPropertyNames.getConstArray();
+
+ for (sal_Int32 nProperty = 0; nProperty < rPropertyNames.getLength();
+ nProperty++)
+ {
+ SfxItemPropertyMapEntry const*const pEntry =
+ m_rPropSet.getPropertyMap().getByName(pPropertyNames[nProperty]);
+ if (!pEntry)
+ {
+ throw beans::UnknownPropertyException(
+ "Unknown property: " + pPropertyNames[nProperty],
+ m_rThis.getXWeak());
+ }
+ switch(pEntry->nWID)
+ {
+ case WID_SECT_CONDITION:
+ {
+ const OUString uTmp( m_bIsDescriptor
+ ? m_pProps->m_sCondition
+ : pSect->GetCondition());
+ pRet[nProperty] <<= uTmp;
+ }
+ break;
+ case WID_SECT_DDE_TYPE:
+ case WID_SECT_DDE_FILE:
+ case WID_SECT_DDE_ELEMENT:
+ {
+ OUString sRet;
+ if (m_bIsDescriptor)
+ {
+ if (m_pProps->m_bDDE)
+ {
+ sRet = m_pProps->m_sLinkFileName;
+ }
+ }
+ else if (SectionType::DdeLink == pSect->GetType())
+ {
+ sRet = pSect->GetLinkFileName();
+ }
+ pRet[nProperty] <<= sRet.getToken(pEntry->nWID - WID_SECT_DDE_TYPE,
+ sfx2::cTokenSeparator);
+ }
+ break;
+ case WID_SECT_DDE_AUTOUPDATE:
+ {
+ // GetUpdateType() returns .._ALWAYS or .._ONCALL
+ if (pSect && pSect->IsLinkType() && pSect->IsConnected()) // #i73247#
+ {
+ const bool bTemp =
+ (pSect->GetUpdateType() == SfxLinkUpdateMode::ALWAYS);
+ pRet[nProperty] <<= bTemp;
+ }
+ }
+ break;
+ case WID_SECT_LINK :
+ {
+ text::SectionFileLink aLink;
+ if (m_bIsDescriptor)
+ {
+ if (!m_pProps->m_bDDE)
+ {
+ aLink.FileURL = m_pProps->m_sLinkFileName;
+ aLink.FilterName = m_pProps->m_sSectionFilter;
+ }
+ }
+ else if (SectionType::FileLink == pSect->GetType())
+ {
+ const OUString& sRet( pSect->GetLinkFileName() );
+ sal_Int32 nIndex(0);
+ aLink.FileURL =
+ sRet.getToken(0, sfx2::cTokenSeparator, nIndex);
+ aLink.FilterName =
+ sRet.getToken(0, sfx2::cTokenSeparator, nIndex);
+ }
+ pRet[nProperty] <<= aLink;
+ }
+ break;
+ case WID_SECT_REGION :
+ {
+ OUString sRet;
+ if (m_bIsDescriptor)
+ {
+ sRet = m_pProps->m_sSectionRegion;
+ }
+ else if (SectionType::FileLink == pSect->GetType())
+ {
+ sRet = pSect->GetLinkFileName().getToken(2,
+ sfx2::cTokenSeparator);
+ }
+ pRet[nProperty] <<= sRet;
+ }
+ break;
+ case WID_SECT_VISIBLE :
+ {
+ const bool bTemp = m_bIsDescriptor
+ ? !m_pProps->m_bHidden : !pSect->IsHidden();
+ pRet[nProperty] <<= bTemp;
+ }
+ break;
+ case WID_SECT_CURRENTLY_VISIBLE:
+ {
+ const bool bTemp = m_bIsDescriptor
+ ? !m_pProps->m_bCondHidden : !pSect->IsCondHidden();
+ pRet[nProperty] <<= bTemp;
+ }
+ break;
+ case WID_SECT_PROTECTED:
+ {
+ const bool bTemp = m_bIsDescriptor
+ ? m_pProps->m_bProtect : pSect->IsProtect();
+ pRet[nProperty] <<= bTemp;
+ }
+ break;
+ case WID_SECT_EDIT_IN_READONLY:
+ {
+ const bool bTemp = m_bIsDescriptor
+ ? m_pProps->m_bEditInReadonly : pSect->IsEditInReadonly();
+ pRet[nProperty] <<= bTemp;
+ }
+ break;
+ case FN_PARAM_LINK_DISPLAY_NAME:
+ {
+ if (pFormat)
+ {
+ pRet[nProperty] <<= pFormat->GetSection()->GetSectionName();
+ }
+ }
+ break;
+ case WID_SECT_DOCUMENT_INDEX:
+ {
+ // search enclosing index
+ SwSection* pEnclosingSection = pSect;
+ while ((pEnclosingSection != nullptr) &&
+ (SectionType::ToxContent != pEnclosingSection->GetType()))
+ {
+ pEnclosingSection = pEnclosingSection->GetParent();
+ }
+ SwTOXBaseSection* const pTOXBaseSect = pEnclosingSection ?
+ dynamic_cast<SwTOXBaseSection*>( pEnclosingSection ) : nullptr;
+ if (pTOXBaseSect)
+ {
+ // convert section to TOXBase and get SwXDocumentIndex
+ const uno::Reference<text::XDocumentIndex> xIndex =
+ SwXDocumentIndex::CreateXDocumentIndex(
+ *pTOXBaseSect->GetFormat()->GetDoc(), pTOXBaseSect);
+ pRet[nProperty] <<= xIndex;
+ }
+ // else: no enclosing index found -> empty return value
+ }
+ break;
+ case WID_SECT_IS_GLOBAL_DOC_SECTION:
+ {
+ const bool bRet = pFormat && (nullptr != pFormat->GetGlobalDocSection());
+ pRet[nProperty] <<= bRet;
+ }
+ break;
+ case FN_UNO_ANCHOR_TYPES:
+ case FN_UNO_TEXT_WRAP:
+ case FN_UNO_ANCHOR_TYPE:
+ ::sw::GetDefaultTextContentValue(
+ pRet[nProperty], u"", pEntry->nWID);
+ break;
+ case FN_UNO_REDLINE_NODE_START:
+ case FN_UNO_REDLINE_NODE_END:
+ {
+ if (!pFormat)
+ break; // #i73247#
+ SwNode* pSectNode = pFormat->GetSectionNode();
+ if (FN_UNO_REDLINE_NODE_END == pEntry->nWID)
+ {
+ pSectNode = pSectNode->EndOfSectionNode();
+ }
+ const SwRedlineTable& rRedTable =
+ pFormat->GetDoc()->getIDocumentRedlineAccess().GetRedlineTable();
+ for (SwRangeRedline* pRedline : rRedTable)
+ {
+ const SwNode& rRedPointNode = pRedline->GetPointNode();
+ const SwNode& rRedMarkNode = pRedline->GetMarkNode();
+ if ((&rRedPointNode == pSectNode) ||
+ (&rRedMarkNode == pSectNode))
+ {
+ const SwNode& rStartOfRedline =
+ (SwNodeIndex(rRedPointNode) <=
+ SwNodeIndex(rRedMarkNode))
+ ? rRedPointNode : rRedMarkNode;
+ const bool bIsStart = (&rStartOfRedline == pSectNode);
+ pRet[nProperty] <<=
+ SwXRedlinePortion::CreateRedlineProperties(
+ *pRedline, bIsStart);
+ break;
+ }
+ }
+ }
+ break;
+ case WID_SECT_PASSWORD:
+ {
+ pRet[nProperty] <<= m_bIsDescriptor
+ ? m_pProps->m_Password : pSect->GetPassword();
+ }
+ break;
+ default:
+ {
+ if (pFormat)
+ {
+ m_rPropSet.getPropertyValue(*pEntry,
+ pFormat->GetAttrSet(), pRet[nProperty]);
+ }
+ else
+ {
+ const SfxPoolItem* pQueryItem = nullptr;
+ if (RES_COL == pEntry->nWID)
+ {
+ if (!m_pProps->m_pColItem)
+ {
+ m_pProps->m_pColItem.reset(new SwFormatCol);
+ }
+ pQueryItem = m_pProps->m_pColItem.get();
+ }
+ else if (RES_BACKGROUND == pEntry->nWID)
+ {
+ if (!m_pProps->m_pBrushItem)
+ {
+ m_pProps->m_pBrushItem.reset(
+ new SvxBrushItem(RES_BACKGROUND));
+ }
+ pQueryItem = m_pProps->m_pBrushItem.get();
+ }
+ else if (RES_FTN_AT_TXTEND == pEntry->nWID)
+ {
+ if (!m_pProps->m_pFootnoteItem)
+ {
+ m_pProps->m_pFootnoteItem.reset(new SwFormatFootnoteAtTextEnd);
+ }
+ pQueryItem = m_pProps->m_pFootnoteItem.get();
+ }
+ else if (RES_END_AT_TXTEND == pEntry->nWID)
+ {
+ if (!m_pProps->m_pEndItem)
+ {
+ m_pProps->m_pEndItem.reset(new SwFormatEndAtTextEnd);
+ }
+ pQueryItem = m_pProps->m_pEndItem.get();
+ }
+ else if (RES_UNKNOWNATR_CONTAINER== pEntry->nWID)
+ {
+ if (!m_pProps->m_pXMLAttr)
+ {
+ m_pProps->m_pXMLAttr.reset(
+ new SvXMLAttrContainerItem);
+ }
+ pQueryItem = m_pProps->m_pXMLAttr.get();
+ }
+ else if (RES_COLUMNBALANCE== pEntry->nWID)
+ {
+ if (!m_pProps->m_pNoBalanceItem)
+ {
+ m_pProps->m_pNoBalanceItem.reset(
+ new SwFormatNoBalancedColumns);
+ }
+ pQueryItem = m_pProps->m_pNoBalanceItem.get();
+ }
+ else if (RES_FRAMEDIR == pEntry->nWID)
+ {
+ if (!m_pProps->m_pFrameDirItem)
+ {
+ m_pProps->m_pFrameDirItem.reset(
+ new SvxFrameDirectionItem(
+ SvxFrameDirection::Environment, RES_FRAMEDIR));
+ }
+ pQueryItem = m_pProps->m_pFrameDirItem.get();
+ }
+ else if (RES_LR_SPACE == pEntry->nWID)
+ {
+ if (!m_pProps->m_pLRSpaceItem)
+ {
+ m_pProps->m_pLRSpaceItem.reset(
+ new SvxLRSpaceItem( RES_LR_SPACE ));
+ }
+ pQueryItem = m_pProps->m_pLRSpaceItem.get();
+ }
+ if (pQueryItem)
+ {
+ pQueryItem->QueryValue(pRet[nProperty],
+ pEntry->nMemberId);
+ }
+ }
+ }
+ }
+ }
+ return aRet;
+}
+
+uno::Sequence< uno::Any > SAL_CALL
+SwXTextSection::getPropertyValues(
+ const uno::Sequence< OUString >& rPropertyNames)
+{
+ SolarMutexGuard aGuard;
+ uno::Sequence< uno::Any > aValues;
+
+ // workaround for bad designed API
+ try
+ {
+ aValues = m_pImpl->GetPropertyValues_Impl( rPropertyNames );
+ }
+ catch (beans::UnknownPropertyException &)
+ {
+ css::uno::Any anyEx = cppu::getCaughtException();
+ throw lang::WrappedTargetRuntimeException("Unknown property exception caught",
+ getXWeak(), anyEx );
+ }
+ catch (lang::WrappedTargetException &)
+ {
+ css::uno::Any anyEx = cppu::getCaughtException();
+ throw lang::WrappedTargetRuntimeException("WrappedTargetException caught",
+ getXWeak(), anyEx );
+ }
+
+ return aValues;
+}
+
+uno::Any SAL_CALL
+SwXTextSection::getPropertyValue(const OUString& rPropertyName)
+{
+ SolarMutexGuard aGuard;
+
+ uno::Sequence< OUString > aPropertyNames { rPropertyName };
+ return m_pImpl->GetPropertyValues_Impl(aPropertyNames).getConstArray()[0];
+}
+
+void SAL_CALL SwXTextSection::addPropertiesChangeListener(
+ const uno::Sequence< OUString >& /*aPropertyNames*/,
+ const uno::Reference< beans::XPropertiesChangeListener >& /*xListener*/ )
+{
+ OSL_FAIL("SwXTextSection::addPropertiesChangeListener(): not implemented");
+}
+
+void SAL_CALL SwXTextSection::removePropertiesChangeListener(
+ const uno::Reference< beans::XPropertiesChangeListener >& /*xListener*/ )
+{
+ OSL_FAIL("SwXTextSection::removePropertiesChangeListener(): not implemented");
+}
+
+void SAL_CALL SwXTextSection::firePropertiesChangeEvent(
+ const uno::Sequence< OUString >& /*aPropertyNames*/,
+ const uno::Reference< beans::XPropertiesChangeListener >& /*xListener*/ )
+{
+ OSL_FAIL("SwXTextSection::firePropertiesChangeEvent(): not implemented");
+}
+
+void SAL_CALL
+SwXTextSection::addPropertyChangeListener(
+ const OUString& /*rPropertyName*/,
+ const uno::Reference< beans::XPropertyChangeListener >& /*xListener*/)
+{
+ OSL_FAIL("SwXTextSection::addPropertyChangeListener(): not implemented");
+}
+
+void SAL_CALL
+SwXTextSection::removePropertyChangeListener(
+ const OUString& /*rPropertyName*/,
+ const uno::Reference< beans::XPropertyChangeListener >& /*xListener*/)
+{
+ OSL_FAIL("SwXTextSection::removePropertyChangeListener(): not implemented");
+}
+
+void SAL_CALL
+SwXTextSection::addVetoableChangeListener(
+ const OUString& /*rPropertyName*/,
+ const uno::Reference< beans::XVetoableChangeListener >& /*xListener*/)
+{
+ OSL_FAIL("SwXTextSection::addVetoableChangeListener(): not implemented");
+}
+
+void SAL_CALL
+SwXTextSection::removeVetoableChangeListener(
+ const OUString& /*rPropertyName*/,
+ const uno::Reference< beans::XVetoableChangeListener >& /*xListener*/)
+{
+ OSL_FAIL("SwXTextSection::removeVetoableChangeListener(): not implemented");
+}
+
+beans::PropertyState SAL_CALL
+SwXTextSection::getPropertyState(const OUString& rPropertyName)
+{
+ SolarMutexGuard aGuard;
+
+ uno::Sequence< OUString > aNames { rPropertyName };
+ return getPropertyStates(aNames).getConstArray()[0];
+}
+
+uno::Sequence< beans::PropertyState > SAL_CALL
+SwXTextSection::getPropertyStates(
+ const uno::Sequence< OUString >& rPropertyNames)
+{
+ SolarMutexGuard aGuard;
+
+ SwSectionFormat *const pFormat = m_pImpl->GetSectionFormat();
+ if (!pFormat && !m_pImpl->m_bIsDescriptor)
+ {
+ throw uno::RuntimeException();
+ }
+
+ uno::Sequence< beans::PropertyState > aStates(rPropertyNames.getLength());
+ beans::PropertyState *const pStates = aStates.getArray();
+ const OUString* pNames = rPropertyNames.getConstArray();
+ for (sal_Int32 i = 0; i < rPropertyNames.getLength(); i++)
+ {
+ pStates[i] = beans::PropertyState_DEFAULT_VALUE;
+ SfxItemPropertyMapEntry const*const pEntry =
+ m_pImpl->m_rPropSet.getPropertyMap().getByName( pNames[i]);
+ if (!pEntry)
+ {
+ throw beans::UnknownPropertyException(
+ "Unknown property: " + pNames[i],
+ getXWeak());
+ }
+ switch (pEntry->nWID)
+ {
+ case WID_SECT_CONDITION:
+ case WID_SECT_DDE_TYPE:
+ case WID_SECT_DDE_FILE:
+ case WID_SECT_DDE_ELEMENT:
+ case WID_SECT_DDE_AUTOUPDATE:
+ case WID_SECT_LINK:
+ case WID_SECT_REGION :
+ case WID_SECT_VISIBLE:
+ case WID_SECT_PROTECTED:
+ case WID_SECT_EDIT_IN_READONLY:
+ case FN_PARAM_LINK_DISPLAY_NAME:
+ case FN_UNO_ANCHOR_TYPES:
+ case FN_UNO_TEXT_WRAP:
+ case FN_UNO_ANCHOR_TYPE:
+ pStates[i] = beans::PropertyState_DIRECT_VALUE;
+ break;
+ default:
+ {
+ if (pFormat)
+ {
+ pStates[i] = m_pImpl->m_rPropSet.getPropertyState(
+ pNames[i], pFormat->GetAttrSet());
+ }
+ else
+ {
+ if (RES_COL == pEntry->nWID)
+ {
+ if (!m_pImpl->m_pProps->m_pColItem)
+ {
+ pStates[i] = beans::PropertyState_DEFAULT_VALUE;
+ }
+ else
+ {
+ pStates[i] = beans::PropertyState_DIRECT_VALUE;
+ }
+ }
+ else
+ {
+ if (!m_pImpl->m_pProps->m_pBrushItem)
+ {
+ pStates[i] = beans::PropertyState_DEFAULT_VALUE;
+ }
+ else
+ {
+ pStates[i] = beans::PropertyState_DIRECT_VALUE;
+ }
+ }
+ }
+ }
+ }
+ }
+ return aStates;
+}
+
+void SAL_CALL
+SwXTextSection::setPropertyToDefault(const OUString& rPropertyName)
+{
+ SolarMutexGuard aGuard;
+
+ SwSectionFormat *const pFormat = m_pImpl->GetSectionFormat();
+ if (!pFormat && !m_pImpl->m_bIsDescriptor)
+ {
+ throw uno::RuntimeException();
+ }
+
+ SfxItemPropertyMapEntry const*const pEntry =
+ m_pImpl->m_rPropSet.getPropertyMap().getByName(rPropertyName);
+ if (!pEntry)
+ {
+ throw beans::UnknownPropertyException(
+ "Unknown property: " + rPropertyName,
+ getXWeak());
+ }
+ if (pEntry->nFlags & beans::PropertyAttribute::READONLY)
+ {
+ throw uno::RuntimeException(
+ "Property is read-only: " + rPropertyName,
+ getXWeak());
+ }
+
+ std::unique_ptr<SwSectionData> const pSectionData(
+ pFormat ? new SwSectionData(*pFormat->GetSection()) : nullptr);
+
+ std::optional<SfxItemSet> oNewAttrSet;
+ bool bLinkModeChanged = false;
+
+ switch (pEntry->nWID)
+ {
+ case WID_SECT_CONDITION:
+ {
+ if (m_pImpl->m_bIsDescriptor)
+ {
+ m_pImpl->m_pProps->m_sCondition.clear();
+ }
+ else
+ {
+ pSectionData->SetCondition(OUString());
+ }
+ }
+ break;
+ case WID_SECT_DDE_TYPE :
+ case WID_SECT_DDE_FILE :
+ case WID_SECT_DDE_ELEMENT :
+ case WID_SECT_LINK :
+ case WID_SECT_REGION :
+ if (m_pImpl->m_bIsDescriptor)
+ {
+ m_pImpl->m_pProps->m_bDDE = false;
+ m_pImpl->m_pProps->m_sLinkFileName.clear();
+ m_pImpl->m_pProps->m_sSectionRegion.clear();
+ m_pImpl->m_pProps->m_sSectionFilter.clear();
+ }
+ else
+ {
+ pSectionData->SetType(SectionType::Content);
+ }
+ break;
+ case WID_SECT_DDE_AUTOUPDATE:
+ if (m_pImpl->m_bIsDescriptor)
+ {
+ m_pImpl->m_pProps->m_bUpdateType = true;
+ }
+ else
+ {
+ bLinkModeChanged = true;
+ }
+ break;
+ case WID_SECT_VISIBLE :
+ {
+ if (m_pImpl->m_bIsDescriptor)
+ {
+ m_pImpl->m_pProps->m_bHidden = false;
+ }
+ else
+ {
+ pSectionData->SetHidden(false);
+ }
+ }
+ break;
+ case WID_SECT_PROTECTED:
+ {
+ if (m_pImpl->m_bIsDescriptor)
+ {
+ m_pImpl->m_pProps->m_bProtect = false;
+ }
+ else
+ {
+ pSectionData->SetProtectFlag(false);
+ }
+ }
+ break;
+ case WID_SECT_EDIT_IN_READONLY:
+ {
+ if (m_pImpl->m_bIsDescriptor)
+ {
+ m_pImpl->m_pProps->m_bEditInReadonly = false;
+ }
+ else
+ {
+ pSectionData->SetEditInReadonlyFlag(false);
+ }
+ }
+ break;
+
+ case FN_UNO_ANCHOR_TYPES:
+ case FN_UNO_TEXT_WRAP:
+ case FN_UNO_ANCHOR_TYPE:
+ break;
+ default:
+ {
+ if (SfxItemPool::IsWhich(pEntry->nWID))
+ {
+ if (pFormat)
+ {
+ const SfxItemSet& rOldAttrSet = pFormat->GetAttrSet();
+ oNewAttrSet.emplace(*rOldAttrSet.GetPool(), pEntry->nWID, pEntry->nWID);
+ oNewAttrSet->ClearItem(pEntry->nWID);
+ }
+ else
+ {
+ if (RES_COL == pEntry->nWID)
+ {
+ m_pImpl->m_pProps->m_pColItem.reset();
+ }
+ else if (RES_BACKGROUND == pEntry->nWID)
+ {
+ m_pImpl->m_pProps->m_pBrushItem.reset();
+ }
+ }
+ }
+ }
+ }
+
+ lcl_UpdateSection(pFormat, pSectionData, oNewAttrSet, bLinkModeChanged);
+}
+
+uno::Any SAL_CALL
+SwXTextSection::getPropertyDefault(const OUString& rPropertyName)
+{
+ SolarMutexGuard aGuard;
+
+ uno::Any aRet;
+ SwSectionFormat *const pFormat = m_pImpl->GetSectionFormat();
+ SfxItemPropertyMapEntry const*const pEntry =
+ m_pImpl->m_rPropSet.getPropertyMap().getByName(rPropertyName);
+ if (!pEntry)
+ {
+ throw beans::UnknownPropertyException(
+ "Unknown property: " + rPropertyName,
+ getXWeak());
+ }
+
+ switch(pEntry->nWID)
+ {
+ case WID_SECT_CONDITION:
+ case WID_SECT_DDE_TYPE :
+ case WID_SECT_DDE_FILE :
+ case WID_SECT_DDE_ELEMENT :
+ case WID_SECT_REGION :
+ case FN_PARAM_LINK_DISPLAY_NAME:
+ aRet <<= OUString();
+ break;
+ case WID_SECT_LINK :
+ aRet <<= text::SectionFileLink();
+ break;
+ case WID_SECT_DDE_AUTOUPDATE:
+ case WID_SECT_VISIBLE :
+ aRet <<= true;
+ break;
+ case WID_SECT_PROTECTED:
+ case WID_SECT_EDIT_IN_READONLY:
+ aRet <<= false;
+ break;
+ case FN_UNO_ANCHOR_TYPES:
+ case FN_UNO_TEXT_WRAP:
+ case FN_UNO_ANCHOR_TYPE:
+ ::sw::GetDefaultTextContentValue(aRet, u"", pEntry->nWID);
+ break;
+ default:
+ if(pFormat && SfxItemPool::IsWhich(pEntry->nWID))
+ {
+ SwDoc *const pDoc = pFormat->GetDoc();
+ const SfxPoolItem& rDefItem =
+ pDoc->GetAttrPool().GetDefaultItem(pEntry->nWID);
+ rDefItem.QueryValue(aRet, pEntry->nMemberId);
+ }
+ }
+ return aRet;
+}
+
+OUString SAL_CALL SwXTextSection::getName()
+{
+ SolarMutexGuard aGuard;
+
+ OUString sRet;
+ SwSectionFormat const*const pFormat = m_pImpl->GetSectionFormat();
+ if(pFormat)
+ {
+ sRet = pFormat->GetSection()->GetSectionName();
+ }
+ else if (m_pImpl->m_bIsDescriptor)
+ {
+ sRet = m_pImpl->m_sName;
+ }
+ else
+ {
+ throw uno::RuntimeException();
+ }
+ return sRet;
+}
+
+void SAL_CALL SwXTextSection::setName(const OUString& rName)
+{
+ SolarMutexGuard aGuard;
+
+ SwSectionFormat *const pFormat = m_pImpl->GetSectionFormat();
+ if(pFormat)
+ {
+ SwSection *const pSect = pFormat->GetSection();
+ SwSectionData aSection(*pSect);
+ aSection.SetSectionName(rName);
+
+ const SwSectionFormats& rFormats = pFormat->GetDoc()->GetSections();
+ size_t nApplyPos = SIZE_MAX;
+ for( size_t i = 0; i < rFormats.size(); ++i )
+ {
+ if(rFormats[i]->GetSection() == pSect)
+ {
+ nApplyPos = i;
+ }
+ else if (rName == rFormats[i]->GetSection()->GetSectionName())
+ {
+ throw uno::RuntimeException();
+ }
+ }
+ if (nApplyPos != SIZE_MAX)
+ {
+ {
+ UnoActionContext aContext(pFormat->GetDoc());
+ pFormat->GetDoc()->UpdateSection(nApplyPos, aSection);
+ }
+ {
+ // temporarily remove actions to allow cursor update
+ // TODO: why? no table cursor here!
+ UnoActionRemoveContext aRemoveContext( pFormat->GetDoc() );
+ }
+ }
+ }
+ else if (m_pImpl->m_bIsDescriptor)
+ {
+ m_pImpl->m_sName = rName;
+ }
+ else
+ {
+ throw uno::RuntimeException();
+ }
+}
+
+OUString SAL_CALL
+SwXTextSection::getImplementationName()
+{
+ return "SwXTextSection";
+}
+
+sal_Bool SAL_CALL SwXTextSection::supportsService(const OUString& rServiceName)
+{
+ return cppu::supportsService(this, rServiceName);
+}
+
+uno::Sequence< OUString > SAL_CALL
+SwXTextSection::getSupportedServiceNames()
+{
+ return {
+ "com.sun.star.text.TextContent",
+ "com.sun.star.text.TextSection",
+ "com.sun.star.document.LinkTarget"
+ };
+}
+
+// MetadatableMixin
+::sfx2::Metadatable* SwXTextSection::GetCoreObject()
+{
+ SwSectionFormat *const pSectionFormat( m_pImpl->GetSectionFormat() );
+ return pSectionFormat;
+}
+
+uno::Reference<frame::XModel> SwXTextSection::GetModel()
+{
+ SwSectionFormat *const pSectionFormat( m_pImpl->GetSectionFormat() );
+ if (pSectionFormat)
+ {
+ SwDocShell const*const pShell( pSectionFormat->GetDoc()->GetDocShell() );
+ return pShell ? pShell->GetModel() : nullptr;
+ }
+ return nullptr;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/core/unocore/unosett.cxx b/sw/source/core/unocore/unosett.cxx
new file mode 100644
index 0000000000..bfc4b00a34
--- /dev/null
+++ b/sw/source/core/unocore/unosett.cxx
@@ -0,0 +1,2126 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <editeng/editids.hrc>
+#include <swtypes.hxx>
+#include <unomid.h>
+#include <hintids.hxx>
+#include <strings.hrc>
+#include <poolfmt.hxx>
+#include <fmtcol.hxx>
+#include <unomap.hxx>
+#include <unosett.hxx>
+#include <unoprnms.hxx>
+#include <ftninfo.hxx>
+#include <doc.hxx>
+#include <pagedesc.hxx>
+#include <IDocumentStylePoolAccess.hxx>
+#include <charfmt.hxx>
+#include <lineinfo.hxx>
+#include <docsh.hxx>
+#include <docary.hxx>
+#include <docstyle.hxx>
+#include <editeng/brushitem.hxx>
+#include <com/sun/star/lang/IndexOutOfBoundsException.hpp>
+#include <com/sun/star/text/FootnoteNumbering.hpp>
+#include <com/sun/star/text/HoriOrientation.hpp>
+#include <com/sun/star/style/LineNumberPosition.hpp>
+#include <com/sun/star/awt/FontDescriptor.hpp>
+#include <com/sun/star/awt/XBitmap.hpp>
+#include <com/sun/star/graphic/XGraphic.hpp>
+#include <com/sun/star/beans/PropertyAttribute.hpp>
+#include <o3tl/any.hxx>
+#include <o3tl/enumarray.hxx>
+#include <tools/UnitConversion.hxx>
+#include <vcl/font.hxx>
+#include <editeng/flstitem.hxx>
+#include <vcl/metric.hxx>
+#include <vcl/graph.hxx>
+#include <vcl/GraphicLoader.hxx>
+#include <sfx2/docfile.hxx>
+#include <svtools/ctrltool.hxx>
+#include <vcl/svapp.hxx>
+#include <editeng/unofdesc.hxx>
+#include <fmtornt.hxx>
+#include <SwStyleNameMapper.hxx>
+#include <com/sun/star/text/PositionAndSpaceMode.hpp>
+#include <com/sun/star/text/LabelFollow.hpp>
+#include <numrule.hxx>
+#include <comphelper/servicehelper.hxx>
+#include <comphelper/sequence.hxx>
+#include <cppuhelper/supportsservice.hxx>
+#include <comphelper/propertyvalue.hxx>
+#include <svl/itemprop.hxx>
+#include <svl/listener.hxx>
+#include <paratr.hxx>
+#include <sal/log.hxx>
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::text;
+using namespace ::com::sun::star::style;
+
+
+namespace
+{
+ SvtBroadcaster& GetPageDescNotifier(SwDoc* pDoc)
+ {
+ return pDoc->getIDocumentStylePoolAccess().GetPageDescFromPool(RES_POOLPAGE_STANDARD)->GetNotifier();
+ }
+}
+
+#define WID_PREFIX 0
+#define WID_SUFFIX 1
+#define WID_NUMBERING_TYPE 2
+#define WID_START_AT 3
+#define WID_FOOTNOTE_COUNTING 4
+#define WID_PARAGRAPH_STYLE 5
+#define WID_PAGE_STYLE 6
+#define WID_CHARACTER_STYLE 7
+#define WID_POSITION_END_OF_DOC 8
+#define WID_END_NOTICE 9
+#define WID_BEGIN_NOTICE 10
+#define WID_ANCHOR_CHARACTER_STYLE 11
+#define WID_NUM_ON 12
+#define WID_SEPARATOR_INTERVAL 13
+#define WID_NUMBER_POSITION 14
+#define WID_DISTANCE 15
+#define WID_INTERVAL 16
+#define WID_SEPARATOR_TEXT 17
+#define WID_COUNT_EMPTY_LINES 18
+#define WID_COUNT_LINES_IN_FRAMES 19
+#define WID_RESTART_AT_EACH_PAGE 20
+
+
+static const SfxItemPropertySet* GetFootnoteSet()
+{
+ static const SfxItemPropertyMapEntry aFootnoteMap_Impl[] =
+ {
+ { UNO_NAME_ANCHOR_CHAR_STYLE_NAME,WID_ANCHOR_CHARACTER_STYLE, ::cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ { UNO_NAME_BEGIN_NOTICE, WID_BEGIN_NOTICE, ::cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ { UNO_NAME_CHAR_STYLE_NAME, WID_CHARACTER_STYLE, ::cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ { UNO_NAME_END_NOTICE, WID_END_NOTICE , ::cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ { UNO_NAME_FOOTNOTE_COUNTING, WID_FOOTNOTE_COUNTING, ::cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE, 0},
+ { UNO_NAME_NUMBERING_TYPE, WID_NUMBERING_TYPE, ::cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE, 0},
+ { UNO_NAME_PAGE_STYLE_NAME, WID_PAGE_STYLE, ::cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ { UNO_NAME_PARA_STYLE_NAME, WID_PARAGRAPH_STYLE, ::cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ { UNO_NAME_POSITION_END_OF_DOC, WID_POSITION_END_OF_DOC,cppu::UnoType<bool>::get(), PROPERTY_NONE, 0},
+ { UNO_NAME_PREFIX, WID_PREFIX, ::cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ { UNO_NAME_START_AT, WID_START_AT , ::cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE, 0},
+ { UNO_NAME_SUFFIX, WID_SUFFIX, ::cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ };
+ static const SfxItemPropertySet aFootnoteSet_Impl(aFootnoteMap_Impl);
+ return &aFootnoteSet_Impl;
+}
+
+static const SfxItemPropertySet* GetEndnoteSet()
+{
+ static const SfxItemPropertyMapEntry aEndnoteMap_Impl[] =
+ {
+ { UNO_NAME_ANCHOR_CHAR_STYLE_NAME,WID_ANCHOR_CHARACTER_STYLE, ::cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ { UNO_NAME_CHAR_STYLE_NAME, WID_CHARACTER_STYLE, ::cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ { UNO_NAME_NUMBERING_TYPE, WID_NUMBERING_TYPE, ::cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE, 0},
+ { UNO_NAME_PAGE_STYLE_NAME, WID_PAGE_STYLE, ::cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ { UNO_NAME_PARA_STYLE_NAME, WID_PARAGRAPH_STYLE, ::cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ { UNO_NAME_PREFIX, WID_PREFIX, ::cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ { UNO_NAME_START_AT, WID_START_AT , ::cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE, 0},
+ { UNO_NAME_SUFFIX, WID_SUFFIX, ::cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ };
+ static const SfxItemPropertySet aEndnoteSet_Impl(aEndnoteMap_Impl);
+ return &aEndnoteSet_Impl;
+}
+
+static const SfxItemPropertySet* GetNumberingRulesSet()
+{
+ static const SfxItemPropertyMapEntry aNumberingRulesMap_Impl[] =
+ {
+ { UNO_NAME_IS_ABSOLUTE_MARGINS, WID_IS_ABS_MARGINS, cppu::UnoType<bool>::get(), PROPERTY_NONE, 0},
+ { UNO_NAME_IS_AUTOMATIC, WID_IS_AUTOMATIC, cppu::UnoType<bool>::get(), PROPERTY_NONE, 0},
+ { UNO_NAME_IS_CONTINUOUS_NUMBERING, WID_CONTINUOUS, cppu::UnoType<bool>::get(), PROPERTY_NONE, 0},
+ { UNO_NAME_NAME, WID_RULE_NAME , ::cppu::UnoType<OUString>::get(), PropertyAttribute::READONLY, 0},
+ { UNO_NAME_NUMBERING_IS_OUTLINE, WID_IS_OUTLINE, cppu::UnoType<bool>::get(), PROPERTY_NONE, 0},
+ { UNO_NAME_DEFAULT_LIST_ID, WID_DEFAULT_LIST_ID, ::cppu::UnoType<OUString>::get(), PropertyAttribute::READONLY, 0},
+ };
+ static const SfxItemPropertySet aNumberingRulesSet_Impl( aNumberingRulesMap_Impl );
+ return &aNumberingRulesSet_Impl;
+}
+
+static const SfxItemPropertySet* GetLineNumberingSet()
+{
+ static const SfxItemPropertyMapEntry aLineNumberingMap_Impl[] =
+ {
+ { UNO_NAME_CHAR_STYLE_NAME, WID_CHARACTER_STYLE, ::cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ { UNO_NAME_COUNT_EMPTY_LINES, WID_COUNT_EMPTY_LINES , cppu::UnoType<bool>::get(),PROPERTY_NONE, 0},
+ { UNO_NAME_COUNT_LINES_IN_FRAMES, WID_COUNT_LINES_IN_FRAMES, cppu::UnoType<bool>::get(),PROPERTY_NONE, 0},
+ { UNO_NAME_DISTANCE, WID_DISTANCE , ::cppu::UnoType<sal_Int32>::get(),PROPERTY_NONE, 0},
+ { UNO_NAME_IS_ON, WID_NUM_ON, cppu::UnoType<bool>::get() , PROPERTY_NONE, 0},
+ { UNO_NAME_INTERVAL, WID_INTERVAL , ::cppu::UnoType<sal_Int16>::get(),PROPERTY_NONE, 0},
+ { UNO_NAME_SEPARATOR_TEXT, WID_SEPARATOR_TEXT, ::cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ { UNO_NAME_NUMBER_POSITION, WID_NUMBER_POSITION, ::cppu::UnoType<sal_Int16>::get(),PROPERTY_NONE, 0},
+ { UNO_NAME_NUMBERING_TYPE, WID_NUMBERING_TYPE , ::cppu::UnoType<sal_Int16>::get(),PROPERTY_NONE, 0},
+ { UNO_NAME_RESTART_AT_EACH_PAGE, WID_RESTART_AT_EACH_PAGE, cppu::UnoType<bool>::get() , PROPERTY_NONE, 0},
+ { UNO_NAME_SEPARATOR_INTERVAL, WID_SEPARATOR_INTERVAL, ::cppu::UnoType<sal_Int16>::get(),PROPERTY_NONE, 0},
+ };
+ static const SfxItemPropertySet aLineNumberingSet_Impl(aLineNumberingMap_Impl);
+ return &aLineNumberingSet_Impl;
+}
+
+static SwCharFormat* lcl_getCharFormat(SwDoc* pDoc, const uno::Any& aValue)
+{
+ SwCharFormat* pRet = nullptr;
+ OUString uTmp;
+ aValue >>= uTmp;
+ OUString sCharFormat;
+ SwStyleNameMapper::FillUIName(uTmp, sCharFormat, SwGetPoolIdFromName::ChrFmt);
+ if (sCharFormat != SwResId(STR_POOLCHR_STANDARD))
+ {
+ pRet = pDoc->FindCharFormatByName( sCharFormat );
+ }
+ if(!pRet)
+ {
+ const sal_uInt16 nId = SwStyleNameMapper::GetPoolIdFromUIName(sCharFormat, SwGetPoolIdFromName::ChrFmt);
+ if(USHRT_MAX != nId)
+ pRet = pDoc->getIDocumentStylePoolAccess().GetCharFormatFromPool( nId );
+ }
+ return pRet;
+}
+
+static SwTextFormatColl* lcl_GetParaStyle(SwDoc* pDoc, const uno::Any& aValue)
+{
+ OUString uTmp;
+ aValue >>= uTmp;
+ OUString sParaStyle;
+ SwStyleNameMapper::FillUIName(uTmp, sParaStyle, SwGetPoolIdFromName::TxtColl );
+ SwTextFormatColl* pRet = pDoc->FindTextFormatCollByName( sParaStyle );
+ if( !pRet )
+ {
+ const sal_uInt16 nId = SwStyleNameMapper::GetPoolIdFromUIName( sParaStyle, SwGetPoolIdFromName::TxtColl );
+ if( USHRT_MAX != nId )
+ pRet = pDoc->getIDocumentStylePoolAccess().GetTextCollFromPool( nId );
+ }
+ return pRet;
+}
+
+static SwPageDesc* lcl_GetPageDesc(SwDoc* pDoc, const uno::Any& aValue)
+{
+ OUString uTmp;
+ aValue >>= uTmp;
+ OUString sPageDesc;
+ SwStyleNameMapper::FillUIName(uTmp, sPageDesc, SwGetPoolIdFromName::PageDesc );
+ SwPageDesc* pRet = pDoc->FindPageDesc( sPageDesc );
+ if(!pRet)
+ {
+ const sal_uInt16 nId = SwStyleNameMapper::GetPoolIdFromUIName(sPageDesc, SwGetPoolIdFromName::PageDesc);
+ if(USHRT_MAX != nId)
+ pRet = pDoc->getIDocumentStylePoolAccess().GetPageDescFromPool( nId );
+ }
+ return pRet;
+}
+
+// Numbering
+const o3tl::enumarray<SvxAdjust, sal_Int16> aSvxToUnoAdjust
+{
+ text::HoriOrientation::LEFT, //3
+ text::HoriOrientation::RIGHT, //1
+ sal_Int16(-1),
+ text::HoriOrientation::CENTER, //2
+ sal_Int16(-1),
+ sal_Int16(-1)
+};
+
+OUString SwXFootnoteProperties::getImplementationName()
+{
+ return "SwXFootnoteProperties";
+}
+
+sal_Bool SwXFootnoteProperties::supportsService(const OUString& rServiceName)
+{
+ return cppu::supportsService(this, rServiceName);
+}
+
+Sequence< OUString > SwXFootnoteProperties::getSupportedServiceNames()
+{
+ Sequence<OUString> aRet { "com.sun.star.text.FootnoteSettings" };
+ return aRet;
+}
+
+SwXFootnoteProperties::SwXFootnoteProperties(SwDoc* pDc) :
+ m_pDoc(pDc),
+ m_pPropertySet(GetFootnoteSet())
+{
+}
+
+SwXFootnoteProperties::~SwXFootnoteProperties()
+{
+
+}
+
+uno::Reference< beans::XPropertySetInfo > SwXFootnoteProperties::getPropertySetInfo()
+{
+ static uno::Reference< beans::XPropertySetInfo > aRef = m_pPropertySet->getPropertySetInfo();
+ return aRef;
+}
+
+void SwXFootnoteProperties::setPropertyValue(const OUString& rPropertyName, const uno::Any& aValue)
+{
+ SolarMutexGuard aGuard;
+ if(!m_pDoc)
+ throw uno::RuntimeException();
+
+ const SfxItemPropertyMapEntry* pEntry = m_pPropertySet->getPropertyMap().getByName( rPropertyName );
+ if(!pEntry)
+ throw beans::UnknownPropertyException("Unknown property: " + rPropertyName, getXWeak() );
+
+ if ( pEntry->nFlags & PropertyAttribute::READONLY)
+ throw PropertyVetoException("Property is read-only: " + rPropertyName, getXWeak() );
+ SwFootnoteInfo aFootnoteInfo(m_pDoc->GetFootnoteInfo());
+ switch(pEntry->nWID)
+ {
+ case WID_PREFIX:
+ {
+ OUString uTmp;
+ aValue >>= uTmp;
+ aFootnoteInfo.SetPrefix(uTmp);
+ }
+ break;
+ case WID_SUFFIX:
+ {
+ OUString uTmp;
+ aValue >>= uTmp;
+ aFootnoteInfo.SetSuffix(uTmp);
+ }
+ break;
+ case WID_NUMBERING_TYPE:
+ {
+ sal_Int16 nTmp = 0;
+ aValue >>= nTmp;
+ if(!(nTmp >= 0 &&
+ (nTmp <= SVX_NUM_ARABIC ||
+ nTmp > SVX_NUM_BITMAP)))
+ throw lang::IllegalArgumentException();
+
+ aFootnoteInfo.m_aFormat.SetNumberingType(static_cast<SvxNumType>(nTmp));
+
+ }
+ break;
+ case WID_START_AT:
+ {
+ sal_Int16 nTmp = 0;
+ aValue >>= nTmp;
+ aFootnoteInfo.m_nFootnoteOffset = nTmp;
+ }
+ break;
+ case WID_FOOTNOTE_COUNTING:
+ {
+ sal_Int16 nTmp = 0;
+ aValue >>= nTmp;
+ switch(nTmp)
+ {
+ case FootnoteNumbering::PER_PAGE:
+ aFootnoteInfo.m_eNum = FTNNUM_PAGE;
+ break;
+ case FootnoteNumbering::PER_CHAPTER:
+ aFootnoteInfo.m_eNum = FTNNUM_CHAPTER;
+ break;
+ case FootnoteNumbering::PER_DOCUMENT:
+ aFootnoteInfo.m_eNum = FTNNUM_DOC;
+ break;
+ }
+ }
+ break;
+ case WID_PARAGRAPH_STYLE:
+ {
+ SwTextFormatColl* pColl = lcl_GetParaStyle(m_pDoc, aValue);
+ if(pColl)
+ aFootnoteInfo.SetFootnoteTextColl(*pColl);
+ }
+ break;
+ case WID_PAGE_STYLE:
+ {
+ SwPageDesc* pDesc = lcl_GetPageDesc(m_pDoc, aValue);
+ if(pDesc)
+ aFootnoteInfo.ChgPageDesc( pDesc );
+ }
+ break;
+ case WID_ANCHOR_CHARACTER_STYLE:
+ case WID_CHARACTER_STYLE:
+ {
+ SwCharFormat* pFormat = lcl_getCharFormat(m_pDoc, aValue);
+ if(pFormat)
+ {
+ if(pEntry->nWID == WID_ANCHOR_CHARACTER_STYLE)
+ aFootnoteInfo.SetAnchorCharFormat(pFormat);
+ else
+ aFootnoteInfo.SetCharFormat(pFormat);
+ }
+ }
+ break;
+ case WID_POSITION_END_OF_DOC:
+ {
+ bool bVal = *o3tl::doAccess<bool>(aValue);
+ aFootnoteInfo.m_ePos = bVal ? FTNPOS_CHAPTER : FTNPOS_PAGE;
+ }
+ break;
+ case WID_END_NOTICE:
+ {
+ OUString uTmp;
+ aValue >>= uTmp;
+ aFootnoteInfo.m_aQuoVadis = uTmp;
+ }
+ break;
+ case WID_BEGIN_NOTICE:
+ {
+ OUString uTmp;
+ aValue >>= uTmp;
+ aFootnoteInfo.m_aErgoSum = uTmp;
+ }
+ break;
+ }
+ m_pDoc->SetFootnoteInfo(aFootnoteInfo);
+
+
+}
+
+uno::Any SwXFootnoteProperties::getPropertyValue(const OUString& rPropertyName)
+{
+ SolarMutexGuard aGuard;
+ uno::Any aRet;
+ if(!m_pDoc)
+ throw uno::RuntimeException();
+
+ const SfxItemPropertyMapEntry* pEntry = m_pPropertySet->getPropertyMap().getByName( rPropertyName );
+ if(!pEntry)
+ throw UnknownPropertyException("Unknown property: " + rPropertyName, getXWeak() );
+
+ const SwFootnoteInfo& rFootnoteInfo = m_pDoc->GetFootnoteInfo();
+ switch(pEntry->nWID)
+ {
+ case WID_PREFIX:
+ {
+ aRet <<= rFootnoteInfo.GetPrefix();
+ }
+ break;
+ case WID_SUFFIX:
+ {
+ aRet <<= rFootnoteInfo.GetSuffix();
+ }
+ break;
+ case WID_NUMBERING_TYPE :
+ {
+ aRet <<= static_cast<sal_Int16>(rFootnoteInfo.m_aFormat.GetNumberingType());
+ }
+ break;
+ case WID_START_AT:
+ aRet <<= static_cast<sal_Int16>(rFootnoteInfo.m_nFootnoteOffset);
+ break;
+ case WID_FOOTNOTE_COUNTING :
+ {
+ sal_Int16 nRet = 0;
+ switch(rFootnoteInfo.m_eNum)
+ {
+ case FTNNUM_PAGE:
+ nRet = FootnoteNumbering::PER_PAGE;
+ break;
+ case FTNNUM_CHAPTER:
+ nRet = FootnoteNumbering::PER_CHAPTER;
+ break;
+ case FTNNUM_DOC:
+ nRet = FootnoteNumbering::PER_DOCUMENT;
+ break;
+ }
+ aRet <<= nRet;
+ }
+ break;
+ case WID_PARAGRAPH_STYLE :
+ {
+ SwTextFormatColl* pColl = rFootnoteInfo.GetFootnoteTextColl();
+ OUString aString;
+ if(pColl)
+ aString = pColl->GetName();
+ SwStyleNameMapper::FillProgName(aString, aString, SwGetPoolIdFromName::TxtColl);
+ aRet <<= aString;
+ }
+ break;
+ case WID_PAGE_STYLE :
+ {
+ OUString aString;
+ if( rFootnoteInfo.KnowsPageDesc() )
+ {
+ SwStyleNameMapper::FillProgName(
+ rFootnoteInfo.GetPageDesc( *m_pDoc )->GetName(),
+ aString,
+ SwGetPoolIdFromName::PageDesc);
+ }
+ aRet <<= aString;
+ }
+ break;
+ case WID_ANCHOR_CHARACTER_STYLE:
+ case WID_CHARACTER_STYLE:
+ {
+ OUString aString;
+ const SwCharFormat* pCharFormat = rFootnoteInfo.GetCurrentCharFormat(pEntry->nWID == WID_ANCHOR_CHARACTER_STYLE);
+ if( pCharFormat )
+ {
+ SwStyleNameMapper::FillProgName(
+ pCharFormat->GetName(),
+ aString,
+ SwGetPoolIdFromName::ChrFmt);
+ }
+ aRet <<= aString;
+ }
+ break;
+ case WID_POSITION_END_OF_DOC:
+ aRet <<= FTNPOS_CHAPTER == rFootnoteInfo.m_ePos;
+ break;
+ case WID_END_NOTICE :
+ aRet <<= rFootnoteInfo.m_aQuoVadis;
+ break;
+ case WID_BEGIN_NOTICE :
+ aRet <<= rFootnoteInfo.m_aErgoSum;
+ break;
+ }
+
+
+ return aRet;
+}
+
+void SwXFootnoteProperties::addPropertyChangeListener(
+ const OUString& /*rPropertyName*/, const uno::Reference< beans::XPropertyChangeListener > & /*xListener*/)
+{
+ OSL_FAIL("not implemented");
+}
+
+void SwXFootnoteProperties::removePropertyChangeListener(
+ const OUString& /*rPropertyName*/, const uno::Reference< beans::XPropertyChangeListener > & /*xListener*/)
+{
+ OSL_FAIL("not implemented");
+}
+
+void SwXFootnoteProperties::addVetoableChangeListener(
+ const OUString& /*rPropertyName*/, const uno::Reference< beans::XVetoableChangeListener > & /*xListener*/)
+{
+ OSL_FAIL("not implemented");
+}
+
+void SwXFootnoteProperties::removeVetoableChangeListener(
+ const OUString& /*rPropertyName*/, const uno::Reference< beans::XVetoableChangeListener > & /*xListener*/)
+{
+ OSL_FAIL("not implemented");
+}
+
+OUString SwXEndnoteProperties::getImplementationName()
+{
+ return "SwXEndnoteProperties";
+}
+
+sal_Bool SwXEndnoteProperties::supportsService(const OUString& rServiceName)
+{
+ return cppu::supportsService(this, rServiceName);
+}
+
+Sequence< OUString > SwXEndnoteProperties::getSupportedServiceNames()
+{
+ Sequence<OUString> aRet { "com.sun.star.text.FootnoteSettings" };
+ return aRet;
+}
+
+SwXEndnoteProperties::SwXEndnoteProperties(SwDoc* pDc) :
+ m_pDoc(pDc),
+ m_pPropertySet(GetEndnoteSet())
+{
+}
+
+SwXEndnoteProperties::~SwXEndnoteProperties()
+{
+}
+
+uno::Reference< beans::XPropertySetInfo > SwXEndnoteProperties::getPropertySetInfo()
+{
+ static uno::Reference< beans::XPropertySetInfo > aRef = m_pPropertySet->getPropertySetInfo();
+ return aRef;
+}
+
+void SwXEndnoteProperties::setPropertyValue(const OUString& rPropertyName, const uno::Any& aValue)
+{
+ SolarMutexGuard aGuard;
+ if(!m_pDoc)
+ return;
+
+ const SfxItemPropertyMapEntry* pEntry = m_pPropertySet->getPropertyMap().getByName( rPropertyName );
+ if(!pEntry)
+ throw UnknownPropertyException("Unknown property: " + rPropertyName, getXWeak() );
+
+ if ( pEntry->nFlags & PropertyAttribute::READONLY)
+ throw PropertyVetoException("Property is read-only: " + rPropertyName, getXWeak() );
+ SwEndNoteInfo aEndInfo(m_pDoc->GetEndNoteInfo());
+ switch(pEntry->nWID)
+ {
+ case WID_PREFIX:
+ {
+ OUString uTmp;
+ aValue >>= uTmp;
+ aEndInfo.SetPrefix(uTmp);
+ }
+ break;
+ case WID_SUFFIX:
+ {
+ OUString uTmp;
+ aValue >>= uTmp;
+ aEndInfo.SetSuffix(uTmp);
+ }
+ break;
+ case WID_NUMBERING_TYPE :
+ {
+ sal_Int16 nTmp = 0;
+ aValue >>= nTmp;
+ aEndInfo.m_aFormat.SetNumberingType(static_cast<SvxNumType>(nTmp));
+ }
+ break;
+ case WID_START_AT:
+ {
+ sal_Int16 nTmp = 0;
+ aValue >>= nTmp;
+ aEndInfo.m_nFootnoteOffset = nTmp;
+ }
+ break;
+ case WID_PARAGRAPH_STYLE :
+ {
+ SwTextFormatColl* pColl = lcl_GetParaStyle(m_pDoc, aValue);
+ if(pColl)
+ aEndInfo.SetFootnoteTextColl(*pColl);
+ }
+ break;
+ case WID_PAGE_STYLE :
+ {
+ SwPageDesc* pDesc = lcl_GetPageDesc(m_pDoc, aValue);
+ if(pDesc)
+ aEndInfo.ChgPageDesc( pDesc );
+ }
+ break;
+ case WID_ANCHOR_CHARACTER_STYLE:
+ case WID_CHARACTER_STYLE :
+ {
+ SwCharFormat* pFormat = lcl_getCharFormat(m_pDoc, aValue);
+ if(pFormat)
+ {
+ if(pEntry->nWID == WID_ANCHOR_CHARACTER_STYLE)
+ aEndInfo.SetAnchorCharFormat(pFormat);
+ else
+ aEndInfo.SetCharFormat(pFormat);
+ }
+ }
+ break;
+ }
+ m_pDoc->SetEndNoteInfo(aEndInfo);
+}
+
+uno::Any SwXEndnoteProperties::getPropertyValue(const OUString& rPropertyName)
+{
+ SolarMutexGuard aGuard;
+ uno::Any aRet;
+ if(m_pDoc)
+ {
+ const SfxItemPropertyMapEntry* pEntry = m_pPropertySet->getPropertyMap().getByName( rPropertyName );
+ if(!pEntry)
+ throw UnknownPropertyException("Unknown property: " + rPropertyName, getXWeak() );
+
+ const SwEndNoteInfo& rEndInfo = m_pDoc->GetEndNoteInfo();
+ switch(pEntry->nWID)
+ {
+ case WID_PREFIX:
+ aRet <<= rEndInfo.GetPrefix();
+ break;
+ case WID_SUFFIX:
+ aRet <<= rEndInfo.GetSuffix();
+ break;
+ case WID_NUMBERING_TYPE :
+ aRet <<= static_cast<sal_Int16>(rEndInfo.m_aFormat.GetNumberingType());
+ break;
+ case WID_START_AT:
+ aRet <<= static_cast<sal_Int16>(rEndInfo.m_nFootnoteOffset);
+ break;
+ case WID_PARAGRAPH_STYLE :
+ {
+ SwTextFormatColl* pColl = rEndInfo.GetFootnoteTextColl();
+ OUString aString;
+ if(pColl)
+ aString = pColl->GetName();
+ SwStyleNameMapper::FillProgName(
+ aString,
+ aString,
+ SwGetPoolIdFromName::TxtColl);
+ aRet <<= aString;
+
+ }
+ break;
+ case WID_PAGE_STYLE :
+ {
+ OUString aString;
+ if( rEndInfo.KnowsPageDesc() )
+ {
+ SwStyleNameMapper::FillProgName(
+ rEndInfo.GetPageDesc( *m_pDoc )->GetName(),
+ aString,
+ SwGetPoolIdFromName::PageDesc);
+ }
+ aRet <<= aString;
+ }
+ break;
+ case WID_ANCHOR_CHARACTER_STYLE:
+ case WID_CHARACTER_STYLE:
+ {
+ OUString aString;
+ const SwCharFormat* pCharFormat = rEndInfo.GetCurrentCharFormat( pEntry->nWID == WID_ANCHOR_CHARACTER_STYLE );
+ if( pCharFormat )
+ {
+ SwStyleNameMapper::FillProgName(
+ pCharFormat->GetName(),
+ aString,
+ SwGetPoolIdFromName::ChrFmt);
+ }
+ aRet <<= aString;
+ }
+ break;
+ }
+
+ }
+ return aRet;
+}
+
+void SwXEndnoteProperties::addPropertyChangeListener(
+ const OUString& /*PropertyName*/, const uno::Reference< beans::XPropertyChangeListener > & /*xListener*/)
+{
+ OSL_FAIL("not implemented");
+}
+
+void SwXEndnoteProperties::removePropertyChangeListener(const OUString& /*PropertyName*/,
+ const uno:: Reference< beans::XPropertyChangeListener > & /*xListener*/)
+{
+ OSL_FAIL("not implemented");
+}
+
+void SwXEndnoteProperties::addVetoableChangeListener(const OUString& /*PropertyName*/,
+ const uno:: Reference< beans::XVetoableChangeListener > & /*xListener*/)
+{
+ OSL_FAIL("not implemented");
+}
+
+void SwXEndnoteProperties::removeVetoableChangeListener(const OUString& /*PropertyName*/, const uno:: Reference< beans::XVetoableChangeListener > & /*xListener*/)
+{
+ OSL_FAIL("not implemented");
+}
+
+OUString SwXLineNumberingProperties::getImplementationName()
+{
+ return "SwXLineNumberingProperties";
+}
+
+sal_Bool SwXLineNumberingProperties::supportsService(const OUString& rServiceName)
+{
+ return cppu::supportsService(this, rServiceName);
+}
+
+Sequence< OUString > SwXLineNumberingProperties::getSupportedServiceNames()
+{
+ Sequence<OUString> aRet { "com.sun.star.text.LineNumberingProperties" };
+ return aRet;
+}
+
+SwXLineNumberingProperties::SwXLineNumberingProperties(SwDoc* pDc) :
+ m_pDoc(pDc),
+ m_pPropertySet(GetLineNumberingSet())
+{
+}
+
+SwXLineNumberingProperties::~SwXLineNumberingProperties()
+{
+}
+
+uno::Reference< beans::XPropertySetInfo > SwXLineNumberingProperties::getPropertySetInfo()
+{
+ static uno::Reference< beans::XPropertySetInfo > aRef = m_pPropertySet->getPropertySetInfo();
+ return aRef;
+}
+
+void SwXLineNumberingProperties::setPropertyValue(
+ const OUString& rPropertyName, const Any& aValue)
+{
+ SolarMutexGuard aGuard;
+ if(!m_pDoc)
+ throw uno::RuntimeException();
+
+ const SfxItemPropertyMapEntry* pEntry = m_pPropertySet->getPropertyMap().getByName( rPropertyName );
+ if(!pEntry)
+ throw UnknownPropertyException("Unknown property: " + rPropertyName, getXWeak() );
+
+ if ( pEntry->nFlags & PropertyAttribute::READONLY)
+ throw PropertyVetoException("Property is read-only: " + rPropertyName, getXWeak() );
+ SwLineNumberInfo aFontMetric(m_pDoc->GetLineNumberInfo());
+ switch(pEntry->nWID)
+ {
+ case WID_NUM_ON:
+ {
+ bool bVal = *o3tl::doAccess<bool>(aValue);
+ aFontMetric.SetPaintLineNumbers(bVal);
+ }
+ break;
+ case WID_CHARACTER_STYLE :
+ {
+ SwCharFormat* pFormat = lcl_getCharFormat(m_pDoc, aValue);
+ if(pFormat)
+ aFontMetric.SetCharFormat(pFormat);
+ }
+ break;
+ case WID_NUMBERING_TYPE :
+ {
+ SvxNumberType aNumType(aFontMetric.GetNumType());
+ sal_Int16 nTmp = 0;
+ aValue >>= nTmp;
+ aNumType.SetNumberingType(static_cast<SvxNumType>(nTmp));
+ aFontMetric.SetNumType(aNumType);
+ }
+ break;
+ case WID_NUMBER_POSITION :
+ {
+ sal_Int16 nTmp = 0;
+ aValue >>= nTmp;
+ switch(nTmp)
+ {
+ case style::LineNumberPosition::LEFT:
+ aFontMetric.SetPos(LINENUMBER_POS_LEFT);
+ break;
+ case style::LineNumberPosition::RIGHT :
+ aFontMetric.SetPos(LINENUMBER_POS_RIGHT);
+ break;
+ case style::LineNumberPosition::INSIDE:
+ aFontMetric.SetPos(LINENUMBER_POS_INSIDE);
+ break;
+ case style::LineNumberPosition::OUTSIDE:
+ aFontMetric.SetPos(LINENUMBER_POS_OUTSIDE);
+ break;
+ }
+ }
+ break;
+ case WID_DISTANCE :
+ {
+ sal_Int32 nVal = 0;
+ aValue >>= nVal;
+ sal_Int32 nTmp = o3tl::toTwips(nVal, o3tl::Length::mm100);
+ if (nTmp > SAL_MAX_UINT16)
+ nTmp = SAL_MAX_UINT16;
+ aFontMetric.SetPosFromLeft(nTmp);
+ }
+ break;
+ case WID_INTERVAL :
+ {
+ sal_Int16 nTmp = 0;
+ aValue >>= nTmp;
+ if( nTmp > 0)
+ aFontMetric.SetCountBy(nTmp);
+ }
+ break;
+ case WID_SEPARATOR_TEXT :
+ {
+ OUString uTmp;
+ aValue >>= uTmp;
+ aFontMetric.SetDivider(uTmp);
+ }
+ break;
+ case WID_SEPARATOR_INTERVAL:
+ {
+ sal_Int16 nTmp = 0;
+ aValue >>= nTmp;
+ if( nTmp >= 0)
+ aFontMetric.SetDividerCountBy(nTmp);
+ }
+ break;
+ case WID_COUNT_EMPTY_LINES :
+ {
+ bool bVal = *o3tl::doAccess<bool>(aValue);
+ aFontMetric.SetCountBlankLines(bVal);
+ }
+ break;
+ case WID_COUNT_LINES_IN_FRAMES :
+ {
+ bool bVal = *o3tl::doAccess<bool>(aValue);
+ aFontMetric.SetCountInFlys(bVal);
+ }
+ break;
+ case WID_RESTART_AT_EACH_PAGE :
+ {
+ bool bVal = *o3tl::doAccess<bool>(aValue);
+ aFontMetric.SetRestartEachPage(bVal);
+ }
+ break;
+ }
+ m_pDoc->SetLineNumberInfo(aFontMetric);
+}
+
+Any SwXLineNumberingProperties::getPropertyValue(const OUString& rPropertyName)
+{
+ SolarMutexGuard aGuard;
+ Any aRet;
+ if(!m_pDoc)
+ throw uno::RuntimeException();
+
+ const SfxItemPropertyMapEntry* pEntry = m_pPropertySet->getPropertyMap().getByName( rPropertyName );
+ if(!pEntry)
+ throw UnknownPropertyException("Unknown property: " + rPropertyName, getXWeak() );
+
+ const SwLineNumberInfo& rInfo = m_pDoc->GetLineNumberInfo();
+ switch(pEntry->nWID)
+ {
+ case WID_NUM_ON:
+ aRet <<= rInfo.IsPaintLineNumbers();
+ break;
+ case WID_CHARACTER_STYLE :
+ {
+ OUString aString;
+ // return empty string if no char format is set
+ // otherwise it would be created here
+ if(rInfo.HasCharFormat())
+ {
+ SwStyleNameMapper::FillProgName(
+ rInfo.GetCharFormat(m_pDoc->getIDocumentStylePoolAccess())->GetName(),
+ aString,
+ SwGetPoolIdFromName::ChrFmt);
+ }
+ aRet <<= aString;
+ }
+ break;
+ case WID_NUMBERING_TYPE :
+ aRet <<= static_cast<sal_Int16>(rInfo.GetNumType().GetNumberingType());
+ break;
+ case WID_NUMBER_POSITION :
+ {
+ sal_Int16 nRet = 0;
+ switch(rInfo.GetPos())
+ {
+ case LINENUMBER_POS_LEFT:
+ nRet = style::LineNumberPosition::LEFT;
+ break;
+ case LINENUMBER_POS_RIGHT :
+ nRet = style::LineNumberPosition::RIGHT ;
+ break;
+ case LINENUMBER_POS_INSIDE:
+ nRet = style::LineNumberPosition::INSIDE ;
+ break;
+ case LINENUMBER_POS_OUTSIDE :
+ nRet = style::LineNumberPosition::OUTSIDE ;
+ break;
+ }
+ aRet <<= nRet;
+ }
+ break;
+ case WID_DISTANCE :
+ {
+ sal_uInt32 nPos = rInfo.GetPosFromLeft();
+ if(USHRT_MAX == nPos)
+ nPos = 0;
+ aRet <<= static_cast < sal_Int32 >(convertTwipToMm100(nPos));
+ }
+ break;
+ case WID_INTERVAL :
+ aRet <<= static_cast<sal_Int16>(rInfo.GetCountBy());
+ break;
+ case WID_SEPARATOR_TEXT :
+ aRet <<= rInfo.GetDivider();
+ break;
+ case WID_SEPARATOR_INTERVAL:
+ aRet <<= static_cast<sal_Int16>(rInfo.GetDividerCountBy());
+ break;
+ case WID_COUNT_EMPTY_LINES :
+ aRet <<= rInfo.IsCountBlankLines();
+ break;
+ case WID_COUNT_LINES_IN_FRAMES :
+ aRet <<= rInfo.IsCountInFlys();
+ break;
+ case WID_RESTART_AT_EACH_PAGE :
+ aRet <<= rInfo.IsRestartEachPage();
+ break;
+ }
+ return aRet;
+}
+
+void SwXLineNumberingProperties::addPropertyChangeListener(const OUString& /*rPropertyName*/, const uno:: Reference< beans::XPropertyChangeListener > & /*xListener*/)
+{
+OSL_FAIL("not implemented");
+}
+
+void SwXLineNumberingProperties::removePropertyChangeListener(const OUString& /*rPropertyName*/, const uno:: Reference< beans::XPropertyChangeListener > & /*xListener*/)
+{
+OSL_FAIL("not implemented");
+}
+
+void SwXLineNumberingProperties::addVetoableChangeListener(const OUString& /*rPropertyName*/, const uno:: Reference< beans::XVetoableChangeListener > & /*xListener*/)
+{
+OSL_FAIL("not implemented");
+}
+
+void SwXLineNumberingProperties::removeVetoableChangeListener(const OUString& /*rPropertyName*/, const uno:: Reference< beans::XVetoableChangeListener > & /*xListener*/)
+{
+OSL_FAIL("not implemented");
+}
+
+constexpr OUString aInvalidStyle = u"__XXX___invalid"_ustr;
+
+class SwXNumberingRules::Impl
+ : public SvtListener
+{
+ SwXNumberingRules& m_rParent;
+ virtual void Notify(const SfxHint&) override;
+ public:
+ explicit Impl(SwXNumberingRules& rParent) : m_rParent(rParent) {}
+};
+
+bool SwXNumberingRules::isInvalidStyle(std::u16string_view rName)
+{
+ return rName == aInvalidStyle;
+}
+
+OUString SwXNumberingRules::getImplementationName()
+{
+ return "SwXNumberingRules";
+}
+
+sal_Bool SwXNumberingRules::supportsService(const OUString& rServiceName)
+{
+ return cppu::supportsService(this, rServiceName);
+}
+
+Sequence< OUString > SwXNumberingRules::getSupportedServiceNames()
+{
+ Sequence<OUString> aRet { "com.sun.star.text.NumberingRules" };
+ return aRet;
+}
+
+SwXNumberingRules::SwXNumberingRules(const SwNumRule& rRule, SwDoc* doc) :
+ m_pImpl(new SwXNumberingRules::Impl(*this)),
+ m_pDoc(doc),
+ m_pDocShell(nullptr),
+ m_pNumRule(new SwNumRule(rRule)),
+ m_pPropertySet(GetNumberingRulesSet()),
+ m_bOwnNumRuleCreated(true)
+{
+ // first organize the document - it is dependent on the set character formats
+ // if no format is set, it should work as well
+ for( sal_uInt16 i = 0; i < MAXLEVEL; ++i)
+ {
+ SwNumFormat rFormat(m_pNumRule->Get(i));
+ SwCharFormat* pCharFormat = rFormat.GetCharFormat();
+ if(pCharFormat)
+ {
+ m_pDoc = pCharFormat->GetDoc();
+ break;
+ }
+ }
+ if(m_pDoc)
+ m_pImpl->StartListening(GetPageDescNotifier(m_pDoc));
+ for(sal_uInt16 i = 0; i < MAXLEVEL; ++i)
+ {
+ m_sNewCharStyleNames[i] = aInvalidStyle;
+ m_sNewBulletFontNames[i] = aInvalidStyle;
+ }
+}
+
+SwXNumberingRules::SwXNumberingRules(SwDocShell& rDocSh) :
+ m_pImpl(new SwXNumberingRules::Impl(*this)),
+ m_pDoc(nullptr),
+ m_pDocShell(&rDocSh),
+ m_pNumRule(nullptr),
+ m_pPropertySet(GetNumberingRulesSet()),
+ m_bOwnNumRuleCreated(false)
+{
+ if (!m_pDocShell->GetDoc())
+ throw uno::RuntimeException("Unitialized shell passed to SwXNumberingRules constructor");
+ m_pImpl->StartListening(GetPageDescNotifier(m_pDocShell->GetDoc()));
+}
+
+SwXNumberingRules::SwXNumberingRules(SwDoc& rDoc) :
+ m_pImpl(new SwXNumberingRules::Impl(*this)),
+ m_pDoc(&rDoc),
+ m_pDocShell(nullptr),
+ m_pNumRule(nullptr),
+ m_pPropertySet(GetNumberingRulesSet()),
+ m_bOwnNumRuleCreated(false)
+{
+ m_pImpl->StartListening(GetPageDescNotifier(&rDoc));
+ m_sCreatedNumRuleName = rDoc.GetUniqueNumRuleName();
+ rDoc.MakeNumRule( m_sCreatedNumRuleName, nullptr, false,
+ // #i89178#
+ numfunc::GetDefaultPositionAndSpaceMode() );
+}
+
+SwXNumberingRules::~SwXNumberingRules()
+{
+ SolarMutexGuard aGuard;
+ if(m_pDoc && !m_sCreatedNumRuleName.isEmpty())
+ m_pDoc->DelNumRule( m_sCreatedNumRuleName );
+ if( m_bOwnNumRuleCreated )
+ delete m_pNumRule;
+}
+
+void SwXNumberingRules::replaceByIndex(sal_Int32 nIndex, const uno::Any& rElement)
+{
+ SolarMutexGuard aGuard;
+ if(nIndex < 0 || MAXLEVEL <= nIndex)
+ throw lang::IndexOutOfBoundsException();
+
+ auto rProperties = o3tl::tryAccess<uno::Sequence<beans::PropertyValue>>(
+ rElement);
+ if(!rProperties)
+ throw lang::IllegalArgumentException();
+ SwNumRule* pRule = nullptr;
+ if(m_pNumRule)
+ SwXNumberingRules::SetNumberingRuleByIndex( *m_pNumRule,
+ *rProperties, nIndex);
+ else if(m_pDocShell)
+ {
+ // #i87650# - correction of cws warnings:
+ SwNumRule aNumRule( *(m_pDocShell->GetDoc()->GetOutlineNumRule()) );
+ SwXNumberingRules::SetNumberingRuleByIndex( aNumRule,
+ *rProperties, nIndex);
+ // set character format if needed
+ // this code appears to be dead - except when a style is assigned for BITMAP numbering?
+ const SwCharFormats* pFormats = m_pDocShell->GetDoc()->GetCharFormats();
+ const size_t nChCount = pFormats->size();
+ for(sal_uInt16 i = 0; i < MAXLEVEL;i++)
+ {
+ SwNumFormat aFormat(aNumRule.Get( i ));
+ if (!m_sNewCharStyleNames[i].isEmpty() &&
+ (!aFormat.GetCharFormat() || aFormat.GetCharFormat()->GetName()!= m_sNewCharStyleNames[i]))
+ {
+ SwCharFormat* pCharFormat = nullptr;
+ for(size_t j = 0; j< nChCount; ++j)
+ {
+ SwCharFormat* pTmp = (*pFormats)[j];
+ if(pTmp->GetName() == m_sNewCharStyleNames[i])
+ {
+ pCharFormat = pTmp;
+ break;
+ }
+ }
+ if(!pCharFormat)
+ {
+ SfxStyleSheetBase* pBase;
+ pBase = m_pDocShell->GetStyleSheetPool()->Find(m_sNewCharStyleNames[i],
+ SfxStyleFamily::Char);
+ if(!pBase)
+ pBase = &m_pDocShell->GetStyleSheetPool()->Make(m_sNewCharStyleNames[i], SfxStyleFamily::Char);
+ pCharFormat = static_cast<SwDocStyleSheet*>(pBase)->GetCharFormat();
+
+ }
+ aFormat.SetCharFormat( pCharFormat );
+ aNumRule.Set( i, aFormat );
+ }
+ }
+ m_pDocShell->GetDoc()->SetOutlineNumRule( aNumRule );
+ }
+ else if(m_pDoc && !m_sCreatedNumRuleName.isEmpty() &&
+ nullptr != (pRule = m_pDoc->FindNumRulePtr( m_sCreatedNumRuleName )))
+ {
+ SwXNumberingRules::SetNumberingRuleByIndex( *pRule,
+ *rProperties, nIndex);
+
+ pRule->Validate(*m_pDoc);
+ }
+ else
+ throw uno::RuntimeException();
+}
+
+sal_Int32 SwXNumberingRules::getCount()
+{
+ return MAXLEVEL;
+}
+
+uno::Any SwXNumberingRules::getByIndex(sal_Int32 nIndex)
+{
+ SolarMutexGuard aGuard;
+ if(nIndex < 0 || MAXLEVEL <= nIndex)
+ throw lang::IndexOutOfBoundsException();
+
+ uno::Any aVal;
+ const SwNumRule* pRule = m_pNumRule;
+ if(!pRule && m_pDoc && !m_sCreatedNumRuleName.isEmpty())
+ pRule = m_pDoc->FindNumRulePtr( m_sCreatedNumRuleName );
+ if(pRule)
+ {
+ uno::Sequence<beans::PropertyValue> aRet = GetNumberingRuleByIndex(
+ *pRule, nIndex);
+ aVal <<= aRet;
+
+ }
+ else if(m_pDocShell)
+ {
+ uno::Sequence<beans::PropertyValue> aRet = GetNumberingRuleByIndex(
+ *m_pDocShell->GetDoc()->GetOutlineNumRule(), nIndex);
+ aVal <<= aRet;
+ }
+ else
+ throw uno::RuntimeException();
+ return aVal;
+}
+
+uno::Type SwXNumberingRules::getElementType()
+{
+ return cppu::UnoType<uno::Sequence<beans::PropertyValue>>::get();
+}
+
+sal_Bool SwXNumberingRules::hasElements()
+{
+ return true;
+}
+
+const TranslateId STR_POOLCOLL_HEADLINE_ARY[]
+{
+ STR_POOLCOLL_HEADLINE1,
+ STR_POOLCOLL_HEADLINE2,
+ STR_POOLCOLL_HEADLINE3,
+ STR_POOLCOLL_HEADLINE4,
+ STR_POOLCOLL_HEADLINE5,
+ STR_POOLCOLL_HEADLINE6,
+ STR_POOLCOLL_HEADLINE7,
+ STR_POOLCOLL_HEADLINE8,
+ STR_POOLCOLL_HEADLINE9,
+ STR_POOLCOLL_HEADLINE10
+};
+
+uno::Sequence<beans::PropertyValue> SwXNumberingRules::GetNumberingRuleByIndex(
+ const SwNumRule& rNumRule, sal_Int32 nIndex) const
+{
+ SolarMutexGuard aGuard;
+ OSL_ENSURE( 0 <= nIndex && nIndex < MAXLEVEL, "index out of range" );
+
+ const SwNumFormat& rFormat = rNumRule.Get( o3tl::narrowing<sal_uInt16>(nIndex) );
+
+ SwCharFormat* pCharFormat = rFormat.GetCharFormat();
+ OUString CharStyleName;
+ if (pCharFormat)
+ CharStyleName = pCharFormat->GetName();
+
+ // Whether or not a style is present: the array entry overwrites this string
+ if (!m_sNewCharStyleNames[nIndex].isEmpty() &&
+ !SwXNumberingRules::isInvalidStyle(m_sNewCharStyleNames[nIndex]))
+ {
+ CharStyleName = m_sNewCharStyleNames[nIndex];
+ }
+
+ OUString aUString;
+ if (m_pDocShell) // -> Chapter Numbering
+ {
+ // template name
+ OUString sValue(SwResId(STR_POOLCOLL_HEADLINE_ARY[nIndex]));
+ const SwTextFormatColls* pColls = m_pDocShell->GetDoc()->GetTextFormatColls();
+ const size_t nCount = pColls->size();
+ for(size_t i = 0; i < nCount; ++i)
+ {
+ SwTextFormatColl &rTextColl = *pColls->operator[](i);
+ if(rTextColl.IsDefault())
+ continue;
+
+ const sal_Int16 nOutLevel = rTextColl.IsAssignedToListLevelOfOutlineStyle()
+ ? static_cast<sal_Int16>(rTextColl.GetAssignedOutlineStyleLevel())
+ : MAXLEVEL;
+ if ( nOutLevel == nIndex )
+ {
+ sValue = rTextColl.GetName();
+ break; // the style for the level in question has been found
+ }
+ else if( sValue==rTextColl.GetName() )
+ {
+ // if the default for the level is existing, but its
+ // level is different, then it cannot be the default.
+ sValue.clear();
+ }
+ }
+ SwStyleNameMapper::FillProgName(sValue, aUString, SwGetPoolIdFromName::TxtColl);
+ }
+
+ OUString referer;
+ if (m_pDoc != nullptr) {
+ auto const sh = m_pDoc->GetPersist();
+ if (sh != nullptr && sh->HasName()) {
+ referer = sh->GetMedium()->GetName();
+ }
+ }
+ return GetPropertiesForNumFormat(
+ rFormat, CharStyleName, m_pDocShell ? & aUString : nullptr, referer);
+
+}
+
+uno::Sequence<beans::PropertyValue> SwXNumberingRules::GetPropertiesForNumFormat(
+ const SwNumFormat& rFormat, OUString const& rCharFormatName,
+ OUString const*const pHeadingStyleName, OUString const & referer)
+{
+ bool bChapterNum = pHeadingStyleName != nullptr;
+
+ std::vector<PropertyValue> aPropertyValues;
+ aPropertyValues.reserve(32);
+ //fill all properties into the array
+
+ //adjust
+ SvxAdjust eAdj = rFormat.GetNumAdjust();
+ sal_Int16 nINT16 = aSvxToUnoAdjust[eAdj];
+ aPropertyValues.push_back(comphelper::makePropertyValue("Adjust", nINT16));
+
+ //parentnumbering
+ nINT16 = rFormat.GetIncludeUpperLevels();
+ aPropertyValues.push_back(comphelper::makePropertyValue("ParentNumbering", nINT16));
+
+ //prefix
+ OUString aUString = rFormat.GetPrefix();
+ aPropertyValues.push_back(comphelper::makePropertyValue("Prefix", aUString));
+
+ //suffix
+ aUString = rFormat.GetSuffix();
+ aPropertyValues.push_back(comphelper::makePropertyValue("Suffix", aUString));
+
+ //listformat
+ if (rFormat.HasListFormat())
+ {
+ aPropertyValues.push_back(comphelper::makePropertyValue("ListFormat", rFormat.GetListFormat()));
+ }
+
+ if (rFormat.GetIsLegal())
+ aPropertyValues.push_back(comphelper::makePropertyValue(UNO_NAME_LEVEL_IS_LEGAL, true));
+
+ //char style name
+ aUString.clear();
+ SwStyleNameMapper::FillProgName( rCharFormatName, aUString, SwGetPoolIdFromName::ChrFmt);
+ aPropertyValues.push_back(comphelper::makePropertyValue("CharStyleName", aUString));
+
+ //startvalue
+ nINT16 = rFormat.GetStart();
+ aPropertyValues.push_back(comphelper::makePropertyValue("StartWith", nINT16));
+
+ if ( rFormat.GetPositionAndSpaceMode() == SvxNumberFormat::LABEL_WIDTH_AND_POSITION )
+ {
+ //leftmargin
+ sal_Int32 nINT32 = convertTwipToMm100(rFormat.GetAbsLSpace());
+ aPropertyValues.push_back(comphelper::makePropertyValue(UNO_NAME_LEFT_MARGIN, nINT32));
+
+ //chartextoffset
+ nINT32 = convertTwipToMm100(rFormat.GetCharTextDistance());
+ aPropertyValues.push_back(comphelper::makePropertyValue(UNO_NAME_SYMBOL_TEXT_DISTANCE, nINT32));
+
+ //firstlineoffset
+ nINT32 = convertTwipToMm100(rFormat.GetFirstLineOffset());
+ aPropertyValues.push_back(comphelper::makePropertyValue(UNO_NAME_FIRST_LINE_OFFSET, nINT32));
+ }
+
+ // PositionAndSpaceMode
+ nINT16 = PositionAndSpaceMode::LABEL_WIDTH_AND_POSITION;
+ if ( rFormat.GetPositionAndSpaceMode() == SvxNumberFormat::LABEL_ALIGNMENT )
+ {
+ nINT16 = PositionAndSpaceMode::LABEL_ALIGNMENT;
+ }
+ aPropertyValues.push_back(comphelper::makePropertyValue(UNO_NAME_POSITION_AND_SPACE_MODE, nINT16));
+
+ if ( rFormat.GetPositionAndSpaceMode() == SvxNumberFormat::LABEL_ALIGNMENT )
+ {
+ // LabelFollowedBy
+ nINT16 = LabelFollow::LISTTAB;
+ if ( rFormat.GetLabelFollowedBy() == SvxNumberFormat::SPACE )
+ {
+ nINT16 = LabelFollow::SPACE;
+ }
+ else if ( rFormat.GetLabelFollowedBy() == SvxNumberFormat::NOTHING )
+ {
+ nINT16 = LabelFollow::NOTHING;
+ }
+ else if ( rFormat.GetLabelFollowedBy() == SvxNumberFormat::NEWLINE )
+ {
+ nINT16 = LabelFollow::NEWLINE;
+ }
+ aPropertyValues.push_back(comphelper::makePropertyValue(UNO_NAME_LABEL_FOLLOWED_BY, nINT16));
+
+ // ListtabStopPosition
+ sal_Int32 nINT32 = convertTwipToMm100(rFormat.GetListtabPos());
+ aPropertyValues.push_back(comphelper::makePropertyValue(UNO_NAME_LISTTAB_STOP_POSITION, nINT32));
+
+ // FirstLineIndent
+ nINT32 = convertTwipToMm100(rFormat.GetFirstLineIndent());
+ aPropertyValues.push_back(comphelper::makePropertyValue(UNO_NAME_FIRST_LINE_INDENT, nINT32));
+
+ // IndentAt
+ nINT32 = convertTwipToMm100(rFormat.GetIndentAt());
+ aPropertyValues.push_back(comphelper::makePropertyValue(UNO_NAME_INDENT_AT, nINT32));
+ }
+
+ //numberingtype
+ nINT16 = rFormat.GetNumberingType();
+ aPropertyValues.push_back(comphelper::makePropertyValue("NumberingType", nINT16));
+
+ if(!bChapterNum)
+ {
+ if(SVX_NUM_CHAR_SPECIAL == rFormat.GetNumberingType())
+ {
+ sal_UCS4 cBullet = rFormat.GetBulletChar();
+
+ //BulletId
+ nINT16 = cBullet;
+ aPropertyValues.push_back(comphelper::makePropertyValue("BulletId", nINT16));
+
+ std::optional<vcl::Font> pFont = rFormat.GetBulletFont();
+
+ //BulletChar
+ aUString = OUString(&cBullet, 1);
+ aPropertyValues.push_back(comphelper::makePropertyValue("BulletChar", aUString));
+
+ //BulletFontName
+ aUString = pFont ? pFont->GetStyleName() : OUString();
+ aPropertyValues.push_back(comphelper::makePropertyValue("BulletFontName", aUString));
+
+ //BulletFont
+ if(pFont)
+ {
+ awt::FontDescriptor aDesc;
+ SvxUnoFontDescriptor::ConvertFromFont( *pFont, aDesc );
+ aPropertyValues.push_back(comphelper::makePropertyValue(UNO_NAME_BULLET_FONT, aDesc));
+ }
+ }
+ if (SVX_NUM_BITMAP == rFormat.GetNumberingType())
+ {
+ const SvxBrushItem* pBrush = rFormat.GetBrush();
+ const Graphic* pGraphic = pBrush ? pBrush->GetGraphic(referer) : nullptr;
+ if (pGraphic)
+ {
+ //GraphicBitmap
+ uno::Reference<awt::XBitmap> xBitmap(pGraphic->GetXGraphic(), uno::UNO_QUERY);
+ aPropertyValues.push_back(comphelper::makePropertyValue(UNO_NAME_GRAPHIC_BITMAP, xBitmap));
+ }
+
+ Size aSize = rFormat.GetGraphicSize();
+ // #i101131#
+ // adjust conversion due to type mismatch between <Size> and <awt::Size>
+ awt::Size aAwtSize(convertTwipToMm100(aSize.Width()), convertTwipToMm100(aSize.Height()));
+ aPropertyValues.push_back(comphelper::makePropertyValue(UNO_NAME_GRAPHIC_SIZE, aAwtSize));
+
+ const SwFormatVertOrient* pOrient = rFormat.GetGraphicOrientation();
+ if(pOrient)
+ {
+ uno::Any any;
+ pOrient->QueryValue(any);
+ aPropertyValues.emplace_back(
+ UNO_NAME_VERT_ORIENT, -1, any, PropertyState_DIRECT_VALUE);
+ }
+ }
+ }
+ else
+ {
+ aUString = *pHeadingStyleName;
+ aPropertyValues.push_back(comphelper::makePropertyValue(UNO_NAME_HEADING_STYLE_NAME, aUString));
+ }
+
+ return ::comphelper::containerToSequence(aPropertyValues);
+}
+
+void SwXNumberingRules::SetNumberingRuleByIndex(
+ SwNumRule& rNumRule,
+ const uno::Sequence<beans::PropertyValue>& rProperties, sal_Int32 nIndex)
+{
+ SolarMutexGuard aGuard;
+ OSL_ENSURE( 0 <= nIndex && nIndex < MAXLEVEL, "index out of range" );
+
+ SwNumFormat aFormat(rNumRule.Get( o3tl::narrowing<sal_uInt16>(nIndex) ));
+
+ OUString sHeadingStyleName;
+ OUString sParagraphStyleName;
+
+ SetPropertiesToNumFormat(aFormat, m_sNewCharStyleNames[nIndex],
+ &m_sNewBulletFontNames[nIndex],
+ &sHeadingStyleName, &sParagraphStyleName,
+ m_pDoc, m_pDocShell, rProperties);
+
+
+ if (m_pDoc && !sParagraphStyleName.isEmpty())
+ {
+ const SwTextFormatColls* pColls = m_pDoc->GetTextFormatColls();
+ const size_t nCount = pColls->size();
+ for (size_t k = 0; k < nCount; ++k)
+ {
+ SwTextFormatColl &rTextColl = *((*pColls)[k]);
+ if (rTextColl.GetName() == sParagraphStyleName)
+ rTextColl.SetFormatAttr( SwNumRuleItem( rNumRule.GetName()));
+ }
+ }
+
+ if (!sHeadingStyleName.isEmpty())
+ {
+ assert(m_pDocShell);
+ const SwTextFormatColls* pColls = m_pDocShell->GetDoc()->GetTextFormatColls();
+ const size_t nCount = pColls->size();
+ for (size_t k = 0; k < nCount; ++k)
+ {
+ SwTextFormatColl &rTextColl = *((*pColls)[k]);
+ if (rTextColl.IsDefault())
+ continue;
+ if (rTextColl.IsAssignedToListLevelOfOutlineStyle() &&
+ rTextColl.GetAssignedOutlineStyleLevel() == nIndex &&
+ rTextColl.GetName() != sHeadingStyleName)
+ {
+ rTextColl.DeleteAssignmentToListLevelOfOutlineStyle();
+ }
+ else if (rTextColl.GetName() == sHeadingStyleName)
+ {
+ rTextColl.AssignToListLevelOfOutlineStyle( nIndex );
+ }
+ }
+ }
+
+ rNumRule.Set(o3tl::narrowing<sal_uInt16>(nIndex), aFormat);
+}
+
+void SwXNumberingRules::SetPropertiesToNumFormat(
+ SwNumFormat & aFormat,
+ OUString & rCharStyleName, OUString *const pBulletFontName,
+ OUString *const pHeadingStyleName,
+ OUString *const pParagraphStyleName,
+ SwDoc *const pDoc,
+ SwDocShell *const pDocShell,
+ const uno::Sequence<beans::PropertyValue>& rProperties)
+{
+ assert(pDoc == nullptr || pDocShell == nullptr); // can't be both ordinary and chapter numbering
+
+ bool bWrongArg = false;
+ std::unique_ptr<SvxBrushItem> pSetBrush;
+ std::unique_ptr<Size> pSetSize;
+ std::unique_ptr<SwFormatVertOrient> pSetVOrient;
+ bool bCharStyleNameSet = false;
+
+ for (const beans::PropertyValue& rProp : rProperties)
+ {
+ if (rProp.Name == UNO_NAME_ADJUST)
+ {
+ sal_Int16 nValue = text::HoriOrientation::NONE;
+ rProp.Value >>= nValue;
+ switch (nValue) {
+ case text::HoriOrientation::RIGHT:
+ aFormat.SetNumAdjust(SvxAdjust::Right);
+ break;
+ case text::HoriOrientation::CENTER:
+ aFormat.SetNumAdjust(SvxAdjust::Center);
+ break;
+ case text::HoriOrientation::LEFT:
+ aFormat.SetNumAdjust(SvxAdjust::Left);
+ break;
+ default:
+ bWrongArg = true;
+ break;
+ }
+ }
+ else if (rProp.Name == UNO_NAME_PARENT_NUMBERING)
+ {
+ sal_Int16 nSet = 0;
+ rProp.Value >>= nSet;
+ if(nSet >= 0 && MAXLEVEL >= nSet)
+ aFormat.SetIncludeUpperLevels( static_cast< sal_uInt8 >(nSet) );
+ }
+ else if (rProp.Name == UNO_NAME_PREFIX)
+ {
+ OUString uTmp;
+ rProp.Value >>= uTmp;
+ aFormat.SetPrefix(uTmp);
+ }
+ else if (rProp.Name == UNO_NAME_SUFFIX)
+ {
+ OUString uTmp;
+ rProp.Value >>= uTmp;
+ aFormat.SetSuffix(uTmp);
+ }
+ else if (rProp.Name == UNO_NAME_CHAR_STYLE_NAME)
+ {
+ bCharStyleNameSet = true;
+ OUString uTmp;
+ rProp.Value >>= uTmp;
+ OUString sCharFormatName;
+ SwStyleNameMapper::FillUIName( uTmp, sCharFormatName, SwGetPoolIdFromName::ChrFmt );
+ SwDoc *const pLocalDoc = pDocShell ? pDocShell->GetDoc() : pDoc;
+ if (sCharFormatName.isEmpty())
+ {
+ rCharStyleName.clear();
+ aFormat.SetCharFormat(nullptr);
+ aFormat.SetCharFormatName("");
+ }
+ else if (pLocalDoc)
+ {
+ SwCharFormat* pCharFormat = nullptr;
+ if (!sCharFormatName.isEmpty())
+ {
+ pCharFormat = pLocalDoc->FindCharFormatByName(sCharFormatName);
+ if(!pCharFormat)
+ {
+
+ SfxStyleSheetBase* pBase;
+ SfxStyleSheetBasePool* pPool = pLocalDoc->GetDocShell()->GetStyleSheetPool();
+ pBase = pPool->Find(sCharFormatName, SfxStyleFamily::Char);
+ if(!pBase)
+ pBase = &pPool->Make(sCharFormatName, SfxStyleFamily::Char);
+ pCharFormat = static_cast<SwDocStyleSheet*>(pBase)->GetCharFormat();
+ }
+ }
+ aFormat.SetCharFormat( pCharFormat );
+ // #i51842#
+ // If the character format has been found its name should not be in the
+ // char style names array
+ rCharStyleName.clear();
+ }
+ else
+ rCharStyleName = sCharFormatName;
+ }
+ else if (rProp.Name == UNO_NAME_START_WITH)
+ {
+ sal_Int16 nVal = 0;
+ rProp.Value >>= nVal;
+ aFormat.SetStart(nVal);
+ }
+ else if (rProp.Name == UNO_NAME_LEFT_MARGIN)
+ {
+ sal_Int32 nValue = 0;
+ rProp.Value >>= nValue;
+ // #i23727# nValue can be negative
+ aFormat.SetAbsLSpace(o3tl::toTwips(nValue, o3tl::Length::mm100));
+ }
+ else if (rProp.Name == UNO_NAME_SYMBOL_TEXT_DISTANCE)
+ {
+ sal_Int32 nValue = 0;
+ rProp.Value >>= nValue;
+ if (nValue >= 0)
+ aFormat.SetCharTextDistance(o3tl::toTwips(nValue, o3tl::Length::mm100));
+ else
+ bWrongArg = true;
+ }
+ else if (rProp.Name == UNO_NAME_FIRST_LINE_OFFSET)
+ {
+ sal_Int32 nValue = 0;
+ rProp.Value >>= nValue;
+ // #i23727# nValue can be positive
+ nValue = o3tl::toTwips(nValue, o3tl::Length::mm100);
+ aFormat.SetFirstLineOffset(nValue);
+ }
+ else if (rProp.Name == UNO_NAME_POSITION_AND_SPACE_MODE)
+ {
+ sal_Int16 nValue = 0;
+ rProp.Value >>= nValue;
+ if ( nValue == 0 )
+ {
+ aFormat.SetPositionAndSpaceMode( SvxNumberFormat::LABEL_WIDTH_AND_POSITION );
+ }
+ else if ( nValue == 1 )
+ {
+ aFormat.SetPositionAndSpaceMode( SvxNumberFormat::LABEL_ALIGNMENT );
+ }
+ else
+ {
+ bWrongArg = true;
+ }
+ }
+ else if (rProp.Name == UNO_NAME_LABEL_FOLLOWED_BY)
+ {
+ sal_Int16 nValue = 0;
+ rProp.Value >>= nValue;
+ if ( nValue == LabelFollow::LISTTAB )
+ {
+ aFormat.SetLabelFollowedBy( SvxNumberFormat::LISTTAB );
+ }
+ else if ( nValue == LabelFollow::SPACE )
+ {
+ aFormat.SetLabelFollowedBy( SvxNumberFormat::SPACE );
+ }
+ else if ( nValue == LabelFollow::NOTHING )
+ {
+ aFormat.SetLabelFollowedBy( SvxNumberFormat::NOTHING );
+ }
+ else if ( nValue == LabelFollow::NEWLINE )
+ {
+ aFormat.SetLabelFollowedBy( SvxNumberFormat::NEWLINE );
+ }
+ else
+ {
+ bWrongArg = true;
+ }
+ }
+ else if (rProp.Name == UNO_NAME_LISTTAB_STOP_POSITION)
+ {
+ sal_Int32 nValue = 0;
+ rProp.Value >>= nValue;
+ nValue = o3tl::toTwips(nValue, o3tl::Length::mm100);
+ if ( nValue >= 0 )
+ {
+ aFormat.SetListtabPos( nValue );
+ }
+ else
+ {
+ bWrongArg = true;
+ }
+ }
+ else if (rProp.Name == UNO_NAME_FIRST_LINE_INDENT)
+ {
+ sal_Int32 nValue = 0;
+ rProp.Value >>= nValue;
+ nValue = o3tl::toTwips(nValue, o3tl::Length::mm100);
+ aFormat.SetFirstLineIndent( nValue );
+ }
+ else if (rProp.Name == UNO_NAME_INDENT_AT)
+ {
+ sal_Int32 nValue = 0;
+ rProp.Value >>= nValue;
+ nValue = o3tl::toTwips(nValue, o3tl::Length::mm100);
+ aFormat.SetIndentAt( nValue );
+ }
+ else if (rProp.Name == UNO_NAME_NUMBERING_TYPE)
+ {
+ sal_Int16 nSet = 0;
+ rProp.Value >>= nSet;
+ if(nSet >= 0)
+ aFormat.SetNumberingType(static_cast<SvxNumType>(nSet));
+ else
+ bWrongArg = true;
+ }
+ else if (rProp.Name == UNO_NAME_PARAGRAPH_STYLE_NAME)
+ {
+ if (pParagraphStyleName)
+ {
+ OUString uTmp;
+ rProp.Value >>= uTmp;
+ OUString sStyleName;
+ SwStyleNameMapper::FillUIName(uTmp, sStyleName, SwGetPoolIdFromName::TxtColl );
+ *pParagraphStyleName = sStyleName;
+ }
+ }
+ else if (rProp.Name == UNO_NAME_BULLET_ID)
+ {
+ sal_Int16 nSet = 0;
+ if( rProp.Value >>= nSet )
+ aFormat.SetBulletChar(nSet);
+ else
+ bWrongArg = true;
+ }
+ else if (rProp.Name == UNO_NAME_BULLET_FONT)
+ {
+ awt::FontDescriptor desc;
+ if (rProp.Value >>= desc)
+ {
+ // #i93725#
+ // do not accept "empty" font
+ if (!desc.Name.isEmpty())
+ {
+ vcl::Font aFont;
+ SvxUnoFontDescriptor::ConvertToFont(desc, aFont);
+ aFormat.SetBulletFont(&aFont);
+ }
+ }
+ else
+ bWrongArg = true;
+ }
+ else if (rProp.Name == UNO_NAME_BULLET_FONT_NAME)
+ {
+ OUString sBulletFontName;
+ rProp.Value >>= sBulletFontName;
+ SwDocShell *const pLclDocShell = pDocShell ? pDocShell : pDoc ? pDoc->GetDocShell() : nullptr;
+ if (!sBulletFontName.isEmpty() && pLclDocShell)
+ {
+ const SvxFontListItem* pFontListItem =
+ static_cast<const SvxFontListItem* >(pLclDocShell
+ ->GetItem( SID_ATTR_CHAR_FONTLIST ));
+ const FontList* pList = pFontListItem->GetFontList();
+ FontMetric aFontMetric = pList->Get(
+ sBulletFontName, WEIGHT_NORMAL, ITALIC_NONE);
+ vcl::Font aFont(aFontMetric);
+ aFormat.SetBulletFont(&aFont);
+ }
+ else if (pBulletFontName)
+ *pBulletFontName = sBulletFontName;
+ }
+ else if (rProp.Name == UNO_NAME_BULLET_CHAR)
+ {
+ OUString aChar;
+ rProp.Value >>= aChar;
+ if (aChar.isEmpty())
+ {
+ // If w:lvlText's value is null - set bullet char to zero
+ aFormat.SetBulletChar(u'\0');
+ }
+ else
+ {
+ sal_Int32 nIndexUtf16 = 0;
+ sal_UCS4 cBullet = aChar.iterateCodePoints(&nIndexUtf16);
+ if (aChar.getLength() == nIndexUtf16)
+ aFormat.SetBulletChar(cBullet);
+ else
+ bWrongArg = true;
+ }
+ }
+ else if (rProp.Name == UNO_NAME_GRAPHIC)
+ {
+ uno::Reference<graphic::XGraphic> xGraphic;
+ if (rProp.Value >>= xGraphic)
+ {
+ if (!pSetBrush)
+ {
+ const SvxBrushItem* pOrigBrush = aFormat.GetBrush();
+ if(pOrigBrush)
+ pSetBrush.reset(new SvxBrushItem(*pOrigBrush));
+ else
+ pSetBrush.reset(new SvxBrushItem(OUString(), OUString(), GPOS_AREA, RES_BACKGROUND));
+ }
+ Graphic aGraphic(xGraphic);
+ pSetBrush->SetGraphic(aGraphic);
+ }
+ else
+ bWrongArg = true;
+ }
+ else if (rProp.Name == UNO_NAME_GRAPHIC_BITMAP)
+ {
+ uno::Reference<awt::XBitmap> xBitmap;
+ if (rProp.Value >>= xBitmap)
+ {
+ if(!pSetBrush)
+ {
+ const SvxBrushItem* pOrigBrush = aFormat.GetBrush();
+ if(pOrigBrush)
+ pSetBrush.reset(new SvxBrushItem(*pOrigBrush));
+ else
+ pSetBrush.reset(new SvxBrushItem(OUString(), OUString(), GPOS_AREA, RES_BACKGROUND));
+ }
+
+ uno::Reference<graphic::XGraphic> xGraphic(xBitmap, uno::UNO_QUERY);
+ Graphic aGraphic(xGraphic);
+ pSetBrush->SetGraphic(aGraphic);
+ }
+ else
+ bWrongArg = true;
+ }
+ else if (rProp.Name == UNO_NAME_GRAPHIC_SIZE)
+ {
+ if(!pSetSize)
+ pSetSize.reset(new Size);
+ awt::Size size;
+ if (rProp.Value >>= size)
+ {
+ pSetSize->setWidth(o3tl::toTwips(size.Width, o3tl::Length::mm100));
+ pSetSize->setHeight(o3tl::toTwips(size.Height, o3tl::Length::mm100));
+ }
+ else
+ bWrongArg = true;
+ }
+ else if (rProp.Name == UNO_NAME_VERT_ORIENT)
+ {
+ if(!pSetVOrient)
+ {
+ if(aFormat.GetGraphicOrientation())
+ pSetVOrient.reset(aFormat.GetGraphicOrientation()->Clone());
+ else
+ pSetVOrient.reset(new SwFormatVertOrient);
+ }
+ pSetVOrient->PutValue(rProp.Value, MID_VERTORIENT_ORIENT);
+ }
+ else if (rProp.Name == UNO_NAME_HEADING_STYLE_NAME
+ && pDocShell) // only on chapter numbering
+ {
+ if (pHeadingStyleName)
+ {
+ OUString uTmp;
+ rProp.Value >>= uTmp;
+ OUString sStyleName;
+ SwStyleNameMapper::FillUIName(uTmp, sStyleName, SwGetPoolIdFromName::TxtColl );
+ *pHeadingStyleName = sStyleName;
+ }
+ }
+ else if (rProp.Name == UNO_NAME_BULLET_REL_SIZE)
+ {
+ // BulletRelSize - unsupported - only available in Impress
+ }
+ else if (rProp.Name == UNO_NAME_BULLET_COLOR)
+ {
+ // BulletColor - ignored too
+ }
+ else if (rProp.Name == UNO_NAME_GRAPHIC_URL)
+ {
+ OUString aURL;
+ if (rProp.Value >>= aURL)
+ {
+ if(!pSetBrush)
+ {
+ const SvxBrushItem* pOrigBrush = aFormat.GetBrush();
+ if(pOrigBrush)
+ pSetBrush.reset(new SvxBrushItem(*pOrigBrush));
+ else
+ pSetBrush.reset(new SvxBrushItem(OUString(), OUString(), GPOS_AREA, RES_BACKGROUND));
+ }
+
+ Graphic aGraphic = vcl::graphic::loadFromURL(aURL);
+ if (!aGraphic.IsNone())
+ pSetBrush->SetGraphic(aGraphic);
+ }
+ else
+ bWrongArg = true;
+ }
+ else if (rProp.Name == UNO_NAME_LIST_FORMAT)
+ {
+ OUString uTmp;
+ rProp.Value >>= uTmp;
+ aFormat.SetListFormat(uTmp);
+ }
+ else if (rProp.Name == UNO_NAME_LEVEL_IS_LEGAL)
+ {
+ if (bool bVal; rProp.Value >>= bVal)
+ aFormat.SetIsLegal(bVal);
+ }
+ else
+ {
+ // Invalid property name
+ throw beans::UnknownPropertyException("Unknown property " + rProp.Name);
+ }
+ }
+ if(!bWrongArg && (pSetBrush || pSetSize || pSetVOrient))
+ {
+ if(!pSetBrush && aFormat.GetBrush())
+ pSetBrush.reset(new SvxBrushItem(*aFormat.GetBrush()));
+
+ if(pSetBrush)
+ {
+ if(!pSetVOrient && aFormat.GetGraphicOrientation())
+ pSetVOrient.reset( new SwFormatVertOrient(*aFormat.GetGraphicOrientation()) );
+
+ if(!pSetSize)
+ {
+ pSetSize.reset(new Size(aFormat.GetGraphicSize()));
+ if(!pSetSize->Width() || !pSetSize->Height())
+ {
+ const Graphic* pGraphic = pSetBrush->GetGraphic();
+ if(pGraphic)
+ *pSetSize = ::GetGraphicSizeTwip(*pGraphic, nullptr);
+ }
+ }
+ sal_Int16 eOrient = pSetVOrient ?
+ pSetVOrient->GetVertOrient() : text::VertOrientation::NONE;
+ aFormat.SetGraphicBrush( pSetBrush.get(), pSetSize.get(), text::VertOrientation::NONE == eOrient ? nullptr : &eOrient );
+ }
+ }
+ if ((!bCharStyleNameSet || rCharStyleName.isEmpty())
+ && aFormat.GetNumberingType() == NumberingType::BITMAP
+ && !aFormat.GetCharFormat()
+ && !SwXNumberingRules::isInvalidStyle(rCharStyleName))
+ {
+ OUString tmp;
+ SwStyleNameMapper::FillProgName(RES_POOLCHR_BULLET_LEVEL, tmp);
+ rCharStyleName = tmp;
+ }
+
+ if(bWrongArg)
+ throw lang::IllegalArgumentException();
+}
+
+uno::Reference< XPropertySetInfo > SwXNumberingRules::getPropertySetInfo()
+{
+ static uno::Reference< beans::XPropertySetInfo > aRef = m_pPropertySet->getPropertySetInfo();
+ return aRef;
+}
+
+void SwXNumberingRules::setPropertyValue( const OUString& rPropertyName, const Any& rValue )
+{
+ SolarMutexGuard aGuard;
+ std::unique_ptr<SwNumRule> pDocRule;
+ SwNumRule* pCreatedRule = nullptr;
+ if(!m_pNumRule)
+ {
+ if(m_pDocShell)
+ {
+ pDocRule.reset(new SwNumRule(*m_pDocShell->GetDoc()->GetOutlineNumRule()));
+ }
+ else if(m_pDoc && !m_sCreatedNumRuleName.isEmpty())
+ {
+ pCreatedRule = m_pDoc->FindNumRulePtr(m_sCreatedNumRuleName);
+ }
+
+ }
+ if(!m_pNumRule && !pDocRule && !pCreatedRule)
+ throw RuntimeException();
+
+ if(rPropertyName == UNO_NAME_IS_AUTOMATIC)
+ {
+ bool bVal = *o3tl::doAccess<bool>(rValue);
+ if(!pCreatedRule)
+ pDocRule ? pDocRule->SetAutoRule(bVal) : m_pNumRule->SetAutoRule(bVal);
+ }
+ else if(rPropertyName == UNO_NAME_IS_CONTINUOUS_NUMBERING)
+ {
+ bool bVal = *o3tl::doAccess<bool>(rValue);
+ pDocRule ? pDocRule->SetContinusNum(bVal) :
+ pCreatedRule ? pCreatedRule->SetContinusNum(bVal) : m_pNumRule->SetContinusNum(bVal);
+ }
+ else if(rPropertyName == UNO_NAME_NAME)
+ {
+ throw IllegalArgumentException();
+ }
+ else if(rPropertyName == UNO_NAME_IS_ABSOLUTE_MARGINS)
+ {
+ bool bVal = *o3tl::doAccess<bool>(rValue);
+ pDocRule ? pDocRule->SetAbsSpaces(bVal) :
+ pCreatedRule ? pCreatedRule->SetAbsSpaces(bVal) : m_pNumRule->SetAbsSpaces(bVal);
+ }
+ else if(rPropertyName == UNO_NAME_NUMBERING_IS_OUTLINE)
+ {
+ bool bVal = *o3tl::doAccess<bool>(rValue);
+ SwNumRuleType eNumRuleType = bVal ? OUTLINE_RULE : NUM_RULE;
+ pDocRule ? pDocRule->SetRuleType(eNumRuleType) :
+ pCreatedRule ? pCreatedRule->SetRuleType(eNumRuleType) : m_pNumRule->SetRuleType(eNumRuleType);
+ }
+ else if(rPropertyName == UNO_NAME_DEFAULT_LIST_ID)
+ {
+ throw IllegalArgumentException();
+ }
+ else
+ throw UnknownPropertyException(rPropertyName);
+
+ if(pDocRule)
+ {
+ assert(m_pDocShell);
+ m_pDocShell->GetDoc()->SetOutlineNumRule(*pDocRule);
+ pDocRule.reset();
+ }
+ else if(pCreatedRule)
+ {
+ pCreatedRule->Validate(*m_pDoc);
+ }
+}
+
+Any SwXNumberingRules::getPropertyValue( const OUString& rPropertyName )
+{
+ Any aRet;
+ const SwNumRule* pRule = m_pNumRule;
+ if(!pRule && m_pDocShell)
+ pRule = m_pDocShell->GetDoc()->GetOutlineNumRule();
+ else if(m_pDoc && !m_sCreatedNumRuleName.isEmpty())
+ pRule = m_pDoc->FindNumRulePtr( m_sCreatedNumRuleName );
+ if(!pRule)
+ throw RuntimeException();
+
+ if(rPropertyName == UNO_NAME_IS_AUTOMATIC)
+ {
+ aRet <<= pRule->IsAutoRule();
+ }
+ else if(rPropertyName == UNO_NAME_IS_CONTINUOUS_NUMBERING)
+ {
+ aRet <<= pRule->IsContinusNum();
+ }
+ else if(rPropertyName == UNO_NAME_NAME)
+ aRet <<= pRule->GetName();
+ else if(rPropertyName == UNO_NAME_IS_ABSOLUTE_MARGINS)
+ {
+ aRet <<= pRule->IsAbsSpaces();
+ }
+ else if(rPropertyName == UNO_NAME_NUMBERING_IS_OUTLINE)
+ {
+ aRet <<= pRule->IsOutlineRule();
+ }
+ else if(rPropertyName == UNO_NAME_DEFAULT_LIST_ID)
+ {
+ OSL_ENSURE( !pRule->GetDefaultListId().isEmpty(),
+ "<SwXNumberingRules::getPropertyValue(..)> - no default list id found. Serious defect." );
+ aRet <<= pRule->GetDefaultListId();
+ }
+ else
+ throw UnknownPropertyException(rPropertyName);
+ return aRet;
+}
+
+void SwXNumberingRules::addPropertyChangeListener(
+ const OUString& /*rPropertyName*/, const uno::Reference< XPropertyChangeListener >& /*xListener*/ )
+{
+}
+
+void SwXNumberingRules::removePropertyChangeListener(
+ const OUString& /*rPropertyName*/, const uno::Reference< XPropertyChangeListener >& /*xListener*/ )
+{
+}
+
+void SwXNumberingRules::addVetoableChangeListener(
+ const OUString& /*rPropertyName*/, const uno::Reference< XVetoableChangeListener >& /*xListener*/ )
+{
+}
+
+void SwXNumberingRules::removeVetoableChangeListener(
+ const OUString& /*rPropertyName*/, const uno::Reference< XVetoableChangeListener >& /*xListener*/ )
+{
+}
+
+OUString SwXNumberingRules::getName()
+{
+ if(m_pNumRule)
+ {
+ OUString aString;
+ SwStyleNameMapper::FillProgName(m_pNumRule->GetName(), aString, SwGetPoolIdFromName::NumRule );
+ return aString;
+ }
+ // consider chapter numbering <SwXNumberingRules>
+ if ( m_pDocShell )
+ {
+ OUString aString;
+ SwStyleNameMapper::FillProgName( m_pDocShell->GetDoc()->GetOutlineNumRule()->GetName(),
+ aString, SwGetPoolIdFromName::NumRule );
+ return aString;
+ }
+ return m_sCreatedNumRuleName;
+}
+
+void SwXNumberingRules::setName(const OUString& /*rName*/)
+{
+ throw RuntimeException("readonly");
+}
+
+void SwXNumberingRules::Impl::Notify(const SfxHint& rHint)
+{
+ if(rHint.GetId() == SfxHintId::Dying)
+ {
+ if(m_rParent.m_bOwnNumRuleCreated)
+ delete m_rParent.m_pNumRule;
+ m_rParent.m_pNumRule = nullptr;
+ m_rParent.m_pDoc = nullptr;
+ }
+}
+
+OUString SwXChapterNumbering::getImplementationName()
+{
+ return "SwXChapterNumbering";
+}
+
+sal_Bool SwXChapterNumbering::supportsService(const OUString& rServiceName)
+{
+ return cppu::supportsService(this, rServiceName);
+}
+
+Sequence< OUString > SwXChapterNumbering::getSupportedServiceNames()
+{
+ return { "com.sun.star.text.ChapterNumbering", "com.sun.star.text.NumberingRules" };
+}
+
+SwXChapterNumbering::SwXChapterNumbering(SwDocShell& rDocSh) :
+ SwXNumberingRules(rDocSh)
+{
+}
+
+SwXChapterNumbering::~SwXChapterNumbering()
+{
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/core/unocore/unosrch.cxx b/sw/source/core/unocore/unosrch.cxx
new file mode 100644
index 0000000000..d41dccb0d0
--- /dev/null
+++ b/sw/source/core/unocore/unosrch.cxx
@@ -0,0 +1,603 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <hintids.hxx>
+#include <unosrch.hxx>
+#include <unomap.hxx>
+#include <swtypes.hxx>
+
+#include <osl/diagnose.h>
+#include <i18nlangtag/languagetag.hxx>
+#include <i18nutil/searchopt.hxx>
+#include <o3tl/any.hxx>
+#include <vcl/svapp.hxx>
+#include <com/sun/star/util/SearchAlgorithms2.hpp>
+#include <com/sun/star/util/SearchFlags.hpp>
+#include <com/sun/star/beans/PropertyAttribute.hpp>
+#include <comphelper/servicehelper.hxx>
+#include <cppuhelper/supportsservice.hxx>
+#include <svl/itemprop.hxx>
+#include <svl/itempool.hxx>
+#include <memory>
+#include <unordered_map>
+
+using namespace ::com::sun::star;
+
+class SwSearchProperties_Impl
+{
+ std::unordered_map<OUString, beans::PropertyValue> maValues;
+ SfxItemPropertyMap mrMap;
+
+ SwSearchProperties_Impl(const SwSearchProperties_Impl&) = delete;
+ SwSearchProperties_Impl& operator=(const SwSearchProperties_Impl&) = delete;
+
+public:
+ SwSearchProperties_Impl();
+
+ /// @throws beans::UnknownPropertyException
+ /// @throws lang::IllegalArgumentException
+ /// @throws uno::RuntimeException
+ void SetProperties(const uno::Sequence< beans::PropertyValue >& aSearchAttribs);
+ uno::Sequence< beans::PropertyValue > GetProperties() const;
+
+ void FillItemSet(SfxItemSet& rSet, bool bIsValueSearch) const;
+ bool HasAttributes() const;
+};
+
+SwSearchProperties_Impl::SwSearchProperties_Impl() :
+ mrMap( aSwMapProvider.GetPropertySet(PROPERTY_MAP_TEXT_CURSOR)->getPropertyMap() )
+{
+}
+
+void SwSearchProperties_Impl::SetProperties(const uno::Sequence< beans::PropertyValue >& aSearchAttribs)
+{
+ //delete all existing values
+ maValues.clear();
+
+ for(const beans::PropertyValue& rSearchAttrib : aSearchAttribs)
+ {
+ const OUString& sName = rSearchAttrib.Name;
+ if( !mrMap.hasPropertyByName(sName) )
+ throw beans::UnknownPropertyException(sName);
+ maValues[sName] = rSearchAttrib;
+ }
+}
+
+uno::Sequence< beans::PropertyValue > SwSearchProperties_Impl::GetProperties() const
+{
+ uno::Sequence< beans::PropertyValue > aRet(maValues.size());
+ beans::PropertyValue* pProps = aRet.getArray();
+ sal_Int32 nPropCount = 0;
+ for(auto const & rPair : maValues)
+ {
+ pProps[nPropCount++] = rPair.second;
+ }
+ return aRet;
+}
+
+void SwSearchProperties_Impl::FillItemSet(SfxItemSet& rSet, bool bIsValueSearch) const
+{
+
+ std::unique_ptr<SfxPoolItem> pBoxItem,
+ pCharBoxItem,
+ pBreakItem,
+ pAutoKernItem ,
+ pWLineItem ,
+ pTabItem ,
+ pSplitItem ,
+ pRegItem ,
+ pLineSpaceItem ,
+ pLineNumItem ,
+ pKeepItem ,
+ pFirstLineIndent,
+ pTextLeftMargin,
+ pRightMargin,
+ pLRItem ,
+ pULItem ,
+ pBackItem ,
+ pAdjItem ,
+ pDescItem ,
+ pInetItem ,
+ pDropItem ,
+ pWeightItem ,
+ pULineItem ,
+ pOLineItem ,
+ pCharFormatItem ,
+ pShadItem ,
+ pPostItem ,
+ pNHyphItem ,
+ pLangItem ,
+ pKernItem ,
+ pFontSizeItem ,
+ pFontItem ,
+ pBlinkItem ,
+ pEscItem ,
+ pCrossedOutItem ,
+ pContourItem ,
+ pCharColorItem ,
+ pCasemapItem ,
+ pBrushItem ,
+ pFontCJKItem,
+ pFontSizeCJKItem,
+ pCJKLangItem,
+ pCJKPostureItem,
+ pCJKWeightItem,
+ pFontCTLItem,
+ pFontSizeCTLItem,
+ pCTLLangItem,
+ pCTLPostureItem,
+ pCTLWeightItem,
+ pShadowItem,
+ pCharReliefItem,
+ pCharRotate,
+ pCharScaleWidth,
+ pParaVertAlign,
+ pParaOrphans,
+ pParaWidows;
+
+ auto funcClone = [&rSet](sal_uInt16 nWID, std::unique_ptr<SfxPoolItem> & rpPoolItem)
+ {
+ if(!rpPoolItem)
+ rpPoolItem.reset(rSet.GetPool()->GetDefaultItem(nWID).Clone());
+ return rpPoolItem.get();
+ };
+ for(auto const & rPair : maValues)
+ {
+ SfxPoolItem* pTempItem = nullptr;
+ const SfxItemPropertyMapEntry* pPropEntry = mrMap.getByName(rPair.first);
+ assert(pPropEntry && "SetProperties only enters values into maValues if mrMap.hasPropertyByName() was true");
+ const SfxItemPropertyMapEntry & rPropEntry = *pPropEntry;
+ sal_uInt16 nWID = rPropEntry.nWID;
+ switch(nWID)
+ {
+ case RES_BOX:
+ pTempItem = funcClone(nWID, pBoxItem);
+ break;
+ case RES_CHRATR_BOX:
+ pTempItem = funcClone(nWID, pCharBoxItem);
+ break;
+ case RES_BREAK:
+ pTempItem = funcClone(nWID, pBreakItem);
+ break;
+ case RES_CHRATR_AUTOKERN:
+ pTempItem = funcClone(nWID, pAutoKernItem);
+ break;
+ case RES_CHRATR_BACKGROUND:
+ pTempItem = funcClone(nWID, pBrushItem);
+ break;
+ case RES_CHRATR_CASEMAP:
+ pTempItem = funcClone(nWID, pCasemapItem);
+ break;
+ case RES_CHRATR_COLOR:
+ pTempItem = funcClone(nWID, pCharColorItem);
+ break;
+ case RES_CHRATR_CONTOUR:
+ pTempItem = funcClone(nWID, pContourItem);
+ break;
+ case RES_CHRATR_CROSSEDOUT:
+ pTempItem = funcClone(nWID, pCrossedOutItem);
+ break;
+ case RES_CHRATR_ESCAPEMENT:
+ pTempItem = funcClone(nWID, pEscItem);
+ break;
+ case RES_CHRATR_BLINK:
+ pTempItem = funcClone(nWID, pBlinkItem);
+ break;
+ case RES_CHRATR_FONT:
+ pTempItem = funcClone(nWID, pFontItem);
+ break;
+ case RES_CHRATR_FONTSIZE:
+ pTempItem = funcClone(nWID, pFontSizeItem);
+ break;
+ case RES_CHRATR_KERNING:
+ pTempItem = funcClone(nWID, pKernItem);
+ break;
+ case RES_CHRATR_LANGUAGE:
+ pTempItem = funcClone(nWID, pLangItem);
+ break;
+ case RES_CHRATR_NOHYPHEN:
+ pTempItem = funcClone(nWID, pNHyphItem);
+ break;
+ case RES_CHRATR_POSTURE:
+ pTempItem = funcClone(nWID, pPostItem);
+ break;
+ case RES_CHRATR_SHADOWED:
+ pTempItem = funcClone(nWID, pShadItem);
+ break;
+ case RES_TXTATR_CHARFMT:
+ pTempItem = funcClone(nWID, pCharFormatItem);
+ break;
+ case RES_CHRATR_UNDERLINE:
+ pTempItem = funcClone(nWID, pULineItem);
+ break;
+ case RES_CHRATR_OVERLINE:
+ pTempItem = funcClone(nWID, pOLineItem);
+ break;
+ case RES_CHRATR_WEIGHT:
+ pTempItem = funcClone(nWID, pWeightItem);
+ break;
+ case RES_PARATR_DROP:
+ pTempItem = funcClone(nWID, pDropItem);
+ break;
+ case RES_TXTATR_INETFMT:
+ pTempItem = funcClone(nWID, pInetItem);
+ break;
+ case RES_PAGEDESC:
+ pTempItem = funcClone(nWID, pDescItem);
+ break;
+ case RES_PARATR_ADJUST:
+ pTempItem = funcClone(nWID, pAdjItem);
+ break;
+ case RES_BACKGROUND:
+ pTempItem = funcClone(nWID, pBackItem);
+ break;
+ case RES_UL_SPACE:
+ pTempItem = funcClone(nWID, pULItem);
+ break;
+ case RES_MARGIN_FIRSTLINE:
+ pTempItem = funcClone(nWID, pFirstLineIndent);
+ break;
+ case RES_MARGIN_TEXTLEFT:
+ pTempItem = funcClone(nWID, pTextLeftMargin);
+ break;
+ case RES_MARGIN_RIGHT:
+ pTempItem = funcClone(nWID, pRightMargin);
+ break;
+ case RES_LR_SPACE:
+ pTempItem = funcClone(nWID, pLRItem);
+ break;
+ case RES_KEEP:
+ pTempItem = funcClone(nWID, pKeepItem);
+ break;
+ case RES_LINENUMBER:
+ pTempItem = funcClone(nWID, pLineNumItem);
+ break;
+ case RES_PARATR_LINESPACING:
+ pTempItem = funcClone(nWID, pLineSpaceItem);
+ break;
+ case RES_PARATR_REGISTER:
+ pTempItem = funcClone(nWID, pRegItem);
+ break;
+ case RES_PARATR_SPLIT:
+ pTempItem = funcClone(nWID, pSplitItem);
+ break;
+ case RES_PARATR_TABSTOP:
+ pTempItem = funcClone(nWID, pTabItem);
+ break;
+ case RES_CHRATR_WORDLINEMODE:
+ pTempItem = funcClone(nWID, pWLineItem);
+ break;
+ case RES_CHRATR_CJK_FONT:
+ pTempItem = funcClone(nWID, pFontCJKItem);
+ break;
+ case RES_CHRATR_CJK_FONTSIZE:
+ pTempItem = funcClone(nWID, pFontSizeCJKItem);
+ break;
+ case RES_CHRATR_CJK_LANGUAGE:
+ pTempItem = funcClone(nWID, pCJKLangItem);
+ break;
+ case RES_CHRATR_CJK_POSTURE:
+ pTempItem = funcClone(nWID, pCJKPostureItem);
+ break;
+ case RES_CHRATR_CJK_WEIGHT:
+ pTempItem = funcClone(nWID, pCJKWeightItem);
+ break;
+ case RES_CHRATR_CTL_FONT:
+ pTempItem = funcClone(nWID, pFontCTLItem);
+ break;
+ case RES_CHRATR_CTL_FONTSIZE:
+ pTempItem = funcClone(nWID, pFontSizeCTLItem);
+ break;
+ case RES_CHRATR_CTL_LANGUAGE:
+ pTempItem = funcClone(nWID, pCTLLangItem);
+ break;
+ case RES_CHRATR_CTL_POSTURE:
+ pTempItem = funcClone(nWID, pCTLPostureItem);
+ break;
+ case RES_CHRATR_CTL_WEIGHT:
+ pTempItem = funcClone(nWID, pCTLWeightItem);
+ break;
+ case RES_CHRATR_SHADOW:
+ pTempItem = funcClone(nWID, pShadowItem);
+ break;
+ case RES_CHRATR_RELIEF:
+ pTempItem = funcClone(nWID, pCharReliefItem);
+ break;
+ case RES_CHRATR_ROTATE:
+ pTempItem = funcClone(nWID, pCharRotate);
+ break;
+ case RES_CHRATR_SCALEW:
+ pTempItem = funcClone(nWID, pCharScaleWidth);
+ break;
+ case RES_PARATR_VERTALIGN:
+ pTempItem = funcClone(nWID, pParaVertAlign);
+ break;
+ case RES_PARATR_ORPHANS:
+ pTempItem = funcClone(nWID, pParaOrphans);
+ break;
+ case RES_PARATR_WIDOWS:
+ pTempItem = funcClone(nWID, pParaWidows);
+ break;
+ }
+ if(pTempItem)
+ {
+ if(bIsValueSearch)
+ {
+ pTempItem->PutValue(rPair.second.Value, rPropEntry.nMemberId);
+ rSet.Put(*pTempItem);
+ }
+ else
+ rSet.InvalidateItem( pTempItem->Which() );
+ }
+ }
+}
+
+bool SwSearchProperties_Impl::HasAttributes() const
+{
+ return !maValues.empty();
+}
+
+SwXTextSearch::SwXTextSearch() :
+ m_pSearchProperties( new SwSearchProperties_Impl),
+ m_pReplaceProperties( new SwSearchProperties_Impl),
+ m_pPropSet(aSwMapProvider.GetPropertySet(PROPERTY_MAP_TEXT_SEARCH)),
+ m_bAll(false),
+ m_bWord(false),
+ m_bBack(false),
+ m_bExpr(false),
+ m_bCase(false),
+ m_bStyles(false),
+ m_bSimilarity(false),
+ m_bLevRelax(false),
+ m_nLevExchange(2),
+ m_nLevAdd(2),
+ m_nLevRemove(2),
+ m_bIsValueSearch(true)
+{
+}
+
+SwXTextSearch::~SwXTextSearch()
+{
+ m_pSearchProperties.reset();
+ m_pReplaceProperties.reset();
+}
+
+namespace
+{
+}
+
+OUString SwXTextSearch::getSearchString()
+{
+ SolarMutexGuard aGuard;
+ return m_sSearchText;
+}
+
+void SwXTextSearch::setSearchString(const OUString& rString)
+{
+ SolarMutexGuard aGuard;
+ m_sSearchText = rString;
+}
+
+OUString SwXTextSearch::getReplaceString()
+{
+ SolarMutexGuard aGuard;
+ return m_sReplaceText;
+}
+
+void SwXTextSearch::setReplaceString(const OUString& rReplaceString)
+{
+ SolarMutexGuard aGuard;
+ m_sReplaceText = rReplaceString;
+}
+
+uno::Reference< beans::XPropertySetInfo > SwXTextSearch::getPropertySetInfo()
+{
+ static uno::Reference< beans::XPropertySetInfo > aRef = m_pPropSet->getPropertySetInfo();
+ return aRef;
+}
+
+void SwXTextSearch::setPropertyValue(const OUString& rPropertyName, const uno::Any& aValue)
+{
+ SolarMutexGuard aGuard;
+ const SfxItemPropertyMapEntry* pEntry = m_pPropSet->getPropertyMap().getByName(rPropertyName);
+ if(!pEntry)
+ throw beans::UnknownPropertyException("Unknown property: " + rPropertyName, getXWeak() );
+
+ if ( pEntry->nFlags & beans::PropertyAttribute::READONLY)
+ throw beans::PropertyVetoException ("Property is read-only: " + rPropertyName, getXWeak() );
+ bool bVal = false;
+ if(auto b = o3tl::tryAccess<bool>(aValue))
+ bVal = *b;
+ switch(pEntry->nWID)
+ {
+ case WID_SEARCH_ALL : m_bAll = bVal; break;
+ case WID_WORDS: m_bWord = bVal; break;
+ case WID_BACKWARDS : m_bBack = bVal; break;
+ case WID_REGULAR_EXPRESSION : m_bExpr = bVal; break;
+ case WID_CASE_SENSITIVE : m_bCase = bVal; break;
+ //case WID_IN_SELECTION : bInSel = bVal; break;
+ case WID_STYLES : m_bStyles = bVal; break;
+ case WID_SIMILARITY : m_bSimilarity = bVal; break;
+ case WID_SIMILARITY_RELAX: m_bLevRelax = bVal; break;
+ case WID_SIMILARITY_EXCHANGE: aValue >>= m_nLevExchange; break;
+ case WID_SIMILARITY_ADD: aValue >>= m_nLevAdd; break;
+ case WID_SIMILARITY_REMOVE : aValue >>= m_nLevRemove;break;
+ };
+
+}
+
+uno::Any SwXTextSearch::getPropertyValue(const OUString& rPropertyName)
+{
+ SolarMutexGuard aGuard;
+ uno::Any aRet;
+
+ const SfxItemPropertyMapEntry* pEntry = m_pPropSet->getPropertyMap().getByName(rPropertyName);
+ bool bSet = false;
+ if(!pEntry)
+ throw beans::UnknownPropertyException("Unknown property: " + rPropertyName, getXWeak() );
+
+ sal_Int16 nSet = 0;
+ switch(pEntry->nWID)
+ {
+ case WID_SEARCH_ALL : bSet = m_bAll; goto SET_BOOL;
+ case WID_WORDS: bSet = m_bWord; goto SET_BOOL;
+ case WID_BACKWARDS : bSet = m_bBack; goto SET_BOOL;
+ case WID_REGULAR_EXPRESSION : bSet = m_bExpr; goto SET_BOOL;
+ case WID_CASE_SENSITIVE : bSet = m_bCase; goto SET_BOOL;
+ //case WID_IN_SELECTION : bSet = bInSel; goto SET_BOOL;
+ case WID_STYLES : bSet = m_bStyles; goto SET_BOOL;
+ case WID_SIMILARITY : bSet = m_bSimilarity; goto SET_BOOL;
+ case WID_SIMILARITY_RELAX: bSet = m_bLevRelax;
+SET_BOOL:
+ aRet <<= bSet;
+ break;
+ case WID_SIMILARITY_EXCHANGE: nSet = m_nLevExchange; goto SET_UINT16;
+ case WID_SIMILARITY_ADD: nSet = m_nLevAdd; goto SET_UINT16;
+ case WID_SIMILARITY_REMOVE : nSet = m_nLevRemove;
+SET_UINT16:
+ aRet <<= nSet;
+ break;
+ }
+
+ return aRet;
+}
+
+void SwXTextSearch::addPropertyChangeListener(const OUString& /*rPropertyName*/, const uno::Reference< beans::XPropertyChangeListener > & /*xListener*/)
+{
+ OSL_FAIL("not implemented");
+}
+
+void SwXTextSearch::removePropertyChangeListener(const OUString& /*rPropertyName*/, const uno::Reference< beans::XPropertyChangeListener > & /*xListener*/)
+{
+ OSL_FAIL("not implemented");
+}
+
+void SwXTextSearch::addVetoableChangeListener(const OUString& /*rPropertyName*/, const uno::Reference< beans::XVetoableChangeListener > & /*xListener*/)
+{
+ OSL_FAIL("not implemented");
+}
+
+void SwXTextSearch::removeVetoableChangeListener(const OUString& /*rPropertyName*/, const uno::Reference< beans::XVetoableChangeListener > & /*xListener*/)
+{
+ OSL_FAIL("not implemented");
+}
+
+sal_Bool SwXTextSearch::getValueSearch()
+{
+ SolarMutexGuard aGuard;
+ return m_bIsValueSearch;
+}
+
+void SwXTextSearch::setValueSearch(sal_Bool ValueSearch_)
+{
+ SolarMutexGuard aGuard;
+ m_bIsValueSearch = ValueSearch_;
+}
+
+uno::Sequence< beans::PropertyValue > SwXTextSearch::getSearchAttributes()
+{
+ return m_pSearchProperties->GetProperties();
+}
+
+void SwXTextSearch::setSearchAttributes(const uno::Sequence< beans::PropertyValue >& rSearchAttribs)
+{
+ m_pSearchProperties->SetProperties(rSearchAttribs);
+}
+
+uno::Sequence< beans::PropertyValue > SwXTextSearch::getReplaceAttributes()
+{
+ return m_pReplaceProperties->GetProperties();
+}
+
+void SwXTextSearch::setReplaceAttributes(const uno::Sequence< beans::PropertyValue >& rReplaceAttribs)
+{
+ m_pReplaceProperties->SetProperties(rReplaceAttribs);
+}
+
+void SwXTextSearch::FillSearchItemSet(SfxItemSet& rSet) const
+{
+ m_pSearchProperties->FillItemSet(rSet, m_bIsValueSearch);
+}
+
+void SwXTextSearch::FillReplaceItemSet(SfxItemSet& rSet) const
+{
+ m_pReplaceProperties->FillItemSet(rSet, m_bIsValueSearch);
+}
+
+bool SwXTextSearch::HasSearchAttributes() const
+{
+ return m_pSearchProperties->HasAttributes();
+}
+
+bool SwXTextSearch::HasReplaceAttributes() const
+{
+ return m_pReplaceProperties->HasAttributes();
+}
+
+OUString SwXTextSearch::getImplementationName()
+{
+ return "SwXTextSearch";
+}
+
+sal_Bool SwXTextSearch::supportsService(const OUString& rServiceName)
+{
+ return cppu::supportsService(this, rServiceName);
+}
+
+uno::Sequence< OUString > SwXTextSearch::getSupportedServiceNames()
+{
+ return { "com.sun.star.util.SearchDescriptor", "com.sun.star.util.ReplaceDescriptor" };
+}
+
+void SwXTextSearch::FillSearchOptions( i18nutil::SearchOptions2& rSearchOpt ) const
+{
+ if( m_bSimilarity )
+ {
+ rSearchOpt.AlgorithmType2 = util::SearchAlgorithms2::APPROXIMATE;
+ rSearchOpt.changedChars = m_nLevExchange;
+ rSearchOpt.deletedChars = m_nLevRemove;
+ rSearchOpt.insertedChars = m_nLevAdd;
+ if( m_bLevRelax )
+ rSearchOpt.searchFlag |= util::SearchFlags::LEV_RELAXED;
+ }
+ else if( m_bExpr )
+ {
+ rSearchOpt.AlgorithmType2 = util::SearchAlgorithms2::REGEXP;
+ }
+ else
+ {
+ rSearchOpt.AlgorithmType2 = util::SearchAlgorithms2::ABSOLUTE;
+ }
+
+ rSearchOpt.Locale = GetAppLanguageTag().getLocale();
+ rSearchOpt.searchString = m_sSearchText;
+ rSearchOpt.replaceString = m_sReplaceText;
+
+ if( !m_bCase )
+ rSearchOpt.transliterateFlags |= TransliterationFlags::IGNORE_CASE;
+ if( m_bWord )
+ rSearchOpt.searchFlag |= util::SearchFlags::NORM_WORD_ONLY;
+
+// bInSel: 1; // How is that possible?
+// TODO: pSearch->bStyles!
+// inSelection??
+// aSrchParam.SetSrchInSelection(TypeConversion::toBOOL(aVal));
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/core/unocore/unostyle.cxx b/sw/source/core/unocore/unostyle.cxx
new file mode 100644
index 0000000000..94219281b5
--- /dev/null
+++ b/sw/source/core/unocore/unostyle.cxx
@@ -0,0 +1,5614 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <sal/config.h>
+
+#include <o3tl/safeint.hxx>
+#include <o3tl/string_view.hxx>
+#include <comphelper/propertysequence.hxx>
+#include <hintids.hxx>
+#include <utility>
+#include <vcl/svapp.hxx>
+#include <svl/hint.hxx>
+#include <svtools/ctrltool.hxx>
+#include <svl/style.hxx>
+#include <svl/itemiter.hxx>
+#include <svl/listener.hxx>
+#include <svl/numformat.hxx>
+#include <svl/zforlist.hxx>
+#include <svl/zformat.hxx>
+#include <svx/pageitem.hxx>
+#include <editeng/colritem.hxx>
+#include <editeng/contouritem.hxx>
+#include <editeng/crossedoutitem.hxx>
+#include <editeng/fontitem.hxx>
+#include <editeng/sizeitem.hxx>
+#include <editeng/udlnitem.hxx>
+#include <editeng/ulspitem.hxx>
+#include <editeng/lrspitem.hxx>
+#include <editeng/boxitem.hxx>
+#include <editeng/postitem.hxx>
+#include <editeng/shdditem.hxx>
+#include <editeng/brushitem.hxx>
+#include <editeng/flstitem.hxx>
+#include <editeng/fhgtitem.hxx>
+#include <editeng/paperinf.hxx>
+#include <editeng/wghtitem.hxx>
+
+#include <autostyle_helper.hxx>
+#include <pagedesc.hxx>
+#include <doc.hxx>
+#include <IDocumentUndoRedo.hxx>
+#include <IDocumentDeviceAccess.hxx>
+#include <IDocumentStylePoolAccess.hxx>
+#include <docary.hxx>
+#include <charfmt.hxx>
+#include <cmdid.h>
+#include <unomid.h>
+#include <unomap.hxx>
+#include <unostyle.hxx>
+#include <unosett.hxx>
+#include <docsh.hxx>
+#include <paratr.hxx>
+#include <unoprnms.hxx>
+#include <shellio.hxx>
+#include <docstyle.hxx>
+#include <unotextbodyhf.hxx>
+#include <fmthdft.hxx>
+#include <fmtpdsc.hxx>
+#include <strings.hrc>
+#include <poolfmt.hxx>
+#include <unoevent.hxx>
+#include <fmtruby.hxx>
+#include <SwStyleNameMapper.hxx>
+#include <sfx2/printer.hxx>
+#include <com/sun/star/frame/XModel.hpp>
+#include <com/sun/star/io/IOException.hpp>
+#include <com/sun/star/style/ParagraphStyleCategory.hpp>
+#include <com/sun/star/style/XStyleFamiliesSupplier.hpp>
+#include <com/sun/star/beans/PropertyAttribute.hpp>
+#include <com/sun/star/beans/NamedValue.hpp>
+#include <com/sun/star/drawing/BitmapMode.hpp>
+#include <com/sun/star/lang/WrappedTargetRuntimeException.hpp>
+#include <com/sun/star/lang/IllegalArgumentException.hpp>
+#include <com/sun/star/lang/IndexOutOfBoundsException.hpp>
+#include <com/sun/star/document/XEventsSupplier.hpp>
+#include <com/sun/star/io/XInputStream.hpp>
+#include <istyleaccess.hxx>
+#include <fmtfsize.hxx>
+#include <numrule.hxx>
+#include <tblafmt.hxx>
+#include <frameformats.hxx>
+
+#include <comphelper/servicehelper.hxx>
+#include <cppuhelper/exc_hlp.hxx>
+#include <cppuhelper/supportsservice.hxx>
+#include <cppuhelper/typeprovider.hxx>
+#include <comphelper/sequence.hxx>
+#include <sal/log.hxx>
+
+#include <svl/stylepool.hxx>
+#include <svx/unobrushitemhelper.hxx>
+#include <editeng/unoipset.hxx>
+#include <editeng/memberids.h>
+#include <svx/unomid.hxx>
+#include <svx/unoshape.hxx>
+#include <svx/xflbstit.hxx>
+#include <svx/xflbmtit.hxx>
+#include <swunohelper.hxx>
+#include <svx/xbtmpit.hxx>
+
+#include <ccoll.hxx>
+#include <hints.hxx>
+#include <uiitems.hxx>
+
+#include <cassert>
+#include <memory>
+#include <set>
+#include <string_view>
+#include <limits>
+
+using namespace css;
+using namespace css::io;
+using namespace css::lang;
+using namespace css::uno;
+
+namespace {
+
+ // these should really be constexprs, but MSVC still is apparently too stupid for them
+ #define nPoolChrNormalRange (RES_POOLCHR_NORMAL_END - RES_POOLCHR_NORMAL_BEGIN)
+ #define nPoolChrHtmlRange (RES_POOLCHR_HTML_END - RES_POOLCHR_HTML_BEGIN)
+ #define nPoolCollTextRange ( RES_POOLCOLL_TEXT_END - RES_POOLCOLL_TEXT_BEGIN)
+ #define nPoolCollListsRange ( RES_POOLCOLL_LISTS_END - RES_POOLCOLL_LISTS_BEGIN)
+ #define nPoolCollExtraRange ( RES_POOLCOLL_EXTRA_END - RES_POOLCOLL_EXTRA_BEGIN)
+ #define nPoolCollRegisterRange ( RES_POOLCOLL_REGISTER_END - RES_POOLCOLL_REGISTER_BEGIN)
+ #define nPoolCollDocRange ( RES_POOLCOLL_DOC_END - RES_POOLCOLL_DOC_BEGIN)
+ #define nPoolCollHtmlRange ( RES_POOLCOLL_HTML_END - RES_POOLCOLL_HTML_BEGIN)
+ #define nPoolFrameRange ( RES_POOLFRM_END - RES_POOLFRM_BEGIN)
+ #define nPoolPageRange ( RES_POOLPAGE_END - RES_POOLPAGE_BEGIN)
+ #define nPoolNumRange ( RES_POOLNUMRULE_END - RES_POOLNUMRULE_BEGIN)
+ #define nPoolCollListsStackedStart ( nPoolCollTextRange)
+ #define nPoolCollExtraStackedStart ( nPoolCollListsStackedStart + nPoolCollListsRange)
+ #define nPoolCollRegisterStackedStart ( nPoolCollExtraStackedStart + nPoolCollExtraRange)
+ #define nPoolCollDocStackedStart ( nPoolCollRegisterStackedStart + nPoolCollRegisterRange)
+ #define nPoolCollHtmlStackedStart ( nPoolCollDocStackedStart + nPoolCollDocRange)
+ using paragraphstyle_t = std::remove_const<decltype(style::ParagraphStyleCategory::TEXT)>::type;
+ using collectionbits_t = sal_uInt16;
+ struct ParagraphStyleCategoryEntry
+ {
+ paragraphstyle_t m_eCategory;
+ SfxStyleSearchBits m_nSwStyleBits;
+ collectionbits_t m_nCollectionBits;
+ constexpr ParagraphStyleCategoryEntry(paragraphstyle_t eCategory, SfxStyleSearchBits nSwStyleBits, collectionbits_t nCollectionBits)
+ : m_eCategory(eCategory)
+ , m_nSwStyleBits(nSwStyleBits)
+ , m_nCollectionBits(nCollectionBits)
+ { }
+ };
+
+constexpr ParagraphStyleCategoryEntry sParagraphStyleCategoryEntries[]
+{
+ { style::ParagraphStyleCategory::TEXT, SfxStyleSearchBits::SwText, COLL_TEXT_BITS },
+ { style::ParagraphStyleCategory::CHAPTER, SfxStyleSearchBits::SwChapter, COLL_DOC_BITS },
+ { style::ParagraphStyleCategory::LIST, SfxStyleSearchBits::SwList, COLL_LISTS_BITS },
+ { style::ParagraphStyleCategory::INDEX, SfxStyleSearchBits::SwIndex, COLL_REGISTER_BITS },
+ { style::ParagraphStyleCategory::EXTRA, SfxStyleSearchBits::SwExtra, COLL_EXTRA_BITS },
+ { style::ParagraphStyleCategory::HTML, SfxStyleSearchBits::SwHtml, COLL_HTML_BITS }
+};
+
+class StyleFamilyEntry
+{
+public:
+ template <SfxStyleFamily f> static StyleFamilyEntry Create(sal_uInt16 nPropMapType, SwGetPoolIdFromName aPoolId, OUString sName, TranslateId pResId)
+ {
+ return StyleFamilyEntry(f, nPropMapType, aPoolId, sName, pResId, GetCountOrName<f>, CreateStyle<f>, TranslateIndex<f>);
+ }
+
+ SfxStyleFamily family() const { return m_eFamily; }
+ sal_uInt16 propMapType() const { return m_nPropMapType; }
+ const uno::Reference<beans::XPropertySetInfo>& xPSInfo() const { return m_xPSInfo; }
+ SwGetPoolIdFromName poolId() const { return m_aPoolId; }
+ const OUString& name() const { return m_sName; }
+ const TranslateId& resId() const { return m_pResId; }
+
+ sal_Int32 getCountOrName(const SwDoc& rDoc, OUString* pString, sal_Int32 nIndex) const { return m_fGetCountOrName(rDoc, pString, nIndex); }
+ css::uno::Reference<css::style::XStyle> createStyle(SfxStyleSheetBasePool* pBasePool, SwDocShell* pDocShell, const OUString& sStyleName) const { return m_fCreateStyle(pBasePool, pDocShell, sStyleName); }
+ sal_uInt16 translateIndex(const sal_uInt16 nIndex) const { return m_fTranslateIndex(nIndex); }
+
+private:
+ using GetCountOrName_t = sal_Int32 (*)(const SwDoc&, OUString*, sal_Int32);
+ using CreateStyle_t = uno::Reference<css::style::XStyle>(*)(SfxStyleSheetBasePool*, SwDocShell*, const OUString&);
+ using TranslateIndex_t = sal_uInt16(*)(const sal_uInt16);
+ SfxStyleFamily m_eFamily;
+ sal_uInt16 m_nPropMapType;
+ uno::Reference<beans::XPropertySetInfo> m_xPSInfo;
+ SwGetPoolIdFromName m_aPoolId;
+ OUString m_sName;
+ TranslateId m_pResId;
+ GetCountOrName_t m_fGetCountOrName;
+ CreateStyle_t m_fCreateStyle;
+ TranslateIndex_t m_fTranslateIndex;
+ StyleFamilyEntry(SfxStyleFamily eFamily, sal_uInt16 nPropMapType, SwGetPoolIdFromName aPoolId, OUString sName, TranslateId pResId, GetCountOrName_t fGetCountOrName, CreateStyle_t fCreateStyle, TranslateIndex_t fTranslateIndex)
+ : m_eFamily(eFamily)
+ , m_nPropMapType(nPropMapType)
+ , m_xPSInfo(aSwMapProvider.GetPropertySet(nPropMapType)->getPropertySetInfo())
+ , m_aPoolId(aPoolId)
+ , m_sName(std::move(sName))
+ , m_pResId(pResId)
+ , m_fGetCountOrName(fGetCountOrName)
+ , m_fCreateStyle(fCreateStyle)
+ , m_fTranslateIndex(fTranslateIndex)
+ { }
+ template<SfxStyleFamily> static inline sal_Int32 GetCountOrName(const SwDoc& rDoc, OUString* pString, sal_Int32 nIndex);
+ template<SfxStyleFamily> static inline css::uno::Reference<css::style::XStyle> CreateStyle(SfxStyleSheetBasePool* pBasePool, SwDocShell* pDocShell, const OUString& sStyleName);
+ template<SfxStyleFamily> static inline sal_uInt16 TranslateIndex(const sal_uInt16 nIndex) { return nIndex; }
+};
+
+template<>
+sal_Int32 StyleFamilyEntry::GetCountOrName<SfxStyleFamily::Char>(const SwDoc& rDoc, OUString* pString, sal_Int32 nIndex)
+{
+ const sal_uInt16 nBaseCount = nPoolChrHtmlRange + nPoolChrNormalRange;
+ nIndex -= nBaseCount;
+ sal_Int32 nCount = 0;
+ for(auto pFormat : *rDoc.GetCharFormats())
+ {
+ if(pFormat->IsDefault() && pFormat != rDoc.GetDfltCharFormat())
+ continue;
+ if(!IsPoolUserFormat(pFormat->GetPoolFormatId()))
+ continue;
+ if(nIndex == nCount)
+ {
+ // the default character format needs to be set to "Default!"
+ if(rDoc.GetDfltCharFormat() == pFormat)
+ *pString = SwResId(STR_POOLCHR_STANDARD);
+ else
+ *pString = pFormat->GetName();
+ break;
+ }
+ ++nCount;
+ }
+ return nCount + nBaseCount;
+}
+
+template<>
+sal_Int32 StyleFamilyEntry::GetCountOrName<SfxStyleFamily::Para>(const SwDoc& rDoc, OUString* pString, sal_Int32 nIndex)
+{
+ const sal_uInt16 nBaseCount = nPoolCollHtmlStackedStart + nPoolCollHtmlRange;
+ nIndex -= nBaseCount;
+ sal_Int32 nCount = 0;
+ for(auto pColl : *rDoc.GetTextFormatColls())
+ {
+ if(pColl->IsDefault())
+ continue;
+ if(!IsPoolUserFormat(pColl->GetPoolFormatId()))
+ continue;
+ if(nIndex == nCount)
+ {
+ *pString = pColl->GetName();
+ break;
+ }
+ ++nCount;
+ }
+ return nCount + nBaseCount;
+}
+
+template<>
+sal_Int32 StyleFamilyEntry::GetCountOrName<SfxStyleFamily::Frame>(const SwDoc& rDoc, OUString* pString, sal_Int32 nIndex)
+{
+ nIndex -= nPoolFrameRange;
+ sal_Int32 nCount = 0;
+ for(const auto pFormat : *rDoc.GetFrameFormats())
+ {
+ if(pFormat->IsDefault() || pFormat->IsAuto())
+ continue;
+ if(!IsPoolUserFormat(pFormat->GetPoolFormatId()))
+ continue;
+ if(nIndex == nCount)
+ {
+ *pString = pFormat->GetName();
+ break;
+ }
+ ++nCount;
+ }
+ return nCount + nPoolFrameRange;
+}
+
+template<>
+sal_Int32 StyleFamilyEntry::GetCountOrName<SfxStyleFamily::Page>(const SwDoc& rDoc, OUString* pString, sal_Int32 nIndex)
+{
+ nIndex -= nPoolPageRange;
+ sal_Int32 nCount = 0;
+ const size_t nArrLen = rDoc.GetPageDescCnt();
+ for(size_t i = 0; i < nArrLen; ++i)
+ {
+ const SwPageDesc& rDesc = rDoc.GetPageDesc(i);
+ if(!IsPoolUserFormat(rDesc.GetPoolFormatId()))
+ continue;
+ if(nIndex == nCount)
+ {
+ *pString = rDesc.GetName();
+ break;
+ }
+ ++nCount;
+ }
+ nCount += nPoolPageRange;
+ return nCount;
+}
+
+template<>
+sal_Int32 StyleFamilyEntry::GetCountOrName<SfxStyleFamily::Pseudo>(const SwDoc& rDoc, OUString* pString, sal_Int32 nIndex)
+{
+ nIndex -= nPoolNumRange;
+ sal_Int32 nCount = 0;
+ for(const auto pRule : rDoc.GetNumRuleTable())
+ {
+ if(pRule->IsAutoRule())
+ continue;
+ if(!IsPoolUserFormat(pRule->GetPoolFormatId()))
+ continue;
+ if(nIndex == nCount)
+ {
+ *pString = pRule->GetName();
+ break;
+ }
+ ++nCount;
+ }
+ return nCount + nPoolNumRange;
+}
+
+template<>
+sal_Int32 StyleFamilyEntry::GetCountOrName<SfxStyleFamily::Table>(const SwDoc& rDoc, OUString* pString, sal_Int32 nIndex)
+{
+ if (!rDoc.HasTableStyles())
+ return 0;
+
+ const auto pAutoFormats = &rDoc.GetTableStyles();
+ const sal_Int32 nCount = pAutoFormats->size();
+ if (0 <= nIndex && nIndex < nCount)
+ *pString = pAutoFormats->operator[](nIndex).GetName();
+
+ return nCount;
+}
+
+template<>
+sal_Int32 StyleFamilyEntry::GetCountOrName<SfxStyleFamily::Cell>(const SwDoc& rDoc, OUString* pString, sal_Int32 nIndex)
+{
+ const auto& rAutoFormats = rDoc.GetTableStyles();
+ const auto& rTableTemplateMap = SwTableAutoFormat::GetTableTemplateMap();
+ const sal_Int32 nUsedCellStylesCount = rAutoFormats.size() * rTableTemplateMap.size();
+ const sal_Int32 nCount = nUsedCellStylesCount + rDoc.GetCellStyles().size();
+ if (0 <= nIndex && nIndex < nCount)
+ {
+ if (nUsedCellStylesCount > nIndex)
+ {
+ const sal_Int32 nAutoFormat = nIndex / rTableTemplateMap.size();
+ const sal_Int32 nBoxFormat = rTableTemplateMap[nIndex % rTableTemplateMap.size()];
+ const SwTableAutoFormat& rTableFormat = rAutoFormats[nAutoFormat];
+ SwStyleNameMapper::FillProgName(rTableFormat.GetName(), *pString, SwGetPoolIdFromName::TabStyle);
+ *pString += rTableFormat.GetTableTemplateCellSubName(rTableFormat.GetBoxFormat(nBoxFormat));
+ }
+ else
+ *pString = rDoc.GetCellStyles()[nIndex-nUsedCellStylesCount].GetName();
+ }
+ return nCount;
+}
+
+template<>
+sal_uInt16 StyleFamilyEntry::TranslateIndex<SfxStyleFamily::Char>(const sal_uInt16 nIndex)
+{
+ static_assert(nPoolChrNormalRange > 0 && nPoolChrHtmlRange > 0, "invalid pool range");
+ if (nIndex < nPoolChrNormalRange)
+ return nIndex + RES_POOLCHR_NORMAL_BEGIN;
+ else if (nIndex < (nPoolChrHtmlRange + nPoolChrNormalRange))
+ return nIndex + RES_POOLCHR_HTML_BEGIN - nPoolChrNormalRange;
+ throw lang::IndexOutOfBoundsException();
+}
+
+template<>
+sal_uInt16 StyleFamilyEntry::TranslateIndex<SfxStyleFamily::Para>(const sal_uInt16 nIndex)
+{
+ static_assert(nPoolCollTextRange > 0 && nPoolCollListsRange > 0 && nPoolCollExtraRange > 0 && nPoolCollRegisterRange > 0 && nPoolCollDocRange > 0 && nPoolCollHtmlRange > 0, "weird pool range");
+ if (nIndex < nPoolCollListsStackedStart)
+ return nIndex + RES_POOLCOLL_TEXT_BEGIN;
+ else if (nIndex < nPoolCollExtraStackedStart)
+ return nIndex + RES_POOLCOLL_LISTS_BEGIN - nPoolCollListsStackedStart;
+ else if (nIndex < nPoolCollRegisterStackedStart)
+ return nIndex + RES_POOLCOLL_EXTRA_BEGIN - nPoolCollExtraStackedStart;
+ else if (nIndex < nPoolCollDocStackedStart)
+ return nIndex + RES_POOLCOLL_REGISTER_BEGIN - nPoolCollRegisterStackedStart;
+ else if (nIndex < nPoolCollHtmlStackedStart)
+ return nIndex + RES_POOLCOLL_DOC_BEGIN - nPoolCollDocStackedStart;
+ else if (nIndex < nPoolCollHtmlStackedStart + nPoolCollTextRange)
+ return nIndex + RES_POOLCOLL_HTML_BEGIN - nPoolCollHtmlStackedStart;
+ throw lang::IndexOutOfBoundsException();
+}
+
+template<>
+sal_uInt16 StyleFamilyEntry::TranslateIndex<SfxStyleFamily::Page>(const sal_uInt16 nIndex)
+{
+ if (nIndex < nPoolPageRange)
+ return nIndex + RES_POOLPAGE_BEGIN;
+ throw lang::IndexOutOfBoundsException();
+}
+
+template<>
+sal_uInt16 StyleFamilyEntry::TranslateIndex<SfxStyleFamily::Frame>(const sal_uInt16 nIndex)
+{
+ if (nIndex < nPoolFrameRange)
+ return nIndex + RES_POOLFRM_BEGIN;
+ throw lang::IndexOutOfBoundsException();
+}
+
+template<>
+sal_uInt16 StyleFamilyEntry::TranslateIndex<SfxStyleFamily::Pseudo>(const sal_uInt16 nIndex)
+{
+ if (nIndex < nPoolNumRange)
+ return nIndex + RES_POOLNUMRULE_BEGIN;
+ throw lang::IndexOutOfBoundsException();
+}
+
+const std::vector<StyleFamilyEntry>& lcl_GetStyleFamilyEntries()
+{
+ static const std::vector<StyleFamilyEntry> our_pStyleFamilyEntries{
+ StyleFamilyEntry::Create<SfxStyleFamily::Char> (PROPERTY_MAP_CHAR_STYLE, SwGetPoolIdFromName::ChrFmt, "CharacterStyles", STR_STYLE_FAMILY_CHARACTER),
+ StyleFamilyEntry::Create<SfxStyleFamily::Para> (PROPERTY_MAP_PARA_STYLE, SwGetPoolIdFromName::TxtColl, "ParagraphStyles", STR_STYLE_FAMILY_PARAGRAPH),
+ StyleFamilyEntry::Create<SfxStyleFamily::Page> (PROPERTY_MAP_PAGE_STYLE, SwGetPoolIdFromName::PageDesc, "PageStyles", STR_STYLE_FAMILY_PAGE),
+ StyleFamilyEntry::Create<SfxStyleFamily::Frame> (PROPERTY_MAP_FRAME_STYLE, SwGetPoolIdFromName::FrmFmt, "FrameStyles", STR_STYLE_FAMILY_FRAME),
+ StyleFamilyEntry::Create<SfxStyleFamily::Pseudo>(PROPERTY_MAP_NUM_STYLE, SwGetPoolIdFromName::NumRule, "NumberingStyles", STR_STYLE_FAMILY_NUMBERING),
+ StyleFamilyEntry::Create<SfxStyleFamily::Table> (PROPERTY_MAP_TABLE_STYLE, SwGetPoolIdFromName::TabStyle, "TableStyles", STR_STYLE_FAMILY_TABLE),
+ StyleFamilyEntry::Create<SfxStyleFamily::Cell> (PROPERTY_MAP_CELL_STYLE, SwGetPoolIdFromName::CellStyle, "CellStyles", STR_STYLE_FAMILY_CELL),
+ };
+ return our_pStyleFamilyEntries;
+}
+
+class SwStyleBase_Impl
+{
+private:
+ SwDoc& m_rDoc;
+ const SwPageDesc* m_pOldPageDesc;
+ rtl::Reference<SwDocStyleSheet> m_xNewBase;
+ SfxItemSet* m_pItemSet;
+ std::unique_ptr<SfxItemSet> m_pMyItemSet;
+ OUString m_rStyleName;
+ const SwAttrSet* m_pParentStyle;
+public:
+ SwStyleBase_Impl(SwDoc& rSwDoc, OUString aName, const SwAttrSet* pParentStyle)
+ : m_rDoc(rSwDoc)
+ , m_pOldPageDesc(nullptr)
+ , m_pItemSet(nullptr)
+ , m_rStyleName(std::move(aName))
+ , m_pParentStyle(pParentStyle)
+ { }
+
+ rtl::Reference<SwDocStyleSheet>& getNewBase()
+ {
+ return m_xNewBase;
+ }
+
+ void setNewBase(SwDocStyleSheet* pNew)
+ {
+ m_xNewBase = pNew;
+ }
+
+ bool HasItemSet() const
+ {
+ return m_xNewBase.is();
+ }
+
+ SfxItemSet& GetItemSet()
+ {
+ assert(m_xNewBase.is());
+ if(!m_pItemSet)
+ {
+ m_pMyItemSet.reset(new SfxItemSet(m_xNewBase->GetItemSet()));
+ m_pItemSet = m_pMyItemSet.get();
+
+ // set parent style to have the correct XFillStyle setting as XFILL_NONE
+ if(!m_pItemSet->GetParent() && m_pParentStyle)
+ m_pItemSet->SetParent(m_pParentStyle);
+ }
+ return *m_pItemSet;
+ }
+
+ const SwPageDesc* GetOldPageDesc();
+
+ // still a hack, but a bit more explicit and with a proper scope
+ struct ItemSetOverrider
+ {
+ SwStyleBase_Impl& m_rStyleBase;
+ SfxItemSet* m_pOldSet;
+ ItemSetOverrider(SwStyleBase_Impl& rStyleBase, SfxItemSet* pTemp)
+ : m_rStyleBase(rStyleBase)
+ , m_pOldSet(m_rStyleBase.m_pItemSet)
+ { m_rStyleBase.m_pItemSet = pTemp; }
+ ~ItemSetOverrider()
+ { m_rStyleBase.m_pItemSet = m_pOldSet; };
+ };
+};
+
+class SwStyleProperties_Impl;
+class SwXStyle : public cppu::WeakImplHelper
+ <
+ css::style::XStyle,
+ css::beans::XPropertySet,
+ css::beans::XMultiPropertySet,
+ css::lang::XServiceInfo,
+ css::lang::XUnoTunnel,
+ css::beans::XPropertyState,
+ css::beans::XMultiPropertyStates
+ >
+ , public SfxListener
+ , public SvtListener
+{
+ SwDoc* m_pDoc;
+ OUString m_sStyleName;
+ const StyleFamilyEntry& m_rEntry;
+ bool m_bIsDescriptor;
+ bool m_bIsConditional;
+ OUString m_sParentStyleName;
+
+protected:
+ SfxStyleSheetBasePool* m_pBasePool;
+ std::unique_ptr<SwStyleProperties_Impl> m_pPropertiesImpl;
+ css::uno::Reference<css::container::XNameAccess> m_xStyleFamily;
+ css::uno::Reference<css::beans::XPropertySet> m_xStyleData;
+
+ template<sal_uInt16>
+ void SetPropertyValue(const SfxItemPropertyMapEntry&, const SfxItemPropertySet&, const uno::Any&, SwStyleBase_Impl&);
+ void SetPropertyValues_Impl( const css::uno::Sequence< OUString >& aPropertyNames, const css::uno::Sequence< css::uno::Any >& aValues );
+ SfxStyleSheetBase* GetStyleSheetBase();
+ void PrepareStyleBase(SwStyleBase_Impl& rBase);
+ template<sal_uInt16>
+ uno::Any GetStyleProperty(const SfxItemPropertyMapEntry& rEntry, const SfxItemPropertySet& rPropSet, SwStyleBase_Impl& rBase);
+ uno::Any GetStyleProperty_Impl(const SfxItemPropertyMapEntry& rEntry, const SfxItemPropertySet& rPropSet, SwStyleBase_Impl& rBase);
+ uno::Any GetPropertyValue_Impl(const SfxItemPropertySet* pPropSet, SwStyleBase_Impl& rBase, const OUString& rPropertyName);
+
+public:
+ SwXStyle(SwDoc* pDoc, SfxStyleFamily eFam, bool bConditional = false);
+ SwXStyle(SfxStyleSheetBasePool* pPool, SfxStyleFamily eFamily, SwDoc* pDoc, const OUString& rStyleName);
+ virtual ~SwXStyle() override;
+
+
+ static const css::uno::Sequence< sal_Int8 > & getUnoTunnelId();
+
+ //XUnoTunnel
+ virtual sal_Int64 SAL_CALL getSomething( const css::uno::Sequence< sal_Int8 >& aIdentifier ) override;
+
+ //XNamed
+ virtual OUString SAL_CALL getName() override;
+ virtual void SAL_CALL setName(const OUString& Name_) override;
+
+ //XStyle
+ virtual sal_Bool SAL_CALL isUserDefined() override;
+ virtual sal_Bool SAL_CALL isInUse() override;
+ virtual OUString SAL_CALL getParentStyle() override;
+ virtual void SAL_CALL setParentStyle(const OUString& aParentStyle) override;
+
+ //XPropertySet
+ virtual css::uno::Reference< css::beans::XPropertySetInfo > SAL_CALL getPropertySetInfo( ) override;
+ virtual void SAL_CALL setPropertyValue( const OUString& aPropertyName, const css::uno::Any& aValue ) override;
+ virtual css::uno::Any SAL_CALL getPropertyValue( const OUString& PropertyName ) override;
+ virtual void SAL_CALL addPropertyChangeListener( const OUString&, const css::uno::Reference< css::beans::XPropertyChangeListener >& ) override
+ { OSL_FAIL("not implemented"); };
+ virtual void SAL_CALL removePropertyChangeListener( const OUString&, const css::uno::Reference< css::beans::XPropertyChangeListener >& ) override
+ { OSL_FAIL("not implemented"); };
+ virtual void SAL_CALL addVetoableChangeListener( const OUString&, const css::uno::Reference< css::beans::XVetoableChangeListener >& ) override
+ { OSL_FAIL("not implemented"); };
+ virtual void SAL_CALL removeVetoableChangeListener( const OUString&, const css::uno::Reference< css::beans::XVetoableChangeListener >& ) override
+ { OSL_FAIL("not implemented"); };
+
+ //XMultiPropertySet
+ virtual void SAL_CALL setPropertyValues( const css::uno::Sequence< OUString >& aPropertyNames, const css::uno::Sequence< css::uno::Any >& aValues ) override;
+ virtual css::uno::Sequence< css::uno::Any > SAL_CALL getPropertyValues( const css::uno::Sequence< OUString >& aPropertyNames ) override;
+ virtual void SAL_CALL addPropertiesChangeListener( const css::uno::Sequence< OUString >&, const css::uno::Reference< css::beans::XPropertiesChangeListener >& ) override
+ {};
+ virtual void SAL_CALL removePropertiesChangeListener( const css::uno::Reference< css::beans::XPropertiesChangeListener >& ) override
+ {};
+ virtual void SAL_CALL firePropertiesChangeEvent( const css::uno::Sequence< OUString >&, const css::uno::Reference< css::beans::XPropertiesChangeListener >& ) override
+ {};
+
+ //XPropertyState
+ virtual css::beans::PropertyState SAL_CALL getPropertyState( const OUString& PropertyName ) override;
+ virtual css::uno::Sequence< css::beans::PropertyState > SAL_CALL getPropertyStates( const css::uno::Sequence< OUString >& aPropertyName ) override;
+ virtual void SAL_CALL setPropertyToDefault( const OUString& PropertyName ) override;
+ virtual css::uno::Any SAL_CALL getPropertyDefault( const OUString& aPropertyName ) override;
+
+ //XMultiPropertyStates
+ virtual void SAL_CALL setAllPropertiesToDefault( ) override;
+ virtual void SAL_CALL setPropertiesToDefault( const css::uno::Sequence< OUString >& aPropertyNames ) override;
+ virtual css::uno::Sequence< css::uno::Any > SAL_CALL getPropertyDefaults( const css::uno::Sequence< OUString >& aPropertyNames ) override;
+
+ //XServiceInfo
+ virtual OUString SAL_CALL getImplementationName() override
+ { return {"SwXStyle"}; };
+ virtual sal_Bool SAL_CALL supportsService(const OUString& rServiceName) override
+ { return cppu::supportsService(this, rServiceName); };
+ virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() override;
+
+ //SfxListener
+ virtual void Notify( SfxBroadcaster& rBC, const SfxHint& rHint ) override;
+ //SvtListener
+ virtual void Notify(const SfxHint&) override;
+ const OUString& GetStyleName() const { return m_sStyleName;}
+ SfxStyleFamily GetFamily() const {return m_rEntry.family();}
+
+ bool IsDescriptor() const {return m_bIsDescriptor;}
+ bool IsConditional() const { return m_bIsConditional;}
+ const OUString& GetParentStyleName() const { return m_sParentStyleName;}
+ void SetDoc(SwDoc* pDc, SfxStyleSheetBasePool* pPool)
+ {
+ m_bIsDescriptor = false; m_pDoc = pDc;
+ m_pBasePool = pPool;
+ SfxListener::StartListening(*m_pBasePool);
+ }
+ SwDoc* GetDoc() const { return m_pDoc; }
+ void Invalidate();
+ void ApplyDescriptorProperties();
+ void SetStyleName(const OUString& rSet){ m_sStyleName = rSet;}
+ /// @throws beans::PropertyVetoException
+ /// @throws lang::IllegalArgumentException
+ /// @throws lang::WrappedTargetException
+ /// @throws uno::RuntimeException
+ void SetStyleProperty(const SfxItemPropertyMapEntry& rEntry, const SfxItemPropertySet& rPropSet, const uno::Any& rValue, SwStyleBase_Impl& rBase);
+ void PutItemToSet(const SvxSetItem* pSetItem, const SfxItemPropertySet& rPropSet, const SfxItemPropertyMapEntry& rEntry, const uno::Any& rVal, SwStyleBase_Impl& rBaseImpl);
+};
+
+typedef cppu::ImplInheritanceHelper< SwXStyle, css::document::XEventsSupplier> SwXFrameStyle_Base;
+class SwXFrameStyle
+ : public SwXFrameStyle_Base
+ , public sw::ICoreFrameStyle
+{
+public:
+ SwXFrameStyle(SfxStyleSheetBasePool& rPool,
+ SwDoc* pDoc,
+ const OUString& rStyleName) :
+ SwXFrameStyle_Base(&rPool, SfxStyleFamily::Frame, pDoc, rStyleName){}
+ explicit SwXFrameStyle(SwDoc *pDoc);
+
+ virtual css::uno::Reference< css::container::XNameReplace > SAL_CALL getEvents( ) override;
+
+ //ICoreStyle
+ virtual void SetItem(sal_uInt16 eAtr, const SfxPoolItem& rItem) override;
+ virtual const SfxPoolItem* GetItem(sal_uInt16 eAtr) override;
+ virtual css::document::XEventsSupplier& GetEventsSupplier() override
+ { return *this; };
+};
+
+class SwXPageStyle
+ : public SwXStyle
+{
+protected:
+ void SetPropertyValues_Impl( const css::uno::Sequence< OUString >& aPropertyNames, const css::uno::Sequence< css::uno::Any >& aValues );
+ css::uno::Sequence< css::uno::Any > GetPropertyValues_Impl( const css::uno::Sequence< OUString >& aPropertyNames );
+
+public:
+ SwXPageStyle(SfxStyleSheetBasePool& rPool, SwDocShell* pDocSh, const OUString& rStyleName);
+ explicit SwXPageStyle(SwDocShell* pDocSh);
+
+ virtual void SAL_CALL setPropertyValue( const OUString& aPropertyName, const css::uno::Any& aValue ) override;
+ virtual css::uno::Any SAL_CALL getPropertyValue( const OUString& PropertyName ) override;
+
+ virtual void SAL_CALL setPropertyValues( const css::uno::Sequence< OUString >& aPropertyNames, const css::uno::Sequence< css::uno::Any >& aValues ) override;
+ virtual css::uno::Sequence< css::uno::Any > SAL_CALL getPropertyValues( const css::uno::Sequence< OUString >& aPropertyNames ) override;
+};
+
+class SwStyleProperties_Impl
+{
+ const SfxItemPropertyMap& mrMap;
+ std::map<OUString, uno::Any> m_vPropertyValues;
+public:
+ explicit SwStyleProperties_Impl(const SfxItemPropertyMap& rMap)
+ : mrMap(rMap)
+ { }
+
+ bool AllowsKey(std::u16string_view rName)
+ {
+ return mrMap.hasPropertyByName(rName);
+ }
+ bool SetProperty(const OUString& rName, const uno::Any& rValue)
+ {
+ if(!AllowsKey(rName))
+ return false;
+ m_vPropertyValues[rName] = rValue;
+ return true;
+ }
+ void GetProperty(const OUString& rName, const uno::Any*& pAny)
+ {
+ if(!AllowsKey(rName))
+ {
+ pAny = nullptr;
+ return;
+ }
+ pAny = &m_vPropertyValues[rName];
+ return;
+ }
+ bool ClearProperty( const OUString& rName )
+ {
+ if(!AllowsKey(rName))
+ return false;
+ m_vPropertyValues[rName] = uno::Any();
+ return true;
+ }
+ void ClearAllProperties( )
+ { m_vPropertyValues.clear(); }
+ void Apply(SwXStyle& rStyle)
+ {
+ for(const auto& rPropertyPair : m_vPropertyValues)
+ {
+ if(rPropertyPair.second.hasValue())
+ rStyle.setPropertyValue(rPropertyPair.first, rPropertyPair.second);
+ }
+ }
+};
+
+template<SfxStyleFamily eFamily>
+css::uno::Reference<css::style::XStyle> StyleFamilyEntry::CreateStyle(SfxStyleSheetBasePool* pBasePool, SwDocShell* pDocShell, const OUString& sStyleName)
+{
+ return pBasePool ? new SwXStyle(pBasePool, eFamily, pDocShell->GetDoc(), sStyleName) : new SwXStyle(pDocShell->GetDoc(), eFamily, false);
+}
+
+template<>
+css::uno::Reference<css::style::XStyle> StyleFamilyEntry::CreateStyle<SfxStyleFamily::Frame>(SfxStyleSheetBasePool* pBasePool, SwDocShell* pDocShell, const OUString& sStyleName)
+{
+ return pBasePool ? new SwXFrameStyle(*pBasePool, pDocShell->GetDoc(), sStyleName) : new SwXFrameStyle(pDocShell->GetDoc());
+}
+
+template<>
+css::uno::Reference<css::style::XStyle> StyleFamilyEntry::CreateStyle<SfxStyleFamily::Page>(SfxStyleSheetBasePool* pBasePool, SwDocShell* pDocShell, const OUString& sStyleName)
+{
+ return pBasePool ? new SwXPageStyle(*pBasePool, pDocShell, sStyleName) : new SwXPageStyle(pDocShell);
+}
+
+template<>
+css::uno::Reference<css::style::XStyle> StyleFamilyEntry::CreateStyle<SfxStyleFamily::Table>(SfxStyleSheetBasePool* /*pBasePool*/, SwDocShell* pDocShell, const OUString& sStyleName)
+{
+ return SwXTextTableStyle::CreateXTextTableStyle(pDocShell, sStyleName);
+}
+
+template<>
+css::uno::Reference<css::style::XStyle> StyleFamilyEntry::CreateStyle<SfxStyleFamily::Cell>(SfxStyleSheetBasePool* /*pBasePool*/, SwDocShell* pDocShell, const OUString& sStyleName)
+{
+ return SwXTextCellStyle::CreateXTextCellStyle(pDocShell, sStyleName);
+}
+
+class XStyleFamily : public cppu::WeakImplHelper
+<
+ container::XNameContainer,
+ lang::XServiceInfo,
+ container::XIndexAccess,
+ beans::XPropertySet
+>
+, public SfxListener
+{
+ const StyleFamilyEntry& m_rEntry;
+ SfxStyleSheetBasePool* m_pBasePool;
+ SwDocShell* m_pDocShell;
+
+ SwXStyle* FindStyle(std::u16string_view rStyleName) const;
+ sal_Int32 GetCountOrName(OUString* pString, sal_Int32 nIndex = SAL_MAX_INT32)
+ { return m_rEntry.getCountOrName(*m_pDocShell->GetDoc(), pString, nIndex); };
+ static const StyleFamilyEntry& InitEntry(SfxStyleFamily eFamily)
+ {
+ auto& entries = lcl_GetStyleFamilyEntries();
+ const auto pEntry = std::find_if(entries.begin(), entries.end(),
+ [eFamily] (const StyleFamilyEntry& e) { return e.family() == eFamily; });
+ assert(pEntry != entries.end());
+ return *pEntry;
+ }
+public:
+ XStyleFamily(SwDocShell* pDocShell, const SfxStyleFamily eFamily)
+ : m_rEntry(InitEntry(eFamily))
+ , m_pBasePool(pDocShell->GetStyleSheetPool())
+ , m_pDocShell(pDocShell)
+ {
+ if (m_pBasePool) //tdf#124142 html docs can have no styles
+ StartListening(*m_pBasePool);
+ }
+
+ //XIndexAccess
+ virtual sal_Int32 SAL_CALL getCount() override
+ {
+ SolarMutexGuard aGuard;
+ return GetCountOrName(nullptr);
+ };
+ virtual uno::Any SAL_CALL getByIndex(sal_Int32 nIndex) override;
+
+ //XElementAccess
+ virtual uno::Type SAL_CALL getElementType( ) override
+ { return cppu::UnoType<style::XStyle>::get(); };
+ virtual sal_Bool SAL_CALL hasElements( ) override
+ {
+ if(!m_pBasePool)
+ throw uno::RuntimeException();
+ return true;
+ }
+
+ //XNameAccess
+ virtual uno::Any SAL_CALL getByName(const OUString& Name) override;
+ virtual uno::Sequence< OUString > SAL_CALL getElementNames() override;
+ virtual sal_Bool SAL_CALL hasByName(const OUString& Name) override;
+
+ //XNameContainer
+ virtual void SAL_CALL insertByName(const OUString& Name, const uno::Any& Element) override;
+ virtual void SAL_CALL replaceByName(const OUString& Name, const uno::Any& Element) override;
+ virtual void SAL_CALL removeByName(const OUString& Name) override;
+
+ //XPropertySet
+ virtual uno::Reference< beans::XPropertySetInfo > SAL_CALL getPropertySetInfo( ) override
+ { return {}; };
+ virtual void SAL_CALL setPropertyValue( const OUString&, const uno::Any&) override
+ { SAL_WARN("sw.uno", "###unexpected!"); };
+ virtual uno::Any SAL_CALL getPropertyValue( const OUString& PropertyName ) override;
+ virtual void SAL_CALL addPropertyChangeListener( const OUString&, const uno::Reference<beans::XPropertyChangeListener>&) override
+ { SAL_WARN("sw.uno", "###unexpected!"); };
+ virtual void SAL_CALL removePropertyChangeListener( const OUString&, const uno::Reference<beans::XPropertyChangeListener>&) override
+ { SAL_WARN("sw.uno", "###unexpected!"); };
+ virtual void SAL_CALL addVetoableChangeListener(const OUString&, const uno::Reference<beans::XVetoableChangeListener>&) override
+ { SAL_WARN("sw.uno", "###unexpected!"); };
+ virtual void SAL_CALL removeVetoableChangeListener(const OUString&, const uno::Reference<beans::XVetoableChangeListener>&) override
+ { SAL_WARN("sw.uno", "###unexpected!"); };
+
+ //SfxListener
+ virtual void Notify(SfxBroadcaster& rBC, const SfxHint& rHint) override
+ {
+ if(rHint.GetId() == SfxHintId::Dying)
+ {
+ m_pBasePool = nullptr;
+ m_pDocShell = nullptr;
+ EndListening(rBC);
+ }
+ }
+
+ //XServiceInfo
+ virtual OUString SAL_CALL getImplementationName() override
+ { return {"XStyleFamily"}; };
+ virtual sal_Bool SAL_CALL supportsService(const OUString& rServiceName) override
+ { return cppu::supportsService(this, rServiceName); };
+ virtual uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() override
+ { return { "com.sun.star.style.StyleFamily" }; }
+};
+}
+
+OUString SwXStyleFamilies::getImplementationName()
+ { return {"SwXStyleFamilies"}; }
+
+sal_Bool SwXStyleFamilies::supportsService(const OUString& rServiceName)
+{
+ return cppu::supportsService(this, rServiceName);
+}
+
+uno::Sequence< OUString > SwXStyleFamilies::getSupportedServiceNames()
+ { return { "com.sun.star.style.StyleFamilies" }; }
+
+SwXStyleFamilies::SwXStyleFamilies(SwDocShell& rDocShell) :
+ SwUnoCollection(rDocShell.GetDoc()),
+ m_pDocShell(&rDocShell)
+ { }
+
+SwXStyleFamilies::~SwXStyleFamilies()
+ { }
+
+uno::Any SAL_CALL SwXStyleFamilies::getByName(const OUString& Name)
+{
+ SolarMutexGuard aGuard;
+ if(!IsValid())
+ throw uno::RuntimeException();
+ auto& entries(lcl_GetStyleFamilyEntries());
+ const auto pEntry = std::find_if(entries.begin(), entries.end(),
+ [&Name] (const StyleFamilyEntry& e) { return e.name() == Name; });
+ if(pEntry == entries.end())
+ throw container::NoSuchElementException();
+ return getByIndex(pEntry - entries.begin());
+}
+
+uno::Sequence< OUString > SwXStyleFamilies::getElementNames()
+{
+ auto& entries(lcl_GetStyleFamilyEntries());
+ uno::Sequence<OUString> aNames(entries.size());
+ std::transform(entries.begin(), entries.end(),
+ aNames.getArray(), [] (const StyleFamilyEntry& e) { return e.name(); });
+ return aNames;
+}
+
+sal_Bool SwXStyleFamilies::hasByName(const OUString& Name)
+{
+ auto& entries(lcl_GetStyleFamilyEntries());
+ return std::any_of(entries.begin(), entries.end(),
+ [&Name] (const StyleFamilyEntry& e) { return e.name() == Name; });
+}
+
+sal_Int32 SwXStyleFamilies::getCount()
+{
+ return lcl_GetStyleFamilyEntries().size();
+}
+
+uno::Any SwXStyleFamilies::getByIndex(sal_Int32 nIndex)
+{
+ auto& entries(lcl_GetStyleFamilyEntries());
+ SolarMutexGuard aGuard;
+ if(nIndex < 0 || o3tl::make_unsigned(nIndex) >= entries.size())
+ throw lang::IndexOutOfBoundsException();
+ if(!IsValid())
+ throw uno::RuntimeException();
+ auto eFamily = entries[nIndex].family();
+ assert(eFamily != SfxStyleFamily::All);
+ auto& rxFamily = m_vFamilies[eFamily];
+ if(!rxFamily.is())
+ rxFamily = new XStyleFamily(m_pDocShell, eFamily);
+ return uno::Any(rxFamily);
+}
+
+uno::Type SwXStyleFamilies::getElementType()
+{
+ return cppu::UnoType<container::XNameContainer>::get();
+}
+
+sal_Bool SwXStyleFamilies::hasElements()
+ { return true; }
+
+void SwXStyleFamilies::loadStylesFromURL(const OUString& rURL,
+ const uno::Sequence< beans::PropertyValue >& aOptions)
+{
+ SolarMutexGuard aGuard;
+ if(!IsValid() || rURL.isEmpty())
+ throw uno::RuntimeException();
+ SwgReaderOption aOpt;
+ aOpt.SetFrameFormats(true);
+ aOpt.SetTextFormats(true);
+ aOpt.SetPageDescs(true);
+ aOpt.SetNumRules(true);
+ aOpt.SetMerge(false);
+ for(const auto& rProperty: aOptions)
+ {
+ bool bValue = false;
+ if(rProperty.Value.getValueType() == cppu::UnoType<bool>::get())
+ bValue = rProperty.Value.get<bool>();
+
+ if(rProperty.Name == UNO_NAME_OVERWRITE_STYLES)
+ aOpt.SetMerge(!bValue);
+ else if(rProperty.Name == UNO_NAME_LOAD_NUMBERING_STYLES)
+ aOpt.SetNumRules(bValue);
+ else if(rProperty.Name == UNO_NAME_LOAD_PAGE_STYLES)
+ aOpt.SetPageDescs(bValue);
+ else if(rProperty.Name == UNO_NAME_LOAD_FRAME_STYLES)
+ aOpt.SetFrameFormats(bValue);
+ else if(rProperty.Name == UNO_NAME_LOAD_TEXT_STYLES)
+ aOpt.SetTextFormats(bValue);
+ else if(rProperty.Name == "InputStream")
+ {
+ Reference<XInputStream> xInputStream;
+ if (!(rProperty.Value >>= xInputStream))
+ throw IllegalArgumentException("Parameter 'InputStream' could not be converted to "
+ "type 'com::sun::star::io::XInputStream'",
+ nullptr, 0);
+
+ aOpt.SetInputStream(xInputStream);
+
+ }
+ }
+ const ErrCodeMsg nErr = m_pDocShell->LoadStylesFromFile( rURL, aOpt, true );
+ if(nErr)
+ throw io::IOException();
+}
+
+uno::Sequence< beans::PropertyValue > SwXStyleFamilies::getStyleLoaderOptions()
+{
+ const uno::Any aVal(true);
+ return comphelper::InitPropertySequence({
+ { UNO_NAME_LOAD_TEXT_STYLES, aVal },
+ { UNO_NAME_LOAD_FRAME_STYLES, aVal },
+ { UNO_NAME_LOAD_PAGE_STYLES, aVal },
+ { UNO_NAME_LOAD_NUMBERING_STYLES, aVal },
+ { UNO_NAME_OVERWRITE_STYLES, aVal }
+ });
+}
+
+static bool lcl_GetHeaderFooterItem(
+ SfxItemSet const& rSet, std::u16string_view rPropName, bool const bFooter,
+ SvxSetItem const*& o_rpItem)
+{
+ o_rpItem = rSet.GetItemIfSet(
+ bFooter ? SID_ATTR_PAGE_FOOTERSET : SID_ATTR_PAGE_HEADERSET,
+ false);
+ if (!o_rpItem &&
+ rPropName == UNO_NAME_FIRST_IS_SHARED)
+ { // fdo#79269 header may not exist, check footer then
+ o_rpItem = rSet.GetItemIfSet(
+ (!bFooter) ? SID_ATTR_PAGE_FOOTERSET : SID_ATTR_PAGE_HEADERSET,
+ false);
+ }
+ return o_rpItem;
+}
+
+uno::Reference<css::style::XStyle> SwXStyleFamilies::CreateStyle(SfxStyleFamily eFamily, SwDoc& rDoc)
+{
+ auto& entries(lcl_GetStyleFamilyEntries());
+ const auto pEntry = std::find_if(entries.begin(), entries.end(),
+ [eFamily] (const StyleFamilyEntry& e) { return e.family() == eFamily; });
+ return pEntry == entries.end() ? nullptr : pEntry->createStyle(nullptr, rDoc.GetDocShell(), "");
+}
+
+// FIXME: Ugly special casing that should die.
+uno::Reference<css::style::XStyle> SwXStyleFamilies::CreateStyleCondParagraph(SwDoc& rDoc)
+ { return new SwXStyle(&rDoc, SfxStyleFamily::Para, true); };
+
+uno::Any XStyleFamily::getByIndex(sal_Int32 nIndex)
+{
+ SolarMutexGuard aGuard;
+ if(nIndex < 0)
+ throw lang::IndexOutOfBoundsException();
+ if(!m_pBasePool)
+ throw uno::RuntimeException();
+ OUString sStyleName;
+ try
+ {
+ SwStyleNameMapper::FillUIName(m_rEntry.translateIndex(nIndex), sStyleName);
+ } catch(...) {}
+ if (sStyleName.isEmpty())
+ GetCountOrName(&sStyleName, nIndex);
+ if(sStyleName.isEmpty())
+ throw lang::IndexOutOfBoundsException();
+ return getByName(sStyleName);
+}
+
+uno::Any XStyleFamily::getByName(const OUString& rName)
+{
+ SolarMutexGuard aGuard;
+ OUString sStyleName;
+ SwStyleNameMapper::FillUIName(rName, sStyleName, m_rEntry.poolId());
+ if(!m_pBasePool)
+ throw uno::RuntimeException();
+ SfxStyleSheetBase* pBase = m_pBasePool->Find(sStyleName, m_rEntry.family());
+ if(!pBase)
+ throw container::NoSuchElementException(rName);
+ uno::Reference<style::XStyle> xStyle = FindStyle(sStyleName);
+ if(!xStyle.is())
+ xStyle = m_rEntry.createStyle(m_pBasePool, m_pDocShell, m_rEntry.family() == SfxStyleFamily::Frame ? pBase->GetName() : sStyleName);
+ return uno::Any(xStyle);
+}
+
+uno::Sequence<OUString> XStyleFamily::getElementNames()
+{
+ SolarMutexGuard aGuard;
+ if(!m_pBasePool)
+ throw uno::RuntimeException();
+ std::vector<OUString> vRet;
+ std::unique_ptr<SfxStyleSheetIterator> pIt = m_pBasePool->CreateIterator(m_rEntry.family());
+ for (SfxStyleSheetBase* pStyle = pIt->First(); pStyle; pStyle = pIt->Next())
+ {
+ OUString sName;
+ SwStyleNameMapper::FillProgName(pStyle->GetName(), sName, m_rEntry.poolId());
+ vRet.push_back(sName);
+ }
+ return comphelper::containerToSequence(vRet);
+}
+
+sal_Bool XStyleFamily::hasByName(const OUString& rName)
+{
+ SolarMutexGuard aGuard;
+ if(!m_pBasePool)
+ throw uno::RuntimeException();
+ OUString sStyleName;
+ SwStyleNameMapper::FillUIName(rName, sStyleName, m_rEntry.poolId());
+ SfxStyleSheetBase* pBase = m_pBasePool->Find(sStyleName, m_rEntry.family());
+ return nullptr != pBase;
+}
+
+void XStyleFamily::insertByName(const OUString& rName, const uno::Any& rElement)
+{
+ SolarMutexGuard aGuard;
+ if(!m_pBasePool)
+ throw uno::RuntimeException();
+ OUString sStyleName;
+ SwStyleNameMapper::FillUIName(rName, sStyleName, m_rEntry.poolId());
+ SfxStyleSheetBase* pBase = m_pBasePool->Find(sStyleName, m_rEntry.family());
+ if (pBase)
+ throw container::ElementExistException();
+ if(rElement.getValueType().getTypeClass() != uno::TypeClass_INTERFACE)
+ throw lang::IllegalArgumentException();
+ if (SwGetPoolIdFromName::CellStyle == m_rEntry.poolId())
+ {
+ // handle cell style
+ uno::Reference<style::XStyle> xStyle = rElement.get<uno::Reference<style::XStyle>>();
+ SwXTextCellStyle* pNewStyle = dynamic_cast<SwXTextCellStyle*>(xStyle.get());
+ if (!pNewStyle)
+ throw lang::IllegalArgumentException();
+
+ pNewStyle->setName(sStyleName); // insertByName sets the element name
+ m_pDocShell->GetDoc()->GetCellStyles().AddBoxFormat(*pNewStyle->GetBoxFormat(), sStyleName);
+ pNewStyle->SetPhysical();
+ }
+ else if (SwGetPoolIdFromName::TabStyle == m_rEntry.poolId())
+ {
+ // handle table style
+ uno::Reference<style::XStyle> xStyle = rElement.get<uno::Reference<style::XStyle>>();
+ SwXTextTableStyle* pNewStyle = dynamic_cast<SwXTextTableStyle*>(xStyle.get());
+ if (!pNewStyle)
+ throw lang::IllegalArgumentException();
+
+ pNewStyle->setName(sStyleName); // insertByName sets the element name
+ m_pDocShell->GetDoc()->GetTableStyles().AddAutoFormat(*pNewStyle->GetTableFormat());
+ pNewStyle->SetPhysical();
+ }
+ else
+ {
+ uno::Reference<lang::XUnoTunnel> xStyleTunnel = rElement.get<uno::Reference<lang::XUnoTunnel>>();
+ SwXStyle* pNewStyle = comphelper::getFromUnoTunnel<SwXStyle>(xStyleTunnel);
+ if (!pNewStyle || !pNewStyle->IsDescriptor() || pNewStyle->GetFamily() != m_rEntry.family())
+ throw lang::IllegalArgumentException();
+
+ SfxStyleSearchBits nMask = SfxStyleSearchBits::All;
+ if(m_rEntry.family() == SfxStyleFamily::Para && !pNewStyle->IsConditional())
+ nMask &= ~SfxStyleSearchBits::SwCondColl;
+ auto pStyle = &m_pBasePool->Make(sStyleName, m_rEntry.family(), nMask);
+ pNewStyle->SetDoc(m_pDocShell->GetDoc(), m_pBasePool);
+ pNewStyle->SetStyleName(sStyleName);
+ pStyle->SetParent(pNewStyle->GetParentStyleName());
+ // after all, we still need to apply the properties of the descriptor
+ pNewStyle->ApplyDescriptorProperties();
+ }
+}
+
+void XStyleFamily::replaceByName(const OUString& rName, const uno::Any& rElement)
+{
+ SolarMutexGuard aGuard;
+ if(!m_pBasePool)
+ throw uno::RuntimeException();
+ OUString sStyleName;
+ SwStyleNameMapper::FillUIName(rName, sStyleName, m_rEntry.poolId());
+ SfxStyleSheetBase* pBase = m_pBasePool->Find(sStyleName, m_rEntry.family());
+ // replacements only for userdefined styles
+ if(!pBase)
+ throw container::NoSuchElementException();
+ if (SwGetPoolIdFromName::CellStyle == m_rEntry.poolId())
+ {
+ // handle cell styles, don't call on assigned cell styles (TableStyle child)
+ OUString sParent;
+ SwBoxAutoFormat* pBoxAutoFormat = SwXTextCellStyle::GetBoxAutoFormat(m_pDocShell, sStyleName, &sParent);
+ if (pBoxAutoFormat && sParent.isEmpty())// if parent exists then this style is assigned to a table style. Don't replace.
+ {
+ uno::Reference<style::XStyle> xStyle = rElement.get<uno::Reference<style::XStyle>>();
+ SwXTextCellStyle* pStyleToReplaceWith = dynamic_cast<SwXTextCellStyle*>(xStyle.get());
+ if (!pStyleToReplaceWith)
+ throw lang::IllegalArgumentException();
+
+ pStyleToReplaceWith->setName(sStyleName);
+ *pBoxAutoFormat = *pStyleToReplaceWith->GetBoxFormat();
+ pStyleToReplaceWith->SetPhysical();
+ }
+ }
+ else if (SwGetPoolIdFromName::TabStyle == m_rEntry.poolId())
+ {
+ // handle table styles
+ SwTableAutoFormat* pTableAutoFormat = SwXTextTableStyle::GetTableAutoFormat(m_pDocShell, sStyleName);
+ if (pTableAutoFormat)
+ {
+ uno::Reference<style::XStyle> xStyle = rElement.get<uno::Reference<style::XStyle>>();
+ SwXTextTableStyle* pStyleToReplaceWith = dynamic_cast<SwXTextTableStyle*>(xStyle.get());
+ if (!pStyleToReplaceWith)
+ throw lang::IllegalArgumentException();
+
+ pStyleToReplaceWith->setName(sStyleName);
+ *pTableAutoFormat = *pStyleToReplaceWith->GetTableFormat();
+ pStyleToReplaceWith->SetPhysical();
+ }
+ }
+ else
+ {
+ if(!pBase->IsUserDefined())
+ throw lang::IllegalArgumentException();
+ //if there's an object available to this style then it must be invalidated
+ uno::Reference<style::XStyle> xStyle = FindStyle(pBase->GetName());
+ if(xStyle.is())
+ {
+ SwXStyle* pStyle = comphelper::getFromUnoTunnel<SwXStyle>(xStyle);
+ if(pStyle)
+ pStyle->Invalidate();
+ }
+ m_pBasePool->Remove(pBase);
+ insertByName(rName, rElement);
+ }
+}
+
+void XStyleFamily::removeByName(const OUString& rName)
+{
+ SolarMutexGuard aGuard;
+ if(!m_pBasePool)
+ throw uno::RuntimeException();
+ OUString sName;
+ SwStyleNameMapper::FillUIName(rName, sName, m_rEntry.poolId());
+ SfxStyleSheetBase* pBase = m_pBasePool->Find(sName, m_rEntry.family());
+ if(!pBase)
+ throw container::NoSuchElementException();
+ if (SwGetPoolIdFromName::CellStyle == m_rEntry.poolId())
+ {
+ // handle cell style
+ m_pDocShell->GetDoc()->GetCellStyles().RemoveBoxFormat(rName);
+ }
+ else if (SwGetPoolIdFromName::TabStyle == m_rEntry.poolId())
+ {
+ // handle table style
+ m_pDocShell->GetDoc()->GetTableStyles().EraseAutoFormat(rName);
+ }
+ else
+ m_pBasePool->Remove(pBase);
+}
+
+uno::Any SAL_CALL XStyleFamily::getPropertyValue( const OUString& sPropertyName )
+{
+ if(sPropertyName != "DisplayName")
+ throw beans::UnknownPropertyException( "unknown property: " + sPropertyName, getXWeak() );
+ SolarMutexGuard aGuard;
+ return uno::Any(SwResId(m_rEntry.resId()));
+}
+
+
+SwXStyle* XStyleFamily::FindStyle(std::u16string_view rStyleName) const
+{
+ SwXStyle* pFoundStyle = nullptr;
+ m_pBasePool->ForAllListeners(
+ [this, &pFoundStyle, &rStyleName] (SfxListener* pListener)
+ {
+ SwXStyle* pTempStyle = dynamic_cast<SwXStyle*>(pListener);
+ if(pTempStyle && pTempStyle->GetFamily() == m_rEntry.family() && pTempStyle->GetStyleName() == rStyleName)
+ {
+ pFoundStyle = pTempStyle;
+ return true; // break
+ }
+ return false;
+ });
+ return pFoundStyle;
+}
+
+static SwGetPoolIdFromName lcl_GetSwEnumFromSfxEnum(SfxStyleFamily eFamily)
+{
+ auto& entries(lcl_GetStyleFamilyEntries());
+ const auto pEntry = std::find_if(entries.begin(), entries.end(),
+ [eFamily] (const StyleFamilyEntry& e) { return e.family() == eFamily; });
+ if(pEntry != entries.end())
+ return pEntry->poolId();
+ SAL_WARN("sw.uno", "someone asking for all styles in unostyle.cxx!" );
+ return SwGetPoolIdFromName::ChrFmt;
+}
+
+const uno::Sequence<sal_Int8>& SwXStyle::getUnoTunnelId()
+{
+ static const comphelper::UnoIdInit theSwXStyleUnoTunnelId;
+ return theSwXStyleUnoTunnelId.getSeq();
+}
+
+sal_Int64 SAL_CALL SwXStyle::getSomething(const uno::Sequence<sal_Int8>& rId)
+{
+ return comphelper::getSomethingImpl(rId, this);
+}
+
+
+uno::Sequence< OUString > SwXStyle::getSupportedServiceNames()
+{
+ tools::Long nCount = 1;
+ if(SfxStyleFamily::Para == m_rEntry.family())
+ {
+ nCount = 5;
+ if(m_bIsConditional)
+ nCount++;
+ }
+ else if(SfxStyleFamily::Char == m_rEntry.family())
+ nCount = 5;
+ else if(SfxStyleFamily::Page == m_rEntry.family())
+ nCount = 3;
+ uno::Sequence< OUString > aRet(nCount);
+ OUString* pArray = aRet.getArray();
+ pArray[0] = "com.sun.star.style.Style";
+ switch(m_rEntry.family())
+ {
+ case SfxStyleFamily::Char:
+ pArray[1] = "com.sun.star.style.CharacterStyle";
+ pArray[2] = "com.sun.star.style.CharacterProperties";
+ pArray[3] = "com.sun.star.style.CharacterPropertiesAsian";
+ pArray[4] = "com.sun.star.style.CharacterPropertiesComplex";
+ break;
+ case SfxStyleFamily::Page:
+ pArray[1] = "com.sun.star.style.PageStyle";
+ pArray[2] = "com.sun.star.style.PageProperties";
+ break;
+ case SfxStyleFamily::Para:
+ pArray[1] = "com.sun.star.style.ParagraphStyle";
+ pArray[2] = "com.sun.star.style.ParagraphProperties";
+ pArray[3] = "com.sun.star.style.ParagraphPropertiesAsian";
+ pArray[4] = "com.sun.star.style.ParagraphPropertiesComplex";
+ if(m_bIsConditional)
+ pArray[5] = "com.sun.star.style.ConditionalParagraphStyle";
+ break;
+
+ default:
+ ;
+ }
+ return aRet;
+}
+
+static uno::Reference<beans::XPropertySet> lcl_InitStandardStyle(const SfxStyleFamily eFamily, uno::Reference<container::XNameAccess> const & rxStyleFamily)
+{
+ using return_t = decltype(lcl_InitStandardStyle(eFamily, rxStyleFamily));
+ if(eFamily != SfxStyleFamily::Para && eFamily != SfxStyleFamily::Page)
+ return {};
+ auto aResult(rxStyleFamily->getByName("Standard"));
+ if(!aResult.has<return_t>())
+ return {};
+ return aResult.get<return_t>();
+}
+
+static uno::Reference<container::XNameAccess> lcl_InitStyleFamily(SwDoc* pDoc, const StyleFamilyEntry& rEntry)
+{
+ using return_t = decltype(lcl_InitStyleFamily(pDoc, rEntry));
+ if(rEntry.family() != SfxStyleFamily::Char
+ && rEntry.family() != SfxStyleFamily::Para
+ && rEntry.family() != SfxStyleFamily::Page)
+ return {};
+ auto xModel(pDoc->GetDocShell()->GetBaseModel());
+ uno::Reference<style::XStyleFamiliesSupplier> xFamilySupplier(xModel, uno::UNO_QUERY);
+ auto xFamilies = xFamilySupplier->getStyleFamilies();
+ auto aResult(xFamilies->getByName(rEntry.name()));
+ if(!aResult.has<return_t>())
+ return {};
+ return aResult.get<return_t>();
+}
+
+static bool lcl_InitConditional(SfxStyleSheetBasePool* pBasePool, const SfxStyleFamily eFamily, const OUString& rStyleName)
+{
+ if(!pBasePool || eFamily != SfxStyleFamily::Para)
+ return false;
+ SfxStyleSheetBase* pBase = pBasePool->Find(rStyleName, eFamily);
+ SAL_WARN_IF(!pBase, "sw.uno", "where is the style?" );
+ if(!pBase)
+ return false;
+ const sal_uInt16 nId(SwStyleNameMapper::GetPoolIdFromUIName(rStyleName, SwGetPoolIdFromName::TxtColl));
+ if(nId != USHRT_MAX)
+ return ::IsConditionalByPoolId(nId);
+ return RES_CONDTXTFMTCOLL == static_cast<SwDocStyleSheet*>(pBase)->GetCollection()->Which();
+}
+
+static const StyleFamilyEntry& lcl_GetStyleEntry(const SfxStyleFamily eFamily)
+{
+ auto& entries = lcl_GetStyleFamilyEntries();
+ const auto pEntry = std::find_if(entries.begin(), entries.end(),
+ [eFamily] (const StyleFamilyEntry& e) { return e.family() == eFamily; });
+ assert(pEntry != entries.end());
+ return *pEntry;
+}
+
+SwXStyle::SwXStyle(SwDoc* pDoc, SfxStyleFamily eFamily, bool bConditional)
+ : m_pDoc(pDoc)
+ , m_rEntry(lcl_GetStyleEntry(eFamily))
+ , m_bIsDescriptor(true)
+ , m_bIsConditional(bConditional)
+ , m_pBasePool(nullptr)
+ , m_xStyleFamily(lcl_InitStyleFamily(pDoc, m_rEntry))
+ , m_xStyleData(lcl_InitStandardStyle(eFamily, m_xStyleFamily))
+{
+ assert(!m_bIsConditional || m_rEntry.family() == SfxStyleFamily::Para); // only paragraph styles are conditional
+ // Register ourselves as a listener to the document (via the page descriptor)
+ SvtListener::StartListening(pDoc->getIDocumentStylePoolAccess().GetPageDescFromPool(RES_POOLPAGE_STANDARD)->GetNotifier());
+ m_pPropertiesImpl = std::make_unique<SwStyleProperties_Impl>(
+ aSwMapProvider.GetPropertySet(m_bIsConditional ? PROPERTY_MAP_CONDITIONAL_PARA_STYLE : m_rEntry.propMapType())->getPropertyMap());
+}
+
+SwXStyle::SwXStyle(SfxStyleSheetBasePool* pPool, SfxStyleFamily eFamily, SwDoc* pDoc, const OUString& rStyleName)
+ : m_pDoc(pDoc)
+ , m_sStyleName(rStyleName)
+ , m_rEntry(lcl_GetStyleEntry(eFamily))
+ , m_bIsDescriptor(false)
+ , m_bIsConditional(lcl_InitConditional(pPool, eFamily, rStyleName))
+ , m_pBasePool(pPool)
+{ }
+
+SwXStyle::~SwXStyle()
+{
+ SolarMutexGuard aGuard;
+ if(m_pBasePool)
+ SfxListener::EndListening(*m_pBasePool);
+ m_pPropertiesImpl.reset();
+ SvtListener::EndListeningAll();
+}
+
+void SwXStyle::Notify(const SfxHint& rHint)
+{
+ if(rHint.GetId() == SfxHintId::Dying)
+ {
+ m_pDoc = nullptr;
+ m_xStyleData.clear();
+ m_xStyleFamily.clear();
+ }
+}
+
+OUString SwXStyle::getName()
+{
+ SolarMutexGuard aGuard;
+ if(!m_pBasePool)
+ return m_sStyleName;
+ SfxStyleSheetBase* pBase = m_pBasePool->Find(m_sStyleName, m_rEntry.family());
+ SAL_WARN_IF(!pBase, "sw.uno", "where is the style?");
+ if(!pBase)
+ throw uno::RuntimeException();
+ OUString aString;
+ SwStyleNameMapper::FillProgName(pBase->GetName(), aString, lcl_GetSwEnumFromSfxEnum ( m_rEntry.family()));
+ return aString;
+}
+
+void SwXStyle::setName(const OUString& rName)
+{
+ SolarMutexGuard aGuard;
+ if(!m_pBasePool)
+ {
+ m_sStyleName = rName;
+ return;
+ }
+ SfxStyleSheetBase* pBase = m_pBasePool->Find(m_sStyleName, m_rEntry.family());
+ SAL_WARN_IF(!pBase, "sw.uno", "where is the style?");
+ if(!pBase || !pBase->IsUserDefined())
+ throw uno::RuntimeException();
+ rtl::Reference<SwDocStyleSheet> xTmp(new SwDocStyleSheet(*static_cast<SwDocStyleSheet*>(pBase)));
+ if(!xTmp->SetName(rName))
+ throw uno::RuntimeException();
+ m_sStyleName = rName;
+}
+
+sal_Bool SwXStyle::isUserDefined()
+{
+ SolarMutexGuard aGuard;
+ if(!m_pBasePool)
+ throw uno::RuntimeException();
+ SfxStyleSheetBase* pBase = m_pBasePool->Find(m_sStyleName, m_rEntry.family());
+ //if it is not found it must be non user defined
+ return pBase && pBase->IsUserDefined();
+}
+
+sal_Bool SwXStyle::isInUse()
+{
+ SolarMutexGuard aGuard;
+ if(!m_pBasePool)
+ throw uno::RuntimeException();
+ SfxStyleSheetBase* pBase = m_pBasePool->Find(m_sStyleName, m_rEntry.family(), SfxStyleSearchBits::Used);
+ return pBase && pBase->IsUsed();
+}
+
+OUString SwXStyle::getParentStyle()
+{
+ SolarMutexGuard aGuard;
+ if(!m_pBasePool)
+ {
+ if(!m_bIsDescriptor)
+ throw uno::RuntimeException();
+ return m_sParentStyleName;
+ }
+ SfxStyleSheetBase* pBase = m_pBasePool->Find(m_sStyleName, m_rEntry.family());
+ OUString aString;
+ if(pBase)
+ aString = pBase->GetParent();
+ SwStyleNameMapper::FillProgName(aString, aString, lcl_GetSwEnumFromSfxEnum(m_rEntry.family()));
+ return aString;
+}
+
+void SwXStyle::setParentStyle(const OUString& rParentStyle)
+{
+ SolarMutexGuard aGuard;
+ OUString sParentStyle;
+ SwStyleNameMapper::FillUIName(rParentStyle, sParentStyle, lcl_GetSwEnumFromSfxEnum ( m_rEntry.family()) );
+ if(!m_pBasePool)
+ {
+ if(!m_bIsDescriptor)
+ throw uno::RuntimeException();
+ m_sParentStyleName = sParentStyle;
+ try
+ {
+ const auto aAny = m_xStyleFamily->getByName(sParentStyle);
+ m_xStyleData = aAny.get<decltype(m_xStyleData)>();
+ }
+ catch(...)
+ { }
+ return;
+ }
+ SfxStyleSheetBase* pBase = m_pBasePool->Find(m_sStyleName, m_rEntry.family());
+ if(!pBase)
+ throw uno::RuntimeException();
+ rtl::Reference<SwDocStyleSheet> xBase(new SwDocStyleSheet(*static_cast<SwDocStyleSheet*>(pBase)));
+ //make it a 'real' style - necessary for pooled styles
+ xBase->GetItemSet();
+ if(xBase->GetParent() != sParentStyle)
+ {
+ if(!xBase->SetParent(sParentStyle))
+ throw uno::RuntimeException();
+ }
+}
+
+uno::Reference<beans::XPropertySetInfo> SwXStyle::getPropertySetInfo()
+{
+ if(m_bIsConditional)
+ {
+ assert(m_rEntry.family() == SfxStyleFamily::Para);
+ static auto xCondParaRef = aSwMapProvider.GetPropertySet(PROPERTY_MAP_CONDITIONAL_PARA_STYLE)->getPropertySetInfo();
+ return xCondParaRef;
+ }
+ return m_rEntry.xPSInfo();
+}
+
+void SwXStyle::ApplyDescriptorProperties()
+{
+ m_bIsDescriptor = false;
+ m_xStyleData.clear();
+ m_xStyleFamily.clear();
+ m_pPropertiesImpl->Apply(*this);
+}
+
+namespace {
+ const TranslateId STR_POOLPAGE_ARY[] =
+ {
+ // Page styles
+ STR_POOLPAGE_STANDARD,
+ STR_POOLPAGE_FIRST,
+ STR_POOLPAGE_LEFT,
+ STR_POOLPAGE_RIGHT,
+ STR_POOLPAGE_ENVELOPE,
+ STR_POOLPAGE_REGISTER,
+ STR_POOLPAGE_HTML,
+ STR_POOLPAGE_FOOTNOTE,
+ STR_POOLPAGE_ENDNOTE,
+ STR_POOLPAGE_LANDSCAPE
+ };
+}
+
+const SwPageDesc* SwStyleBase_Impl::GetOldPageDesc()
+{
+ if(!m_pOldPageDesc)
+ {
+ SwPageDesc *pd = m_rDoc.FindPageDesc(m_rStyleName);
+ if(pd)
+ m_pOldPageDesc = pd;
+
+ if(!m_pOldPageDesc)
+ {
+ for (size_t i = 0; i < SAL_N_ELEMENTS(STR_POOLPAGE_ARY); ++i)
+ {
+ if (SwResId(STR_POOLPAGE_ARY[i]) == m_rStyleName)
+ {
+ m_pOldPageDesc = m_rDoc.getIDocumentStylePoolAccess().GetPageDescFromPool(RES_POOLPAGE_BEGIN + i);
+ break;
+ }
+ }
+ }
+ }
+ return m_pOldPageDesc;
+}
+
+
+
+static sal_uInt8 lcl_TranslateMetric(const SfxItemPropertyMapEntry& rEntry, SwDoc* pDoc, uno::Any& o_aValue)
+{
+ // check for needed metric translation
+ if(!(rEntry.nMoreFlags & PropertyMoreFlags::METRIC_ITEM))
+ return rEntry.nMemberId;
+ // exception: If these ItemTypes are used, do not convert when these are negative
+ // since this means they are intended as percent values
+ if((XATTR_FILLBMP_SIZEX == rEntry.nWID || XATTR_FILLBMP_SIZEY == rEntry.nWID)
+ && o_aValue.has<sal_Int32>()
+ && o_aValue.get<sal_Int32>() < 0)
+ return rEntry.nMemberId;
+ if(!pDoc)
+ return rEntry.nMemberId;
+
+ const SfxItemPool& rPool = pDoc->GetAttrPool();
+ const MapUnit eMapUnit(rPool.GetMetric(rEntry.nWID));
+ if(eMapUnit != MapUnit::Map100thMM)
+ SvxUnoConvertFromMM(eMapUnit, o_aValue);
+ return rEntry.nMemberId;
+}
+template<>
+void SwXStyle::SetPropertyValue<HINT_BEGIN>(const SfxItemPropertyMapEntry& rEntry, const SfxItemPropertySet& rPropSet, const uno::Any& rValue, SwStyleBase_Impl& o_rStyleBase)
+{
+ // default ItemSet handling
+ SfxItemSet& rStyleSet = o_rStyleBase.GetItemSet();
+ SfxItemSet aSet(*rStyleSet.GetPool(), rEntry.nWID, rEntry.nWID);
+ aSet.SetParent(&rStyleSet);
+ rPropSet.setPropertyValue(rEntry, rValue, aSet);
+ rStyleSet.Put(aSet);
+}
+template<>
+void SwXStyle::SetPropertyValue<FN_UNO_HIDDEN>(const SfxItemPropertyMapEntry& rEntry, const SfxItemPropertySet& rPropSet, const uno::Any& rValue, SwStyleBase_Impl& o_rStyleBase)
+{
+ bool bHidden = false;
+ if(rValue >>= bHidden)
+ {
+ //make it a 'real' style - necessary for pooled styles
+ o_rStyleBase.getNewBase()->GetItemSet();
+ o_rStyleBase.getNewBase()->SetHidden(bHidden);
+ }
+ SetPropertyValue<HINT_BEGIN>(rEntry, rPropSet, rValue, o_rStyleBase);
+}
+template<>
+void SwXStyle::SetPropertyValue<FN_UNO_STYLE_INTEROP_GRAB_BAG>(const SfxItemPropertyMapEntry& rEntry, const SfxItemPropertySet& rPropSet, const uno::Any& rValue, SwStyleBase_Impl& o_rStyleBase)
+{
+ o_rStyleBase.getNewBase()->GetItemSet();
+ o_rStyleBase.getNewBase()->SetGrabBagItem(rValue);
+ SetPropertyValue<HINT_BEGIN>(rEntry, rPropSet, rValue, o_rStyleBase);
+}
+template<>
+void SwXStyle::SetPropertyValue<sal_uInt16(XATTR_FILLGRADIENT)>(const SfxItemPropertyMapEntry& rEntry, const SfxItemPropertySet& rPropSet, const uno::Any& rValue, SwStyleBase_Impl& o_rStyleBase)
+{
+ uno::Any aValue(rValue);
+ const auto nMemberId(lcl_TranslateMetric(rEntry, m_pDoc, aValue));
+ if(MID_NAME == nMemberId)
+ {
+ // add set commands for FillName items
+ SfxItemSet& rStyleSet = o_rStyleBase.GetItemSet();
+ if(!aValue.has<OUString>())
+ throw lang::IllegalArgumentException();
+ SvxShape::SetFillAttribute(rEntry.nWID, aValue.get<OUString>(), rStyleSet);
+ }
+ else if(MID_BITMAP == nMemberId)
+ {
+ if(sal_uInt16(XATTR_FILLBITMAP) == rEntry.nWID)
+ {
+ Graphic aNullGraphic;
+ SfxItemSet& rStyleSet = o_rStyleBase.GetItemSet();
+ XFillBitmapItem aXFillBitmapItem(std::move(aNullGraphic));
+ aXFillBitmapItem.PutValue(aValue, nMemberId);
+ rStyleSet.Put(aXFillBitmapItem);
+ }
+ }
+ else
+ SetPropertyValue<HINT_BEGIN>(rEntry, rPropSet, aValue, o_rStyleBase);
+}
+template<>
+void SwXStyle::SetPropertyValue<sal_uInt16(RES_BACKGROUND)>(const SfxItemPropertyMapEntry& rEntry, const SfxItemPropertySet&, const uno::Any& rValue, SwStyleBase_Impl& o_rStyleBase)
+{
+ SfxItemSet& rStyleSet = o_rStyleBase.GetItemSet();
+ const std::unique_ptr<SvxBrushItem> aOriginalBrushItem(getSvxBrushItemFromSourceSet(rStyleSet, RES_BACKGROUND, true, m_pDoc->IsInXMLImport()));
+ std::unique_ptr<SvxBrushItem> aChangedBrushItem(aOriginalBrushItem->Clone());
+
+ uno::Any aValue(rValue);
+ const auto nMemberId(lcl_TranslateMetric(rEntry, m_pDoc, aValue));
+ aChangedBrushItem->PutValue(aValue, nMemberId);
+
+ // 0xff is already the default - but if BackTransparent is set
+ // to true, it must be applied in the item set on ODF import
+ // to potentially override parent style, which is unknown yet
+ if(*aChangedBrushItem == *aOriginalBrushItem && (MID_GRAPHIC_TRANSPARENT != nMemberId || !aValue.has<bool>() || !aValue.get<bool>()))
+ return;
+
+ setSvxBrushItemAsFillAttributesToTargetSet(*aChangedBrushItem, rStyleSet);
+}
+template<>
+void SwXStyle::SetPropertyValue<OWN_ATTR_FILLBMP_MODE>(const SfxItemPropertyMapEntry&, const SfxItemPropertySet&, const uno::Any& rValue, SwStyleBase_Impl& o_rStyleBase)
+{
+ drawing::BitmapMode eMode;
+ if(!(rValue >>= eMode))
+ {
+ if(!rValue.has<sal_Int32>())
+ throw lang::IllegalArgumentException();
+ eMode = static_cast<drawing::BitmapMode>(rValue.get<sal_Int32>());
+ }
+ SfxItemSet& rStyleSet = o_rStyleBase.GetItemSet();
+ rStyleSet.Put(XFillBmpStretchItem(drawing::BitmapMode_STRETCH == eMode));
+ rStyleSet.Put(XFillBmpTileItem(drawing::BitmapMode_REPEAT == eMode));
+}
+template<>
+void SwXStyle::SetPropertyValue<sal_uInt16(RES_PAPER_BIN)>(const SfxItemPropertyMapEntry& rEntry, const SfxItemPropertySet& rPropSet, const uno::Any& rValue, SwStyleBase_Impl& o_rStyleBase)
+{
+ if(!rValue.has<OUString>())
+ throw lang::IllegalArgumentException();
+ SfxPrinter* pPrinter = m_pDoc->getIDocumentDeviceAccess().getPrinter(true);
+ OUString sValue(rValue.get<OUString>());
+ using printeridx_t = decltype(pPrinter->GetPaperBinCount());
+ printeridx_t nBin = std::numeric_limits<printeridx_t>::max();
+ if(sValue == "[From printer settings]")
+ nBin = std::numeric_limits<printeridx_t>::max()-1;
+ else if(pPrinter)
+ {
+ for(sal_uInt16 i=0, nEnd = pPrinter->GetPaperBinCount(); i < nEnd; ++i)
+ {
+ if (sValue == pPrinter->GetPaperBinName(i))
+ {
+ nBin = i;
+ break;
+ }
+ }
+ }
+ if(nBin == std::numeric_limits<printeridx_t>::max())
+ throw lang::IllegalArgumentException();
+ SfxItemSet& rStyleSet = o_rStyleBase.GetItemSet();
+ SfxItemSet aSet(*rStyleSet.GetPool(), rEntry.nWID, rEntry.nWID);
+ aSet.SetParent(&rStyleSet);
+ rPropSet.setPropertyValue(rEntry, uno::Any(static_cast<sal_Int8>(nBin == std::numeric_limits<printeridx_t>::max()-1 ? -1 : nBin)), aSet);
+ rStyleSet.Put(aSet);
+}
+template<>
+void SwXStyle::SetPropertyValue<FN_UNO_NUM_RULES>(const SfxItemPropertyMapEntry&, const SfxItemPropertySet&, const uno::Any& rValue, SwStyleBase_Impl& o_rStyleBase)
+{
+ auto xNumberTunnel(rValue.get<uno::Reference<container::XIndexReplace>>());
+ if(!xNumberTunnel)
+ throw lang::IllegalArgumentException();
+ SwXNumberingRules* pSwXRules = dynamic_cast<SwXNumberingRules*>(xNumberTunnel.get());
+ if(!pSwXRules)
+ return;
+ SwNumRule aSetRule(*pSwXRules->GetNumRule());
+ for(sal_uInt16 i = 0; i < MAXLEVEL; ++i)
+ {
+ const SwNumFormat* pFormat = aSetRule.GetNumFormat(i);
+ if(!pFormat)
+ continue;
+ SwNumFormat aFormat(*pFormat);
+ const auto& rCharName(pSwXRules->GetNewCharStyleNames()[i]);
+ if(!rCharName.isEmpty()
+ && !SwXNumberingRules::isInvalidStyle(rCharName)
+ && (!pFormat->GetCharFormat() || pFormat->GetCharFormat()->GetName() != rCharName))
+ {
+ auto pCharFormatIt(std::find_if(m_pDoc->GetCharFormats()->begin(), m_pDoc->GetCharFormats()->end(),
+ [&rCharName] (SwCharFormat* pF) { return pF->GetName() == rCharName; }));
+ if(pCharFormatIt != m_pDoc->GetCharFormats()->end())
+ aFormat.SetCharFormat(*pCharFormatIt);
+ else if(m_pBasePool)
+ {
+ auto pBase(m_pBasePool->Find(rCharName, SfxStyleFamily::Char));
+ if(!pBase)
+ pBase = &m_pBasePool->Make(rCharName, SfxStyleFamily::Char);
+ aFormat.SetCharFormat(static_cast<SwDocStyleSheet*>(pBase)->GetCharFormat());
+ }
+ else
+ aFormat.SetCharFormat(nullptr);
+ }
+ // same for fonts:
+ const auto& rBulletName(pSwXRules->GetBulletFontNames()[i]);
+ if(!rBulletName.isEmpty()
+ && !SwXNumberingRules::isInvalidStyle(rBulletName)
+ && (!pFormat->GetBulletFont() || pFormat->GetBulletFont()->GetFamilyName() != rBulletName))
+ {
+ const auto pFontListItem(static_cast<const SvxFontListItem*>(m_pDoc->GetDocShell()->GetItem(SID_ATTR_CHAR_FONTLIST)));
+ const auto pList(pFontListItem->GetFontList());
+ FontMetric aFontInfo(pList->Get(rBulletName, WEIGHT_NORMAL, ITALIC_NONE));
+ vcl::Font aFont(aFontInfo);
+ aFormat.SetBulletFont(&aFont);
+ }
+ aSetRule.Set(i, &aFormat);
+ }
+ o_rStyleBase.getNewBase()->SetNumRule(aSetRule);
+}
+template<>
+void SwXStyle::SetPropertyValue<sal_uInt16(RES_PARATR_OUTLINELEVEL)>(const SfxItemPropertyMapEntry&, const SfxItemPropertySet&, const uno::Any& rValue, SwStyleBase_Impl& o_rStyleBase)
+{
+ if(!rValue.has<sal_Int16>())
+ return;
+ const auto nLevel(rValue.get<sal_Int16>());
+ if(0 <= nLevel && nLevel <= MAXLEVEL)
+ o_rStyleBase.getNewBase()->GetCollection()->SetAttrOutlineLevel(nLevel);
+}
+template<>
+void SwXStyle::SetPropertyValue<FN_UNO_FOLLOW_STYLE>(const SfxItemPropertyMapEntry&, const SfxItemPropertySet&, const uno::Any& rValue, SwStyleBase_Impl& o_rStyleBase)
+{
+ if(!rValue.has<OUString>())
+ return;
+ const auto sValue(rValue.get<OUString>());
+ OUString aString;
+ SwStyleNameMapper::FillUIName(sValue, aString, m_rEntry.poolId());
+ o_rStyleBase.getNewBase()->SetFollow(aString);
+}
+
+template <>
+void SwXStyle::SetPropertyValue<FN_UNO_LINK_STYLE>(const SfxItemPropertyMapEntry&,
+ const SfxItemPropertySet&,
+ const uno::Any& rValue,
+ SwStyleBase_Impl& o_rStyleBase)
+{
+ if (!rValue.has<OUString>())
+ return;
+ const auto sValue(rValue.get<OUString>());
+ OUString aString;
+ SwStyleNameMapper::FillUIName(sValue, aString, m_rEntry.poolId());
+ o_rStyleBase.getNewBase()->SetLink(aString);
+}
+
+template<>
+void SwXStyle::SetPropertyValue<sal_uInt16(RES_PAGEDESC)>(const SfxItemPropertyMapEntry& rEntry, const SfxItemPropertySet& rPropSet, const uno::Any& rValue, SwStyleBase_Impl& o_rStyleBase)
+{
+ if(MID_PAGEDESC_PAGEDESCNAME != rEntry.nMemberId)
+ {
+ SetPropertyValue<HINT_BEGIN>(rEntry, rPropSet, rValue, o_rStyleBase);
+ return;
+ }
+ if(!rValue.has<OUString>())
+ throw lang::IllegalArgumentException();
+ // special handling for RES_PAGEDESC
+ SfxItemSet& rStyleSet = o_rStyleBase.GetItemSet();
+ std::unique_ptr<SwFormatPageDesc> pNewDesc;
+ if(const SwFormatPageDesc* pItem = rStyleSet.GetItemIfSet(RES_PAGEDESC))
+ pNewDesc.reset(new SwFormatPageDesc(*pItem));
+ else
+ pNewDesc.reset(new SwFormatPageDesc);
+ const auto sValue(rValue.get<OUString>());
+ OUString sDescName;
+ SwStyleNameMapper::FillUIName(sValue, sDescName, SwGetPoolIdFromName::PageDesc);
+ if(pNewDesc->GetPageDesc() && pNewDesc->GetPageDesc()->GetName() == sDescName)
+ return;
+ if(sDescName.isEmpty())
+ {
+ rStyleSet.ClearItem(RES_BREAK);
+ rStyleSet.Put(SwFormatPageDesc());
+ }
+ else
+ {
+ SwPageDesc* pPageDesc(SwPageDesc::GetByName(*m_pDoc, sDescName));
+ if(!pPageDesc)
+ throw lang::IllegalArgumentException();
+ pNewDesc->RegisterToPageDesc(*pPageDesc);
+ rStyleSet.Put(std::move(pNewDesc));
+ }
+}
+template<>
+void SwXStyle::SetPropertyValue<sal_uInt16(RES_TEXT_VERT_ADJUST)>(const SfxItemPropertyMapEntry& rEntry, const SfxItemPropertySet& rPropSet, const uno::Any& rValue, SwStyleBase_Impl& o_rStyleBase)
+{
+ if(m_rEntry.family() != SfxStyleFamily::Page)
+ {
+ SetPropertyValue<HINT_BEGIN>(rEntry, rPropSet, rValue, o_rStyleBase);
+ return;
+ }
+ if(!m_pDoc || !rValue.has<drawing::TextVerticalAdjust>() || !o_rStyleBase.GetOldPageDesc())
+ return;
+ SwPageDesc* pPageDesc = m_pDoc->FindPageDesc(o_rStyleBase.GetOldPageDesc()->GetName());
+ if(pPageDesc)
+ pPageDesc->SetVerticalAdjustment(rValue.get<drawing::TextVerticalAdjust>());
+}
+template<>
+void SwXStyle::SetPropertyValue<FN_UNO_IS_AUTO_UPDATE>(const SfxItemPropertyMapEntry&, const SfxItemPropertySet&, const uno::Any& rValue, SwStyleBase_Impl& o_rStyleBase)
+{
+ if(!rValue.has<bool>())
+ throw lang::IllegalArgumentException();
+ const bool bAuto(rValue.get<bool>());
+ if(SfxStyleFamily::Para == m_rEntry.family())
+ o_rStyleBase.getNewBase()->GetCollection()->SetAutoUpdateOnDirectFormat(bAuto);
+ else if(SfxStyleFamily::Frame == m_rEntry.family())
+ o_rStyleBase.getNewBase()->GetFrameFormat()->SetAutoUpdateOnDirectFormat(bAuto);
+}
+template<>
+void SwXStyle::SetPropertyValue<FN_UNO_PARA_STYLE_CONDITIONS>(const SfxItemPropertyMapEntry&, const SfxItemPropertySet&, const uno::Any& rValue, SwStyleBase_Impl& o_rStyleBase)
+{
+ static_assert(COND_COMMAND_COUNT == 28, "invalid size of command count?");
+ using expectedarg_t = uno::Sequence<beans::NamedValue>;
+ if(!rValue.has<expectedarg_t>() || !m_pBasePool)
+ throw lang::IllegalArgumentException();
+ SwCondCollItem aCondItem;
+ const auto aNamedValues = rValue.get<expectedarg_t>();
+ for(const auto& rNamedValue : aNamedValues)
+ {
+ if(!rNamedValue.Value.has<OUString>())
+ throw lang::IllegalArgumentException();
+
+ const OUString sValue(rNamedValue.Value.get<OUString>());
+ // get UI style name from programmatic style name
+ OUString aStyleName;
+ SwStyleNameMapper::FillUIName(sValue, aStyleName, lcl_GetSwEnumFromSfxEnum(m_rEntry.family()));
+
+ // check for correct context and style name
+ const auto nIdx(GetCommandContextIndex(rNamedValue.Name));
+ if (nIdx == -1)
+ throw lang::IllegalArgumentException();
+ bool bStyleFound = false;
+ for(auto pBase = m_pBasePool->First(SfxStyleFamily::Para); pBase; pBase = m_pBasePool->Next())
+ {
+ bStyleFound = pBase->GetName() == aStyleName;
+ if (bStyleFound)
+ break;
+ }
+ if (!bStyleFound)
+ throw lang::IllegalArgumentException();
+ aCondItem.SetStyle(&aStyleName, nIdx);
+ }
+ o_rStyleBase.GetItemSet().Put(aCondItem);
+}
+template<>
+void SwXStyle::SetPropertyValue<FN_UNO_CATEGORY>(const SfxItemPropertyMapEntry&, const SfxItemPropertySet&, const uno::Any& rValue, SwStyleBase_Impl& o_rStyleBase)
+{
+ if(!o_rStyleBase.getNewBase()->IsUserDefined() || !rValue.has<paragraphstyle_t>())
+ throw lang::IllegalArgumentException();
+ static const std::map<paragraphstyle_t, SfxStyleSearchBits> aUnoToCore = []{
+ std::map<paragraphstyle_t, SfxStyleSearchBits> map;
+ std::transform(std::begin(sParagraphStyleCategoryEntries), std::end(sParagraphStyleCategoryEntries), std::inserter(map, map.end()),
+ [] (const ParagraphStyleCategoryEntry& rEntry) { return std::make_pair(rEntry.m_eCategory, rEntry.m_nSwStyleBits); });
+ return map;
+ }();
+ const auto pUnoToCoreIt(aUnoToCore.find(rValue.get<paragraphstyle_t>()));
+ if (pUnoToCoreIt == aUnoToCore.end())
+ throw lang::IllegalArgumentException();
+ o_rStyleBase.getNewBase()->SetMask( pUnoToCoreIt->second|SfxStyleSearchBits::UserDefined );
+}
+template<>
+void SwXStyle::SetPropertyValue<SID_SWREGISTER_COLLECTION>(const SfxItemPropertyMapEntry&, const SfxItemPropertySet&, const uno::Any& rValue, SwStyleBase_Impl& o_rStyleBase)
+{
+ OUString sName;
+ rValue >>= sName;
+ SwRegisterItem aReg(!sName.isEmpty());
+ aReg.SetWhich(SID_SWREGISTER_MODE);
+ o_rStyleBase.GetItemSet().Put(aReg);
+ OUString aString;
+ SwStyleNameMapper::FillUIName(sName, aString, SwGetPoolIdFromName::TxtColl);
+ o_rStyleBase.GetItemSet().Put(SfxStringItem(SID_SWREGISTER_COLLECTION, aString ) );
+}
+template<>
+void SwXStyle::SetPropertyValue<sal_uInt16(RES_TXTATR_CJK_RUBY)>(const SfxItemPropertyMapEntry& rEntry, const SfxItemPropertySet& rPropSet, const uno::Any& rValue, SwStyleBase_Impl& o_rStyleBase)
+{
+ if(MID_RUBY_CHARSTYLE != rEntry.nMemberId)
+ return;
+ if(!rValue.has<OUString>())
+ throw lang::IllegalArgumentException();
+ const auto sValue(rValue.get<OUString>());
+ SfxItemSet& rStyleSet(o_rStyleBase.GetItemSet());
+ std::unique_ptr<SwFormatRuby> pRuby;
+ if(const SwFormatRuby* pRubyItem = rStyleSet.GetItemIfSet(RES_TXTATR_CJK_RUBY))
+ pRuby.reset(new SwFormatRuby(*pRubyItem));
+ else
+ pRuby.reset(new SwFormatRuby(OUString()));
+ OUString sStyle;
+ SwStyleNameMapper::FillUIName(sValue, sStyle, SwGetPoolIdFromName::ChrFmt);
+ pRuby->SetCharFormatName(sValue);
+ pRuby->SetCharFormatId(0);
+ if(!sValue.isEmpty())
+ {
+ const sal_uInt16 nId(SwStyleNameMapper::GetPoolIdFromUIName(sValue, SwGetPoolIdFromName::ChrFmt));
+ pRuby->SetCharFormatId(nId);
+ }
+ rStyleSet.Put(std::move(pRuby));
+ SetPropertyValue<HINT_BEGIN>(rEntry, rPropSet, rValue, o_rStyleBase);
+}
+template<>
+void SwXStyle::SetPropertyValue<sal_uInt16(RES_PARATR_DROP)>(const SfxItemPropertyMapEntry& rEntry, const SfxItemPropertySet& rPropSet, const uno::Any& rValue, SwStyleBase_Impl& o_rStyleBase)
+{
+ if(MID_DROPCAP_CHAR_STYLE_NAME != rEntry.nMemberId)
+ {
+ SetPropertyValue<HINT_BEGIN>(rEntry, rPropSet, rValue, o_rStyleBase);
+ return;
+ }
+ if(!rValue.has<OUString>())
+ throw lang::IllegalArgumentException();
+ SfxItemSet& rStyleSet(o_rStyleBase.GetItemSet());
+ std::unique_ptr<SwFormatDrop> pDrop;
+ if(const SwFormatDrop* pDropItem = rStyleSet.GetItemIfSet(RES_PARATR_DROP))
+ pDrop.reset(new SwFormatDrop(*pDropItem));
+ else
+ pDrop.reset(new SwFormatDrop);
+ const auto sValue(rValue.get<OUString>());
+ OUString sStyle;
+ SwStyleNameMapper::FillUIName(sValue, sStyle, SwGetPoolIdFromName::ChrFmt);
+ auto pStyle(static_cast<SwDocStyleSheet*>(m_pDoc->GetDocShell()->GetStyleSheetPool()->Find(sStyle, SfxStyleFamily::Char)));
+ //default character style must not be set as default format
+ if(!pStyle || pStyle->GetCharFormat() == m_pDoc->GetDfltCharFormat() )
+ {
+ throw lang::IllegalArgumentException();
+ }
+ pDrop->SetCharFormat(pStyle->GetCharFormat());
+ rStyleSet.Put(std::move(pDrop));
+}
+template<>
+void SwXStyle::SetPropertyValue<sal_uInt16(RES_PARATR_NUMRULE)>(const SfxItemPropertyMapEntry& rEntry, const SfxItemPropertySet& rPropSet, const uno::Any& rValue, SwStyleBase_Impl& o_rStyleBase)
+{
+ uno::Any aValue(rValue);
+ lcl_TranslateMetric(rEntry, m_pDoc, aValue);
+ SetPropertyValue<HINT_BEGIN>(rEntry, rPropSet, aValue, o_rStyleBase);
+ // --> OD 2006-10-18 #i70223#
+ if(SfxStyleFamily::Para == m_rEntry.family() &&
+ o_rStyleBase.getNewBase().is() && o_rStyleBase.getNewBase()->GetCollection() &&
+ //rBase.getNewBase()->GetCollection()->GetOutlineLevel() < MAXLEVEL /* assigned to list level of outline style */) //#outline level,removed by zhaojianwei
+ o_rStyleBase.getNewBase()->GetCollection()->IsAssignedToListLevelOfOutlineStyle()) ////<-end,add by zhaojianwei
+ {
+ OUString sNewNumberingRuleName;
+ aValue >>= sNewNumberingRuleName;
+ if(sNewNumberingRuleName.isEmpty() || sNewNumberingRuleName != m_pDoc->GetOutlineNumRule()->GetName())
+ o_rStyleBase.getNewBase()->GetCollection()->DeleteAssignmentToListLevelOfOutlineStyle();
+ }
+}
+
+void SwXStyle::SetStyleProperty(const SfxItemPropertyMapEntry& rEntry, const SfxItemPropertySet& rPropSet, const uno::Any& rValue, SwStyleBase_Impl& rBase)
+{
+ using propertytype_t = decltype(rEntry.nWID);
+ using coresetter_t = std::function<void(SwXStyle&, const SfxItemPropertyMapEntry&, const SfxItemPropertySet&, const uno::Any&, SwStyleBase_Impl&)>;
+ static const std::map<propertytype_t, coresetter_t> aUnoToCore{
+ // these explicit std::mem_fn() calls shouldn't be needed, but apparently MSVC is currently too stupid for C++11 again
+ { FN_UNO_HIDDEN, std::mem_fn(&SwXStyle::SetPropertyValue<FN_UNO_HIDDEN>) },
+ { FN_UNO_STYLE_INTEROP_GRAB_BAG, std::mem_fn(&SwXStyle::SetPropertyValue<FN_UNO_STYLE_INTEROP_GRAB_BAG>) },
+ { XATTR_FILLGRADIENT, std::mem_fn(&SwXStyle::SetPropertyValue<sal_uInt16(XATTR_FILLGRADIENT)>) },
+ { XATTR_FILLHATCH, std::mem_fn(&SwXStyle::SetPropertyValue<sal_uInt16(XATTR_FILLGRADIENT)>) },
+ { XATTR_FILLBITMAP, std::mem_fn(&SwXStyle::SetPropertyValue<sal_uInt16(XATTR_FILLGRADIENT)>) },
+ { XATTR_FILLFLOATTRANSPARENCE, std::mem_fn(&SwXStyle::SetPropertyValue<sal_uInt16(XATTR_FILLGRADIENT)>) },
+ { RES_BACKGROUND, std::mem_fn(&SwXStyle::SetPropertyValue<sal_uInt16(RES_BACKGROUND)>) },
+ { OWN_ATTR_FILLBMP_MODE, std::mem_fn(&SwXStyle::SetPropertyValue<OWN_ATTR_FILLBMP_MODE>) },
+ { RES_PAPER_BIN, std::mem_fn(&SwXStyle::SetPropertyValue<sal_uInt16(RES_PAPER_BIN)>) },
+ { FN_UNO_NUM_RULES, std::mem_fn(&SwXStyle::SetPropertyValue<FN_UNO_NUM_RULES>) },
+ { RES_PARATR_OUTLINELEVEL, std::mem_fn(&SwXStyle::SetPropertyValue<sal_uInt16(RES_PARATR_OUTLINELEVEL)>) },
+ { FN_UNO_FOLLOW_STYLE, std::mem_fn(&SwXStyle::SetPropertyValue<FN_UNO_FOLLOW_STYLE>) },
+ { FN_UNO_LINK_STYLE, std::mem_fn(&SwXStyle::SetPropertyValue<FN_UNO_LINK_STYLE>) },
+ { RES_PAGEDESC, std::mem_fn(&SwXStyle::SetPropertyValue<sal_uInt16(RES_PAGEDESC)>) },
+ { RES_TEXT_VERT_ADJUST, std::mem_fn(&SwXStyle::SetPropertyValue<sal_uInt16(RES_TEXT_VERT_ADJUST)>) },
+ { FN_UNO_IS_AUTO_UPDATE, std::mem_fn(&SwXStyle::SetPropertyValue<FN_UNO_IS_AUTO_UPDATE>) },
+ { FN_UNO_PARA_STYLE_CONDITIONS, std::mem_fn(&SwXStyle::SetPropertyValue<FN_UNO_PARA_STYLE_CONDITIONS>) },
+ { FN_UNO_CATEGORY, std::mem_fn(&SwXStyle::SetPropertyValue<FN_UNO_CATEGORY>) },
+ { SID_SWREGISTER_COLLECTION, std::mem_fn(&SwXStyle::SetPropertyValue<SID_SWREGISTER_COLLECTION>) },
+ { RES_TXTATR_CJK_RUBY, std::mem_fn(&SwXStyle::SetPropertyValue<sal_uInt16(RES_TXTATR_CJK_RUBY)>) },
+ { RES_PARATR_DROP, std::mem_fn(&SwXStyle::SetPropertyValue<sal_uInt16(RES_PARATR_DROP)>) },
+ { RES_PARATR_NUMRULE, std::mem_fn(&SwXStyle::SetPropertyValue<sal_uInt16(RES_PARATR_NUMRULE)>) }
+ };
+ const auto pUnoToCoreIt(aUnoToCore.find(rEntry.nWID));
+ if(pUnoToCoreIt != aUnoToCore.end())
+ pUnoToCoreIt->second(*this, rEntry, rPropSet, rValue, rBase);
+ else
+ {
+ // adapted switch logic to a more readable state; removed goto's and made
+ // execution of standard setting of property in ItemSet dependent of this variable
+ uno::Any aValue(rValue);
+ lcl_TranslateMetric(rEntry, m_pDoc, aValue);
+ SetPropertyValue<HINT_BEGIN>(rEntry, rPropSet, aValue, rBase);
+ }
+}
+
+void SwXStyle::SetPropertyValues_Impl(const uno::Sequence<OUString>& rPropertyNames, const uno::Sequence<uno::Any>& rValues)
+{
+ if(!m_pDoc)
+ throw uno::RuntimeException();
+ sal_uInt16 nPropSetId = m_bIsConditional ? PROPERTY_MAP_CONDITIONAL_PARA_STYLE : m_rEntry.propMapType();
+ const SfxItemPropertySet* pPropSet = aSwMapProvider.GetPropertySet(nPropSetId);
+ const SfxItemPropertyMap &rMap = pPropSet->getPropertyMap();
+ if(rPropertyNames.getLength() != rValues.getLength())
+ throw lang::IllegalArgumentException();
+
+ SwStyleBase_Impl aBaseImpl(*m_pDoc, m_sStyleName, &GetDoc()->GetDfltTextFormatColl()->GetAttrSet()); // add pDfltTextFormatColl as parent
+ if(m_pBasePool)
+ {
+ SfxStyleSheetBase* pBase = m_pBasePool->Find(m_sStyleName, m_rEntry.family());
+ SAL_WARN_IF(!pBase, "sw.uno", "where is the style?");
+ if(!pBase)
+ throw uno::RuntimeException();
+ aBaseImpl.setNewBase(new SwDocStyleSheet(*static_cast<SwDocStyleSheet*>(pBase)));
+ }
+ if(!aBaseImpl.getNewBase().is() && !m_bIsDescriptor)
+ throw uno::RuntimeException();
+
+ const OUString* pNames = rPropertyNames.getConstArray();
+ const uno::Any* pValues = rValues.getConstArray();
+ for(sal_Int32 nProp = 0; nProp < rPropertyNames.getLength(); ++nProp)
+ {
+ const SfxItemPropertyMapEntry* pEntry = rMap.getByName(pNames[nProp]);
+ if(!pEntry || (!m_bIsConditional && pNames[nProp] == UNO_NAME_PARA_STYLE_CONDITIONS))
+ throw beans::UnknownPropertyException("Unknown property: " + pNames[nProp], getXWeak());
+ if(pEntry->nFlags & beans::PropertyAttribute::READONLY)
+ throw beans::PropertyVetoException ("Property is read-only: " + pNames[nProp], getXWeak());
+ if(aBaseImpl.getNewBase().is())
+ SetStyleProperty(*pEntry, *pPropSet, pValues[nProp], aBaseImpl);
+ else if(!m_pPropertiesImpl->SetProperty(pNames[nProp], pValues[nProp]))
+ throw lang::IllegalArgumentException();
+ }
+
+ if(aBaseImpl.HasItemSet())
+ aBaseImpl.getNewBase()->SetItemSet(aBaseImpl.GetItemSet());
+}
+
+void SwXStyle::setPropertyValues(const uno::Sequence<OUString>& rPropertyNames, const uno::Sequence<uno::Any>& rValues)
+{
+ SolarMutexGuard aGuard;
+ // workaround for bad designed API
+ try
+ {
+ SetPropertyValues_Impl( rPropertyNames, rValues );
+ }
+ catch (const beans::UnknownPropertyException &rException)
+ {
+ // wrap the original (here not allowed) exception in
+ // a lang::WrappedTargetException that gets thrown instead.
+ lang::WrappedTargetException aWExc;
+ aWExc.TargetException <<= rException;
+ throw aWExc;
+ }
+}
+
+SfxStyleSheetBase* SwXStyle::GetStyleSheetBase()
+{
+ if(!m_pBasePool)
+ return nullptr;
+ SfxStyleSheetBase* pBase = m_pBasePool->Find(m_sStyleName, m_rEntry.family());
+ return pBase;
+}
+void SwXStyle::PrepareStyleBase(SwStyleBase_Impl& rBase)
+{
+ SfxStyleSheetBase* pBase(GetStyleSheetBase());
+ if(!pBase)
+ throw uno::RuntimeException();
+ if(!rBase.getNewBase().is())
+ rBase.setNewBase(new SwDocStyleSheet(*static_cast<SwDocStyleSheet*>(pBase)));
+}
+
+template<>
+uno::Any SwXStyle::GetStyleProperty<HINT_BEGIN>(const SfxItemPropertyMapEntry& rEntry, const SfxItemPropertySet& rPropSet, SwStyleBase_Impl& rBase);
+template<>
+uno::Any SwXStyle::GetStyleProperty<FN_UNO_IS_PHYSICAL>(const SfxItemPropertyMapEntry&, const SfxItemPropertySet&, SwStyleBase_Impl&)
+{
+ SfxStyleSheetBase* pBase(GetStyleSheetBase());
+ if(!pBase)
+ return uno::Any(false);
+ bool bPhys = static_cast<SwDocStyleSheet*>(pBase)->IsPhysical();
+ // The standard character format is not existing physically
+ if( bPhys && SfxStyleFamily::Char == GetFamily() &&
+ static_cast<SwDocStyleSheet*>(pBase)->GetCharFormat() &&
+ static_cast<SwDocStyleSheet*>(pBase)->GetCharFormat()->IsDefault() )
+ bPhys = false;
+ return uno::Any(bool(bPhys));
+}
+template<>
+uno::Any SwXStyle::GetStyleProperty<FN_UNO_HIDDEN>(const SfxItemPropertyMapEntry&, const SfxItemPropertySet&, SwStyleBase_Impl&)
+{
+ SfxStyleSheetBase* pBase(GetStyleSheetBase());
+ if(!pBase)
+ return uno::Any(false);
+ rtl::Reference<SwDocStyleSheet> xBase(new SwDocStyleSheet(*static_cast<SwDocStyleSheet*>(pBase)));
+ return uno::Any(xBase->IsHidden());
+}
+template<>
+uno::Any SwXStyle::GetStyleProperty<FN_UNO_STYLE_INTEROP_GRAB_BAG>(const SfxItemPropertyMapEntry&, const SfxItemPropertySet&, SwStyleBase_Impl&)
+{
+ SfxStyleSheetBase* pBase(GetStyleSheetBase());
+ if(!pBase)
+ return uno::Any();
+ uno::Any aRet;
+ rtl::Reference<SwDocStyleSheet> xBase(new SwDocStyleSheet(*static_cast<SwDocStyleSheet*>(pBase)));
+ xBase->GetGrabBagItem(aRet);
+ return aRet;
+}
+template<>
+uno::Any SwXStyle::GetStyleProperty<sal_uInt16(RES_PAPER_BIN)>(const SfxItemPropertyMapEntry& rEntry, const SfxItemPropertySet& rPropSet, SwStyleBase_Impl& rBase)
+{
+ PrepareStyleBase(rBase);
+ SfxItemSet& rSet = rBase.GetItemSet();
+ uno::Any aValue;
+ rPropSet.getPropertyValue(rEntry, rSet, aValue);
+ sal_Int8 nBin(aValue.get<sal_Int8>());
+ if(nBin == -1)
+ return uno::Any(OUString("[From printer settings]"));
+ SfxPrinter* pPrinter = GetDoc()->getIDocumentDeviceAccess().getPrinter(false);
+ if(!pPrinter)
+ return uno::Any();
+ return uno::Any(pPrinter->GetPaperBinName(nBin));
+}
+template<>
+uno::Any SwXStyle::GetStyleProperty<FN_UNO_NUM_RULES>(const SfxItemPropertyMapEntry&, const SfxItemPropertySet&, SwStyleBase_Impl& rBase)
+{
+ PrepareStyleBase(rBase);
+ const SwNumRule* pRule = rBase.getNewBase()->GetNumRule();
+ assert(pRule && "Where is the NumRule?");
+ uno::Reference<container::XIndexReplace> xRules(new SwXNumberingRules(*pRule, GetDoc()));
+ return uno::Any(xRules);
+}
+template<>
+uno::Any SwXStyle::GetStyleProperty<sal_uInt16(RES_PARATR_OUTLINELEVEL)>(const SfxItemPropertyMapEntry&, const SfxItemPropertySet&, SwStyleBase_Impl& rBase)
+{
+ PrepareStyleBase(rBase);
+ SAL_WARN_IF(SfxStyleFamily::Para != GetFamily(), "sw.uno", "only paras");
+ return uno::Any(sal_Int16(rBase.getNewBase()->GetCollection()->GetAttrOutlineLevel()));
+}
+template<>
+uno::Any SwXStyle::GetStyleProperty<FN_UNO_FOLLOW_STYLE>(const SfxItemPropertyMapEntry&, const SfxItemPropertySet&, SwStyleBase_Impl& rBase)
+{
+ PrepareStyleBase(rBase);
+ OUString aString;
+ SwStyleNameMapper::FillProgName(rBase.getNewBase()->GetFollow(), aString, lcl_GetSwEnumFromSfxEnum(GetFamily()));
+ return uno::Any(aString);
+}
+
+template <>
+uno::Any SwXStyle::GetStyleProperty<FN_UNO_LINK_STYLE>(const SfxItemPropertyMapEntry&,
+ const SfxItemPropertySet&,
+ SwStyleBase_Impl& rBase)
+{
+ PrepareStyleBase(rBase);
+ OUString aString;
+ SwStyleNameMapper::FillProgName(rBase.getNewBase()->GetLink(), aString,
+ lcl_GetSwEnumFromSfxEnum(GetFamily()));
+ return uno::Any(aString);
+}
+
+template<>
+uno::Any SwXStyle::GetStyleProperty<sal_uInt16(RES_PAGEDESC)>(const SfxItemPropertyMapEntry& rEntry, const SfxItemPropertySet& rPropSet, SwStyleBase_Impl& rBase)
+{
+ PrepareStyleBase(rBase);
+ if(MID_PAGEDESC_PAGEDESCNAME != rEntry.nMemberId)
+ return GetStyleProperty<HINT_BEGIN>(rEntry, rPropSet, rBase);
+ // special handling for RES_PAGEDESC
+ const SwFormatPageDesc* pItem =
+ rBase.GetItemSet().GetItemIfSet(RES_PAGEDESC);
+ if(!pItem)
+ return uno::Any();
+ const SwPageDesc* pDesc = pItem->GetPageDesc();
+ if(!pDesc)
+ return uno::Any();
+ OUString aString;
+ SwStyleNameMapper::FillProgName(pDesc->GetName(), aString, SwGetPoolIdFromName::PageDesc);
+ return uno::Any(aString);
+}
+template<>
+uno::Any SwXStyle::GetStyleProperty<FN_UNO_IS_AUTO_UPDATE>(const SfxItemPropertyMapEntry&, const SfxItemPropertySet&, SwStyleBase_Impl& rBase)
+{
+ PrepareStyleBase(rBase);
+ switch(GetFamily())
+ {
+ case SfxStyleFamily::Para : return uno::Any(rBase.getNewBase()->GetCollection()->IsAutoUpdateOnDirectFormat());
+ case SfxStyleFamily::Frame: return uno::Any(rBase.getNewBase()->GetFrameFormat()->IsAutoUpdateOnDirectFormat());
+ default: return uno::Any();
+ }
+}
+template<>
+uno::Any SwXStyle::GetStyleProperty<FN_UNO_DISPLAY_NAME>(const SfxItemPropertyMapEntry&, const SfxItemPropertySet&, SwStyleBase_Impl& rBase)
+{
+ PrepareStyleBase(rBase);
+ return uno::Any(rBase.getNewBase()->GetName());
+}
+template<>
+uno::Any SwXStyle::GetStyleProperty<FN_UNO_PARA_STYLE_CONDITIONS>(const SfxItemPropertyMapEntry&, const SfxItemPropertySet&, SwStyleBase_Impl& rBase)
+{
+ PrepareStyleBase(rBase);
+ static_assert(COND_COMMAND_COUNT == 28, "invalid size of command count?");
+ uno::Sequence<beans::NamedValue> aSeq(COND_COMMAND_COUNT);
+ sal_uInt16 nIndex = 0;
+ for(auto& rNV : asNonConstRange(aSeq))
+ {
+ rNV.Name = GetCommandContextByIndex(nIndex++);
+ rNV.Value <<= OUString();
+ }
+ SwFormat* pFormat = static_cast<SwDocStyleSheet*>(GetStyleSheetBase())->GetCollection();
+ if(pFormat && RES_CONDTXTFMTCOLL == pFormat->Which())
+ {
+ const CommandStruct* pCmds = SwCondCollItem::GetCmds();
+ beans::NamedValue* pSeq = aSeq.getArray();
+ for(sal_uInt16 n = 0; n < COND_COMMAND_COUNT; ++n)
+ {
+ const SwCollCondition* pCond = static_cast<SwConditionTextFormatColl*>(pFormat)->HasCondition(SwCollCondition(nullptr, pCmds[n].nCnd, pCmds[n].nSubCond));
+ if(!pCond || !pCond->GetTextFormatColl())
+ continue;
+ // get programmatic style name from UI style name
+ OUString aStyleName = pCond->GetTextFormatColl()->GetName();
+ SwStyleNameMapper::FillProgName(aStyleName, aStyleName, lcl_GetSwEnumFromSfxEnum(GetFamily()));
+ pSeq[n].Value <<= aStyleName;
+ }
+ }
+ return uno::Any(aSeq);
+}
+template<>
+uno::Any SwXStyle::GetStyleProperty<FN_UNO_CATEGORY>(const SfxItemPropertyMapEntry&, const SfxItemPropertySet&, SwStyleBase_Impl& rBase)
+{
+ PrepareStyleBase(rBase);
+ static const std::map<collectionbits_t, paragraphstyle_t> aUnoToCore = []{
+ std::map<collectionbits_t, paragraphstyle_t> map;
+ std::transform(std::begin(sParagraphStyleCategoryEntries), std::end(sParagraphStyleCategoryEntries), std::inserter(map, map.end()),
+ [] (const ParagraphStyleCategoryEntry& rEntry) { return std::make_pair(rEntry.m_nCollectionBits, rEntry.m_eCategory); });
+ return map;
+ }();
+ const sal_uInt16 nPoolId = rBase.getNewBase()->GetCollection()->GetPoolFormatId();
+ const auto pUnoToCoreIt(aUnoToCore.find(COLL_GET_RANGE_BITS & nPoolId));
+ if(pUnoToCoreIt == aUnoToCore.end())
+ return uno::Any(sal_Int16(-1));
+ return uno::Any(pUnoToCoreIt->second);
+}
+template<>
+uno::Any SwXStyle::GetStyleProperty<SID_SWREGISTER_COLLECTION>(const SfxItemPropertyMapEntry&, const SfxItemPropertySet&, SwStyleBase_Impl& rBase)
+{
+ PrepareStyleBase(rBase);
+ const SwPageDesc *pPageDesc = rBase.getNewBase()->GetPageDesc();
+ if(!pPageDesc)
+ return uno::Any(OUString());
+ const SwTextFormatColl* pCol = pPageDesc->GetRegisterFormatColl();
+ if(!pCol)
+ return uno::Any(OUString());
+ OUString aName;
+ SwStyleNameMapper::FillProgName(pCol->GetName(), aName, SwGetPoolIdFromName::TxtColl);
+ return uno::Any(aName);
+}
+template<>
+uno::Any SwXStyle::GetStyleProperty<sal_uInt16(RES_BACKGROUND)>(const SfxItemPropertyMapEntry& rEntry, const SfxItemPropertySet&, SwStyleBase_Impl& rBase)
+{
+ PrepareStyleBase(rBase);
+ const SfxItemSet& rSet = rBase.GetItemSet();
+ const std::unique_ptr<SvxBrushItem> aOriginalBrushItem(getSvxBrushItemFromSourceSet(rSet, RES_BACKGROUND));
+ uno::Any aResult;
+ if(!aOriginalBrushItem->QueryValue(aResult, rEntry.nMemberId))
+ SAL_WARN("sw.uno", "error getting attribute from RES_BACKGROUND.");
+ return aResult;
+}
+template<>
+uno::Any SwXStyle::GetStyleProperty<OWN_ATTR_FILLBMP_MODE>(const SfxItemPropertyMapEntry&, const SfxItemPropertySet&, SwStyleBase_Impl& rBase)
+{
+ PrepareStyleBase(rBase);
+ const SfxItemSet& rSet = rBase.GetItemSet();
+ if (rSet.Get(XATTR_FILLBMP_TILE).GetValue())
+ return uno::Any(drawing::BitmapMode_REPEAT);
+ if (rSet.Get(XATTR_FILLBMP_STRETCH).GetValue())
+ return uno::Any(drawing::BitmapMode_STRETCH);
+ return uno::Any(drawing::BitmapMode_NO_REPEAT);
+}
+template<>
+uno::Any SwXStyle::GetStyleProperty<HINT_BEGIN>(const SfxItemPropertyMapEntry& rEntry, const SfxItemPropertySet& rPropSet, SwStyleBase_Impl& rBase)
+{
+ PrepareStyleBase(rBase);
+ SfxItemSet& rSet = rBase.GetItemSet();
+ uno::Any aResult;
+ rPropSet.getPropertyValue(rEntry, rSet, aResult);
+ //
+ // since the sfx uint16 item now exports a sal_Int32, we may have to fix this here
+ if(rEntry.aType == cppu::UnoType<sal_Int16>::get() && aResult.getValueType() == cppu::UnoType<sal_Int32>::get())
+ aResult <<= static_cast<sal_Int16>(aResult.get<sal_Int32>());
+ // check for needed metric translation
+ if(rEntry.nMoreFlags & PropertyMoreFlags::METRIC_ITEM && GetDoc())
+ {
+ const SfxItemPool& rPool = GetDoc()->GetAttrPool();
+ const MapUnit eMapUnit(rPool.GetMetric(rEntry.nWID));
+ bool bAllowedConvert(true);
+ // exception: If these ItemTypes are used, do not convert when these are negative
+ // since this means they are intended as percent values
+ if(XATTR_FILLBMP_SIZEX == rEntry.nWID || XATTR_FILLBMP_SIZEY == rEntry.nWID)
+ bAllowedConvert = !aResult.has<sal_Int32>() || aResult.get<sal_Int32>() > 0;
+ if(eMapUnit != MapUnit::Map100thMM && bAllowedConvert)
+ SvxUnoConvertToMM(eMapUnit, aResult);
+ }
+ return aResult;
+}
+
+uno::Any SwXStyle::GetStyleProperty_Impl(const SfxItemPropertyMapEntry& rEntry, const SfxItemPropertySet& rPropSet, SwStyleBase_Impl& rBase)
+{
+ using propertytype_t = decltype(rEntry.nWID);
+ using coresetter_t = std::function<uno::Any(SwXStyle&, const SfxItemPropertyMapEntry&, const SfxItemPropertySet&, SwStyleBase_Impl&)>;
+ static const std::map<propertytype_t, coresetter_t> aUnoToCore{
+ // these explicit std::mem_fn() calls shouldn't be needed, but apparently MSVC is currently too stupid for C++11 again
+ { FN_UNO_IS_PHYSICAL, std::mem_fn(&SwXStyle::GetStyleProperty<FN_UNO_IS_PHYSICAL>) },
+ { FN_UNO_HIDDEN, std::mem_fn(&SwXStyle::GetStyleProperty<FN_UNO_HIDDEN>) },
+ { FN_UNO_STYLE_INTEROP_GRAB_BAG, std::mem_fn(&SwXStyle::GetStyleProperty<FN_UNO_STYLE_INTEROP_GRAB_BAG>) },
+ { RES_PAPER_BIN, std::mem_fn(&SwXStyle::GetStyleProperty<sal_uInt16(RES_PAPER_BIN)>) },
+ { FN_UNO_NUM_RULES, std::mem_fn(&SwXStyle::GetStyleProperty<FN_UNO_NUM_RULES>) },
+ { RES_PARATR_OUTLINELEVEL, std::mem_fn(&SwXStyle::GetStyleProperty<sal_uInt16(RES_PARATR_OUTLINELEVEL)>) },
+ { FN_UNO_FOLLOW_STYLE, std::mem_fn(&SwXStyle::GetStyleProperty<FN_UNO_FOLLOW_STYLE>) },
+ { FN_UNO_LINK_STYLE, std::mem_fn(&SwXStyle::GetStyleProperty<FN_UNO_LINK_STYLE>) },
+ { RES_PAGEDESC, std::mem_fn(&SwXStyle::GetStyleProperty<sal_uInt16(RES_PAGEDESC)>) },
+ { FN_UNO_IS_AUTO_UPDATE, std::mem_fn(&SwXStyle::GetStyleProperty<FN_UNO_IS_AUTO_UPDATE>) },
+ { FN_UNO_DISPLAY_NAME, std::mem_fn(&SwXStyle::GetStyleProperty<FN_UNO_DISPLAY_NAME>) },
+ { FN_UNO_PARA_STYLE_CONDITIONS, std::mem_fn(&SwXStyle::GetStyleProperty<FN_UNO_PARA_STYLE_CONDITIONS>) },
+ { FN_UNO_CATEGORY, std::mem_fn(&SwXStyle::GetStyleProperty<FN_UNO_CATEGORY>) },
+ { SID_SWREGISTER_COLLECTION, std::mem_fn(&SwXStyle::GetStyleProperty<SID_SWREGISTER_COLLECTION>) },
+ { RES_BACKGROUND, std::mem_fn(&SwXStyle::GetStyleProperty<sal_uInt16(RES_BACKGROUND)>) },
+ { OWN_ATTR_FILLBMP_MODE, std::mem_fn(&SwXStyle::GetStyleProperty<OWN_ATTR_FILLBMP_MODE>) }
+ };
+ const auto pUnoToCoreIt(aUnoToCore.find(rEntry.nWID));
+ if(pUnoToCoreIt != aUnoToCore.end())
+ return pUnoToCoreIt->second(*this, rEntry, rPropSet, rBase);
+ return GetStyleProperty<HINT_BEGIN>(rEntry, rPropSet, rBase);
+}
+
+uno::Any SwXStyle::GetPropertyValue_Impl(const SfxItemPropertySet* pPropSet, SwStyleBase_Impl& rBase, const OUString& rPropertyName)
+{
+ const SfxItemPropertyMap& rMap = pPropSet->getPropertyMap();
+ const SfxItemPropertyMapEntry* pEntry = rMap.getByName(rPropertyName);
+ if(!pEntry || (!m_bIsConditional && rPropertyName == UNO_NAME_PARA_STYLE_CONDITIONS))
+ throw beans::UnknownPropertyException("Unknown property: " + rPropertyName, getXWeak());
+ if(m_pBasePool)
+ return GetStyleProperty_Impl(*pEntry, *pPropSet, rBase);
+ const uno::Any* pAny = nullptr;
+ m_pPropertiesImpl->GetProperty(rPropertyName, pAny);
+ if(pAny->hasValue())
+ return *pAny;
+ uno::Any aValue;
+ switch(m_rEntry.family())
+ {
+ case SfxStyleFamily::Pseudo:
+ throw uno::RuntimeException("No default value for: " + rPropertyName);
+ break;
+ case SfxStyleFamily::Para:
+ case SfxStyleFamily::Page:
+ aValue = m_xStyleData->getPropertyValue(rPropertyName);
+ break;
+ case SfxStyleFamily::Char:
+ case SfxStyleFamily::Frame:
+ {
+ if(pEntry->nWID < POOLATTR_BEGIN || pEntry->nWID >= RES_UNKNOWNATR_END)
+ throw uno::RuntimeException("No default value for: " + rPropertyName);
+ SwFormat* pFormat;
+ if(m_rEntry.family() == SfxStyleFamily::Char)
+ pFormat = m_pDoc->GetDfltCharFormat();
+ else
+ pFormat = m_pDoc->GetDfltFrameFormat();
+ const SwAttrPool* pPool = pFormat->GetAttrSet().GetPool();
+ const SfxPoolItem& rItem = pPool->GetDefaultItem(pEntry->nWID);
+ rItem.QueryValue(aValue, pEntry->nMemberId);
+ }
+ break;
+ default:
+ ;
+ }
+ return aValue;
+}
+
+uno::Any SwXStyle::getPropertyValue(const OUString& rPropertyName)
+{
+ SolarMutexGuard aGuard;
+ if(!m_pDoc)
+ throw uno::RuntimeException();
+ if(!m_pBasePool && !m_bIsDescriptor)
+ throw uno::RuntimeException();
+ sal_uInt16 nPropSetId = m_bIsConditional ? PROPERTY_MAP_CONDITIONAL_PARA_STYLE : m_rEntry.propMapType();
+ const SfxItemPropertySet* pPropSet = aSwMapProvider.GetPropertySet(nPropSetId);
+ SwStyleBase_Impl aBase(*m_pDoc, m_sStyleName, &m_pDoc->GetDfltTextFormatColl()->GetAttrSet()); // add pDfltTextFormatColl as parent
+ return GetPropertyValue_Impl(pPropSet, aBase, rPropertyName);
+}
+
+uno::Sequence<uno::Any> SwXStyle::getPropertyValues(const uno::Sequence<OUString>& rPropertyNames)
+{
+ SolarMutexGuard aGuard;
+ if(!m_pDoc)
+ throw uno::RuntimeException();
+ if(!m_pBasePool && !m_bIsDescriptor)
+ throw uno::RuntimeException();
+ sal_uInt16 nPropSetId = m_bIsConditional ? PROPERTY_MAP_CONDITIONAL_PARA_STYLE : m_rEntry.propMapType();
+ const SfxItemPropertySet* pPropSet = aSwMapProvider.GetPropertySet(nPropSetId);
+ SwStyleBase_Impl aBase(*m_pDoc, m_sStyleName, &m_pDoc->GetDfltTextFormatColl()->GetAttrSet()); // add pDfltTextFormatColl as parent
+ uno::Sequence<uno::Any> aValues(rPropertyNames.getLength());
+ auto aValuesRange = asNonConstRange(aValues);
+ // workaround for bad designed API
+ try
+ {
+ for(sal_Int32 nProp = 0; nProp < rPropertyNames.getLength(); ++nProp)
+ aValuesRange[nProp] = GetPropertyValue_Impl(pPropSet, aBase, rPropertyNames[nProp]);
+ }
+ catch(beans::UnknownPropertyException&)
+ {
+ css::uno::Any anyEx = cppu::getCaughtException();
+ throw css::lang::WrappedTargetRuntimeException("Unknown property exception caught",
+ getXWeak(), anyEx );
+ }
+ catch(lang::WrappedTargetException&)
+ {
+ css::uno::Any anyEx = cppu::getCaughtException();
+ throw lang::WrappedTargetRuntimeException("WrappedTargetException caught",
+ getXWeak(), anyEx );
+ }
+ return aValues;
+}
+
+void SwXStyle::setPropertyValue(const OUString& rPropertyName, const uno::Any& rValue)
+{
+ SolarMutexGuard aGuard;
+ const uno::Sequence<OUString> aProperties(&rPropertyName, 1);
+ const uno::Sequence<uno::Any> aValues(&rValue, 1);
+ SetPropertyValues_Impl(aProperties, aValues);
+}
+
+beans::PropertyState SwXStyle::getPropertyState(const OUString& rPropertyName)
+{
+ SolarMutexGuard aGuard;
+ uno::Sequence<OUString> aNames{rPropertyName};
+ uno::Sequence<beans::PropertyState> aStates = getPropertyStates(aNames);
+ return aStates.getConstArray()[0];
+}
+
+// allow to retarget the SfxItemSet working on, default correctly. Only
+// use pSourceSet below this point (except in header/footer processing)
+static const SfxItemSet* lcl_GetItemsetForProperty(const SfxItemSet& rSet, SfxStyleFamily eFamily, std::u16string_view rPropertyName)
+{
+ if(eFamily != SfxStyleFamily::Page)
+ return &rSet;
+ const bool isFooter = o3tl::starts_with(rPropertyName, u"Footer");
+ if(!isFooter && !o3tl::starts_with(rPropertyName, u"Header") && rPropertyName != UNO_NAME_FIRST_IS_SHARED)
+ return &rSet;
+ const SvxSetItem* pSetItem;
+ if(!lcl_GetHeaderFooterItem(rSet, rPropertyName, isFooter, pSetItem))
+ return nullptr;
+ return &pSetItem->GetItemSet();
+}
+uno::Sequence<beans::PropertyState> SwXStyle::getPropertyStates(const uno::Sequence<OUString>& rPropertyNames)
+{
+ SolarMutexGuard aGuard;
+ uno::Sequence<beans::PropertyState> aRet(rPropertyNames.getLength());
+ beans::PropertyState* pStates = aRet.getArray();
+
+ if(!m_pBasePool)
+ throw uno::RuntimeException();
+ SfxStyleSheetBase* pBase = m_pBasePool->Find(m_sStyleName, m_rEntry.family());
+
+ SAL_WARN_IF(!pBase, "sw.uno", "where is the style?");
+ if(!pBase)
+ throw uno::RuntimeException();
+
+ const OUString* pNames = rPropertyNames.getConstArray();
+ rtl::Reference<SwDocStyleSheet> xStyle(new SwDocStyleSheet(*static_cast<SwDocStyleSheet*>(pBase)));
+ sal_uInt16 nPropSetId = m_bIsConditional ? PROPERTY_MAP_CONDITIONAL_PARA_STYLE : m_rEntry.propMapType();
+
+ const SfxItemPropertySet* pPropSet = aSwMapProvider.GetPropertySet(nPropSetId);
+ const SfxItemPropertyMap& rMap = pPropSet->getPropertyMap();
+ const SfxItemSet& rSet = xStyle->GetItemSet();
+
+ for(sal_Int32 i = 0; i < rPropertyNames.getLength(); ++i)
+ {
+ const OUString sPropName = pNames[i];
+ const SfxItemPropertyMapEntry* pEntry = rMap.getByName(sPropName);
+
+ if(!pEntry)
+ throw beans::UnknownPropertyException("Unknown property: " + sPropName, getXWeak());
+
+ if (FN_UNO_NUM_RULES == pEntry->nWID || FN_UNO_FOLLOW_STYLE == pEntry->nWID
+ || pEntry->nWID == FN_UNO_LINK_STYLE)
+ {
+ // handle NumRules first, done
+ pStates[i] = beans::PropertyState_DIRECT_VALUE;
+ continue;
+ }
+ const SfxItemSet* pSourceSet = lcl_GetItemsetForProperty(rSet, m_rEntry.family(), sPropName);
+ if(!pSourceSet)
+ {
+ // if no SetItem, value is ambiguous and we are done
+ pStates[i] = beans::PropertyState_AMBIGUOUS_VALUE;
+ continue;
+ }
+ switch(pEntry->nWID)
+ {
+ case OWN_ATTR_FILLBMP_MODE:
+ {
+ if(SfxItemState::SET == pSourceSet->GetItemState(XATTR_FILLBMP_STRETCH, false)
+ || SfxItemState::SET == pSourceSet->GetItemState(XATTR_FILLBMP_TILE, false))
+ {
+ pStates[i] = beans::PropertyState_DIRECT_VALUE;
+ }
+ else
+ {
+ pStates[i] = beans::PropertyState_AMBIGUOUS_VALUE;
+ }
+ }
+ break;
+ case XATTR_FILLSTYLE:
+ {
+ if (m_rEntry.family() == SfxStyleFamily::Frame
+ && xStyle->GetFrameFormat()->DerivedFrom() == GetDoc()->GetDfltFrameFormat())
+ { // tdf#156155 mpDfltFrameFormat is the parent, but because
+ // it IsDefault() it is not enumerated/exported as a style
+ // to ODF, so export its one important value here.
+ pStates[i] = beans::PropertyState_DIRECT_VALUE;
+ }
+ else
+ {
+ pStates[i] = pPropSet->getPropertyState(*pEntry, *pSourceSet);
+ }
+ }
+ break;
+ case RES_BACKGROUND:
+ {
+ // for FlyFrames we need to mark the used properties from type RES_BACKGROUND
+ // as beans::PropertyState_DIRECT_VALUE to let users of this property call
+ // getPropertyValue where the member properties will be mapped from the
+ // fill attributes to the according SvxBrushItem entries
+ if (SWUnoHelper::needToMapFillItemsToSvxBrushItemTypes(*pSourceSet, pEntry->nMemberId))
+ {
+ pStates[i] = beans::PropertyState_DIRECT_VALUE;
+ }
+ else
+ {
+ pStates[i] = beans::PropertyState_DEFAULT_VALUE;
+ }
+ }
+ break;
+ default:
+ {
+ pStates[i] = pPropSet->getPropertyState(*pEntry, *pSourceSet);
+
+ if(SfxStyleFamily::Page == m_rEntry.family() && SID_ATTR_PAGE_SIZE == pEntry->nWID && beans::PropertyState_DIRECT_VALUE == pStates[i])
+ {
+ const SvxSizeItem& rSize = rSet.Get(SID_ATTR_PAGE_SIZE);
+ sal_uInt8 nMemberId = pEntry->nMemberId & 0x7f;
+
+ if((LONG_MAX == rSize.GetSize().Width() && (MID_SIZE_WIDTH == nMemberId || MID_SIZE_SIZE == nMemberId)) ||
+ (LONG_MAX == rSize.GetSize().Height() && MID_SIZE_HEIGHT == nMemberId))
+ {
+ pStates[i] = beans::PropertyState_DEFAULT_VALUE;
+ }
+ }
+ }
+ }
+ }
+ return aRet;
+}
+
+void SwXStyle::setPropertyToDefault(const OUString& rPropertyName)
+{
+ const uno::Sequence<OUString> aSequence(&rPropertyName, 1);
+ setPropertiesToDefault(aSequence);
+}
+
+static SwFormat* lcl_GetFormatForStyle(SwDoc const * pDoc, const rtl::Reference<SwDocStyleSheet>& xStyle, const SfxStyleFamily eFamily)
+{
+ if(!xStyle.is())
+ return nullptr;
+ switch(eFamily)
+ {
+ case SfxStyleFamily::Char: return xStyle->GetCharFormat();
+ case SfxStyleFamily::Para: return xStyle->GetCollection();
+ case SfxStyleFamily::Frame: return xStyle->GetFrameFormat();
+ case SfxStyleFamily::Page:
+ {
+ SwPageDesc* pDesc(pDoc->FindPageDesc(xStyle->GetPageDesc()->GetName()));
+ if(pDesc)
+ return &pDesc->GetMaster();
+ }
+ break;
+ default: ;
+ }
+ return nullptr;
+}
+
+void SAL_CALL SwXStyle::setPropertiesToDefault(const uno::Sequence<OUString>& aPropertyNames)
+{
+ SolarMutexGuard aGuard;
+ const rtl::Reference<SwDocStyleSheet> xStyle(new SwDocStyleSheet(*static_cast<SwDocStyleSheet*>(GetStyleSheetBase())));
+ SwFormat* pTargetFormat = lcl_GetFormatForStyle(m_pDoc, xStyle, m_rEntry.family());
+ if(!pTargetFormat)
+ {
+ if(!m_bIsDescriptor)
+ return;
+ for(const auto& rName : aPropertyNames)
+ m_pPropertiesImpl->ClearProperty(rName);
+ return;
+ }
+ const sal_uInt16 nPropSetId = m_bIsConditional ? PROPERTY_MAP_CONDITIONAL_PARA_STYLE : m_rEntry.propMapType();
+ const SfxItemPropertySet* pPropSet = aSwMapProvider.GetPropertySet(nPropSetId);
+ const SfxItemPropertyMap &rMap = pPropSet->getPropertyMap();
+ for(const auto& rName : aPropertyNames)
+ {
+ const SfxItemPropertyMapEntry* pEntry = rMap.getByName(rName);
+ if(!pEntry)
+ throw beans::UnknownPropertyException("Unknown property: " + rName, getXWeak());
+ if (pEntry->nWID == FN_UNO_FOLLOW_STYLE || pEntry->nWID == FN_UNO_LINK_STYLE
+ || pEntry->nWID == FN_UNO_NUM_RULES)
+ throw uno::RuntimeException("Cannot reset: " + rName, getXWeak());
+ if(pEntry->nFlags & beans::PropertyAttribute::READONLY)
+ throw uno::RuntimeException("setPropertiesToDefault: property is read-only: " + rName, getXWeak());
+ if(pEntry->nWID == RES_PARATR_OUTLINELEVEL)
+ {
+ static_cast<SwTextFormatColl*>(pTargetFormat)->DeleteAssignmentToListLevelOfOutlineStyle();
+ continue;
+ }
+ pTargetFormat->ResetFormatAttr(pEntry->nWID);
+ if(OWN_ATTR_FILLBMP_MODE == pEntry->nWID)
+ {
+ //
+ SwDoc* pDoc = pTargetFormat->GetDoc();
+ SfxItemSetFixed<XATTR_FILL_FIRST, XATTR_FILL_LAST> aSet(pDoc->GetAttrPool());
+ aSet.SetParent(&pTargetFormat->GetAttrSet());
+
+ aSet.ClearItem(XATTR_FILLBMP_STRETCH);
+ aSet.ClearItem(XATTR_FILLBMP_TILE);
+
+ pTargetFormat->SetFormatAttr(aSet);
+ }
+ }
+}
+
+void SAL_CALL SwXStyle::setAllPropertiesToDefault()
+{
+ SolarMutexGuard aGuard;
+ if(!m_pBasePool)
+ {
+ if(!m_bIsDescriptor)
+ throw uno::RuntimeException();
+ m_pPropertiesImpl->ClearAllProperties();
+ return;
+ }
+ const rtl::Reference<SwDocStyleSheet> xStyle(new SwDocStyleSheet(*static_cast<SwDocStyleSheet*>(GetStyleSheetBase())));
+ if(!xStyle.is())
+ throw uno::RuntimeException();
+ if(SfxStyleFamily::Page == m_rEntry.family())
+ {
+ size_t nPgDscPos(0);
+ SwPageDesc* pDesc = m_pDoc->FindPageDesc(xStyle->GetPageDesc()->GetName(), &nPgDscPos);
+ SwFormat* pPageFormat(nullptr);
+ if(pDesc)
+ {
+ pPageFormat = &pDesc->GetMaster();
+ pDesc->SetUseOn(UseOnPage::All);
+ }
+ else
+ pPageFormat = lcl_GetFormatForStyle(m_pDoc, xStyle, m_rEntry.family());
+ SwPageDesc& rPageDesc = m_pDoc->GetPageDesc(nPgDscPos);
+ rPageDesc.ResetAllMasterAttr();
+
+ pPageFormat->SetPageFormatToDefault();
+ SwPageDesc* pStdPgDsc = m_pDoc->getIDocumentStylePoolAccess().GetPageDescFromPool(RES_POOLPAGE_STANDARD);
+ std::shared_ptr<SwFormatFrameSize> aFrameSz(std::make_shared<SwFormatFrameSize>(SwFrameSize::Fixed));
+
+ if(RES_POOLPAGE_STANDARD == rPageDesc.GetPoolFormatId())
+ {
+ if(m_pDoc->getIDocumentDeviceAccess().getPrinter(false))
+ {
+ const Size aPhysSize( SvxPaperInfo::GetPaperSize(
+ static_cast<Printer*>(m_pDoc->getIDocumentDeviceAccess().getPrinter(false))));
+ aFrameSz->SetSize(aPhysSize);
+ }
+ else
+ {
+ aFrameSz->SetSize(SvxPaperInfo::GetDefaultPaperSize());
+ }
+
+ }
+ else
+ {
+ aFrameSz.reset(pStdPgDsc->GetMaster().GetFrameSize().Clone());
+ }
+
+ if(pStdPgDsc->GetLandscape())
+ {
+ SwTwips nTmp = aFrameSz->GetHeight();
+ aFrameSz->SetHeight(aFrameSz->GetWidth());
+ aFrameSz->SetWidth(nTmp);
+ }
+
+ pPageFormat->SetFormatAttr(*aFrameSz);
+ m_pDoc->ChgPageDesc(nPgDscPos, m_pDoc->GetPageDesc(nPgDscPos));
+ return;
+ }
+ if(SfxStyleFamily::Para == m_rEntry.family())
+ {
+ if(xStyle->GetCollection())
+ xStyle->GetCollection()->DeleteAssignmentToListLevelOfOutlineStyle();
+ }
+ SwFormat* const pTargetFormat = lcl_GetFormatForStyle(m_pDoc, xStyle, m_rEntry.family());
+ if(!pTargetFormat)
+ return;
+ pTargetFormat->ResetAllFormatAttr();
+}
+
+uno::Sequence<uno::Any> SAL_CALL SwXStyle::getPropertyDefaults(const uno::Sequence<OUString>& aPropertyNames)
+{
+ SolarMutexGuard aGuard;
+ sal_Int32 nCount = aPropertyNames.getLength();
+ uno::Sequence<uno::Any> aRet(nCount);
+ if(!nCount)
+ return aRet;
+ auto pRet = aRet.getArray();
+ SfxStyleSheetBase* pBase = GetStyleSheetBase();
+ if(!pBase)
+ throw uno::RuntimeException();
+ rtl::Reference<SwDocStyleSheet> xStyle(new SwDocStyleSheet(*static_cast<SwDocStyleSheet*>(pBase)));
+ const sal_uInt16 nPropSetId = m_bIsConditional ? PROPERTY_MAP_CONDITIONAL_PARA_STYLE : m_rEntry.propMapType();
+ const SfxItemPropertySet* pPropSet = aSwMapProvider.GetPropertySet(nPropSetId);
+ const SfxItemPropertyMap& rMap = pPropSet->getPropertyMap();
+
+ const SfxItemSet &rSet = xStyle->GetItemSet(), *pParentSet = rSet.GetParent();
+ for(sal_Int32 i = 0; i < nCount; ++i)
+ {
+ const SfxItemPropertyMapEntry* pEntry = rMap.getByName(aPropertyNames[i]);
+
+ if(!pEntry)
+ throw beans::UnknownPropertyException("Unknown property: " + aPropertyNames[i], getXWeak());
+ // these cannot be in an item set, especially not the
+ // parent set, so the default value is void
+ if (pEntry->nWID >= RES_UNKNOWNATR_END)
+ continue;
+
+ if(pParentSet)
+ {
+ aSwMapProvider.GetPropertySet(nPropSetId)->getPropertyValue(aPropertyNames[i], *pParentSet, pRet[i]);
+ }
+ else if(pEntry->nWID != rSet.GetPool()->GetSlotId(pEntry->nWID))
+ {
+ const SfxPoolItem& rItem = rSet.GetPool()->GetDefaultItem(pEntry->nWID);
+ rItem.QueryValue(pRet[i], pEntry->nMemberId);
+ }
+ }
+ return aRet;
+}
+
+uno::Any SwXStyle::getPropertyDefault(const OUString& rPropertyName)
+{
+ const uno::Sequence<OUString> aSequence(&rPropertyName, 1);
+ return getPropertyDefaults(aSequence)[0];
+}
+
+void SwXStyle::Notify(SfxBroadcaster& rBC, const SfxHint& rHint)
+{
+ if((rHint.GetId() == SfxHintId::Dying) || (rHint.GetId() == SfxHintId::StyleSheetErased))
+ {
+ m_pBasePool = nullptr;
+ SfxListener::EndListening(rBC);
+ }
+ else if(rHint.GetId() == SfxHintId::StyleSheetChanged)
+ {
+ SfxStyleSheetBasePool& rBP = static_cast<SfxStyleSheetBasePool&>(rBC);
+ SfxStyleSheetBase* pOwnBase = rBP.Find(m_sStyleName, m_rEntry.family());
+ if(!pOwnBase)
+ {
+ SfxListener::EndListening(rBC);
+ Invalidate();
+ }
+ }
+}
+
+void SwXStyle::Invalidate()
+{
+ m_sStyleName.clear();
+ m_pBasePool = nullptr;
+ m_pDoc = nullptr;
+ m_xStyleData.clear();
+ m_xStyleFamily.clear();
+}
+
+SwXPageStyle::SwXPageStyle(SfxStyleSheetBasePool& rPool, SwDocShell* pDocSh, const OUString& rStyleName)
+ : SwXStyle(&rPool, SfxStyleFamily::Page, pDocSh->GetDoc(), rStyleName)
+{ }
+
+SwXPageStyle::SwXPageStyle(SwDocShell* pDocSh)
+ : SwXStyle(pDocSh->GetDoc(), SfxStyleFamily::Page)
+{ }
+
+void SwXStyle::PutItemToSet(const SvxSetItem* pSetItem, const SfxItemPropertySet& rPropSet, const SfxItemPropertyMapEntry& rEntry, const uno::Any& rVal, SwStyleBase_Impl& rBaseImpl)
+{
+ // create a new SvxSetItem and get it's ItemSet as new target
+ std::unique_ptr<SvxSetItem> pNewSetItem(pSetItem->Clone());
+ SfxItemSet& rSetSet = pNewSetItem->GetItemSet();
+
+ // set parent to ItemSet to ensure XFILL_NONE as XFillStyleItem
+ rSetSet.SetParent(&m_pDoc->GetDfltFrameFormat()->GetAttrSet());
+
+ // replace the used SfxItemSet at the SwStyleBase_Impl temporarily and use the
+ // default method to set the property
+ {
+ SwStyleBase_Impl::ItemSetOverrider o(rBaseImpl, &rSetSet);
+ SetStyleProperty(rEntry, rPropSet, rVal, rBaseImpl);
+ }
+
+ // reset parent at ItemSet from SetItem
+ rSetSet.SetParent(nullptr);
+
+ // set the new SvxSetItem at the real target and delete it
+ rBaseImpl.GetItemSet().Put(std::move(pNewSetItem));
+}
+
+void SwXPageStyle::SetPropertyValues_Impl(const uno::Sequence<OUString>& rPropertyNames, const uno::Sequence<uno::Any>& rValues)
+{
+ if(!GetDoc())
+ throw uno::RuntimeException();
+
+ if(rPropertyNames.getLength() != rValues.getLength())
+ throw lang::IllegalArgumentException();
+
+ const SfxItemPropertySet* pPropSet = aSwMapProvider.GetPropertySet(PROPERTY_MAP_PAGE_STYLE);
+ const SfxItemPropertyMap& rMap = pPropSet->getPropertyMap();
+ SwStyleBase_Impl aBaseImpl(*GetDoc(), GetStyleName(), &GetDoc()->GetDfltFrameFormat()->GetAttrSet()); // add pDfltFrameFormat as parent
+ if(!m_pBasePool)
+ {
+ if(!IsDescriptor())
+ throw uno::RuntimeException();
+ for(sal_Int32 nProp = 0; nProp < rPropertyNames.getLength(); ++nProp)
+ if(!m_pPropertiesImpl->SetProperty(rPropertyNames[nProp], rValues[nProp]))
+ throw lang::IllegalArgumentException();
+ return;
+ }
+ SfxStyleSheetBase* pBase = GetStyleSheetBase();
+ if(!pBase)
+ throw uno::RuntimeException();
+ aBaseImpl.setNewBase(new SwDocStyleSheet(*static_cast<SwDocStyleSheet*>(pBase)));
+ for(sal_Int32 nProp = 0; nProp < rPropertyNames.getLength(); ++nProp)
+ {
+ const OUString& rPropName = rPropertyNames[nProp];
+ const SfxItemPropertyMapEntry* pEntry = rMap.getByName(rPropName);
+
+ if(!pEntry)
+ throw beans::UnknownPropertyException("Unknown property: " + rPropName, getXWeak());
+ if(pEntry->nFlags & beans::PropertyAttribute::READONLY)
+ throw beans::PropertyVetoException("Property is read-only: " + rPropName, getXWeak());
+
+ const bool bHeader(rPropName.startsWith("Header"));
+ const bool bFooter(rPropName.startsWith("Footer"));
+ const bool bFirstIsShared(rPropName == UNO_NAME_FIRST_IS_SHARED);
+ if(bHeader || bFooter || bFirstIsShared)
+ {
+ switch(pEntry->nWID)
+ {
+ case SID_ATTR_PAGE_ON:
+ case RES_BACKGROUND:
+ case RES_BOX:
+ case RES_LR_SPACE:
+ case RES_SHADOW:
+ case RES_UL_SPACE:
+ case SID_ATTR_PAGE_DYNAMIC:
+ case SID_ATTR_PAGE_SHARED:
+ case SID_ATTR_PAGE_SHARED_FIRST:
+ case SID_ATTR_PAGE_SIZE:
+ case RES_HEADER_FOOTER_EAT_SPACING:
+ {
+ // it is a Header/Footer entry, access the SvxSetItem containing it's information
+ const SvxSetItem* pSetItem = nullptr;
+ if (lcl_GetHeaderFooterItem(aBaseImpl.GetItemSet(), rPropName, bFooter, pSetItem))
+ {
+ PutItemToSet(pSetItem, *pPropSet, *pEntry, rValues[nProp], aBaseImpl);
+
+ if (pEntry->nWID == SID_ATTR_PAGE_SHARED_FIRST)
+ {
+ // Need to add this to the other as well
+ pSetItem = aBaseImpl.GetItemSet().GetItemIfSet(
+ bFooter ? SID_ATTR_PAGE_HEADERSET : SID_ATTR_PAGE_FOOTERSET,
+ false);
+ if (pSetItem)
+ {
+ PutItemToSet(pSetItem, *pPropSet, *pEntry, rValues[nProp], aBaseImpl);
+ }
+ }
+ }
+ else if(pEntry->nWID == SID_ATTR_PAGE_ON && rValues[nProp].get<bool>())
+ {
+ // Header/footer gets switched on, create defaults and the needed SfxSetItem
+ SfxItemSetFixed
+ <RES_FRMATR_BEGIN,RES_FRMATR_END - 1, // [82
+
+ // FillAttribute support
+ XATTR_FILL_FIRST, XATTR_FILL_LAST, // [1014
+
+ SID_ATTR_BORDER_INNER,SID_ATTR_BORDER_INNER, // [10023
+ SID_ATTR_PAGE_SIZE,SID_ATTR_PAGE_SIZE, // [10051
+ SID_ATTR_PAGE_ON,SID_ATTR_PAGE_SHARED, // [10060
+ SID_ATTR_PAGE_SHARED_FIRST,SID_ATTR_PAGE_SHARED_FIRST>
+ aTempSet(*aBaseImpl.GetItemSet().GetPool());
+
+ // set correct parent to get the XFILL_NONE FillStyle as needed
+ aTempSet.SetParent(&GetDoc()->GetDfltFrameFormat()->GetAttrSet());
+
+ aTempSet.Put(SfxBoolItem(SID_ATTR_PAGE_ON, true));
+ constexpr tools::Long constTwips_5mm = o3tl::toTwips(5, o3tl::Length::mm);
+ aTempSet.Put(SvxSizeItem(SID_ATTR_PAGE_SIZE, Size(constTwips_5mm, constTwips_5mm)));
+ aTempSet.Put(SvxLRSpaceItem(RES_LR_SPACE));
+ aTempSet.Put(SvxULSpaceItem(RES_UL_SPACE));
+ aTempSet.Put(SfxBoolItem(SID_ATTR_PAGE_SHARED, true));
+ aTempSet.Put(SfxBoolItem(SID_ATTR_PAGE_SHARED_FIRST, true));
+ aTempSet.Put(SfxBoolItem(SID_ATTR_PAGE_DYNAMIC, true));
+
+ SvxSetItem aNewSetItem(bFooter ? SID_ATTR_PAGE_FOOTERSET : SID_ATTR_PAGE_HEADERSET, aTempSet);
+ aBaseImpl.GetItemSet().Put(aNewSetItem);
+ }
+ }
+ continue;
+ case XATTR_FILLBMP_SIZELOG:
+ case XATTR_FILLBMP_TILEOFFSETX:
+ case XATTR_FILLBMP_TILEOFFSETY:
+ case XATTR_FILLBMP_POSOFFSETX:
+ case XATTR_FILLBMP_POSOFFSETY:
+ case XATTR_FILLBMP_POS:
+ case XATTR_FILLBMP_SIZEX:
+ case XATTR_FILLBMP_SIZEY:
+ case XATTR_FILLBMP_STRETCH:
+ case XATTR_FILLBMP_TILE:
+ case OWN_ATTR_FILLBMP_MODE:
+ case XATTR_FILLCOLOR:
+ case XATTR_FILLBACKGROUND:
+ case XATTR_FILLBITMAP:
+ case XATTR_GRADIENTSTEPCOUNT:
+ case XATTR_FILLGRADIENT:
+ case XATTR_FILLHATCH:
+ case XATTR_FILLSTYLE:
+ case XATTR_FILLTRANSPARENCE:
+ case XATTR_FILLFLOATTRANSPARENCE:
+ case XATTR_SECONDARYFILLCOLOR:
+ if(bFirstIsShared) // only special handling for headers/footers here
+ break;
+ {
+ const SvxSetItem* pSetItem =
+ aBaseImpl.GetItemSet().GetItemIfSet(bFooter ? SID_ATTR_PAGE_FOOTERSET : SID_ATTR_PAGE_HEADERSET, false);
+
+ if(pSetItem)
+ {
+ // create a new SvxSetItem and get it's ItemSet as new target
+ std::unique_ptr<SvxSetItem> pNewSetItem(pSetItem->Clone());
+ SfxItemSet& rSetSet = pNewSetItem->GetItemSet();
+
+ // set parent to ItemSet to ensure XFILL_NONE as XFillStyleItem
+ rSetSet.SetParent(&GetDoc()->GetDfltFrameFormat()->GetAttrSet());
+
+ // replace the used SfxItemSet at the SwStyleBase_Impl temporarily and use the
+ // default method to set the property
+ {
+ SwStyleBase_Impl::ItemSetOverrider o(aBaseImpl, &rSetSet);
+ SetStyleProperty(*pEntry, *pPropSet, rValues[nProp], aBaseImpl);
+ }
+
+ // reset parent at ItemSet from SetItem
+ rSetSet.SetParent(nullptr);
+
+ // set the new SvxSetItem at the real target and delete it
+ aBaseImpl.GetItemSet().Put(std::move(pNewSetItem));
+ }
+ }
+ continue;
+ default: ;
+ }
+ }
+ switch(pEntry->nWID)
+ {
+ case SID_ATTR_PAGE_DYNAMIC:
+ case SID_ATTR_PAGE_SHARED:
+ case SID_ATTR_PAGE_SHARED_FIRST:
+ case SID_ATTR_PAGE_ON:
+ case RES_HEADER_FOOTER_EAT_SPACING:
+ // these slots are exclusive to Header/Footer, thus this is an error
+ throw beans::UnknownPropertyException("Unknown property: " + rPropName, getXWeak());
+ case FN_UNO_HEADER:
+ case FN_UNO_HEADER_LEFT:
+ case FN_UNO_HEADER_RIGHT:
+ case FN_UNO_HEADER_FIRST:
+ case FN_UNO_FOOTER:
+ case FN_UNO_FOOTER_LEFT:
+ case FN_UNO_FOOTER_RIGHT:
+ case FN_UNO_FOOTER_FIRST:
+ throw lang::IllegalArgumentException();
+ case FN_PARAM_FTN_INFO:
+ {
+ const SwPageFootnoteInfoItem& rItem = aBaseImpl.GetItemSet().Get(FN_PARAM_FTN_INFO);
+ std::unique_ptr<SfxPoolItem> pNewFootnoteItem(rItem.Clone());
+ if(!pNewFootnoteItem->PutValue(rValues[nProp], pEntry->nMemberId))
+ throw lang::IllegalArgumentException();
+ aBaseImpl.GetItemSet().Put(std::move(pNewFootnoteItem));
+ break;
+ }
+ default:
+ {
+ SetStyleProperty(*pEntry, *pPropSet, rValues[nProp], aBaseImpl);
+ break;
+ }
+ }
+ }
+
+ if(aBaseImpl.HasItemSet())
+ {
+ ::sw::UndoGuard const undoGuard(GetDoc()->GetIDocumentUndoRedo());
+
+ if (undoGuard.UndoWasEnabled())
+ {
+ // Fix i64460: as long as Undo of page styles with header/footer causes trouble...
+ GetDoc()->GetIDocumentUndoRedo().DelAllUndoObj();
+ }
+
+ aBaseImpl.getNewBase()->SetItemSet(aBaseImpl.GetItemSet());
+ }
+}
+
+void SwXPageStyle::setPropertyValues(const uno::Sequence<OUString>& rPropertyNames, const uno::Sequence<uno::Any>& rValues)
+{
+ SolarMutexGuard aGuard;
+
+ // workaround for bad designed API
+ try
+ {
+ SetPropertyValues_Impl(rPropertyNames, rValues);
+ }
+ catch (const beans::UnknownPropertyException &rException)
+ {
+ // wrap the original (here not allowed) exception in
+ // a lang::WrappedTargetException that gets thrown instead.
+ lang::WrappedTargetException aWExc;
+ aWExc.TargetException <<= rException;
+ throw aWExc;
+ }
+}
+
+static rtl::Reference<SwXHeadFootText> lcl_makeHeaderFooter(const sal_uInt16 nRes, const bool bHeader, SwFrameFormat const*const pFrameFormat)
+{
+ if (!pFrameFormat)
+ return nullptr;
+ const SfxItemSet& rSet = pFrameFormat->GetAttrSet();
+ const SfxPoolItem* pItem;
+ if(SfxItemState::SET != rSet.GetItemState(nRes, true, &pItem))
+ return nullptr;
+ SwFrameFormat* const pHeadFootFormat = bHeader
+ ? static_cast<SwFormatHeader*>(const_cast<SfxPoolItem*>(pItem))->GetHeaderFormat()
+ : static_cast<SwFormatFooter*>(const_cast<SfxPoolItem*>(pItem))->GetFooterFormat();
+ if(!pHeadFootFormat)
+ return nullptr;
+ return SwXHeadFootText::CreateXHeadFootText(*pHeadFootFormat, bHeader);
+}
+
+uno::Sequence<uno::Any> SwXPageStyle::GetPropertyValues_Impl(const uno::Sequence<OUString>& rPropertyNames)
+{
+ if(!GetDoc())
+ throw uno::RuntimeException();
+
+ sal_Int32 nLength = rPropertyNames.getLength();
+ uno::Sequence<uno::Any> aRet (nLength);
+ auto aRetRange = asNonConstRange(aRet);
+ if(!m_pBasePool)
+ {
+ if(!IsDescriptor())
+ throw uno::RuntimeException();
+ for(sal_Int32 nProp = 0; nProp < rPropertyNames.getLength(); ++nProp)
+ {
+ const uno::Any* pAny = nullptr;
+ m_pPropertiesImpl->GetProperty(rPropertyNames[nProp], pAny);
+ if (!pAny->hasValue())
+ aRetRange[nProp] = m_xStyleData->getPropertyValue(rPropertyNames[nProp]);
+ else
+ aRetRange[nProp] = *pAny;
+ }
+ return aRet;
+ }
+ const SfxItemPropertySet* pPropSet = aSwMapProvider.GetPropertySet(PROPERTY_MAP_PAGE_STYLE);
+ const SfxItemPropertyMap& rMap = pPropSet->getPropertyMap();
+ SwStyleBase_Impl aBase(*GetDoc(), GetStyleName(), &GetDoc()->GetDfltFrameFormat()->GetAttrSet()); // add pDfltFrameFormat as parent
+ SfxStyleSheetBase* pBase = GetStyleSheetBase();
+ if(!pBase)
+ throw uno::RuntimeException();
+ for(sal_Int32 nProp = 0; nProp < nLength; ++nProp)
+ {
+ const OUString& rPropName = rPropertyNames[nProp];
+ const SfxItemPropertyMapEntry* pEntry = rMap.getByName(rPropName);
+
+ if (!pEntry)
+ throw beans::UnknownPropertyException("Unknown property: " + rPropName, getXWeak() );
+ const bool bHeader(rPropName.startsWith("Header"));
+ const bool bFooter(rPropName.startsWith("Footer"));
+ const bool bFirstIsShared(rPropName == UNO_NAME_FIRST_IS_SHARED);
+ if(bHeader || bFooter || bFirstIsShared)
+ {
+ switch(pEntry->nWID)
+ {
+ case SID_ATTR_PAGE_ON:
+ case RES_BACKGROUND:
+ case RES_BOX:
+ case RES_LR_SPACE:
+ case RES_SHADOW:
+ case RES_UL_SPACE:
+ case SID_ATTR_PAGE_DYNAMIC:
+ case SID_ATTR_PAGE_SHARED:
+ case SID_ATTR_PAGE_SHARED_FIRST:
+ case SID_ATTR_PAGE_SIZE:
+ case RES_HEADER_FOOTER_EAT_SPACING:
+ {
+ // slot is a Header/Footer slot
+ rtl::Reference< SwDocStyleSheet > xStyle( new SwDocStyleSheet( *static_cast<SwDocStyleSheet*>(pBase) ) );
+ const SfxItemSet& rSet = xStyle->GetItemSet();
+ const SvxSetItem* pSetItem;
+
+ if (lcl_GetHeaderFooterItem(rSet, rPropName, bFooter, pSetItem))
+ {
+ // get from SfxItemSet of the corresponding SfxSetItem
+ const SfxItemSet& rSetSet = pSetItem->GetItemSet();
+ {
+ SwStyleBase_Impl::ItemSetOverrider o(aBase, &const_cast< SfxItemSet& >(rSetSet));
+ aRetRange[nProp] = GetStyleProperty_Impl(*pEntry, *pPropSet, aBase);
+ }
+ }
+ else if(pEntry->nWID == SID_ATTR_PAGE_ON)
+ {
+ // header/footer is not available, thus off. Default is <false>, though
+ aRetRange[nProp] <<= false;
+ }
+ }
+ continue;
+ case XATTR_FILLBMP_SIZELOG:
+ case XATTR_FILLBMP_TILEOFFSETX:
+ case XATTR_FILLBMP_TILEOFFSETY:
+ case XATTR_FILLBMP_POSOFFSETX:
+ case XATTR_FILLBMP_POSOFFSETY:
+ case XATTR_FILLBMP_POS:
+ case XATTR_FILLBMP_SIZEX:
+ case XATTR_FILLBMP_SIZEY:
+ case XATTR_FILLBMP_STRETCH:
+ case XATTR_FILLBMP_TILE:
+ case OWN_ATTR_FILLBMP_MODE:
+ case XATTR_FILLCOLOR:
+ case XATTR_FILLBACKGROUND:
+ case XATTR_FILLBITMAP:
+ case XATTR_GRADIENTSTEPCOUNT:
+ case XATTR_FILLGRADIENT:
+ case XATTR_FILLHATCH:
+ case XATTR_FILLSTYLE:
+ case XATTR_FILLTRANSPARENCE:
+ case XATTR_FILLFLOATTRANSPARENCE:
+ case XATTR_SECONDARYFILLCOLOR:
+ if(bFirstIsShared) // only special handling for headers/footers here
+ break;
+ {
+ rtl::Reference< SwDocStyleSheet > xStyle( new SwDocStyleSheet( *static_cast<SwDocStyleSheet*>(pBase) ) );
+ const SfxItemSet& rSet = xStyle->GetItemSet();
+ const SvxSetItem* pSetItem =
+ rSet.GetItemIfSet(bFooter ? SID_ATTR_PAGE_FOOTERSET : SID_ATTR_PAGE_HEADERSET, false);
+ if(pSetItem)
+ {
+ // set at SfxItemSet of the corresponding SfxSetItem
+ const SfxItemSet& rSetSet = pSetItem->GetItemSet();
+ {
+ SwStyleBase_Impl::ItemSetOverrider o(aBase, &const_cast<SfxItemSet&>(rSetSet));
+ aRetRange[nProp] = GetStyleProperty_Impl(*pEntry, *pPropSet, aBase);
+ }
+ }
+ }
+ continue;
+ default: ;
+ }
+ }
+ switch(pEntry->nWID)
+ {
+ // these slots are exclusive to Header/Footer, thus this is an error
+ case SID_ATTR_PAGE_DYNAMIC:
+ case SID_ATTR_PAGE_SHARED:
+ case SID_ATTR_PAGE_SHARED_FIRST:
+ case SID_ATTR_PAGE_ON:
+ case RES_HEADER_FOOTER_EAT_SPACING:
+ throw beans::UnknownPropertyException( "Unknown property: " + rPropName, getXWeak() );
+ case FN_UNO_HEADER:
+ case FN_UNO_HEADER_LEFT:
+ case FN_UNO_HEADER_FIRST:
+ case FN_UNO_HEADER_RIGHT:
+ case FN_UNO_FOOTER:
+ case FN_UNO_FOOTER_LEFT:
+ case FN_UNO_FOOTER_FIRST:
+ case FN_UNO_FOOTER_RIGHT:
+ {
+ bool bLeft(false);
+ bool bFirst(false);
+ sal_uInt16 nRes = 0;
+ switch(pEntry->nWID)
+ {
+ case FN_UNO_HEADER: nRes = RES_HEADER; break;
+ case FN_UNO_HEADER_LEFT: nRes = RES_HEADER; bLeft = true; break;
+ case FN_UNO_HEADER_FIRST: nRes = RES_HEADER; bFirst = true; break;
+ case FN_UNO_HEADER_RIGHT: nRes = RES_HEADER; break;
+ case FN_UNO_FOOTER: nRes = RES_FOOTER; break;
+ case FN_UNO_FOOTER_LEFT: nRes = RES_FOOTER; bLeft = true; break;
+ case FN_UNO_FOOTER_FIRST: nRes = RES_FOOTER; bFirst = true; break;
+ case FN_UNO_FOOTER_RIGHT: nRes = RES_FOOTER; break;
+ default: ;
+ }
+
+ const SwPageDesc* pDesc = aBase.GetOldPageDesc();
+ assert(pDesc);
+ const SwFrameFormat* pFrameFormat = nullptr;
+ bool bShare = (nRes == RES_HEADER && pDesc->IsHeaderShared()) || (nRes == RES_FOOTER && pDesc->IsFooterShared());
+ bool bShareFirst = pDesc->IsFirstShared();
+ // TextLeft returns the left content if there is one,
+ // Text and TextRight return the master content.
+ // TextRight does the same as Text and is for
+ // compatibility only.
+ if(bLeft && !bShare)
+ pFrameFormat = &pDesc->GetLeft();
+ else if(bFirst && !bShareFirst)
+ {
+ pFrameFormat = &pDesc->GetFirstMaster();
+ // no need to make GetFirstLeft() accessible
+ // since it is always shared
+ }
+ else
+ pFrameFormat = &pDesc->GetMaster();
+ const uno::Reference<text::XText> xRet = lcl_makeHeaderFooter(nRes, nRes == RES_HEADER, pFrameFormat);
+ if (xRet.is())
+ aRetRange[nProp] <<= xRet;
+ }
+ break;
+ case FN_PARAM_FTN_INFO:
+ {
+ rtl::Reference<SwDocStyleSheet> xStyle(new SwDocStyleSheet(*static_cast<SwDocStyleSheet*>(pBase)));
+ const SfxItemSet& rSet = xStyle->GetItemSet();
+ const SfxPoolItem& rItem = rSet.Get(FN_PARAM_FTN_INFO);
+ rItem.QueryValue(aRetRange[nProp], pEntry->nMemberId);
+ }
+ break;
+ default:
+ aRetRange[nProp] = GetStyleProperty_Impl(*pEntry, *pPropSet, aBase);
+ }
+ }
+ return aRet;
+}
+
+uno::Sequence<uno::Any> SwXPageStyle::getPropertyValues(const uno::Sequence<OUString>& rPropertyNames)
+{
+ SolarMutexGuard aGuard;
+ uno::Sequence<uno::Any> aValues;
+
+ // workaround for bad designed API
+ try
+ {
+ aValues = GetPropertyValues_Impl(rPropertyNames);
+ }
+ catch(beans::UnknownPropertyException &)
+ {
+ css::uno::Any anyEx = cppu::getCaughtException();
+ throw lang::WrappedTargetRuntimeException("Unknown property exception caught",
+ getXWeak(), anyEx );
+ }
+ catch(lang::WrappedTargetException &)
+ {
+ css::uno::Any anyEx = cppu::getCaughtException();
+ throw lang::WrappedTargetRuntimeException("WrappedTargetException caught",
+ getXWeak(), anyEx );
+ }
+
+ return aValues;
+}
+
+uno::Any SwXPageStyle::getPropertyValue(const OUString& rPropertyName)
+{
+ SolarMutexGuard aGuard;
+ const uno::Sequence<OUString> aProperties(&rPropertyName, 1);
+ return GetPropertyValues_Impl(aProperties)[0];
+}
+
+void SwXPageStyle::setPropertyValue(const OUString& rPropertyName, const uno::Any& rValue)
+{
+ SolarMutexGuard aGuard;
+ const uno::Sequence<OUString> aProperties(&rPropertyName, 1);
+ const uno::Sequence<uno::Any> aValues(&rValue, 1);
+
+ // Trick: if the Domain Mapper changes the props of shared header/footer,
+ // store the old ones in time for later use.
+ const bool bIsHeader = rPropertyName == UNO_NAME_HEADER_IS_SHARED;
+ const bool bIsFooter = rPropertyName == UNO_NAME_FOOTER_IS_SHARED;
+ if ((bIsFooter || bIsHeader) && rValue == uno::Any(true))
+ {
+ // Find the matching page descriptor
+ for (size_t i = 0; i < GetDoc()->GetPageDescCnt(); i++)
+ {
+ auto pPageDesc = &GetDoc()->GetPageDesc(i);
+ // If we have the right page descriptor stash the necessary formats in import time.
+ if (pPageDesc->GetName() == GetStyleName())
+ {
+ auto pLeftHeader = pPageDesc->GetLeft().GetHeader().GetHeaderFormat();
+ if (bIsHeader && pLeftHeader)
+ {
+ pPageDesc->StashFrameFormat(pPageDesc->GetLeft(), true, true, false);
+ pPageDesc->StashFrameFormat(pPageDesc->GetFirstMaster(), true, false, true);
+ pPageDesc->StashFrameFormat(pPageDesc->GetFirstLeft(), true, true, true);
+ }
+ auto pLeftFooter = pPageDesc->GetLeft().GetFooter().GetFooterFormat();
+ if (bIsFooter && pLeftFooter)
+ {
+ pPageDesc->StashFrameFormat(pPageDesc->GetLeft(), false, true, false);
+ pPageDesc->StashFrameFormat(pPageDesc->GetFirstMaster(), false, false, true);
+ pPageDesc->StashFrameFormat(pPageDesc->GetFirstLeft(), false, true, true);
+ }
+ }
+ }
+ }
+ // And set the props... as we did it before.
+ SetPropertyValues_Impl(aProperties, aValues);
+}
+
+SwXFrameStyle::SwXFrameStyle(SwDoc *pDoc)
+ : SwXFrameStyle_Base(pDoc, SfxStyleFamily::Frame, false)
+{ }
+
+void SwXFrameStyle::SetItem(sal_uInt16 eAtr, const SfxPoolItem& rItem)
+{
+ assert(eAtr >= RES_FRMATR_BEGIN && eAtr < RES_FRMATR_END);
+ SfxStyleSheetBase* pBase = GetStyleSheetBase();
+ if(!pBase)
+ return;
+ rtl::Reference<SwDocStyleSheet> xStyle(new SwDocStyleSheet(*static_cast<SwDocStyleSheet*>(pBase)));
+ SfxItemSet& rStyleSet = xStyle->GetItemSet();
+ SfxItemSet aSet(*rStyleSet.GetPool(), sal_uInt16(eAtr), sal_uInt16(eAtr));
+ aSet.Put(rItem);
+ xStyle->SetItemSet(aSet);
+}
+
+const SfxPoolItem* SwXFrameStyle::GetItem(sal_uInt16 eAtr)
+{
+ assert(eAtr >= RES_FRMATR_BEGIN && eAtr < RES_FRMATR_END);
+ SfxStyleSheetBase* pBase = GetStyleSheetBase();
+ if(!pBase)
+ return nullptr;
+ rtl::Reference<SwDocStyleSheet> xStyle(new SwDocStyleSheet(*static_cast<SwDocStyleSheet*>(pBase)));
+ return &xStyle->GetItemSet().Get(eAtr);
+}
+
+uno::Reference<container::XNameReplace> SwXFrameStyle::getEvents()
+{
+ return new SwFrameStyleEventDescriptor(*this);
+}
+
+// Already implemented autostyle families: 3
+#define AUTOSTYLE_FAMILY_COUNT 3
+const IStyleAccess::SwAutoStyleFamily aAutoStyleByIndex[] =
+{
+ IStyleAccess::AUTO_STYLE_CHAR,
+ IStyleAccess::AUTO_STYLE_RUBY,
+ IStyleAccess::AUTO_STYLE_PARA
+};
+
+class SwAutoStylesEnumImpl
+{
+ std::vector<std::shared_ptr<SfxItemSet>> mAutoStyles;
+ std::vector<std::shared_ptr<SfxItemSet>>::iterator m_aIter;
+ SwDoc& m_rDoc;
+ IStyleAccess::SwAutoStyleFamily m_eFamily;
+public:
+ SwAutoStylesEnumImpl( SwDoc& rInitDoc, IStyleAccess::SwAutoStyleFamily eFam );
+ bool hasMoreElements() { return m_aIter != mAutoStyles.end(); }
+ std::shared_ptr<SfxItemSet> const & nextElement() { return *(m_aIter++); }
+ IStyleAccess::SwAutoStyleFamily getFamily() const { return m_eFamily; }
+ SwDoc& getDoc() const { return m_rDoc; }
+};
+
+SwXAutoStyles::SwXAutoStyles(SwDocShell& rDocShell) :
+ SwUnoCollection(rDocShell.GetDoc()), m_pDocShell( &rDocShell )
+{
+}
+
+SwXAutoStyles::~SwXAutoStyles()
+{
+}
+
+sal_Int32 SwXAutoStyles::getCount()
+{
+ return AUTOSTYLE_FAMILY_COUNT;
+}
+
+uno::Any SwXAutoStyles::getByIndex(sal_Int32 nIndex)
+{
+ SolarMutexGuard aGuard;
+ uno::Any aRet;
+ if(nIndex < 0 || nIndex >= AUTOSTYLE_FAMILY_COUNT)
+ throw lang::IndexOutOfBoundsException();
+ if(!IsValid())
+ throw uno::RuntimeException();
+
+ uno::Reference< style::XAutoStyleFamily > aRef;
+ IStyleAccess::SwAutoStyleFamily nType = aAutoStyleByIndex[nIndex];
+ switch( nType )
+ {
+ case IStyleAccess::AUTO_STYLE_CHAR:
+ {
+ if(!m_xAutoCharStyles.is())
+ m_xAutoCharStyles = new SwXAutoStyleFamily(m_pDocShell, nType);
+ aRef = m_xAutoCharStyles;
+ }
+ break;
+ case IStyleAccess::AUTO_STYLE_RUBY:
+ {
+ if(!m_xAutoRubyStyles.is())
+ m_xAutoRubyStyles = new SwXAutoStyleFamily(m_pDocShell, nType );
+ aRef = m_xAutoRubyStyles;
+ }
+ break;
+ case IStyleAccess::AUTO_STYLE_PARA:
+ {
+ if(!m_xAutoParaStyles.is())
+ m_xAutoParaStyles = new SwXAutoStyleFamily(m_pDocShell, nType );
+ aRef = m_xAutoParaStyles;
+ }
+ break;
+
+ default:
+ ;
+ }
+ aRet <<= aRef;
+
+ return aRet;
+}
+
+uno::Type SwXAutoStyles::getElementType( )
+{
+ return cppu::UnoType<style::XAutoStyleFamily>::get();
+}
+
+sal_Bool SwXAutoStyles::hasElements( )
+{
+ return true;
+}
+
+uno::Any SwXAutoStyles::getByName(const OUString& Name)
+{
+ uno::Any aRet;
+ if(Name == "CharacterStyles")
+ aRet = getByIndex(0);
+ else if(Name == "RubyStyles")
+ aRet = getByIndex(1);
+ else if(Name == "ParagraphStyles")
+ aRet = getByIndex(2);
+ else
+ throw container::NoSuchElementException();
+ return aRet;
+}
+
+uno::Sequence< OUString > SwXAutoStyles::getElementNames()
+{
+ uno::Sequence< OUString > aNames(AUTOSTYLE_FAMILY_COUNT);
+ OUString* pNames = aNames.getArray();
+ pNames[0] = "CharacterStyles";
+ pNames[1] = "RubyStyles";
+ pNames[2] = "ParagraphStyles";
+ return aNames;
+}
+
+sal_Bool SwXAutoStyles::hasByName(const OUString& Name)
+{
+ if( Name == "CharacterStyles" ||
+ Name == "RubyStyles" ||
+ Name == "ParagraphStyles" )
+ return true;
+ else
+ return false;
+}
+
+SwXAutoStyleFamily::SwXAutoStyleFamily(SwDocShell* pDocSh, IStyleAccess::SwAutoStyleFamily nFamily) :
+ m_pDocShell( pDocSh ), m_eFamily(nFamily)
+{
+ // Register ourselves as a listener to the document (via the page descriptor)
+ StartListening(pDocSh->GetDoc()->getIDocumentStylePoolAccess().GetPageDescFromPool(RES_POOLPAGE_STANDARD)->GetNotifier());
+}
+
+SwXAutoStyleFamily::~SwXAutoStyleFamily()
+{
+}
+
+void SwXAutoStyleFamily::Notify(const SfxHint& rHint)
+{
+ if(rHint.GetId() == SfxHintId::Dying)
+ m_pDocShell = nullptr;
+}
+
+std::shared_ptr<SfxItemSet>
+PropValuesToAutoStyleItemSet(SwDoc& rDoc, IStyleAccess::SwAutoStyleFamily eFamily,
+ const uno::Sequence<beans::PropertyValue>& Values, SwAttrSet& aSet)
+{
+ const SfxItemPropertySet* pPropSet = nullptr;
+ switch( eFamily )
+ {
+ case IStyleAccess::AUTO_STYLE_CHAR:
+ {
+ pPropSet = aSwMapProvider.GetPropertySet(PROPERTY_MAP_CHAR_AUTO_STYLE);
+ break;
+ }
+ case IStyleAccess::AUTO_STYLE_RUBY:
+ {
+ pPropSet = aSwMapProvider.GetPropertySet(PROPERTY_MAP_RUBY_AUTO_STYLE);
+ break;
+ }
+ case IStyleAccess::AUTO_STYLE_PARA:
+ {
+ pPropSet = aSwMapProvider.GetPropertySet(PROPERTY_MAP_PARA_AUTO_STYLE);
+ break;
+ }
+ default: ;
+ }
+
+ if( !pPropSet)
+ throw uno::RuntimeException();
+
+ const bool bTakeCareOfDrawingLayerFillStyle(IStyleAccess::AUTO_STYLE_PARA == eFamily);
+
+ if(!bTakeCareOfDrawingLayerFillStyle)
+ {
+ for( const beans::PropertyValue& rValue : Values )
+ {
+ try
+ {
+ pPropSet->setPropertyValue( rValue.Name, rValue.Value, aSet );
+ }
+ catch (const beans::UnknownPropertyException &)
+ {
+ OSL_FAIL( "Unknown property" );
+ }
+ catch (const lang::IllegalArgumentException &)
+ {
+ OSL_FAIL( "Illegal argument" );
+ }
+ }
+ }
+ else
+ {
+ // set parent to ItemSet to ensure XFILL_NONE as XFillStyleItem
+ // to make cases in RES_BACKGROUND work correct; target *is* a style
+ // where this is the case
+ aSet.SetParent(&rDoc.GetDfltTextFormatColl()->GetAttrSet());
+
+ // here the used DrawingLayer FillStyles are imported when family is
+ // equal to IStyleAccess::AUTO_STYLE_PARA, thus we will need to serve the
+ // used slots functionality here to do this correctly
+ const SfxItemPropertyMap& rMap = pPropSet->getPropertyMap();
+
+ for( const beans::PropertyValue& rValue : Values )
+ {
+ const OUString& rPropName = rValue.Name;
+ uno::Any aValue(rValue.Value);
+ const SfxItemPropertyMapEntry* pEntry = rMap.getByName(rPropName);
+
+ if (!pEntry)
+ {
+ SAL_WARN("sw.core", "SwXAutoStyleFamily::insertStyle: Unknown property: " << rPropName);
+ continue;
+ }
+
+ const sal_uInt8 nMemberId(pEntry->nMemberId);
+ bool bDone(false);
+
+ // check for needed metric translation
+ if(pEntry->nMoreFlags & PropertyMoreFlags::METRIC_ITEM)
+ {
+ bool bDoIt(true);
+
+ if(XATTR_FILLBMP_SIZEX == pEntry->nWID || XATTR_FILLBMP_SIZEY == pEntry->nWID)
+ {
+ // exception: If these ItemTypes are used, do not convert when these are negative
+ // since this means they are intended as percent values
+ sal_Int32 nValue = 0;
+
+ if(aValue >>= nValue)
+ {
+ bDoIt = nValue > 0;
+ }
+ }
+
+ if(bDoIt)
+ {
+ const SfxItemPool& rPool = rDoc.GetAttrPool();
+ const MapUnit eMapUnit(rPool.GetMetric(pEntry->nWID));
+
+ if(eMapUnit != MapUnit::Map100thMM)
+ {
+ SvxUnoConvertFromMM(eMapUnit, aValue);
+ }
+ }
+ }
+
+ switch(pEntry->nWID)
+ {
+ case XATTR_FILLGRADIENT:
+ case XATTR_FILLHATCH:
+ case XATTR_FILLBITMAP:
+ case XATTR_FILLFLOATTRANSPARENCE:
+ // not yet needed; activate when LineStyle support may be added
+ // case XATTR_LINESTART:
+ // case XATTR_LINEEND:
+ // case XATTR_LINEDASH:
+ {
+ if(MID_NAME == nMemberId)
+ {
+ // add set commands for FillName items
+ OUString aTempName;
+
+ if(!(aValue >>= aTempName))
+ {
+ throw lang::IllegalArgumentException();
+ }
+
+ SvxShape::SetFillAttribute(pEntry->nWID, aTempName, aSet);
+ bDone = true;
+ }
+ else if (MID_BITMAP == nMemberId)
+ {
+ if(XATTR_FILLBITMAP == pEntry->nWID)
+ {
+ Graphic aNullGraphic;
+ XFillBitmapItem aXFillBitmapItem(std::move(aNullGraphic));
+
+ aXFillBitmapItem.PutValue(aValue, nMemberId);
+ aSet.Put(aXFillBitmapItem);
+ bDone = true;
+ }
+ }
+
+ break;
+ }
+ case RES_BACKGROUND:
+ {
+ const std::unique_ptr<SvxBrushItem> aOriginalBrushItem(getSvxBrushItemFromSourceSet(aSet, RES_BACKGROUND, true, rDoc.IsInXMLImport()));
+ std::unique_ptr<SvxBrushItem> aChangedBrushItem(aOriginalBrushItem->Clone());
+
+ aChangedBrushItem->PutValue(aValue, nMemberId);
+
+ if(*aChangedBrushItem != *aOriginalBrushItem)
+ {
+ setSvxBrushItemAsFillAttributesToTargetSet(*aChangedBrushItem, aSet);
+ }
+
+ bDone = true;
+ break;
+ }
+ case OWN_ATTR_FILLBMP_MODE:
+ {
+ drawing::BitmapMode eMode;
+
+ if(!(aValue >>= eMode))
+ {
+ sal_Int32 nMode = 0;
+
+ if(!(aValue >>= nMode))
+ {
+ throw lang::IllegalArgumentException();
+ }
+
+ eMode = static_cast<drawing::BitmapMode>(nMode);
+ }
+
+ aSet.Put(XFillBmpStretchItem(drawing::BitmapMode_STRETCH == eMode));
+ aSet.Put(XFillBmpTileItem(drawing::BitmapMode_REPEAT == eMode));
+
+ bDone = true;
+ break;
+ }
+ default: break;
+ }
+
+ if(!bDone)
+ {
+ try
+ {
+ pPropSet->setPropertyValue( rPropName, aValue, aSet );
+ }
+ catch (const beans::UnknownPropertyException &)
+ {
+ OSL_FAIL( "Unknown property" );
+ }
+ catch (const lang::IllegalArgumentException &)
+ {
+ OSL_FAIL( "Illegal argument" );
+ }
+ }
+ }
+
+ // clear parent again
+ aSet.SetParent(nullptr);
+ }
+
+ // need to ensure uniqueness of evtl. added NameOrIndex items
+ // currently in principle only needed when bTakeCareOfDrawingLayerFillStyle,
+ // but does not hurt and is easily forgotten later eventually, so keep it
+ // as common case
+ rDoc.CheckForUniqueItemForLineFillNameOrIndex(aSet);
+
+ return rDoc.GetIStyleAccess().cacheAutomaticStyle(aSet, eFamily);
+}
+
+uno::Reference< style::XAutoStyle > SwXAutoStyleFamily::insertStyle(
+ const uno::Sequence< beans::PropertyValue >& Values )
+{
+ if (!m_pDocShell)
+ {
+ throw uno::RuntimeException();
+ }
+
+ WhichRangesContainer pRange;
+ switch (m_eFamily)
+ {
+ case IStyleAccess::AUTO_STYLE_CHAR:
+ {
+ pRange = aCharAutoFormatSetRange;
+ break;
+ }
+ case IStyleAccess::AUTO_STYLE_RUBY:
+ {
+ pRange = WhichRangesContainer(RES_TXTATR_CJK_RUBY, RES_TXTATR_CJK_RUBY);
+ break;
+ }
+ case IStyleAccess::AUTO_STYLE_PARA:
+ {
+ pRange = aTextNodeSetRange; // checked, already added support for [XATTR_FILL_FIRST, XATTR_FILL_LAST]
+ break;
+ }
+ default:
+ throw uno::RuntimeException();
+ }
+
+ SwAttrSet aEmptySet(m_pDocShell->GetDoc()->GetAttrPool(), pRange);
+ auto pSet = PropValuesToAutoStyleItemSet(*m_pDocShell->GetDoc(), m_eFamily, Values, aEmptySet);
+
+ uno::Reference<style::XAutoStyle> xRet = new SwXAutoStyle(m_pDocShell->GetDoc(), pSet, m_eFamily);
+
+ return xRet;
+}
+
+uno::Reference< container::XEnumeration > SwXAutoStyleFamily::createEnumeration( )
+{
+ if( !m_pDocShell )
+ throw uno::RuntimeException();
+ return uno::Reference< container::XEnumeration >
+ (new SwXAutoStylesEnumerator( *m_pDocShell->GetDoc(), m_eFamily ));
+}
+
+uno::Type SwXAutoStyleFamily::getElementType( )
+{
+ return cppu::UnoType<style::XAutoStyle>::get();
+}
+
+sal_Bool SwXAutoStyleFamily::hasElements( )
+{
+ return false;
+}
+
+SwAutoStylesEnumImpl::SwAutoStylesEnumImpl( SwDoc& rInitDoc, IStyleAccess::SwAutoStyleFamily eFam )
+: m_rDoc( rInitDoc ), m_eFamily( eFam )
+{
+ // special case for ruby auto styles:
+ if ( IStyleAccess::AUTO_STYLE_RUBY == eFam )
+ {
+ std::set< std::pair< sal_uInt16, text::RubyAdjust > > aRubyMap;
+ SwAttrPool& rAttrPool = m_rDoc.GetAttrPool();
+
+ // do this in two phases otherwise we invalidate the iterators when we insert into the pool
+ std::vector<const SwFormatRuby*> vRubyItems;
+ for (const SfxPoolItem* pItem : rAttrPool.GetItemSurrogates(RES_TXTATR_CJK_RUBY))
+ {
+ auto pRubyItem = dynamic_cast<const SwFormatRuby*>(pItem);
+ if ( pRubyItem && pRubyItem->GetTextRuby() )
+ vRubyItems.push_back(pRubyItem);
+ }
+ for (const SwFormatRuby* pRubyItem : vRubyItems)
+ {
+ std::pair< sal_uInt16, text::RubyAdjust > aPair( pRubyItem->GetPosition(), pRubyItem->GetAdjustment() );
+ if ( aRubyMap.insert( aPair ).second )
+ {
+ auto pItemSet = std::make_shared<SfxItemSetFixed<RES_TXTATR_CJK_RUBY, RES_TXTATR_CJK_RUBY>>( rAttrPool );
+ pItemSet->Put( *pRubyItem );
+ mAutoStyles.push_back( pItemSet );
+ }
+ }
+ }
+ else
+ {
+ m_rDoc.GetIStyleAccess().getAllStyles( mAutoStyles, m_eFamily );
+ }
+
+ m_aIter = mAutoStyles.begin();
+}
+
+SwXAutoStylesEnumerator::SwXAutoStylesEnumerator( SwDoc& rDoc, IStyleAccess::SwAutoStyleFamily eFam )
+: m_pImpl( new SwAutoStylesEnumImpl( rDoc, eFam ) )
+{
+ // Register ourselves as a listener to the document (via the page descriptor)
+ StartListening(rDoc.getIDocumentStylePoolAccess().GetPageDescFromPool(RES_POOLPAGE_STANDARD)->GetNotifier());
+}
+
+SwXAutoStylesEnumerator::~SwXAutoStylesEnumerator()
+{
+}
+
+void SwXAutoStylesEnumerator::Notify( const SfxHint& rHint)
+{
+ if(rHint.GetId() == SfxHintId::Dying)
+ m_pImpl.reset();
+}
+
+sal_Bool SwXAutoStylesEnumerator::hasMoreElements( )
+{
+ if( !m_pImpl )
+ throw uno::RuntimeException();
+ return m_pImpl->hasMoreElements();
+}
+
+uno::Any SwXAutoStylesEnumerator::nextElement( )
+{
+ if( !m_pImpl )
+ throw uno::RuntimeException();
+ uno::Any aRet;
+ if( m_pImpl->hasMoreElements() )
+ {
+ std::shared_ptr<SfxItemSet> pNextSet = m_pImpl->nextElement();
+ uno::Reference< style::XAutoStyle > xAutoStyle = new SwXAutoStyle(&m_pImpl->getDoc(),
+ pNextSet, m_pImpl->getFamily());
+ aRet <<= xAutoStyle;
+ }
+ return aRet;
+}
+
+// SwXAutoStyle with the family IStyleAccess::AUTO_STYLE_PARA (or
+// PROPERTY_MAP_PARA_AUTO_STYLE) now uses DrawingLayer FillStyles to allow
+// unified paragraph background fill, thus the UNO API implementation has to
+// support the needed slots for these. This seems to be used only for reading
+// (no setPropertyValue implementation here), so maybe specialized for saving
+// the Writer Doc to ODF
+
+SwXAutoStyle::SwXAutoStyle(
+ SwDoc* pDoc,
+ std::shared_ptr<SfxItemSet> pInitSet,
+ IStyleAccess::SwAutoStyleFamily eFam)
+: mpSet(std::move(pInitSet)),
+ meFamily(eFam),
+ mrDoc(*pDoc)
+{
+ // Register ourselves as a listener to the document (via the page descriptor)
+ //StartListening(mrDoc.getIDocumentStylePoolAccess().GetPageDescFromPool(RES_POOLPAGE_STANDARD)->GetNotifier());
+}
+
+SwXAutoStyle::~SwXAutoStyle()
+{
+}
+
+void SwXAutoStyle::Notify(const SfxHint& rHint)
+{
+ if(rHint.GetId() == SfxHintId::Dying)
+ mpSet.reset();
+}
+
+uno::Reference< beans::XPropertySetInfo > SwXAutoStyle::getPropertySetInfo( )
+{
+ uno::Reference< beans::XPropertySetInfo > xRet;
+ switch( meFamily )
+ {
+ case IStyleAccess::AUTO_STYLE_CHAR:
+ {
+ static const auto xCharRef = aSwMapProvider.GetPropertySet(PROPERTY_MAP_CHAR_AUTO_STYLE)->getPropertySetInfo();
+ xRet = xCharRef;
+ }
+ break;
+ case IStyleAccess::AUTO_STYLE_RUBY:
+ {
+ static const auto xRubyRef = aSwMapProvider.GetPropertySet(PROPERTY_MAP_RUBY_AUTO_STYLE)->getPropertySetInfo();
+ xRet = xRubyRef;
+ }
+ break;
+ case IStyleAccess::AUTO_STYLE_PARA:
+ {
+ static const auto xParaRef = aSwMapProvider.GetPropertySet(PROPERTY_MAP_PARA_AUTO_STYLE)->getPropertySetInfo();
+ xRet = xParaRef;
+ }
+ break;
+
+ default:
+ ;
+ }
+
+ return xRet;
+}
+
+void SwXAutoStyle::setPropertyValue( const OUString& /*rPropertyName*/, const uno::Any& /*rValue*/ )
+{
+}
+
+uno::Any SwXAutoStyle::getPropertyValue( const OUString& rPropertyName )
+{
+ SolarMutexGuard aGuard;
+ const uno::Sequence<OUString> aProperties(&rPropertyName, 1);
+ return GetPropertyValues_Impl(aProperties).getConstArray()[0];
+}
+
+void SwXAutoStyle::addPropertyChangeListener( const OUString& /*aPropertyName*/,
+ const uno::Reference< beans::XPropertyChangeListener >& /*xListener*/ )
+{
+}
+
+void SwXAutoStyle::removePropertyChangeListener( const OUString& /*aPropertyName*/,
+ const uno::Reference< beans::XPropertyChangeListener >& /*aListener*/ )
+{
+}
+
+void SwXAutoStyle::addVetoableChangeListener( const OUString& /*PropertyName*/,
+ const uno::Reference< beans::XVetoableChangeListener >& /*aListener*/ )
+{
+}
+
+void SwXAutoStyle::removeVetoableChangeListener( const OUString& /*PropertyName*/,
+ const uno::Reference< beans::XVetoableChangeListener >& /*aListener*/ )
+{
+}
+
+void SwXAutoStyle::setPropertyValues(
+ const uno::Sequence< OUString >& /*aPropertyNames*/,
+ const uno::Sequence< uno::Any >& /*aValues*/ )
+{
+}
+
+uno::Sequence< uno::Any > SwXAutoStyle::GetPropertyValues_Impl(
+ const uno::Sequence< OUString > & rPropertyNames )
+{
+ if( !mpSet )
+ {
+ throw uno::RuntimeException();
+ }
+
+ // query_item
+ sal_uInt16 nPropSetId = PROPERTY_MAP_CHAR_AUTO_STYLE;
+ switch(meFamily)
+ {
+ case IStyleAccess::AUTO_STYLE_CHAR : nPropSetId = PROPERTY_MAP_CHAR_AUTO_STYLE; break;
+ case IStyleAccess::AUTO_STYLE_RUBY : nPropSetId = PROPERTY_MAP_RUBY_AUTO_STYLE; break;
+ case IStyleAccess::AUTO_STYLE_PARA : nPropSetId = PROPERTY_MAP_PARA_AUTO_STYLE; break;
+ default: ;
+ }
+
+ const SfxItemPropertySet* pPropSet = aSwMapProvider.GetPropertySet(nPropSetId);
+ const SfxItemPropertyMap& rMap = pPropSet->getPropertyMap();
+ const OUString* pNames = rPropertyNames.getConstArray();
+
+ const sal_Int32 nLen(rPropertyNames.getLength());
+ uno::Sequence< uno::Any > aRet( nLen );
+ uno::Any* pValues = aRet.getArray();
+ const bool bTakeCareOfDrawingLayerFillStyle(IStyleAccess::AUTO_STYLE_PARA == meFamily);
+
+ for( sal_Int32 i = 0; i < nLen; ++i )
+ {
+ const OUString sPropName = pNames[i];
+ const SfxItemPropertyMapEntry* pEntry = rMap.getByName(sPropName);
+ if(!pEntry)
+ {
+ throw beans::UnknownPropertyException("Unknown property: " + sPropName, getXWeak() );
+ }
+
+ uno::Any aTarget;
+ bool bDone(false);
+
+ if ( RES_TXTATR_AUTOFMT == pEntry->nWID || RES_AUTO_STYLE == pEntry->nWID )
+ {
+ OUString sName(StylePool::nameOf( mpSet ));
+ aTarget <<= sName;
+ bDone = true;
+ }
+ else if(bTakeCareOfDrawingLayerFillStyle)
+ {
+ // add support for DrawingLayer FillStyle slots
+ switch(pEntry->nWID)
+ {
+ case RES_BACKGROUND:
+ {
+ const std::unique_ptr<SvxBrushItem> aOriginalBrushItem(getSvxBrushItemFromSourceSet(*mpSet, RES_BACKGROUND));
+
+ if(!aOriginalBrushItem->QueryValue(aTarget, pEntry->nMemberId))
+ {
+ OSL_ENSURE(false, "Error getting attribute from RES_BACKGROUND (!)");
+ }
+
+ bDone = true;
+ break;
+ }
+ case OWN_ATTR_FILLBMP_MODE:
+ {
+ if (mpSet->Get(XATTR_FILLBMP_TILE).GetValue())
+ {
+ aTarget <<= drawing::BitmapMode_REPEAT;
+ }
+ else if (mpSet->Get(XATTR_FILLBMP_STRETCH).GetValue())
+ {
+ aTarget <<= drawing::BitmapMode_STRETCH;
+ }
+ else
+ {
+ aTarget <<= drawing::BitmapMode_NO_REPEAT;
+ }
+
+ bDone = true;
+ break;
+ }
+ }
+ }
+
+ if(!bDone)
+ {
+ pPropSet->getPropertyValue( *pEntry, *mpSet, aTarget );
+ }
+
+ if(bTakeCareOfDrawingLayerFillStyle)
+ {
+ if(pEntry->aType == cppu::UnoType<sal_Int16>::get() && pEntry->aType != aTarget.getValueType())
+ {
+ // since the sfx uint16 item now exports a sal_Int32, we may have to fix this here
+ sal_Int32 nValue = 0;
+ if (aTarget >>= nValue)
+ {
+ aTarget <<= static_cast<sal_Int16>(nValue);
+ }
+ }
+
+ // check for needed metric translation
+ if(pEntry->nMoreFlags & PropertyMoreFlags::METRIC_ITEM)
+ {
+ bool bDoIt(true);
+
+ if(XATTR_FILLBMP_SIZEX == pEntry->nWID || XATTR_FILLBMP_SIZEY == pEntry->nWID)
+ {
+ // exception: If these ItemTypes are used, do not convert when these are negative
+ // since this means they are intended as percent values
+ sal_Int32 nValue = 0;
+
+ if(aTarget >>= nValue)
+ {
+ bDoIt = nValue > 0;
+ }
+ }
+
+ if(bDoIt)
+ {
+ const SfxItemPool& rPool = mrDoc.GetAttrPool();
+ const MapUnit eMapUnit(rPool.GetMetric(pEntry->nWID));
+
+ if(eMapUnit != MapUnit::Map100thMM)
+ {
+ SvxUnoConvertToMM(eMapUnit, aTarget);
+ }
+ }
+ }
+ }
+
+ // add value
+ pValues[i] = aTarget;
+ }
+
+ return aRet;
+}
+
+uno::Sequence< uno::Any > SwXAutoStyle::getPropertyValues (
+ const uno::Sequence< OUString >& rPropertyNames )
+{
+ SolarMutexGuard aGuard;
+ uno::Sequence< uno::Any > aValues;
+
+ // workaround for bad designed API
+ try
+ {
+ aValues = GetPropertyValues_Impl( rPropertyNames );
+ }
+ catch (beans::UnknownPropertyException &)
+ {
+ css::uno::Any exc = cppu::getCaughtException();
+ throw lang::WrappedTargetRuntimeException("Unknown property exception caught", getXWeak(), exc );
+ }
+ catch (lang::WrappedTargetException &)
+ {
+ css::uno::Any exc = cppu::getCaughtException();
+ throw lang::WrappedTargetRuntimeException("WrappedTargetException caught", getXWeak(), exc );
+ }
+
+ return aValues;
+}
+
+void SwXAutoStyle::addPropertiesChangeListener(
+ const uno::Sequence< OUString >& /*aPropertyNames*/,
+ const uno::Reference< beans::XPropertiesChangeListener >& /*xListener*/ )
+{
+}
+
+void SwXAutoStyle::removePropertiesChangeListener(
+ const uno::Reference< beans::XPropertiesChangeListener >& /*xListener*/ )
+{
+}
+
+void SwXAutoStyle::firePropertiesChangeEvent(
+ const uno::Sequence< OUString >& /*aPropertyNames*/,
+ const uno::Reference< beans::XPropertiesChangeListener >& /*xListener*/ )
+{
+}
+
+beans::PropertyState SwXAutoStyle::getPropertyState( const OUString& rPropertyName )
+{
+ SolarMutexGuard aGuard;
+
+ uno::Sequence< OUString > aNames { rPropertyName };
+ uno::Sequence< beans::PropertyState > aStates = getPropertyStates(aNames);
+ return aStates.getConstArray()[0];
+}
+
+void SwXAutoStyle::setPropertyToDefault( const OUString& /*PropertyName*/ )
+{
+}
+
+uno::Any SwXAutoStyle::getPropertyDefault( const OUString& rPropertyName )
+{
+ const uno::Sequence < OUString > aSequence ( &rPropertyName, 1 );
+ return getPropertyDefaults ( aSequence ).getConstArray()[0];
+}
+
+uno::Sequence< beans::PropertyState > SwXAutoStyle::getPropertyStates(
+ const uno::Sequence< OUString >& rPropertyNames )
+{
+ if (!mpSet)
+ {
+ throw uno::RuntimeException();
+ }
+
+ SolarMutexGuard aGuard;
+ uno::Sequence< beans::PropertyState > aRet(rPropertyNames.getLength());
+ beans::PropertyState* pStates = aRet.getArray();
+ const OUString* pNames = rPropertyNames.getConstArray();
+
+ sal_uInt16 nPropSetId = PROPERTY_MAP_CHAR_AUTO_STYLE;
+ switch(meFamily)
+ {
+ case IStyleAccess::AUTO_STYLE_CHAR : nPropSetId = PROPERTY_MAP_CHAR_AUTO_STYLE; break;
+ case IStyleAccess::AUTO_STYLE_RUBY : nPropSetId = PROPERTY_MAP_RUBY_AUTO_STYLE; break;
+ case IStyleAccess::AUTO_STYLE_PARA : nPropSetId = PROPERTY_MAP_PARA_AUTO_STYLE; break;
+ default: ;
+ }
+
+ const SfxItemPropertySet* pPropSet = aSwMapProvider.GetPropertySet(nPropSetId);
+ const SfxItemPropertyMap& rMap = pPropSet->getPropertyMap();
+ const bool bTakeCareOfDrawingLayerFillStyle(IStyleAccess::AUTO_STYLE_PARA == meFamily);
+
+ for(sal_Int32 i = 0; i < rPropertyNames.getLength(); i++)
+ {
+ const OUString sPropName = pNames[i];
+ const SfxItemPropertyMapEntry* pEntry = rMap.getByName(sPropName);
+ if(!pEntry)
+ {
+ throw beans::UnknownPropertyException("Unknown property: " + sPropName, getXWeak() );
+ }
+
+ bool bDone(false);
+
+ if(bTakeCareOfDrawingLayerFillStyle)
+ {
+ // DrawingLayer PropertyStyle support
+ switch(pEntry->nWID)
+ {
+ case OWN_ATTR_FILLBMP_MODE:
+ {
+ if(SfxItemState::SET == mpSet->GetItemState(XATTR_FILLBMP_STRETCH, false)
+ || SfxItemState::SET == mpSet->GetItemState(XATTR_FILLBMP_TILE, false))
+ {
+ pStates[i] = beans::PropertyState_DIRECT_VALUE;
+ }
+ else
+ {
+ pStates[i] = beans::PropertyState_AMBIGUOUS_VALUE;
+ }
+
+ bDone = true;
+ break;
+ }
+ case RES_BACKGROUND:
+ {
+ if (SWUnoHelper::needToMapFillItemsToSvxBrushItemTypes(*mpSet,
+ pEntry->nMemberId))
+ {
+ pStates[i] = beans::PropertyState_DIRECT_VALUE;
+ }
+ else
+ {
+ pStates[i] = beans::PropertyState_DEFAULT_VALUE;
+ }
+ bDone = true;
+
+ break;
+ }
+ }
+ }
+
+ if(!bDone)
+ {
+ pStates[i] = pPropSet->getPropertyState(*pEntry, *mpSet );
+ }
+ }
+
+ return aRet;
+}
+
+void SwXAutoStyle::setAllPropertiesToDefault( )
+{
+}
+
+void SwXAutoStyle::setPropertiesToDefault(
+ const uno::Sequence< OUString >& /*rPropertyNames*/ )
+{
+}
+
+uno::Sequence< uno::Any > SwXAutoStyle::getPropertyDefaults(
+ const uno::Sequence< OUString >& /*aPropertyNames*/ )
+{
+ return { };
+}
+
+uno::Sequence< beans::PropertyValue > SwXAutoStyle::getProperties()
+{
+ if( !mpSet )
+ throw uno::RuntimeException();
+ SolarMutexGuard aGuard;
+ std::vector< beans::PropertyValue > aPropertyVector;
+
+ sal_uInt16 nPropSetId = 0;
+ switch(meFamily)
+ {
+ case IStyleAccess::AUTO_STYLE_CHAR : nPropSetId = PROPERTY_MAP_CHAR_AUTO_STYLE; break;
+ case IStyleAccess::AUTO_STYLE_RUBY : nPropSetId = PROPERTY_MAP_RUBY_AUTO_STYLE; break;
+ case IStyleAccess::AUTO_STYLE_PARA : nPropSetId = PROPERTY_MAP_PARA_AUTO_STYLE; break;
+ default: ;
+ }
+
+ const SfxItemPropertySet* pPropSet = aSwMapProvider.GetPropertySet(nPropSetId);
+ const SfxItemPropertyMap &rMap = pPropSet->getPropertyMap();
+
+ SfxItemSet& rSet = *mpSet;
+ SfxItemIter aIter(rSet);
+
+ for (const SfxPoolItem* pItem = aIter.GetCurItem(); pItem; pItem = aIter.NextItem())
+ {
+ const sal_uInt16 nWID = pItem->Which();
+
+ // TODO: Optimize - and fix! the old iteration filled each WhichId
+ // only once but there are more properties than WhichIds
+ for( const auto pEntry : rMap.getPropertyEntries() )
+ {
+ if ( pEntry->nWID == nWID )
+ {
+ beans::PropertyValue aPropertyValue;
+ aPropertyValue.Name = pEntry->aName;
+ pItem->QueryValue( aPropertyValue.Value, pEntry->nMemberId );
+ aPropertyVector.push_back( aPropertyValue );
+ }
+ }
+ }
+
+ const sal_Int32 nCount = aPropertyVector.size();
+ uno::Sequence< beans::PropertyValue > aRet( nCount );
+ beans::PropertyValue* pProps = aRet.getArray();
+
+ for ( int i = 0; i < nCount; ++i, pProps++ )
+ {
+ *pProps = aPropertyVector[i];
+ }
+
+ return aRet;
+}
+
+SwXTextTableStyle::SwXTextTableStyle(SwDocShell* pDocShell, SwTableAutoFormat* pTableAutoFormat) :
+ m_pDocShell(pDocShell), m_pTableAutoFormat(pTableAutoFormat), m_bPhysical(true)
+{
+ UpdateCellStylesMapping();
+}
+
+SwXTextTableStyle::SwXTextTableStyle(SwDocShell* pDocShell, const OUString& rTableAutoFormatName) :
+ m_pDocShell(pDocShell), m_pTableAutoFormat_Impl(new SwTableAutoFormat(rTableAutoFormatName)), m_bPhysical(false)
+{
+ m_pTableAutoFormat = m_pTableAutoFormat_Impl.get();
+ UpdateCellStylesMapping();
+}
+
+uno::Reference<style::XStyle> SwXTextTableStyle::CreateXTextTableStyle(SwDocShell* pDocShell, const OUString& rTableAutoFormatName)
+{
+ SolarMutexGuard aGuard;
+ rtl::Reference<SwXTextTableStyle> xTextTableStyle;
+ SwTableAutoFormat* pAutoFormat = GetTableAutoFormat(pDocShell, rTableAutoFormatName);
+ if (pAutoFormat && pAutoFormat->GetName() == rTableAutoFormatName)
+ {
+ xTextTableStyle = pAutoFormat->GetXObject();
+ if (!xTextTableStyle.is())
+ {
+ xTextTableStyle.set(new SwXTextTableStyle(pDocShell, pAutoFormat));
+ pAutoFormat->SetXObject(xTextTableStyle);
+ }
+ }
+
+ // If corresponding AutoFormat doesn't exist create a non physical style.
+ if (!xTextTableStyle.is())
+ {
+ xTextTableStyle.set(new SwXTextTableStyle(pDocShell, rTableAutoFormatName));
+ SAL_INFO("sw.uno", "creating SwXTextTableStyle for non existing SwTableAutoFormat");
+ }
+
+ return xTextTableStyle;
+}
+
+void SwXTextTableStyle::UpdateCellStylesMapping()
+{
+ const std::vector<sal_Int32> aTableTemplateMap = SwTableAutoFormat::GetTableTemplateMap();
+ assert(aTableTemplateMap.size() == STYLE_COUNT && "can not map SwTableAutoFormat to a SwXTextTableStyle");
+ for (sal_Int32 i=0; i<STYLE_COUNT; ++i)
+ {
+ SwBoxAutoFormat* pBoxFormat = &m_pTableAutoFormat->GetBoxFormat(aTableTemplateMap[i]);
+ rtl::Reference<SwXTextCellStyle> xCellStyle(pBoxFormat->GetXObject());
+ if (!xCellStyle.is())
+ {
+ xCellStyle.set(new SwXTextCellStyle(m_pDocShell, pBoxFormat, m_pTableAutoFormat->GetName()));
+ pBoxFormat->SetXObject(xCellStyle);
+ }
+ m_aCellStyles[i] = xCellStyle;
+ }
+}
+
+const CellStyleNameMap& SwXTextTableStyle::GetCellStyleNameMap()
+{
+ static CellStyleNameMap const aMap
+ {
+ { "first-row" , FIRST_ROW_STYLE },
+ { "last-row" , LAST_ROW_STYLE },
+ { "first-column" , FIRST_COLUMN_STYLE },
+ { "last-column" , LAST_COLUMN_STYLE },
+ { "body" , BODY_STYLE },
+ { "even-rows" , EVEN_ROWS_STYLE },
+ { "odd-rows" , ODD_ROWS_STYLE },
+ { "even-columns" , EVEN_COLUMNS_STYLE },
+ { "odd-columns" , ODD_COLUMNS_STYLE },
+ { "background" , BACKGROUND_STYLE },
+ // loext namespace
+ { "first-row-start-column" , FIRST_ROW_START_COLUMN_STYLE },
+ { "first-row-end-column" , FIRST_ROW_END_COLUMN_STYLE },
+ { "last-row-start-column" , LAST_ROW_START_COLUMN_STYLE },
+ { "last-row-end-column" , LAST_ROW_END_COLUMN_STYLE },
+ { "first-row-even-column" , FIRST_ROW_EVEN_COLUMN_STYLE },
+ { "last-row-even-column" , LAST_ROW_EVEN_COLUMN_STYLE },
+ };
+ return aMap;
+}
+
+SwTableAutoFormat* SwXTextTableStyle::GetTableFormat()
+{
+ return m_pTableAutoFormat;
+}
+
+SwTableAutoFormat* SwXTextTableStyle::GetTableAutoFormat(SwDocShell* pDocShell, std::u16string_view sName)
+{
+ const size_t nStyles = pDocShell->GetDoc()->GetTableStyles().size();
+ for(size_t i=0; i < nStyles; ++i)
+ {
+ SwTableAutoFormat* pAutoFormat = &pDocShell->GetDoc()->GetTableStyles()[i];
+ if (pAutoFormat->GetName() == sName)
+ {
+ return pAutoFormat;
+ }
+ }
+ // not found
+ return nullptr;
+}
+
+void SwXTextTableStyle::SetPhysical()
+{
+ if (!m_bPhysical)
+ {
+ // find table format in doc
+ SwTableAutoFormat* pTableAutoFormat = GetTableAutoFormat(m_pDocShell, m_pTableAutoFormat->GetName());
+ if (pTableAutoFormat)
+ {
+ m_bPhysical = true;
+ /// take care of children, make SwXTextCellStyles use new core SwBoxAutoFormats
+ const std::vector<sal_Int32> aTableTemplateMap = SwTableAutoFormat::GetTableTemplateMap();
+ for (size_t i=0; i<aTableTemplateMap.size(); ++i)
+ {
+ SwBoxAutoFormat* pOldBoxFormat = &m_pTableAutoFormat->GetBoxFormat(aTableTemplateMap[i]);
+ rtl::Reference<SwXTextCellStyle> xCellStyle(pOldBoxFormat->GetXObject());
+ if (!xCellStyle.is())
+ continue;
+ SwBoxAutoFormat& rNewBoxFormat = pTableAutoFormat->GetBoxFormat(aTableTemplateMap[i]);
+ xCellStyle->SetBoxFormat(&rNewBoxFormat);
+ rNewBoxFormat.SetXObject(xCellStyle);
+ }
+ m_pTableAutoFormat_Impl = nullptr;
+ m_pTableAutoFormat = pTableAutoFormat;
+ m_pTableAutoFormat->SetXObject(this);
+ }
+ else
+ SAL_WARN("sw.uno", "setting style physical, but SwTableAutoFormat in document not found");
+ }
+ else
+ SAL_WARN("sw.uno", "calling SetPhysical on a physical SwXTextTableStyle");
+}
+
+// XStyle
+sal_Bool SAL_CALL SwXTextTableStyle::isUserDefined()
+{
+ SolarMutexGuard aGuard;
+ // only first style is not user defined
+ if (m_pDocShell->GetDoc()->GetTableStyles()[0].GetName() == m_pTableAutoFormat->GetName())
+ return false;
+
+ return true;
+}
+
+sal_Bool SAL_CALL SwXTextTableStyle::isInUse()
+{
+ SolarMutexGuard aGuard;
+ if (!m_bPhysical)
+ return false;
+
+ for (const SwTableFormat* pFormat : *m_pDocShell->GetDoc()->GetTableFrameFormats())
+ {
+ if(pFormat->IsUsed())
+ {
+ SwTable* pTable = SwTable::FindTable(pFormat);
+ if(pTable->GetTableStyleName() == m_pTableAutoFormat->GetName())
+ return true;
+ }
+ }
+ return false;
+}
+
+OUString SAL_CALL SwXTextTableStyle::getParentStyle()
+{
+ return OUString();
+}
+
+void SAL_CALL SwXTextTableStyle::setParentStyle(const OUString& /*aParentStyle*/)
+{ }
+
+//XNamed
+OUString SAL_CALL SwXTextTableStyle::getName()
+{
+ SolarMutexGuard aGuard;
+ OUString sProgName;
+ SwStyleNameMapper::FillProgName(m_pTableAutoFormat->GetName(), sProgName, SwGetPoolIdFromName::TabStyle);
+ return sProgName;
+}
+
+void SAL_CALL SwXTextTableStyle::setName(const OUString& rName)
+{
+ SolarMutexGuard aGuard;
+ m_pTableAutoFormat->SetName(rName);
+}
+
+//XPropertySet
+css::uno::Reference<css::beans::XPropertySetInfo> SAL_CALL SwXTextTableStyle::getPropertySetInfo()
+{
+ static uno::Reference<beans::XPropertySetInfo> xRef(aSwMapProvider.GetPropertySet(PROPERTY_MAP_TABLE_STYLE)->getPropertySetInfo());
+ return xRef;
+}
+
+void SAL_CALL SwXTextTableStyle::setPropertyValue(const OUString& /*rPropertyName*/, const css::uno::Any& /*aValue*/)
+{
+ SAL_WARN("sw.uno", "not implemented");
+}
+
+css::uno::Any SAL_CALL SwXTextTableStyle::getPropertyValue(const OUString& rPropertyName)
+{
+ SolarMutexGuard aGuard;
+ bool bIsRow = false;
+
+ if (rPropertyName == UNO_NAME_TABLE_FIRST_ROW_END_COLUMN)
+ bIsRow = m_pTableAutoFormat->FirstRowEndColumnIsRow();
+ else if (rPropertyName == UNO_NAME_TABLE_FIRST_ROW_START_COLUMN)
+ bIsRow = m_pTableAutoFormat->FirstRowStartColumnIsRow();
+ else if (rPropertyName == UNO_NAME_TABLE_LAST_ROW_END_COLUMN)
+ bIsRow = m_pTableAutoFormat->LastRowEndColumnIsRow();
+ else if (rPropertyName == UNO_NAME_TABLE_LAST_ROW_START_COLUMN)
+ bIsRow = m_pTableAutoFormat->LastRowStartColumnIsRow();
+ else if (rPropertyName == UNO_NAME_DISPLAY_NAME)
+ return uno::Any(m_pTableAutoFormat->GetName());
+ else
+ throw css::beans::UnknownPropertyException(rPropertyName);
+
+ return uno::Any(bIsRow ? OUString("row") : OUString("column"));
+}
+
+void SAL_CALL SwXTextTableStyle::addPropertyChangeListener( const OUString& /*aPropertyName*/, const css::uno::Reference< css::beans::XPropertyChangeListener >& /*xListener*/ )
+{
+ SAL_WARN("sw.uno", "not implemented");
+}
+
+void SAL_CALL SwXTextTableStyle::removePropertyChangeListener( const OUString& /*aPropertyName*/, const css::uno::Reference< css::beans::XPropertyChangeListener >& /*aListener*/ )
+{
+ SAL_WARN("sw.uno", "not implemented");
+}
+
+void SAL_CALL SwXTextTableStyle::addVetoableChangeListener( const OUString& /*PropertyName*/, const css::uno::Reference< css::beans::XVetoableChangeListener >& /*aListener*/ )
+{
+ SAL_WARN("sw.uno", "not implemented");
+}
+
+void SAL_CALL SwXTextTableStyle::removeVetoableChangeListener( const OUString& /*PropertyName*/, const css::uno::Reference< css::beans::XVetoableChangeListener >& /*aListener*/ )
+{
+ SAL_WARN("sw.uno", "not implemented");
+}
+
+//XNameAccess
+uno::Any SAL_CALL SwXTextTableStyle::getByName(const OUString& rName)
+{
+ SolarMutexGuard aGuard;
+ const CellStyleNameMap& rMap = GetCellStyleNameMap();
+ CellStyleNameMap::const_iterator iter = rMap.find(rName);
+ if(iter == rMap.end())
+ throw css::container::NoSuchElementException();
+
+ auto nIdx = (*iter).second;
+ return css::uno::Any(uno::Reference(cppu::getXWeak(m_aCellStyles[nIdx].get())));
+}
+
+css::uno::Sequence<OUString> SAL_CALL SwXTextTableStyle::getElementNames()
+{
+ return comphelper::mapKeysToSequence(GetCellStyleNameMap());
+}
+
+sal_Bool SAL_CALL SwXTextTableStyle::hasByName(const OUString& rName)
+{
+ const CellStyleNameMap& rMap = GetCellStyleNameMap();
+ CellStyleNameMap::const_iterator iter = rMap.find(rName);
+ return iter != rMap.end();
+}
+
+//XNameContainer
+void SAL_CALL SwXTextTableStyle::insertByName(const OUString& /*Name*/, const uno::Any& /*Element*/)
+{
+ SAL_WARN("sw.uno", "not implemented");
+}
+
+void SAL_CALL SwXTextTableStyle::replaceByName(const OUString& rName, const uno::Any& rElement)
+{
+ SolarMutexGuard aGuard;
+ const CellStyleNameMap& rMap = GetCellStyleNameMap();
+ CellStyleNameMap::const_iterator iter = rMap.find(rName);
+ if(iter == rMap.end())
+ throw container::NoSuchElementException();
+ const sal_Int32 nCellStyle = iter->second;
+
+ rtl::Reference<SwXTextCellStyle> xStyleToReplaceWith = dynamic_cast<SwXTextCellStyle*>(rElement.get<uno::Reference<style::XStyle>>().get());
+ if (!xStyleToReplaceWith.is())
+ throw lang::IllegalArgumentException();
+
+ // replace only with physical ...
+ if (!xStyleToReplaceWith->IsPhysical())
+ throw lang::IllegalArgumentException();
+
+ const auto& rTableTemplateMap = SwTableAutoFormat::GetTableTemplateMap();
+ const sal_Int32 nBoxFormat = rTableTemplateMap[nCellStyle];
+
+ // move SwBoxAutoFormat to dest. SwTableAutoFormat
+ m_pTableAutoFormat->SetBoxFormat(*xStyleToReplaceWith->GetBoxFormat(), nBoxFormat);
+ // remove unassigned SwBoxAutoFormat, which is not anymore in use anyways
+ m_pDocShell->GetDoc()->GetCellStyles().RemoveBoxFormat(xStyleToReplaceWith->getName());
+ // make SwXTextCellStyle use new, moved SwBoxAutoFormat
+ xStyleToReplaceWith->SetBoxFormat(&m_pTableAutoFormat->GetBoxFormat(nBoxFormat));
+ m_pTableAutoFormat->GetBoxFormat(nBoxFormat).SetXObject(xStyleToReplaceWith);
+ // make this SwXTextTableStyle use new SwXTextCellStyle
+ m_aCellStyles[nCellStyle] = xStyleToReplaceWith;
+}
+
+void SAL_CALL SwXTextTableStyle::removeByName(const OUString& /*Name*/)
+{
+ SAL_WARN("sw.uno", "not implemented");
+}
+
+//XElementAccess
+uno::Type SAL_CALL SAL_CALL SwXTextTableStyle::getElementType()
+{
+ return cppu::UnoType<style::XStyle>::get();
+}
+
+sal_Bool SAL_CALL SAL_CALL SwXTextTableStyle::hasElements()
+{
+ return true;
+}
+
+//XServiceInfo
+OUString SAL_CALL SwXTextTableStyle::getImplementationName()
+{
+ return {"SwXTextTableStyle"};
+}
+
+sal_Bool SAL_CALL SwXTextTableStyle::supportsService(const OUString& rServiceName)
+{
+ return cppu::supportsService(this, rServiceName);
+}
+
+css::uno::Sequence<OUString> SAL_CALL SwXTextTableStyle::getSupportedServiceNames()
+{
+ return {"com.sun.star.style.Style"};
+}
+
+// SwXTextCellStyle
+SwXTextCellStyle::SwXTextCellStyle(SwDocShell* pDocShell, SwBoxAutoFormat* pBoxAutoFormat, OUString sParentStyle) :
+ m_pDocShell(pDocShell),
+ m_pBoxAutoFormat(pBoxAutoFormat),
+ m_sParentStyle(std::move(sParentStyle)),
+ m_bPhysical(true)
+{ }
+
+SwXTextCellStyle::SwXTextCellStyle(SwDocShell* pDocShell, OUString sName) :
+ m_pDocShell(pDocShell),
+ m_pBoxAutoFormat_Impl(std::make_shared<SwBoxAutoFormat>()),
+ m_sName(std::move(sName)),
+ m_bPhysical(false)
+{
+ m_pBoxAutoFormat = m_pBoxAutoFormat_Impl.get();
+}
+
+SwBoxAutoFormat* SwXTextCellStyle::GetBoxFormat()
+{
+ return m_pBoxAutoFormat;
+}
+
+void SwXTextCellStyle::SetBoxFormat(SwBoxAutoFormat* pBoxFormat)
+{
+ if (m_bPhysical)
+ m_pBoxAutoFormat = pBoxFormat;
+ else
+ SAL_INFO("sw.uno", "trying to call SwXTextCellStyle::SetBoxFormat on non physical style");
+}
+
+void SwXTextCellStyle::SetPhysical()
+{
+ if (!m_bPhysical)
+ {
+ SwBoxAutoFormat* pBoxAutoFormat = GetBoxAutoFormat(m_pDocShell, m_sName, &m_sParentStyle);
+ if (pBoxAutoFormat)
+ {
+ m_bPhysical = true;
+ m_pBoxAutoFormat_Impl = nullptr;
+ m_pBoxAutoFormat = pBoxAutoFormat;
+ m_pBoxAutoFormat->SetXObject(this);
+ }
+ else
+ SAL_WARN("sw.uno", "setting style physical, but SwBoxAutoFormat in document not found");
+ }
+ else
+ SAL_WARN("sw.uno", "calling SetPhysical on a physical SwXTextCellStyle");
+}
+
+bool SwXTextCellStyle::IsPhysical() const
+{
+ return m_bPhysical;
+}
+
+SwBoxAutoFormat* SwXTextCellStyle::GetBoxAutoFormat(SwDocShell* pDocShell, std::u16string_view sName, OUString* pParentName)
+{
+ if (sName.empty())
+ return nullptr;
+
+ SwBoxAutoFormat* pBoxAutoFormat = pDocShell->GetDoc()->GetCellStyles().GetBoxFormat(sName);
+ if (!pBoxAutoFormat)
+ {
+ sal_Int32 nTemplateIndex;
+ OUString sParentName;
+ std::u16string_view sCellSubName;
+
+ size_t nSeparatorIndex = sName.rfind('.');
+ if (nSeparatorIndex == std::u16string_view::npos)
+ return nullptr;
+
+ sParentName = sName.substr(0, nSeparatorIndex);
+ sCellSubName = sName.substr(nSeparatorIndex+1);
+ nTemplateIndex = o3tl::toInt32(sCellSubName)-1; // -1 because cell styles names start from 1, but internally are indexed from 0
+ if (0 > nTemplateIndex)
+ return nullptr;
+
+ const auto& rTableTemplateMap = SwTableAutoFormat::GetTableTemplateMap();
+ if (rTableTemplateMap.size() <= o3tl::make_unsigned(nTemplateIndex))
+ return nullptr;
+
+ SwStyleNameMapper::FillUIName(sParentName, sParentName, SwGetPoolIdFromName::TabStyle);
+ SwTableAutoFormat* pTableAutoFormat = pDocShell->GetDoc()->GetTableStyles().FindAutoFormat(sParentName);
+ if (!pTableAutoFormat)
+ return nullptr;
+
+ if (pParentName)
+ *pParentName = sParentName;
+ sal_uInt32 nBoxIndex = rTableTemplateMap[nTemplateIndex];
+ pBoxAutoFormat = &pTableAutoFormat->GetBoxFormat(nBoxIndex);
+ }
+
+ return pBoxAutoFormat;
+}
+
+css::uno::Reference<css::style::XStyle> SwXTextCellStyle::CreateXTextCellStyle(SwDocShell* pDocShell, const OUString& sName)
+{
+ rtl::Reference<SwXTextCellStyle> xTextCellStyle;
+
+ if (!sName.isEmpty()) // create a cell style for a physical box
+ {
+ OUString sParentName;
+ SwBoxAutoFormat* pBoxFormat = GetBoxAutoFormat(pDocShell, sName, &sParentName);
+
+ // something went wrong but we don't want a crash
+ if (!pBoxFormat)
+ {
+ // return a default-dummy style to prevent crash
+ static SwBoxAutoFormat aDefaultBoxFormat;
+ pBoxFormat = &aDefaultBoxFormat;
+ }
+
+ xTextCellStyle = pBoxFormat->GetXObject();
+ if (!xTextCellStyle.is())
+ {
+ xTextCellStyle.set(new SwXTextCellStyle(pDocShell, pBoxFormat, sParentName));
+ pBoxFormat->SetXObject(xTextCellStyle);
+ }
+ }
+ else // create a non physical style
+ xTextCellStyle.set(new SwXTextCellStyle(pDocShell, sName));
+
+ return xTextCellStyle;
+}
+
+// XStyle
+sal_Bool SAL_CALL SwXTextCellStyle::isUserDefined()
+{
+ SolarMutexGuard aGuard;
+ // if this cell belong to first table style then its default style
+ if (&m_pDocShell->GetDoc()->GetTableStyles()[0] == m_pDocShell->GetDoc()->GetTableStyles().FindAutoFormat(m_sParentStyle))
+ return false;
+
+ return true;
+}
+
+sal_Bool SAL_CALL SwXTextCellStyle::isInUse()
+{
+ SolarMutexGuard aGuard;
+ uno::Reference<style::XStyleFamiliesSupplier> xFamiliesSupplier(m_pDocShell->GetModel(), uno::UNO_QUERY);
+ if (!xFamiliesSupplier.is())
+ return false;
+
+ uno::Reference<container::XNameAccess> xFamilies = xFamiliesSupplier->getStyleFamilies();
+ if (!xFamilies.is())
+ return false;
+
+ uno::Reference<container::XNameAccess> xTableStyles;
+ xFamilies->getByName("TableStyles") >>= xTableStyles;
+ if (!xTableStyles.is())
+ return false;
+
+ uno::Reference<style::XStyle> xStyle;
+ xTableStyles->getByName(m_sParentStyle) >>= xStyle;
+ if (!xStyle.is())
+ return false;
+
+ return xStyle->isInUse();
+}
+
+OUString SAL_CALL SwXTextCellStyle::getParentStyle()
+{
+ // Do not return name of the parent (which is a table style) because the parent should be a cell style.
+ return OUString();
+}
+
+void SAL_CALL SwXTextCellStyle::setParentStyle(const OUString& /*sParentStyle*/)
+{
+ // Changing parent to one which is unaware of it will lead to a something unexpected. getName() rely on a parent.
+ SAL_INFO("sw.uno", "Changing SwXTextCellStyle parent");
+}
+
+//XNamed
+OUString SAL_CALL SwXTextCellStyle::getName()
+{
+ SolarMutexGuard aGuard;
+ OUString sName;
+
+ // if style is physical then we request a name from doc
+ if (m_bPhysical)
+ {
+ SwTableAutoFormat* pTableFormat = m_pDocShell->GetDoc()->GetTableStyles().FindAutoFormat(m_sParentStyle);
+ if (!pTableFormat)
+ {
+ // if auto format is not found as a child of table formats, look in SwDoc cellstyles
+ sName = m_pDocShell->GetDoc()->GetCellStyles().GetBoxFormatName(*m_pBoxAutoFormat);
+ }
+ else
+ {
+ OUString sParentStyle;
+ SwStyleNameMapper::FillProgName(m_sParentStyle, sParentStyle, SwGetPoolIdFromName::TabStyle);
+ sName = sParentStyle + pTableFormat->GetTableTemplateCellSubName(*m_pBoxAutoFormat);
+ }
+ }
+ else
+ sName = m_sName;
+
+ return sName;
+}
+
+void SAL_CALL SwXTextCellStyle::setName(const OUString& sName)
+{
+ SolarMutexGuard aGuard;
+ // if style is physical then we can not rename it.
+ if (!m_bPhysical)
+ m_sName = sName;
+ // change name if style is unassigned (name is not generated automatically)
+ m_pDocShell->GetDoc()->GetCellStyles().ChangeBoxFormatName(getName(), sName);
+}
+
+//XPropertySet
+css::uno::Reference<css::beans::XPropertySetInfo> SAL_CALL SwXTextCellStyle::getPropertySetInfo()
+{
+ static uno::Reference<beans::XPropertySetInfo> xRef(aSwMapProvider.GetPropertySet(PROPERTY_MAP_CELL_STYLE)->getPropertySetInfo());
+ return xRef;
+}
+
+void SAL_CALL SwXTextCellStyle::setPropertyValue(const OUString& rPropertyName, const css::uno::Any& aValue)
+{
+ SolarMutexGuard aGuard;
+ const SfxItemPropertyMapEntry *const pEntry = aSwMapProvider.GetPropertySet(PROPERTY_MAP_CELL_STYLE)->getPropertyMap().getByName(rPropertyName);
+ if(pEntry)
+ {
+ switch(pEntry->nWID)
+ {
+ case RES_BACKGROUND:
+ {
+ SvxBrushItem rBrush = m_pBoxAutoFormat->GetBackground();
+ rBrush.PutValue(aValue, 0);
+ m_pBoxAutoFormat->SetBackground(rBrush);
+ return;
+ }
+ case RES_BOX:
+ {
+ SvxBoxItem rBox = m_pBoxAutoFormat->GetBox();
+ rBox.PutValue(aValue, pEntry->nMemberId);
+ m_pBoxAutoFormat->SetBox(rBox);
+ return;
+ }
+ case RES_VERT_ORIENT:
+ {
+ SwFormatVertOrient rVertOrient = m_pBoxAutoFormat->GetVerticalAlignment();
+ rVertOrient.PutValue(aValue, pEntry->nMemberId);
+ m_pBoxAutoFormat->SetVerticalAlignment(rVertOrient);
+ return;
+ }
+ case RES_FRAMEDIR:
+ {
+ SvxFrameDirectionItem rDirItem = m_pBoxAutoFormat->GetTextOrientation();
+ rDirItem.PutValue(aValue, pEntry->nMemberId);
+ m_pBoxAutoFormat->SetTextOrientation(rDirItem);
+ return;
+ }
+ case RES_BOXATR_FORMAT:
+ {
+ sal_uInt32 nKey;
+ if (aValue >>= nKey)
+ {
+ // FIXME: It's not working for old "automatic" currency formats, which are still in use by autotbl.fmt.
+ // Scenario:
+ // 1) Mark all styles present by default in autotbl.fmt as default.
+ // 2) convert all currencies present in autotbl.fmt before calling this code
+ const SvNumberformat* pNumFormat = m_pDocShell->GetDoc()->GetNumberFormatter()->GetEntry(nKey);
+ if (pNumFormat)
+ m_pBoxAutoFormat->SetValueFormat(pNumFormat->GetFormatstring(), pNumFormat->GetLanguage(), GetAppLanguage());
+ }
+ return;
+ }
+ // Paragraph attributes
+ case RES_PARATR_ADJUST:
+ {
+ SvxAdjustItem rAdjustItem = m_pBoxAutoFormat->GetAdjust();
+ rAdjustItem.PutValue(aValue, pEntry->nMemberId);
+ m_pBoxAutoFormat->SetAdjust(rAdjustItem);
+ return;
+ }
+ case RES_CHRATR_COLOR:
+ {
+ SvxColorItem rColorItem = m_pBoxAutoFormat->GetColor();
+ rColorItem.PutValue(aValue, pEntry->nMemberId);
+ m_pBoxAutoFormat->SetColor(rColorItem);
+ return;
+ }
+ case RES_CHRATR_SHADOWED:
+ {
+ SvxShadowedItem rShadowedItem = m_pBoxAutoFormat->GetShadowed();
+ bool bValue = false; aValue >>= bValue;
+ rShadowedItem.SetValue(bValue);
+ m_pBoxAutoFormat->SetShadowed(rShadowedItem);
+ return;
+ }
+ case RES_CHRATR_CONTOUR:
+ {
+ SvxContourItem rContourItem = m_pBoxAutoFormat->GetContour();
+ bool bValue = false; aValue >>= bValue;
+ rContourItem.SetValue(bValue);
+ m_pBoxAutoFormat->SetContour(rContourItem);
+ return;
+ }
+ case RES_CHRATR_CROSSEDOUT:
+ {
+ SvxCrossedOutItem rCrossedOutItem = m_pBoxAutoFormat->GetCrossedOut();
+ rCrossedOutItem.PutValue(aValue, pEntry->nMemberId);
+ m_pBoxAutoFormat->SetCrossedOut(rCrossedOutItem);
+ return;
+ }
+ case RES_CHRATR_UNDERLINE:
+ {
+ SvxUnderlineItem rUnderlineItem = m_pBoxAutoFormat->GetUnderline();
+ rUnderlineItem.PutValue(aValue, pEntry->nMemberId);
+ m_pBoxAutoFormat->SetUnderline(rUnderlineItem);
+ return;
+ }
+ case RES_CHRATR_FONTSIZE:
+ {
+ SvxFontHeightItem rFontHeightItem = m_pBoxAutoFormat->GetHeight();
+ rFontHeightItem.PutValue(aValue, pEntry->nMemberId);
+ m_pBoxAutoFormat->SetHeight(rFontHeightItem);
+ return;
+ }
+ case RES_CHRATR_WEIGHT:
+ {
+ SvxWeightItem rWeightItem = m_pBoxAutoFormat->GetWeight();
+ rWeightItem.PutValue(aValue, pEntry->nMemberId);
+ m_pBoxAutoFormat->SetWeight(rWeightItem);
+ return;
+ }
+ case RES_CHRATR_POSTURE:
+ {
+ SvxPostureItem rPostureItem = m_pBoxAutoFormat->GetPosture();
+ rPostureItem.PutValue(aValue, pEntry->nMemberId);
+ m_pBoxAutoFormat->SetPosture(rPostureItem);
+ return;
+ }
+ case RES_CHRATR_FONT:
+ {
+ SvxFontItem rFontItem = m_pBoxAutoFormat->GetFont();
+ rFontItem.PutValue(aValue, pEntry->nMemberId);
+ m_pBoxAutoFormat->SetFont(rFontItem);
+ return;
+ }
+ case RES_CHRATR_CJK_FONTSIZE:
+ {
+ SvxFontHeightItem rFontHeightItem = m_pBoxAutoFormat->GetCJKHeight();
+ rFontHeightItem.PutValue(aValue, pEntry->nMemberId);
+ m_pBoxAutoFormat->SetCJKHeight(rFontHeightItem);
+ return;
+ }
+ case RES_CHRATR_CJK_WEIGHT:
+ {
+ SvxWeightItem rWeightItem = m_pBoxAutoFormat->GetCJKWeight();
+ rWeightItem.PutValue(aValue, pEntry->nMemberId);
+ m_pBoxAutoFormat->SetCJKWeight(rWeightItem);
+ return;
+ }
+ case RES_CHRATR_CJK_POSTURE:
+ {
+ SvxPostureItem rPostureItem = m_pBoxAutoFormat->GetCJKPosture();
+ rPostureItem.PutValue(aValue, pEntry->nMemberId);
+ m_pBoxAutoFormat->SetCJKPosture(rPostureItem);
+ return;
+ }
+ case RES_CHRATR_CJK_FONT:
+ {
+ SvxFontItem rFontItem = m_pBoxAutoFormat->GetCJKFont();
+ rFontItem.PutValue(aValue, pEntry->nMemberId);
+ m_pBoxAutoFormat->SetCJKFont(rFontItem);
+ return;
+ }
+ case RES_CHRATR_CTL_FONTSIZE:
+ {
+ SvxFontHeightItem rFontHeightItem = m_pBoxAutoFormat->GetCTLHeight();
+ rFontHeightItem.PutValue(aValue, pEntry->nMemberId);
+ m_pBoxAutoFormat->SetCTLHeight(rFontHeightItem);
+ return;
+ }
+ case RES_CHRATR_CTL_WEIGHT:
+ {
+ SvxWeightItem rWeightItem = m_pBoxAutoFormat->GetCTLWeight();
+ rWeightItem.PutValue(aValue, pEntry->nMemberId);
+ m_pBoxAutoFormat->SetCTLWeight(rWeightItem);
+ return;
+ }
+ case RES_CHRATR_CTL_POSTURE:
+ {
+ SvxPostureItem rPostureItem = m_pBoxAutoFormat->GetCTLPosture();
+ rPostureItem.PutValue(aValue, pEntry->nMemberId);
+ m_pBoxAutoFormat->SetCTLPosture(rPostureItem);
+ return;
+ }
+ case RES_CHRATR_CTL_FONT:
+ {
+ SvxFontItem rFontItem = m_pBoxAutoFormat->GetCTLFont();
+ rFontItem.PutValue(aValue, pEntry->nMemberId);
+ m_pBoxAutoFormat->SetCTLFont(rFontItem);
+ return;
+ }
+ default:
+ SAL_WARN("sw.uno", "SwXTextCellStyle unknown nWID");
+ throw css::uno::RuntimeException();
+ }
+ }
+
+ throw css::beans::UnknownPropertyException(rPropertyName);
+}
+
+css::uno::Any SAL_CALL SwXTextCellStyle::getPropertyValue(const OUString& rPropertyName)
+{
+ SolarMutexGuard aGuard;
+ uno::Any aRet;
+ const SfxItemPropertyMapEntry *const pEntry = aSwMapProvider.GetPropertySet(PROPERTY_MAP_CELL_STYLE)->getPropertyMap().getByName(rPropertyName);
+ if(pEntry)
+ {
+ switch(pEntry->nWID)
+ {
+ case RES_BACKGROUND:
+ {
+ const SvxBrushItem& rBrush = m_pBoxAutoFormat->GetBackground();
+ rBrush.QueryValue(aRet);
+ return aRet;
+ }
+ case RES_BOX:
+ {
+ const SvxBoxItem& rBox = m_pBoxAutoFormat->GetBox();
+ rBox.QueryValue(aRet, pEntry->nMemberId);
+ return aRet;
+ }
+ case RES_VERT_ORIENT:
+ {
+ const SwFormatVertOrient& rVertOrient = m_pBoxAutoFormat->GetVerticalAlignment();
+ rVertOrient.QueryValue(aRet, pEntry->nMemberId);
+ return aRet;
+ }
+ case RES_FRAMEDIR:
+ {
+ const SvxFrameDirectionItem& rDirItem = m_pBoxAutoFormat->GetTextOrientation();
+ rDirItem.QueryValue(aRet, pEntry->nMemberId);
+ return aRet;
+ }
+ case RES_BOXATR_FORMAT:
+ {
+ OUString sFormat;
+ LanguageType eLng, eSys;
+ m_pBoxAutoFormat->GetValueFormat(sFormat, eLng, eSys);
+ if(!sFormat.isEmpty())
+ {
+ SvNumFormatType nType; bool bNew; sal_Int32 nCheckPos;
+ sal_uInt32 nKey = m_pDocShell->GetDoc()->GetNumberFormatter()->GetIndexPuttingAndConverting(sFormat, eLng, eSys, nType, bNew, nCheckPos);
+ aRet <<= nKey;
+ }
+ return aRet;
+ }
+ // Paragraph attributes
+ case RES_PARATR_ADJUST:
+ {
+ const SvxAdjustItem& rAdjustItem = m_pBoxAutoFormat->GetAdjust();
+ rAdjustItem.QueryValue(aRet, pEntry->nMemberId);
+ return aRet;
+ }
+ case RES_CHRATR_COLOR:
+ {
+ const SvxColorItem& rColorItem = m_pBoxAutoFormat->GetColor();
+ rColorItem.QueryValue(aRet, pEntry->nMemberId);
+ return aRet;
+ }
+ case RES_CHRATR_SHADOWED:
+ {
+ const SvxShadowedItem& rShadowedItem = m_pBoxAutoFormat->GetShadowed();
+ aRet <<= rShadowedItem.GetValue();
+ return aRet;
+ }
+ case RES_CHRATR_CONTOUR:
+ {
+ const SvxContourItem& rContourItem = m_pBoxAutoFormat->GetContour();
+ aRet <<= rContourItem.GetValue();
+ return aRet;
+ }
+ case RES_CHRATR_CROSSEDOUT:
+ {
+ const SvxCrossedOutItem& rCrossedOutItem = m_pBoxAutoFormat->GetCrossedOut();
+ rCrossedOutItem.QueryValue(aRet, pEntry->nMemberId);
+ return aRet;
+ }
+ case RES_CHRATR_UNDERLINE:
+ {
+ const SvxUnderlineItem& rUnderlineItem = m_pBoxAutoFormat->GetUnderline();
+ rUnderlineItem.QueryValue(aRet, pEntry->nMemberId);
+ return aRet;
+ }
+ case RES_CHRATR_FONTSIZE:
+ {
+ const SvxFontHeightItem& rFontHeightItem = m_pBoxAutoFormat->GetHeight();
+ rFontHeightItem.QueryValue(aRet, pEntry->nMemberId);
+ return aRet;
+ }
+ case RES_CHRATR_WEIGHT:
+ {
+ const SvxWeightItem& rWeightItem = m_pBoxAutoFormat->GetWeight();
+ rWeightItem.QueryValue(aRet, pEntry->nMemberId);
+ return aRet;
+ }
+ case RES_CHRATR_POSTURE:
+ {
+ const SvxPostureItem& rPostureItem = m_pBoxAutoFormat->GetPosture();
+ rPostureItem.QueryValue(aRet, pEntry->nMemberId);
+ return aRet;
+ }
+ case RES_CHRATR_FONT:
+ {
+ const SvxFontItem rFontItem = m_pBoxAutoFormat->GetFont();
+ rFontItem.QueryValue(aRet, pEntry->nMemberId);
+ return aRet;
+ }
+ case RES_CHRATR_CJK_FONTSIZE:
+ {
+ const SvxFontHeightItem rFontHeightItem = m_pBoxAutoFormat->GetCJKHeight();
+ rFontHeightItem.QueryValue(aRet, pEntry->nMemberId);
+ return aRet;
+ }
+ case RES_CHRATR_CJK_WEIGHT:
+ {
+ const SvxWeightItem& rWeightItem = m_pBoxAutoFormat->GetCJKWeight();
+ rWeightItem.QueryValue(aRet, pEntry->nMemberId);
+ return aRet;
+ }
+ case RES_CHRATR_CJK_POSTURE:
+ {
+ const SvxPostureItem& rPostureItem = m_pBoxAutoFormat->GetCJKPosture();
+ rPostureItem.QueryValue(aRet, pEntry->nMemberId);
+ return aRet;
+ }
+ case RES_CHRATR_CJK_FONT:
+ {
+ const SvxFontItem rFontItem = m_pBoxAutoFormat->GetCJKFont();
+ rFontItem.QueryValue(aRet, pEntry->nMemberId);
+ return aRet;
+ }
+ case RES_CHRATR_CTL_FONTSIZE:
+ {
+ const SvxFontHeightItem rFontHeightItem = m_pBoxAutoFormat->GetCTLHeight();
+ rFontHeightItem.QueryValue(aRet, pEntry->nMemberId);
+ return aRet;
+ }
+ case RES_CHRATR_CTL_WEIGHT:
+ {
+ const SvxWeightItem& rWeightItem = m_pBoxAutoFormat->GetCTLWeight();
+ rWeightItem.QueryValue(aRet, pEntry->nMemberId);
+ return aRet;
+ }
+ case RES_CHRATR_CTL_POSTURE:
+ {
+ const SvxPostureItem& rPostureItem = m_pBoxAutoFormat->GetCTLPosture();
+ rPostureItem.QueryValue(aRet, pEntry->nMemberId);
+ return aRet;
+ }
+ case RES_CHRATR_CTL_FONT:
+ {
+ const SvxFontItem rFontItem = m_pBoxAutoFormat->GetCTLFont();
+ rFontItem.QueryValue(aRet, pEntry->nMemberId);
+ return aRet;
+ }
+ default:
+ SAL_WARN("sw.uno", "SwXTextCellStyle unknown nWID");
+ throw css::uno::RuntimeException();
+ }
+ }
+
+ throw css::beans::UnknownPropertyException(rPropertyName);
+}
+
+void SAL_CALL SwXTextCellStyle::addPropertyChangeListener( const OUString& /*aPropertyName*/, const css::uno::Reference< css::beans::XPropertyChangeListener >& /*xListener*/ )
+{
+ SAL_WARN("sw.uno", "not implemented");
+}
+
+void SAL_CALL SwXTextCellStyle::removePropertyChangeListener( const OUString& /*aPropertyName*/, const css::uno::Reference< css::beans::XPropertyChangeListener >& /*aListener*/ )
+{
+ SAL_WARN("sw.uno", "not implemented");
+}
+
+void SAL_CALL SwXTextCellStyle::addVetoableChangeListener( const OUString& /*PropertyName*/, const css::uno::Reference< css::beans::XVetoableChangeListener >& /*aListener*/ )
+{
+ SAL_WARN("sw.uno", "not implemented");
+}
+
+void SAL_CALL SwXTextCellStyle::removeVetoableChangeListener( const OUString& /*PropertyName*/, const css::uno::Reference< css::beans::XVetoableChangeListener >& /*aListener*/ )
+{
+ SAL_WARN("sw.uno", "not implemented");
+}
+
+//XPropertyState
+css::beans::PropertyState SAL_CALL SwXTextCellStyle::getPropertyState(const OUString& rPropertyName)
+{
+ SolarMutexGuard aGuard;
+ uno::Sequence<OUString> aNames { rPropertyName };
+ uno::Sequence<beans::PropertyState> aStates = getPropertyStates(aNames);
+ return aStates.getConstArray()[0];
+}
+
+css::uno::Sequence<css::beans::PropertyState> SAL_CALL SwXTextCellStyle::getPropertyStates(const css::uno::Sequence<OUString>& aPropertyNames)
+{
+ SolarMutexGuard aGuard;
+ uno::Sequence<beans::PropertyState> aRet(aPropertyNames.getLength());
+ beans::PropertyState* pStates = aRet.getArray();
+ const SwBoxAutoFormat& rDefaultBoxFormat = SwTableAutoFormat::GetDefaultBoxFormat();
+ const SfxItemPropertyMap& rMap = aSwMapProvider.GetPropertySet(PROPERTY_MAP_CELL_STYLE)->getPropertyMap();
+ const OUString* pNames = aPropertyNames.getConstArray();
+ for(sal_Int32 i=0; i < aPropertyNames.getLength(); ++i)
+ {
+ const OUString sPropName = pNames[i];
+ const SfxItemPropertyMapEntry* pEntry = rMap.getByName(sPropName);
+ if(pEntry)
+ {
+ uno::Any aAny1, aAny2;
+ switch(pEntry->nWID)
+ {
+ case RES_BACKGROUND:
+ m_pBoxAutoFormat->GetBackground().QueryValue(aAny1, pEntry->nMemberId);
+ rDefaultBoxFormat.GetBackground().QueryValue(aAny2, pEntry->nMemberId);
+ pStates[i] = aAny1 == aAny2 ? beans::PropertyState_DEFAULT_VALUE : beans::PropertyState_DIRECT_VALUE;
+ break;
+ case RES_BOX:
+ m_pBoxAutoFormat->GetBox().QueryValue(aAny1, pEntry->nMemberId);
+ rDefaultBoxFormat.GetBox().QueryValue(aAny2, pEntry->nMemberId);
+ pStates[i] = aAny1 == aAny2 ? beans::PropertyState_DEFAULT_VALUE : beans::PropertyState_DIRECT_VALUE;
+ break;
+ case RES_VERT_ORIENT:
+ m_pBoxAutoFormat->GetVerticalAlignment().QueryValue(aAny1, pEntry->nMemberId);
+ rDefaultBoxFormat.GetVerticalAlignment().QueryValue(aAny2, pEntry->nMemberId);
+ pStates[i] = aAny1 == aAny2 ? beans::PropertyState_DEFAULT_VALUE : beans::PropertyState_DIRECT_VALUE;
+ break;
+ case RES_FRAMEDIR:
+ m_pBoxAutoFormat->GetTextOrientation().QueryValue(aAny1, pEntry->nMemberId);
+ rDefaultBoxFormat.GetTextOrientation().QueryValue(aAny2, pEntry->nMemberId);
+ pStates[i] = aAny1 == aAny2 ? beans::PropertyState_DEFAULT_VALUE : beans::PropertyState_DIRECT_VALUE;
+ break;
+ case RES_BOXATR_FORMAT:
+ {
+ OUString sFormat;
+ LanguageType eLng, eSys;
+ m_pBoxAutoFormat->GetValueFormat(sFormat, eLng, eSys);
+ pStates[i] = sFormat.isEmpty() ? beans::PropertyState_DEFAULT_VALUE : beans::PropertyState_DIRECT_VALUE;
+ break;
+ }
+ case RES_PARATR_ADJUST:
+ m_pBoxAutoFormat->GetAdjust().QueryValue(aAny1, pEntry->nMemberId);
+ rDefaultBoxFormat.GetAdjust().QueryValue(aAny2, pEntry->nMemberId);
+ pStates[i] = aAny1 == aAny2 ? beans::PropertyState_DEFAULT_VALUE : beans::PropertyState_DIRECT_VALUE;
+ break;
+ case RES_CHRATR_COLOR:
+ m_pBoxAutoFormat->GetColor().QueryValue(aAny1, pEntry->nMemberId);
+ rDefaultBoxFormat.GetColor().QueryValue(aAny2, pEntry->nMemberId);
+ pStates[i] = aAny1 == aAny2 ? beans::PropertyState_DEFAULT_VALUE : beans::PropertyState_DIRECT_VALUE;
+ break;
+ case RES_CHRATR_SHADOWED:
+ m_pBoxAutoFormat->GetShadowed().QueryValue(aAny1, pEntry->nMemberId);
+ rDefaultBoxFormat.GetShadowed().QueryValue(aAny2, pEntry->nMemberId);
+ pStates[i] = aAny1 == aAny2 ? beans::PropertyState_DEFAULT_VALUE : beans::PropertyState_DIRECT_VALUE;
+ break;
+ case RES_CHRATR_CONTOUR:
+ m_pBoxAutoFormat->GetContour().QueryValue(aAny1, pEntry->nMemberId);
+ rDefaultBoxFormat.GetContour().QueryValue(aAny2, pEntry->nMemberId);
+ pStates[i] = aAny1 == aAny2 ? beans::PropertyState_DEFAULT_VALUE : beans::PropertyState_DIRECT_VALUE;
+ break;
+ case RES_CHRATR_CROSSEDOUT:
+ m_pBoxAutoFormat->GetCrossedOut().QueryValue(aAny1, pEntry->nMemberId);
+ rDefaultBoxFormat.GetCrossedOut().QueryValue(aAny2, pEntry->nMemberId);
+ pStates[i] = aAny1 == aAny2 ? beans::PropertyState_DEFAULT_VALUE : beans::PropertyState_DIRECT_VALUE;
+ break;
+ case RES_CHRATR_UNDERLINE:
+ m_pBoxAutoFormat->GetUnderline().QueryValue(aAny1, pEntry->nMemberId);
+ rDefaultBoxFormat.GetUnderline().QueryValue(aAny2, pEntry->nMemberId);
+ pStates[i] = aAny1 == aAny2 ? beans::PropertyState_DEFAULT_VALUE : beans::PropertyState_DIRECT_VALUE;
+ break;
+ case RES_CHRATR_FONTSIZE:
+ m_pBoxAutoFormat->GetHeight().QueryValue(aAny1, pEntry->nMemberId);
+ rDefaultBoxFormat.GetHeight().QueryValue(aAny2, pEntry->nMemberId);
+ pStates[i] = aAny1 == aAny2 ? beans::PropertyState_DEFAULT_VALUE : beans::PropertyState_DIRECT_VALUE;
+ break;
+ case RES_CHRATR_WEIGHT:
+ m_pBoxAutoFormat->GetWeight().QueryValue(aAny1, pEntry->nMemberId);
+ rDefaultBoxFormat.GetWeight().QueryValue(aAny2, pEntry->nMemberId);
+ pStates[i] = aAny1 == aAny2 ? beans::PropertyState_DEFAULT_VALUE : beans::PropertyState_DIRECT_VALUE;
+ break;
+ case RES_CHRATR_POSTURE:
+ m_pBoxAutoFormat->GetPosture().QueryValue(aAny1, pEntry->nMemberId);
+ rDefaultBoxFormat.GetPosture().QueryValue(aAny2, pEntry->nMemberId);
+ pStates[i] = aAny1 == aAny2 ? beans::PropertyState_DEFAULT_VALUE : beans::PropertyState_DIRECT_VALUE;
+ break;
+ case RES_CHRATR_FONT:
+ m_pBoxAutoFormat->GetFont().QueryValue(aAny1, pEntry->nMemberId);
+ rDefaultBoxFormat.GetFont().QueryValue(aAny2, pEntry->nMemberId);
+ pStates[i] = aAny1 == aAny2 ? beans::PropertyState_DEFAULT_VALUE : beans::PropertyState_DIRECT_VALUE;
+ break;
+ case RES_CHRATR_CJK_FONTSIZE:
+ m_pBoxAutoFormat->GetCJKHeight().QueryValue(aAny1, pEntry->nMemberId);
+ rDefaultBoxFormat.GetCJKHeight().QueryValue(aAny2, pEntry->nMemberId);
+ pStates[i] = aAny1 == aAny2 ? beans::PropertyState_DEFAULT_VALUE : beans::PropertyState_DIRECT_VALUE;
+ break;
+ case RES_CHRATR_CJK_WEIGHT:
+ m_pBoxAutoFormat->GetCJKWeight().QueryValue(aAny1, pEntry->nMemberId);
+ rDefaultBoxFormat.GetCJKWeight().QueryValue(aAny2, pEntry->nMemberId);
+ pStates[i] = aAny1 == aAny2 ? beans::PropertyState_DEFAULT_VALUE : beans::PropertyState_DIRECT_VALUE;
+ break;
+ case RES_CHRATR_CJK_POSTURE:
+ m_pBoxAutoFormat->GetCJKPosture().QueryValue(aAny1, pEntry->nMemberId);
+ rDefaultBoxFormat.GetCJKPosture().QueryValue(aAny2, pEntry->nMemberId);
+ pStates[i] = aAny1 == aAny2 ? beans::PropertyState_DEFAULT_VALUE : beans::PropertyState_DIRECT_VALUE;
+ break;
+ case RES_CHRATR_CJK_FONT:
+ m_pBoxAutoFormat->GetCJKFont().QueryValue(aAny1, pEntry->nMemberId);
+ rDefaultBoxFormat.GetCJKFont().QueryValue(aAny2, pEntry->nMemberId);
+ pStates[i] = aAny1 == aAny2 ? beans::PropertyState_DEFAULT_VALUE : beans::PropertyState_DIRECT_VALUE;
+ break;
+ case RES_CHRATR_CTL_FONTSIZE:
+ m_pBoxAutoFormat->GetCTLHeight().QueryValue(aAny1, pEntry->nMemberId);
+ rDefaultBoxFormat.GetCTLHeight().QueryValue(aAny2, pEntry->nMemberId);
+ pStates[i] = aAny1 == aAny2 ? beans::PropertyState_DEFAULT_VALUE : beans::PropertyState_DIRECT_VALUE;
+ break;
+ case RES_CHRATR_CTL_WEIGHT:
+ m_pBoxAutoFormat->GetCTLWeight().QueryValue(aAny1, pEntry->nMemberId);
+ rDefaultBoxFormat.GetCTLWeight().QueryValue(aAny2, pEntry->nMemberId);
+ pStates[i] = aAny1 == aAny2 ? beans::PropertyState_DEFAULT_VALUE : beans::PropertyState_DIRECT_VALUE;
+ break;
+ case RES_CHRATR_CTL_POSTURE:
+ m_pBoxAutoFormat->GetCTLPosture().QueryValue(aAny1, pEntry->nMemberId);
+ rDefaultBoxFormat.GetCTLPosture().QueryValue(aAny2, pEntry->nMemberId);
+ pStates[i] = aAny1 == aAny2 ? beans::PropertyState_DEFAULT_VALUE : beans::PropertyState_DIRECT_VALUE;
+ break;
+ case RES_CHRATR_CTL_FONT:
+ m_pBoxAutoFormat->GetCTLFont().QueryValue(aAny1, pEntry->nMemberId);
+ rDefaultBoxFormat.GetCTLFont().QueryValue(aAny2, pEntry->nMemberId);
+ pStates[i] = aAny1 == aAny2 ? beans::PropertyState_DEFAULT_VALUE : beans::PropertyState_DIRECT_VALUE;
+ break;
+ default:
+ // fallthrough to DIRECT_VALUE, to export properties for which getPropertyStates is not implemented
+ pStates[i] = beans::PropertyState_DIRECT_VALUE;
+ SAL_WARN("sw.uno", "SwXTextCellStyle getPropertyStates unknown nWID");
+ }
+ }
+ else
+ {
+ SAL_WARN("sw.uno", "SwXTextCellStyle unknown property:" + sPropName);
+ throw css::beans::UnknownPropertyException(sPropName);
+ }
+ }
+ return aRet;
+}
+
+void SAL_CALL SwXTextCellStyle::setPropertyToDefault(const OUString& rPropertyName)
+{
+ SolarMutexGuard aGuard;
+ const SwBoxAutoFormat& rDefaultBoxFormat = SwTableAutoFormat::GetDefaultBoxFormat();
+ const SfxItemPropertyMap& rMap = aSwMapProvider.GetPropertySet(PROPERTY_MAP_CELL_STYLE)->getPropertyMap();
+ const SfxItemPropertyMapEntry* pEntry = rMap.getByName(rPropertyName);
+ if(!pEntry)
+ return;
+
+ uno::Any aAny;
+ switch(pEntry->nWID)
+ {
+ case RES_BACKGROUND:
+ {
+ SvxBrushItem rBrush = m_pBoxAutoFormat->GetBackground();
+ rDefaultBoxFormat.GetBackground().QueryValue(aAny, pEntry->nMemberId);
+ rBrush.PutValue(aAny, pEntry->nMemberId);
+ m_pBoxAutoFormat->SetBackground(rBrush);
+ break;
+ }
+ case RES_BOX:
+ {
+ SvxBoxItem rBox = m_pBoxAutoFormat->GetBox();
+ rDefaultBoxFormat.GetBox().QueryValue(aAny, pEntry->nMemberId);
+ rBox.PutValue(aAny, pEntry->nMemberId);
+ m_pBoxAutoFormat->SetBox(rBox);
+ break;
+ }
+ case RES_VERT_ORIENT:
+ {
+ SwFormatVertOrient rVertOrient = m_pBoxAutoFormat->GetVerticalAlignment();
+ rDefaultBoxFormat.GetVerticalAlignment().QueryValue(aAny, pEntry->nMemberId);
+ rVertOrient.PutValue(aAny, pEntry->nMemberId);
+ m_pBoxAutoFormat->SetVerticalAlignment(rVertOrient);
+ break;
+ }
+ case RES_FRAMEDIR:
+ {
+ SvxFrameDirectionItem rFrameDirectionItem = m_pBoxAutoFormat->GetTextOrientation();
+ rDefaultBoxFormat.GetTextOrientation().QueryValue(aAny, pEntry->nMemberId);
+ rFrameDirectionItem.PutValue(aAny, pEntry->nMemberId);
+ m_pBoxAutoFormat->SetTextOrientation(rFrameDirectionItem);
+ break;
+ }
+ case RES_BOXATR_FORMAT:
+ {
+ OUString sFormat;
+ LanguageType eLng, eSys;
+ rDefaultBoxFormat.GetValueFormat(sFormat, eLng, eSys);
+ m_pBoxAutoFormat->SetValueFormat(sFormat, eLng, eSys);
+ break;
+ }
+ case RES_PARATR_ADJUST:
+ {
+ SvxAdjustItem rAdjustItem = m_pBoxAutoFormat->GetAdjust();
+ rDefaultBoxFormat.GetAdjust().QueryValue(aAny, pEntry->nMemberId);
+ rAdjustItem.PutValue(aAny, pEntry->nMemberId);
+ m_pBoxAutoFormat->SetAdjust(rAdjustItem);
+ break;
+ }
+ case RES_CHRATR_COLOR:
+ {
+ SvxColorItem rColorItem = m_pBoxAutoFormat->GetColor();
+ rDefaultBoxFormat.GetColor().QueryValue(aAny, pEntry->nMemberId);
+ rColorItem.PutValue(aAny, pEntry->nMemberId);
+ m_pBoxAutoFormat->SetColor(rColorItem);
+ break;
+ }
+ case RES_CHRATR_SHADOWED:
+ {
+ SvxShadowedItem rShadowedItem = m_pBoxAutoFormat->GetShadowed();
+ rDefaultBoxFormat.GetShadowed().QueryValue(aAny, pEntry->nMemberId);
+ rShadowedItem.PutValue(aAny, pEntry->nMemberId);
+ m_pBoxAutoFormat->SetShadowed(rShadowedItem);
+ break;
+ }
+ case RES_CHRATR_CONTOUR:
+ {
+ SvxContourItem rContourItem = m_pBoxAutoFormat->GetContour();
+ rDefaultBoxFormat.GetContour().QueryValue(aAny, pEntry->nMemberId);
+ rContourItem.PutValue(aAny, pEntry->nMemberId);
+ m_pBoxAutoFormat->SetContour(rContourItem);
+ break;
+ }
+ case RES_CHRATR_CROSSEDOUT:
+ {
+ SvxCrossedOutItem rCrossedOutItem = m_pBoxAutoFormat->GetCrossedOut();
+ rDefaultBoxFormat.GetCrossedOut().QueryValue(aAny, pEntry->nMemberId);
+ rCrossedOutItem.PutValue(aAny, pEntry->nMemberId);
+ m_pBoxAutoFormat->SetCrossedOut(rCrossedOutItem);
+ break;
+ }
+ case RES_CHRATR_UNDERLINE:
+ {
+ SvxUnderlineItem rUnderlineItem = m_pBoxAutoFormat->GetUnderline();
+ rDefaultBoxFormat.GetUnderline().QueryValue(aAny, pEntry->nMemberId);
+ rUnderlineItem.PutValue(aAny, pEntry->nMemberId);
+ m_pBoxAutoFormat->SetUnderline(rUnderlineItem);
+ break;
+ }
+ case RES_CHRATR_FONTSIZE:
+ {
+ SvxFontHeightItem rFontHeightItem = m_pBoxAutoFormat->GetHeight();
+ rDefaultBoxFormat.GetHeight().QueryValue(aAny, pEntry->nMemberId);
+ rFontHeightItem.PutValue(aAny, pEntry->nMemberId);
+ m_pBoxAutoFormat->SetHeight(rFontHeightItem);
+ break;
+ }
+ case RES_CHRATR_WEIGHT:
+ {
+ SvxWeightItem rWeightItem = m_pBoxAutoFormat->GetWeight();
+ rDefaultBoxFormat.GetWeight().QueryValue(aAny, pEntry->nMemberId);
+ rWeightItem.PutValue(aAny, pEntry->nMemberId);
+ m_pBoxAutoFormat->SetWeight(rWeightItem);
+ break;
+ }
+ case RES_CHRATR_POSTURE:
+ {
+ SvxPostureItem rPostureItem = m_pBoxAutoFormat->GetPosture();
+ rDefaultBoxFormat.GetPosture().QueryValue(aAny, pEntry->nMemberId);
+ rPostureItem.PutValue(aAny, pEntry->nMemberId);
+ m_pBoxAutoFormat->SetPosture(rPostureItem);
+ break;
+ }
+ case RES_CHRATR_FONT:
+ {
+ SvxFontItem rFontItem = m_pBoxAutoFormat->GetFont();
+ rDefaultBoxFormat.GetFont().QueryValue(aAny, pEntry->nMemberId);
+ rFontItem.PutValue(aAny, pEntry->nMemberId);
+ m_pBoxAutoFormat->SetFont(rFontItem);
+ break;
+ }
+ case RES_CHRATR_CJK_FONTSIZE:
+ {
+ SvxFontHeightItem rFontHeightItem = m_pBoxAutoFormat->GetCJKHeight();
+ rDefaultBoxFormat.GetCJKHeight().QueryValue(aAny, pEntry->nMemberId);
+ rFontHeightItem.PutValue(aAny, pEntry->nMemberId);
+ m_pBoxAutoFormat->SetCJKHeight(rFontHeightItem);
+ break;
+ }
+ case RES_CHRATR_CJK_WEIGHT:
+ {
+ SvxWeightItem rWeightItem = m_pBoxAutoFormat->GetCJKWeight();
+ rDefaultBoxFormat.GetCJKWeight().QueryValue(aAny, pEntry->nMemberId);
+ rWeightItem.PutValue(aAny, pEntry->nMemberId);
+ m_pBoxAutoFormat->SetCJKWeight(rWeightItem);
+ break;
+ }
+ case RES_CHRATR_CJK_POSTURE:
+ {
+ SvxPostureItem rPostureItem = m_pBoxAutoFormat->GetCJKPosture();
+ rDefaultBoxFormat.GetCJKPosture().QueryValue(aAny, pEntry->nMemberId);
+ rPostureItem.PutValue(aAny, pEntry->nMemberId);
+ m_pBoxAutoFormat->SetCJKPosture(rPostureItem);
+ break;
+ }
+ case RES_CHRATR_CJK_FONT:
+ {
+ SvxFontItem rFontItem = m_pBoxAutoFormat->GetCJKFont();
+ rDefaultBoxFormat.GetCJKFont().QueryValue(aAny, pEntry->nMemberId);
+ rFontItem.PutValue(aAny, pEntry->nMemberId);
+ m_pBoxAutoFormat->SetCJKFont(rFontItem);
+ break;
+ }
+ case RES_CHRATR_CTL_FONTSIZE:
+ {
+ SvxFontHeightItem rFontHeightItem = m_pBoxAutoFormat->GetCTLHeight();
+ rDefaultBoxFormat.GetCTLHeight().QueryValue(aAny, pEntry->nMemberId);
+ rFontHeightItem.PutValue(aAny, pEntry->nMemberId);
+ m_pBoxAutoFormat->SetCTLHeight(rFontHeightItem);
+ break;
+ }
+ case RES_CHRATR_CTL_WEIGHT:
+ {
+ SvxWeightItem rWeightItem = m_pBoxAutoFormat->GetCTLWeight();
+ rDefaultBoxFormat.GetCTLWeight().QueryValue(aAny, pEntry->nMemberId);
+ rWeightItem.PutValue(aAny, pEntry->nMemberId);
+ m_pBoxAutoFormat->SetCTLWeight(rWeightItem);
+ break;
+ }
+ case RES_CHRATR_CTL_POSTURE:
+ {
+ SvxPostureItem rPostureItem = m_pBoxAutoFormat->GetCTLPosture();
+ rDefaultBoxFormat.GetCTLPosture().QueryValue(aAny, pEntry->nMemberId);
+ rPostureItem.PutValue(aAny, pEntry->nMemberId);
+ m_pBoxAutoFormat->SetCTLPosture(rPostureItem);
+ break;
+ }
+ case RES_CHRATR_CTL_FONT:
+ {
+ SvxFontItem rFontItem = m_pBoxAutoFormat->GetCTLFont();
+ rDefaultBoxFormat.GetCTLFont().QueryValue(aAny, pEntry->nMemberId);
+ rFontItem.PutValue(aAny, pEntry->nMemberId);
+ m_pBoxAutoFormat->SetCTLFont(rFontItem);
+ break;
+ }
+ default:
+ SAL_WARN("sw.uno", "SwXTextCellStyle setPropertyToDefault unknown nWID");
+ }
+}
+
+css::uno::Any SAL_CALL SwXTextCellStyle::getPropertyDefault(const OUString& /*aPropertyName*/)
+{
+ SAL_WARN("sw.uno", "not implemented");
+ uno::Any aRet;
+ return aRet;
+}
+
+//XServiceInfo
+OUString SAL_CALL SwXTextCellStyle::getImplementationName()
+{
+ return {"SwXTextCellStyle"};
+}
+
+sal_Bool SAL_CALL SwXTextCellStyle::supportsService(const OUString& rServiceName)
+{
+ return cppu::supportsService(this, rServiceName);
+}
+
+css::uno::Sequence<OUString> SAL_CALL SwXTextCellStyle::getSupportedServiceNames()
+{
+ return {"com.sun.star.style.Style"};
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/core/unocore/unotbl.cxx b/sw/source/core/unocore/unotbl.cxx
new file mode 100644
index 0000000000..c2f92df7f1
--- /dev/null
+++ b/sw/source/core/unocore/unotbl.cxx
@@ -0,0 +1,4116 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <tuple>
+#include <utility>
+#include <memory>
+#include <vector>
+#include <algorithm>
+#include <limits>
+
+#include <comphelper/interfacecontainer4.hxx>
+#include <o3tl/any.hxx>
+#include <o3tl/safeint.hxx>
+#include <tools/UnitConversion.hxx>
+#include <editeng/memberids.h>
+#include <float.h>
+#include <swtypes.hxx>
+#include <cmdid.h>
+#include <unocoll.hxx>
+#include <unomid.h>
+#include <unomap.hxx>
+#include <unotbl.hxx>
+#include <section.hxx>
+#include <unocrsr.hxx>
+#include <hints.hxx>
+#include <swtblfmt.hxx>
+#include <doc.hxx>
+#include <IDocumentUndoRedo.hxx>
+#include <IDocumentContentOperations.hxx>
+#include <IDocumentFieldsAccess.hxx>
+#include <IDocumentRedlineAccess.hxx>
+#include <IDocumentState.hxx>
+#include <IDocumentLayoutAccess.hxx>
+#include <shellres.hxx>
+#include <docary.hxx>
+#include <ndole.hxx>
+#include <ndtxt.hxx>
+#include <frame.hxx>
+#include <vcl/svapp.hxx>
+#include <fmtfsize.hxx>
+#include <tblafmt.hxx>
+#include <tabcol.hxx>
+#include <cellatr.hxx>
+#include <fmtpdsc.hxx>
+#include <pagedesc.hxx>
+#include <viewsh.hxx>
+#include <rootfrm.hxx>
+#include <tabfrm.hxx>
+#include <redline.hxx>
+#include <unoport.hxx>
+#include <unocrsrhelper.hxx>
+#include <com/sun/star/lang/IndexOutOfBoundsException.hpp>
+#include <com/sun/star/text/WrapTextMode.hpp>
+#include <com/sun/star/text/TextContentAnchorType.hpp>
+#include <com/sun/star/text/TableColumnSeparator.hpp>
+#include <com/sun/star/text/VertOrientation.hpp>
+#include <com/sun/star/text/XTextSection.hpp>
+#include <com/sun/star/table/TableBorder.hpp>
+#include <com/sun/star/table/TableBorder2.hpp>
+#include <com/sun/star/table/BorderLine2.hpp>
+#include <com/sun/star/table/TableBorderDistances.hpp>
+#include <com/sun/star/beans/PropertyAttribute.hpp>
+#include <com/sun/star/chart/XChartDataChangeEventListener.hpp>
+#include <com/sun/star/chart/ChartDataChangeEvent.hpp>
+#include <com/sun/star/table/CellContentType.hpp>
+#include <unotextrange.hxx>
+#include <unotextcursor.hxx>
+#include <unoparagraph.hxx>
+#include <svl/numformat.hxx>
+#include <svl/zforlist.hxx>
+#include <editeng/formatbreakitem.hxx>
+#include <editeng/shaditem.hxx>
+#include <editeng/lrspitem.hxx>
+#include <editeng/ulspitem.hxx>
+#include <fmtornt.hxx>
+#include <editeng/keepitem.hxx>
+#include <fmtlsplt.hxx>
+#include <swundo.hxx>
+#include <SwStyleNameMapper.hxx>
+#include <frmatr.hxx>
+#include <sortopt.hxx>
+#include <sal/log.hxx>
+#include <editeng/frmdiritem.hxx>
+#include <comphelper/servicehelper.hxx>
+#include <comphelper/string.hxx>
+#include <cppuhelper/supportsservice.hxx>
+#include <comphelper/sequence.hxx>
+#include <comphelper/sequenceashashmap.hxx>
+#include <swtable.hxx>
+#include <docsh.hxx>
+#include <fesh.hxx>
+#include <itabenum.hxx>
+#include <frameformats.hxx>
+#include <o3tl/string_view.hxx>
+
+using namespace ::com::sun::star;
+using ::editeng::SvxBorderLine;
+
+namespace
+{
+ template<typename Tcoretype, typename Tunotype>
+ struct FindUnoInstanceHint final : SfxHint
+ {
+ FindUnoInstanceHint(Tcoretype* pCore) : m_pCore(pCore), m_pResult(nullptr) {};
+ const Tcoretype* const m_pCore;
+ mutable rtl::Reference<Tunotype> m_pResult;
+ };
+ SwFrameFormat* lcl_EnsureCoreConnected(SwFrameFormat* pFormat, cppu::OWeakObject* pObject)
+ {
+ if(!pFormat)
+ throw uno::RuntimeException("Lost connection to core objects", pObject);
+ return pFormat;
+ }
+ SwTable* lcl_EnsureTableNotComplex(SwTable* pTable, cppu::OWeakObject* pObject)
+ {
+ if(pTable->IsTableComplex())
+ throw uno::RuntimeException("Table too complex", pObject);
+ return pTable;
+ }
+
+ chart::ChartDataChangeEvent createChartEvent(uno::Reference<uno::XInterface> const& xSource)
+ {
+ //TODO: find appropriate settings of the Event
+ chart::ChartDataChangeEvent event;
+ event.Source = xSource;
+ event.Type = chart::ChartDataChangeType_ALL;
+ event.StartColumn = 0;
+ event.EndColumn = 1;
+ event.StartRow = 0;
+ event.EndRow = 1;
+ return event;
+ }
+
+ void lcl_SendChartEvent(std::unique_lock<std::mutex>& rGuard,
+ uno::Reference<uno::XInterface> const& xSource,
+ ::comphelper::OInterfaceContainerHelper4<chart::XChartDataChangeEventListener> & rListeners)
+ {
+ if (rListeners.getLength(rGuard))
+ rListeners.notifyEach(rGuard,
+ &chart::XChartDataChangeEventListener::chartDataChanged,
+ createChartEvent(xSource));
+ }
+}
+
+#define UNO_TABLE_COLUMN_SUM 10000
+
+
+static bool lcl_LineToSvxLine(const table::BorderLine& rLine, SvxBorderLine& rSvxLine)
+{
+ rSvxLine.SetColor(Color(ColorTransparency, rLine.Color));
+
+ rSvxLine.GuessLinesWidths( SvxBorderLineStyle::NONE,
+ o3tl::toTwips(rLine.OuterLineWidth, o3tl::Length::mm100),
+ o3tl::toTwips(rLine.InnerLineWidth, o3tl::Length::mm100),
+ o3tl::toTwips(rLine.LineDistance, o3tl::Length::mm100) );
+
+ return rLine.InnerLineWidth > 0 || rLine.OuterLineWidth > 0;
+}
+
+/// @throws lang::IllegalArgumentException
+/// @throws uno::RuntimeException
+static void lcl_SetSpecialProperty(SwFrameFormat* pFormat,
+ const SfxItemPropertyMapEntry* pEntry,
+ const uno::Any& aValue)
+{
+ // special treatment for "non-items"
+ switch(pEntry->nWID)
+ {
+ case FN_TABLE_HEADLINE_REPEAT:
+ case FN_TABLE_HEADLINE_COUNT:
+ {
+ SwTable* pTable = SwTable::FindTable( pFormat );
+ UnoActionContext aAction(pFormat->GetDoc());
+ if( pEntry->nWID == FN_TABLE_HEADLINE_REPEAT)
+ {
+ pFormat->GetDoc()->SetRowsToRepeat( *pTable, aValue.get<bool>() ? 1 : 0 );
+ }
+ else
+ {
+ sal_Int32 nRepeat = 0;
+ aValue >>= nRepeat;
+ if( nRepeat >= 0 && nRepeat < SAL_MAX_UINT16 )
+ pFormat->GetDoc()->SetRowsToRepeat( *pTable, o3tl::narrowing<sal_uInt16>(nRepeat) );
+ }
+ }
+ break;
+
+ case FN_TABLE_IS_RELATIVE_WIDTH:
+ case FN_TABLE_WIDTH:
+ case FN_TABLE_RELATIVE_WIDTH:
+ {
+ SwFormatFrameSize aSz( pFormat->GetFrameSize() );
+ if(FN_TABLE_WIDTH == pEntry->nWID)
+ {
+ sal_Int32 nWidth = 0;
+ aValue >>= nWidth;
+ aSz.SetWidthPercent(0);
+ aSz.SetWidth ( o3tl::toTwips(nWidth, o3tl::Length::mm100) );
+ }
+ else if(FN_TABLE_RELATIVE_WIDTH == pEntry->nWID)
+ {
+ sal_Int16 nSet = 0;
+ aValue >>= nSet;
+ if(nSet && nSet <=100)
+ aSz.SetWidthPercent( static_cast<sal_uInt8>(nSet) );
+ }
+ else if(FN_TABLE_IS_RELATIVE_WIDTH == pEntry->nWID)
+ {
+ if(!aValue.get<bool>())
+ aSz.SetWidthPercent(0);
+ else
+ {
+ throw lang::IllegalArgumentException("relative width cannot be switched on with this property", nullptr, 0);
+ }
+ }
+ pFormat->GetDoc()->SetAttr(aSz, *pFormat);
+ }
+ break;
+
+ case RES_PAGEDESC:
+ {
+ OUString sPageStyle;
+ aValue >>= sPageStyle;
+ const SwPageDesc* pDesc = nullptr;
+ if (!sPageStyle.isEmpty())
+ {
+ SwStyleNameMapper::FillUIName(sPageStyle, sPageStyle, SwGetPoolIdFromName::PageDesc);
+ pDesc = SwPageDesc::GetByName(*pFormat->GetDoc(), sPageStyle);
+ }
+ SwFormatPageDesc aDesc( pDesc );
+ pFormat->GetDoc()->SetAttr(aDesc, *pFormat);
+ }
+ break;
+
+ default:
+ throw lang::IllegalArgumentException();
+ }
+}
+
+static uno::Any lcl_GetSpecialProperty(SwFrameFormat* pFormat, const SfxItemPropertyMapEntry* pEntry )
+{
+ switch(pEntry->nWID)
+ {
+ case FN_TABLE_HEADLINE_REPEAT:
+ case FN_TABLE_HEADLINE_COUNT:
+ {
+ SwTable* pTable = SwTable::FindTable( pFormat );
+ const sal_uInt16 nRepeat = pTable->GetRowsToRepeat();
+ if(pEntry->nWID == FN_TABLE_HEADLINE_REPEAT)
+ return uno::Any(nRepeat > 0);
+ return uno::Any(sal_Int32(nRepeat));
+ }
+
+ case FN_TABLE_WIDTH:
+ case FN_TABLE_IS_RELATIVE_WIDTH:
+ case FN_TABLE_RELATIVE_WIDTH:
+ {
+ uno::Any aRet;
+ const SwFormatFrameSize& rSz = pFormat->GetFrameSize();
+ if(FN_TABLE_WIDTH == pEntry->nWID)
+ rSz.QueryValue(aRet, MID_FRMSIZE_WIDTH|CONVERT_TWIPS);
+ else if(FN_TABLE_RELATIVE_WIDTH == pEntry->nWID)
+ rSz.QueryValue(aRet, MID_FRMSIZE_REL_WIDTH);
+ else
+ aRet <<= (0 != rSz.GetWidthPercent());
+ return aRet;
+ }
+
+ case RES_PAGEDESC:
+ {
+ const SfxItemSet& rSet = pFormat->GetAttrSet();
+ if(const SwFormatPageDesc* pItem = rSet.GetItemIfSet(RES_PAGEDESC, false))
+ {
+ const SwPageDesc* pDsc = pItem->GetPageDesc();
+ if(pDsc)
+ return uno::Any(SwStyleNameMapper::GetProgName(pDsc->GetName(), SwGetPoolIdFromName::PageDesc ));
+ }
+ return uno::Any(OUString());
+ }
+
+ case RES_ANCHOR:
+ return uno::Any(text::TextContentAnchorType_AT_PARAGRAPH);
+
+ case FN_UNO_ANCHOR_TYPES:
+ {
+ uno::Sequence<text::TextContentAnchorType> aTypes{text::TextContentAnchorType_AT_PARAGRAPH};
+ return uno::Any(aTypes);
+ }
+
+ case FN_UNO_WRAP :
+ return uno::Any(text::WrapTextMode_NONE);
+
+ case FN_PARAM_LINK_DISPLAY_NAME :
+ return uno::Any(pFormat->GetName());
+
+ case FN_UNO_REDLINE_NODE_START:
+ case FN_UNO_REDLINE_NODE_END:
+ {
+ SwTable* pTable = SwTable::FindTable( pFormat );
+ SwNode* pTableNode = pTable->GetTableNode();
+ if(FN_UNO_REDLINE_NODE_END == pEntry->nWID)
+ pTableNode = pTableNode->EndOfSectionNode();
+ for(const SwRangeRedline* pRedline : pFormat->GetDoc()->getIDocumentRedlineAccess().GetRedlineTable())
+ {
+ const SwNode& rRedPointNode = pRedline->GetPointNode();
+ const SwNode& rRedMarkNode = pRedline->GetMarkNode();
+ if(rRedPointNode == *pTableNode || rRedMarkNode == *pTableNode)
+ {
+ const SwNode& rStartOfRedline = SwNodeIndex(rRedPointNode) <= SwNodeIndex(rRedMarkNode) ?
+ rRedPointNode : rRedMarkNode;
+ bool bIsStart = &rStartOfRedline == pTableNode;
+ return uno::Any(SwXRedlinePortion::CreateRedlineProperties(*pRedline, bIsStart));
+ }
+ }
+ }
+ }
+ return uno::Any();
+}
+
+/** get position of a cell with a given name
+ *
+ * If everything was OK, the indices for column and row are changed (both >= 0).
+ * In case of errors, at least one of them is < 0.
+ *
+ * Also since the implementations of tables does not really have columns using
+ * this function is appropriate only for tables that are not complex (i.e.
+ * where IsTableComplex() returns false).
+ *
+ * @param rCellName e.g. A1..Z1, a1..z1, AA1..AZ1, Aa1..Az1, BA1..BZ1, Ba1..Bz1, ...
+ * @param [IN,OUT] o_rColumn (0-based)
+ * @param [IN,OUT] o_rRow (0-based)
+ */
+//TODO: potential for throwing proper exceptions instead of having every caller to check for errors
+void SwXTextTable::GetCellPosition(std::u16string_view aCellName, sal_Int32& o_rColumn, sal_Int32& o_rRow)
+{
+ o_rColumn = o_rRow = -1; // default return values indicating failure
+ const sal_Int32 nLen = aCellName.size();
+ if(!nLen)
+ {
+ SAL_WARN("sw.uno", "failed to get column or row index");
+ return;
+ }
+ sal_Int32 nRowPos = 0;
+ while (nRowPos<nLen)
+ {
+ if (aCellName[nRowPos]>='0' && aCellName[nRowPos]<='9')
+ {
+ break;
+ }
+ ++nRowPos;
+ }
+ if (nRowPos<=0 || nRowPos>=nLen)
+ return;
+
+ sal_Int32 nColIdx = 0;
+ for (sal_Int32 i = 0; i < nRowPos; ++i)
+ {
+ nColIdx *= 52;
+ if (i < nRowPos - 1)
+ ++nColIdx;
+ const sal_Unicode cChar = aCellName[i];
+ if ('A' <= cChar && cChar <= 'Z')
+ nColIdx += cChar - 'A';
+ else if ('a' <= cChar && cChar <= 'z')
+ nColIdx += 26 + cChar - 'a';
+ else
+ {
+ nColIdx = -1; // sth failed
+ break;
+ }
+ }
+
+ o_rColumn = nColIdx;
+ o_rRow = o3tl::toInt32(aCellName.substr(nRowPos)) - 1; // - 1 because indices ought to be 0 based
+}
+
+/** compare position of two cells (check rows first)
+ *
+ * @note this function probably also make sense only
+ * for cell names of non-complex tables
+ *
+ * @param rCellName1 e.g. "A1" (non-empty string with valid cell name)
+ * @param rCellName2 e.g. "A1" (non-empty string with valid cell name)
+ * @return -1 if cell_1 < cell_2; 0 if both cells are equal; +1 if cell_1 > cell_2
+ */
+int sw_CompareCellsByRowFirst( std::u16string_view aCellName1, std::u16string_view aCellName2 )
+{
+ sal_Int32 nCol1 = -1, nRow1 = -1, nCol2 = -1, nRow2 = -1;
+ SwXTextTable::GetCellPosition( aCellName1, nCol1, nRow1 );
+ SwXTextTable::GetCellPosition( aCellName2, nCol2, nRow2 );
+
+ if (nRow1 < nRow2 || (nRow1 == nRow2 && nCol1 < nCol2))
+ return -1;
+ else if (nCol1 == nCol2 && nRow1 == nRow2)
+ return 0;
+ else
+ return +1;
+}
+
+/** compare position of two cells (check columns first)
+ *
+ * @note this function probably also make sense only
+ * for cell names of non-complex tables
+ *
+ * @param rCellName1 e.g. "A1" (non-empty string with valid cell name)
+ * @param rCellName2 e.g. "A1" (non-empty string with valid cell name)
+ * @return -1 if cell_1 < cell_2; 0 if both cells are equal; +1 if cell_1 > cell_2
+ */
+int sw_CompareCellsByColFirst( std::u16string_view aCellName1, std::u16string_view aCellName2 )
+{
+ sal_Int32 nCol1 = -1, nRow1 = -1, nCol2 = -1, nRow2 = -1;
+ SwXTextTable::GetCellPosition( aCellName1, nCol1, nRow1 );
+ SwXTextTable::GetCellPosition( aCellName2, nCol2, nRow2 );
+
+ if (nCol1 < nCol2 || (nCol1 == nCol2 && nRow1 < nRow2))
+ return -1;
+ else if (nRow1 == nRow2 && nCol1 == nCol2)
+ return 0;
+ else
+ return +1;
+}
+
+/** compare position of two cell ranges
+ *
+ * @note this function probably also make sense only
+ * for cell names of non-complex tables
+ *
+ * @param rRange1StartCell e.g. "A1" (non-empty string with valid cell name)
+ * @param rRange1EndCell e.g. "A1" (non-empty string with valid cell name)
+ * @param rRange2StartCell e.g. "A1" (non-empty string with valid cell name)
+ * @param rRange2EndCell e.g. "A1" (non-empty string with valid cell name)
+ * @param bCmpColsFirst if <true> position in columns will be compared first before rows
+ *
+ * @return -1 if cell_range_1 < cell_range_2; 0 if both cell ranges are equal; +1 if cell_range_1 > cell_range_2
+ */
+int sw_CompareCellRanges(
+ std::u16string_view aRange1StartCell, std::u16string_view aRange1EndCell,
+ std::u16string_view aRange2StartCell, std::u16string_view aRange2EndCell,
+ bool bCmpColsFirst )
+{
+ int (*pCompareCells)( std::u16string_view, std::u16string_view ) =
+ bCmpColsFirst ? &sw_CompareCellsByColFirst : &sw_CompareCellsByRowFirst;
+
+ int nCmpResStartCells = pCompareCells( aRange1StartCell, aRange2StartCell );
+ if ((-1 == nCmpResStartCells ) ||
+ ( 0 == nCmpResStartCells &&
+ -1 == pCompareCells( aRange1EndCell, aRange2EndCell ) ))
+ return -1;
+ else if (0 == nCmpResStartCells &&
+ 0 == pCompareCells( aRange1EndCell, aRange2EndCell ))
+ return 0;
+ else
+ return +1;
+}
+
+/** get cell name at a specified coordinate
+ *
+ * @param nColumn column index (0-based)
+ * @param nRow row index (0-based)
+ * @return the cell name
+ */
+OUString sw_GetCellName( sal_Int32 nColumn, sal_Int32 nRow )
+{
+ if (nColumn < 0 || nRow < 0)
+ return OUString();
+ OUString sCellName;
+ sw_GetTableBoxColStr( static_cast< sal_uInt16 >(nColumn), sCellName );
+ return sCellName + OUString::number( nRow + 1 );
+}
+
+/** Find the top left or bottom right corner box in given table.
+ Consider nested lines when finding the box.
+
+ @param rTableLines the table
+ @param i_bTopLeft if true, find top left box, otherwise find bottom
+ right box
+ */
+static const SwTableBox* lcl_FindCornerTableBox(const SwTableLines& rTableLines, const bool i_bTopLeft)
+{
+ const SwTableLines* pLines(&rTableLines);
+ while(true)
+ {
+ assert(!pLines->empty());
+ if(pLines->empty())
+ return nullptr;
+ const SwTableLine* pLine(i_bTopLeft ? pLines->front() : pLines->back());
+ assert(pLine);
+ const SwTableBoxes& rBoxes(pLine->GetTabBoxes());
+ assert(rBoxes.size() != 0);
+ const SwTableBox* pBox = i_bTopLeft ? rBoxes.front() : rBoxes.back();
+ assert(pBox);
+ if (pBox->GetSttNd())
+ return pBox;
+ pLines = &pBox->GetTabLines();
+ }
+}
+
+/** cleanup order in a range
+ *
+ * Sorts the input to a uniform format. I.e. for the four possible representation
+ * A1:C5, C5:A1, A5:C1, C1:A5
+ * the result will be always A1:C5.
+ *
+ * @param [IN,OUT] rCell1 cell name (will be modified to upper-left corner), e.g. "A1" (non-empty string with valid cell name)
+ * @param [IN,OUT] rCell2 cell name (will be modified to lower-right corner), e.g. "A1" (non-empty string with valid cell name)
+ */
+void sw_NormalizeRange(OUString &rCell1, OUString &rCell2)
+{
+ sal_Int32 nCol1 = -1, nRow1 = -1, nCol2 = -1, nRow2 = -1;
+ SwXTextTable::GetCellPosition( rCell1, nCol1, nRow1 );
+ SwXTextTable::GetCellPosition( rCell2, nCol2, nRow2 );
+ if (nCol2 < nCol1 || nRow2 < nRow1)
+ {
+ rCell1 = sw_GetCellName( std::min(nCol1, nCol2), std::min(nRow1, nRow2) );
+ rCell2 = sw_GetCellName( std::max(nCol1, nCol2), std::max(nRow1, nRow2) );
+ }
+}
+
+void SwRangeDescriptor::Normalize()
+{
+ if (nTop > nBottom)
+ std::swap(nBottom, nTop);
+ if (nLeft > nRight)
+ std::swap(nLeft, nRight);
+}
+
+static rtl::Reference<SwXCell> lcl_CreateXCell(SwFrameFormat* pFormat, sal_Int32 nColumn, sal_Int32 nRow)
+{
+ const OUString sCellName = sw_GetCellName(nColumn, nRow);
+ SwTable* pTable = SwTable::FindTable(pFormat);
+ SwTableBox* pBox = const_cast<SwTableBox*>(pTable->GetTableBox(sCellName));
+ if(!pBox)
+ return nullptr;
+ return SwXCell::CreateXCell(pFormat, pBox, pTable);
+}
+
+static void lcl_InspectLines(SwTableLines& rLines, std::vector<OUString>& rAllNames)
+{
+ for(auto pLine : rLines)
+ {
+ for(auto pBox : pLine->GetTabBoxes())
+ {
+ if(!pBox->GetName().isEmpty() && pBox->getRowSpan() > 0)
+ rAllNames.push_back(pBox->GetName());
+ SwTableLines& rBoxLines = pBox->GetTabLines();
+ if(!rBoxLines.empty())
+ lcl_InspectLines(rBoxLines, rAllNames);
+ }
+ }
+}
+
+static bool lcl_FormatTable(SwFrameFormat const * pTableFormat)
+{
+ bool bHasFrames = false;
+ SwIterator<SwFrame,SwFormat> aIter( *pTableFormat );
+ for(SwFrame* pFrame = aIter.First(); pFrame; pFrame = aIter.Next())
+ {
+ vcl::RenderContext* pRenderContext = pFrame->getRootFrame()->GetCurrShell()->GetOut();
+ // mba: no TYPEINFO for SwTabFrame
+ if(!pFrame->IsTabFrame())
+ continue;
+ DisableCallbackAction a(*pFrame->getRootFrame());
+ SwTabFrame* pTabFrame = static_cast<SwTabFrame*>(pFrame);
+ if(pTabFrame->isFrameAreaDefinitionValid())
+ pTabFrame->InvalidatePos();
+ pTabFrame->SetONECalcLowers();
+ pTabFrame->Calc(pRenderContext);
+ bHasFrames = true;
+ }
+ return bHasFrames;
+}
+
+static void lcl_CursorSelect(SwPaM& rCursor, bool bExpand)
+{
+ if(bExpand)
+ {
+ if(!rCursor.HasMark())
+ rCursor.SetMark();
+ }
+ else if(rCursor.HasMark())
+ rCursor.DeleteMark();
+}
+
+static void lcl_GetTableSeparators(uno::Any& rRet, SwTable const * pTable, SwTableBox const * pBox, bool bRow)
+{
+ SwTabCols aCols;
+ aCols.SetLeftMin ( 0 );
+ aCols.SetLeft ( 0 );
+ aCols.SetRight ( UNO_TABLE_COLUMN_SUM );
+ aCols.SetRightMax( UNO_TABLE_COLUMN_SUM );
+
+ pTable->GetTabCols( aCols, pBox, false, bRow );
+
+ const size_t nSepCount = aCols.Count();
+ uno::Sequence< text::TableColumnSeparator> aColSeq(nSepCount);
+ text::TableColumnSeparator* pArray = aColSeq.getArray();
+ bool bError = false;
+ for(size_t i = 0; i < nSepCount; ++i)
+ {
+ pArray[i].Position = static_cast< sal_Int16 >(aCols[i]);
+ pArray[i].IsVisible = !aCols.IsHidden(i);
+ if(!bRow && !pArray[i].IsVisible)
+ {
+ bError = true;
+ break;
+ }
+ }
+ if(!bError)
+ rRet <<= aColSeq;
+
+}
+
+static void lcl_SetTableSeparators(const uno::Any& rVal, SwTable* pTable, SwTableBox const * pBox, bool bRow, SwDoc* pDoc)
+{
+ SwTabCols aOldCols;
+
+ aOldCols.SetLeftMin ( 0 );
+ aOldCols.SetLeft ( 0 );
+ aOldCols.SetRight ( UNO_TABLE_COLUMN_SUM );
+ aOldCols.SetRightMax( UNO_TABLE_COLUMN_SUM );
+
+ pTable->GetTabCols( aOldCols, pBox, false, bRow );
+ const size_t nOldCount = aOldCols.Count();
+ // there is no use in setting tab cols if there is only one column
+ if( !nOldCount )
+ return;
+
+ auto pSepSeq =
+ o3tl::tryAccess<uno::Sequence<text::TableColumnSeparator>>(rVal);
+ if(!pSepSeq || static_cast<size_t>(pSepSeq->getLength()) != nOldCount)
+ return;
+ SwTabCols aCols(aOldCols);
+ const text::TableColumnSeparator* pArray = pSepSeq->getConstArray();
+ tools::Long nLastValue = 0;
+ //sal_Int32 nTableWidth = aCols.GetRight() - aCols.GetLeft();
+ for(size_t i = 0; i < nOldCount; ++i)
+ {
+ aCols[i] = pArray[i].Position;
+ if(bool(pArray[i].IsVisible) == aCols.IsHidden(i) ||
+ (!bRow && aCols.IsHidden(i)) ||
+ aCols[i] < nLastValue ||
+ UNO_TABLE_COLUMN_SUM < aCols[i] )
+ return; // probably this should assert()
+ nLastValue = aCols[i];
+ }
+ pDoc->SetTabCols(*pTable, aCols, aOldCols, pBox, bRow );
+}
+
+/* non UNO function call to set string in SwXCell */
+void sw_setString( SwXCell &rCell, const OUString &rText,
+ bool bKeepNumberFormat = false )
+{
+ if(rCell.IsValid())
+ {
+ SwFrameFormat* pBoxFormat = rCell.m_pBox->ClaimFrameFormat();
+ pBoxFormat->LockModify();
+ pBoxFormat->ResetFormatAttr( RES_BOXATR_FORMULA );
+ pBoxFormat->ResetFormatAttr( RES_BOXATR_VALUE );
+ if (!bKeepNumberFormat)
+ pBoxFormat->SetFormatAttr( SwTableBoxNumFormat(/*default Text*/) );
+ pBoxFormat->UnlockModify();
+ }
+ rCell.SwXText::setString(rText);
+}
+
+
+/* non UNO function call to set value in SwXCell */
+void sw_setValue( SwXCell &rCell, double nVal )
+{
+ if(!rCell.IsValid())
+ return;
+ // first this text (maybe) needs to be deleted
+ SwNodeOffset nNdPos = rCell.m_pBox->IsValidNumTextNd();
+ if(NODE_OFFSET_MAX != nNdPos)
+ sw_setString( rCell, OUString(), true ); // true == keep number format
+ SwDoc* pDoc = rCell.GetDoc();
+ UnoActionContext aAction(pDoc);
+ SwFrameFormat* pBoxFormat = rCell.m_pBox->ClaimFrameFormat();
+ SfxItemSetFixed<RES_BOXATR_FORMAT, RES_BOXATR_VALUE> aSet(pDoc->GetAttrPool());
+
+ //!! do we need to set a new number format? Yes, if
+ // - there is no current number format
+ // - the current number format is not a number format according to the number formatter, but rather a text format
+ const SwTableBoxNumFormat* pNumFormat = pBoxFormat->GetAttrSet().GetItemIfSet(RES_BOXATR_FORMAT);
+ if(!pNumFormat
+ || pDoc->GetNumberFormatter()->IsTextFormat(pNumFormat->GetValue()))
+ {
+ aSet.Put(SwTableBoxNumFormat(0));
+ }
+
+ SwTableBoxValue aVal(nVal);
+ aSet.Put(aVal);
+ pDoc->SetTableBoxFormulaAttrs( *rCell.m_pBox, aSet );
+ // update table
+ pDoc->getIDocumentFieldsAccess().UpdateTableFields(SwTable::FindTable(rCell.GetFrameFormat()));
+}
+
+
+SwXCell::SwXCell(SwFrameFormat* pTableFormat, SwTableBox* pBx, size_t const nPos) :
+ SwXText(pTableFormat->GetDoc(), CursorType::TableText),
+ m_pPropSet(aSwMapProvider.GetPropertySet(PROPERTY_MAP_TABLE_CELL)),
+ m_pBox(pBx),
+ m_pStartNode(nullptr),
+ m_pTableFormat(pTableFormat),
+ m_nFndPos(nPos)
+{
+ StartListening(pTableFormat->GetNotifier());
+}
+
+SwXCell::SwXCell(SwFrameFormat* pTableFormat, const SwStartNode& rStartNode) :
+ SwXText(pTableFormat->GetDoc(), CursorType::TableText),
+ m_pPropSet(aSwMapProvider.GetPropertySet(PROPERTY_MAP_TABLE_CELL)),
+ m_pBox(nullptr),
+ m_pStartNode(&rStartNode),
+ m_pTableFormat(pTableFormat),
+ m_nFndPos(NOTFOUND)
+{
+ StartListening(pTableFormat->GetNotifier());
+}
+
+SwXCell::~SwXCell()
+{
+ SolarMutexGuard aGuard;
+ EndListeningAll();
+}
+
+uno::Sequence< uno::Type > SAL_CALL SwXCell::getTypes( )
+{
+ return comphelper::concatSequences(
+ SwXCellBaseClass::getTypes(),
+ SwXText::getTypes()
+ );
+}
+
+uno::Sequence< sal_Int8 > SAL_CALL SwXCell::getImplementationId( )
+{
+ return css::uno::Sequence<sal_Int8>();
+}
+
+void SAL_CALL SwXCell::acquire( ) noexcept
+{
+ SwXCellBaseClass::acquire();
+}
+
+void SAL_CALL SwXCell::release( ) noexcept
+{
+ SolarMutexGuard aGuard;
+
+ SwXCellBaseClass::release();
+}
+
+uno::Any SAL_CALL SwXCell::queryInterface( const uno::Type& aType )
+{
+ uno::Any aRet = SwXText::queryInterface(aType);
+ if(aRet.getValueType() == cppu::UnoType<void>::get())
+ aRet = SwXCellBaseClass::queryInterface(aType);
+ return aRet;
+}
+
+const SwStartNode *SwXCell::GetStartNode() const
+{
+ const SwStartNode* pSttNd = nullptr;
+
+ if( m_pStartNode || IsValid() )
+ pSttNd = m_pStartNode ? m_pStartNode : m_pBox->GetSttNd();
+
+ return pSttNd;
+}
+
+bool SwXCell::IsValid() const
+{
+ // FIXME: this is now a const method, to make SwXText::IsValid invisible
+ // but the const_cast here are still ridiculous. TODO: find a better way.
+ SwFrameFormat* pTableFormat = m_pBox ? GetFrameFormat() : nullptr;
+ if(!pTableFormat)
+ {
+ const_cast<SwXCell*>(this)->m_pBox = nullptr;
+ }
+ else
+ {
+ SwTable* pTable = SwTable::FindTable( pTableFormat );
+ SwTableBox const*const pFoundBox =
+ const_cast<SwXCell*>(this)->FindBox(pTable, m_pBox);
+ if (!pFoundBox)
+ {
+ const_cast<SwXCell*>(this)->m_pBox = nullptr;
+ }
+ }
+ return nullptr != m_pBox;
+}
+
+OUString SwXCell::getFormula()
+{
+ SolarMutexGuard aGuard;
+ if(!IsValid())
+ return OUString();
+ SwTableBoxFormula aFormula( m_pBox->GetFrameFormat()->GetTableBoxFormula() );
+ SwTable* pTable = SwTable::FindTable( GetFrameFormat() );
+ aFormula.PtrToBoxNm( pTable );
+ return aFormula.GetFormula();
+}
+
+///@see sw_setValue (TODO: seems to be copy and paste programming here)
+void SwXCell::setFormula(const OUString& rFormula)
+{
+ SolarMutexGuard aGuard;
+ if(!IsValid())
+ return;
+ // first this text (maybe) needs to be deleted
+ SwNodeOffset nNdPos = m_pBox->IsValidNumTextNd();
+ if(SwNodeOffset(USHRT_MAX) == nNdPos)
+ sw_setString( *this, OUString(), true );
+ OUString sFormula(comphelper::string::stripStart(rFormula, ' '));
+ if( !sFormula.isEmpty() && '=' == sFormula[0] )
+ sFormula = sFormula.copy( 1 );
+ SwTableBoxFormula aFormula( sFormula );
+ SwDoc* pMyDoc = GetDoc();
+ UnoActionContext aAction(pMyDoc);
+ SfxItemSetFixed<RES_BOXATR_FORMAT, RES_BOXATR_FORMULA> aSet(pMyDoc->GetAttrPool());
+ SwFrameFormat* pBoxFormat = m_pBox->GetFrameFormat();
+ const SwTableBoxNumFormat* pNumFormat =
+ pBoxFormat->GetAttrSet().GetItemIfSet(RES_BOXATR_FORMAT);
+ if(!pNumFormat
+ || pMyDoc->GetNumberFormatter()->IsTextFormat(pNumFormat->GetValue()))
+ {
+ aSet.Put(SwTableBoxNumFormat(0));
+ }
+ aSet.Put(aFormula);
+ GetDoc()->SetTableBoxFormulaAttrs( *m_pBox, aSet );
+ // update table
+ pMyDoc->getIDocumentFieldsAccess().UpdateTableFields(SwTable::FindTable(GetFrameFormat()));
+}
+
+double SwXCell::getValue()
+{
+ SolarMutexGuard aGuard;
+ // #i112652# a table cell may contain NaN as a value, do not filter that
+ if(IsValid() && !getString().isEmpty())
+ return m_pBox->GetFrameFormat()->GetTableBoxValue().GetValue();
+ return std::numeric_limits<double>::quiet_NaN();
+}
+
+void SwXCell::setValue(double rValue)
+{
+ SolarMutexGuard aGuard;
+ sw_setValue( *this, rValue );
+}
+
+table::CellContentType SwXCell::getType()
+{
+ SolarMutexGuard aGuard;
+
+ table::CellContentType nRes = table::CellContentType_EMPTY;
+ sal_uInt32 nNdPos = m_pBox->IsFormulaOrValueBox();
+ switch (nNdPos)
+ {
+ case 0 : nRes = table::CellContentType_TEXT; break;
+ case USHRT_MAX : nRes = table::CellContentType_EMPTY; break;
+ case RES_BOXATR_VALUE : nRes = table::CellContentType_VALUE; break;
+ case RES_BOXATR_FORMULA : nRes = table::CellContentType_FORMULA; break;
+ default :
+ OSL_FAIL( "unexpected case" );
+ }
+ return nRes;
+}
+
+void SwXCell::setString(const OUString& aString)
+{
+ SolarMutexGuard aGuard;
+ sw_setString( *this, aString );
+}
+
+sal_Int32 SwXCell::getError()
+{
+ SolarMutexGuard aGuard;
+ OUString sContent = getString();
+ return sal_Int32(sContent == SwViewShell::GetShellRes()->aCalc_Error);
+}
+
+rtl::Reference< SwXTextCursor > SwXCell::createXTextCursor()
+{
+ if(!m_pStartNode && !IsValid())
+ throw uno::RuntimeException();
+ const SwStartNode* pSttNd = m_pStartNode ? m_pStartNode : m_pBox->GetSttNd();
+ SwPosition aPos(*pSttNd);
+ rtl::Reference<SwXTextCursor> const pXCursor =
+ new SwXTextCursor(*GetDoc(), this, CursorType::TableText, aPos);
+ auto& rUnoCursor(pXCursor->GetCursor());
+ rUnoCursor.Move(fnMoveForward, GoInNode);
+ return pXCursor;
+}
+
+rtl::Reference<SwXTextCursor> SwXCell::createXTextCursorByRange(const uno::Reference< text::XTextRange > & xTextPosition)
+{
+ SwUnoInternalPaM aPam(*GetDoc());
+ if((!m_pStartNode && !IsValid()) || !::sw::XTextRangeToSwPaM(aPam, xTextPosition))
+ throw uno::RuntimeException();
+ const SwStartNode* pSttNd = m_pStartNode ? m_pStartNode : m_pBox->GetSttNd();
+ // skip sections
+ SwStartNode* p1 = aPam.GetPointNode().StartOfSectionNode();
+ while(p1->IsSectionNode())
+ p1 = p1->StartOfSectionNode();
+ if( p1 != pSttNd )
+ return nullptr;
+ return new SwXTextCursor(*GetDoc(), this, CursorType::TableText,
+ *aPam.GetPoint(), aPam.GetMark());
+}
+
+uno::Reference< beans::XPropertySetInfo > SwXCell::getPropertySetInfo()
+{
+ static uno::Reference< beans::XPropertySetInfo > xRef = m_pPropSet->getPropertySetInfo();
+ return xRef;
+}
+
+void SwXCell::setPropertyValue(const OUString& rPropertyName, const uno::Any& aValue)
+{
+ SolarMutexGuard aGuard;
+ if(!IsValid())
+ return;
+ // Hack to support hidden property to transfer textDirection
+ if(rPropertyName == "FRMDirection")
+ {
+ SvxFrameDirectionItem aItem(SvxFrameDirection::Environment, RES_FRAMEDIR);
+ aItem.PutValue(aValue, 0);
+ m_pBox->GetFrameFormat()->SetFormatAttr(aItem);
+ }
+ else if(rPropertyName == "TableRedlineParams")
+ {
+ // Get the table row properties
+ uno::Sequence<beans::PropertyValue> tableCellProperties = aValue.get< uno::Sequence< beans::PropertyValue > >();
+ comphelper::SequenceAsHashMap aPropMap(tableCellProperties);
+ OUString sRedlineType;
+ if(!(aPropMap.getValue("RedlineType") >>= sRedlineType))
+ throw beans::UnknownPropertyException("No redline type property: ", getXWeak());
+
+ // Create a 'Table Cell Redline' object
+ SwUnoCursorHelper::makeTableCellRedline(*m_pBox, sRedlineType, tableCellProperties);
+
+
+ }
+ else if (rPropertyName == "VerticalMerge")
+ {
+ //Hack to allow clearing of numbering from the paragraphs in the merged cells.
+ SwNodeIndex aIdx(*GetStartNode(), 1);
+ const SwNode* pEndNd = aIdx.GetNode().EndOfSectionNode();
+ while (&aIdx.GetNode() != pEndNd)
+ {
+ SwTextNode* pNd = aIdx.GetNode().GetTextNode();
+ if (pNd)
+ pNd->SetCountedInList(false);
+ ++aIdx;
+ }
+ }
+ else
+ {
+ auto pEntry(m_pPropSet->getPropertyMap().getByName(rPropertyName));
+ if ( !pEntry )
+ {
+ // not a table property: ignore it, if it is a paragraph/character property
+ const SfxItemPropertySet& rParaPropSet = *aSwMapProvider.GetPropertySet(PROPERTY_MAP_PARAGRAPH);
+ pEntry = rParaPropSet.getPropertyMap().getByName(rPropertyName);
+
+ if ( pEntry )
+ return;
+ }
+
+ if(!pEntry)
+ throw beans::UnknownPropertyException(rPropertyName, getXWeak());
+ if(pEntry->nWID != FN_UNO_CELL_ROW_SPAN)
+ {
+ SwFrameFormat* pBoxFormat = m_pBox->ClaimFrameFormat();
+ SwAttrSet aSet(pBoxFormat->GetAttrSet());
+ m_pPropSet->setPropertyValue(rPropertyName, aValue, aSet);
+ pBoxFormat->GetDoc()->SetAttr(aSet, *pBoxFormat);
+ }
+ else if(aValue.isExtractableTo(cppu::UnoType<sal_Int32>::get()))
+ m_pBox->setRowSpan(aValue.get<sal_Int32>());
+ }
+}
+
+uno::Any SwXCell::getPropertyValue(const OUString& rPropertyName)
+{
+ SolarMutexGuard aGuard;
+ if(!IsValid())
+ return uno::Any();
+ auto pEntry(m_pPropSet->getPropertyMap().getByName(rPropertyName));
+ if(!pEntry)
+ throw beans::UnknownPropertyException(rPropertyName, getXWeak());
+ switch(pEntry->nWID)
+ {
+ case FN_UNO_CELL_ROW_SPAN:
+ return uno::Any(m_pBox->getRowSpan());
+ case FN_UNO_TEXT_SECTION:
+ {
+ SwFrameFormat* pTableFormat = GetFrameFormat();
+ SwTable* pTable = SwTable::FindTable(pTableFormat);
+ SwTableNode* pTableNode = pTable->GetTableNode();
+ SwSectionNode* pSectionNode = pTableNode->FindSectionNode();
+ if(!pSectionNode)
+ return uno::Any();
+ SwSection& rSect = pSectionNode->GetSection();
+ return uno::Any(SwXTextSections::GetObject(*rSect.GetFormat()));
+ }
+ break;
+ case FN_UNO_CELL_NAME:
+ return uno::Any(m_pBox->GetName());
+ case FN_UNO_REDLINE_NODE_START:
+ case FN_UNO_REDLINE_NODE_END:
+ {
+ //redline can only be returned if it's a living object
+ return SwXText::getPropertyValue(rPropertyName);
+ }
+ break;
+ case FN_UNO_PARENT_TEXT:
+ {
+ if (!m_xParentText.is())
+ {
+ const SwStartNode* pSttNd = m_pBox->GetSttNd();
+ if (!pSttNd)
+ return uno::Any();
+
+ const SwTableNode* pTableNode = pSttNd->FindTableNode();
+ if (!pTableNode)
+ return uno::Any();
+
+ SwPosition aPos(*pTableNode);
+ SwDoc& rDoc = aPos.GetDoc();
+ m_xParentText = sw::CreateParentXText(rDoc, aPos);
+ }
+
+ return uno::Any(m_xParentText);
+ }
+ break;
+ default:
+ {
+ const SwAttrSet& rSet = m_pBox->GetFrameFormat()->GetAttrSet();
+ uno::Any aResult;
+ m_pPropSet->getPropertyValue(rPropertyName, rSet, aResult);
+ return aResult;
+ }
+ }
+}
+
+void SwXCell::addPropertyChangeListener(const OUString& /*rPropertyName*/, const uno::Reference< beans::XPropertyChangeListener > & /*xListener*/)
+ { throw uno::RuntimeException("not implemented", getXWeak()); };
+
+void SwXCell::removePropertyChangeListener(const OUString& /*rPropertyName*/, const uno::Reference< beans::XPropertyChangeListener > & /*xListener*/)
+ { throw uno::RuntimeException("not implemented", getXWeak()); };
+
+void SwXCell::addVetoableChangeListener(const OUString& /*rPropertyName*/, const uno::Reference< beans::XVetoableChangeListener > & /*xListener*/)
+ { throw uno::RuntimeException("not implemented", getXWeak()); };
+
+void SwXCell::removeVetoableChangeListener(const OUString& /*rPropertyName*/, const uno::Reference< beans::XVetoableChangeListener > & /*xListener*/)
+ { throw uno::RuntimeException("not implemented", getXWeak()); };
+
+uno::Reference<container::XEnumeration> SwXCell::createEnumeration()
+{
+ SolarMutexGuard aGuard;
+ if(!IsValid())
+ return uno::Reference<container::XEnumeration>();
+ const SwStartNode* pSttNd = m_pBox->GetSttNd();
+ SwPosition aPos(*pSttNd);
+ auto pUnoCursor(GetDoc()->CreateUnoCursor(aPos));
+ pUnoCursor->Move(fnMoveForward, GoInNode);
+ // remember table and start node for later travelling
+ // (used in export of tables in tables)
+ return SwXParagraphEnumeration::Create(this, pUnoCursor, CursorType::TableText, m_pBox);
+}
+
+uno::Type SAL_CALL SwXCell::getElementType()
+{
+ return cppu::UnoType<text::XTextRange>::get();
+}
+
+sal_Bool SwXCell::hasElements()
+{
+ return true;
+}
+
+void SwXCell::Notify(const SfxHint& rHint)
+{
+ if(rHint.GetId() == SfxHintId::Dying)
+ {
+ m_pTableFormat = nullptr;
+ }
+ else if(auto pFindHint = dynamic_cast<const FindUnoInstanceHint<SwTableBox, SwXCell>*>(&rHint))
+ {
+ if(!pFindHint->m_pResult && pFindHint->m_pCore == GetTableBox())
+ pFindHint->m_pResult = this;
+ }
+}
+
+rtl::Reference<SwXCell> SwXCell::CreateXCell(SwFrameFormat* pTableFormat, SwTableBox* pBox, SwTable *pTable )
+{
+ if(!pTableFormat || !pBox)
+ return nullptr;
+ if(!pTable)
+ pTable = SwTable::FindTable(pTableFormat);
+ SwTableSortBoxes::const_iterator it = pTable->GetTabSortBoxes().find(pBox);
+ if(it == pTable->GetTabSortBoxes().end())
+ return nullptr;
+ size_t const nPos = it - pTable->GetTabSortBoxes().begin();
+ FindUnoInstanceHint<SwTableBox, SwXCell> aHint{pBox};
+ pTableFormat->GetNotifier().Broadcast(aHint);
+ return aHint.m_pResult ? aHint.m_pResult.get() : new SwXCell(pTableFormat, pBox, nPos);
+}
+
+/** search if a box exists in a table
+ *
+ * @param pTable the table to search in
+ * @param pBox2 box model to find
+ * @return the box if existent in pTable, 0 (!!!) if not found
+ */
+SwTableBox* SwXCell::FindBox(SwTable* pTable, SwTableBox* pBox2)
+{
+ // check if nFndPos happens to point to the right table box
+ if( m_nFndPos < pTable->GetTabSortBoxes().size() &&
+ pBox2 == pTable->GetTabSortBoxes()[ m_nFndPos ] )
+ return pBox2;
+
+ // if not, seek the entry (and return, if successful)
+ SwTableSortBoxes::const_iterator it = pTable->GetTabSortBoxes().find( pBox2 );
+ if( it != pTable->GetTabSortBoxes().end() )
+ {
+ m_nFndPos = it - pTable->GetTabSortBoxes().begin();
+ return pBox2;
+ }
+
+ // box not found: reset nFndPos pointer
+ m_nFndPos = NOTFOUND;
+ return nullptr;
+}
+
+double SwXCell::GetForcedNumericalValue() const
+{
+ if(table::CellContentType_TEXT != const_cast<SwXCell*>(this)->getType())
+ return getValue();
+ // now we'll try to get a useful numerical value
+ // from the text in the cell...
+ sal_uInt32 nFIndex;
+ SvNumberFormatter* pNumFormatter(const_cast<SvNumberFormatter*>(GetDoc()->GetNumberFormatter()));
+ // look for SwTableBoxNumFormat value in parents as well
+ auto pBoxFormat(GetTableBox()->GetFrameFormat());
+ const SwTableBoxNumFormat* pNumFormat = pBoxFormat->GetAttrSet().GetItemIfSet(RES_BOXATR_FORMAT);
+
+ if (pNumFormat)
+ {
+ // please note that the language of the numberformat
+ // is implicitly coded into the below value as well
+ nFIndex = pNumFormat->GetValue();
+
+ // since the current value indicates a text format but the call
+ // to 'IsNumberFormat' below won't work for text formats
+ // we need to get rid of the part that indicates the text format.
+ // According to ER this can be done like this:
+ nFIndex -= (nFIndex % SV_COUNTRY_LANGUAGE_OFFSET);
+ }
+ else
+ {
+ // system language is probably not the best possible choice
+ // but since we have to guess anyway (because the language of at
+ // the text is NOT the one used for the number format!)
+ // it is at least conform to what is used in
+ // SwTableShell::Execute when
+ // SID_ATTR_NUMBERFORMAT_VALUE is set...
+ LanguageType eLang = LANGUAGE_SYSTEM;
+ nFIndex = pNumFormatter->GetStandardIndex( eLang );
+ }
+ double fTmp;
+ if (!const_cast<SwDoc*>(GetDoc())->IsNumberFormat(const_cast<SwXCell*>(this)->getString(), nFIndex, fTmp))
+ return std::numeric_limits<double>::quiet_NaN();
+ return fTmp;
+}
+
+uno::Any SwXCell::GetAny() const
+{
+ if(!m_pBox)
+ throw uno::RuntimeException();
+ // check if table box value item is set
+ auto pBoxFormat(m_pBox->GetFrameFormat());
+ const bool bIsNum = pBoxFormat->GetItemState(RES_BOXATR_VALUE, false) == SfxItemState::SET;
+ return bIsNum ? uno::Any(getValue()) : uno::Any(const_cast<SwXCell*>(this)->getString());
+}
+
+OUString SwXCell::getImplementationName()
+ { return "SwXCell"; }
+
+sal_Bool SwXCell::supportsService(const OUString& rServiceName)
+ { return cppu::supportsService(this, rServiceName); }
+
+uno::Sequence< OUString > SwXCell::getSupportedServiceNames()
+ { return {"com.sun.star.text.CellProperties"}; }
+
+OUString SwXTextTableRow::getImplementationName()
+ { return "SwXTextTableRow"; }
+
+sal_Bool SwXTextTableRow::supportsService(const OUString& rServiceName)
+ { return cppu::supportsService(this, rServiceName); }
+
+uno::Sequence< OUString > SwXTextTableRow::getSupportedServiceNames()
+ { return {"com.sun.star.text.TextTableRow"}; }
+
+
+SwXTextTableRow::SwXTextTableRow(SwFrameFormat* pFormat, SwTableLine* pLn) :
+ m_pFormat(pFormat),
+ m_pLine(pLn),
+ m_pPropSet(aSwMapProvider.GetPropertySet(PROPERTY_MAP_TEXT_TABLE_ROW))
+{
+ StartListening(m_pFormat->GetNotifier());
+}
+
+SwXTextTableRow::~SwXTextTableRow()
+{
+ SolarMutexGuard aGuard;
+ EndListeningAll();
+}
+
+uno::Reference< beans::XPropertySetInfo > SwXTextTableRow::getPropertySetInfo()
+{
+ static uno::Reference<beans::XPropertySetInfo> xRef = m_pPropSet->getPropertySetInfo();
+ return xRef;
+}
+
+void SwXTextTableRow::setPropertyValue(const OUString& rPropertyName, const uno::Any& aValue)
+{
+ SolarMutexGuard aGuard;
+ SwFrameFormat* pFormat = lcl_EnsureCoreConnected(GetFrameFormat(), this);
+ SwTable* pTable = SwTable::FindTable( pFormat );
+ SwTableLine* pLn = SwXTextTableRow::FindLine(pTable, m_pLine);
+ if(!pLn)
+ return;
+
+ // Check for a specific property
+ if ( rPropertyName == "TableRedlineParams" )
+ {
+ // Get the table row properties
+ uno::Sequence< beans::PropertyValue > tableRowProperties = aValue.get< uno::Sequence< beans::PropertyValue > >();
+ comphelper::SequenceAsHashMap aPropMap( tableRowProperties );
+ OUString sRedlineType;
+ if( !(aPropMap.getValue("RedlineType") >>= sRedlineType) )
+ {
+ throw beans::UnknownPropertyException("No redline type property: ", getXWeak() );
+ }
+
+ // Create a 'Table Row Redline' object
+ SwUnoCursorHelper::makeTableRowRedline( *pLn, sRedlineType, tableRowProperties);
+
+ }
+ else
+ {
+ const SfxItemPropertyMapEntry* pEntry =
+ m_pPropSet->getPropertyMap().getByName(rPropertyName);
+ SwDoc* pDoc = pFormat->GetDoc();
+ if (!pEntry)
+ throw beans::UnknownPropertyException("Unknown property: " + rPropertyName, getXWeak() );
+ if ( pEntry->nFlags & beans::PropertyAttribute::READONLY)
+ throw beans::PropertyVetoException("Property is read-only: " + rPropertyName, getXWeak() );
+
+ switch(pEntry->nWID)
+ {
+ case FN_UNO_ROW_HEIGHT:
+ case FN_UNO_ROW_AUTO_HEIGHT:
+ {
+ SwFormatFrameSize aFrameSize(pLn->GetFrameFormat()->GetFrameSize());
+ if(FN_UNO_ROW_AUTO_HEIGHT== pEntry->nWID)
+ {
+ bool bSet = *o3tl::doAccess<bool>(aValue);
+ aFrameSize.SetHeightSizeType(bSet ? SwFrameSize::Variable : SwFrameSize::Fixed);
+ }
+ else
+ {
+ sal_Int32 nHeight = 0;
+ aValue >>= nHeight;
+ Size aSz(aFrameSize.GetSize());
+ aSz.setHeight( o3tl::toTwips(nHeight, o3tl::Length::mm100) );
+ aFrameSize.SetSize(aSz);
+ }
+ pDoc->SetAttr(aFrameSize, *pLn->ClaimFrameFormat());
+ }
+ break;
+
+ case FN_UNO_TABLE_COLUMN_SEPARATORS:
+ {
+ UnoActionContext aContext(pDoc);
+ SwTable* pTable2 = SwTable::FindTable( pFormat );
+ lcl_SetTableSeparators(aValue, pTable2, m_pLine->GetTabBoxes()[0], true, pDoc);
+ }
+ break;
+
+ default:
+ {
+ SwFrameFormat* pLnFormat = pLn->ClaimFrameFormat();
+ SwAttrSet aSet(pLnFormat->GetAttrSet());
+ m_pPropSet->setPropertyValue(*pEntry, aValue, aSet);
+ pDoc->SetAttr(aSet, *pLnFormat);
+ }
+ }
+ }
+}
+
+uno::Any SwXTextTableRow::getPropertyValue(const OUString& rPropertyName)
+{
+ SolarMutexGuard aGuard;
+ uno::Any aRet;
+ SwFrameFormat* pFormat = lcl_EnsureCoreConnected(GetFrameFormat(), this);
+ SwTable* pTable = SwTable::FindTable( pFormat );
+ SwTableLine* pLn = SwXTextTableRow::FindLine(pTable, m_pLine);
+ if(pLn)
+ {
+ const SfxItemPropertyMapEntry* pEntry =
+ m_pPropSet->getPropertyMap().getByName(rPropertyName);
+ if (!pEntry)
+ throw beans::UnknownPropertyException("Unknown property: " + rPropertyName, getXWeak() );
+
+ switch(pEntry->nWID)
+ {
+ case FN_UNO_ROW_HEIGHT:
+ case FN_UNO_ROW_AUTO_HEIGHT:
+ {
+ const SwFormatFrameSize& rSize = pLn->GetFrameFormat()->GetFrameSize();
+ if(FN_UNO_ROW_AUTO_HEIGHT== pEntry->nWID)
+ {
+ aRet <<= SwFrameSize::Variable == rSize.GetHeightSizeType();
+ }
+ else
+ aRet <<= static_cast<sal_Int32>(convertTwipToMm100(rSize.GetSize().Height()));
+ }
+ break;
+
+ case FN_UNO_TABLE_COLUMN_SEPARATORS:
+ {
+ lcl_GetTableSeparators(aRet, pTable, m_pLine->GetTabBoxes()[0], true);
+ }
+ break;
+
+ default:
+ {
+ const SwAttrSet& rSet = pLn->GetFrameFormat()->GetAttrSet();
+ m_pPropSet->getPropertyValue(*pEntry, rSet, aRet);
+ }
+ }
+ }
+ return aRet;
+}
+
+void SwXTextTableRow::addPropertyChangeListener(const OUString& /*rPropertyName*/, const uno::Reference< beans::XPropertyChangeListener > & /*xListener*/)
+ { throw uno::RuntimeException("not implemented", getXWeak()); };
+
+void SwXTextTableRow::removePropertyChangeListener(const OUString& /*rPropertyName*/, const uno::Reference< beans::XPropertyChangeListener > & /*xListener*/)
+ { throw uno::RuntimeException("not implemented", getXWeak()); };
+
+void SwXTextTableRow::addVetoableChangeListener(const OUString& /*rPropertyName*/, const uno::Reference< beans::XVetoableChangeListener > & /*xListener*/)
+ { throw uno::RuntimeException("not implemented", getXWeak()); };
+
+void SwXTextTableRow::removeVetoableChangeListener(const OUString& /*rPropertyName*/, const uno::Reference< beans::XVetoableChangeListener > & /*xListener*/)
+ { throw uno::RuntimeException("not implemented", getXWeak()); };
+
+void SwXTextTableRow::Notify(const SfxHint& rHint)
+{
+ if(rHint.GetId() == SfxHintId::Dying)
+ {
+ m_pFormat = nullptr;
+ } else if(auto pFindHint = dynamic_cast<const FindUnoInstanceHint<SwTableLine, SwXTextTableRow>*>(&rHint))
+ {
+ if(!pFindHint->m_pCore && pFindHint->m_pCore == m_pLine)
+ pFindHint->m_pResult = this;
+ }
+}
+
+SwTableLine* SwXTextTableRow::FindLine(SwTable* pTable, SwTableLine const * pLine)
+{
+ for(const auto& pCurrentLine : pTable->GetTabLines())
+ if(pCurrentLine == pLine)
+ return pCurrentLine;
+ return nullptr;
+}
+
+// SwXTextTableCursor
+
+OUString SwXTextTableCursor::getImplementationName()
+ { return "SwXTextTableCursor"; }
+
+sal_Bool SwXTextTableCursor::supportsService(const OUString& rServiceName)
+ { return cppu::supportsService(this, rServiceName); }
+
+void SwXTextTableCursor::release() noexcept
+{
+ SolarMutexGuard aGuard;
+ SwXTextTableCursor_Base::release();
+}
+
+const SwPaM* SwXTextTableCursor::GetPaM() const { return &GetCursor(); }
+SwPaM* SwXTextTableCursor::GetPaM() { return &GetCursor(); }
+const SwDoc* SwXTextTableCursor::GetDoc() const { return GetFrameFormat()->GetDoc(); }
+SwDoc* SwXTextTableCursor::GetDoc() { return GetFrameFormat()->GetDoc(); }
+const SwUnoCursor& SwXTextTableCursor::GetCursor() const { return *m_pUnoCursor; }
+SwUnoCursor& SwXTextTableCursor::GetCursor() { return *m_pUnoCursor; }
+
+uno::Sequence<OUString> SwXTextTableCursor::getSupportedServiceNames()
+ { return {"com.sun.star.text.TextTableCursor"}; }
+
+SwXTextTableCursor::SwXTextTableCursor(SwFrameFormat* pFrameFormat, SwTableBox const* pBox)
+ : m_pFrameFormat(pFrameFormat)
+ , m_pPropSet(aSwMapProvider.GetPropertySet(PROPERTY_MAP_TEXT_TABLE_CURSOR))
+{
+ StartListening(m_pFrameFormat->GetNotifier());
+ SwDoc* pDoc = m_pFrameFormat->GetDoc();
+ const SwStartNode* pSttNd = pBox->GetSttNd();
+ SwPosition aPos(*pSttNd);
+ m_pUnoCursor = pDoc->CreateUnoCursor(aPos, true);
+ m_pUnoCursor->Move( fnMoveForward, GoInNode );
+ SwUnoTableCursor& rTableCursor = dynamic_cast<SwUnoTableCursor&>(*m_pUnoCursor);
+ rTableCursor.MakeBoxSels();
+}
+
+SwXTextTableCursor::SwXTextTableCursor(SwFrameFormat& rTableFormat, const SwTableCursor* pTableSelection)
+ : m_pFrameFormat(&rTableFormat)
+ , m_pPropSet(aSwMapProvider.GetPropertySet(PROPERTY_MAP_TEXT_TABLE_CURSOR))
+{
+ StartListening(m_pFrameFormat->GetNotifier());
+ m_pUnoCursor = pTableSelection->GetDoc().CreateUnoCursor(*pTableSelection->GetPoint(), true);
+ if(pTableSelection->HasMark())
+ {
+ m_pUnoCursor->SetMark();
+ *m_pUnoCursor->GetMark() = *pTableSelection->GetMark();
+ }
+ const SwSelBoxes& rBoxes = pTableSelection->GetSelectedBoxes();
+ SwUnoTableCursor& rTableCursor = dynamic_cast<SwUnoTableCursor&>(*m_pUnoCursor);
+ for(auto pBox : rBoxes)
+ rTableCursor.InsertBox(*pBox);
+ rTableCursor.MakeBoxSels();
+}
+
+OUString SwXTextTableCursor::getRangeName()
+{
+ SolarMutexGuard aGuard;
+ SwUnoCursor& rUnoCursor = GetCursor();
+ SwUnoTableCursor* pTableCursor = dynamic_cast<SwUnoTableCursor*>(&rUnoCursor);
+ //!! see also SwChartDataSequence::getSourceRangeRepresentation
+ if(!pTableCursor)
+ return OUString();
+ pTableCursor->MakeBoxSels();
+ const SwStartNode* pNode = pTableCursor->GetPoint()->GetNode().FindTableBoxStartNode();
+ const SwTable* pTable = SwTable::FindTable(GetFrameFormat());
+ const SwTableBox* pEndBox = pTable->GetTableBox(pNode->GetIndex());
+ if(pTableCursor->HasMark())
+ {
+ pNode = pTableCursor->GetMark()->GetNode().FindTableBoxStartNode();
+ const SwTableBox* pStartBox = pTable->GetTableBox(pNode->GetIndex());
+ if(pEndBox != pStartBox)
+ {
+ // need to switch start and end?
+ if(*pTableCursor->GetPoint() < *pTableCursor->GetMark())
+ std::swap(pStartBox, pEndBox);
+ return pStartBox->GetName() + ":" + pEndBox->GetName();
+ }
+ }
+ return pEndBox->GetName();
+}
+
+sal_Bool SwXTextTableCursor::gotoCellByName(const OUString& sCellName, sal_Bool bExpand)
+{
+ SolarMutexGuard aGuard;
+ SwUnoCursor& rUnoCursor = GetCursor();
+ auto& rTableCursor = dynamic_cast<SwUnoTableCursor&>(rUnoCursor);
+ lcl_CursorSelect(rTableCursor, bExpand);
+ return rTableCursor.GotoTableBox(sCellName);
+}
+
+sal_Bool SwXTextTableCursor::goLeft(sal_Int16 Count, sal_Bool bExpand)
+{
+ SolarMutexGuard aGuard;
+ SwUnoCursor& rUnoCursor = GetCursor();
+ SwUnoTableCursor& rTableCursor = dynamic_cast<SwUnoTableCursor&>(rUnoCursor);
+ lcl_CursorSelect(rTableCursor, bExpand);
+ return rTableCursor.Left(Count);
+}
+
+sal_Bool SwXTextTableCursor::goRight(sal_Int16 Count, sal_Bool bExpand)
+{
+ SolarMutexGuard aGuard;
+ SwUnoCursor& rUnoCursor = GetCursor();
+ SwUnoTableCursor& rTableCursor = dynamic_cast<SwUnoTableCursor&>(rUnoCursor);
+ lcl_CursorSelect(rTableCursor, bExpand);
+ return rTableCursor.Right(Count);
+}
+
+sal_Bool SwXTextTableCursor::goUp(sal_Int16 Count, sal_Bool bExpand)
+{
+ SolarMutexGuard aGuard;
+ SwUnoCursor& rUnoCursor = GetCursor();
+ SwUnoTableCursor& rTableCursor = dynamic_cast<SwUnoTableCursor&>(rUnoCursor);
+ lcl_CursorSelect(rTableCursor, bExpand);
+ return rTableCursor.UpDown(true, Count, nullptr, 0,
+ *rUnoCursor.GetDoc().getIDocumentLayoutAccess().GetCurrentLayout());
+}
+
+sal_Bool SwXTextTableCursor::goDown(sal_Int16 Count, sal_Bool bExpand)
+{
+ SolarMutexGuard aGuard;
+ SwUnoCursor& rUnoCursor = GetCursor();
+ SwUnoTableCursor& rTableCursor = dynamic_cast<SwUnoTableCursor&>(rUnoCursor);
+ lcl_CursorSelect(rTableCursor, bExpand);
+ return rTableCursor.UpDown(false, Count, nullptr, 0,
+ *rUnoCursor.GetDoc().getIDocumentLayoutAccess().GetCurrentLayout());
+}
+
+void SwXTextTableCursor::gotoStart(sal_Bool bExpand)
+{
+ SolarMutexGuard aGuard;
+ SwUnoCursor& rUnoCursor = GetCursor();
+ SwUnoTableCursor& rTableCursor = dynamic_cast<SwUnoTableCursor&>(rUnoCursor);
+ lcl_CursorSelect(rTableCursor, bExpand);
+ rTableCursor.MoveTable(GotoCurrTable, fnTableStart);
+}
+
+void SwXTextTableCursor::gotoEnd(sal_Bool bExpand)
+{
+ SolarMutexGuard aGuard;
+ SwUnoCursor& rUnoCursor = GetCursor();
+ SwUnoTableCursor& rTableCursor = dynamic_cast<SwUnoTableCursor&>(rUnoCursor);
+ lcl_CursorSelect(rTableCursor, bExpand);
+ rTableCursor.MoveTable(GotoCurrTable, fnTableEnd);
+}
+
+sal_Bool SwXTextTableCursor::mergeRange()
+{
+ SolarMutexGuard aGuard;
+ SwUnoCursor& rUnoCursor = GetCursor();
+
+ SwUnoTableCursor& rTableCursor = dynamic_cast<SwUnoTableCursor&>(rUnoCursor);
+ {
+ // HACK: remove pending actions for selecting old style tables
+ UnoActionRemoveContext aRemoveContext(rTableCursor);
+ }
+ rTableCursor.MakeBoxSels();
+ bool bResult;
+ {
+ UnoActionContext aContext(&rUnoCursor.GetDoc());
+ bResult = TableMergeErr::Ok == rTableCursor.GetDoc().MergeTable(rTableCursor);
+ }
+ if(bResult)
+ {
+ size_t nCount = rTableCursor.GetSelectedBoxesCount();
+ while (nCount--)
+ rTableCursor.DeleteBox(nCount);
+ }
+ rTableCursor.MakeBoxSels();
+ return bResult;
+}
+
+sal_Bool SwXTextTableCursor::splitRange(sal_Int16 Count, sal_Bool Horizontal)
+{
+ SolarMutexGuard aGuard;
+ if (Count <= 0)
+ throw uno::RuntimeException("Illegal first argument: needs to be > 0", getXWeak());
+ SwUnoCursor& rUnoCursor = GetCursor();
+ SwUnoTableCursor& rTableCursor = dynamic_cast<SwUnoTableCursor&>(rUnoCursor);
+ {
+ // HACK: remove pending actions for selecting old style tables
+ UnoActionRemoveContext aRemoveContext(rTableCursor);
+ }
+ rTableCursor.MakeBoxSels();
+ bool bResult;
+ {
+ UnoActionContext aContext(&rUnoCursor.GetDoc());
+ bResult = rTableCursor.GetDoc().SplitTable(rTableCursor.GetSelectedBoxes(), !Horizontal, Count);
+ }
+ rTableCursor.MakeBoxSels();
+ return bResult;
+}
+
+uno::Reference< beans::XPropertySetInfo > SwXTextTableCursor::getPropertySetInfo()
+{
+ static uno::Reference< beans::XPropertySetInfo > xRef = m_pPropSet->getPropertySetInfo();
+ return xRef;
+}
+
+void SwXTextTableCursor::setPropertyValue(const OUString& rPropertyName, const uno::Any& aValue)
+{
+ SolarMutexGuard aGuard;
+ SwUnoCursor& rUnoCursor = GetCursor();
+ auto pEntry(m_pPropSet->getPropertyMap().getByName(rPropertyName));
+ if(!pEntry)
+ throw beans::UnknownPropertyException("Unknown property: " + rPropertyName, getXWeak());
+ if(pEntry->nFlags & beans::PropertyAttribute::READONLY)
+ throw beans::PropertyVetoException("Property is read-only: " + rPropertyName, getXWeak());
+ {
+ auto pSttNode = rUnoCursor.GetPointNode().StartOfSectionNode();
+ const SwTableNode* pTableNode = pSttNode->FindTableNode();
+ lcl_FormatTable(pTableNode->GetTable().GetFrameFormat());
+ }
+ auto& rTableCursor = dynamic_cast<SwUnoTableCursor&>(rUnoCursor);
+ rTableCursor.MakeBoxSels();
+ SwDoc& rDoc = rUnoCursor.GetDoc();
+ switch(pEntry->nWID)
+ {
+ case FN_UNO_TABLE_CELL_BACKGROUND:
+ {
+ std::unique_ptr<SfxPoolItem> aBrush(std::make_unique<SvxBrushItem>(RES_BACKGROUND));
+ SwDoc::GetBoxAttr(rUnoCursor, aBrush);
+ aBrush->PutValue(aValue, pEntry->nMemberId);
+ rDoc.SetBoxAttr(rUnoCursor, *aBrush);
+
+ }
+ break;
+ case RES_BOXATR_FORMAT:
+ {
+ SfxUInt32Item aNumberFormat(RES_BOXATR_FORMAT);
+ aNumberFormat.PutValue(aValue, 0);
+ rDoc.SetBoxAttr(rUnoCursor, aNumberFormat);
+ }
+ break;
+ case FN_UNO_PARA_STYLE:
+ SwUnoCursorHelper::SetTextFormatColl(aValue, rUnoCursor);
+ break;
+ default:
+ {
+ SfxItemSet aItemSet(rDoc.GetAttrPool(), pEntry->nWID, pEntry->nWID);
+ SwUnoCursorHelper::GetCursorAttr(rTableCursor.GetSelRing(),
+ aItemSet);
+
+ if (!SwUnoCursorHelper::SetCursorPropertyValue(
+ *pEntry, aValue, rTableCursor.GetSelRing(), aItemSet))
+ {
+ m_pPropSet->setPropertyValue(*pEntry, aValue, aItemSet);
+ }
+ SwUnoCursorHelper::SetCursorAttr(rTableCursor.GetSelRing(),
+ aItemSet, SetAttrMode::DEFAULT, true);
+ }
+ }
+}
+
+uno::Any SwXTextTableCursor::getPropertyValue(const OUString& rPropertyName)
+{
+ SolarMutexGuard aGuard;
+ SwUnoCursor& rUnoCursor = GetCursor();
+ {
+ auto pSttNode = rUnoCursor.GetPointNode().StartOfSectionNode();
+ const SwTableNode* pTableNode = pSttNode->FindTableNode();
+ lcl_FormatTable(pTableNode->GetTable().GetFrameFormat());
+ }
+ SwUnoTableCursor& rTableCursor = dynamic_cast<SwUnoTableCursor&>(rUnoCursor);
+ auto pEntry(m_pPropSet->getPropertyMap().getByName(rPropertyName));
+ if(!pEntry)
+ throw beans::UnknownPropertyException("Unknown property: " + rPropertyName, getXWeak());
+ rTableCursor.MakeBoxSels();
+ uno::Any aResult;
+ switch(pEntry->nWID)
+ {
+ case FN_UNO_TABLE_CELL_BACKGROUND:
+ {
+ std::unique_ptr<SfxPoolItem> aBrush(std::make_unique<SvxBrushItem>(RES_BACKGROUND));
+ if (SwDoc::GetBoxAttr(rUnoCursor, aBrush))
+ aBrush->QueryValue(aResult, pEntry->nMemberId);
+ }
+ break;
+ case RES_BOXATR_FORMAT:
+ // TODO: GetAttr for table selections in a Doc is missing
+ throw uno::RuntimeException("Unknown property: " + rPropertyName, getXWeak());
+ break;
+ case FN_UNO_PARA_STYLE:
+ {
+ auto pFormat(SwUnoCursorHelper::GetCurTextFormatColl(rUnoCursor, false));
+ if(pFormat)
+ aResult <<= pFormat->GetName();
+ }
+ break;
+ default:
+ {
+ SfxItemSetFixed
+ <RES_CHRATR_BEGIN, RES_FRMATR_END-1,
+ RES_UNKNOWNATR_CONTAINER, RES_UNKNOWNATR_CONTAINER>
+ aSet(rTableCursor.GetDoc().GetAttrPool());
+ SwUnoCursorHelper::GetCursorAttr(rTableCursor.GetSelRing(), aSet);
+ m_pPropSet->getPropertyValue(*pEntry, aSet, aResult);
+ }
+ }
+ return aResult;
+}
+
+void SwXTextTableCursor::addPropertyChangeListener(const OUString& /*rPropertyName*/, const uno::Reference< beans::XPropertyChangeListener > & /*xListener*/)
+ { throw uno::RuntimeException("not implemented", getXWeak()); };
+
+void SwXTextTableCursor::removePropertyChangeListener(const OUString& /*rPropertyName*/, const uno::Reference< beans::XPropertyChangeListener > & /*xListener*/)
+ { throw uno::RuntimeException("not implemented", getXWeak()); };
+
+void SwXTextTableCursor::addVetoableChangeListener(const OUString& /*rPropertyName*/, const uno::Reference< beans::XVetoableChangeListener > & /*xListener*/)
+ { throw uno::RuntimeException("not implemented", getXWeak()); };
+
+void SwXTextTableCursor::removeVetoableChangeListener(const OUString& /*rPropertyName*/, const uno::Reference< beans::XVetoableChangeListener > & /*xListener*/)
+ { throw uno::RuntimeException("not implemented", getXWeak()); };
+
+void SwXTextTableCursor::Notify( const SfxHint& rHint )
+{
+ if(rHint.GetId() == SfxHintId::Dying)
+ m_pFrameFormat = nullptr;
+}
+
+
+// SwXTextTable ===========================================================
+
+namespace {
+
+class SwTableProperties_Impl
+{
+ SwUnoCursorHelper::SwAnyMapHelper m_aAnyMap;
+
+public:
+ SwTableProperties_Impl();
+
+ void SetProperty(sal_uInt16 nWhichId, sal_uInt16 nMemberId, const uno::Any& aVal);
+ bool GetProperty(sal_uInt16 nWhichId, sal_uInt16 nMemberId, const uno::Any*& rpAny);
+ void AddItemToSet(SfxItemSet& rSet, std::function<std::unique_ptr<SfxPoolItem>()> aItemFactory,
+ sal_uInt16 nWhich, std::initializer_list<sal_uInt16> vMember, bool bAddTwips = false);
+ void ApplyTableAttr(const SwTable& rTable, SwDoc& rDoc);
+};
+
+}
+
+SwTableProperties_Impl::SwTableProperties_Impl()
+ { }
+
+void SwTableProperties_Impl::SetProperty(sal_uInt16 nWhichId, sal_uInt16 nMemberId, const uno::Any& rVal)
+ {
+ m_aAnyMap.SetValue(nWhichId, nMemberId, rVal);
+ }
+
+bool SwTableProperties_Impl::GetProperty(sal_uInt16 nWhichId, sal_uInt16 nMemberId, const uno::Any*& rpAny )
+ {
+ return m_aAnyMap.FillValue(nWhichId, nMemberId, rpAny);
+ }
+
+void SwTableProperties_Impl::AddItemToSet(SfxItemSet& rSet,
+ std::function<std::unique_ptr<SfxPoolItem>()> aItemFactory,
+ sal_uInt16 nWhich, std::initializer_list<sal_uInt16> vMember, bool bAddTwips)
+{
+ std::vector< std::pair<sal_uInt16, const uno::Any* > > vMemberAndAny;
+ for(sal_uInt16 nMember : vMember)
+ {
+ const uno::Any* pAny = nullptr;
+ GetProperty(nWhich, nMember, pAny);
+ if(pAny)
+ vMemberAndAny.emplace_back(nMember, pAny);
+ }
+ if(!vMemberAndAny.empty())
+ {
+ std::unique_ptr<SfxPoolItem> aItem(aItemFactory());
+ for(const auto& aMemberAndAny : vMemberAndAny)
+ aItem->PutValue(*aMemberAndAny.second, aMemberAndAny.first | (bAddTwips ? CONVERT_TWIPS : 0) );
+ rSet.Put(std::move(aItem));
+ }
+}
+void SwTableProperties_Impl::ApplyTableAttr(const SwTable& rTable, SwDoc& rDoc)
+{
+ SfxItemSetFixed<
+ RES_FRM_SIZE, RES_BREAK,
+ RES_HORI_ORIENT, RES_HORI_ORIENT,
+ RES_BACKGROUND, RES_BACKGROUND,
+ RES_SHADOW, RES_SHADOW,
+ RES_KEEP, RES_KEEP,
+ RES_LAYOUT_SPLIT, RES_LAYOUT_SPLIT>
+ aSet(rDoc.GetAttrPool());
+ const uno::Any* pRepHead;
+ const SwFrameFormat &rFrameFormat = *rTable.GetFrameFormat();
+ if(GetProperty(FN_TABLE_HEADLINE_REPEAT, 0xff, pRepHead ))
+ {
+ bool bVal(pRepHead->get<bool>());
+ const_cast<SwTable&>(rTable).SetRowsToRepeat( bVal ? 1 : 0 ); // TODO: MULTIHEADER
+ }
+
+ AddItemToSet(aSet, [&rFrameFormat]() { return rFrameFormat.makeBackgroundBrushItem(); }, RES_BACKGROUND, {
+ MID_BACK_COLOR,
+ MID_GRAPHIC_TRANSPARENT,
+ MID_GRAPHIC_POSITION,
+ MID_GRAPHIC,
+ MID_GRAPHIC_FILTER });
+
+ bool bPutBreak = true;
+ const uno::Any* pPage;
+ if(GetProperty(FN_UNO_PAGE_STYLE, 0, pPage) || GetProperty(RES_PAGEDESC, 0xff, pPage))
+ {
+ OUString sPageStyle = pPage->get<OUString>();
+ if(!sPageStyle.isEmpty())
+ {
+ SwStyleNameMapper::FillUIName(sPageStyle, sPageStyle, SwGetPoolIdFromName::PageDesc);
+ const SwPageDesc* pDesc = SwPageDesc::GetByName(rDoc, sPageStyle);
+ if(pDesc)
+ {
+ SwFormatPageDesc aDesc(pDesc);
+ const uno::Any* pPgNo;
+ if(GetProperty(RES_PAGEDESC, MID_PAGEDESC_PAGENUMOFFSET, pPgNo))
+ {
+ aDesc.SetNumOffset(pPgNo->get<sal_Int16>());
+ }
+ aSet.Put(aDesc);
+ bPutBreak = false;
+ }
+
+ }
+ }
+
+ if(bPutBreak)
+ AddItemToSet(aSet, [&rFrameFormat]() { return std::unique_ptr<SfxPoolItem>(rFrameFormat.GetBreak().Clone()); }, RES_BREAK, {0});
+ AddItemToSet(aSet, [&rFrameFormat]() { return std::unique_ptr<SfxPoolItem>(rFrameFormat.GetShadow().Clone()); }, RES_SHADOW, {0}, true);
+ AddItemToSet(aSet, [&rFrameFormat]() { return std::unique_ptr<SfxPoolItem>(rFrameFormat.GetKeep().Clone()); }, RES_KEEP, {0});
+ AddItemToSet(aSet, [&rFrameFormat]() { return std::unique_ptr<SfxPoolItem>(rFrameFormat.GetHoriOrient().Clone()); }, RES_HORI_ORIENT, {MID_HORIORIENT_ORIENT}, true);
+
+ const uno::Any* pSzRel(nullptr);
+ GetProperty(FN_TABLE_IS_RELATIVE_WIDTH, 0xff, pSzRel);
+ const uno::Any* pRelWidth(nullptr);
+ GetProperty(FN_TABLE_RELATIVE_WIDTH, 0xff, pRelWidth);
+ const uno::Any* pWidth(nullptr);
+ GetProperty(FN_TABLE_WIDTH, 0xff, pWidth);
+
+ bool bPutSize = pWidth != nullptr;
+ SwFormatFrameSize aSz(SwFrameSize::Variable);
+ if(pWidth)
+ {
+ aSz.PutValue(*pWidth, MID_FRMSIZE_WIDTH);
+ bPutSize = true;
+ }
+ if(pSzRel && pSzRel->get<bool>() && pRelWidth)
+ {
+ aSz.PutValue(*pRelWidth, MID_FRMSIZE_REL_WIDTH|CONVERT_TWIPS);
+ bPutSize = true;
+ }
+ if(bPutSize)
+ {
+ if(!aSz.GetWidth())
+ aSz.SetWidth(MINLAY);
+ aSet.Put(aSz);
+ }
+ AddItemToSet(aSet, [&rFrameFormat]() { return std::unique_ptr<SfxPoolItem>(rFrameFormat.GetLRSpace().Clone()); }, RES_LR_SPACE, {
+ MID_L_MARGIN|CONVERT_TWIPS,
+ MID_R_MARGIN|CONVERT_TWIPS });
+ AddItemToSet(aSet, [&rFrameFormat]() { return std::unique_ptr<SfxPoolItem>(rFrameFormat.GetULSpace().Clone()); }, RES_UL_SPACE, {
+ MID_UP_MARGIN|CONVERT_TWIPS,
+ MID_LO_MARGIN|CONVERT_TWIPS });
+ const::uno::Any* pSplit(nullptr);
+ if(GetProperty(RES_LAYOUT_SPLIT, 0, pSplit))
+ {
+ SwFormatLayoutSplit aSp(pSplit->get<bool>());
+ aSet.Put(aSp);
+ }
+ if(aSet.Count())
+ {
+ rDoc.SetAttr(aSet, *rTable.GetFrameFormat());
+ }
+}
+
+class SwXTextTable::Impl
+ : public SvtListener
+{
+private:
+ SwFrameFormat* m_pFrameFormat;
+
+public:
+ unotools::WeakReference<SwXTextTable> m_wThis;
+ std::mutex m_Mutex; // just for OInterfaceContainerHelper4
+ ::comphelper::OInterfaceContainerHelper4<css::lang::XEventListener> m_EventListeners;
+ ::comphelper::OInterfaceContainerHelper4<chart::XChartDataChangeEventListener> m_ChartListeners;
+
+ const SfxItemPropertySet * m_pPropSet;
+
+ css::uno::WeakReference<css::table::XTableRows> m_xRows;
+ css::uno::WeakReference<css::table::XTableColumns> m_xColumns;
+
+ bool m_bFirstRowAsLabel;
+ bool m_bFirstColumnAsLabel;
+
+ // Descriptor-interface
+ std::unique_ptr<SwTableProperties_Impl> m_pTableProps;
+ OUString m_sTableName;
+ unsigned short m_nRows;
+ unsigned short m_nColumns;
+
+ explicit Impl(SwFrameFormat* const pFrameFormat)
+ : m_pFrameFormat(pFrameFormat)
+ , m_pPropSet(aSwMapProvider.GetPropertySet(PROPERTY_MAP_TEXT_TABLE))
+ , m_bFirstRowAsLabel(false)
+ , m_bFirstColumnAsLabel(false)
+ , m_pTableProps(pFrameFormat ? nullptr : new SwTableProperties_Impl)
+ , m_nRows(pFrameFormat ? 0 : 2)
+ , m_nColumns(pFrameFormat ? 0 : 2)
+ {
+ if(m_pFrameFormat)
+ StartListening(m_pFrameFormat->GetNotifier());
+ }
+
+ SwFrameFormat* GetFrameFormat() { return m_pFrameFormat; }
+ void SetFrameFormat(SwFrameFormat& rFrameFormat)
+ {
+ EndListeningAll();
+ m_pFrameFormat = &rFrameFormat;
+ StartListening(m_pFrameFormat->GetNotifier());
+ }
+
+ bool IsDescriptor() const { return m_pTableProps != nullptr; }
+
+ // note: lock mutex before calling this to avoid concurrent update
+ static std::pair<sal_uInt16, sal_uInt16> ThrowIfComplex(SwXTextTable &rThis)
+ {
+ sal_uInt16 const nRowCount(rThis.m_pImpl->GetRowCount());
+ sal_uInt16 const nColCount(rThis.m_pImpl->GetColumnCount());
+ if (!nRowCount || !nColCount)
+ {
+ throw uno::RuntimeException("Table too complex", rThis.getXWeak());
+ }
+ return std::make_pair(nRowCount, nColCount);
+ }
+
+ sal_uInt16 GetRowCount();
+ sal_uInt16 GetColumnCount();
+
+ virtual void Notify(const SfxHint&) override;
+
+};
+
+SwXTextTable::SwXTextTable()
+ : m_pImpl(new Impl(nullptr))
+{
+}
+
+SwXTextTable::SwXTextTable(SwFrameFormat& rFrameFormat)
+ : m_pImpl(new Impl(&rFrameFormat))
+{
+}
+
+SwXTextTable::~SwXTextTable()
+{
+}
+
+rtl::Reference<SwXTextTable> SwXTextTable::CreateXTextTable(SwFrameFormat* const pFrameFormat)
+{
+ rtl::Reference<SwXTextTable> xTable;
+ if(pFrameFormat)
+ xTable = dynamic_cast<SwXTextTable*>(pFrameFormat->GetXObject().get().get()); // cached?
+ if(xTable.is())
+ return xTable;
+ xTable = pFrameFormat ? new SwXTextTable(*pFrameFormat) : new SwXTextTable();
+ if(pFrameFormat)
+ pFrameFormat->SetXObject(xTable->getXWeak());
+ // need a permanent Reference to initialize m_wThis
+ xTable->m_pImpl->m_wThis = xTable.get();
+ return xTable;
+}
+
+SwFrameFormat* SwXTextTable::GetFrameFormat()
+{
+ return m_pImpl->GetFrameFormat();
+}
+
+void SwXTextTable::initialize(sal_Int32 nR, sal_Int32 nC)
+{
+ if (!m_pImpl->IsDescriptor() || nR <= 0 || nC <= 0 || nR >= SAL_MAX_UINT16 || nC >= SAL_MAX_UINT16)
+ throw uno::RuntimeException();
+ m_pImpl->m_nRows = o3tl::narrowing<sal_uInt16>(nR);
+ m_pImpl->m_nColumns = o3tl::narrowing<sal_uInt16>(nC);
+}
+
+uno::Reference<table::XTableRows> SAL_CALL SwXTextTable::getRows()
+{
+ SolarMutexGuard aGuard;
+ uno::Reference<table::XTableRows> xResult(m_pImpl->m_xRows);
+ if(xResult.is())
+ return xResult;
+ if(SwFrameFormat* pFormat = GetFrameFormat())
+ m_pImpl->m_xRows = xResult = new SwXTableRows(*pFormat);
+ if(!xResult.is())
+ throw uno::RuntimeException();
+ return xResult;
+}
+
+uno::Reference<table::XTableColumns> SAL_CALL SwXTextTable::getColumns()
+{
+ SolarMutexGuard aGuard;
+ uno::Reference<table::XTableColumns> xResult(m_pImpl->m_xColumns);
+ if(xResult.is())
+ return xResult;
+ if(SwFrameFormat* pFormat = GetFrameFormat())
+ m_pImpl->m_xColumns = xResult = new SwXTableColumns(*pFormat);
+ if(!xResult.is())
+ throw uno::RuntimeException();
+ return xResult;
+}
+
+uno::Reference<table::XCell> SwXTextTable::getCellByName(const OUString& sCellName)
+{
+ SolarMutexGuard aGuard;
+ SwFrameFormat* pFormat = lcl_EnsureCoreConnected(GetFrameFormat(), this);
+ SwTable* pTable = SwTable::FindTable(pFormat);
+ SwTableBox* pBox = const_cast<SwTableBox*>(pTable->GetTableBox(sCellName));
+ if(!pBox)
+ return nullptr;
+ return SwXCell::CreateXCell(pFormat, pBox);
+}
+
+uno::Sequence<OUString> SwXTextTable::getCellNames()
+{
+ SolarMutexGuard aGuard;
+ SwFrameFormat* pFormat(GetFrameFormat());
+ if(!pFormat)
+ return {};
+ SwTable* pTable = SwTable::FindTable(pFormat);
+ // exists at the table and at all boxes
+ SwTableLines& rTableLines = pTable->GetTabLines();
+ std::vector<OUString> aAllNames;
+ lcl_InspectLines(rTableLines, aAllNames);
+ return comphelper::containerToSequence(aAllNames);
+}
+
+uno::Reference<text::XTextTableCursor> SwXTextTable::createCursorByCellName(const OUString& sCellName)
+{
+ SolarMutexGuard aGuard;
+ SwFrameFormat* pFormat = lcl_EnsureCoreConnected(GetFrameFormat(), this);
+ SwTable* pTable = SwTable::FindTable(pFormat);
+ SwTableBox* pBox = const_cast<SwTableBox*>(pTable->GetTableBox(sCellName));
+ if(!pBox || pBox->getRowSpan() == 0)
+ throw uno::RuntimeException();
+ return new SwXTextTableCursor(pFormat, pBox);
+}
+
+void SAL_CALL
+SwXTextTable::attach(const uno::Reference<text::XTextRange> & xTextRange)
+{
+ SolarMutexGuard aGuard;
+
+ // attach() must only be called once
+ if (!m_pImpl->IsDescriptor()) /* already attached ? */
+ throw uno::RuntimeException("SwXTextTable: already attached to range.", getXWeak());
+
+ SwXTextRange* pRange(dynamic_cast<SwXTextRange*>(xTextRange.get()));
+ OTextCursorHelper* pCursor(dynamic_cast<OTextCursorHelper*>(xTextRange.get()));
+ SwDoc* pDoc = pRange ? &pRange->GetDoc() : pCursor ? pCursor->GetDoc() : nullptr;
+ if (!pDoc || !m_pImpl->m_nRows || !m_pImpl->m_nColumns)
+ throw lang::IllegalArgumentException();
+ SwUnoInternalPaM aPam(*pDoc);
+ // this now needs to return TRUE
+ ::sw::XTextRangeToSwPaM(aPam, xTextRange);
+ {
+ UnoActionContext aCont(pDoc);
+
+ pDoc->GetIDocumentUndoRedo().StartUndo(SwUndoId::EMPTY, nullptr);
+ const SwTable* pTable(nullptr);
+ if( 0 != aPam.Start()->GetContentIndex() )
+ {
+ pDoc->getIDocumentContentOperations().SplitNode(*aPam.Start(), false);
+ }
+ //TODO: if it is the last paragraph than add another one!
+ if(aPam.HasMark())
+ {
+ pDoc->getIDocumentContentOperations().DeleteAndJoin(aPam);
+ aPam.DeleteMark();
+ }
+
+ OUString tableName;
+ if (const::uno::Any* pName;
+ m_pImpl->m_pTableProps->GetProperty(FN_UNO_TABLE_NAME, 0, pName))
+ {
+ tableName = pName->get<OUString>();
+ }
+ else if (!m_pImpl->m_sTableName.isEmpty())
+ {
+ sal_uInt16 nIndex = 1;
+ tableName = m_pImpl->m_sTableName;
+ while (pDoc->FindTableFormatByName(tableName, true) && nIndex < USHRT_MAX)
+ tableName = m_pImpl->m_sTableName + OUString::number(nIndex++);
+ }
+
+ pTable = pDoc->InsertTable(SwInsertTableOptions( SwInsertTableFlags::Headline | SwInsertTableFlags::DefaultBorder | SwInsertTableFlags::SplitLayout, 0 ),
+ *aPam.GetPoint(),
+ m_pImpl->m_nRows,
+ m_pImpl->m_nColumns,
+ text::HoriOrientation::FULL,
+ nullptr, nullptr, false, true,
+ tableName);
+ if(pTable)
+ {
+ // here, the properties of the descriptor need to be analyzed
+ m_pImpl->m_pTableProps->ApplyTableAttr(*pTable, *pDoc);
+ SwFrameFormat* pTableFormat(pTable->GetFrameFormat());
+ lcl_FormatTable(pTableFormat);
+
+ m_pImpl->SetFrameFormat(*pTableFormat);
+
+ m_pImpl->m_pTableProps.reset();
+ }
+ pDoc->GetIDocumentUndoRedo().EndUndo( SwUndoId::END, nullptr );
+ }
+}
+
+uno::Reference<text::XTextRange> SwXTextTable::getAnchor()
+{
+ SolarMutexGuard aGuard;
+ SwTableFormat *const pFormat = static_cast<SwTableFormat*>(
+ lcl_EnsureCoreConnected(GetFrameFormat(), this));
+ return new SwXTextRange(*pFormat);
+}
+
+void SwXTextTable::dispose()
+{
+ SolarMutexGuard aGuard;
+ SwFrameFormat* pFormat = lcl_EnsureCoreConnected(GetFrameFormat(), this);
+ SwTable* pTable = SwTable::FindTable(pFormat);
+ SwSelBoxes aSelBoxes;
+ for(auto& rBox : pTable->GetTabSortBoxes() )
+ aSelBoxes.insert(rBox);
+ pFormat->GetDoc()->DeleteRowCol(aSelBoxes, SwDoc::RowColMode::DeleteProtected);
+}
+
+void SAL_CALL SwXTextTable::addEventListener(
+ const uno::Reference<lang::XEventListener> & xListener)
+{
+ // no need to lock here as m_pImpl is const and container threadsafe
+ std::unique_lock aGuard(m_pImpl->m_Mutex);
+ m_pImpl->m_EventListeners.addInterface(aGuard, xListener);
+}
+
+void SAL_CALL SwXTextTable::removeEventListener(
+ const uno::Reference< lang::XEventListener > & xListener)
+{
+ // no need to lock here as m_pImpl is const and container threadsafe
+ std::unique_lock aGuard(m_pImpl->m_Mutex);
+ m_pImpl->m_EventListeners.removeInterface(aGuard, xListener);
+}
+
+uno::Reference<table::XCell> SwXTextTable::getCellByPosition(sal_Int32 nColumn, sal_Int32 nRow)
+{
+ SolarMutexGuard aGuard;
+ SwFrameFormat* pFormat(GetFrameFormat());
+ // sheet is unimportant
+ if(nColumn >= 0 && nRow >= 0 && pFormat)
+ {
+ auto pXCell = lcl_CreateXCell(pFormat, nColumn, nRow);
+ if(pXCell)
+ return pXCell;
+ }
+ throw lang::IndexOutOfBoundsException();
+}
+
+namespace {
+
+rtl::Reference<SwXCellRange> GetRangeByName(
+ SwFrameFormat* pFormat, SwTable const * pTable,
+ const OUString& rTLName, const OUString& rBRName,
+ SwRangeDescriptor const & rDesc)
+{
+ const SwTableBox* pTLBox = pTable->GetTableBox(rTLName);
+ if(!pTLBox)
+ return nullptr;
+ const SwStartNode* pSttNd = pTLBox->GetSttNd();
+ SwPosition aPos(*pSttNd);
+ // set cursor to the upper-left cell of the range
+ auto pUnoCursor(pFormat->GetDoc()->CreateUnoCursor(aPos, true));
+ pUnoCursor->Move(fnMoveForward, GoInNode);
+ pUnoCursor->SetRemainInSection(false);
+ const SwTableBox* pBRBox(pTable->GetTableBox(rBRName));
+ if(!pBRBox)
+ return nullptr;
+ pUnoCursor->SetMark();
+ pUnoCursor->GetPoint()->Assign( *pBRBox->GetSttNd() );
+ pUnoCursor->Move( fnMoveForward, GoInNode );
+ SwUnoTableCursor& rCursor = dynamic_cast<SwUnoTableCursor&>(*pUnoCursor);
+ // HACK: remove pending actions for selecting old style tables
+ UnoActionRemoveContext aRemoveContext(rCursor);
+ rCursor.MakeBoxSels();
+ // pUnoCursor will be provided and will not be deleted
+ return SwXCellRange::CreateXCellRange(pUnoCursor, *pFormat, rDesc);
+}
+
+} // namespace
+
+uno::Reference<table::XCellRange> SwXTextTable::getCellRangeByPosition(sal_Int32 nLeft, sal_Int32 nTop, sal_Int32 nRight, sal_Int32 nBottom)
+{
+ SolarMutexGuard aGuard;
+ SwFrameFormat* pFormat(GetFrameFormat());
+ if(pFormat &&
+ nLeft <= nRight && nTop <= nBottom &&
+ nLeft >= 0 && nRight >= 0 && nTop >= 0 && nBottom >= 0 )
+ {
+ SwTable* pTable = SwTable::FindTable(pFormat);
+ if(!pTable->IsTableComplex())
+ {
+ SwRangeDescriptor aDesc;
+ aDesc.nTop = nTop;
+ aDesc.nBottom = nBottom;
+ aDesc.nLeft = nLeft;
+ aDesc.nRight = nRight;
+ const OUString sTLName = sw_GetCellName(aDesc.nLeft, aDesc.nTop);
+ const OUString sBRName = sw_GetCellName(aDesc.nRight, aDesc.nBottom);
+ // please note that according to the 'if' statement at the begin
+ // sTLName:sBRName already denotes the normalized range string
+ return GetRangeByName(pFormat, pTable, sTLName, sBRName, aDesc);
+ }
+ }
+ throw lang::IndexOutOfBoundsException();
+}
+
+uno::Reference<table::XCellRange> SwXTextTable::getCellRangeByName(const OUString& sRange)
+{
+ SolarMutexGuard aGuard;
+ SwFrameFormat* pFormat = lcl_EnsureCoreConnected(GetFrameFormat(), this);
+ SwTable* pTable = lcl_EnsureTableNotComplex(SwTable::FindTable(pFormat), this);
+ sal_Int32 nPos = 0;
+ const OUString sTLName(sRange.getToken(0, ':', nPos));
+ const OUString sBRName(sRange.getToken(0, ':', nPos));
+ if(sTLName.isEmpty() || sBRName.isEmpty())
+ throw uno::RuntimeException();
+ SwRangeDescriptor aDesc;
+ aDesc.nTop = aDesc.nLeft = aDesc.nBottom = aDesc.nRight = -1;
+ SwXTextTable::GetCellPosition(sTLName, aDesc.nLeft, aDesc.nTop );
+ SwXTextTable::GetCellPosition(sBRName, aDesc.nRight, aDesc.nBottom );
+
+ // we should normalize the range now (e.g. A5:C1 will become A1:C5)
+ // since (depending on what is done later) it will be troublesome
+ // elsewhere when the cursor in the implementation does not
+ // point to the top-left and bottom-right cells
+ aDesc.Normalize();
+ return GetRangeByName(pFormat, pTable, sTLName, sBRName, aDesc);
+}
+
+uno::Sequence< uno::Sequence< uno::Any > > SAL_CALL SwXTextTable::getDataArray()
+{
+ SolarMutexGuard aGuard;
+ std::pair<sal_uInt16, sal_uInt16> const RowsAndColumns(SwXTextTable::Impl::ThrowIfComplex(*this));
+ uno::Reference<sheet::XCellRangeData> const xAllRange(
+ getCellRangeByPosition(0, 0, RowsAndColumns.second-1, RowsAndColumns.first-1),
+ uno::UNO_QUERY_THROW);
+ return xAllRange->getDataArray();
+}
+
+void SAL_CALL SwXTextTable::setDataArray(const uno::Sequence< uno::Sequence< uno::Any > >& rArray)
+{
+ SolarMutexGuard aGuard;
+ std::pair<sal_uInt16, sal_uInt16> const RowsAndColumns(SwXTextTable::Impl::ThrowIfComplex(*this));
+ uno::Reference<sheet::XCellRangeData> const xAllRange(
+ getCellRangeByPosition(0, 0, RowsAndColumns.second-1, RowsAndColumns.first-1),
+ uno::UNO_QUERY_THROW);
+ return xAllRange->setDataArray(rArray);
+}
+
+uno::Sequence< uno::Sequence< double > > SwXTextTable::getData()
+{
+ SolarMutexGuard aGuard;
+ std::pair<sal_uInt16, sal_uInt16> const RowsAndColumns(SwXTextTable::Impl::ThrowIfComplex(*this));
+ uno::Reference<chart::XChartDataArray> const xAllRange(
+ getCellRangeByPosition(0, 0, RowsAndColumns.second-1, RowsAndColumns.first-1),
+ uno::UNO_QUERY_THROW);
+ static_cast<SwXCellRange*>(xAllRange.get())->SetLabels(
+ m_pImpl->m_bFirstRowAsLabel, m_pImpl->m_bFirstColumnAsLabel);
+ return xAllRange->getData();
+}
+
+void SwXTextTable::setData(const uno::Sequence< uno::Sequence< double > >& rData)
+{
+ SolarMutexGuard aGuard;
+ std::pair<sal_uInt16, sal_uInt16> const RowsAndColumns(SwXTextTable::Impl::ThrowIfComplex(*this));
+ uno::Reference<chart::XChartDataArray> const xAllRange(
+ getCellRangeByPosition(0, 0, RowsAndColumns.second-1, RowsAndColumns.first-1),
+ uno::UNO_QUERY_THROW);
+ static_cast<SwXCellRange*>(xAllRange.get())->SetLabels(
+ m_pImpl->m_bFirstRowAsLabel, m_pImpl->m_bFirstColumnAsLabel);
+ xAllRange->setData(rData);
+ // this is rather inconsistent: setData on XTextTable sends events, but e.g. CellRanges do not
+ std::unique_lock aGuard2(m_pImpl->m_Mutex);
+ lcl_SendChartEvent(aGuard2, *this, m_pImpl->m_ChartListeners);
+}
+
+uno::Sequence<OUString> SwXTextTable::getRowDescriptions()
+{
+ SolarMutexGuard aGuard;
+ std::pair<sal_uInt16, sal_uInt16> const RowsAndColumns(SwXTextTable::Impl::ThrowIfComplex(*this));
+ uno::Reference<chart::XChartDataArray> const xAllRange(
+ getCellRangeByPosition(0, 0, RowsAndColumns.second-1, RowsAndColumns.first-1),
+ uno::UNO_QUERY_THROW);
+ static_cast<SwXCellRange*>(xAllRange.get())->SetLabels(
+ m_pImpl->m_bFirstRowAsLabel, m_pImpl->m_bFirstColumnAsLabel);
+ return xAllRange->getRowDescriptions();
+}
+
+void SwXTextTable::setRowDescriptions(const uno::Sequence<OUString>& rRowDesc)
+{
+ SolarMutexGuard aGuard;
+ std::pair<sal_uInt16, sal_uInt16> const RowsAndColumns(SwXTextTable::Impl::ThrowIfComplex(*this));
+ uno::Reference<chart::XChartDataArray> const xAllRange(
+ getCellRangeByPosition(0, 0, RowsAndColumns.second-1, RowsAndColumns.first-1),
+ uno::UNO_QUERY_THROW);
+ static_cast<SwXCellRange*>(xAllRange.get())->SetLabels(
+ m_pImpl->m_bFirstRowAsLabel, m_pImpl->m_bFirstColumnAsLabel);
+ xAllRange->setRowDescriptions(rRowDesc);
+}
+
+uno::Sequence<OUString> SwXTextTable::getColumnDescriptions()
+{
+ SolarMutexGuard aGuard;
+ std::pair<sal_uInt16, sal_uInt16> const RowsAndColumns(SwXTextTable::Impl::ThrowIfComplex(*this));
+ uno::Reference<chart::XChartDataArray> const xAllRange(
+ getCellRangeByPosition(0, 0, RowsAndColumns.second-1, RowsAndColumns.first-1),
+ uno::UNO_QUERY_THROW);
+ static_cast<SwXCellRange*>(xAllRange.get())->SetLabels(
+ m_pImpl->m_bFirstRowAsLabel, m_pImpl->m_bFirstColumnAsLabel);
+ return xAllRange->getColumnDescriptions();
+}
+
+void SwXTextTable::setColumnDescriptions(const uno::Sequence<OUString>& rColumnDesc)
+{
+ SolarMutexGuard aGuard;
+ std::pair<sal_uInt16, sal_uInt16> const RowsAndColumns(SwXTextTable::Impl::ThrowIfComplex(*this));
+ uno::Reference<chart::XChartDataArray> const xAllRange(
+ getCellRangeByPosition(0, 0, RowsAndColumns.second-1, RowsAndColumns.first-1),
+ uno::UNO_QUERY_THROW);
+ static_cast<SwXCellRange*>(xAllRange.get())->SetLabels(
+ m_pImpl->m_bFirstRowAsLabel, m_pImpl->m_bFirstColumnAsLabel);
+ return xAllRange->setColumnDescriptions(rColumnDesc);
+}
+
+void SAL_CALL SwXTextTable::addChartDataChangeEventListener(
+ const uno::Reference<chart::XChartDataChangeEventListener> & xListener)
+{
+ // no need to lock here as m_pImpl is const and container threadsafe
+ std::unique_lock aGuard(m_pImpl->m_Mutex);
+ m_pImpl->m_ChartListeners.addInterface(aGuard, xListener);
+}
+
+void SAL_CALL SwXTextTable::removeChartDataChangeEventListener(
+ const uno::Reference<chart::XChartDataChangeEventListener> & xListener)
+{
+ // no need to lock here as m_pImpl is const and container threadsafe
+ std::unique_lock aGuard(m_pImpl->m_Mutex);
+ m_pImpl->m_ChartListeners.removeInterface(aGuard, xListener);
+}
+
+sal_Bool SwXTextTable::isNotANumber(double nNumber)
+{
+ // We use DBL_MIN because starcalc does (which uses it because chart
+ // wants it that way!)
+ return ( nNumber == DBL_MIN );
+}
+
+double SwXTextTable::getNotANumber()
+{
+ // We use DBL_MIN because starcalc does (which uses it because chart
+ // wants it that way!)
+ return DBL_MIN;
+}
+
+uno::Sequence< beans::PropertyValue > SwXTextTable::createSortDescriptor()
+{
+ SolarMutexGuard aGuard;
+
+ return SwUnoCursorHelper::CreateSortDescriptor(true);
+}
+
+void SwXTextTable::sort(const uno::Sequence< beans::PropertyValue >& rDescriptor)
+{
+ SolarMutexGuard aGuard;
+ SwSortOptions aSortOpt;
+ SwFrameFormat* pFormat = GetFrameFormat();
+ if(!(pFormat &&
+ SwUnoCursorHelper::ConvertSortProperties(rDescriptor, aSortOpt)))
+ return;
+
+ SwTable* pTable = SwTable::FindTable( pFormat );
+ SwSelBoxes aBoxes;
+ const SwTableSortBoxes& rTBoxes = pTable->GetTabSortBoxes();
+ for (size_t n = 0; n < rTBoxes.size(); ++n)
+ {
+ SwTableBox* pBox = rTBoxes[ n ];
+ aBoxes.insert( pBox );
+ }
+ UnoActionContext aContext( pFormat->GetDoc() );
+ pFormat->GetDoc()->SortTable(aBoxes, aSortOpt);
+}
+
+void SwXTextTable::autoFormat(const OUString& sAutoFormatName)
+{
+ SolarMutexGuard aGuard;
+ SwFrameFormat* pFormat = lcl_EnsureCoreConnected(GetFrameFormat(), this);
+ SwTable* pTable = lcl_EnsureTableNotComplex(SwTable::FindTable(pFormat), this);
+ SwTableAutoFormatTable aAutoFormatTable;
+ aAutoFormatTable.Load();
+ for (size_t i = aAutoFormatTable.size(); i;)
+ if( sAutoFormatName == aAutoFormatTable[ --i ].GetName() )
+ {
+ SwSelBoxes aBoxes;
+ const SwTableSortBoxes& rTBoxes = pTable->GetTabSortBoxes();
+ for (size_t n = 0; n < rTBoxes.size(); ++n)
+ {
+ SwTableBox* pBox = rTBoxes[ n ];
+ aBoxes.insert( pBox );
+ }
+ UnoActionContext aContext( pFormat->GetDoc() );
+ pFormat->GetDoc()->SetTableAutoFormat( aBoxes, aAutoFormatTable[i] );
+ break;
+ }
+}
+
+uno::Reference< beans::XPropertySetInfo > SwXTextTable::getPropertySetInfo()
+{
+ static uno::Reference<beans::XPropertySetInfo> xRef = m_pImpl->m_pPropSet->getPropertySetInfo();
+ return xRef;
+}
+
+void SwXTextTable::setPropertyValue(const OUString& rPropertyName, const uno::Any& aValue)
+{
+ SolarMutexGuard aGuard;
+ SwFrameFormat* pFormat = GetFrameFormat();
+ if(!aValue.hasValue())
+ throw lang::IllegalArgumentException();
+ const SfxItemPropertyMapEntry* pEntry =
+ m_pImpl->m_pPropSet->getPropertyMap().getByName(rPropertyName);
+ if( !pEntry )
+ throw lang::IllegalArgumentException();
+ if(pFormat)
+ {
+ if ( pEntry->nFlags & beans::PropertyAttribute::READONLY)
+ throw beans::PropertyVetoException("Property is read-only: " + rPropertyName, getXWeak() );
+
+ if(0xBF == pEntry->nMemberId)
+ {
+ lcl_SetSpecialProperty(pFormat, pEntry, aValue);
+ }
+ else
+ {
+ switch(pEntry->nWID)
+ {
+ case FN_UNO_TABLE_NAME :
+ {
+ OUString sName;
+ aValue >>= sName;
+ setName( sName );
+ }
+ break;
+
+ case FN_UNO_RANGE_ROW_LABEL:
+ {
+ bool bTmp = *o3tl::doAccess<bool>(aValue);
+ if (m_pImpl->m_bFirstRowAsLabel != bTmp)
+ {
+ std::unique_lock aGuard2(m_pImpl->m_Mutex);
+ lcl_SendChartEvent(aGuard2, *this, m_pImpl->m_ChartListeners);
+ m_pImpl->m_bFirstRowAsLabel = bTmp;
+ }
+ }
+ break;
+
+ case FN_UNO_RANGE_COL_LABEL:
+ {
+ bool bTmp = *o3tl::doAccess<bool>(aValue);
+ if (m_pImpl->m_bFirstColumnAsLabel != bTmp)
+ {
+ std::unique_lock aGuard2(m_pImpl->m_Mutex);
+ lcl_SendChartEvent(aGuard2, *this, m_pImpl->m_ChartListeners);
+ m_pImpl->m_bFirstColumnAsLabel = bTmp;
+ }
+ }
+ break;
+
+ case FN_UNO_TABLE_BORDER:
+ case FN_UNO_TABLE_BORDER2:
+ {
+ table::TableBorder oldBorder;
+ table::TableBorder2 aBorder;
+ SvxBorderLine aTopLine;
+ SvxBorderLine aBottomLine;
+ SvxBorderLine aLeftLine;
+ SvxBorderLine aRightLine;
+ SvxBorderLine aHoriLine;
+ SvxBorderLine aVertLine;
+ if (aValue >>= oldBorder)
+ {
+ aBorder.IsTopLineValid = oldBorder.IsTopLineValid;
+ aBorder.IsBottomLineValid = oldBorder.IsBottomLineValid;
+ aBorder.IsLeftLineValid = oldBorder.IsLeftLineValid;
+ aBorder.IsRightLineValid = oldBorder.IsRightLineValid;
+ aBorder.IsHorizontalLineValid = oldBorder.IsHorizontalLineValid;
+ aBorder.IsVerticalLineValid = oldBorder.IsVerticalLineValid;
+ aBorder.Distance = oldBorder.Distance;
+ aBorder.IsDistanceValid = oldBorder.IsDistanceValid;
+ lcl_LineToSvxLine(
+ oldBorder.TopLine, aTopLine);
+ lcl_LineToSvxLine(
+ oldBorder.BottomLine, aBottomLine);
+ lcl_LineToSvxLine(
+ oldBorder.LeftLine, aLeftLine);
+ lcl_LineToSvxLine(
+ oldBorder.RightLine, aRightLine);
+ lcl_LineToSvxLine(
+ oldBorder.HorizontalLine, aHoriLine);
+ lcl_LineToSvxLine(
+ oldBorder.VerticalLine, aVertLine);
+ }
+ else if (aValue >>= aBorder)
+ {
+ SvxBoxItem::LineToSvxLine(
+ aBorder.TopLine, aTopLine, true);
+ SvxBoxItem::LineToSvxLine(
+ aBorder.BottomLine, aBottomLine, true);
+ SvxBoxItem::LineToSvxLine(
+ aBorder.LeftLine, aLeftLine, true);
+ SvxBoxItem::LineToSvxLine(
+ aBorder.RightLine, aRightLine, true);
+ SvxBoxItem::LineToSvxLine(
+ aBorder.HorizontalLine, aHoriLine, true);
+ SvxBoxItem::LineToSvxLine(
+ aBorder.VerticalLine, aVertLine, true);
+ }
+ else
+ {
+ break; // something else
+ }
+ SwDoc* pDoc = pFormat->GetDoc();
+ if(!lcl_FormatTable(pFormat))
+ break;
+ SwTable* pTable = SwTable::FindTable( pFormat );
+ SwTableLines &rLines = pTable->GetTabLines();
+
+ const SwTableBox* pTLBox = lcl_FindCornerTableBox(rLines, true);
+ const SwStartNode* pSttNd = pTLBox->GetSttNd();
+ SwPosition aPos(*pSttNd);
+ // set cursor to top left cell
+ auto pUnoCursor(pDoc->CreateUnoCursor(aPos, true));
+ pUnoCursor->Move( fnMoveForward, GoInNode );
+ pUnoCursor->SetRemainInSection( false );
+
+ const SwTableBox* pBRBox = lcl_FindCornerTableBox(rLines, false);
+ pUnoCursor->SetMark();
+ pUnoCursor->GetPoint()->Assign( *pBRBox->GetSttNd() );
+ pUnoCursor->Move( fnMoveForward, GoInNode );
+ SwUnoTableCursor& rCursor = dynamic_cast<SwUnoTableCursor&>(*pUnoCursor);
+ // HACK: remove pending actions for selecting old style tables
+ UnoActionRemoveContext aRemoveContext(rCursor);
+ rCursor.MakeBoxSels();
+
+ SfxItemSetFixed<RES_BOX, RES_BOX,
+ SID_ATTR_BORDER_INNER, SID_ATTR_BORDER_INNER>
+ aSet(pDoc->GetAttrPool());
+
+ SvxBoxItem aBox( RES_BOX );
+ SvxBoxInfoItem aBoxInfo( SID_ATTR_BORDER_INNER );
+
+ aBox.SetLine(aTopLine.isEmpty() ? nullptr : &aTopLine, SvxBoxItemLine::TOP);
+ aBoxInfo.SetValid(SvxBoxInfoItemValidFlags::TOP, aBorder.IsTopLineValid);
+
+ aBox.SetLine(aBottomLine.isEmpty() ? nullptr : &aBottomLine, SvxBoxItemLine::BOTTOM);
+ aBoxInfo.SetValid(SvxBoxInfoItemValidFlags::BOTTOM, aBorder.IsBottomLineValid);
+
+ aBox.SetLine(aLeftLine.isEmpty() ? nullptr : &aLeftLine, SvxBoxItemLine::LEFT);
+ aBoxInfo.SetValid(SvxBoxInfoItemValidFlags::LEFT, aBorder.IsLeftLineValid);
+
+ aBox.SetLine(aRightLine.isEmpty() ? nullptr : &aRightLine, SvxBoxItemLine::RIGHT);
+ aBoxInfo.SetValid(SvxBoxInfoItemValidFlags::RIGHT, aBorder.IsRightLineValid);
+
+ aBoxInfo.SetLine(aHoriLine.isEmpty() ? nullptr : &aHoriLine, SvxBoxInfoItemLine::HORI);
+ aBoxInfo.SetValid(SvxBoxInfoItemValidFlags::HORI, aBorder.IsHorizontalLineValid);
+
+ aBoxInfo.SetLine(aVertLine.isEmpty() ? nullptr : &aVertLine, SvxBoxInfoItemLine::VERT);
+ aBoxInfo.SetValid(SvxBoxInfoItemValidFlags::VERT, aBorder.IsVerticalLineValid);
+
+ aBox.SetAllDistances(o3tl::toTwips(aBorder.Distance, o3tl::Length::mm100));
+ aBoxInfo.SetValid(SvxBoxInfoItemValidFlags::DISTANCE, aBorder.IsDistanceValid);
+
+ aSet.Put(aBox);
+ aSet.Put(aBoxInfo);
+
+ pDoc->SetTabBorders(rCursor, aSet);
+ }
+ break;
+
+ case FN_UNO_TABLE_BORDER_DISTANCES:
+ {
+ table::TableBorderDistances aTableBorderDistances;
+ if( !(aValue >>= aTableBorderDistances) ||
+ (!aTableBorderDistances.IsLeftDistanceValid &&
+ !aTableBorderDistances.IsRightDistanceValid &&
+ !aTableBorderDistances.IsTopDistanceValid &&
+ !aTableBorderDistances.IsBottomDistanceValid ))
+ break;
+
+ const sal_uInt16 nLeftDistance = o3tl::toTwips(aTableBorderDistances.LeftDistance, o3tl::Length::mm100);
+ const sal_uInt16 nRightDistance = o3tl::toTwips(aTableBorderDistances.RightDistance, o3tl::Length::mm100);
+ const sal_uInt16 nTopDistance = o3tl::toTwips(aTableBorderDistances.TopDistance, o3tl::Length::mm100);
+ const sal_uInt16 nBottomDistance = o3tl::toTwips(aTableBorderDistances.BottomDistance, o3tl::Length::mm100);
+ SwDoc* pDoc = pFormat->GetDoc();
+ SwTable* pTable = SwTable::FindTable( pFormat );
+ SwTableLines &rLines = pTable->GetTabLines();
+ pDoc->GetIDocumentUndoRedo().StartUndo(SwUndoId::START, nullptr);
+ for(size_t i = 0; i < rLines.size(); ++i)
+ {
+ SwTableLine* pLine = rLines[i];
+ SwTableBoxes& rBoxes = pLine->GetTabBoxes();
+ for(size_t k = 0; k < rBoxes.size(); ++k)
+ {
+ SwTableBox* pBox = rBoxes[k];
+ const SwFrameFormat* pBoxFormat = pBox->GetFrameFormat();
+ const SvxBoxItem& rBox = pBoxFormat->GetBox();
+ if(
+ (aTableBorderDistances.IsLeftDistanceValid && nLeftDistance != rBox.GetDistance( SvxBoxItemLine::LEFT )) ||
+ (aTableBorderDistances.IsRightDistanceValid && nRightDistance != rBox.GetDistance( SvxBoxItemLine::RIGHT )) ||
+ (aTableBorderDistances.IsTopDistanceValid && nTopDistance != rBox.GetDistance( SvxBoxItemLine::TOP )) ||
+ (aTableBorderDistances.IsBottomDistanceValid && nBottomDistance != rBox.GetDistance( SvxBoxItemLine::BOTTOM )))
+ {
+ SvxBoxItem aSetBox( rBox );
+ SwFrameFormat* pSetBoxFormat = pBox->ClaimFrameFormat();
+ if( aTableBorderDistances.IsLeftDistanceValid )
+ aSetBox.SetDistance( nLeftDistance, SvxBoxItemLine::LEFT );
+ if( aTableBorderDistances.IsRightDistanceValid )
+ aSetBox.SetDistance( nRightDistance, SvxBoxItemLine::RIGHT );
+ if( aTableBorderDistances.IsTopDistanceValid )
+ aSetBox.SetDistance( nTopDistance, SvxBoxItemLine::TOP );
+ if( aTableBorderDistances.IsBottomDistanceValid )
+ aSetBox.SetDistance( nBottomDistance, SvxBoxItemLine::BOTTOM );
+ pDoc->SetAttr( aSetBox, *pSetBoxFormat );
+ }
+ }
+ }
+ pDoc->GetIDocumentUndoRedo().EndUndo(SwUndoId::END, nullptr);
+ }
+ break;
+
+ case FN_UNO_TABLE_COLUMN_SEPARATORS:
+ {
+ UnoActionContext aContext(pFormat->GetDoc());
+ SwTable* pTable = SwTable::FindTable( pFormat );
+ lcl_SetTableSeparators(aValue, pTable, pTable->GetTabLines()[0]->GetTabBoxes()[0], false, pFormat->GetDoc());
+ }
+ break;
+
+ case FN_UNO_TABLE_COLUMN_RELATIVE_SUM:/*_readonly_*/ break;
+
+ case FN_UNO_TABLE_TEMPLATE_NAME:
+ {
+ SwTable* pTable = SwTable::FindTable(pFormat);
+ OUString sName;
+ if (!(aValue >>= sName))
+ break;
+ SwStyleNameMapper::FillUIName(sName, sName, SwGetPoolIdFromName::TabStyle);
+ pTable->SetTableStyleName(sName);
+ SwDoc* pDoc = pFormat->GetDoc();
+ if (SwFEShell* pFEShell = pDoc->GetDocShell()->GetFEShell())
+ pFEShell->UpdateTableStyleFormatting(pTable->GetTableNode());
+ }
+ break;
+
+ default:
+ {
+ SwAttrSet aSet(pFormat->GetAttrSet());
+ m_pImpl->m_pPropSet->setPropertyValue(*pEntry, aValue, aSet);
+ pFormat->GetDoc()->SetAttr(aSet, *pFormat);
+ }
+ }
+ }
+ }
+ else if (m_pImpl->IsDescriptor())
+ {
+ m_pImpl->m_pTableProps->SetProperty(pEntry->nWID, pEntry->nMemberId, aValue);
+ }
+ else
+ throw uno::RuntimeException();
+}
+
+uno::Any SwXTextTable::getPropertyValue(const OUString& rPropertyName)
+{
+ SolarMutexGuard aGuard;
+ uno::Any aRet;
+ SwFrameFormat* pFormat = GetFrameFormat();
+ const SfxItemPropertyMapEntry* pEntry =
+ m_pImpl->m_pPropSet->getPropertyMap().getByName(rPropertyName);
+
+ if (!pEntry)
+ throw beans::UnknownPropertyException("Unknown property: " + rPropertyName, getXWeak() );
+
+ if(pFormat)
+ {
+ if(0xBF == pEntry->nMemberId)
+ {
+ aRet = lcl_GetSpecialProperty(pFormat, pEntry );
+ }
+ else
+ {
+ switch(pEntry->nWID)
+ {
+ case FN_UNO_TABLE_NAME:
+ {
+ aRet <<= getName();
+ }
+ break;
+
+ case FN_UNO_ANCHOR_TYPES:
+ case FN_UNO_TEXT_WRAP:
+ case FN_UNO_ANCHOR_TYPE:
+ ::sw::GetDefaultTextContentValue(
+ aRet, u"", pEntry->nWID);
+ break;
+
+ case FN_UNO_RANGE_ROW_LABEL:
+ {
+ aRet <<= m_pImpl->m_bFirstRowAsLabel;
+ }
+ break;
+
+ case FN_UNO_RANGE_COL_LABEL:
+ aRet <<= m_pImpl->m_bFirstColumnAsLabel;
+ break;
+
+ case FN_UNO_TABLE_BORDER:
+ case FN_UNO_TABLE_BORDER2:
+ {
+ SwDoc* pDoc = pFormat->GetDoc();
+ // tables without layout (invisible header/footer?)
+ if(!lcl_FormatTable(pFormat))
+ break;
+ SwTable* pTable = SwTable::FindTable( pFormat );
+ SwTableLines &rLines = pTable->GetTabLines();
+
+ const SwTableBox* pTLBox = lcl_FindCornerTableBox(rLines, true);
+ const SwStartNode* pSttNd = pTLBox->GetSttNd();
+ SwPosition aPos(*pSttNd);
+ // set cursor to top left cell
+ auto pUnoCursor(pDoc->CreateUnoCursor(aPos, true));
+ pUnoCursor->Move( fnMoveForward, GoInNode );
+ pUnoCursor->SetRemainInSection( false );
+
+ const SwTableBox* pBRBox = lcl_FindCornerTableBox(rLines, false);
+ pUnoCursor->SetMark();
+ const SwStartNode* pLastNd = pBRBox->GetSttNd();
+ pUnoCursor->GetPoint()->Assign( *pLastNd );
+
+ pUnoCursor->Move( fnMoveForward, GoInNode );
+ SwUnoTableCursor& rCursor = dynamic_cast<SwUnoTableCursor&>(*pUnoCursor);
+ // HACK: remove pending actions for selecting old style tables
+ UnoActionRemoveContext aRemoveContext(rCursor);
+ rCursor.MakeBoxSels();
+
+ SfxItemSetFixed<RES_BOX, RES_BOX,
+ SID_ATTR_BORDER_INNER, SID_ATTR_BORDER_INNER>
+ aSet(pDoc->GetAttrPool());
+ aSet.Put(SvxBoxInfoItem( SID_ATTR_BORDER_INNER ));
+ SwDoc::GetTabBorders(rCursor, aSet);
+ const SvxBoxInfoItem& rBoxInfoItem = aSet.Get(SID_ATTR_BORDER_INNER);
+ const SvxBoxItem& rBox = aSet.Get(RES_BOX);
+
+ if (FN_UNO_TABLE_BORDER == pEntry->nWID)
+ {
+ table::TableBorder aTableBorder;
+ aTableBorder.TopLine = SvxBoxItem::SvxLineToLine(rBox.GetTop(), true);
+ aTableBorder.IsTopLineValid = rBoxInfoItem.IsValid(SvxBoxInfoItemValidFlags::TOP);
+ aTableBorder.BottomLine = SvxBoxItem::SvxLineToLine(rBox.GetBottom(), true);
+ aTableBorder.IsBottomLineValid = rBoxInfoItem.IsValid(SvxBoxInfoItemValidFlags::BOTTOM);
+ aTableBorder.LeftLine = SvxBoxItem::SvxLineToLine(rBox.GetLeft(), true);
+ aTableBorder.IsLeftLineValid = rBoxInfoItem.IsValid(SvxBoxInfoItemValidFlags::LEFT);
+ aTableBorder.RightLine = SvxBoxItem::SvxLineToLine(rBox.GetRight(), true);
+ aTableBorder.IsRightLineValid = rBoxInfoItem.IsValid(SvxBoxInfoItemValidFlags::RIGHT );
+ aTableBorder.HorizontalLine = SvxBoxItem::SvxLineToLine(rBoxInfoItem.GetHori(), true);
+ aTableBorder.IsHorizontalLineValid = rBoxInfoItem.IsValid(SvxBoxInfoItemValidFlags::HORI);
+ aTableBorder.VerticalLine = SvxBoxItem::SvxLineToLine(rBoxInfoItem.GetVert(), true);
+ aTableBorder.IsVerticalLineValid = rBoxInfoItem.IsValid(SvxBoxInfoItemValidFlags::VERT);
+ aTableBorder.Distance = convertTwipToMm100(rBox.GetSmallestDistance());
+ aTableBorder.IsDistanceValid = rBoxInfoItem.IsValid(SvxBoxInfoItemValidFlags::DISTANCE);
+ aRet <<= aTableBorder;
+ }
+ else
+ {
+ table::TableBorder2 aTableBorder;
+ aTableBorder.TopLine = SvxBoxItem::SvxLineToLine(rBox.GetTop(), true);
+ aTableBorder.IsTopLineValid = rBoxInfoItem.IsValid(SvxBoxInfoItemValidFlags::TOP);
+ aTableBorder.BottomLine = SvxBoxItem::SvxLineToLine(rBox.GetBottom(), true);
+ aTableBorder.IsBottomLineValid = rBoxInfoItem.IsValid(SvxBoxInfoItemValidFlags::BOTTOM);
+ aTableBorder.LeftLine = SvxBoxItem::SvxLineToLine(rBox.GetLeft(), true);
+ aTableBorder.IsLeftLineValid = rBoxInfoItem.IsValid(SvxBoxInfoItemValidFlags::LEFT);
+ aTableBorder.RightLine = SvxBoxItem::SvxLineToLine(rBox.GetRight(), true);
+ aTableBorder.IsRightLineValid = rBoxInfoItem.IsValid(SvxBoxInfoItemValidFlags::RIGHT );
+ aTableBorder.HorizontalLine = SvxBoxItem::SvxLineToLine(rBoxInfoItem.GetHori(), true);
+ aTableBorder.IsHorizontalLineValid = rBoxInfoItem.IsValid(SvxBoxInfoItemValidFlags::HORI);
+ aTableBorder.VerticalLine = SvxBoxItem::SvxLineToLine(rBoxInfoItem.GetVert(), true);
+ aTableBorder.IsVerticalLineValid = rBoxInfoItem.IsValid(SvxBoxInfoItemValidFlags::VERT);
+ aTableBorder.Distance = convertTwipToMm100(rBox.GetSmallestDistance());
+ aTableBorder.IsDistanceValid = rBoxInfoItem.IsValid(SvxBoxInfoItemValidFlags::DISTANCE);
+ aRet <<= aTableBorder;
+ }
+ }
+ break;
+
+ case FN_UNO_TABLE_BORDER_DISTANCES :
+ {
+ table::TableBorderDistances aTableBorderDistances( 0, true, 0, true, 0, true, 0, true ) ;
+ SwTable* pTable = SwTable::FindTable( pFormat );
+ const SwTableLines &rLines = pTable->GetTabLines();
+ bool bFirst = true;
+ sal_uInt16 nLeftDistance = 0;
+ sal_uInt16 nRightDistance = 0;
+ sal_uInt16 nTopDistance = 0;
+ sal_uInt16 nBottomDistance = 0;
+
+ for(size_t i = 0; i < rLines.size(); ++i)
+ {
+ const SwTableLine* pLine = rLines[i];
+ const SwTableBoxes& rBoxes = pLine->GetTabBoxes();
+ for(size_t k = 0; k < rBoxes.size(); ++k)
+ {
+ const SwTableBox* pBox = rBoxes[k];
+ SwFrameFormat* pBoxFormat = pBox->GetFrameFormat();
+ const SvxBoxItem& rBox = pBoxFormat->GetBox();
+ if( bFirst )
+ {
+ nLeftDistance = convertTwipToMm100( rBox.GetDistance( SvxBoxItemLine::LEFT ));
+ nRightDistance = convertTwipToMm100( rBox.GetDistance( SvxBoxItemLine::RIGHT ));
+ nTopDistance = convertTwipToMm100( rBox.GetDistance( SvxBoxItemLine::TOP ));
+ nBottomDistance = convertTwipToMm100( rBox.GetDistance( SvxBoxItemLine::BOTTOM ));
+ bFirst = false;
+ }
+ else
+ {
+ if( aTableBorderDistances.IsLeftDistanceValid &&
+ nLeftDistance != convertTwipToMm100( rBox.GetDistance( SvxBoxItemLine::LEFT )))
+ aTableBorderDistances.IsLeftDistanceValid = false;
+ if( aTableBorderDistances.IsRightDistanceValid &&
+ nRightDistance != convertTwipToMm100( rBox.GetDistance( SvxBoxItemLine::RIGHT )))
+ aTableBorderDistances.IsRightDistanceValid = false;
+ if( aTableBorderDistances.IsTopDistanceValid &&
+ nTopDistance != convertTwipToMm100( rBox.GetDistance( SvxBoxItemLine::TOP )))
+ aTableBorderDistances.IsTopDistanceValid = false;
+ if( aTableBorderDistances.IsBottomDistanceValid &&
+ nBottomDistance != convertTwipToMm100( rBox.GetDistance( SvxBoxItemLine::BOTTOM )))
+ aTableBorderDistances.IsBottomDistanceValid = false;
+ }
+
+ }
+ if( !aTableBorderDistances.IsLeftDistanceValid &&
+ !aTableBorderDistances.IsRightDistanceValid &&
+ !aTableBorderDistances.IsTopDistanceValid &&
+ !aTableBorderDistances.IsBottomDistanceValid )
+ break;
+ }
+ if( aTableBorderDistances.IsLeftDistanceValid)
+ aTableBorderDistances.LeftDistance = nLeftDistance;
+ if( aTableBorderDistances.IsRightDistanceValid)
+ aTableBorderDistances.RightDistance = nRightDistance;
+ if( aTableBorderDistances.IsTopDistanceValid)
+ aTableBorderDistances.TopDistance = nTopDistance;
+ if( aTableBorderDistances.IsBottomDistanceValid)
+ aTableBorderDistances.BottomDistance = nBottomDistance;
+
+ aRet <<= aTableBorderDistances;
+ }
+ break;
+
+ case FN_UNO_TABLE_COLUMN_SEPARATORS:
+ {
+ SwTable* pTable = SwTable::FindTable( pFormat );
+ lcl_GetTableSeparators(aRet, pTable, pTable->GetTabLines()[0]->GetTabBoxes()[0], false);
+ }
+ break;
+
+ case FN_UNO_TABLE_COLUMN_RELATIVE_SUM:
+ aRet <<= sal_Int16(UNO_TABLE_COLUMN_SUM);
+ break;
+
+ case RES_ANCHOR:
+ // AnchorType is readonly and might be void (no return value)
+ break;
+
+ case FN_UNO_TEXT_SECTION:
+ {
+ SwTable* pTable = SwTable::FindTable( pFormat );
+ SwTableNode* pTableNode = pTable->GetTableNode();
+ SwSectionNode* pSectionNode = pTableNode->FindSectionNode();
+ if(pSectionNode)
+ {
+ SwSection& rSect = pSectionNode->GetSection();
+ uno::Reference< text::XTextSection > xSect =
+ SwXTextSections::GetObject( *rSect.GetFormat() );
+ aRet <<= xSect;
+ }
+ }
+ break;
+
+ case FN_UNO_TABLE_TEMPLATE_NAME:
+ {
+ SwTable* pTable = SwTable::FindTable(pFormat);
+ OUString sName;
+ SwStyleNameMapper::FillProgName(pTable->GetTableStyleName(), sName, SwGetPoolIdFromName::TabStyle);
+ aRet <<= sName;
+ }
+ break;
+
+ default:
+ {
+ const SwAttrSet& rSet = pFormat->GetAttrSet();
+ m_pImpl->m_pPropSet->getPropertyValue(*pEntry, rSet, aRet);
+ }
+ }
+ }
+ }
+ else if (m_pImpl->IsDescriptor())
+ {
+ const uno::Any* pAny = nullptr;
+ if (!m_pImpl->m_pTableProps->GetProperty(pEntry->nWID, pEntry->nMemberId, pAny))
+ throw lang::IllegalArgumentException();
+ else if(pAny)
+ aRet = *pAny;
+ }
+ else
+ throw uno::RuntimeException();
+ return aRet;
+}
+
+void SwXTextTable::addPropertyChangeListener(const OUString& /*rPropertyName*/, const uno::Reference< beans::XPropertyChangeListener > & /*xListener*/)
+ { throw uno::RuntimeException("Not implemented", getXWeak()); }
+
+void SwXTextTable::removePropertyChangeListener(const OUString& /*rPropertyName*/, const uno::Reference< beans::XPropertyChangeListener > & /*xListener*/)
+ { throw uno::RuntimeException("Not implemented", getXWeak()); }
+
+void SwXTextTable::addVetoableChangeListener(const OUString& /*rPropertyName*/, const uno::Reference< beans::XVetoableChangeListener > & /*xListener*/)
+ { throw uno::RuntimeException("Not implemented", getXWeak()); }
+
+void SwXTextTable::removeVetoableChangeListener(const OUString& /*rPropertyName*/, const uno::Reference< beans::XVetoableChangeListener > & /*xListener*/)
+ { throw uno::RuntimeException("Not implemented", getXWeak()); }
+
+OUString SwXTextTable::getName()
+{
+ SolarMutexGuard aGuard;
+ SwFrameFormat* pFormat = GetFrameFormat();
+ if (!pFormat && !m_pImpl->IsDescriptor())
+ throw uno::RuntimeException();
+ if(pFormat)
+ {
+ return pFormat->GetName();
+ }
+ return m_pImpl->m_sTableName;
+}
+
+void SwXTextTable::setName(const OUString& rName)
+{
+ SolarMutexGuard aGuard;
+ SwFrameFormat* pFormat = GetFrameFormat();
+ if ((!pFormat && !m_pImpl->IsDescriptor()) ||
+ rName.isEmpty() ||
+ rName.indexOf('.')>=0 ||
+ rName.indexOf(' ')>=0 )
+ throw uno::RuntimeException();
+
+ if(pFormat)
+ {
+ const OUString aOldName( pFormat->GetName() );
+ const sw::TableFrameFormats* pFrameFormats = pFormat->GetDoc()->GetTableFrameFormats();
+ for (size_t i = pFrameFormats->size(); i;)
+ {
+ const SwTableFormat* pTmpFormat = (*pFrameFormats)[--i];
+ if( !pTmpFormat->IsDefault() &&
+ pTmpFormat->GetName() == rName &&
+ pFormat->GetDoc()->IsUsed( *pTmpFormat ))
+ {
+ throw uno::RuntimeException();
+ }
+ }
+
+ pFormat->SetFormatName( rName );
+
+ SwStartNode *pStNd;
+ SwNodeIndex aIdx( *pFormat->GetDoc()->GetNodes().GetEndOfAutotext().StartOfSectionNode(), 1 );
+ while ( nullptr != (pStNd = aIdx.GetNode().GetStartNode()) )
+ {
+ ++aIdx;
+ SwNode *const pNd = & aIdx.GetNode();
+ if ( pNd->IsOLENode() &&
+ aOldName == static_cast<const SwOLENode*>(pNd)->GetChartTableName() )
+ {
+ static_cast<SwOLENode*>(pNd)->SetChartTableName( rName );
+
+ SwTable* pTable = SwTable::FindTable( pFormat );
+ //TL_CHART2: chart needs to be notified about name changes
+ pFormat->GetDoc()->UpdateCharts( pTable->GetFrameFormat()->GetName() );
+ }
+ aIdx.Assign( *pStNd->EndOfSectionNode(), + 1 );
+ }
+ pFormat->GetDoc()->getIDocumentState().SetModified();
+ }
+ else
+ m_pImpl->m_sTableName = rName;
+}
+
+sal_uInt16 SwXTextTable::Impl::GetRowCount()
+{
+ sal_uInt16 nRet = 0;
+ SwFrameFormat* pFormat = GetFrameFormat();
+ if(pFormat)
+ {
+ SwTable* pTable = SwTable::FindTable( pFormat );
+ if(!pTable->IsTableComplex())
+ {
+ nRet = pTable->GetTabLines().size();
+ }
+ }
+ return nRet;
+}
+
+sal_uInt16 SwXTextTable::Impl::GetColumnCount()
+{
+ SwFrameFormat* pFormat = GetFrameFormat();
+ sal_uInt16 nRet = 0;
+ if(pFormat)
+ {
+ SwTable* pTable = SwTable::FindTable( pFormat );
+ if(!pTable->IsTableComplex())
+ {
+ SwTableLines& rLines = pTable->GetTabLines();
+ SwTableLine* pLine = rLines.front();
+ nRet = pLine->GetTabBoxes().size();
+ }
+ }
+ return nRet;
+}
+
+void SwXTextTable::Impl::Notify(const SfxHint& rHint)
+{
+ if(rHint.GetId() == SfxHintId::Dying)
+ {
+ m_pFrameFormat = nullptr;
+ EndListeningAll();
+ }
+ std::unique_lock aGuard(m_Mutex);
+ if (m_EventListeners.getLength(aGuard) == 0 && m_ChartListeners.getLength(aGuard) == 0)
+ return;
+ uno::Reference<uno::XInterface> const xThis(m_wThis);
+ // fdo#72695: if UNO object is already dead, don't revive it with event
+ if (!xThis)
+ return;
+ if(!m_pFrameFormat)
+ {
+ lang::EventObject const ev(xThis);
+ m_EventListeners.disposeAndClear(aGuard, ev);
+ m_ChartListeners.disposeAndClear(aGuard, ev);
+ }
+ else
+ {
+ lcl_SendChartEvent(aGuard, xThis, m_ChartListeners);
+ }
+}
+
+OUString SAL_CALL SwXTextTable::getImplementationName()
+ { return "SwXTextTable"; }
+
+sal_Bool SwXTextTable::supportsService(const OUString& rServiceName)
+ { return cppu::supportsService(this, rServiceName); }
+
+uno::Sequence<OUString> SwXTextTable::getSupportedServiceNames()
+{
+ return {
+ "com.sun.star.document.LinkTarget",
+ "com.sun.star.text.TextTable",
+ "com.sun.star.text.TextContent",
+ "com.sun.star.text.TextSortable" };
+}
+
+
+class SwXCellRange::Impl
+ : public SvtListener
+{
+private:
+ SwFrameFormat* m_pFrameFormat;
+
+public:
+ uno::WeakReference<uno::XInterface> m_wThis;
+ std::mutex m_Mutex; // just for OInterfaceContainerHelper4
+ ::comphelper::OInterfaceContainerHelper4<chart::XChartDataChangeEventListener> m_ChartListeners;
+
+ sw::UnoCursorPointer m_pTableCursor;
+
+ SwRangeDescriptor m_RangeDescriptor;
+ const SfxItemPropertySet* m_pPropSet;
+
+ bool m_bFirstRowAsLabel;
+ bool m_bFirstColumnAsLabel;
+
+ Impl(sw::UnoCursorPointer const& pCursor, SwFrameFormat& rFrameFormat, SwRangeDescriptor const& rDesc)
+ : m_pFrameFormat(&rFrameFormat)
+ , m_pTableCursor(pCursor)
+ , m_RangeDescriptor(rDesc)
+ , m_pPropSet(aSwMapProvider.GetPropertySet(PROPERTY_MAP_TABLE_RANGE))
+ , m_bFirstRowAsLabel(false)
+ , m_bFirstColumnAsLabel(false)
+ {
+ StartListening(rFrameFormat.GetNotifier());
+ m_RangeDescriptor.Normalize();
+ }
+
+ SwFrameFormat* GetFrameFormat()
+ {
+ return m_pFrameFormat;
+ }
+
+ std::tuple<sal_uInt32, sal_uInt32, sal_uInt32, sal_uInt32> GetLabelCoordinates(bool bRow);
+
+ uno::Sequence<OUString> GetLabelDescriptions(SwXCellRange & rThis, bool bRow);
+
+ void SetLabelDescriptions(SwXCellRange & rThis,
+ const css::uno::Sequence<OUString>& rDesc, bool bRow);
+
+ sal_Int32 GetRowCount() const;
+ sal_Int32 GetColumnCount() const;
+
+ virtual void Notify(const SfxHint& ) override;
+
+};
+
+OUString SwXCellRange::getImplementationName()
+ { return "SwXCellRange"; }
+
+sal_Bool SwXCellRange::supportsService(const OUString& rServiceName)
+ { return cppu::supportsService(this, rServiceName); }
+
+uno::Sequence<OUString> SwXCellRange::getSupportedServiceNames()
+{
+ return {
+ "com.sun.star.text.CellRange",
+ "com.sun.star.style.CharacterProperties",
+ "com.sun.star.style.CharacterPropertiesAsian",
+ "com.sun.star.style.CharacterPropertiesComplex",
+ "com.sun.star.style.ParagraphProperties",
+ "com.sun.star.style.ParagraphPropertiesAsian",
+ "com.sun.star.style.ParagraphPropertiesComplex" };
+}
+
+SwXCellRange::SwXCellRange(sw::UnoCursorPointer const& pCursor,
+ SwFrameFormat& rFrameFormat, SwRangeDescriptor const & rDesc)
+ : m_pImpl(new Impl(pCursor, rFrameFormat, rDesc))
+{
+}
+
+SwXCellRange::~SwXCellRange()
+{
+}
+
+rtl::Reference<SwXCellRange> SwXCellRange::CreateXCellRange(
+ sw::UnoCursorPointer const& pCursor, SwFrameFormat& rFrameFormat,
+ SwRangeDescriptor const & rDesc)
+{
+ rtl::Reference<SwXCellRange> pCellRange(new SwXCellRange(pCursor, rFrameFormat, rDesc));
+ // need a permanent Reference to initialize m_wThis
+ pCellRange->m_pImpl->m_wThis = uno::Reference<table::XCellRange>(pCellRange);
+ return pCellRange;
+}
+
+void SwXCellRange::SetLabels(bool bFirstRowAsLabel, bool bFirstColumnAsLabel)
+{
+ m_pImpl->m_bFirstRowAsLabel = bFirstRowAsLabel;
+ m_pImpl->m_bFirstColumnAsLabel = bFirstColumnAsLabel;
+}
+
+std::vector< uno::Reference< table::XCell > > SwXCellRange::GetCells()
+{
+ SwFrameFormat *const pFormat = m_pImpl->GetFrameFormat();
+ const sal_Int32 nRowCount(m_pImpl->GetRowCount());
+ const sal_Int32 nColCount(m_pImpl->GetColumnCount());
+ std::vector< uno::Reference< table::XCell > > vResult;
+ vResult.reserve(static_cast<size_t>(nRowCount)*static_cast<size_t>(nColCount));
+ for(sal_Int32 nRow = 0; nRow < nRowCount; ++nRow)
+ for(sal_Int32 nCol = 0; nCol < nColCount; ++nCol)
+ vResult.emplace_back(lcl_CreateXCell(pFormat, m_pImpl->m_RangeDescriptor.nLeft + nCol, m_pImpl->m_RangeDescriptor.nTop + nRow));
+ return vResult;
+}
+
+uno::Reference<table::XCell> SAL_CALL
+SwXCellRange::getCellByPosition(sal_Int32 nColumn, sal_Int32 nRow)
+{
+ SolarMutexGuard aGuard;
+ uno::Reference< table::XCell > aRet;
+ SwFrameFormat *const pFormat = m_pImpl->GetFrameFormat();
+ if(pFormat)
+ {
+ if(nColumn >= 0 && nRow >= 0 &&
+ m_pImpl->GetColumnCount() > nColumn && m_pImpl->GetRowCount() > nRow )
+ {
+ rtl::Reference<SwXCell> pXCell = lcl_CreateXCell(pFormat,
+ m_pImpl->m_RangeDescriptor.nLeft + nColumn,
+ m_pImpl->m_RangeDescriptor.nTop + nRow);
+ if(pXCell)
+ aRet = pXCell;
+ }
+ }
+ if(!aRet.is())
+ throw lang::IndexOutOfBoundsException();
+ return aRet;
+}
+
+uno::Reference<table::XCellRange> SAL_CALL
+SwXCellRange::getCellRangeByPosition(
+ sal_Int32 nLeft, sal_Int32 nTop, sal_Int32 nRight, sal_Int32 nBottom)
+{
+ SolarMutexGuard aGuard;
+ rtl::Reference< SwXCellRange > aRet;
+ SwFrameFormat *const pFormat = m_pImpl->GetFrameFormat();
+ if (pFormat && m_pImpl->GetColumnCount() > nRight
+ && m_pImpl->GetRowCount() > nBottom &&
+ nLeft <= nRight && nTop <= nBottom
+ && nLeft >= 0 && nRight >= 0 && nTop >= 0 && nBottom >= 0 )
+ {
+ SwTable* pTable = SwTable::FindTable( pFormat );
+ if(!pTable->IsTableComplex())
+ {
+ SwRangeDescriptor aNewDesc;
+ aNewDesc.nTop = nTop + m_pImpl->m_RangeDescriptor.nTop;
+ aNewDesc.nBottom = nBottom + m_pImpl->m_RangeDescriptor.nTop;
+ aNewDesc.nLeft = nLeft + m_pImpl->m_RangeDescriptor.nLeft;
+ aNewDesc.nRight = nRight + m_pImpl->m_RangeDescriptor.nLeft;
+ aNewDesc.Normalize();
+ const OUString sTLName = sw_GetCellName(aNewDesc.nLeft, aNewDesc.nTop);
+ const OUString sBRName = sw_GetCellName(aNewDesc.nRight, aNewDesc.nBottom);
+ const SwTableBox* pTLBox = pTable->GetTableBox( sTLName );
+ if(pTLBox)
+ {
+ const SwStartNode* pSttNd = pTLBox->GetSttNd();
+ SwPosition aPos(*pSttNd);
+ // set cursor in the upper-left cell of the range
+ auto pUnoCursor(pFormat->GetDoc()->CreateUnoCursor(aPos, true));
+ pUnoCursor->Move( fnMoveForward, GoInNode );
+ pUnoCursor->SetRemainInSection( false );
+ const SwTableBox* pBRBox = pTable->GetTableBox( sBRName );
+ if(pBRBox)
+ {
+ pUnoCursor->SetMark();
+ pUnoCursor->GetPoint()->Assign( *pBRBox->GetSttNd() );
+ pUnoCursor->Move( fnMoveForward, GoInNode );
+ SwUnoTableCursor& rCursor = dynamic_cast<SwUnoTableCursor&>(*pUnoCursor);
+ // HACK: remove pending actions for selecting old style tables
+ UnoActionRemoveContext aRemoveContext(rCursor);
+ rCursor.MakeBoxSels();
+ // pUnoCursor will be provided and will not be deleted
+ aRet = SwXCellRange::CreateXCellRange(pUnoCursor, *pFormat, aNewDesc).get();
+ }
+ }
+ }
+ }
+ if(!aRet.is())
+ throw lang::IndexOutOfBoundsException();
+ return aRet;
+}
+
+uno::Reference<table::XCellRange> SAL_CALL
+SwXCellRange::getCellRangeByName(const OUString& rRange)
+{
+ SolarMutexGuard aGuard;
+ sal_Int32 nPos = 0;
+ const OUString sTLName(rRange.getToken(0, ':', nPos));
+ const OUString sBRName(rRange.getToken(0, ':', nPos));
+ if(sTLName.isEmpty() || sBRName.isEmpty())
+ throw uno::RuntimeException();
+ SwRangeDescriptor aDesc;
+ aDesc.nTop = aDesc.nLeft = aDesc.nBottom = aDesc.nRight = -1;
+ SwXTextTable::GetCellPosition( sTLName, aDesc.nLeft, aDesc.nTop );
+ SwXTextTable::GetCellPosition( sBRName, aDesc.nRight, aDesc.nBottom );
+ aDesc.Normalize();
+ return getCellRangeByPosition(
+ aDesc.nLeft - m_pImpl->m_RangeDescriptor.nLeft,
+ aDesc.nTop - m_pImpl->m_RangeDescriptor.nTop,
+ aDesc.nRight - m_pImpl->m_RangeDescriptor.nLeft,
+ aDesc.nBottom - m_pImpl->m_RangeDescriptor.nTop);
+}
+
+uno::Reference< beans::XPropertySetInfo > SwXCellRange::getPropertySetInfo()
+{
+ static uno::Reference<beans::XPropertySetInfo> xRef = m_pImpl->m_pPropSet->getPropertySetInfo();
+ return xRef;
+}
+
+void SAL_CALL
+SwXCellRange::setPropertyValue(const OUString& rPropertyName, const uno::Any& aValue)
+{
+ SolarMutexGuard aGuard;
+ SwFrameFormat *const pFormat = m_pImpl->GetFrameFormat();
+ if(!pFormat)
+ return;
+
+ const SfxItemPropertyMapEntry *const pEntry =
+ m_pImpl->m_pPropSet->getPropertyMap().getByName(rPropertyName);
+ if(!pEntry)
+ throw beans::UnknownPropertyException("Unknown property: " + rPropertyName, getXWeak() );
+
+ if ( pEntry->nFlags & beans::PropertyAttribute::READONLY)
+ throw beans::PropertyVetoException("Property is read-only: " + rPropertyName, getXWeak() );
+
+ SwDoc& rDoc = m_pImpl->m_pTableCursor->GetDoc();
+ SwUnoTableCursor& rCursor(dynamic_cast<SwUnoTableCursor&>(*m_pImpl->m_pTableCursor));
+ {
+ // HACK: remove pending actions for selecting old style tables
+ UnoActionRemoveContext aRemoveContext(rCursor);
+ }
+ rCursor.MakeBoxSels();
+ switch(pEntry->nWID )
+ {
+ case FN_UNO_TABLE_CELL_BACKGROUND:
+ {
+ std::unique_ptr<SfxPoolItem> aBrush(std::make_unique<SvxBrushItem>(RES_BACKGROUND));
+ SwDoc::GetBoxAttr(*m_pImpl->m_pTableCursor, aBrush);
+ aBrush->PutValue(aValue, pEntry->nMemberId);
+ rDoc.SetBoxAttr(*m_pImpl->m_pTableCursor, *aBrush);
+
+ }
+ break;
+ case RES_BOX :
+ {
+ SfxItemSetFixed<RES_BOX, RES_BOX,
+ SID_ATTR_BORDER_INNER, SID_ATTR_BORDER_INNER>
+ aSet(rDoc.GetAttrPool());
+ SvxBoxInfoItem aBoxInfo( SID_ATTR_BORDER_INNER );
+ aBoxInfo.SetValid(SvxBoxInfoItemValidFlags::ALL, false);
+ SvxBoxInfoItemValidFlags nValid = SvxBoxInfoItemValidFlags::NONE;
+ switch(pEntry->nMemberId & ~CONVERT_TWIPS)
+ {
+ case LEFT_BORDER : nValid = SvxBoxInfoItemValidFlags::LEFT; break;
+ case RIGHT_BORDER: nValid = SvxBoxInfoItemValidFlags::RIGHT; break;
+ case TOP_BORDER : nValid = SvxBoxInfoItemValidFlags::TOP; break;
+ case BOTTOM_BORDER: nValid = SvxBoxInfoItemValidFlags::BOTTOM; break;
+ case LEFT_BORDER_DISTANCE :
+ case RIGHT_BORDER_DISTANCE:
+ case TOP_BORDER_DISTANCE :
+ case BOTTOM_BORDER_DISTANCE:
+ nValid = SvxBoxInfoItemValidFlags::DISTANCE;
+ break;
+ }
+ aBoxInfo.SetValid(nValid);
+
+ aSet.Put(aBoxInfo);
+ SwDoc::GetTabBorders(rCursor, aSet);
+
+ aSet.Put(aBoxInfo);
+ SvxBoxItem aBoxItem(aSet.Get(RES_BOX));
+ static_cast<SfxPoolItem&>(aBoxItem).PutValue(aValue, pEntry->nMemberId);
+ aSet.Put(aBoxItem);
+ rDoc.SetTabBorders(*m_pImpl->m_pTableCursor, aSet);
+ }
+ break;
+ case RES_BOXATR_FORMAT:
+ {
+ SfxUInt32Item aNumberFormat(RES_BOXATR_FORMAT);
+ static_cast<SfxPoolItem&>(aNumberFormat).PutValue(aValue, 0);
+ rDoc.SetBoxAttr(rCursor, aNumberFormat);
+ }
+ break;
+ case FN_UNO_RANGE_ROW_LABEL:
+ {
+ bool bTmp = *o3tl::doAccess<bool>(aValue);
+ if (m_pImpl->m_bFirstRowAsLabel != bTmp)
+ {
+ std::unique_lock aGuard2(m_pImpl->m_Mutex);
+ lcl_SendChartEvent(aGuard2, *this, m_pImpl->m_ChartListeners);
+ m_pImpl->m_bFirstRowAsLabel = bTmp;
+ }
+ }
+ break;
+ case FN_UNO_RANGE_COL_LABEL:
+ {
+ bool bTmp = *o3tl::doAccess<bool>(aValue);
+ if (m_pImpl->m_bFirstColumnAsLabel != bTmp)
+ {
+ std::unique_lock aGuard2(m_pImpl->m_Mutex);
+ lcl_SendChartEvent(aGuard2, *this, m_pImpl->m_ChartListeners);
+ m_pImpl->m_bFirstColumnAsLabel = bTmp;
+ }
+ }
+ break;
+ case RES_VERT_ORIENT:
+ {
+ sal_Int16 nAlign = -1;
+ aValue >>= nAlign;
+ if( nAlign >= text::VertOrientation::NONE && nAlign <= text::VertOrientation::BOTTOM)
+ rDoc.SetBoxAlign( rCursor, nAlign );
+ }
+ break;
+ default:
+ {
+ SfxItemSet aItemSet( rDoc.GetAttrPool(), pEntry->nWID, pEntry->nWID );
+ SwUnoCursorHelper::GetCursorAttr(rCursor.GetSelRing(),
+ aItemSet);
+
+ if (!SwUnoCursorHelper::SetCursorPropertyValue(
+ *pEntry, aValue, rCursor.GetSelRing(), aItemSet))
+ {
+ m_pImpl->m_pPropSet->setPropertyValue(*pEntry, aValue, aItemSet);
+ }
+ SwUnoCursorHelper::SetCursorAttr(rCursor.GetSelRing(),
+ aItemSet, SetAttrMode::DEFAULT, true);
+ }
+ }
+}
+
+uno::Any SAL_CALL SwXCellRange::getPropertyValue(const OUString& rPropertyName)
+{
+ SolarMutexGuard aGuard;
+ uno::Any aRet;
+ SwFrameFormat *const pFormat = m_pImpl->GetFrameFormat();
+ if(pFormat)
+ {
+ const SfxItemPropertyMapEntry *const pEntry =
+ m_pImpl->m_pPropSet->getPropertyMap().getByName(rPropertyName);
+ if(!pEntry)
+ throw beans::UnknownPropertyException("Unknown property: " + rPropertyName, getXWeak() );
+
+ switch(pEntry->nWID )
+ {
+ case FN_UNO_TABLE_CELL_BACKGROUND:
+ {
+ std::unique_ptr<SfxPoolItem> aBrush(std::make_unique<SvxBrushItem>(RES_BACKGROUND));
+ if (SwDoc::GetBoxAttr(*m_pImpl->m_pTableCursor, aBrush))
+ aBrush->QueryValue(aRet, pEntry->nMemberId);
+
+ }
+ break;
+ case RES_BOX :
+ {
+ SwDoc& rDoc = m_pImpl->m_pTableCursor->GetDoc();
+ SfxItemSetFixed<RES_BOX, RES_BOX,
+ SID_ATTR_BORDER_INNER, SID_ATTR_BORDER_INNER>
+ aSet(rDoc.GetAttrPool());
+ aSet.Put(SvxBoxInfoItem( SID_ATTR_BORDER_INNER ));
+ SwDoc::GetTabBorders(*m_pImpl->m_pTableCursor, aSet);
+ const SvxBoxItem& rBoxItem = aSet.Get(RES_BOX);
+ rBoxItem.QueryValue(aRet, pEntry->nMemberId);
+ }
+ break;
+ case RES_BOXATR_FORMAT:
+ OSL_FAIL("not implemented");
+ break;
+ case FN_UNO_PARA_STYLE:
+ {
+ SwFormatColl *const pTmpFormat =
+ SwUnoCursorHelper::GetCurTextFormatColl(*m_pImpl->m_pTableCursor, false);
+ OUString sRet;
+ if (pTmpFormat)
+ sRet = pTmpFormat->GetName();
+ aRet <<= sRet;
+ }
+ break;
+ case FN_UNO_RANGE_ROW_LABEL:
+ aRet <<= m_pImpl->m_bFirstRowAsLabel;
+ break;
+ case FN_UNO_RANGE_COL_LABEL:
+ aRet <<= m_pImpl->m_bFirstColumnAsLabel;
+ break;
+ case RES_VERT_ORIENT:
+ {
+ std::unique_ptr<SfxPoolItem> aVertOrient(
+ std::make_unique<SwFormatVertOrient>(RES_VERT_ORIENT));
+ if (SwDoc::GetBoxAttr(*m_pImpl->m_pTableCursor, aVertOrient))
+ {
+ aVertOrient->QueryValue( aRet, pEntry->nMemberId );
+ }
+ }
+ break;
+ default:
+ {
+ SfxItemSetFixed<
+ RES_CHRATR_BEGIN, RES_FRMATR_END - 1,
+ RES_UNKNOWNATR_CONTAINER,
+ RES_UNKNOWNATR_CONTAINER>
+ aSet(m_pImpl->m_pTableCursor->GetDoc().GetAttrPool());
+ // first look at the attributes of the cursor
+ SwUnoTableCursor& rCursor =
+ dynamic_cast<SwUnoTableCursor&>(*m_pImpl->m_pTableCursor);
+ SwUnoCursorHelper::GetCursorAttr(rCursor.GetSelRing(), aSet);
+ m_pImpl->m_pPropSet->getPropertyValue(*pEntry, aSet, aRet);
+ }
+ }
+
+ }
+ return aRet;
+}
+
+void SwXCellRange::addPropertyChangeListener(const OUString& /*PropertyName*/, const uno::Reference< beans::XPropertyChangeListener > & /*aListener*/)
+ { throw uno::RuntimeException("Not implemented", getXWeak()); }
+
+void SwXCellRange::removePropertyChangeListener(const OUString& /*PropertyName*/, const uno::Reference< beans::XPropertyChangeListener > & /*aListener*/)
+ { throw uno::RuntimeException("Not implemented", getXWeak()); }
+
+void SwXCellRange::addVetoableChangeListener(const OUString& /*PropertyName*/, const uno::Reference< beans::XVetoableChangeListener > & /*aListener*/)
+ { throw uno::RuntimeException("Not implemented", getXWeak()); }
+
+void SwXCellRange::removeVetoableChangeListener(const OUString& /*PropertyName*/, const uno::Reference< beans::XVetoableChangeListener > & /*aListener*/)
+ { throw uno::RuntimeException("Not implemented", getXWeak()); }
+
+///@see SwXCellRange::getData
+uno::Sequence<uno::Sequence<uno::Any>> SAL_CALL SwXCellRange::getDataArray()
+{
+ SolarMutexGuard aGuard;
+ const sal_Int32 nRowCount = m_pImpl->GetRowCount();
+ const sal_Int32 nColCount = m_pImpl->GetColumnCount();
+ if(!nRowCount || !nColCount)
+ throw uno::RuntimeException("Table too complex", getXWeak());
+ lcl_EnsureCoreConnected(m_pImpl->GetFrameFormat(), this);
+ uno::Sequence< uno::Sequence< uno::Any > > aRowSeq(nRowCount);
+ auto vCells(GetCells());
+ auto pCurrentCell(vCells.begin());
+ for(auto& rRow : asNonConstRange(aRowSeq))
+ {
+ rRow = uno::Sequence< uno::Any >(nColCount);
+ for(auto& rCellAny : asNonConstRange(rRow))
+ {
+ auto pCell(static_cast<SwXCell*>(pCurrentCell->get()));
+ if(!pCell)
+ throw uno::RuntimeException("Table too complex", getXWeak());
+ rCellAny = pCell->GetAny();
+ ++pCurrentCell;
+ }
+ }
+ return aRowSeq;
+}
+
+///@see SwXCellRange::setData
+void SAL_CALL SwXCellRange::setDataArray(const uno::Sequence< uno::Sequence< uno::Any > >& rArray)
+{
+ SolarMutexGuard aGuard;
+ const sal_Int32 nRowCount = m_pImpl->GetRowCount();
+ const sal_Int32 nColCount = m_pImpl->GetColumnCount();
+ if(!nRowCount || !nColCount)
+ throw uno::RuntimeException("Table too complex", getXWeak());
+ SwFrameFormat *const pFormat = m_pImpl->GetFrameFormat();
+ if(!pFormat)
+ return;
+ if(rArray.getLength() != nRowCount)
+ throw uno::RuntimeException("Row count mismatch. expected: " + OUString::number(nRowCount) + " got: " + OUString::number(rArray.getLength()), getXWeak());
+ auto vCells(GetCells());
+ auto pCurrentCell(vCells.begin());
+ for(const auto& rColSeq : rArray)
+ {
+ if(rColSeq.getLength() != nColCount)
+ throw uno::RuntimeException("Column count mismatch. expected: " + OUString::number(nColCount) + " got: " + OUString::number(rColSeq.getLength()), getXWeak());
+ for(const auto& aValue : rColSeq)
+ {
+ auto pCell(static_cast<SwXCell*>(pCurrentCell->get()));
+ if(!pCell || !pCell->GetTableBox())
+ throw uno::RuntimeException("Box for cell missing", getXWeak());
+ if(aValue.isExtractableTo(cppu::UnoType<OUString>::get()))
+ sw_setString(*pCell, aValue.get<OUString>());
+ else if(aValue.isExtractableTo(cppu::UnoType<double>::get()))
+ sw_setValue(*pCell, aValue.get<double>());
+ else
+ sw_setString(*pCell, OUString(), true);
+ ++pCurrentCell;
+ }
+ }
+}
+
+uno::Sequence<uno::Sequence<double>> SAL_CALL
+SwXCellRange::getData()
+{
+ SolarMutexGuard aGuard;
+ const sal_Int32 nRowCount = m_pImpl->GetRowCount();
+ const sal_Int32 nColCount = m_pImpl->GetColumnCount();
+ if(!nRowCount || !nColCount)
+ throw uno::RuntimeException("Table too complex", getXWeak());
+ if (m_pImpl->m_bFirstColumnAsLabel || m_pImpl->m_bFirstRowAsLabel)
+ {
+ uno::Reference<chart::XChartDataArray> const xDataRange(
+ getCellRangeByPosition((m_pImpl->m_bFirstColumnAsLabel) ? 1 : 0,
+ (m_pImpl->m_bFirstRowAsLabel) ? 1 : 0,
+ nColCount-1, nRowCount-1), uno::UNO_QUERY_THROW);
+ return xDataRange->getData();
+ }
+ uno::Sequence< uno::Sequence< double > > vRows(nRowCount);
+ auto vCells(GetCells());
+ auto pCurrentCell(vCells.begin());
+ for(auto& rRow : asNonConstRange(vRows))
+ {
+ rRow = uno::Sequence<double>(nColCount);
+ for(auto& rValue : asNonConstRange(rRow))
+ {
+ if(!(*pCurrentCell))
+ throw uno::RuntimeException("Table too complex", getXWeak());
+ rValue = (*pCurrentCell)->getValue();
+ ++pCurrentCell;
+ }
+ }
+ return vRows;
+}
+
+void SAL_CALL
+SwXCellRange::setData(const uno::Sequence< uno::Sequence<double> >& rData)
+{
+ SolarMutexGuard aGuard;
+ const sal_Int32 nRowCount = m_pImpl->GetRowCount();
+ const sal_Int32 nColCount = m_pImpl->GetColumnCount();
+ if(!nRowCount || !nColCount)
+ throw uno::RuntimeException("Table too complex", getXWeak());
+ if (m_pImpl->m_bFirstColumnAsLabel || m_pImpl->m_bFirstRowAsLabel)
+ {
+ uno::Reference<chart::XChartDataArray> const xDataRange(
+ getCellRangeByPosition((m_pImpl->m_bFirstColumnAsLabel) ? 1 : 0,
+ (m_pImpl->m_bFirstRowAsLabel) ? 1 : 0,
+ nColCount-1, nRowCount-1), uno::UNO_QUERY_THROW);
+ return xDataRange->setData(rData);
+ }
+ lcl_EnsureCoreConnected(m_pImpl->GetFrameFormat(), this);
+ if(rData.getLength() != nRowCount)
+ throw uno::RuntimeException("Row count mismatch. expected: " + OUString::number(nRowCount) + " got: " + OUString::number(rData.getLength()), getXWeak());
+ auto vCells(GetCells());
+ auto pCurrentCell(vCells.begin());
+ for(const auto& rRow : rData)
+ {
+ if(rRow.getLength() != nColCount)
+ throw uno::RuntimeException("Column count mismatch. expected: " + OUString::number(nColCount) + " got: " + OUString::number(rRow.getLength()), getXWeak());
+ for(const auto& rValue : rRow)
+ {
+ uno::Reference<table::XCell>(*pCurrentCell, uno::UNO_SET_THROW)->setValue(rValue);
+ ++pCurrentCell;
+ }
+ }
+}
+
+std::tuple<sal_uInt32, sal_uInt32, sal_uInt32, sal_uInt32>
+SwXCellRange::Impl::GetLabelCoordinates(bool bRow)
+{
+ sal_uInt32 nLeft, nTop, nRight, nBottom;
+ nLeft = nTop = nRight = nBottom = 0;
+ if(bRow)
+ {
+ nTop = m_bFirstRowAsLabel ? 1 : 0;
+ nBottom = GetRowCount() - 1;
+ }
+ else
+ {
+ nLeft = m_bFirstColumnAsLabel ? 1 : 0;
+ nRight = GetColumnCount() - 1;
+ }
+ return std::make_tuple(nLeft, nTop, nRight, nBottom);
+}
+
+uno::Sequence<OUString>
+SwXCellRange::Impl::GetLabelDescriptions(SwXCellRange & rThis, bool bRow)
+{
+ SolarMutexGuard aGuard;
+ sal_uInt32 nLeft, nTop, nRight, nBottom;
+ std::tie(nLeft, nTop, nRight, nBottom) = GetLabelCoordinates(bRow);
+ if(!nRight && !nBottom)
+ throw uno::RuntimeException("Table too complex", rThis.getXWeak());
+ lcl_EnsureCoreConnected(GetFrameFormat(), &rThis);
+ if (!(bRow ? m_bFirstColumnAsLabel : m_bFirstRowAsLabel))
+ return {}; // without labels we have no descriptions
+ auto xLabelRange(rThis.getCellRangeByPosition(nLeft, nTop, nRight, nBottom));
+ auto vCells(static_cast<SwXCellRange*>(xLabelRange.get())->GetCells());
+ uno::Sequence<OUString> vResult(vCells.size());
+ std::transform(vCells.begin(), vCells.end(), vResult.getArray(),
+ [](uno::Reference<table::XCell> xCell) -> OUString { return uno::Reference<text::XText>(xCell, uno::UNO_QUERY_THROW)->getString(); });
+ return vResult;
+}
+
+uno::Sequence<OUString> SAL_CALL SwXCellRange::getRowDescriptions()
+{
+ return m_pImpl->GetLabelDescriptions(*this, true);
+}
+
+uno::Sequence<OUString> SAL_CALL SwXCellRange::getColumnDescriptions()
+{
+ return m_pImpl->GetLabelDescriptions(*this, false);
+}
+
+void SwXCellRange::Impl::SetLabelDescriptions(SwXCellRange & rThis,
+ const uno::Sequence<OUString>& rDesc, bool bRow)
+{
+ SolarMutexGuard aGuard;
+ lcl_EnsureCoreConnected(GetFrameFormat(), &rThis);
+ if (!(bRow ? m_bFirstColumnAsLabel : m_bFirstRowAsLabel))
+ return; // if there are no labels we cannot set descriptions
+ sal_uInt32 nLeft, nTop, nRight, nBottom;
+ std::tie(nLeft, nTop, nRight, nBottom) = GetLabelCoordinates(bRow);
+ if(!nRight && !nBottom)
+ throw uno::RuntimeException("Table too complex", rThis.getXWeak());
+ auto xLabelRange(rThis.getCellRangeByPosition(nLeft, nTop, nRight, nBottom));
+ if (!xLabelRange.is())
+ throw uno::RuntimeException("Missing Cell Range", rThis.getXWeak());
+ auto vCells(static_cast<SwXCellRange*>(xLabelRange.get())->GetCells());
+ if (sal::static_int_cast<sal_uInt32>(rDesc.getLength()) != vCells.size())
+ throw uno::RuntimeException("Too few or too many descriptions", rThis.getXWeak());
+ auto pDescIterator(rDesc.begin());
+ for(auto& xCell : vCells)
+ uno::Reference<text::XText>(xCell, uno::UNO_QUERY_THROW)->setString(*pDescIterator++);
+}
+
+void SAL_CALL SwXCellRange::setRowDescriptions(
+ const uno::Sequence<OUString>& rRowDesc)
+{
+ m_pImpl->SetLabelDescriptions(*this, rRowDesc, true);
+}
+
+void SAL_CALL SwXCellRange::setColumnDescriptions(
+ const uno::Sequence<OUString>& rColumnDesc)
+{
+ m_pImpl->SetLabelDescriptions(*this, rColumnDesc, false);
+}
+
+void SAL_CALL SwXCellRange::addChartDataChangeEventListener(
+ const uno::Reference<chart::XChartDataChangeEventListener> & xListener)
+{
+ // no need to lock here as m_pImpl is const and container threadsafe
+ std::unique_lock aGuard(m_pImpl->m_Mutex);
+ m_pImpl->m_ChartListeners.addInterface(aGuard, xListener);
+}
+
+void SAL_CALL SwXCellRange::removeChartDataChangeEventListener(
+ const uno::Reference<chart::XChartDataChangeEventListener> & xListener)
+{
+ // no need to lock here as m_pImpl is const and container threadsafe
+ std::unique_lock aGuard(m_pImpl->m_Mutex);
+ m_pImpl->m_ChartListeners.removeInterface(aGuard, xListener);
+}
+
+sal_Bool SwXCellRange::isNotANumber(double /*fNumber*/)
+ { throw uno::RuntimeException("Not implemented", getXWeak()); }
+
+double SwXCellRange::getNotANumber()
+ { throw uno::RuntimeException("Not implemented", getXWeak()); }
+
+uno::Sequence< beans::PropertyValue > SwXCellRange::createSortDescriptor()
+{
+ SolarMutexGuard aGuard;
+ return SwUnoCursorHelper::CreateSortDescriptor(true);
+}
+
+void SAL_CALL SwXCellRange::sort(const uno::Sequence< beans::PropertyValue >& rDescriptor)
+{
+ SolarMutexGuard aGuard;
+ SwSortOptions aSortOpt;
+ SwFrameFormat *const pFormat = m_pImpl->GetFrameFormat();
+ if(pFormat && SwUnoCursorHelper::ConvertSortProperties(rDescriptor, aSortOpt))
+ {
+ SwUnoTableCursor& rTableCursor = dynamic_cast<SwUnoTableCursor&>(*m_pImpl->m_pTableCursor);
+ rTableCursor.MakeBoxSels();
+ UnoActionContext aContext(pFormat->GetDoc());
+ pFormat->GetDoc()->SortTable(rTableCursor.GetSelectedBoxes(), aSortOpt);
+ }
+}
+
+sal_Int32 SwXCellRange::Impl::GetColumnCount() const
+{
+ return m_RangeDescriptor.nRight - m_RangeDescriptor.nLeft + 1;
+}
+
+sal_Int32 SwXCellRange::Impl::GetRowCount() const
+{
+ return m_RangeDescriptor.nBottom - m_RangeDescriptor.nTop + 1;
+}
+
+const SwUnoCursor* SwXCellRange::GetTableCursor() const
+{
+ SwFrameFormat *const pFormat = m_pImpl->GetFrameFormat();
+ return pFormat ? &(*m_pImpl->m_pTableCursor) : nullptr;
+}
+
+void SwXCellRange::Impl::Notify( const SfxHint& rHint )
+{
+ uno::Reference<uno::XInterface> const xThis(m_wThis);
+ if(rHint.GetId() == SfxHintId::Dying)
+ {
+ m_pFrameFormat = nullptr;
+ m_pTableCursor.reset(nullptr);
+ }
+ if (xThis.is())
+ { // fdo#72695: if UNO object is already dead, don't revive it with event
+ if(m_pFrameFormat)
+ {
+ std::unique_lock aGuard(m_Mutex);
+ lcl_SendChartEvent(aGuard, xThis, m_ChartListeners);
+ }
+ else
+ {
+ std::unique_lock aGuard(m_Mutex);
+ m_ChartListeners.disposeAndClear(aGuard, lang::EventObject(xThis));
+ }
+ }
+}
+
+class SwXTableRows::Impl : public SvtListener
+{
+private:
+ SwFrameFormat* m_pFrameFormat;
+
+public:
+ explicit Impl(SwFrameFormat& rFrameFormat) : m_pFrameFormat(&rFrameFormat)
+ {
+ StartListening(rFrameFormat.GetNotifier());
+ }
+ SwFrameFormat* GetFrameFormat() { return m_pFrameFormat; }
+ virtual void Notify(const SfxHint&) override;
+};
+
+// SwXTableRows
+
+OUString SwXTableRows::getImplementationName()
+ { return "SwXTableRows"; }
+
+sal_Bool SwXTableRows::supportsService(const OUString& rServiceName)
+ { return cppu::supportsService(this, rServiceName); }
+
+uno::Sequence< OUString > SwXTableRows::getSupportedServiceNames()
+ { return { "com.sun.star.text.TableRows" }; }
+
+
+SwXTableRows::SwXTableRows(SwFrameFormat& rFrameFormat) :
+ m_pImpl(new SwXTableRows::Impl(rFrameFormat))
+{ }
+
+SwXTableRows::~SwXTableRows()
+{ }
+
+SwFrameFormat* SwXTableRows::GetFrameFormat()
+{
+ return m_pImpl->GetFrameFormat();
+}
+
+sal_Int32 SwXTableRows::getCount()
+{
+ SolarMutexGuard aGuard;
+ SwFrameFormat* pFrameFormat = GetFrameFormat();
+ if(!pFrameFormat)
+ throw uno::RuntimeException();
+ SwTable* pTable = SwTable::FindTable(pFrameFormat);
+ return pTable->GetTabLines().size();
+}
+
+///@see SwXCell::CreateXCell (TODO: seems to be copy and paste programming here)
+uno::Any SwXTableRows::getByIndex(sal_Int32 nIndex)
+{
+ SolarMutexGuard aGuard;
+ SwFrameFormat* pFrameFormat(lcl_EnsureCoreConnected(GetFrameFormat(), this));
+ if(nIndex < 0)
+ throw lang::IndexOutOfBoundsException();
+ SwTable* pTable = SwTable::FindTable( pFrameFormat );
+ if(o3tl::make_unsigned(nIndex) >= pTable->GetTabLines().size())
+ throw lang::IndexOutOfBoundsException();
+ SwTableLine* pLine = pTable->GetTabLines()[nIndex];
+ FindUnoInstanceHint<SwTableLine,SwXTextTableRow> aHint{pLine};
+ pFrameFormat->GetNotifier().Broadcast(aHint);
+ if(!aHint.m_pResult)
+ aHint.m_pResult = new SwXTextTableRow(pFrameFormat, pLine);
+ uno::Reference<beans::XPropertySet> xRet = static_cast<beans::XPropertySet*>(aHint.m_pResult.get());
+ return uno::Any(xRet);
+}
+
+uno::Type SAL_CALL SwXTableRows::getElementType()
+{
+ return cppu::UnoType<beans::XPropertySet>::get();
+}
+
+sal_Bool SwXTableRows::hasElements()
+{
+ SolarMutexGuard aGuard;
+ SwFrameFormat* pFrameFormat = GetFrameFormat();
+ if(!pFrameFormat)
+ throw uno::RuntimeException();
+ // a table always has rows
+ return true;
+}
+
+void SwXTableRows::insertByIndex(sal_Int32 nIndex, sal_Int32 nCount)
+{
+ SolarMutexGuard aGuard;
+ if (nCount == 0)
+ return;
+ SwFrameFormat* pFrameFormat(lcl_EnsureCoreConnected(GetFrameFormat(), this));
+ SwTable* pTable = lcl_EnsureTableNotComplex(SwTable::FindTable(pFrameFormat), this);
+ const size_t nRowCount = pTable->GetTabLines().size();
+ if (nCount <= 0 || 0 > nIndex || o3tl::make_unsigned(nIndex) > nRowCount)
+ throw uno::RuntimeException("Illegal arguments", getXWeak());
+ const OUString sTLName = sw_GetCellName(0, nIndex);
+ const SwTableBox* pTLBox = pTable->GetTableBox(sTLName);
+ bool bAppend = false;
+ if(!pTLBox)
+ {
+ bAppend = true;
+ // to append at the end the cursor must be in the last line
+ SwTableLines& rLines = pTable->GetTabLines();
+ SwTableLine* pLine = rLines.back();
+ SwTableBoxes& rBoxes = pLine->GetTabBoxes();
+ pTLBox = rBoxes.front();
+ }
+ if(!pTLBox)
+ throw uno::RuntimeException("Illegal arguments", getXWeak());
+ const SwStartNode* pSttNd = pTLBox->GetSttNd();
+ SwPosition aPos(*pSttNd);
+ // set cursor to the upper-left cell of the range
+ UnoActionContext aAction(pFrameFormat->GetDoc());
+ std::shared_ptr<SwUnoTableCursor> const pUnoCursor(
+ std::dynamic_pointer_cast<SwUnoTableCursor>(
+ pFrameFormat->GetDoc()->CreateUnoCursor(aPos, true)));
+ pUnoCursor->Move( fnMoveForward, GoInNode );
+ {
+ // remove actions - TODO: why?
+ UnoActionRemoveContext aRemoveContext(&pUnoCursor->GetDoc());
+ }
+ pFrameFormat->GetDoc()->InsertRow(*pUnoCursor, o3tl::narrowing<sal_uInt16>(nCount), bAppend);
+}
+
+void SwXTableRows::removeByIndex(sal_Int32 nIndex, sal_Int32 nCount)
+{
+ SolarMutexGuard aGuard;
+ if (nCount == 0)
+ return;
+ SwFrameFormat* pFrameFormat(lcl_EnsureCoreConnected(GetFrameFormat(), this));
+ if(nIndex < 0 || nCount <=0 )
+ throw uno::RuntimeException();
+ SwTable* pTable = lcl_EnsureTableNotComplex(SwTable::FindTable(pFrameFormat), this);
+ OUString sTLName = sw_GetCellName(0, nIndex);
+ const SwTableBox* pTLBox = pTable->GetTableBox(sTLName);
+ if(!pTLBox)
+ throw uno::RuntimeException("Illegal arguments", getXWeak());
+ const SwStartNode* pSttNd = pTLBox->GetSttNd();
+ SwPosition aPos(*pSttNd);
+ // set cursor to the upper-left cell of the range
+ auto pUnoCursor(pFrameFormat->GetDoc()->CreateUnoCursor(aPos, true));
+ pUnoCursor->Move(fnMoveForward, GoInNode);
+ pUnoCursor->SetRemainInSection( false );
+ const OUString sBLName = sw_GetCellName(0, nIndex + nCount - 1);
+ const SwTableBox* pBLBox = pTable->GetTableBox( sBLName );
+ if(!pBLBox)
+ throw uno::RuntimeException("Illegal arguments", getXWeak());
+ pUnoCursor->SetMark();
+ pUnoCursor->GetPoint()->Assign( *pBLBox->GetSttNd() );
+ pUnoCursor->Move(fnMoveForward, GoInNode);
+ SwUnoTableCursor& rCursor = dynamic_cast<SwUnoTableCursor&>(*pUnoCursor);
+ {
+ // HACK: remove pending actions for selecting old style tables
+ UnoActionRemoveContext aRemoveContext(rCursor);
+ }
+ rCursor.MakeBoxSels();
+ { // these braces are important
+ UnoActionContext aAction(pFrameFormat->GetDoc());
+ pFrameFormat->GetDoc()->DeleteRow(*pUnoCursor);
+ pUnoCursor.reset();
+ }
+ {
+ // invalidate all actions - TODO: why?
+ UnoActionRemoveContext aRemoveContext(pFrameFormat->GetDoc());
+ }
+}
+
+void SwXTableRows::Impl::Notify( const SfxHint& rHint)
+{
+ if(rHint.GetId() == SfxHintId::Dying)
+ m_pFrameFormat = nullptr;
+}
+
+// SwXTableColumns
+
+class SwXTableColumns::Impl : public SvtListener
+{
+ SwFrameFormat* m_pFrameFormat;
+ public:
+ explicit Impl(SwFrameFormat& rFrameFormat) : m_pFrameFormat(&rFrameFormat)
+ {
+ StartListening(rFrameFormat.GetNotifier());
+ }
+ SwFrameFormat* GetFrameFormat() { return m_pFrameFormat; }
+ virtual void Notify(const SfxHint&) override;
+};
+
+OUString SwXTableColumns::getImplementationName()
+ { return "SwXTableColumns"; }
+
+sal_Bool SwXTableColumns::supportsService(const OUString& rServiceName)
+ { return cppu::supportsService(this, rServiceName); }
+
+uno::Sequence< OUString > SwXTableColumns::getSupportedServiceNames()
+ { return { "com.sun.star.text.TableColumns"}; }
+
+
+SwXTableColumns::SwXTableColumns(SwFrameFormat& rFrameFormat) :
+ m_pImpl(new SwXTableColumns::Impl(rFrameFormat))
+{ }
+
+SwXTableColumns::~SwXTableColumns()
+{ }
+
+SwFrameFormat* SwXTableColumns::GetFrameFormat() const
+{
+ return m_pImpl->GetFrameFormat();
+}
+
+sal_Int32 SwXTableColumns::getCount()
+{
+ SolarMutexGuard aGuard;
+ SwFrameFormat* pFrameFormat(lcl_EnsureCoreConnected(GetFrameFormat(), this));
+ SwTable* pTable = SwTable::FindTable( pFrameFormat );
+// if(!pTable->IsTableComplex())
+// throw uno::RuntimeException("Table too complex", getXWeak());
+ SwTableLines& rLines = pTable->GetTabLines();
+ SwTableLine* pLine = rLines.front();
+ return pLine->GetTabBoxes().size();
+}
+
+uno::Any SwXTableColumns::getByIndex(sal_Int32 nIndex)
+{
+ SolarMutexGuard aGuard;
+ if(nIndex < 0 || getCount() <= nIndex)
+ throw lang::IndexOutOfBoundsException();
+ return uno::Any(uno::Reference<uno::XInterface>()); // i#21699 not supported
+}
+
+uno::Type SAL_CALL SwXTableColumns::getElementType()
+{
+ return cppu::UnoType<uno::XInterface>::get();
+}
+
+sal_Bool SwXTableColumns::hasElements()
+{
+ SolarMutexGuard aGuard;
+ lcl_EnsureCoreConnected(GetFrameFormat(), this);
+ return true;
+}
+
+///@see SwXTableRows::insertByIndex (TODO: seems to be copy and paste programming here)
+void SwXTableColumns::insertByIndex(sal_Int32 nIndex, sal_Int32 nCount)
+{
+ SolarMutexGuard aGuard;
+ if (nCount == 0)
+ return;
+ SwFrameFormat* pFrameFormat(lcl_EnsureCoreConnected(GetFrameFormat(), this));
+ SwTable* pTable = lcl_EnsureTableNotComplex(SwTable::FindTable(pFrameFormat), this);
+ SwTableLines& rLines = pTable->GetTabLines();
+ SwTableLine* pLine = rLines.front();
+ const size_t nColCount = pLine->GetTabBoxes().size();
+ if (nCount <= 0 || 0 > nIndex || o3tl::make_unsigned(nIndex) > nColCount)
+ throw uno::RuntimeException("Illegal arguments", getXWeak());
+ const OUString sTLName = sw_GetCellName(nIndex, 0);
+ const SwTableBox* pTLBox = pTable->GetTableBox( sTLName );
+ bool bAppend = false;
+ if(!pTLBox)
+ {
+ bAppend = true;
+ // to append at the end the cursor must be in the last line
+ SwTableBoxes& rBoxes = pLine->GetTabBoxes();
+ pTLBox = rBoxes.back();
+ }
+ if(!pTLBox)
+ throw uno::RuntimeException("Illegal arguments", getXWeak());
+ const SwStartNode* pSttNd = pTLBox->GetSttNd();
+ SwPosition aPos(*pSttNd);
+ UnoActionContext aAction(pFrameFormat->GetDoc());
+ auto pUnoCursor(pFrameFormat->GetDoc()->CreateUnoCursor(aPos, true));
+ pUnoCursor->Move(fnMoveForward, GoInNode);
+
+ {
+ // remove actions - TODO: why?
+ UnoActionRemoveContext aRemoveContext(&pUnoCursor->GetDoc());
+ }
+
+ pFrameFormat->GetDoc()->InsertCol(*pUnoCursor, o3tl::narrowing<sal_uInt16>(nCount), bAppend);
+}
+
+///@see SwXTableRows::removeByIndex (TODO: seems to be copy and paste programming here)
+void SwXTableColumns::removeByIndex(sal_Int32 nIndex, sal_Int32 nCount)
+{
+ SolarMutexGuard aGuard;
+ if (nCount == 0)
+ return;
+ SwFrameFormat* pFrameFormat(lcl_EnsureCoreConnected(GetFrameFormat(), this));
+ if(nIndex < 0 || nCount <=0 )
+ throw uno::RuntimeException();
+ SwTable* pTable = lcl_EnsureTableNotComplex(SwTable::FindTable(pFrameFormat), this);
+ const OUString sTLName = sw_GetCellName(nIndex, 0);
+ const SwTableBox* pTLBox = pTable->GetTableBox( sTLName );
+ if(!pTLBox)
+ throw uno::RuntimeException("Cell not found", getXWeak());
+ const SwStartNode* pSttNd = pTLBox->GetSttNd();
+ SwPosition aPos(*pSttNd);
+ // set cursor to the upper-left cell of the range
+ auto pUnoCursor(pFrameFormat->GetDoc()->CreateUnoCursor(aPos, true));
+ pUnoCursor->Move(fnMoveForward, GoInNode);
+ pUnoCursor->SetRemainInSection(false);
+ const OUString sTRName = sw_GetCellName(nIndex + nCount - 1, 0);
+ const SwTableBox* pTRBox = pTable->GetTableBox(sTRName);
+ if(!pTRBox)
+ throw uno::RuntimeException("Cell not found", getXWeak());
+ pUnoCursor->SetMark();
+ pUnoCursor->GetPoint()->Assign( *pTRBox->GetSttNd() );
+ pUnoCursor->Move(fnMoveForward, GoInNode);
+ SwUnoTableCursor& rCursor = dynamic_cast<SwUnoTableCursor&>(*pUnoCursor);
+ {
+ // HACK: remove pending actions for selecting old style tables
+ UnoActionRemoveContext aRemoveContext(rCursor);
+ }
+ rCursor.MakeBoxSels();
+ { // these braces are important
+ UnoActionContext aAction(pFrameFormat->GetDoc());
+ pFrameFormat->GetDoc()->DeleteCol(*pUnoCursor);
+ pUnoCursor.reset();
+ }
+ {
+ // invalidate all actions - TODO: why?
+ UnoActionRemoveContext aRemoveContext(pFrameFormat->GetDoc());
+ }
+}
+
+void SwXTableColumns::Impl::Notify(const SfxHint& rHint)
+{
+ if(rHint.GetId() == SfxHintId::Dying)
+ m_pFrameFormat = nullptr;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/core/unocore/unotext.cxx b/sw/source/core/unocore/unotext.cxx
new file mode 100644
index 0000000000..f959d6a610
--- /dev/null
+++ b/sw/source/core/unocore/unotext.cxx
@@ -0,0 +1,2706 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <stdlib.h>
+
+#include <memory>
+#include <set>
+
+#include <com/sun/star/drawing/XDrawPageSupplier.hpp>
+#include <com/sun/star/text/ControlCharacter.hpp>
+#include <com/sun/star/text/TableColumnSeparator.hpp>
+#include <com/sun/star/lang/IndexOutOfBoundsException.hpp>
+#include <com/sun/star/lang/WrappedTargetRuntimeException.hpp>
+
+#include <svl/listener.hxx>
+#include <vcl/svapp.hxx>
+#include <comphelper/profilezone.hxx>
+#include <comphelper/sequence.hxx>
+#include <comphelper/servicehelper.hxx>
+#include <cppuhelper/exc_hlp.hxx>
+#include <cppuhelper/supportsservice.hxx>
+#include <sal/log.hxx>
+#include <comphelper/diagnose_ex.hxx>
+
+#include <cmdid.h>
+#include <unotextbodyhf.hxx>
+#include <unotext.hxx>
+#include <unotextrange.hxx>
+#include <unotextcursor.hxx>
+#include <unosection.hxx>
+#include <unobookmark.hxx>
+#include <unorefmark.hxx>
+#include <unoport.hxx>
+#include <unotbl.hxx>
+#include <unoidx.hxx>
+#include <unocoll.hxx>
+#include <unoframe.hxx>
+#include <unofield.hxx>
+#include <unometa.hxx>
+#include <unomap.hxx>
+#include <unoprnms.hxx>
+#include <unoparagraph.hxx>
+#include <unocrsrhelper.hxx>
+#include <docary.hxx>
+#include <doc.hxx>
+#include <IDocumentRedlineAccess.hxx>
+#include <IDocumentUndoRedo.hxx>
+#include <bookmark.hxx>
+#include <redline.hxx>
+#include <swundo.hxx>
+#include <section.hxx>
+#include <fmtanchr.hxx>
+#include <fmtcntnt.hxx>
+#include <ndtxt.hxx>
+#include <SwRewriter.hxx>
+#include <strings.hrc>
+#include <frameformats.hxx>
+#include <unocontentcontrol.hxx>
+
+using namespace ::com::sun::star;
+
+constexpr OUString cInvalidObject = u"this object is invalid"_ustr;
+
+class SwXText::Impl
+{
+
+public:
+ SwXText & m_rThis;
+ SfxItemPropertySet const& m_rPropSet;
+ const CursorType m_eType;
+ SwDoc * m_pDoc;
+ bool m_bIsValid;
+
+ Impl( SwXText & rThis,
+ SwDoc *const pDoc, const CursorType eType)
+ : m_rThis(rThis)
+ , m_rPropSet(*aSwMapProvider.GetPropertySet(PROPERTY_MAP_TEXT))
+ , m_eType(eType)
+ , m_pDoc(pDoc)
+ , m_bIsValid(nullptr != pDoc)
+ {
+ }
+
+ /// @throws lang::IllegalArgumentException
+ /// @throws uno::RuntimeException
+ rtl::Reference<SwXParagraph>
+ finishOrAppendParagraph(
+ const uno::Sequence< beans::PropertyValue >&
+ rCharacterAndParagraphProperties,
+ const uno::Reference< text::XTextRange >& xInsertPosition);
+
+ /// @throws lang::IllegalArgumentException
+ /// @throws uno::RuntimeException
+ sal_Int16 ComparePositions(
+ const uno::Reference<text::XTextRange>& xPos1,
+ const uno::Reference<text::XTextRange>& xPos2);
+
+ /// @throws lang::IllegalArgumentException
+ /// @throws uno::RuntimeException
+ bool CheckForOwnMember(const SwPaM & rPaM);
+
+ void ConvertCell(
+ const uno::Sequence< uno::Reference< text::XTextRange > > & rCell,
+ std::vector<SwNodeRange> & rRowNodes,
+ SwNodeRange *const pLastCell);
+
+};
+
+SwXText::SwXText(SwDoc *const pDoc, const CursorType eType)
+ : m_pImpl( new SwXText::Impl(*this, pDoc, eType) )
+{
+}
+
+SwXText::~SwXText()
+{
+}
+
+const SwDoc * SwXText::GetDoc() const
+{
+ return m_pImpl->m_pDoc;
+}
+
+SwDoc * SwXText::GetDoc()
+{
+ return m_pImpl->m_pDoc;
+}
+
+bool SwXText::IsValid() const
+{
+ return m_pImpl->m_bIsValid;
+}
+
+void SwXText::Invalidate()
+{
+ m_pImpl->m_bIsValid = false;
+}
+
+void SwXText::SetDoc(SwDoc *const pDoc)
+{
+ OSL_ENSURE(!m_pImpl->m_pDoc || !pDoc,
+ "SwXText::SetDoc: already have a doc?");
+ m_pImpl->m_pDoc = pDoc;
+ m_pImpl->m_bIsValid = (nullptr != pDoc);
+}
+
+void
+SwXText::PrepareForAttach(uno::Reference< text::XTextRange > &, const SwPaM &)
+{
+}
+
+bool SwXText::CheckForOwnMemberMeta(const SwPaM &, const bool)
+{
+ OSL_ENSURE(CursorType::Meta != m_pImpl->m_eType, "should not be called!");
+ return false;
+}
+
+const SwStartNode *SwXText::GetStartNode() const
+{
+ return GetDoc()->GetNodes().GetEndOfContent().StartOfSectionNode();
+}
+
+uno::Reference< text::XTextCursor > SAL_CALL SwXText::createTextCursor()
+{
+ SolarMutexGuard aGuard;
+ rtl::Reference<SwXTextCursor> xCursor = createXTextCursor();
+ if (!xCursor.is())
+ throw uno::RuntimeException(cInvalidObject);
+ return static_cast<text::XWordCursor*>(xCursor.get());
+}
+
+rtl::Reference< SwXTextCursor >
+SwXText::createXTextCursor()
+{
+ rtl::Reference< SwXTextCursor > xRet;
+ if(IsValid())
+ {
+ SwNode& rNode = GetDoc()->GetNodes().GetEndOfContent();
+ SwPosition aPos(rNode);
+ xRet = new SwXTextCursor(*GetDoc(), this, m_pImpl->m_eType, aPos);
+ xRet->gotoStart(false);
+ }
+ return xRet;
+}
+
+css::uno::Reference< css::text::XTextCursor > SAL_CALL SwXText::createTextCursorByRange(
+ const ::css::uno::Reference< ::css::text::XTextRange >& aTextPosition )
+{
+ SolarMutexGuard aGuard;
+ return static_cast<text::XWordCursor*>(createXTextCursorByRange(aTextPosition).get());
+}
+
+
+uno::Any SAL_CALL
+SwXText::queryInterface(const uno::Type& rType)
+{
+ uno::Any aRet;
+ if (rType == cppu::UnoType<text::XText>::get())
+ {
+ aRet <<= uno::Reference< text::XText >(this);
+ }
+ else if (rType == cppu::UnoType<text::XSimpleText>::get())
+ {
+ aRet <<= uno::Reference< text::XSimpleText >(this);
+ }
+ else if (rType == cppu::UnoType<text::XTextRange>::get())
+ {
+ aRet <<= uno::Reference< text::XTextRange>(this);
+ }
+ else if (rType == cppu::UnoType<text::XTextRangeCompare>::get())
+ {
+ aRet <<= uno::Reference< text::XTextRangeCompare >(this);
+ }
+ else if (rType == cppu::UnoType<lang::XTypeProvider>::get())
+ {
+ aRet <<= uno::Reference< lang::XTypeProvider >(this);
+ }
+ else if (rType == cppu::UnoType<text::XRelativeTextContentInsert>::get())
+ {
+ aRet <<= uno::Reference< text::XRelativeTextContentInsert >(this);
+ }
+ else if (rType == cppu::UnoType<text::XRelativeTextContentRemove>::get())
+ {
+ aRet <<= uno::Reference< text::XRelativeTextContentRemove >(this);
+ }
+ else if (rType == cppu::UnoType<beans::XPropertySet>::get())
+ {
+ aRet <<= uno::Reference< beans::XPropertySet >(this);
+ }
+ else if (rType == cppu::UnoType<text::XTextAppendAndConvert>::get())
+ {
+ aRet <<= uno::Reference< text::XTextAppendAndConvert >(this);
+ }
+ else if (rType == cppu::UnoType<text::XTextAppend>::get())
+ {
+ aRet <<= uno::Reference< text::XTextAppend >(this);
+ }
+ else if (rType == cppu::UnoType<text::XTextPortionAppend>::get())
+ {
+ aRet <<= uno::Reference< text::XTextPortionAppend >(this);
+ }
+ else if (rType == cppu::UnoType<text::XParagraphAppend>::get())
+ {
+ aRet <<= uno::Reference< text::XParagraphAppend >(this);
+ }
+ else if (rType == cppu::UnoType<text::XTextConvert>::get() )
+ {
+ aRet <<= uno::Reference< text::XTextConvert >(this);
+ }
+ else if (rType == cppu::UnoType<text::XTextContentAppend>::get())
+ {
+ aRet <<= uno::Reference< text::XTextContentAppend >(this);
+ }
+ else if(rType == cppu::UnoType<text::XTextCopy>::get())
+ {
+ aRet <<= uno::Reference< text::XTextCopy >( this );
+ }
+ return aRet;
+}
+
+uno::Sequence< uno::Type > SAL_CALL
+SwXText::getTypes()
+{
+ static const uno::Sequence< uno::Type > aTypes {
+ cppu::UnoType<text::XText>::get(),
+ cppu::UnoType<text::XTextRangeCompare>::get(),
+ cppu::UnoType<text::XRelativeTextContentInsert>::get(),
+ cppu::UnoType<text::XRelativeTextContentRemove>::get(),
+ cppu::UnoType<lang::XUnoTunnel>::get(),
+ cppu::UnoType<beans::XPropertySet>::get(),
+ cppu::UnoType<text::XTextPortionAppend>::get(),
+ cppu::UnoType<text::XParagraphAppend>::get(),
+ cppu::UnoType<text::XTextContentAppend>::get(),
+ cppu::UnoType<text::XTextConvert>::get(),
+ cppu::UnoType<text::XTextAppend>::get(),
+ cppu::UnoType<text::XTextAppendAndConvert>::get()
+ };
+ return aTypes;
+}
+
+// belongs the range in the text ? insert it then.
+void SAL_CALL
+SwXText::insertString(const uno::Reference< text::XTextRange >& xTextRange,
+ const OUString& rString, sal_Bool bAbsorb)
+{
+ SolarMutexGuard aGuard;
+ comphelper::ProfileZone aZone("SwXText::insertString");
+
+ if (!xTextRange.is())
+ {
+ throw uno::RuntimeException();
+ }
+ if (!GetDoc())
+ {
+ throw uno::RuntimeException();
+ }
+ SwXTextRange *const pRange = dynamic_cast<SwXTextRange*>(xTextRange.get());
+ OTextCursorHelper *const pCursor = dynamic_cast<OTextCursorHelper*>(xTextRange.get());
+ if ((!pRange || &pRange ->GetDoc() != GetDoc()) &&
+ (!pCursor || pCursor->GetDoc() != GetDoc()))
+ {
+ throw uno::RuntimeException();
+ }
+
+ const SwStartNode *const pOwnStartNode = GetStartNode();
+ SwPaM aPam(GetDoc()->GetNodes());
+ const SwPaM * pPam(nullptr);
+ if (pCursor)
+ {
+ pPam = pCursor->GetPaM();
+ }
+ else // pRange
+ {
+ if (pRange->GetPositions(aPam))
+ {
+ pPam = &aPam;
+ }
+ }
+ if (!pPam)
+ {
+ throw uno::RuntimeException();
+ }
+
+ const SwStartNode* pTmp(pPam->GetPointNode().StartOfSectionNode());
+ while (pTmp && pTmp->IsSectionNode())
+ {
+ pTmp = pTmp->StartOfSectionNode();
+ }
+ if (!pOwnStartNode || (pOwnStartNode != pTmp))
+ {
+ throw uno::RuntimeException();
+ }
+
+ bool bForceExpandHints( false );
+ if (CursorType::Meta == m_pImpl->m_eType)
+ {
+ try
+ {
+ bForceExpandHints = CheckForOwnMemberMeta(*pPam, bAbsorb);
+ }
+ catch (const lang::IllegalArgumentException& iae)
+ {
+ // stupid method not allowed to throw iae
+ css::uno::Any anyEx = cppu::getCaughtException();
+ throw lang::WrappedTargetRuntimeException( iae.Message,
+ uno::Reference< uno::XInterface >(), anyEx );
+ }
+ }
+ if (bAbsorb)
+ {
+ //!! scan for CR characters and inserting the paragraph breaks
+ //!! has to be done in the called function.
+ //!! Implemented in SwXTextRange::DeleteAndInsert
+ if (pCursor)
+ {
+ SwXTextCursor * const pTextCursor(
+ dynamic_cast<SwXTextCursor*>(pCursor) );
+ if (pTextCursor)
+ {
+ pTextCursor->DeleteAndInsert(rString, ::sw::DeleteAndInsertMode::ForceReplace
+ | (bForceExpandHints ? ::sw::DeleteAndInsertMode::ForceExpandHints : ::sw::DeleteAndInsertMode::Default));
+ }
+ else
+ {
+ xTextRange->setString(rString);
+ }
+ }
+ else
+ {
+ pRange->DeleteAndInsert(rString, ::sw::DeleteAndInsertMode::ForceReplace
+ | (bForceExpandHints ? ::sw::DeleteAndInsertMode::ForceExpandHints : ::sw::DeleteAndInsertMode::Default));
+ }
+ }
+ else
+ {
+ // create a PaM positioned before the parameter PaM,
+ // so the text is inserted before
+ UnoActionContext aContext(GetDoc());
+ SwPaM aInsertPam(*pPam->Start());
+ ::sw::GroupUndoGuard const undoGuard(GetDoc()->GetIDocumentUndoRedo());
+ SwUnoCursorHelper::DocInsertStringSplitCR(
+ *GetDoc(), aInsertPam, rString, bForceExpandHints );
+ }
+}
+
+void SAL_CALL
+SwXText::insertControlCharacter(
+ const uno::Reference< text::XTextRange > & xTextRange,
+ sal_Int16 nControlCharacter, sal_Bool bAbsorb)
+{
+ SolarMutexGuard aGuard;
+
+ if (!xTextRange.is())
+ {
+ throw lang::IllegalArgumentException();
+ }
+ if (!GetDoc())
+ {
+ throw uno::RuntimeException();
+ }
+
+ SwUnoInternalPaM aPam(*GetDoc());
+ if (!::sw::XTextRangeToSwPaM(aPam, xTextRange))
+ {
+ throw uno::RuntimeException();
+ }
+ const bool bForceExpandHints(CheckForOwnMemberMeta(aPam, bAbsorb));
+
+ const SwInsertFlags nInsertFlags =
+ bForceExpandHints
+ ? ( SwInsertFlags::FORCEHINTEXPAND | SwInsertFlags::EMPTYEXPAND)
+ : SwInsertFlags::EMPTYEXPAND;
+
+ if (bAbsorb && aPam.HasMark())
+ {
+ m_pImpl->m_pDoc->getIDocumentContentOperations().DeleteAndJoin(aPam);
+ aPam.DeleteMark();
+ }
+
+ sal_Unicode cIns = 0;
+ switch (nControlCharacter)
+ {
+ case text::ControlCharacter::PARAGRAPH_BREAK :
+ // a table cell now becomes an ordinary text cell!
+ m_pImpl->m_pDoc->ClearBoxNumAttrs(aPam.GetPoint()->GetNode());
+ m_pImpl->m_pDoc->getIDocumentContentOperations().SplitNode(*aPam.GetPoint(), false);
+ break;
+ case text::ControlCharacter::APPEND_PARAGRAPH:
+ {
+ m_pImpl->m_pDoc->ClearBoxNumAttrs(aPam.GetPoint()->GetNode());
+ m_pImpl->m_pDoc->getIDocumentContentOperations().AppendTextNode(*aPam.GetPoint());
+
+ SwXTextRange *const pRange =
+ dynamic_cast<SwXTextRange*>(xTextRange.get());
+ OTextCursorHelper *const pCursor =
+ dynamic_cast<OTextCursorHelper*>(xTextRange.get());
+ if (pRange)
+ {
+ pRange->SetPositions(aPam);
+ }
+ else if (pCursor)
+ {
+ SwPaM *const pCursorPam = pCursor->GetPaM();
+ *pCursorPam->GetPoint() = *aPam.GetPoint();
+ pCursorPam->DeleteMark();
+ }
+ }
+ break;
+ case text::ControlCharacter::LINE_BREAK: cIns = 10; break;
+ case text::ControlCharacter::SOFT_HYPHEN: cIns = CHAR_SOFTHYPHEN; break;
+ case text::ControlCharacter::HARD_HYPHEN: cIns = CHAR_HARDHYPHEN; break;
+ case text::ControlCharacter::HARD_SPACE: cIns = CHAR_HARDBLANK; break;
+ }
+ if (cIns)
+ {
+ m_pImpl->m_pDoc->getIDocumentContentOperations().InsertString(
+ aPam, OUString(cIns), nInsertFlags);
+ }
+
+ if (!bAbsorb)
+ return;
+
+ SwXTextRange *const pRange =
+ dynamic_cast<SwXTextRange*>(xTextRange.get());
+ OTextCursorHelper *const pCursor =
+ dynamic_cast<OTextCursorHelper*>(xTextRange.get());
+
+ SwCursor aCursor(*aPam.GetPoint(), nullptr);
+ SwUnoCursorHelper::SelectPam(aCursor, true);
+ aCursor.Left(1);
+ // here, the PaM needs to be moved:
+ if (pRange)
+ {
+ pRange->SetPositions(aCursor);
+ }
+ else if (pCursor)
+ {
+ SwPaM *const pUnoCursor = pCursor->GetPaM();
+ *pUnoCursor->GetPoint() = *aCursor.GetPoint();
+ if (aCursor.HasMark())
+ {
+ pUnoCursor->SetMark();
+ *pUnoCursor->GetMark() = *aCursor.GetMark();
+ }
+ else
+ {
+ pUnoCursor->DeleteMark();
+ }
+ }
+}
+
+void SAL_CALL
+SwXText::insertTextContent(
+ const uno::Reference< text::XTextRange > & xRange,
+ const uno::Reference< text::XTextContent > & xContent,
+ sal_Bool bAbsorb)
+{
+ SolarMutexGuard aGuard;
+ comphelper::ProfileZone aZone("SwXText::insertTextContent");
+
+ if (!xRange.is())
+ throw lang::IllegalArgumentException("first parameter invalid", nullptr, 0);
+ if (!xContent.is())
+ throw lang::IllegalArgumentException("second parameter invalid", nullptr, 1);
+ if (!GetDoc())
+ throw uno::RuntimeException(cInvalidObject);
+
+ SwUnoInternalPaM aPam(*GetDoc());
+ if (!::sw::XTextRangeToSwPaM(aPam, xRange))
+ throw lang::IllegalArgumentException("first parameter invalid", nullptr, 0);
+
+ // first test if the range is at the right position, then call
+ // xContent->attach
+ const SwStartNode* pOwnStartNode = GetStartNode();
+ SwStartNodeType eSearchNodeType = SwNormalStartNode;
+ switch (m_pImpl->m_eType)
+ {
+ case CursorType::Frame: eSearchNodeType = SwFlyStartNode; break;
+ case CursorType::TableText: eSearchNodeType = SwTableBoxStartNode; break;
+ case CursorType::Footnote: eSearchNodeType = SwFootnoteStartNode; break;
+ case CursorType::Header: eSearchNodeType = SwHeaderStartNode; break;
+ case CursorType::Footer: eSearchNodeType = SwFooterStartNode; break;
+ //case CURSOR_INVALID:
+ //case CursorType::Body:
+ default:
+ break;
+ }
+
+ const SwStartNode* pTmp =
+ aPam.GetPointNode().FindSttNodeByType(eSearchNodeType);
+
+ // ignore SectionNodes
+ while (pTmp && pTmp->IsSectionNode())
+ {
+ pTmp = pTmp->StartOfSectionNode();
+ }
+ // if the document starts with a section
+ while (pOwnStartNode && pOwnStartNode->IsSectionNode())
+ {
+ pOwnStartNode = pOwnStartNode->StartOfSectionNode();
+ }
+ // this checks if (this) and xRange are in the same text::XText interface
+ if (pOwnStartNode != pTmp)
+ throw uno::RuntimeException("text interface and cursor not related");
+
+ const bool bForceExpandHints(CheckForOwnMemberMeta(aPam, bAbsorb));
+
+ // special treatment for Contents that do not replace the range, but
+ // instead are "overlaid"
+ SwXDocumentIndexMark *const pDocumentIndexMark =
+ dynamic_cast<SwXDocumentIndexMark*>(xContent.get());
+ SwXTextSection *const pSection =
+ dynamic_cast<SwXTextSection*>(xContent.get());
+ SwXBookmark *const pBookmark =
+ dynamic_cast<SwXBookmark*>(xContent.get());
+ SwXReferenceMark *const pReferenceMark =
+ dynamic_cast<SwXReferenceMark*>(xContent.get());
+ SwXMeta *const pMeta = dynamic_cast<SwXMeta*>(xContent.get());
+ auto* pContentControl = dynamic_cast<SwXContentControl*>(xContent.get());
+ SwXTextField* pTextField = dynamic_cast<SwXTextField*>(xContent.get());
+ if (pTextField && pTextField->GetServiceId() != SwServiceType::FieldTypeAnnotation)
+ pTextField = nullptr;
+
+ const bool bAttribute = pBookmark || pDocumentIndexMark
+ || pSection || pReferenceMark || pMeta || pContentControl || pTextField;
+
+ if (bAbsorb && !bAttribute)
+ {
+ if (SwXTextRange *const pRange = dynamic_cast<SwXTextRange*>(xRange.get()))
+ {
+ pRange->DeleteAndInsert(u"", ::sw::DeleteAndInsertMode::ForceReplace
+ | (bForceExpandHints ? ::sw::DeleteAndInsertMode::ForceExpandHints : ::sw::DeleteAndInsertMode::Default));
+ }
+ else if (SwXTextCursor *const pCursor = dynamic_cast<SwXTextCursor*>(dynamic_cast<OTextCursorHelper*>(xRange.get())))
+ {
+ pCursor->DeleteAndInsert(u"", ::sw::DeleteAndInsertMode::ForceReplace
+ | (bForceExpandHints ? ::sw::DeleteAndInsertMode::ForceExpandHints : ::sw::DeleteAndInsertMode::Default));
+ }
+ else
+ {
+ xRange->setString(OUString());
+ }
+ }
+ uno::Reference< text::XTextRange > xTempRange =
+ (bAttribute && bAbsorb) ? xRange : xRange->getStart();
+ if (bForceExpandHints)
+ {
+ // if necessary, replace xTempRange with a new SwXTextCursor
+ PrepareForAttach(xTempRange, aPam);
+ }
+ xContent->attach(xTempRange);
+}
+
+void SAL_CALL
+SwXText::insertTextContentBefore(
+ const uno::Reference< text::XTextContent>& xNewContent,
+ const uno::Reference< text::XTextContent>& xSuccessor)
+{
+ SolarMutexGuard aGuard;
+
+ if(!GetDoc())
+ throw uno::RuntimeException(cInvalidObject);
+
+ SwXParagraph *const pPara = dynamic_cast<SwXParagraph*>(xNewContent.get());
+ if (!pPara || !pPara->IsDescriptor() || !xSuccessor.is())
+ {
+ throw lang::IllegalArgumentException();
+ }
+
+ bool bRet = false;
+ SwXTextSection *const pXSection = dynamic_cast<SwXTextSection*>(xSuccessor.get());
+ SwXTextTable *const pXTable = dynamic_cast<SwXTextTable*>(xSuccessor.get());
+ SwFrameFormat *const pTableFormat = pXTable ? pXTable->GetFrameFormat() : nullptr;
+ SwTextNode * pTextNode = nullptr;
+ if(pTableFormat && pTableFormat->GetDoc() == GetDoc())
+ {
+ SwTable *const pTable = SwTable::FindTable( pTableFormat );
+ SwTableNode *const pTableNode = pTable->GetTableNode();
+
+ const SwNodeIndex aTableIdx( *pTableNode, -1 );
+ SwPosition aBefore(aTableIdx);
+ bRet = GetDoc()->getIDocumentContentOperations().AppendTextNode( aBefore );
+ pTextNode = aBefore.GetNode().GetTextNode();
+ }
+ else if (pXSection && pXSection->GetFormat() &&
+ pXSection->GetFormat()->GetDoc() == GetDoc())
+ {
+ SwSectionFormat *const pSectFormat = pXSection->GetFormat();
+ SwSectionNode *const pSectNode = pSectFormat->GetSectionNode();
+
+ const SwNodeIndex aSectIdx( *pSectNode, -1 );
+ SwPosition aBefore(aSectIdx);
+ bRet = GetDoc()->getIDocumentContentOperations().AppendTextNode( aBefore );
+ pTextNode = aBefore.GetNode().GetTextNode();
+ }
+ if (!bRet || !pTextNode)
+ {
+ throw lang::IllegalArgumentException();
+ }
+ pPara->attachToText(*this, *pTextNode);
+}
+
+void SAL_CALL
+SwXText::insertTextContentAfter(
+ const uno::Reference< text::XTextContent>& xNewContent,
+ const uno::Reference< text::XTextContent>& xPredecessor)
+{
+ SolarMutexGuard aGuard;
+
+ if(!GetDoc())
+ {
+ throw uno::RuntimeException();
+ }
+
+ SwXParagraph *const pPara = dynamic_cast<SwXParagraph*>(xNewContent.get());
+ if(!pPara || !pPara->IsDescriptor() || !xPredecessor.is())
+ {
+ throw lang::IllegalArgumentException();
+ }
+
+ SwXTextSection *const pXSection = dynamic_cast<SwXTextSection*>(xPredecessor.get());
+ SwXTextTable *const pXTable = dynamic_cast<SwXTextTable*>(xPredecessor.get());
+ SwFrameFormat *const pTableFormat = pXTable ? pXTable->GetFrameFormat() : nullptr;
+ bool bRet = false;
+ SwTextNode * pTextNode = nullptr;
+ if(pTableFormat && pTableFormat->GetDoc() == GetDoc())
+ {
+ SwTable *const pTable = SwTable::FindTable( pTableFormat );
+ SwTableNode *const pTableNode = pTable->GetTableNode();
+
+ SwEndNode *const pTableEnd = pTableNode->EndOfSectionNode();
+ SwPosition aTableEnd(*pTableEnd);
+ bRet = GetDoc()->getIDocumentContentOperations().AppendTextNode( aTableEnd );
+ pTextNode = aTableEnd.GetNode().GetTextNode();
+ }
+ else if (pXSection && pXSection->GetFormat() &&
+ pXSection->GetFormat()->GetDoc() == GetDoc())
+ {
+ SwSectionFormat *const pSectFormat = pXSection->GetFormat();
+ SwSectionNode *const pSectNode = pSectFormat->GetSectionNode();
+ SwEndNode *const pEnd = pSectNode->EndOfSectionNode();
+ SwPosition aEnd(*pEnd);
+ bRet = GetDoc()->getIDocumentContentOperations().AppendTextNode( aEnd );
+ pTextNode = aEnd.GetNode().GetTextNode();
+ }
+ if (!bRet || !pTextNode)
+ {
+ throw lang::IllegalArgumentException();
+ }
+ pPara->attachToText(*this, *pTextNode);
+}
+
+void SAL_CALL
+SwXText::removeTextContentBefore(
+ const uno::Reference< text::XTextContent>& xSuccessor)
+{
+ SolarMutexGuard aGuard;
+
+ if(!GetDoc())
+ throw uno::RuntimeException(cInvalidObject);
+
+ bool bRet = false;
+ SwXTextSection *const pXSection = dynamic_cast<SwXTextSection*>(xSuccessor.get());
+ SwXTextTable *const pXTable = dynamic_cast<SwXTextTable*>(xSuccessor.get());
+ SwFrameFormat *const pTableFormat = pXTable ? pXTable->GetFrameFormat() : nullptr;
+ if(pTableFormat && pTableFormat->GetDoc() == GetDoc())
+ {
+ SwTable *const pTable = SwTable::FindTable( pTableFormat );
+ SwTableNode *const pTableNode = pTable->GetTableNode();
+
+ const SwNodeIndex aTableIdx( *pTableNode, -1 );
+ if(aTableIdx.GetNode().IsTextNode())
+ {
+ SwPaM aBefore(aTableIdx);
+ bRet = GetDoc()->getIDocumentContentOperations().DelFullPara( aBefore );
+ }
+ }
+ else if (pXSection && pXSection->GetFormat() &&
+ pXSection->GetFormat()->GetDoc() == GetDoc())
+ {
+ SwSectionFormat *const pSectFormat = pXSection->GetFormat();
+ SwSectionNode *const pSectNode = pSectFormat->GetSectionNode();
+
+ const SwNodeIndex aSectIdx( *pSectNode, -1 );
+ if(aSectIdx.GetNode().IsTextNode())
+ {
+ SwPaM aBefore(aSectIdx);
+ bRet = GetDoc()->getIDocumentContentOperations().DelFullPara( aBefore );
+ }
+ }
+ if(!bRet)
+ {
+ throw lang::IllegalArgumentException();
+ }
+}
+
+void SAL_CALL
+SwXText::removeTextContentAfter(
+ const uno::Reference< text::XTextContent>& xPredecessor)
+{
+ SolarMutexGuard aGuard;
+
+ if(!GetDoc())
+ throw uno::RuntimeException(cInvalidObject);
+
+ bool bRet = false;
+ SwXTextSection *const pXSection = dynamic_cast<SwXTextSection*>(xPredecessor.get());
+ SwXTextTable *const pXTable = dynamic_cast<SwXTextTable*>(xPredecessor.get());
+ SwFrameFormat *const pTableFormat = pXTable ? pXTable->GetFrameFormat() : nullptr;
+ if(pTableFormat && pTableFormat->GetDoc() == GetDoc())
+ {
+ SwTable *const pTable = SwTable::FindTable( pTableFormat );
+ SwTableNode *const pTableNode = pTable->GetTableNode();
+ SwEndNode *const pTableEnd = pTableNode->EndOfSectionNode();
+
+ const SwNodeIndex aTableIdx( *pTableEnd, 1 );
+ if(aTableIdx.GetNode().IsTextNode())
+ {
+ SwPaM aPaM(aTableIdx);
+ bRet = GetDoc()->getIDocumentContentOperations().DelFullPara( aPaM );
+ }
+ }
+ else if (pXSection && pXSection->GetFormat() &&
+ pXSection->GetFormat()->GetDoc() == GetDoc())
+ {
+ SwSectionFormat *const pSectFormat = pXSection->GetFormat();
+ SwSectionNode *const pSectNode = pSectFormat->GetSectionNode();
+ SwEndNode *const pEnd = pSectNode->EndOfSectionNode();
+ const SwNodeIndex aSectIdx( *pEnd, 1 );
+ if(aSectIdx.GetNode().IsTextNode())
+ {
+ SwPaM aAfter(aSectIdx);
+ bRet = GetDoc()->getIDocumentContentOperations().DelFullPara( aAfter );
+ }
+ }
+ if(!bRet)
+ {
+ throw lang::IllegalArgumentException();
+ }
+}
+
+void SAL_CALL
+SwXText::removeTextContent(
+ const uno::Reference< text::XTextContent > & xContent)
+{
+ // forward: need no solar mutex here
+ if(!xContent.is())
+ throw uno::RuntimeException("first parameter invalid");
+ xContent->dispose();
+}
+
+uno::Reference< text::XText > SAL_CALL
+SwXText::getText()
+{
+ SolarMutexGuard aGuard;
+ comphelper::ProfileZone aZone("SwXText::getText");
+
+ const uno::Reference< text::XText > xRet(this);
+ return xRet;
+}
+
+uno::Reference< text::XTextRange > SAL_CALL
+SwXText::getStart()
+{
+ SolarMutexGuard aGuard;
+
+ const rtl::Reference< SwXTextCursor > xRef = createXTextCursor();
+ if(!xRef.is())
+ throw uno::RuntimeException(cInvalidObject);
+ xRef->gotoStart(false);
+ return static_cast<text::XWordCursor*>(xRef.get());
+}
+
+uno::Reference< text::XTextRange > SAL_CALL
+SwXText::getEnd()
+{
+ SolarMutexGuard aGuard;
+
+ const rtl::Reference< SwXTextCursor > xRef = createXTextCursor();
+ if(!xRef.is())
+ throw uno::RuntimeException(cInvalidObject);
+ xRef->gotoEnd(false);
+ return static_cast<text::XWordCursor*>(xRef.get());
+}
+
+OUString SAL_CALL SwXText::getString()
+{
+ SolarMutexGuard aGuard;
+
+ const rtl::Reference< SwXTextCursor > xRet = createXTextCursor();
+ if(!xRet.is())
+ {
+ SAL_WARN("sw.uno", "cursor was not created in getString() call. Returning empty string.");
+ return OUString();
+ }
+ xRet->gotoEnd(true);
+ return xRet->getString();
+}
+
+void SAL_CALL
+SwXText::setString(const OUString& rString)
+{
+ SolarMutexGuard aGuard;
+
+ if (!GetDoc())
+ throw uno::RuntimeException(cInvalidObject);
+
+ const SwStartNode* pStartNode = GetStartNode();
+ if (!pStartNode)
+ {
+ throw uno::RuntimeException();
+ }
+
+ GetDoc()->GetIDocumentUndoRedo().StartUndo(SwUndoId::START, nullptr);
+ //insert an empty paragraph at the start and at the end to ensure that
+ //all tables and sections can be removed by the selecting text::XTextCursor
+ if (CursorType::Meta != m_pImpl->m_eType)
+ {
+ SwPosition aStartPos(*pStartNode);
+ const SwEndNode* pEnd = pStartNode->EndOfSectionNode();
+ SwNodeIndex aEndIdx(*pEnd);
+ --aEndIdx;
+ //the inserting of nodes should only be done if really necessary
+ //to prevent #97924# (removes paragraph attributes when setting the text
+ //e.g. of a table cell
+ bool bInsertNodes = false;
+ SwNodeIndex aStartIdx(*pStartNode);
+ do
+ {
+ ++aStartIdx;
+ SwNode& rCurrentNode = aStartIdx.GetNode();
+ if(rCurrentNode.GetNodeType() == SwNodeType::Section
+ ||rCurrentNode.GetNodeType() == SwNodeType::Table)
+ {
+ bInsertNodes = true;
+ break;
+ }
+ }
+ while(aStartIdx < aEndIdx);
+ if(bInsertNodes)
+ {
+ GetDoc()->getIDocumentContentOperations().AppendTextNode( aStartPos );
+ SwPaM aPam(aEndIdx.GetNode());
+ GetDoc()->getIDocumentContentOperations().AppendTextNode( *aPam.Start() );
+ }
+ }
+
+ const rtl::Reference< SwXTextCursor > xRet = createXTextCursor();
+ if(!xRet.is())
+ {
+ GetDoc()->GetIDocumentUndoRedo().EndUndo(SwUndoId::END, nullptr);
+ throw uno::RuntimeException(cInvalidObject);
+ }
+ xRet->gotoEnd(true);
+ xRet->setString(rString);
+ GetDoc()->GetIDocumentUndoRedo().EndUndo(SwUndoId::END, nullptr);
+}
+
+//FIXME why is CheckForOwnMember duplicated in some insert methods?
+// Description: Checks if pRange/pCursor are member of the same text interface.
+// Only one of the pointers has to be set!
+bool SwXText::Impl::CheckForOwnMember(
+ const SwPaM & rPaM)
+{
+ const rtl::Reference< SwXTextCursor > xOwnCursor(m_rThis.createXTextCursor());
+ const SwStartNode* pOwnStartNode =
+ xOwnCursor->GetPaM()->GetPointNode().StartOfSectionNode();
+ SwStartNodeType eSearchNodeType = SwNormalStartNode;
+ switch (m_eType)
+ {
+ case CursorType::Frame: eSearchNodeType = SwFlyStartNode; break;
+ case CursorType::TableText: eSearchNodeType = SwTableBoxStartNode; break;
+ case CursorType::Footnote: eSearchNodeType = SwFootnoteStartNode; break;
+ case CursorType::Header: eSearchNodeType = SwHeaderStartNode; break;
+ case CursorType::Footer: eSearchNodeType = SwFooterStartNode; break;
+ //case CURSOR_INVALID:
+ //case CursorType::Body:
+ default:
+ ;
+ }
+
+ const SwNode& rSrcNode = rPaM.GetPointNode();
+ const SwStartNode* pTmp = rSrcNode.FindSttNodeByType(eSearchNodeType);
+
+ // skip SectionNodes / TableNodes to be able to compare across table/section boundaries
+ while (pTmp
+ && (pTmp->IsSectionNode() || pTmp->IsTableNode()
+ || (m_eType != CursorType::TableText
+ && pTmp->GetStartNodeType() == SwTableBoxStartNode)))
+ {
+ pTmp = pTmp->StartOfSectionNode();
+ }
+
+ while (pOwnStartNode->IsSectionNode() || pOwnStartNode->IsTableNode()
+ || (m_eType != CursorType::TableText
+ && pOwnStartNode->GetStartNodeType() == SwTableBoxStartNode))
+ {
+ pOwnStartNode = pOwnStartNode->StartOfSectionNode();
+ }
+
+ //this checks if (this) and xRange are in the same text::XText interface
+ return (pOwnStartNode == pTmp);
+}
+
+sal_Int16
+SwXText::Impl::ComparePositions(
+ const uno::Reference<text::XTextRange>& xPos1,
+ const uno::Reference<text::XTextRange>& xPos2)
+{
+ SwUnoInternalPaM aPam1(*m_pDoc);
+ SwUnoInternalPaM aPam2(*m_pDoc);
+
+ if (!::sw::XTextRangeToSwPaM(aPam1, xPos1) ||
+ !::sw::XTextRangeToSwPaM(aPam2, xPos2))
+ {
+ throw lang::IllegalArgumentException();
+ }
+ if (!CheckForOwnMember(aPam1) || !CheckForOwnMember(aPam2))
+ {
+ throw lang::IllegalArgumentException();
+ }
+
+ sal_Int16 nCompare = 0;
+ SwPosition const*const pStart1 = aPam1.Start();
+ SwPosition const*const pStart2 = aPam2.Start();
+ if (*pStart1 < *pStart2)
+ {
+ nCompare = 1;
+ }
+ else if (*pStart1 > *pStart2)
+ {
+ nCompare = -1;
+ }
+ else
+ {
+ OSL_ENSURE(*pStart1 == *pStart2,
+ "SwPositions should be equal here");
+ nCompare = 0;
+ }
+
+ return nCompare;
+}
+
+sal_Int16 SAL_CALL
+SwXText::compareRegionStarts(
+ const uno::Reference<text::XTextRange>& xRange1,
+ const uno::Reference<text::XTextRange>& xRange2)
+{
+ SolarMutexGuard aGuard;
+
+ if (!xRange1.is() || !xRange2.is())
+ {
+ throw lang::IllegalArgumentException();
+ }
+ const uno::Reference<text::XTextRange> xStart1 = xRange1->getStart();
+ const uno::Reference<text::XTextRange> xStart2 = xRange2->getStart();
+
+ return m_pImpl->ComparePositions(xStart1, xStart2);
+}
+
+sal_Int16 SAL_CALL
+SwXText::compareRegionEnds(
+ const uno::Reference<text::XTextRange>& xRange1,
+ const uno::Reference<text::XTextRange>& xRange2)
+{
+ SolarMutexGuard aGuard;
+
+ if (!xRange1.is() || !xRange2.is())
+ {
+ throw lang::IllegalArgumentException();
+ }
+ uno::Reference<text::XTextRange> xEnd1 = xRange1->getEnd();
+ uno::Reference<text::XTextRange> xEnd2 = xRange2->getEnd();
+
+ return m_pImpl->ComparePositions(xEnd1, xEnd2);
+}
+
+uno::Reference< beans::XPropertySetInfo > SAL_CALL
+SwXText::getPropertySetInfo()
+{
+ SolarMutexGuard g;
+
+ static uno::Reference< beans::XPropertySetInfo > xInfo =
+ m_pImpl->m_rPropSet.getPropertySetInfo();
+ return xInfo;
+}
+
+void SAL_CALL
+SwXText::setPropertyValue(const OUString& /*aPropertyName*/,
+ const uno::Any& /*aValue*/)
+{
+ throw lang::IllegalArgumentException();
+}
+
+uno::Any SAL_CALL
+SwXText::getPropertyValue(
+ const OUString& rPropertyName)
+{
+ SolarMutexGuard aGuard;
+
+ if(!IsValid())
+ {
+ throw uno::RuntimeException();
+ }
+
+ SfxItemPropertyMapEntry const*const pEntry =
+ m_pImpl->m_rPropSet.getPropertyMap().getByName(rPropertyName);
+ if (!pEntry)
+ throw beans::UnknownPropertyException("Unknown property: " + rPropertyName);
+
+ uno::Any aRet;
+ switch (pEntry->nWID)
+ {
+// no code necessary - the redline is always located at the end node
+// case FN_UNO_REDLINE_NODE_START:
+// break;
+ case FN_UNO_REDLINE_NODE_END:
+ {
+ const SwRedlineTable& rRedTable = GetDoc()->getIDocumentRedlineAccess().GetRedlineTable();
+ const size_t nRedTableCount = rRedTable.size();
+ if (nRedTableCount > 0)
+ {
+ SwStartNode const*const pStartNode = GetStartNode();
+ const SwNode& rOwnIndex = *pStartNode->EndOfSectionNode();
+ for (size_t nRed = 0; nRed < nRedTableCount; ++nRed)
+ {
+ SwRangeRedline const*const pRedline = rRedTable[nRed];
+ SwPosition const*const pRedStart = pRedline->Start();
+ const SwNode& rRedNode = pRedStart->GetNode();
+ if (rOwnIndex == rRedNode)
+ {
+ aRet <<= SwXRedlinePortion::CreateRedlineProperties(
+ *pRedline, true);
+ break;
+ }
+ }
+ }
+ }
+ break;
+ }
+ return aRet;
+}
+
+void SAL_CALL
+SwXText::addPropertyChangeListener(
+ const OUString& /*rPropertyName*/,
+ const uno::Reference< beans::XPropertyChangeListener >& /*xListener*/)
+{
+ OSL_FAIL("SwXText::addPropertyChangeListener(): not implemented");
+}
+
+void SAL_CALL
+SwXText::removePropertyChangeListener(
+ const OUString& /*rPropertyName*/,
+ const uno::Reference< beans::XPropertyChangeListener >& /*xListener*/)
+{
+ OSL_FAIL("SwXText::removePropertyChangeListener(): not implemented");
+}
+
+void SAL_CALL
+SwXText::addVetoableChangeListener(
+ const OUString& /*rPropertyName*/,
+ const uno::Reference< beans::XVetoableChangeListener >& /*xListener*/)
+{
+ OSL_FAIL("SwXText::addVetoableChangeListener(): not implemented");
+}
+
+void SAL_CALL
+SwXText::removeVetoableChangeListener(
+ const OUString& /*rPropertyName*/,
+ const uno::Reference< beans::XVetoableChangeListener >& /*xListener*/)
+{
+ OSL_FAIL("SwXText::removeVetoableChangeListener(): not implemented");
+}
+
+namespace
+{
+}
+
+uno::Reference< text::XTextRange > SAL_CALL
+SwXText::finishParagraph(
+ const uno::Sequence< beans::PropertyValue > & rProperties)
+{
+ SolarMutexGuard g;
+
+ return m_pImpl->finishOrAppendParagraph(rProperties, uno::Reference< text::XTextRange >());
+}
+
+uno::Reference< text::XTextRange > SAL_CALL
+SwXText::finishParagraphInsert(
+ const uno::Sequence< beans::PropertyValue > & rProperties,
+ const uno::Reference< text::XTextRange >& xInsertPosition)
+{
+ SolarMutexGuard g;
+
+ return m_pImpl->finishOrAppendParagraph(rProperties, xInsertPosition);
+}
+
+rtl::Reference<SwXParagraph>
+SwXText::Impl::finishOrAppendParagraph(
+ const uno::Sequence< beans::PropertyValue > & rProperties,
+ const uno::Reference< text::XTextRange >& xInsertPosition)
+{
+ if (!m_bIsValid)
+ {
+ throw uno::RuntimeException();
+ }
+
+ const SwStartNode* pStartNode = m_rThis.GetStartNode();
+ if(!pStartNode)
+ {
+ throw uno::RuntimeException();
+ }
+
+ rtl::Reference<SwXParagraph> xRet;
+ bool bIllegalException = false;
+ bool bRuntimeException = false;
+ OUString sMessage;
+ m_pDoc->GetIDocumentUndoRedo().StartUndo(SwUndoId::START , nullptr);
+ // find end node, go backward - don't skip tables because the new
+ // paragraph has to be the last node
+ //aPam.Move( fnMoveBackward, GoInNode );
+ SwPaM aPam(*pStartNode->EndOfSectionNode(), SwNodeOffset(-1));
+ // If we got a position reference, then the insert point is not the end of
+ // the document.
+ if (xInsertPosition.is())
+ {
+ SwUnoInternalPaM aStartPam(*m_rThis.GetDoc());
+ ::sw::XTextRangeToSwPaM(aStartPam, xInsertPosition);
+ aPam = aStartPam;
+ aPam.SetMark();
+ }
+ m_pDoc->getIDocumentContentOperations().AppendTextNode( *aPam.GetPoint() );
+ // remove attributes from the previous paragraph
+ m_pDoc->ResetAttrs(aPam);
+ // in case of finishParagraph the PaM needs to be moved to the
+ // previous paragraph
+ aPam.Move( fnMoveBackward, GoInNode );
+
+ try
+ {
+ SfxItemPropertySet const*const pParaPropSet =
+ aSwMapProvider.GetPropertySet(PROPERTY_MAP_PARAGRAPH);
+
+ SwUnoCursorHelper::SetPropertyValues(aPam, *pParaPropSet, rProperties);
+
+ // tdf#127616 keep direct character formatting of empty paragraphs,
+ // if character style of the paragraph sets also the same attributes
+ if (aPam.Start()->GetNode().GetTextNode()->Len() == 0)
+ {
+ auto itCharStyle = std::find_if(rProperties.begin(), rProperties.end(), [](const beans::PropertyValue& rValue)
+ {
+ return rValue.Name == "CharStyleName";
+ });
+ if ( itCharStyle != rProperties.end() )
+ {
+ for (const auto& rValue : rProperties)
+ {
+ if ( rValue != *itCharStyle && rValue.Name.startsWith("Char") )
+ {
+ SwUnoCursorHelper::SetPropertyValue(aPam, *pParaPropSet, rValue.Name, rValue.Value);
+ }
+ }
+ }
+ }
+ }
+ catch (const lang::IllegalArgumentException& rIllegal)
+ {
+ sMessage = rIllegal.Message;
+ bIllegalException = true;
+ }
+ catch (const uno::RuntimeException& rRuntime)
+ {
+ sMessage = rRuntime.Message;
+ bRuntimeException = true;
+ }
+ catch (const uno::Exception& rEx)
+ {
+ sMessage = rEx.Message;
+ bRuntimeException = true;
+ }
+
+ m_pDoc->GetIDocumentUndoRedo().EndUndo(SwUndoId::END, nullptr);
+ if (bIllegalException || bRuntimeException)
+ {
+ m_pDoc->GetIDocumentUndoRedo().Undo();
+ if (bIllegalException)
+ {
+ throw lang::IllegalArgumentException(sMessage, nullptr, 0);
+ }
+ else
+ {
+ throw uno::RuntimeException(sMessage);
+ }
+ }
+ SwTextNode *const pTextNode( aPam.Start()->GetNode().GetTextNode() );
+ OSL_ENSURE(pTextNode, "no SwTextNode?");
+ if (pTextNode)
+ {
+ xRet = SwXParagraph::CreateXParagraph(*m_pDoc, pTextNode, &m_rThis);
+ }
+
+ return xRet;
+}
+
+uno::Reference< text::XTextRange > SAL_CALL
+SwXText::insertTextPortion(
+ const OUString& rText,
+ const uno::Sequence< beans::PropertyValue > &
+ rCharacterAndParagraphProperties,
+ const uno::Reference<text::XTextRange>& xInsertPosition)
+{
+ SolarMutexGuard aGuard;
+
+ if(!IsValid())
+ {
+ throw uno::RuntimeException();
+ }
+ uno::Reference< text::XTextRange > xRet;
+ const rtl::Reference<SwXTextCursor> xTextCursor = createXTextCursorByRange(xInsertPosition);
+
+ bool bIllegalException = false;
+ bool bRuntimeException = false;
+ OUString sMessage;
+ m_pImpl->m_pDoc->GetIDocumentUndoRedo().StartUndo(SwUndoId::INSERT, nullptr);
+
+ auto& rCursor(xTextCursor->GetCursor());
+ m_pImpl->m_pDoc->DontExpandFormat( *rCursor.Start() );
+
+ if (!rText.isEmpty())
+ {
+ SwNodeIndex const nodeIndex(rCursor.GetPoint()->GetNode(), -1);
+ const sal_Int32 nContentPos = rCursor.GetPoint()->GetContentIndex();
+ SwUnoCursorHelper::DocInsertStringSplitCR(
+ *m_pImpl->m_pDoc, rCursor, rText, false);
+ SwUnoCursorHelper::SelectPam(rCursor, true);
+ rCursor.GetPoint()->Assign(nodeIndex.GetNode(), SwNodeOffset(+1), nContentPos);
+ }
+
+ try
+ {
+ SfxItemPropertySet const*const pCursorPropSet =
+ aSwMapProvider.GetPropertySet(PROPERTY_MAP_TEXT_CURSOR);
+ SwUnoCursorHelper::SetPropertyValues(rCursor, *pCursorPropSet,
+ rCharacterAndParagraphProperties,
+ SetAttrMode::NOFORMATATTR);
+ }
+ catch (const lang::IllegalArgumentException& rIllegal)
+ {
+ sMessage = rIllegal.Message;
+ bIllegalException = true;
+ }
+ catch (const uno::RuntimeException& rRuntime)
+ {
+ sMessage = rRuntime.Message;
+ bRuntimeException = true;
+ }
+ m_pImpl->m_pDoc->GetIDocumentUndoRedo().EndUndo(SwUndoId::INSERT, nullptr);
+ if (bIllegalException || bRuntimeException)
+ {
+ m_pImpl->m_pDoc->GetIDocumentUndoRedo().Undo();
+ if (bIllegalException)
+ {
+ throw lang::IllegalArgumentException(sMessage, nullptr, 0);
+ }
+ else
+ {
+ throw uno::RuntimeException(sMessage);
+ }
+ }
+ xRet = new SwXTextRange(rCursor, this);
+ return xRet;
+}
+
+// Append text portions at the end of the last paragraph of the text interface.
+// Support of import filters.
+uno::Reference< text::XTextRange > SAL_CALL
+SwXText::appendTextPortion(
+ const OUString& rText,
+ const uno::Sequence< beans::PropertyValue > &
+ rCharacterAndParagraphProperties)
+{
+ // Right now this doesn't need a guard, as it's just calling the insert
+ // version, that has it already.
+ uno::Reference<text::XTextRange> xInsertPosition = getEnd();
+ return insertTextPortion(rText, rCharacterAndParagraphProperties, xInsertPosition);
+}
+
+// enable inserting/appending text contents like graphic objects, shapes and so on to
+// support import filters
+uno::Reference< text::XTextRange > SAL_CALL
+SwXText::insertTextContentWithProperties(
+ const uno::Reference< text::XTextContent >& xTextContent,
+ const uno::Sequence< beans::PropertyValue >&
+ rCharacterAndParagraphProperties,
+ const uno::Reference< text::XTextRange >& xInsertPosition)
+{
+ SolarMutexGuard aGuard;
+
+ if (!IsValid())
+ {
+ throw uno::RuntimeException();
+ }
+
+ SwUnoInternalPaM aPam(*GetDoc());
+ if (!::sw::XTextRangeToSwPaM(aPam, xInsertPosition))
+ {
+ throw lang::IllegalArgumentException("invalid position", nullptr, 2);
+ }
+
+ SwRewriter aRewriter;
+ aRewriter.AddRule(UndoArg1, SwResId(STR_UNDO_INSERT_TEXTBOX));
+
+ m_pImpl->m_pDoc->GetIDocumentUndoRedo().StartUndo(SwUndoId::INSERT, &aRewriter);
+
+ // Any direct formatting ending at the insert position (xRange) should not
+ // be expanded to cover the inserted content (xContent)
+ // (insertTextContent() shouldn't do this, only ...WithProperties()!)
+ GetDoc()->DontExpandFormat( *aPam.Start() );
+
+ // now attach the text content here
+ insertTextContent( xInsertPosition, xTextContent, false );
+ // now apply the properties to the anchor
+ if (rCharacterAndParagraphProperties.hasElements())
+ {
+ try
+ {
+ const uno::Reference< beans::XPropertySet > xAnchor(
+ xTextContent->getAnchor(), uno::UNO_QUERY);
+ if (xAnchor.is())
+ {
+ for (const auto& rProperty : rCharacterAndParagraphProperties)
+ {
+ xAnchor->setPropertyValue(rProperty.Name, rProperty.Value);
+ }
+ }
+ }
+ catch (const uno::Exception& e)
+ {
+ css::uno::Any anyEx = cppu::getCaughtException();
+ m_pImpl->m_pDoc->GetIDocumentUndoRedo().EndUndo(SwUndoId::INSERT, &aRewriter);
+ throw lang::WrappedTargetRuntimeException( e.Message,
+ uno::Reference< uno::XInterface >(), anyEx );
+ }
+ }
+ m_pImpl->m_pDoc->GetIDocumentUndoRedo().EndUndo(SwUndoId::INSERT, &aRewriter);
+ return xInsertPosition;
+}
+
+uno::Reference< text::XTextRange > SAL_CALL
+SwXText::appendTextContent(
+ const uno::Reference< text::XTextContent >& xTextContent,
+ const uno::Sequence< beans::PropertyValue >& rCharacterAndParagraphProperties
+ )
+{
+ // Right now this doesn't need a guard, as it's just calling the insert
+ // version, that has it already.
+ uno::Reference<text::XTextRange> xInsertPosition = getEnd();
+ return insertTextContentWithProperties(xTextContent, rCharacterAndParagraphProperties, xInsertPosition);
+}
+
+// determine whether SwFrameFormat is a graphic node
+static bool isGraphicNode(const SwFrameFormat* pFrameFormat)
+{
+ // safety
+ if( !pFrameFormat->GetContent().GetContentIdx() )
+ {
+ return false;
+ }
+ auto index = *pFrameFormat->GetContent().GetContentIdx();
+ // consider the next node -> there is the graphic stored
+ ++index;
+ return index.GetNode().IsGrfNode();
+}
+
+/// Determines if the at-para rAnchor is anchored at the start or end of rAnchorCheckPam.
+static bool IsAtParaMatch(const SwPaM& rAnchorCheckPam, const SwFormatAnchor& rAnchor)
+{
+ if (rAnchor.GetAnchorId() != RndStdIds::FLY_AT_PARA)
+ {
+ return false;
+ }
+
+ if (rAnchorCheckPam.Start()->GetNode() == *rAnchor.GetAnchorNode())
+ {
+ return true;
+ }
+
+ if (rAnchorCheckPam.End()->GetNode() == *rAnchor.GetAnchorNode())
+ {
+ SwTextNode* pEndTextNode = rAnchorCheckPam.End()->GetNode().GetTextNode();
+ if (pEndTextNode && rAnchorCheckPam.End()->GetContentIndex() == pEndTextNode->Len())
+ {
+ // rAnchorCheckPam covers the entire last text node, rAnchor is at-para, consider this
+ // as "inside pam" rather than "at the end of pam".
+ return false;
+ }
+ return true;
+ }
+
+ return false;
+}
+
+// move previously appended paragraphs into a text frames
+// to support import filters
+uno::Reference< text::XTextContent > SAL_CALL
+SwXText::convertToTextFrame(
+ const uno::Reference< text::XTextRange >& xStart,
+ const uno::Reference< text::XTextRange >& xEnd,
+ const uno::Sequence< beans::PropertyValue >& rFrameProperties)
+{
+ SolarMutexGuard aGuard;
+
+ if(!IsValid())
+ {
+ throw uno::RuntimeException();
+ }
+ // tdf#143384 recognize dummy property, that was set to make createTextCursor
+ // to not ignore tables.
+ // It is enough to use this hack only for the range start,
+ // because as far as I know, the range cannot end with table when this property is set.
+ ::sw::TextRangeMode eMode = ::sw::TextRangeMode::RequireTextNode;
+ for (const auto& rCellProperty : rFrameProperties)
+ {
+ if (rCellProperty.Name == "CursorNotIgnoreTables")
+ {
+ bool bAllowNonTextNode = false;
+ rCellProperty.Value >>= bAllowNonTextNode;
+ if (bAllowNonTextNode)
+ eMode = ::sw::TextRangeMode::AllowTableNode;
+ break;
+ }
+ }
+ uno::Reference< text::XTextContent > xRet;
+ std::optional<SwUnoInternalPaM> pTempStartPam(*GetDoc());
+ std::optional<SwUnoInternalPaM> pEndPam(*GetDoc());
+ if (!::sw::XTextRangeToSwPaM(*pTempStartPam, xStart, eMode)
+ || !::sw::XTextRangeToSwPaM(*pEndPam, xEnd))
+ {
+ throw lang::IllegalArgumentException();
+ }
+
+ auto pStartPam(GetDoc()->CreateUnoCursor(*pTempStartPam->GetPoint()));
+ if (pTempStartPam->HasMark())
+ {
+ pStartPam->SetMark();
+ *pStartPam->GetMark() = *pTempStartPam->GetMark();
+ }
+ pTempStartPam.reset();
+
+ SwXTextRange *const pStartRange = dynamic_cast<SwXTextRange*>(xStart.get());
+ SwXTextRange *const pEndRange = dynamic_cast<SwXTextRange*>(xEnd.get());
+ // bookmarks have to be removed before the referenced text node
+ // is deleted in DelFullPara
+ if (pStartRange)
+ {
+ pStartRange->Invalidate();
+ }
+ if (pEndRange)
+ {
+ pEndRange->Invalidate();
+ }
+
+ m_pImpl->m_pDoc->GetIDocumentUndoRedo().StartUndo( SwUndoId::START, nullptr );
+ bool bIllegalException = false;
+ bool bRuntimeException = false;
+ OUString sMessage;
+ SwStartNode* pStartStartNode = pStartPam->GetPointNode().StartOfSectionNode();
+ while (pStartStartNode && pStartStartNode->IsSectionNode())
+ {
+ pStartStartNode = pStartStartNode->StartOfSectionNode();
+ }
+ SwStartNode* pEndStartNode = pEndPam->GetPointNode().StartOfSectionNode();
+ while (pEndStartNode && pEndStartNode->IsSectionNode())
+ {
+ pEndStartNode = pEndStartNode->StartOfSectionNode();
+ }
+ bool bParaAfterInserted = false;
+ bool bParaBeforeInserted = false;
+ ::std::optional<SwPaM> oAnchorCheckPam;
+ oAnchorCheckPam.emplace(*pStartPam->Start(), *pEndPam->End());
+ if (
+ pStartStartNode && pEndStartNode &&
+ (pStartStartNode != pEndStartNode || pStartStartNode != GetStartNode())
+ )
+ {
+ // todo: if the start/end is in a table then insert a paragraph
+ // before/after, move the start/end nodes, then convert and
+ // remove the additional paragraphs in the end
+ SwTableNode * pStartTableNode(nullptr);
+ if (pStartStartNode->GetStartNodeType() == SwTableBoxStartNode)
+ {
+ pStartTableNode = pStartStartNode->FindTableNode();
+ // Is it the same table start node than the end?
+ SwTableNode *const pEndStartTableNode(pEndStartNode->FindTableNode());
+ while (pEndStartTableNode && pStartTableNode &&
+ pEndStartTableNode->GetIndex() < pStartTableNode->GetIndex())
+ {
+ SwStartNode* pStartStartTableNode = pStartTableNode->StartOfSectionNode();
+ pStartTableNode = pStartStartTableNode->FindTableNode();
+ }
+ }
+ if (pStartTableNode)
+ {
+ const SwNodeIndex aTableIdx( *pStartTableNode, -1 );
+ SwPosition aBefore(aTableIdx);
+ bParaBeforeInserted = GetDoc()->getIDocumentContentOperations().AppendTextNode( aBefore );
+ pStartPam->DeleteMark();
+ *pStartPam->GetPoint() = aBefore;
+ pStartStartNode = pStartPam->GetPointNode().StartOfSectionNode();
+ }
+ if (pEndStartNode->GetStartNodeType() == SwTableBoxStartNode)
+ {
+ SwTableNode *const pEndTableNode = pEndStartNode->FindTableNode();
+ SwEndNode *const pTableEnd = pEndTableNode->EndOfSectionNode();
+ SwPosition aTableEnd(*pTableEnd);
+ bParaAfterInserted = GetDoc()->getIDocumentContentOperations().AppendTextNode( aTableEnd );
+ pEndPam->DeleteMark();
+ *pEndPam->GetPoint() = aTableEnd;
+ pEndStartNode = pEndPam->GetPointNode().StartOfSectionNode();
+ }
+ // now we should have the positions in the same hierarchy
+ if ((pStartStartNode != pEndStartNode) ||
+ (pStartStartNode != GetStartNode()))
+ {
+ // if not - remove the additional paragraphs and throw
+ oAnchorCheckPam.reset(); // clear SwIndex before deleting nodes
+ if (bParaBeforeInserted)
+ {
+ SwCursor aDelete(*pStartPam->GetPoint(), nullptr);
+ *pStartPam->GetPoint() = // park it because node is deleted
+ SwPosition(GetDoc()->GetNodes().GetEndOfContent());
+ aDelete.MovePara(GoCurrPara, fnParaStart);
+ aDelete.SetMark();
+ aDelete.MovePara(GoCurrPara, fnParaEnd);
+ GetDoc()->getIDocumentContentOperations().DelFullPara(aDelete);
+ }
+ if (bParaAfterInserted)
+ {
+ SwCursor aDelete(*pEndPam->GetPoint(), nullptr);
+ *pEndPam->GetPoint() = // park it because node is deleted
+ SwPosition(GetDoc()->GetNodes().GetEndOfContent());
+ aDelete.MovePara(GoCurrPara, fnParaStart);
+ aDelete.SetMark();
+ aDelete.MovePara(GoCurrPara, fnParaEnd);
+ GetDoc()->getIDocumentContentOperations().DelFullPara(aDelete);
+ }
+ throw lang::IllegalArgumentException();
+ }
+ }
+
+ // make a selection from pStartPam to pEndPam
+ // If there is no content in the frame the shape is in
+ // it gets deleted in the DelFullPara call below,
+ // In this case insert a tmp text node ( we delete it later )
+ if (pStartPam->Start()->GetNode() == pEndPam->Start()->GetNode()
+ && pStartPam->End()->GetNode() == pEndPam->End()->GetNode())
+ {
+ SwPosition aEnd(*pStartPam->End());
+ bParaAfterInserted = GetDoc()->getIDocumentContentOperations().AppendTextNode( aEnd );
+ pEndPam->DeleteMark();
+ *pEndPam->GetPoint() = aEnd;
+ *oAnchorCheckPam->End() = aEnd;
+ }
+ pStartPam->SetMark();
+ *pStartPam->End() = *pEndPam->End();
+ pEndPam.reset();
+
+ // see if there are frames already anchored to this node
+ // we have to work with the SdrObjects, as unique name is not guaranteed in their frame format
+ // tdf#115094: do nothing if we have a graphic node
+ o3tl::sorted_vector<const SdrObject*> aAnchoredObjectsByPtr;
+ std::set<OUString> aAnchoredObjectsByName;
+ for (size_t i = 0; i < m_pImpl->m_pDoc->GetSpzFrameFormats()->size(); ++i)
+ {
+ const SwFrameFormat* pFrameFormat = (*m_pImpl->m_pDoc->GetSpzFrameFormats())[i];
+ const SwFormatAnchor& rAnchor = pFrameFormat->GetAnchor();
+ // note: Word can do at-char anchors in text frames - sometimes!
+ // see testFlyInFly for why this checks only the edges of the selection,
+ // and testFloatingTablesAnchor for why it excludes pre/post table
+ // added nodes
+ if (!isGraphicNode(pFrameFormat)
+ && (IsAtParaMatch(*oAnchorCheckPam, rAnchor)
+ || (RndStdIds::FLY_AT_CHAR == rAnchor.GetAnchorId()
+ && ( *oAnchorCheckPam->Start() == *rAnchor.GetContentAnchor()
+ || *oAnchorCheckPam->End() == *rAnchor.GetContentAnchor()))))
+ {
+ if (pFrameFormat->GetName().isEmpty())
+ {
+ aAnchoredObjectsByPtr.insert(pFrameFormat->FindSdrObject());
+ }
+ else
+ {
+ aAnchoredObjectsByName.insert(pFrameFormat->GetName());
+ }
+ }
+ }
+ oAnchorCheckPam.reset(); // clear SwIndex before deleting nodes
+
+ const rtl::Reference<SwXTextFrame> xNewFrame =
+ SwXTextFrame::CreateXTextFrame(*m_pImpl->m_pDoc, nullptr);
+ try
+ {
+ for (const beans::PropertyValue& rValue : rFrameProperties)
+ {
+ xNewFrame->SwXFrame::setPropertyValue(rValue.Name, rValue.Value);
+ }
+
+ { // has to be in a block to remove the SwIndexes before
+ // DelFullPara is called
+ const uno::Reference< text::XTextRange> xInsertTextRange =
+ new SwXTextRange(*pStartPam, this);
+ assert(xNewFrame->IsDescriptor());
+ xNewFrame->attachToRange(xInsertTextRange, pStartPam.get());
+ assert(!xNewFrame->getName().isEmpty());
+ }
+
+ SwTextNode *const pTextNode(pStartPam->GetPointNode().GetTextNode());
+ assert(pTextNode);
+ if (!pTextNode || !pTextNode->Len()) // don't remove if it contains text!
+ {
+ { // has to be in a block to remove the SwIndexes before
+ // DelFullPara is called
+ SwPaM aMovePam( pStartPam->GetPointNode() );
+ if (aMovePam.Move( fnMoveForward, GoInContent ))
+ {
+ // move the anchor to the next paragraph
+ SwFormatAnchor aNewAnchor(xNewFrame->GetFrameFormat()->GetAnchor());
+ aNewAnchor.SetAnchor( aMovePam.Start() );
+ m_pImpl->m_pDoc->SetAttr(
+ aNewAnchor, *xNewFrame->GetFrameFormat() );
+
+ // also move frames anchored to us
+ for (size_t i = 0; i < m_pImpl->m_pDoc->GetSpzFrameFormats()->size(); ++i)
+ {
+ SwFrameFormat* pFrameFormat = (*m_pImpl->m_pDoc->GetSpzFrameFormats())[i];
+ if ((!pFrameFormat->GetName().isEmpty() && aAnchoredObjectsByName.find(pFrameFormat->GetName()) != aAnchoredObjectsByName.end() ) ||
+ ( pFrameFormat->GetName().isEmpty() && aAnchoredObjectsByPtr.find(pFrameFormat->FindSdrObject()) != aAnchoredObjectsByPtr.end()) )
+ {
+ // copy the anchor to the next paragraph
+ SwFormatAnchor aAnchor(pFrameFormat->GetAnchor());
+ aAnchor.SetAnchor(aMovePam.Start());
+ m_pImpl->m_pDoc->SetAttr(aAnchor, *pFrameFormat);
+ }
+ else
+ {
+ // if this frame is a textbox of a shape anchored to us, move this textbox too.
+ const auto& pTextBoxes = pFrameFormat->GetOtherTextBoxFormats();
+ if (pFrameFormat->Which() == RES_FLYFRMFMT && pTextBoxes
+ && pTextBoxes->GetOwnerShape())
+ {
+ const auto& rShapeAnchor = pTextBoxes->GetOwnerShape()->GetAnchor();
+ if (rShapeAnchor.GetAnchorId() == RndStdIds::FLY_AS_CHAR
+ && rShapeAnchor.GetContentAnchor() && pFrameFormat->GetAnchor().GetContentAnchor()
+ && pStartPam->ContainsPosition(*pFrameFormat->GetAnchor().GetContentAnchor()))
+ {
+ const SwNode& rAnchorNode
+ = *pFrameFormat->GetAnchor().GetAnchorNode();
+ if (!(rAnchorNode.FindFooterStartNode() || rAnchorNode.FindHeaderStartNode()))
+ {
+ SwFormatAnchor aAnchor(pFrameFormat->GetAnchor());
+ aAnchor.SetAnchor(aMovePam.Start());
+ m_pImpl->m_pDoc->SetAttr(aAnchor, *pFrameFormat);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ m_pImpl->m_pDoc->getIDocumentContentOperations().DelFullPara(*pStartPam);
+ }
+ }
+ catch (const lang::IllegalArgumentException& rIllegal)
+ {
+ sMessage = rIllegal.Message;
+ bIllegalException = true;
+ }
+ catch (const uno::RuntimeException& rRuntime)
+ {
+ sMessage = rRuntime.Message;
+ bRuntimeException = true;
+ }
+ xRet = static_cast<SwXFrame*>(xNewFrame.get());
+ if (bParaBeforeInserted || bParaAfterInserted)
+ {
+ const rtl::Reference<SwXTextCursor> xFrameTextCursor =
+ xNewFrame->createXTextCursor();
+ if (bParaBeforeInserted)
+ {
+ // todo: remove paragraph before frame
+ m_pImpl->m_pDoc->getIDocumentContentOperations().DelFullPara(*xFrameTextCursor->GetPaM());
+ }
+ if (bParaAfterInserted)
+ {
+ xFrameTextCursor->gotoEnd(false);
+ if (!bParaBeforeInserted)
+ m_pImpl->m_pDoc->getIDocumentContentOperations().DelFullPara(*xFrameTextCursor->GetPaM());
+ else
+ {
+ // In case the frame has a table only, the cursor points to the end of the first cell of the table.
+ SwPaM aPaM(*xFrameTextCursor->GetPaM()->GetPointNode().FindSttNodeByType(SwFlyStartNode)->EndOfSectionNode());
+ // Now we have the end of the frame -- the node before that will be the paragraph we want to remove.
+ aPaM.GetPoint()->Adjust(SwNodeOffset(-1));
+ m_pImpl->m_pDoc->getIDocumentContentOperations().DelFullPara(aPaM);
+ }
+ }
+ }
+
+ m_pImpl->m_pDoc->GetIDocumentUndoRedo().EndUndo(SwUndoId::END, nullptr);
+ if (bIllegalException || bRuntimeException)
+ {
+ m_pImpl->m_pDoc->GetIDocumentUndoRedo().Undo();
+ if (bIllegalException)
+ {
+ throw lang::IllegalArgumentException(sMessage, nullptr, 0);
+ }
+ else
+ {
+ throw uno::RuntimeException(sMessage);
+ }
+ }
+ return xRet;
+}
+
+namespace {
+
+// Move previously imported paragraphs into a new text table.
+struct VerticallyMergedCell
+{
+ std::vector<uno::Reference< beans::XPropertySet > > aCells;
+ sal_Int32 nLeftPosition;
+ bool bOpen;
+
+ VerticallyMergedCell(uno::Reference< beans::XPropertySet > const& rxCell,
+ const sal_Int32 nLeft)
+ : nLeftPosition( nLeft )
+ , bOpen( true )
+ {
+ aCells.push_back( rxCell );
+ }
+};
+
+}
+
+#define COL_POS_FUZZY 2
+
+static bool lcl_SimilarPosition( const sal_Int32 nPos1, const sal_Int32 nPos2 )
+{
+ return abs( nPos1 - nPos2 ) < COL_POS_FUZZY;
+}
+
+void SwXText::Impl::ConvertCell(
+ const uno::Sequence< uno::Reference< text::XTextRange > > & rCell,
+ std::vector<SwNodeRange> & rRowNodes,
+ SwNodeRange *const pLastCell)
+{
+ if (rCell.getLength() != 2)
+ {
+ throw lang::IllegalArgumentException(
+ "rCell needs to contain 2 elements",
+ uno::Reference< text::XTextCopy >( &m_rThis ), sal_Int16( 2 ) );
+ }
+ const uno::Reference<text::XTextRange> xStartRange = rCell[0];
+ const uno::Reference<text::XTextRange> xEndRange = rCell[1];
+ SwUnoInternalPaM aStartCellPam(*m_pDoc);
+ SwUnoInternalPaM aEndCellPam(*m_pDoc);
+
+ // !!! TODO - PaMs in tables and sections do not work here -
+ // the same applies to PaMs in frames !!!
+
+ if (!::sw::XTextRangeToSwPaM(aStartCellPam, xStartRange) ||
+ !::sw::XTextRangeToSwPaM(aEndCellPam, xEndRange))
+ {
+ throw lang::IllegalArgumentException(
+ "Start or End range cannot be resolved to a SwPaM",
+ uno::Reference< text::XTextCopy >( &m_rThis ), sal_Int16( 2 ) );
+ }
+
+ SwNodeRange aTmpRange(aStartCellPam.Start()->GetNode(),
+ aEndCellPam.End()->GetNode());
+ std::optional<SwNodeRange> oCorrectedRange;
+ m_pDoc->GetNodes().ExpandRangeForTableBox(aTmpRange, oCorrectedRange);
+
+ if (oCorrectedRange)
+ {
+ SwPaM aNewStartPaM(oCorrectedRange->aStart, 0);
+ aStartCellPam = aNewStartPaM;
+
+ sal_Int32 nEndLen = 0;
+ SwTextNode * pTextNode = oCorrectedRange->aEnd.GetNode().GetTextNode();
+ if (pTextNode != nullptr)
+ nEndLen = pTextNode->Len();
+
+ SwPaM aNewEndPaM(oCorrectedRange->aEnd, nEndLen);
+ aEndCellPam = aNewEndPaM;
+
+ oCorrectedRange.reset();
+ }
+
+ /** check the nodes between start and end
+ it is allowed to have pairs of StartNode/EndNodes
+ */
+ if (aStartCellPam.Start()->GetNode() < aEndCellPam.End()->GetNode())
+ {
+ // increment on each StartNode and decrement on each EndNode
+ // we must reach zero at the end and must not go below zero
+ tools::Long nOpenNodeBlock = 0;
+ SwNodeIndex aCellIndex(aStartCellPam.Start()->GetNode());
+ while (aCellIndex < aEndCellPam.End()->GetNodeIndex())
+ {
+ if (aCellIndex.GetNode().IsStartNode())
+ {
+ ++nOpenNodeBlock;
+ }
+ else if (aCellIndex.GetNode().IsEndNode())
+ {
+ --nOpenNodeBlock;
+ }
+ if (nOpenNodeBlock < 0)
+ {
+ throw lang::IllegalArgumentException();
+ }
+ ++aCellIndex;
+ }
+ if (nOpenNodeBlock != 0)
+ {
+ throw lang::IllegalArgumentException();
+ }
+ }
+
+ /** The vector<vector> NodeRanges has to contain consecutive nodes.
+ In rTableRanges the ranges don't need to be full paragraphs but
+ they have to follow each other. To process the ranges they
+ have to be aligned on paragraph borders by inserting paragraph
+ breaks. Non-consecutive ranges must initiate an exception.
+ */
+ if (!pLastCell) // first cell?
+ {
+ // align the beginning - if necessary
+ if (aStartCellPam.Start()->GetContentIndex())
+ {
+ m_pDoc->getIDocumentContentOperations().SplitNode(*aStartCellPam.Start(), false);
+ }
+ }
+ else
+ {
+ // check the predecessor
+ const SwNodeOffset nStartCellNodeIndex =
+ aStartCellPam.Start()->GetNodeIndex();
+ const SwNodeOffset nLastNodeEndIndex = pLastCell->aEnd.GetIndex();
+ if (nLastNodeEndIndex == nStartCellNodeIndex)
+ {
+ // same node as predecessor then equal nContent?
+ if (0 != aStartCellPam.Start()->GetContentIndex())
+ {
+ throw lang::IllegalArgumentException();
+ }
+
+ m_pDoc->getIDocumentContentOperations().SplitNode(*aStartCellPam.Start(), false);
+ SwNodeOffset const nNewIndex(aStartCellPam.Start()->GetNodeIndex());
+ if (nNewIndex != nStartCellNodeIndex)
+ {
+ // aStartCellPam now points to the 2nd node
+ // the last cell may *also* point to 2nd node now - fix it!
+ assert(nNewIndex == nStartCellNodeIndex + 1);
+ if (pLastCell->aEnd.GetIndex() == nNewIndex)
+ {
+ --pLastCell->aEnd;
+ if (pLastCell->aStart.GetIndex() == nNewIndex)
+ {
+ --pLastCell->aStart;
+ }
+ }
+ }
+ }
+ else if (nStartCellNodeIndex == (nLastNodeEndIndex + 1))
+ {
+ // next paragraph - now the content index of the new should be 0
+ // and of the old one should be equal to the text length
+ // but if it isn't we don't care - the cell is being inserted on
+ // the node border anyway
+ }
+ else
+ {
+ throw lang::IllegalArgumentException();
+ }
+ }
+ // now check if there's a need to insert another paragraph break
+ if (aEndCellPam.End()->GetContentIndex() <
+ aEndCellPam.End()->GetNode().GetTextNode()->Len())
+ {
+ m_pDoc->getIDocumentContentOperations().SplitNode(*aEndCellPam.End(), false);
+ // take care that the new start/endcell is moved to the right position
+ // aStartCellPam has to point to the start of the new (previous) node
+ // aEndCellPam has to point to the end of the new (previous) node
+ aStartCellPam.DeleteMark();
+ aStartCellPam.Move(fnMoveBackward, GoInNode);
+ aStartCellPam.GetPoint()->SetContent(0);
+ aEndCellPam.DeleteMark();
+ aEndCellPam.Move(fnMoveBackward, GoInNode);
+ aEndCellPam.GetPoint()->SetContent(
+ aEndCellPam.GetPointNode().GetTextNode()->Len() );
+ }
+
+ assert(aStartCellPam.Start()->GetContentIndex() == 0);
+ assert(aEndCellPam.End()->GetContentIndex() == aEndCellPam.End()->GetNode().GetTextNode()->Len());
+ SwNodeRange aCellRange(aStartCellPam.Start()->GetNode(),
+ aEndCellPam.End()->GetNode());
+ rRowNodes.push_back(aCellRange); // note: invalidates pLastCell!
+
+ // tdf#149649 delete any fieldmarks overlapping the cell
+ IDocumentMarkAccess & rIDMA(*m_pDoc->getIDocumentMarkAccess());
+ while (sw::mark::IFieldmark *const pMark = rIDMA.getInnerFieldmarkFor(*aStartCellPam.Start()))
+ {
+ if (pMark->GetMarkEnd() <= *aEndCellPam.End())
+ {
+ if (pMark->GetMarkStart() < *aStartCellPam.Start())
+ {
+ SAL_INFO("sw.uno", "deleting fieldmark overlapping table cell");
+ rIDMA.deleteMark(pMark);
+ }
+ else
+ {
+ break;
+ }
+ }
+ else
+ {
+ SwPosition const sepPos(::sw::mark::FindFieldSep(*pMark));
+ if (*aStartCellPam.Start() <= sepPos && sepPos <= *aEndCellPam.End())
+ {
+ SAL_INFO("sw.uno", "deleting fieldmark with separator in table cell");
+ rIDMA.deleteMark(pMark);
+ }
+ else
+ {
+ break;
+ }
+ }
+ }
+ while (sw::mark::IFieldmark *const pMark = rIDMA.getInnerFieldmarkFor(*aEndCellPam.End()))
+ {
+ if (*aStartCellPam.Start() <= pMark->GetMarkStart())
+ {
+ if (*aEndCellPam.End() < pMark->GetMarkEnd())
+ {
+ SAL_INFO("sw.uno", "deleting fieldmark overlapping table cell");
+ rIDMA.deleteMark(pMark);
+ }
+ else
+ {
+ break;
+ }
+ }
+ else
+ {
+ SwPosition const sepPos(::sw::mark::FindFieldSep(*pMark));
+ if (*aStartCellPam.Start() <= sepPos && sepPos <= *aEndCellPam.End())
+ {
+ SAL_INFO("sw.uno", "deleting fieldmark with separator in table cell");
+ rIDMA.deleteMark(pMark);
+ }
+ else
+ {
+ break;
+ }
+ }
+ }
+}
+
+typedef uno::Sequence< text::TableColumnSeparator > TableColumnSeparators;
+
+static void
+lcl_ApplyRowProperties(
+ uno::Sequence<beans::PropertyValue> const& rRowProperties,
+ uno::Any const& rRow,
+ TableColumnSeparators & rRowSeparators)
+{
+ uno::Reference< beans::XPropertySet > xRow;
+ rRow >>= xRow;
+ for (const beans::PropertyValue& rProperty : rRowProperties)
+ {
+ if ( rProperty.Name == "TableColumnSeparators" )
+ {
+ // add the separators to access the cell's positions
+ // for vertical merging later
+ TableColumnSeparators aSeparators;
+ rProperty.Value >>= aSeparators;
+ rRowSeparators = aSeparators;
+ }
+ xRow->setPropertyValue(rProperty.Name, rProperty.Value);
+ }
+}
+
+static sal_Int32 lcl_GetLeftPos(sal_Int32 nCell, TableColumnSeparators const& rRowSeparators)
+{
+ if(!nCell)
+ return 0;
+ if (rRowSeparators.getLength() < nCell)
+ return -1;
+ return rRowSeparators[nCell - 1].Position;
+}
+
+static void
+lcl_ApplyCellProperties(
+ const sal_Int32 nLeftPos,
+ const uno::Sequence< beans::PropertyValue >& rCellProperties,
+ const uno::Reference< uno::XInterface >& xCell,
+ std::vector<VerticallyMergedCell> & rMergedCells)
+{
+ const uno::Reference< beans::XPropertySet > xCellPS(xCell, uno::UNO_QUERY);
+ for (const auto& rCellProperty : rCellProperties)
+ {
+ const OUString & rName = rCellProperty.Name;
+ const uno::Any & rValue = rCellProperty.Value;
+ if ( rName == "VerticalMerge" )
+ {
+ // determine left border position
+ // add the cell to a queue of merged cells
+ bool bMerge = false;
+ rValue >>= bMerge;
+ if (bMerge)
+ {
+ // 'close' all the cell with the same left position
+ // if separate vertical merges in the same column exist
+ for(auto& aMergedCell : rMergedCells)
+ {
+ if(lcl_SimilarPosition(aMergedCell.nLeftPosition, nLeftPos))
+ {
+ aMergedCell.bOpen = false;
+ }
+ }
+ // add the new group of merged cells
+ rMergedCells.emplace_back(xCellPS, nLeftPos);
+ }
+ else
+ {
+ bool bFound = false;
+ SAL_WARN_IF(rMergedCells.empty(), "sw.uno", "the first merged cell is missing");
+ for(auto& aMergedCell : rMergedCells)
+ {
+ if (aMergedCell.bOpen && lcl_SimilarPosition(aMergedCell.nLeftPosition, nLeftPos))
+ {
+ aMergedCell.aCells.push_back( xCellPS );
+ bFound = true;
+ }
+ }
+ SAL_WARN_IF(!bFound, "sw.uno", "couldn't find first vertically merged cell" );
+ }
+ }
+ else
+ {
+ try
+ {
+ static const std::initializer_list<std::u16string_view> vDenylist = {
+ u"LeftMargin",
+ };
+ if (std::find(vDenylist.begin(), vDenylist.end(), rName) == vDenylist.end())
+ {
+ xCellPS->setPropertyValue(rName, rValue);
+ }
+ }
+ catch (const uno::Exception&)
+ {
+ TOOLS_WARN_EXCEPTION( "sw.uno", "Exception when setting cell property " << rName );
+ }
+ }
+ }
+}
+
+static void
+lcl_MergeCells(std::vector<VerticallyMergedCell> & rMergedCells)
+{
+ for(auto& aMergedCell : rMergedCells)
+ {
+ // the first of the cells gets the number of cells set as RowSpan
+ // the others get the inverted number of remaining merged cells
+ // (3,-2,-1)
+ sal_Int32 nCellCount = static_cast<sal_Int32>(aMergedCell.aCells.size());
+ if(nCellCount<2)
+ {
+ SAL_WARN("sw.uno", "incomplete vertical cell merge");
+ continue;
+ }
+ aMergedCell.aCells.front()->setPropertyValue(UNO_NAME_ROW_SPAN, uno::Any(nCellCount--));
+ nCellCount*=-1;
+ for(auto pxPSet = aMergedCell.aCells.begin()+1; nCellCount<0; ++pxPSet, ++nCellCount)
+ {
+ (*pxPSet)->setPropertyValue(UNO_NAME_ROW_SPAN, uno::Any(nCellCount));
+ (*pxPSet)->setPropertyValue("VerticalMerge", uno::Any(true));
+ }
+ }
+}
+
+uno::Reference< text::XTextTable > SAL_CALL
+SwXText::convertToTable(
+ const uno::Sequence< uno::Sequence< uno::Sequence<
+ uno::Reference< text::XTextRange > > > >& rTableRanges,
+ const uno::Sequence< uno::Sequence< uno::Sequence<
+ beans::PropertyValue > > >& rCellProperties,
+ const uno::Sequence< uno::Sequence< beans::PropertyValue > >&
+ rRowProperties,
+ const uno::Sequence< beans::PropertyValue >& rTableProperties)
+{
+ SolarMutexGuard aGuard;
+
+ if(!IsValid())
+ {
+ throw uno::RuntimeException();
+ }
+
+ IDocumentRedlineAccess & rIDRA(m_pImpl->m_pDoc->getIDocumentRedlineAccess());
+ if (!IDocumentRedlineAccess::IsShowChanges(rIDRA.GetRedlineFlags()))
+ {
+ throw uno::RuntimeException(
+ "cannot convertToTable if tracked changes are hidden!");
+ }
+
+ //at first collect the text ranges as SwPaMs
+ const uno::Sequence< uno::Sequence< uno::Reference< text::XTextRange > > >*
+ pTableRanges = rTableRanges.getConstArray();
+ std::vector< std::vector<SwNodeRange> > aTableNodes;
+ for (sal_Int32 nRow = 0; nRow < rTableRanges.getLength(); ++nRow)
+ {
+ std::vector<SwNodeRange> aRowNodes;
+ const uno::Sequence< uno::Reference< text::XTextRange > >* pRow =
+ pTableRanges[nRow].getConstArray();
+ const sal_Int32 nCells(pTableRanges[nRow].getLength());
+
+ if (0 == nCells) // this would lead to no pLastCell below
+ { // and make it impossible to detect node gaps
+ throw lang::IllegalArgumentException();
+ }
+
+ for (sal_Int32 nCell = 0; nCell < nCells; ++nCell)
+ {
+ SwNodeRange *const pLastCell(
+ (nCell == 0)
+ ? ((nRow == 0)
+ ? nullptr
+ : &*aTableNodes.rbegin()->rbegin())
+ : &*aRowNodes.rbegin());
+ m_pImpl->ConvertCell(pRow[nCell], aRowNodes, pLastCell);
+ }
+ assert(!aRowNodes.empty());
+ aTableNodes.push_back(aRowNodes);
+ }
+
+ std::vector< TableColumnSeparators >
+ aRowSeparators(rRowProperties.getLength());
+ std::vector<VerticallyMergedCell> aMergedCells;
+
+ SwTable const*const pTable = m_pImpl->m_pDoc->TextToTable( aTableNodes );
+
+ if (!pTable)
+ return uno::Reference< text::XTextTable >();
+
+ uno::Reference<text::XTextTable> const xRet =
+ SwXTextTable::CreateXTextTable(pTable->GetFrameFormat());
+ uno::Reference<beans::XPropertySet> const xPrSet(xRet, uno::UNO_QUERY);
+ // set properties to the table
+ // catch lang::WrappedTargetException and lang::IndexOutOfBoundsException
+ try
+ {
+ //apply table properties
+ for(const auto& rTableProperty : rTableProperties)
+ {
+ try
+ {
+ static const std::initializer_list<std::u16string_view> vDenylist = {
+ u"BottomBorder",
+ u"CharAutoKerning",
+ u"CharFontName",
+ u"CharFontNameAsian",
+ u"CharFontNameComplex",
+ u"CharHeight",
+ u"CharHeightAsian",
+ u"CharHeightComplex",
+ u"CharInteropGrabBag",
+ u"CharLocale",
+ u"CharLocaleAsian",
+ u"CharLocaleComplex",
+ u"HorizontalBorder",
+ u"LeftBorder",
+ u"ParaAdjust",
+ u"ParaBottomMargin",
+ u"ParaIsHyphenation",
+ u"ParaLineSpacing",
+ u"ParaOrphans",
+ u"ParaTopMargin",
+ u"ParaWidows",
+ u"RightBorder",
+ u"TopBorder",
+ u"VerticalBorder",
+ };
+ if (std::find(vDenylist.begin(), vDenylist.end(), rTableProperty.Name) == vDenylist.end())
+ {
+ xPrSet->setPropertyValue(rTableProperty.Name, rTableProperty.Value);
+ }
+ }
+ catch (const uno::Exception&)
+ {
+ TOOLS_WARN_EXCEPTION( "sw.uno", "Exception when setting property: " << rTableProperty.Name );
+ }
+ }
+
+ //apply row properties
+ const auto xRows = xRet->getRows();
+ const sal_Int32 nLast = std::min(xRows->getCount(), rRowProperties.getLength());
+ SAL_WARN_IF(nLast != rRowProperties.getLength(), "sw.uno", "not enough rows for properties");
+ for(sal_Int32 nCnt = 0; nCnt < nLast; ++nCnt)
+ lcl_ApplyRowProperties(rRowProperties[nCnt], xRows->getByIndex(nCnt), aRowSeparators[nCnt]);
+
+ uno::Reference<table::XCellRange> const xCR(xRet, uno::UNO_QUERY_THROW);
+ //apply cell properties
+ sal_Int32 nRow = 0;
+ for(const auto& rCellPropertiesForRow : rCellProperties)
+ {
+ sal_Int32 nCell = 0;
+ for(const auto& rCellProps : rCellPropertiesForRow)
+ {
+ lcl_ApplyCellProperties(lcl_GetLeftPos(nCell, aRowSeparators[nRow]),
+ rCellProps,
+ xCR->getCellByPosition(nCell, nRow),
+ aMergedCells);
+ ++nCell;
+ }
+ ++nRow;
+ }
+
+ // now that the cell properties are set the vertical merge values
+ // have to be applied
+ lcl_MergeCells(aMergedCells);
+ }
+ catch (const lang::WrappedTargetException&)
+ {
+ }
+ catch (const lang::IndexOutOfBoundsException&)
+ {
+ }
+
+ assert(SwTable::FindTable(pTable->GetFrameFormat()) == pTable);
+ assert(pTable->GetFrameFormat() ==
+ dynamic_cast<SwXTextTable&>(*xRet).GetFrameFormat());
+ return xRet;
+}
+
+void SAL_CALL
+SwXText::copyText(
+ const uno::Reference< text::XTextCopy >& xSource )
+{
+ SolarMutexGuard aGuard;
+
+ SwXText* const pSource(dynamic_cast<SwXText*>(xSource.get()));
+ if (!pSource)
+ throw uno::RuntimeException();
+
+ rtl::Reference< SwXTextCursor > const xCursor = pSource->createXTextCursor();
+ xCursor->gotoEnd( true );
+
+ SwNodeIndex rNdIndex( *GetStartNode( ), 1 );
+ SwPosition rPos( rNdIndex );
+ // tdf#112202 need SwXText because cursor cannot select table at the start
+ SwTextNode * pFirstNode;
+ {
+ SwPaM temp(*pSource->GetStartNode(), *pSource->GetStartNode()->EndOfSectionNode(), SwNodeOffset(+1), SwNodeOffset(-1));
+ pFirstNode = temp.GetMark()->GetNode().GetTextNode();
+ if (pFirstNode)
+ {
+ temp.GetMark()->AssignStartIndex(*pFirstNode);
+ }
+ if (SwTextNode *const pNode = temp.GetPoint()->GetNode().GetTextNode())
+ {
+ temp.GetPoint()->AssignEndIndex(*pNode);
+ }
+ // Explicitly request copy text mode, so
+ // sw::DocumentContentOperationsManager::CopyFlyInFlyImpl() will copy shapes anchored to
+ // us, even if we have only a single paragraph.
+ m_pImpl->m_pDoc->getIDocumentContentOperations().CopyRange(temp, rPos, SwCopyFlags::CheckPosInFly);
+ }
+ if (!pFirstNode)
+ { // the node at rPos was split; get rid of the first empty one so
+ // that the pasted table is first
+ auto pDelCursor(m_pImpl->m_pDoc->CreateUnoCursor(SwPosition(*GetStartNode(), SwNodeOffset(1))));
+ m_pImpl->m_pDoc->getIDocumentContentOperations().DelFullPara(*pDelCursor);
+ }
+}
+
+SwXBodyText::SwXBodyText(SwDoc *const pDoc)
+ : SwXText(pDoc, CursorType::Body)
+{
+}
+
+SwXBodyText::~SwXBodyText()
+{
+}
+
+OUString SAL_CALL
+SwXBodyText::getImplementationName()
+{
+ return "SwXBodyText";
+}
+
+sal_Bool SAL_CALL SwXBodyText::supportsService(const OUString& rServiceName)
+{
+ return cppu::supportsService(this, rServiceName);
+}
+
+uno::Sequence< OUString > SAL_CALL
+SwXBodyText::getSupportedServiceNames()
+{
+ return { "com.sun.star.text.Text" };
+}
+
+uno::Sequence< uno::Type > SAL_CALL
+SwXBodyText::getTypes()
+{
+ const uno::Sequence< uno::Type > aTypes = SwXBodyText_Base::getTypes();
+ const uno::Sequence< uno::Type > aTextTypes = SwXText::getTypes();
+ return ::comphelper::concatSequences(aTypes, aTextTypes);
+}
+
+uno::Sequence< sal_Int8 > SAL_CALL
+SwXBodyText::getImplementationId()
+{
+ return css::uno::Sequence<sal_Int8>();
+}
+
+uno::Any SAL_CALL
+SwXBodyText::queryInterface(const uno::Type& rType)
+{
+ const uno::Any ret = SwXText::queryInterface(rType);
+ return (ret.getValueType() == cppu::UnoType<void>::get())
+ ? SwXBodyText_Base::queryInterface(rType)
+ : ret;
+}
+
+rtl::Reference<SwXTextCursor> SwXBodyText::CreateTextCursor(const bool bIgnoreTables)
+{
+ if(!IsValid())
+ {
+ return nullptr;
+ }
+
+ // the cursor has to skip tables contained in this text
+ SwPaM aPam(GetDoc()->GetNodes().GetEndOfContent());
+ aPam.Move( fnMoveBackward, GoInDoc );
+ if (!bIgnoreTables)
+ {
+ SwTableNode * pTableNode = aPam.GetPointNode().FindTableNode();
+ while (pTableNode)
+ {
+ aPam.GetPoint()->Assign( *pTableNode->EndOfSectionNode() );
+ SwContentNode* pCont = GetDoc()->GetNodes().GoNext(aPam.GetPoint());
+ pTableNode = pCont->FindTableNode();
+ }
+ }
+ return new SwXTextCursor(*GetDoc(), this, CursorType::Body, *aPam.GetPoint());
+}
+
+rtl::Reference< SwXTextCursor >
+SwXBodyText::createXTextCursor()
+{
+ return CreateTextCursor();
+}
+
+rtl::Reference< SwXTextCursor >
+SwXBodyText::createXTextCursorByRange(
+ const uno::Reference< text::XTextRange > & xTextPosition)
+{
+ if(!IsValid())
+ throw uno::RuntimeException(cInvalidObject);
+
+ rtl::Reference< SwXTextCursor > aRef;
+ SwUnoInternalPaM aPam(*GetDoc());
+ if (::sw::XTextRangeToSwPaM(aPam, xTextPosition))
+ {
+ if ( !aPam.GetPointNode().GetTextNode() )
+ throw uno::RuntimeException("Invalid text range" );
+
+ SwNode& rNode = GetDoc()->GetNodes().GetEndOfContent();
+
+ SwStartNode* p1 = aPam.GetPointNode().StartOfSectionNode();
+ //document starts with a section?
+ while(p1->IsSectionNode())
+ {
+ p1 = p1->StartOfSectionNode();
+ }
+ SwStartNode *const p2 = rNode.StartOfSectionNode();
+
+ if(p1 == p2)
+ {
+ aRef = new SwXTextCursor(*GetDoc(), this, CursorType::Body,
+ *aPam.GetPoint(), aPam.GetMark());
+ }
+ }
+ if(!aRef.is())
+ {
+ throw uno::RuntimeException( "End of content node doesn't have the proper start node",
+ uno::Reference< uno::XInterface >( *this ) );
+ }
+ return aRef;
+}
+
+uno::Reference< container::XEnumeration > SAL_CALL
+SwXBodyText::createEnumeration()
+{
+ return createParagraphEnumeration();
+}
+
+rtl::Reference< SwXParagraphEnumeration >
+SwXBodyText::createParagraphEnumeration()
+{
+ SolarMutexGuard aGuard;
+
+ if (!IsValid())
+ throw uno::RuntimeException(cInvalidObject);
+
+ SwNode& rNode = GetDoc()->GetNodes().GetEndOfContent();
+ SwPosition aPos(rNode);
+ auto pUnoCursor(GetDoc()->CreateUnoCursor(aPos));
+ pUnoCursor->Move(fnMoveBackward, GoInDoc);
+ return SwXParagraphEnumeration::Create(this, pUnoCursor, CursorType::Body);
+}
+
+uno::Type SAL_CALL
+SwXBodyText::getElementType()
+{
+ return cppu::UnoType<text::XTextRange>::get();
+}
+
+sal_Bool SAL_CALL
+SwXBodyText::hasElements()
+{
+ SolarMutexGuard aGuard;
+
+ if (!IsValid())
+ throw uno::RuntimeException(cInvalidObject);
+
+ return true;
+}
+
+class SwXHeadFootText::Impl
+ : public SvtListener
+{
+ public:
+ SwFrameFormat* m_pHeadFootFormat;
+ bool m_bIsHeader;
+
+ Impl(SwFrameFormat& rHeadFootFormat, const bool bIsHeader)
+ : m_pHeadFootFormat(&rHeadFootFormat)
+ , m_bIsHeader(bIsHeader)
+ {
+ StartListening(m_pHeadFootFormat->GetNotifier());
+ }
+
+ SwFrameFormat* GetHeadFootFormat() const {
+ return m_pHeadFootFormat;
+ }
+
+ SwFrameFormat& GetHeadFootFormatOrThrow() {
+ if (!m_pHeadFootFormat) {
+ throw uno::RuntimeException("SwXHeadFootText: disposed or invalid", nullptr);
+ }
+ return *m_pHeadFootFormat;
+ }
+ protected:
+ virtual void Notify(const SfxHint& rHint) override
+ {
+ if(rHint.GetId() == SfxHintId::Dying)
+ m_pHeadFootFormat = nullptr;
+ }
+};
+
+rtl::Reference<SwXHeadFootText> SwXHeadFootText::CreateXHeadFootText(
+ SwFrameFormat& rHeadFootFormat,
+ const bool bIsHeader)
+{
+ // re-use existing SwXHeadFootText
+ // #i105557#: do not iterate over the registered clients: race condition
+ rtl::Reference<SwXHeadFootText> xText = dynamic_cast<SwXHeadFootText*>(rHeadFootFormat.GetXObject().get().get());
+ if(!xText.is())
+ {
+ xText = new SwXHeadFootText(rHeadFootFormat, bIsHeader);
+ rHeadFootFormat.SetXObject(static_cast<cppu::OWeakObject*>(xText.get()));
+ }
+ return xText;
+}
+
+SwXHeadFootText::SwXHeadFootText(SwFrameFormat& rHeadFootFormat, const bool bIsHeader)
+ : SwXText(
+ rHeadFootFormat.GetDoc(),
+ bIsHeader ? CursorType::Header : CursorType::Footer)
+ , m_pImpl(new SwXHeadFootText::Impl(rHeadFootFormat, bIsHeader))
+{
+}
+
+SwXHeadFootText::~SwXHeadFootText()
+{ }
+
+OUString SAL_CALL
+SwXHeadFootText::getImplementationName()
+{
+ return {"SwXHeadFootText"};
+}
+
+sal_Bool SAL_CALL SwXHeadFootText::supportsService(const OUString& rServiceName)
+{
+ return cppu::supportsService(this, rServiceName);
+}
+
+uno::Sequence<OUString> SAL_CALL
+SwXHeadFootText::getSupportedServiceNames()
+{
+ return {"com.sun.star.text.Text"};
+}
+
+const SwStartNode* SwXHeadFootText::GetStartNode() const
+{
+ const SwStartNode* pSttNd = nullptr;
+ SwFrameFormat* const pHeadFootFormat = m_pImpl->GetHeadFootFormat();
+ if(pHeadFootFormat)
+ {
+ const SwFormatContent& rFlyContent = pHeadFootFormat->GetContent();
+ if(rFlyContent.GetContentIdx())
+ {
+ pSttNd = rFlyContent.GetContentIdx()->GetNode().GetStartNode();
+ }
+ }
+ return pSttNd;
+}
+
+uno::Sequence<uno::Type> SAL_CALL SwXHeadFootText::getTypes()
+{
+ return ::comphelper::concatSequences(
+ SwXHeadFootText_Base::getTypes(),
+ SwXText::getTypes());
+}
+
+uno::Sequence<sal_Int8> SAL_CALL SwXHeadFootText::getImplementationId()
+{
+ return css::uno::Sequence<sal_Int8>();
+}
+
+uno::Any SAL_CALL SwXHeadFootText::queryInterface(const uno::Type& rType)
+{
+ const uno::Any ret = SwXHeadFootText_Base::queryInterface(rType);
+ return (ret.getValueType() == cppu::UnoType<void>::get())
+ ? SwXText::queryInterface(rType)
+ : ret;
+}
+
+rtl::Reference<SwXTextCursor> SwXHeadFootText::CreateTextCursor(const bool bIgnoreTables)
+{
+ SwFrameFormat & rHeadFootFormat( m_pImpl->GetHeadFootFormatOrThrow() );
+
+ const SwFormatContent& rFlyContent = rHeadFootFormat.GetContent();
+ const SwNode& rNode = rFlyContent.GetContentIdx()->GetNode();
+ SwPosition aPos(rNode);
+ rtl::Reference<SwXTextCursor> pXCursor = new SwXTextCursor(*GetDoc(), this,
+ (m_pImpl->m_bIsHeader) ? CursorType::Header : CursorType::Footer, aPos);
+ auto& rUnoCursor(pXCursor->GetCursor());
+ rUnoCursor.Move(fnMoveForward, GoInNode);
+
+ // save current start node to be able to check if there is content
+ // after the table - otherwise the cursor would be in the body text!
+ SwStartNode const*const pOwnStartNode = rNode.FindSttNodeByType(
+ (m_pImpl->m_bIsHeader) ? SwHeaderStartNode : SwFooterStartNode);
+
+ if (!bIgnoreTables)
+ {
+ // is there a table here?
+ SwTableNode* pTableNode = rUnoCursor.GetPointNode().FindTableNode();
+ while (pTableNode)
+ {
+ rUnoCursor.GetPoint()->Assign(*pTableNode->EndOfSectionNode());
+ SwContentNode* pCont = GetDoc()->GetNodes().GoNext(rUnoCursor.GetPoint());
+ pTableNode = pCont->FindTableNode();
+ }
+ }
+ SwStartNode const*const pNewStartNode = rUnoCursor.GetPointNode().FindSttNodeByType(
+ (m_pImpl->m_bIsHeader) ? SwHeaderStartNode : SwFooterStartNode);
+ if (!pNewStartNode || (pNewStartNode != pOwnStartNode))
+ {
+ throw uno::RuntimeException("no text available");
+ }
+ return pXCursor;
+}
+
+rtl::Reference< SwXTextCursor >
+SwXHeadFootText::createXTextCursor()
+{
+ return CreateTextCursor(false);
+}
+
+rtl::Reference<SwXTextCursor> SwXHeadFootText::createXTextCursorByRange(
+ const uno::Reference<text::XTextRange>& xTextPosition)
+{
+ SwFrameFormat& rHeadFootFormat( m_pImpl->GetHeadFootFormatOrThrow() );
+
+ SwUnoInternalPaM aPam(*GetDoc());
+ if (!sw::XTextRangeToSwPaM(aPam, xTextPosition))
+ {
+ throw uno::RuntimeException(cInvalidObject);
+ }
+
+ SwNode& rNode = rHeadFootFormat.GetContent().GetContentIdx()->GetNode();
+ SwPosition aPos(rNode);
+ SwPaM aHFPam(aPos);
+ aHFPam.Move(fnMoveForward, GoInNode);
+ SwStartNode* const pOwnStartNode = aHFPam.GetPointNode().FindSttNodeByType(
+ (m_pImpl->m_bIsHeader) ? SwHeaderStartNode : SwFooterStartNode);
+ SwStartNode* const p1 = aPam.GetPointNode().FindSttNodeByType(
+ (m_pImpl->m_bIsHeader) ? SwHeaderStartNode : SwFooterStartNode);
+ if (p1 == pOwnStartNode)
+ {
+ return new SwXTextCursor(
+ *GetDoc(),
+ this,
+ (m_pImpl->m_bIsHeader) ? CursorType::Header : CursorType::Footer,
+ *aPam.GetPoint(), aPam.GetMark());
+ }
+ return nullptr;
+}
+
+uno::Reference<container::XEnumeration> SAL_CALL SwXHeadFootText::createEnumeration()
+{
+ SolarMutexGuard aGuard;
+ SwFrameFormat& rHeadFootFormat(m_pImpl->GetHeadFootFormatOrThrow());
+
+ const SwFormatContent& rFlyContent = rHeadFootFormat.GetContent();
+ const SwNode& rNode = rFlyContent.GetContentIdx()->GetNode();
+ SwPosition aPos(rNode);
+ auto pUnoCursor(GetDoc()->CreateUnoCursor(aPos));
+ pUnoCursor->Move(fnMoveForward, GoInNode);
+ return SwXParagraphEnumeration::Create(
+ this,
+ pUnoCursor,
+ (m_pImpl->m_bIsHeader)
+ ? CursorType::Header
+ : CursorType::Footer);
+}
+
+uno::Type SAL_CALL SwXHeadFootText::getElementType()
+ { return cppu::UnoType<text::XTextRange>::get(); }
+
+sal_Bool SAL_CALL SwXHeadFootText::hasElements()
+ { return true; }
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/core/unocore/unotextmarkup.cxx b/sw/source/core/unocore/unotextmarkup.cxx
new file mode 100644
index 0000000000..4bbc860160
--- /dev/null
+++ b/sw/source/core/unocore/unotextmarkup.cxx
@@ -0,0 +1,514 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <unotextmarkup.hxx>
+
+#include <comphelper/servicehelper.hxx>
+#include <o3tl/safeint.hxx>
+#include <osl/diagnose.h>
+#include <svl/listener.hxx>
+#include <utility>
+#include <vcl/svapp.hxx>
+#include <SwSmartTagMgr.hxx>
+#include <com/sun/star/lang/IndexOutOfBoundsException.hpp>
+#include <com/sun/star/text/TextMarkupType.hpp>
+#include <com/sun/star/text/TextMarkupDescriptor.hpp>
+#include <com/sun/star/container/ElementExistException.hpp>
+#include <com/sun/star/container/XStringKeyMap.hpp>
+#include <ndtxt.hxx>
+#include <SwGrammarMarkUp.hxx>
+#include <TextCursorHelper.hxx>
+#include <GrammarContact.hxx>
+
+#include <com/sun/star/lang/XUnoTunnel.hpp>
+#include <com/sun/star/text/XTextRange.hpp>
+
+#include <pam.hxx>
+
+#include <unotextrange.hxx>
+#include <modeltoviewhelper.hxx>
+
+using namespace ::com::sun::star;
+
+struct SwXTextMarkup::Impl
+ : public SvtListener
+{
+ SwTextNode* m_pTextNode;
+ ModelToViewHelper const m_ConversionMap;
+
+ Impl(SwTextNode* const pTextNode, ModelToViewHelper aMap)
+ : m_pTextNode(pTextNode)
+ , m_ConversionMap(std::move(aMap))
+ {
+ if(m_pTextNode)
+ StartListening(pTextNode->GetNotifier());
+ }
+
+ virtual void Notify(const SfxHint& rHint) override;
+};
+
+SwXTextMarkup::SwXTextMarkup(
+ SwTextNode *const pTextNode, const ModelToViewHelper& rMap)
+ : m_pImpl(new Impl(pTextNode, rMap))
+{
+}
+
+SwXTextMarkup::~SwXTextMarkup()
+{
+}
+
+SwTextNode* SwXTextMarkup::GetTextNode()
+{
+ return m_pImpl->m_pTextNode;
+}
+
+void SwXTextMarkup::ClearTextNode()
+{
+ m_pImpl->m_pTextNode = nullptr;
+ m_pImpl->EndListeningAll();
+}
+
+const ModelToViewHelper& SwXTextMarkup::GetConversionMap() const
+{
+ return m_pImpl->m_ConversionMap;
+}
+
+uno::Reference< container::XStringKeyMap > SAL_CALL SwXTextMarkup::getMarkupInfoContainer()
+{
+ return new SwXStringKeyMap;
+}
+
+void SAL_CALL SwXTextMarkup::commitTextRangeMarkup(::sal_Int32 nType, const OUString & aIdentifier, const uno::Reference< text::XTextRange> & xRange,
+ const uno::Reference< container::XStringKeyMap > & xMarkupInfoContainer)
+{
+ SolarMutexGuard aGuard;
+
+ if (auto pRange = dynamic_cast<SwXTextRange*>(xRange.get()))
+ {
+ SwDoc& rDoc = pRange->GetDoc();
+
+ SwUnoInternalPaM aPam(rDoc);
+
+ ::sw::XTextRangeToSwPaM(aPam, xRange);
+
+ auto [startPos, endPos] = aPam.StartEnd(); // SwPosition*
+
+ commitStringMarkup (nType, aIdentifier, startPos->GetContentIndex(), endPos->GetContentIndex() - startPos->GetContentIndex(), xMarkupInfoContainer);
+ }
+ else if (auto pCursor = dynamic_cast<OTextCursorHelper*>(xRange.get()))
+ {
+ SwPaM & rPam(*pCursor->GetPaM());
+
+ auto [startPos, endPos] = rPam.StartEnd(); // SwPosition*
+
+ commitStringMarkup (nType, aIdentifier, startPos->GetContentIndex(), endPos->GetContentIndex() - startPos->GetContentIndex(), xMarkupInfoContainer);
+ }
+}
+
+void SAL_CALL SwXTextMarkup::commitStringMarkup(
+ ::sal_Int32 nType,
+ const OUString & rIdentifier,
+ ::sal_Int32 nStart,
+ ::sal_Int32 nLength,
+ const uno::Reference< container::XStringKeyMap > & xMarkupInfoContainer)
+{
+ SolarMutexGuard aGuard;
+
+ // paragraph already dead or modified?
+ if (!m_pImpl->m_pTextNode || nLength <= 0)
+ return;
+
+ if ( nType == text::TextMarkupType::SMARTTAG &&
+ !SwSmartTagMgr::Get().IsSmartTagTypeEnabled( rIdentifier ) )
+ return;
+
+ // get appropriate list to use...
+ SwWrongList* pWList = nullptr;
+ bool bRepaint = false;
+ if ( nType == text::TextMarkupType::SPELLCHECK )
+ {
+ pWList = m_pImpl->m_pTextNode->GetWrong();
+ if ( !pWList )
+ {
+ pWList = new SwWrongList( WRONGLIST_SPELL );
+ m_pImpl->m_pTextNode->SetWrong( std::unique_ptr<SwWrongList>(pWList) );
+ }
+ }
+ else if ( nType == text::TextMarkupType::PROOFREADING || nType == text::TextMarkupType::SENTENCE )
+ {
+ sw::GrammarContact* pGrammarContact = sw::getGrammarContactFor(*m_pImpl->m_pTextNode);
+ if( pGrammarContact )
+ {
+ pWList = pGrammarContact->getGrammarCheck(*m_pImpl->m_pTextNode, true);
+ OSL_ENSURE( pWList, "GrammarContact _has_ to deliver a wrong list" );
+ }
+ else
+ {
+ pWList = m_pImpl->m_pTextNode->GetGrammarCheck();
+ if ( !pWList )
+ {
+ m_pImpl->m_pTextNode->SetGrammarCheck( std::make_unique<SwGrammarMarkUp>() );
+ pWList = m_pImpl->m_pTextNode->GetGrammarCheck();
+ }
+ }
+ bRepaint = pWList == m_pImpl->m_pTextNode->GetGrammarCheck();
+ if( pWList->GetBeginInv() < COMPLETE_STRING )
+ static_cast<SwGrammarMarkUp*>(pWList)->ClearGrammarList();
+ }
+ else if ( nType == text::TextMarkupType::SMARTTAG )
+ {
+ pWList = m_pImpl->m_pTextNode->GetSmartTags();
+ if ( !pWList )
+ {
+ pWList = new SwWrongList( WRONGLIST_SMARTTAG );
+ m_pImpl->m_pTextNode->SetSmartTags( std::unique_ptr<SwWrongList>(pWList) );
+ }
+ }
+ else
+ {
+ OSL_FAIL( "Unknown mark-up type" );
+ return;
+ }
+
+ const ModelToViewHelper::ModelPosition aStartPos =
+ m_pImpl->m_ConversionMap.ConvertToModelPosition( nStart );
+ const ModelToViewHelper::ModelPosition aEndPos =
+ m_pImpl->m_ConversionMap.ConvertToModelPosition( nStart + nLength - 1);
+
+ const bool bStartInField = aStartPos.mbIsField;
+ const bool bEndInField = aEndPos.mbIsField;
+ bool bCommit = false;
+
+ if ( bStartInField && bEndInField && aStartPos.mnPos == aEndPos.mnPos )
+ {
+ nStart = aStartPos.mnSubPos;
+ const sal_Int32 nFieldPosModel = aStartPos.mnPos;
+ const sal_uInt16 nInsertPos = pWList->GetWrongPos( nFieldPosModel );
+
+ SwWrongList* pSubList = pWList->SubList( nInsertPos );
+ if ( !pSubList )
+ {
+ if( nType == text::TextMarkupType::PROOFREADING || nType == text::TextMarkupType::SENTENCE )
+ pSubList = new SwGrammarMarkUp();
+ else
+ pSubList = new SwWrongList( pWList->GetWrongListType() );
+ pWList->InsertSubList( nFieldPosModel, 1, nInsertPos, pSubList );
+ }
+
+ pWList = pSubList;
+ bCommit = true;
+ }
+ else if ( !bStartInField && !bEndInField )
+ {
+ nStart = aStartPos.mnPos;
+ bCommit = true;
+ nLength = aEndPos.mnPos + 1 - aStartPos.mnPos;
+ }
+ else if( nType == text::TextMarkupType::PROOFREADING || nType == text::TextMarkupType::SENTENCE )
+ {
+ bCommit = true;
+ nStart = aStartPos.mnPos;
+ sal_Int32 nEnd = aEndPos.mnPos;
+ if( bStartInField && nType != text::TextMarkupType::SENTENCE )
+ {
+ const sal_Int32 nFieldPosModel = aStartPos.mnPos;
+ const sal_uInt16 nInsertPos = pWList->GetWrongPos( nFieldPosModel );
+ SwWrongList* pSubList = pWList->SubList( nInsertPos );
+ if ( !pSubList )
+ {
+ pSubList = new SwGrammarMarkUp();
+ pWList->InsertSubList( nFieldPosModel, 1, nInsertPos, pSubList );
+ }
+ const sal_Int32 nTmpStart =
+ m_pImpl->m_ConversionMap.ConvertToViewPosition(aStartPos.mnPos);
+ const sal_Int32 nTmpLen =
+ m_pImpl->m_ConversionMap.ConvertToViewPosition(aStartPos.mnPos + 1)
+ - nTmpStart - aStartPos.mnSubPos;
+ if( nTmpLen > 0 )
+ {
+ pSubList->Insert( rIdentifier, xMarkupInfoContainer, aStartPos.mnSubPos, nTmpLen );
+ }
+ ++nStart;
+ }
+ if( bEndInField && nType != text::TextMarkupType::SENTENCE )
+ {
+ const sal_Int32 nFieldPosModel = aEndPos.mnPos;
+ const sal_uInt16 nInsertPos = pWList->GetWrongPos( nFieldPosModel );
+ SwWrongList* pSubList = pWList->SubList( nInsertPos );
+ if ( !pSubList )
+ {
+ pSubList = new SwGrammarMarkUp();
+ pWList->InsertSubList( nFieldPosModel, 1, nInsertPos, pSubList );
+ }
+ const sal_Int32 nTmpLen = aEndPos.mnSubPos + 1;
+ pSubList->Insert( rIdentifier, xMarkupInfoContainer, 0, nTmpLen );
+ }
+ else
+ ++nEnd;
+ if( nEnd > nStart )
+ nLength = nEnd - nStart;
+ else
+ bCommit = false;
+ }
+
+ if ( bCommit )
+ {
+ if( nType == text::TextMarkupType::SENTENCE )
+ static_cast<SwGrammarMarkUp*>(pWList)->setSentence( nStart );
+ else
+ pWList->Insert( rIdentifier, xMarkupInfoContainer, nStart, nLength );
+ }
+
+ if( bRepaint )
+ sw::finishGrammarCheckFor(*m_pImpl->m_pTextNode);
+}
+
+static void lcl_commitGrammarMarkUp(
+ const ModelToViewHelper& rConversionMap,
+ SwGrammarMarkUp* pWList,
+ ::sal_Int32 nType,
+ const OUString & rIdentifier,
+ ::sal_Int32 nStart,
+ ::sal_Int32 nLength,
+ const uno::Reference< container::XStringKeyMap > & xMarkupInfoContainer)
+{
+ OSL_ENSURE( nType == text::TextMarkupType::PROOFREADING || nType == text::TextMarkupType::SENTENCE, "Wrong mark-up type" );
+ const ModelToViewHelper::ModelPosition aStartPos =
+ rConversionMap.ConvertToModelPosition( nStart );
+ const ModelToViewHelper::ModelPosition aEndPos =
+ rConversionMap.ConvertToModelPosition( nStart + nLength - 1);
+
+ const bool bStartInField = aStartPos.mbIsField;
+ const bool bEndInField = aEndPos.mbIsField;
+ bool bCommit = false;
+
+ if ( bStartInField && bEndInField && aStartPos.mnPos == aEndPos.mnPos )
+ {
+ nStart = aStartPos.mnSubPos;
+ const sal_Int32 nFieldPosModel = aStartPos.mnPos;
+ const sal_uInt16 nInsertPos = pWList->GetWrongPos( nFieldPosModel );
+
+ SwGrammarMarkUp* pSubList = static_cast<SwGrammarMarkUp*>(pWList->SubList( nInsertPos ));
+ if ( !pSubList )
+ {
+ pSubList = new SwGrammarMarkUp();
+ pWList->InsertSubList( nFieldPosModel, 1, nInsertPos, pSubList );
+ }
+
+ pWList = pSubList;
+ bCommit = true;
+ }
+ else if ( !bStartInField && !bEndInField )
+ {
+ nStart = aStartPos.mnPos;
+ bCommit = true;
+ nLength = aEndPos.mnPos + 1 - aStartPos.mnPos;
+ }
+ else
+ {
+ bCommit = true;
+ nStart = aStartPos.mnPos;
+ sal_Int32 nEnd = aEndPos.mnPos;
+ if( bStartInField && nType != text::TextMarkupType::SENTENCE )
+ {
+ const sal_Int32 nFieldPosModel = aStartPos.mnPos;
+ const sal_uInt16 nInsertPos = pWList->GetWrongPos( nFieldPosModel );
+ SwGrammarMarkUp* pSubList = static_cast<SwGrammarMarkUp*>(pWList->SubList( nInsertPos ));
+ if ( !pSubList )
+ {
+ pSubList = new SwGrammarMarkUp();
+ pWList->InsertSubList( nFieldPosModel, 1, nInsertPos, pSubList );
+ }
+ const sal_Int32 nTmpStart = rConversionMap.ConvertToViewPosition( aStartPos.mnPos );
+ const sal_Int32 nTmpLen = rConversionMap.ConvertToViewPosition( aStartPos.mnPos + 1 )
+ - nTmpStart - aStartPos.mnSubPos;
+ if( nTmpLen > 0 )
+ pSubList->Insert( rIdentifier, xMarkupInfoContainer, aStartPos.mnSubPos, nTmpLen );
+ ++nStart;
+ }
+ if( bEndInField && nType != text::TextMarkupType::SENTENCE )
+ {
+ const sal_Int32 nFieldPosModel = aEndPos.mnPos;
+ const sal_uInt16 nInsertPos = pWList->GetWrongPos( nFieldPosModel );
+ SwGrammarMarkUp* pSubList = static_cast<SwGrammarMarkUp*>(pWList->SubList( nInsertPos ));
+ if ( !pSubList )
+ {
+ pSubList = new SwGrammarMarkUp();
+ pWList->InsertSubList( nFieldPosModel, 1, nInsertPos, pSubList );
+ }
+ const sal_Int32 nTmpLen = aEndPos.mnSubPos + 1;
+ pSubList->Insert( rIdentifier, xMarkupInfoContainer, 0, nTmpLen );
+ }
+ else
+ ++nEnd;
+ if( nEnd > nStart )
+ nLength = nEnd - nStart;
+ else
+ bCommit = false;
+ }
+
+ if ( bCommit )
+ {
+ if( nType == text::TextMarkupType::SENTENCE )
+ pWList->setSentence( nStart+nLength );
+ else
+ pWList->Insert( rIdentifier, xMarkupInfoContainer, nStart, nLength );
+ }
+}
+
+void SAL_CALL SwXTextMarkup::commitMultiTextMarkup(
+ const uno::Sequence< text::TextMarkupDescriptor > &rMarkups )
+{
+ SolarMutexGuard aGuard;
+
+ // paragraph already dead or modified?
+ if (!m_pImpl->m_pTextNode)
+ return;
+
+ // for grammar checking there should be exactly one sentence markup
+ // and 0..n grammar markups.
+ // Different markups are not expected but may be applied anyway since
+ // that should be no problem...
+ // but it has to be implemented, at the moment only this function is for
+ // grammar markups and sentence markup only!
+ const text::TextMarkupDescriptor *pSentenceMarkUp = nullptr;
+ for( const text::TextMarkupDescriptor &rDesc : rMarkups )
+ {
+ if (rDesc.nType == text::TextMarkupType::SENTENCE)
+ {
+ if (pSentenceMarkUp != nullptr)
+ throw lang::IllegalArgumentException(); // there is already one sentence markup
+ pSentenceMarkUp = &rDesc;
+ }
+ else if( rDesc.nType != text::TextMarkupType::PROOFREADING )
+ return;
+ }
+
+ if( pSentenceMarkUp == nullptr )
+ return;
+
+ // get appropriate list to use...
+ SwGrammarMarkUp* pWList = nullptr;
+ bool bRepaint = false;
+ sw::GrammarContact* pGrammarContact = sw::getGrammarContactFor(*m_pImpl->m_pTextNode);
+ if( pGrammarContact )
+ {
+ pWList = pGrammarContact->getGrammarCheck(*m_pImpl->m_pTextNode, true);
+ OSL_ENSURE( pWList, "GrammarContact _has_ to deliver a wrong list" );
+ }
+ else
+ {
+ pWList = m_pImpl->m_pTextNode->GetGrammarCheck();
+ if ( !pWList )
+ {
+ m_pImpl->m_pTextNode->SetGrammarCheck( std::make_unique<SwGrammarMarkUp>() );
+ pWList = m_pImpl->m_pTextNode->GetGrammarCheck();
+ pWList->SetInvalid( 0, COMPLETE_STRING );
+ }
+ }
+ bRepaint = pWList == m_pImpl->m_pTextNode->GetGrammarCheck();
+
+ bool bAcceptGrammarError = false;
+ if( pWList->GetBeginInv() < COMPLETE_STRING )
+ {
+ const ModelToViewHelper::ModelPosition aSentenceEnd =
+ m_pImpl->m_ConversionMap.ConvertToModelPosition(
+ pSentenceMarkUp->nOffset + pSentenceMarkUp->nLength );
+ bAcceptGrammarError = aSentenceEnd.mnPos > pWList->GetBeginInv();
+ pWList->ClearGrammarList( aSentenceEnd.mnPos );
+ }
+
+ if( bAcceptGrammarError )
+ {
+ for( const text::TextMarkupDescriptor &rDesc : rMarkups )
+ {
+ lcl_commitGrammarMarkUp(m_pImpl->m_ConversionMap, pWList, rDesc.nType,
+ rDesc.aIdentifier, rDesc.nOffset, rDesc.nLength, rDesc.xMarkupInfoContainer );
+ }
+ }
+ else
+ {
+ bRepaint = false;
+ const text::TextMarkupDescriptor &rDesc = *pSentenceMarkUp;
+ lcl_commitGrammarMarkUp(m_pImpl->m_ConversionMap, pWList, rDesc.nType,
+ rDesc.aIdentifier, rDesc.nOffset, rDesc.nLength, rDesc.xMarkupInfoContainer );
+ }
+
+ if( bRepaint )
+ sw::finishGrammarCheckFor(*m_pImpl->m_pTextNode);
+}
+
+void SwXTextMarkup::Impl::Notify(const SfxHint& rHint)
+{
+ DBG_TESTSOLARMUTEX();
+ if(rHint.GetId() == SfxHintId::Dying)
+ {
+ m_pTextNode = nullptr;
+ }
+}
+
+SwXStringKeyMap::SwXStringKeyMap()
+{
+}
+
+uno::Any SAL_CALL SwXStringKeyMap::getValue(const OUString & aKey)
+{
+ std::map< OUString, uno::Any >::const_iterator aIter = maMap.find( aKey );
+ if ( aIter == maMap.end() )
+ throw container::NoSuchElementException();
+
+ return (*aIter).second;
+}
+
+sal_Bool SAL_CALL SwXStringKeyMap::hasValue(const OUString & aKey)
+{
+ return maMap.find( aKey ) != maMap.end();
+}
+
+void SAL_CALL SwXStringKeyMap::insertValue(const OUString & aKey, const uno::Any & aValue)
+{
+ std::map< OUString, uno::Any >::const_iterator aIter = maMap.find( aKey );
+ if ( aIter != maMap.end() )
+ throw container::ElementExistException();
+
+ maMap[ aKey ] = aValue;
+}
+
+::sal_Int32 SAL_CALL SwXStringKeyMap::getCount()
+{
+ return maMap.size();
+}
+
+OUString SAL_CALL SwXStringKeyMap::getKeyByIndex(::sal_Int32 nIndex)
+{
+ if ( o3tl::make_unsigned(nIndex) >= maMap.size() )
+ throw lang::IndexOutOfBoundsException();
+
+ return OUString();
+}
+
+uno::Any SAL_CALL SwXStringKeyMap::getValueByIndex(::sal_Int32 nIndex)
+{
+ if ( o3tl::make_unsigned(nIndex) >= maMap.size() )
+ throw lang::IndexOutOfBoundsException();
+
+ return uno::Any();
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */