summaryrefslogtreecommitdiffstats
path: root/sw/source/core/unocore
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-27 16:51:28 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-27 16:51:28 +0000
commit940b4d1848e8c70ab7642901a68594e8016caffc (patch)
treeeb72f344ee6c3d9b80a7ecc079ea79e9fba8676d /sw/source/core/unocore
parentInitial commit. (diff)
downloadlibreoffice-940b4d1848e8c70ab7642901a68594e8016caffc.tar.xz
libreoffice-940b4d1848e8c70ab7642901a68594e8016caffc.zip
Adding upstream version 1:7.0.4.upstream/1%7.0.4upstream
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.cxx46
-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.cxx336
-rw-r--r--sw/source/core/unocore/unobkm.cxx734
-rw-r--r--sw/source/core/unocore/unochart.cxx2717
-rw-r--r--sw/source/core/unocore/unocoll.cxx1941
-rw-r--r--sw/source/core/unocore/unocrsr.cxx214
-rw-r--r--sw/source/core/unocore/unocrsrhelper.cxx1507
-rw-r--r--sw/source/core/unocore/unodraw.cxx2854
-rw-r--r--sw/source/core/unocore/unoevent.cxx233
-rw-r--r--sw/source/core/unocore/unofield.cxx3034
-rw-r--r--sw/source/core/unocore/unoflatpara.cxx593
-rw-r--r--sw/source/core/unocore/unoframe.cxx3656
-rw-r--r--sw/source/core/unocore/unoftn.cxx575
-rw-r--r--sw/source/core/unocore/unoidx.cxx3118
-rw-r--r--sw/source/core/unocore/unomap.cxx1569
-rw-r--r--sw/source/core/unocore/unomap1.cxx1665
-rw-r--r--sw/source/core/unocore/unomapproperties.hxx529
-rw-r--r--sw/source/core/unocore/unoobj.cxx2948
-rw-r--r--sw/source/core/unocore/unoobj2.cxx1692
-rw-r--r--sw/source/core/unocore/unoparagraph.cxx1417
-rw-r--r--sw/source/core/unocore/unoport.cxx825
-rw-r--r--sw/source/core/unocore/unoportenum.cxx1489
-rw-r--r--sw/source/core/unocore/unoredline.cxx587
-rw-r--r--sw/source/core/unocore/unoredlines.cxx168
-rw-r--r--sw/source/core/unocore/unorefmk.cxx1522
-rw-r--r--sw/source/core/unocore/unosect.cxx1735
-rw-r--r--sw/source/core/unocore/unosett.cxx2446
-rw-r--r--sw/source/core/unocore/unosrch.cxx691
-rw-r--r--sw/source/core/unocore/unostyle.cxx5596
-rw-r--r--sw/source/core/unocore/unotbl.cxx4194
-rw-r--r--sw/source/core/unocore/unotext.cxx2717
-rw-r--r--sw/source/core/unocore/unotextmarkup.cxx531
35 files changed, 54569 insertions, 0 deletions
diff --git a/sw/source/core/unocore/SwXTextDefaults.cxx b/sw/source/core/unocore/SwXTextDefaults.cxx
new file mode 100644
index 000000000..19ceff59d
--- /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 SfxItemPropertySimpleEntry *pMap = m_pPropSet->getPropertyMap().getByName( rPropertyName );
+ if (!pMap)
+ throw UnknownPropertyException( "Unknown property: " + rPropertyName, static_cast < cppu::OWeakObject * > ( this ) );
+ if ( pMap->nFlags & PropertyAttribute::READONLY)
+ throw PropertyVetoException ( "Property is read-only: " + rPropertyName, static_cast < cppu::OWeakObject * > ( this ) );
+
+ const SfxPoolItem& rItem = m_pDoc->GetDefault(pMap->nWID);
+ if (RES_PAGEDESC == pMap->nWID && MID_PAGEDESC_PAGEDESCNAME == pMap->nMemberId)
+ {
+ SfxItemSet aSet( m_pDoc->GetAttrPool(), svl::Items<RES_PAGEDESC, RES_PAGEDESC>{} );
+ 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 SfxItemPropertySimpleEntry *pMap = m_pPropSet->getPropertyMap().getByName( rPropertyName );
+ if (!pMap)
+ throw UnknownPropertyException( "Unknown property: " + rPropertyName, static_cast < cppu::OWeakObject * > ( this ) );
+ 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 SfxItemPropertySimpleEntry *pMap = m_pPropSet->getPropertyMap().getByName( rPropertyName );
+ if (!pMap)
+ throw UnknownPropertyException( "Unknown property: " + rPropertyName, static_cast < cppu::OWeakObject * > ( this ) );
+
+ 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.begin(),
+ [this](const OUString& rName) -> PropertyState { return getPropertyState(rName); });
+
+ return aRet;
+}
+
+void SAL_CALL SwXTextDefaults::setPropertyToDefault( const OUString& rPropertyName )
+{
+ if (!m_pDoc)
+ throw RuntimeException();
+ const SfxItemPropertySimpleEntry *pMap = m_pPropSet->getPropertyMap().getByName( rPropertyName );
+ if (!pMap)
+ throw UnknownPropertyException( "Unknown property: " + rPropertyName, static_cast < cppu::OWeakObject * > ( this ) );
+ if ( pMap->nFlags & PropertyAttribute::READONLY)
+ throw RuntimeException( "setPropertyToDefault: property is read-only: " + rPropertyName, static_cast < cppu::OWeakObject * > ( this ) );
+ SfxItemPool& rSet (m_pDoc->GetAttrPool());
+ rSet.ResetPoolDefaultItem ( pMap->nWID );
+}
+
+Any SAL_CALL SwXTextDefaults::getPropertyDefault( const OUString& rPropertyName )
+{
+ if (!m_pDoc)
+ throw RuntimeException();
+ const SfxItemPropertySimpleEntry *pMap = m_pPropSet->getPropertyMap().getByName( rPropertyName );
+ if (!pMap)
+ throw UnknownPropertyException( "Unknown property: " + rPropertyName, static_cast < cppu::OWeakObject * > ( this ) );
+ 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 000000000..d2c45acf4
--- /dev/null
+++ b/sw/source/core/unocore/TextCursorHelper.cxx
@@ -0,0 +1,46 @@
+/* -*- 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>
+
+using namespace ::com::sun::star;
+
+namespace
+{
+ class theOTextCursorHelperUnoTunnelId : public rtl::Static< UnoTunnelIdInit, theOTextCursorHelperUnoTunnelId > {};
+}
+
+const uno::Sequence< sal_Int8 > & OTextCursorHelper::getUnoTunnelId()
+{
+ return theOTextCursorHelperUnoTunnelId::get().getSeq();
+}
+
+//XUnoTunnel
+sal_Int64 SAL_CALL OTextCursorHelper::getSomething(
+ const uno::Sequence< sal_Int8 >& rId )
+{
+ if( isUnoTunnelId<OTextCursorHelper>(rId) )
+ {
+ return sal::static_int_cast< sal_Int64 >( reinterpret_cast< sal_IntPtr >(this) );
+ }
+ return 0;
+}
+
+/* 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 000000000..4542469f5
--- /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 <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(
+ const OUString& 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 = rXMLString.copy( 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 = (aCellStr.copy( i + 1 )).toInt32() - 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 000000000..51966860f
--- /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 000000000..9bfa185af
--- /dev/null
+++ b/sw/source/core/unocore/swunohelper.cxx
@@ -0,0 +1,336 @@
+/* -*- 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 <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::makeAny( true ) );
+ bRemoved = true;
+ }
+ catch( css::uno::Exception& )
+ {
+ bRemoved = false;
+ OSL_FAIL( "Exception from executeCommand( delete )" );
+ }
+ return bRemoved;
+}
+
+bool UCB_MoveFile( const OUString& rURL, const OUString& 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& )
+ {
+ OSL_FAIL( "Exception from executeCommand( transfer )" );
+ bCopyCompleted = false;
+ }
+ return bCopyCompleted;
+}
+
+bool UCB_IsCaseSensitiveFileName( const OUString& 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;
+ OSL_FAIL( "Exception from 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& )
+ {
+ OSL_FAIL( "Exception caught!" );
+ }
+ }
+ }
+ catch( css::uno::Exception& )
+ {
+ OSL_FAIL( "Exception caught!" );
+ 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 000000000..c8fa27faa
--- /dev/null
+++ b/sw/source/core/unocore/unobkm.cxx
@@ -0,0 +1,734 @@
+/* -*- 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/interfacecontainer2.hxx>
+#include <comphelper/sequence.hxx>
+#include <comphelper/servicehelper.hxx>
+#include <cppuhelper/supportsservice.hxx>
+#include <osl/mutex.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
+{
+private:
+ ::osl::Mutex m_Mutex; // just for OInterfaceContainerHelper2
+
+public:
+ uno::WeakReference<uno::XInterface> m_wThis;
+ ::comphelper::OInterfaceContainerHelper2 m_EventListeners;
+ SwDoc* m_pDoc;
+ ::sw::mark::IMark* m_pRegisteredBookmark;
+ OUString m_sMarkName;
+ bool m_bHidden;
+ OUString m_HideCondition;
+
+ Impl( SwDoc *const pDoc )
+ : m_EventListeners(m_Mutex)
+ , 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);
+ m_EventListeners.disposeAndClear(ev);
+ }
+}
+
+void SwXBookmark::Impl::registerInMark(SwXBookmark& rThis,
+ ::sw::mark::IMark* const pBkmk)
+{
+ const uno::Reference<text::XTextContent> 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;
+}
+
+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();
+}
+
+SwXBookmark::SwXBookmark(SwDoc *const pDoc)
+ : m_pImpl( new SwXBookmark::Impl(pDoc) )
+{
+}
+
+SwXBookmark::SwXBookmark()
+ : m_pImpl( new SwXBookmark::Impl(nullptr) )
+{
+}
+
+SwXBookmark::~SwXBookmark()
+{
+}
+
+uno::Reference<text::XTextContent> 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?");
+ uno::Reference<text::XTextContent> 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< lang::XUnoTunnel> & xUT)
+{
+ SwXBookmark *const pXBkm(
+ ::sw::UnoTunnelGetImplementation<SwXBookmark>(xUT));
+ if (pXBkm && (pDoc == pXBkm->m_pImpl->m_pDoc))
+ {
+ return pXBkm->m_pImpl->m_pRegisteredBookmark;
+ }
+ return nullptr;
+}
+
+namespace
+{
+ class theSwXBookmarkUnoTunnelId : public rtl::Static< UnoTunnelIdInit, theSwXBookmarkUnoTunnelId > {};
+}
+
+const uno::Sequence< sal_Int8 > & SwXBookmark::getUnoTunnelId()
+{
+ return theSwXBookmarkUnoTunnelId::get().getSeq();
+}
+
+sal_Int64 SAL_CALL SwXBookmark::getSomething( const uno::Sequence< sal_Int8 >& rId )
+{
+ return ::sw::UnoTunnelImpl<SwXBookmark>(rId, this);
+}
+
+void SwXBookmark::attachToRangeEx(
+ const uno::Reference< text::XTextRange > & xTextRange,
+ IDocumentMarkAccess::MarkType eType)
+{
+ if (m_pImpl->m_pRegisteredBookmark)
+ {
+ throw uno::RuntimeException();
+ }
+
+ const uno::Reference<lang::XUnoTunnel> xRangeTunnel(
+ xTextRange, uno::UNO_QUERY);
+ SwXTextRange* pRange = nullptr;
+ OTextCursorHelper* pCursor = nullptr;
+ if(xRangeTunnel.is())
+ {
+ pRange = ::sw::UnoTunnelGetImplementation<SwXTextRange>(xRangeTunnel);
+ pCursor =
+ ::sw::UnoTunnelGetImplementation<OTextCursorHelper>(xRangeTunnel);
+ }
+
+ 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));
+ // #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
+ m_pImpl->m_EventListeners.addInterface(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
+ m_pImpl->m_EventListeners.removeInterface(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",
+ static_cast<::cppu::OWeakObject*>(this));
+ }
+
+ 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)
+{
+ 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, static_cast< cppu::OWeakObject * >(this), 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");
+}
+
+SwXFieldmark::SwXFieldmark(bool _isReplacementObject, SwDoc* pDc)
+ : SwXFieldmark_Base(pDc)
+ , m_bReplacementObject(_isReplacementObject)
+{ }
+
+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();
+}
+
+void SwXFieldmark::attachToRange( const uno::Reference < text::XTextRange >& xTextRange )
+{
+
+ attachToRangeEx( xTextRange,
+ ( m_bReplacementObject ? IDocumentMarkAccess::MarkType::CHECKBOX_FIELDMARK : IDocumentMarkAccess::MarkType::TEXT_FIELDMARK ) );
+}
+
+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();
+ if(fieldType != getFieldType())
+ {
+ if(fieldType == ODF_FORMDROPDOWN || fieldType == ODF_FORMCHECKBOX || fieldType == ODF_FORMDATE)
+ {
+ ::sw::mark::IFieldmark* pNewFieldmark = GetIDocumentMarkAccess()->changeFormFieldmarkType(pBkm, fieldType);
+ if (pNewFieldmark)
+ {
+ registerInMark(*this, pNewFieldmark);
+ return;
+ }
+ }
+
+ // We did not generate a new fieldmark, so set the type ID
+ pBkm->SetFieldname(fieldType);
+ }
+}
+
+uno::Reference<container::XNameContainer> SwXFieldmark::getParameters()
+{
+ SolarMutexGuard aGuard;
+ IFieldmark *pBkm = dynamic_cast<IFieldmark*>(GetBookmark());
+ if(!pBkm)
+ throw uno::RuntimeException();
+ return uno::Reference<container::XNameContainer>(new SwXFieldmarkParameters(pBkm));
+}
+
+uno::Reference<text::XTextContent>
+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);
+ uno::Reference<text::XTextContent> xMark;
+ if (pMarkBase)
+ {
+ xMark = pMarkBase->GetXBookmark();
+ }
+ if (!xMark.is())
+ {
+ // FIXME: These belong in XTextFieldsSupplier
+ SwXFieldmark* pXBkmk = nullptr;
+ 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.set(pXBkmk);
+ 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
+ SwXFieldmark_Base::setPropertyValue( PropertyName, rValue );
+}
+
+// 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::makeAny( pCheckboxFm->IsChecked() );
+ }
+ return SwXFieldmark_Base::getPropertyValue( rPropertyName );
+}
+
+/* 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 000000000..4b0cf5738
--- /dev/null
+++ b/sw/source/core/unocore/unochart.cxx
@@ -0,0 +1,2717 @@
+/* -*- 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 <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 <cppuhelper/supportsservice.hxx>
+#include <osl/mutex.hxx>
+#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_bIsLocked( false )
+{
+ m_aUnlockTimer.SetTimeout( 1500 );
+ m_aUnlockTimer.SetInvokeHandler( LINK( this, SwChartLockController_Helper, DoUnlockAllCharts ));
+ m_aUnlockTimer.SetDebugName( "sw::SwChartLockController_Helper aUnlockTimer" );
+}
+
+SwChartLockController_Helper::~SwChartLockController_Helper() COVERITY_NOEXCEPT_FALSE
+{
+ if (m_pDoc) // still connected?
+ 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 osl::Mutex & GetChartMutex()
+{
+ static osl::Mutex aMutex;
+ return aMutex;
+}
+
+static void LaunchModifiedEvent(
+ ::comphelper::OInterfaceContainerHelper2 &rICH,
+ const uno::Reference< uno::XInterface > &rxI )
+{
+ lang::EventObject aEvtObj( rxI );
+ comphelper::OInterfaceIteratorHelper2 aIt( rICH );
+ while (aIt.hasMoreElements())
+ {
+ uno::Reference< util::XModifyListener > xRef( aIt.next(), uno::UNO_QUERY );
+ if (xRef.is())
+ xRef->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,
+ const OUString &rCellRangeName )
+{
+ sal_Int32 nToken = -1 == rCellRangeName.indexOf('.') ? 0 : 1;
+ OUString aCellRangeNoTableName( rCellRangeName.getToken( nToken, '.' ) );
+ OUString aTLName( aCellRangeNoTableName.getToken(0, ':') ); // name of top left cell
+ OUString aBRName( aCellRangeNoTableName.getToken(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( SwFrameFormat &rTableFormat, SwUnoCursor &rTableCursor )
+{
+ OUString aRes;
+
+ //!! see also SwXTextTableCursor::getRangeName
+
+ SwUnoTableCursor* pUnoTableCursor = dynamic_cast<SwUnoTableCursor*>(&rTableCursor);
+ if (!pUnoTableCursor)
+ return OUString();
+ pUnoTableCursor->MakeBoxSels();
+
+ const SwStartNode* pStart;
+ const SwTableBox* pStartBox = nullptr;
+ const SwTableBox* pEndBox = nullptr;
+
+ pStart = pUnoTableCursor->GetPoint()->nNode.GetNode().FindTableBoxStartNode();
+ if (pStart)
+ {
+ const SwTable* pTable = SwTable::FindTable( &rTableFormat );
+ pEndBox = pTable->GetTableBox( pStart->GetIndex());
+ aRes = pEndBox->GetName();
+
+ if(pUnoTableCursor->HasMark())
+ {
+ pStart = pUnoTableCursor->GetMark()->nNode.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( const OUString &rTableName,
+ const OUString &rStartCell, const OUString &rEndCell,
+ bool bForceEndCellName )
+{
+ OSL_ENSURE( !rTableName.isEmpty(), "table name missing" );
+ OSL_ENSURE( !rStartCell.isEmpty(), "cell name missing" );
+ OUString aRes = rTableName + "." + rStartCell;
+
+ if (!rEndCell.isEmpty())
+ {
+ aRes += ":" + rEndCell;
+ }
+ else if (bForceEndCellName)
+ {
+ aRes += ":" + rStartCell;
+ }
+
+ return aRes;
+}
+
+static bool GetTableAndCellsFromRangeRep(
+ const OUString &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 aRange; // cell range
+ OUString aStartCell; // name of top left cell
+ OUString aEndCell; // name of bottom right cell
+ sal_Int32 nIdx = rRangeRepresentation.indexOf( '.' );
+ if (nIdx >= 0)
+ {
+ aTableName = rRangeRepresentation.copy( 0, nIdx );
+ aRange = rRangeRepresentation.copy( nIdx + 1 );
+ sal_Int32 nPos = aRange.indexOf( ':' );
+ if (nPos >= 0) // a cell-range like "Table1.A2:D4"
+ {
+ aStartCell = aRange.copy( 0, nPos );
+ aEndCell = aRange.copy( 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, const OUString &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,
+ const OUString &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()->nNode = *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( const OUString &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( rRangeRepresentation.getToken( 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* pSwDoc ) :
+ m_aEventListeners( GetChartMutex() ),
+ m_pDoc( pSwDoc )
+{
+ 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( sal_uLong nN = rNodes.Count(); nN--; )
+ {
+ SwNodePtr 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 = pTable->GetTabLines().front()->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)
+ {
+ sal_Int32 nFirstSeqLen = 0;
+ sal_Int32 nFirstSeqLabelIdx = -1;
+ bool bFirstFound = false;
+ for (oi = 0; oi < oiEnd; ++oi)
+ {
+ // row/col used at all?
+ if (aDataStartIdx[oi] != -1 &&
+ (!bFirstIsLabel || aLabelIdx[oi] != -1))
+ {
+ ++nNumLDS;
+ if (!bFirstFound)
+ {
+ nFirstSeqLen = aDataLen[oi];
+ nFirstSeqLabelIdx = aLabelIdx[oi];
+ bFirstFound = true;
+ }
+ else
+ {
+ if (nFirstSeqLen != aDataLen[oi] ||
+ nFirstSeqLabelIdx != aLabelIdx[oi])
+ throw lang::IllegalArgumentException();
+ }
+ }
+ }
+ }
+ 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)
+ {
+ 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 : 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(
+ const OUString &rCellRangeRepresentation )
+{
+ // check that we do not have multiple ranges
+ if (-1 == rCellRangeRepresentation.indexOf( ';' ))
+ {
+ // 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 );
+ std::sort( aSortedMapping.begin(), aSortedMapping.end() );
+ bool bNeedSequenceMapping = false;
+ for (sal_Int32 i = 0; i < aSequenceMapping.getLength(); ++i)
+ {
+ auto it = std::find( aSortedMapping.begin(), aSortedMapping.end(),
+ aSequenceMapping[i] );
+ aSequenceMapping[i] = std::distance(aSortedMapping.begin(), it);
+
+ if (i != 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);
+ sal_Int32 nProps = 0;
+ aResult[nProps ].Name = "FirstCellAsLabel";
+ aResult[nProps++].Value <<= bFirstCellIsLabel;
+ aResult[nProps ].Name = "CellRangeRepresentation";
+ aResult[nProps++].Value <<= aSortedCellRanges;
+ if (!aBrokenCellRangeForExport.isEmpty())
+ {
+ aResult[nProps ].Name = "BrokenCellRangeForExport";
+ aResult[nProps++].Value <<= aBrokenCellRangeForExport;
+ }
+ if (nDtaSrcIsColumns == 0 || nDtaSrcIsColumns == 1)
+ {
+ chart::ChartDataRowSource eDataRowSource = (nDtaSrcIsColumns == 1) ?
+ chart::ChartDataRowSource_COLUMNS : chart::ChartDataRowSource_ROWS;
+ aResult[nProps ].Name = "DataRowSource";
+ aResult[nProps++].Value <<= eDataRowSource;
+
+ if (aSequenceMapping.hasElements())
+ {
+ aResult[nProps ].Name = "SequenceMapping";
+ aResult[nProps++].Value <<= aSequenceMapping;
+ }
+ }
+ aResult.realloc( nProps );
+
+ return aResult;
+}
+
+uno::Reference< chart2::data::XDataSequence > SwChartDataProvider::Impl_createDataSequenceByRangeRepresentation(
+ const OUString& 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*/ )
+{
+ return uno::Reference<css::chart2::data::XDataSequence>();
+}
+
+void SAL_CALL SwChartDataProvider::dispose( )
+{
+ bool bMustDispose( false );
+ {
+ osl::MutexGuard aGuard( GetChartMutex() );
+ bMustDispose = !m_bDisposed;
+ if (!m_bDisposed)
+ m_bDisposed = true;
+ }
+ if (bMustDispose)
+ {
+ // 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( dynamic_cast< chart2::data::XDataProvider * >(this) );
+ m_aEventListeners.disposeAndClear( aEvtObj );
+ }
+}
+
+void SAL_CALL SwChartDataProvider::addEventListener(
+ const uno::Reference< lang::XEventListener >& rxListener )
+{
+ osl::MutexGuard aGuard( GetChartMutex() );
+ if (!m_bDisposed && rxListener.is())
+ m_aEventListeners.addInterface( rxListener );
+}
+
+void SAL_CALL SwChartDataProvider::removeEventListener(
+ const uno::Reference< lang::XEventListener >& rxListener )
+{
+ osl::MutexGuard aGuard( GetChartMutex() );
+ if (!m_bDisposed && rxListener.is())
+ m_aEventListeners.removeInterface( 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, uno::Reference< chart2::data::XDataSequence > const &rxDataSequence )
+{
+ m_aDataSequences[ &rTable ].insert( rxDataSequence );
+}
+
+void SwChartDataProvider::RemoveDataSequence( const SwTable &rTable, uno::Reference< chart2::data::XDataSequence > const &rxDataSequence )
+{
+ m_aDataSequences[ &rTable ].erase( rxDataSequence );
+}
+
+void SwChartDataProvider::InvalidateTable( const SwTable *pTable )
+{
+ OSL_ENSURE( pTable, "table pointer is NULL" );
+ if (pTable)
+ {
+ if (!m_bDisposed)
+ pTable->GetFrameFormat()->GetDoc()->getIDocumentChartDataProviderAccess().GetChartControllerHelper().StartOrContinueLocking();
+
+ const Set_DataSequenceRef_t &rSet = m_aDataSequences[ pTable ];
+ for (const auto& rItem : rSet)
+ {
+ uno::Reference< chart2::data::XDataSequence > xTemp(rItem); // temporary needed for g++ 3.3.5
+ uno::Reference< util::XModifiable > xRef( xTemp, uno::UNO_QUERY );
+ if (xRef.is())
+ {
+ // mark the sequence as 'dirty' and notify listeners
+ xRef->setModified( true );
+ }
+ }
+ }
+}
+
+void SwChartDataProvider::DeleteBox( const SwTable *pTable, const SwTableBox &rBox )
+{
+ OSL_ENSURE( pTable, "table pointer is NULL" );
+ if (pTable)
+ {
+ if (!m_bDisposed)
+ pTable->GetFrameFormat()->GetDoc()->getIDocumentChartDataProviderAccess().GetChartControllerHelper().StartOrContinueLocking();
+
+ Set_DataSequenceRef_t &rSet = m_aDataSequences[ pTable ];
+
+ // iterate over all data-sequences for that table...
+ Set_DataSequenceRef_t::iterator aIt( rSet.begin() );
+ Set_DataSequenceRef_t::iterator aEndIt( rSet.end() );
+ Set_DataSequenceRef_t::iterator aDelIt; // iterator used for deletion when appropriate
+ while (aIt != aEndIt)
+ {
+ SwChartDataSequence *pDataSeq = nullptr;
+ bool bNowEmpty = false;
+ bool bSeqDisposed = false;
+
+ // check if weak reference is still valid...
+ uno::Reference< chart2::data::XDataSequence > xTemp(*aIt);
+ if (xTemp.is())
+ {
+ // then delete that table box (check if implementation cursor needs to be adjusted)
+ pDataSeq = static_cast< SwChartDataSequence * >( xTemp.get() );
+ if (pDataSeq)
+ {
+ try
+ {
+ bNowEmpty = pDataSeq->DeleteBox( rBox );
+ }
+ catch (const lang::DisposedException&)
+ {
+ bNowEmpty = true;
+ bSeqDisposed = true;
+ }
+
+ if (bNowEmpty)
+ aDelIt = aIt;
+ }
+ }
+ ++aIt;
+
+ if (bNowEmpty)
+ {
+ rSet.erase( aDelIt );
+ if (pDataSeq && !bSeqDisposed)
+ pDataSeq->dispose(); // the current way to tell chart that sth. got removed
+ }
+ }
+ }
+}
+
+void SwChartDataProvider::DisposeAllDataSequences( const SwTable *pTable )
+{
+ OSL_ENSURE( pTable, "table pointer is NULL" );
+ if (pTable)
+ {
+ 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 Set_DataSequenceRef_t aSet( m_aDataSequences[ pTable ] );
+
+ for (const auto& rItem : aSet)
+ {
+ uno::Reference< chart2::data::XDataSequence > xTemp(rItem); // temporary needed for g++ 3.3.5
+ uno::Reference< lang::XComponent > xRef( xTemp, uno::UNO_QUERY );
+ 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)
+ {
+ 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)
+ {
+ //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 Set_DataSequenceRef_t &rSet = m_aDataSequences[ &rTable ];
+ for (const auto& rItem : rSet)
+ {
+ uno::Reference< chart2::data::XDataSequence > xTemp(rItem); // temporary needed for g++ 3.3.5
+ uno::Reference< chart2::data::XTextualDataSequence > xRef( xTemp, uno::UNO_QUERY );
+ if (xRef.is())
+ {
+ const sal_Int32 nLen = xRef->getTextualData().getLength();
+ if (nLen > 1) // value data-sequence ?
+ {
+ auto pDataSeq = comphelper::getUnoTunnelImplementation<SwChartDataSequence>(xRef);
+ if (pDataSeq)
+ {
+ 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_aEvtListeners( GetChartMutex() ),
+ m_aModifyListeners( GetChartMutex() ),
+ 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)
+ {
+ uno::Reference< chart2::data::XDataSequence > xRef( dynamic_cast< chart2::data::XDataSequence * >(this), uno::UNO_QUERY );
+ m_xDataProvider->AddDataSequence( *pTable, xRef );
+ m_xDataProvider->addEventListener( dynamic_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_aEvtListeners( GetChartMutex() ),
+ m_aModifyListeners( GetChartMutex() ),
+ 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)
+ {
+ uno::Reference< chart2::data::XDataSequence > xRef( dynamic_cast< chart2::data::XDataSequence * >(this), uno::UNO_QUERY );
+ m_xDataProvider->AddDataSequence( *pTable, xRef );
+ m_xDataProvider->addEventListener( dynamic_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()
+{
+}
+
+namespace
+{
+ class theSwChartDataSequenceUnoTunnelId : public rtl::Static< UnoTunnelIdInit, theSwChartDataSequenceUnoTunnelId > {};
+}
+
+const uno::Sequence< sal_Int8 > & SwChartDataSequence::getUnoTunnelId()
+{
+ return theSwChartDataSequenceUnoTunnelId::get().getSeq();
+}
+
+sal_Int64 SAL_CALL SwChartDataSequence::getSomething( const uno::Sequence< sal_Int8 > &rId )
+{
+ if( isUnoTunnelId<SwChartDataSequence>(rId) )
+ {
+ return sal::static_int_cast< sal_Int64 >( reinterpret_cast< sal_IntPtr >(this) );
+ }
+ return 0;
+}
+
+
+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;
+ OUString aNew;
+ if (bUseCol)
+ {
+ aRplc = "%COLUMNLETTER";
+ aNew = aCellName.copy(0, pBuf - aCellName.getStr());
+ }
+ else
+ {
+ aRplc = "%ROWNUMBER";
+ aNew = OUString(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.begin(),
+ [] (decltype(vCells)::value_type& xCell)
+ { return static_cast<SwXCell*>(xCell.get())->getString(); });
+ return vTextData;
+}
+
+uno::Sequence< uno::Any > SAL_CALL SwChartDataSequence::getData()
+{
+ SolarMutexGuard aGuard;
+ auto vCells(GetCells());
+ uno::Sequence< uno::Any > vAnyData(vCells.size());
+ std::transform(vCells.begin(),
+ vCells.end(),
+ vAnyData.begin(),
+ [] (decltype(vCells)::value_type& xCell)
+ { return static_cast<SwXCell*>(xCell.get())->GetAny(); });
+ return vAnyData;
+}
+
+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.begin(),
+ [] (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 (dynamic_cast<const sw::LegacyModifyHint*>(&rHint))
+ {
+ 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, dynamic_cast< XModifyBroadcaster * >(this) );
+}
+
+void SAL_CALL SwChartDataSequence::addModifyListener(
+ const uno::Reference< util::XModifyListener >& rxListener )
+{
+ osl::MutexGuard aGuard( GetChartMutex() );
+ if (!m_bDisposed && rxListener.is())
+ m_aModifyListeners.addInterface( rxListener );
+}
+
+void SAL_CALL SwChartDataSequence::removeModifyListener(
+ const uno::Reference< util::XModifyListener >& rxListener )
+{
+ osl::MutexGuard aGuard( GetChartMutex() );
+ if (!m_bDisposed && rxListener.is())
+ m_aModifyListeners.removeInterface( rxListener );
+}
+
+void SAL_CALL SwChartDataSequence::disposing( const lang::EventObject& rSource )
+{
+ if (m_bDisposed)
+ throw lang::DisposedException();
+ if (rSource.Source == static_cast<cppu::OWeakObject*>(m_xDataProvider.get()))
+ {
+ m_xDataProvider.clear();
+ }
+}
+
+void SAL_CALL SwChartDataSequence::dispose( )
+{
+ bool bMustDispose( false );
+ {
+ osl::MutexGuard aGuard( GetChartMutex() );
+ bMustDispose = !m_bDisposed;
+ if (!m_bDisposed)
+ m_bDisposed = true;
+ }
+ if (bMustDispose)
+ {
+ m_bDisposed = true;
+ if (m_xDataProvider.is())
+ {
+ const SwTable* pTable = SwTable::FindTable( GetFrameFormat() );
+ if (pTable)
+ {
+ uno::Reference< chart2::data::XDataSequence > xRef( dynamic_cast< chart2::data::XDataSequence * >(this), uno::UNO_QUERY );
+ m_xDataProvider->RemoveDataSequence( *pTable, xRef );
+ }
+ 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( dynamic_cast< chart2::data::XDataSequence * >(this) );
+ m_aModifyListeners.disposeAndClear( aEvtObj );
+ m_aEvtListeners.disposeAndClear( aEvtObj );
+ }
+}
+
+void SAL_CALL SwChartDataSequence::addEventListener(
+ const uno::Reference< lang::XEventListener >& rxListener )
+{
+ osl::MutexGuard aGuard( GetChartMutex() );
+ if (!m_bDisposed && rxListener.is())
+ m_aEvtListeners.addInterface( rxListener );
+}
+
+void SAL_CALL SwChartDataSequence::removeEventListener(
+ const uno::Reference< lang::XEventListener >& rxListener )
+{
+ osl::MutexGuard aGuard( GetChartMutex() );
+ if (!m_bDisposed && rxListener.is())
+ m_aEvtListeners.removeInterface( 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()->nNode.GetNode().FindTableBoxStartNode();
+ const SwStartNode* pMarkStartNode = m_pTableCursor->GetMark()->nNode.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->nNode = aNewPos.nNode;
+ pPos->nContent = aNewPos.nContent;
+ }
+ 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()->nNode.GetNode().FindTableBoxStartNode();
+ pEndBox = pTable->GetTableBox( pStartNd->GetIndex() );
+ const OUString aEndBox( pEndBox->GetName() );
+
+ pStartNd = pUnoTableCursor->GetMark()->nNode.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
+ FillRangeDescriptor( aDesc, aStartBox + ":" + aEndBox );
+
+ 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()->nNode = *pNewEndBox->GetSttNd();
+ pUnoTableCursor->GetMark()->nNode = *pNewStartBox->GetSttNd();
+ pUnoTableCursor->Move( fnMoveForward, GoInNode );
+ pUnoTableCursor->MakeBoxSels();
+ }
+}
+
+SwChartLabeledDataSequence::SwChartLabeledDataSequence() :
+ m_aEventListeners( GetChartMutex() ),
+ m_aModifyListeners( GetChartMutex() )
+{
+ 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( dynamic_cast< util::XModifyListener* >(this), uno::UNO_QUERY );
+ uno::Reference< lang::XEventListener > xEL( dynamic_cast< lang::XEventListener* >(this), uno::UNO_QUERY );
+
+ // 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, dynamic_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, dynamic_cast< XModifyBroadcaster * >(this) );
+ }
+}
+
+uno::Reference< util::XCloneable > SAL_CALL SwChartLabeledDataSequence::createClone( )
+{
+ SolarMutexGuard aGuard;
+ if (m_bDisposed)
+ throw lang::DisposedException();
+
+ uno::Reference< util::XCloneable > xRes;
+
+ uno::Reference< util::XCloneable > xDataCloneable( m_xData, uno::UNO_QUERY );
+ uno::Reference< util::XCloneable > xLabelsCloneable( m_xLabels, uno::UNO_QUERY );
+ 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 );
+ }
+ xRes = pRes;
+ return xRes;
+}
+
+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 )
+{
+ osl::MutexGuard 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())
+ dispose();
+}
+
+void SAL_CALL SwChartLabeledDataSequence::modified(
+ const lang::EventObject& rEvent )
+{
+ if (rEvent.Source == m_xData || rEvent.Source == m_xLabels)
+ {
+ LaunchModifiedEvent( m_aModifyListeners, dynamic_cast< XModifyBroadcaster * >(this) );
+ }
+}
+
+void SAL_CALL SwChartLabeledDataSequence::addModifyListener(
+ const uno::Reference< util::XModifyListener >& rxListener )
+{
+ osl::MutexGuard aGuard( GetChartMutex() );
+ if (!m_bDisposed && rxListener.is())
+ m_aModifyListeners.addInterface( rxListener );
+}
+
+void SAL_CALL SwChartLabeledDataSequence::removeModifyListener(
+ const uno::Reference< util::XModifyListener >& rxListener )
+{
+ osl::MutexGuard aGuard( GetChartMutex() );
+ if (!m_bDisposed && rxListener.is())
+ m_aModifyListeners.removeInterface( rxListener );
+}
+
+void SAL_CALL SwChartLabeledDataSequence::dispose( )
+{
+ bool bMustDispose( false );
+ {
+ osl::MutexGuard 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( dynamic_cast< chart2::data::XLabeledDataSequence * >(this) );
+ m_aModifyListeners.disposeAndClear( aEvtObj );
+ m_aEventListeners.disposeAndClear( aEvtObj );
+ }
+}
+
+void SAL_CALL SwChartLabeledDataSequence::addEventListener(
+ const uno::Reference< lang::XEventListener >& rxListener )
+{
+ osl::MutexGuard aGuard( GetChartMutex() );
+ if (!m_bDisposed && rxListener.is())
+ m_aEventListeners.addInterface( rxListener );
+}
+
+void SAL_CALL SwChartLabeledDataSequence::removeEventListener(
+ const uno::Reference< lang::XEventListener >& rxListener )
+{
+ osl::MutexGuard aGuard( GetChartMutex() );
+ if (!m_bDisposed && rxListener.is())
+ m_aEventListeners.removeInterface( 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 000000000..9965a5b9c
--- /dev/null
+++ b/sw/source/core/unocore/unocoll.cxx
@@ -0,0 +1,1941 @@
+/* -*- 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 <svtools/unoimap.hxx>
+#include <svtools/unoevent.hxx>
+#include <unotbl.hxx>
+#include <unostyle.hxx>
+#include <unofield.hxx>
+#include <unoidx.hxx>
+#include <unoframe.hxx>
+#include <textboxhelper.hxx>
+#include <unofootnote.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 <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>
+
+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 );
+ 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::makeAny( 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( 2 );
+ aArgs[0] <<= uno::Reference< uno::XInterface >();
+ aArgs[1] <<= 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::makeAny( 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 }
+};
+
+const SvEventDescription* sw_GetSupportedMacroItems()
+{
+ static const SvEventDescription aMacroDescriptionsImpl[] =
+ {
+ { SvMacroItemId::OnMouseOver, "OnMouseOver" },
+ { SvMacroItemId::OnMouseOut, "OnMouseOut" },
+ { SvMacroItemId::NONE, nullptr }
+ };
+
+ return aMacroDescriptionsImpl;
+}
+
+OUString SwXServiceProvider::GetProviderName(SwServiceType nObjectType)
+{
+ SolarMutexGuard aGuard;
+ 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(const OUString& rServiceName)
+{
+ for(const ProvNamesId_Type & i : aProvNamesId)
+ {
+ if (rServiceName.equalsAscii(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 = SwXTextTable::CreateXTextTable(nullptr);
+ }
+ break;
+ case SwServiceType::TypeTextFrame:
+ {
+ xRet = SwXTextFrame::CreateXTextFrame(rDoc, nullptr);
+ }
+ break;
+ case SwServiceType::TypeGraphic :
+ case SwServiceType::TypeTextGraphic /* #i47503# */ :
+ {
+ xRet = SwXTextGraphicObject::CreateXTextGraphicObject(rDoc, nullptr);
+
+ }
+ break;
+ case SwServiceType::TypeOLE :
+ {
+ xRet = SwXTextEmbeddedObject::CreateXTextEmbeddedObject(rDoc, nullptr);
+ }
+ break;
+ case SwServiceType::TypeBookmark :
+ {
+ xRet = SwXBookmark::CreateXBookmark(rDoc, nullptr);
+ }
+ break;
+ case SwServiceType::TypeFieldMark :
+ {
+ xRet = SwXFieldmark::CreateXFieldmark(rDoc, nullptr);
+ }
+ break;
+ case SwServiceType::TypeFormFieldMark :
+ {
+ xRet = SwXFieldmark::CreateXFieldmark(rDoc, nullptr, true);
+ }
+ break;
+ case SwServiceType::VbaObjectProvider :
+#if HAVE_FEATURE_SCRIPTING
+ {
+ SwVbaObjectForCodeNameProvider* pObjProv =
+ new SwVbaObjectForCodeNameProvider(rDoc.GetDocShell());
+ xRet = static_cast<cppu::OWeakObject*>(pObjProv);
+ }
+#endif
+ break;
+ case SwServiceType::VbaCodeNameProvider :
+#if HAVE_FEATURE_SCRIPTING
+ {
+ if (rDoc.GetDocShell() && ooo::vba::isAlienWordDoc(*rDoc.GetDocShell()))
+ {
+ SwVbaCodeNameProvider* pObjProv = new SwVbaCodeNameProvider(rDoc.GetDocShell());
+ xRet = static_cast<cppu::OWeakObject*>(pObjProv);
+ }
+ }
+#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(1);
+ aArgs[ 0 ] <<= rDoc.GetDocShell()->GetModel();
+ aGlobs <<= ::comphelper::getProcessServiceFactory()->createInstanceWithArguments( "ooo.vba.word.Globals", aArgs );
+ pBasicMan->SetGlobalUNOConstant( "VBAGlobals", aGlobs );
+ }
+ aGlobs >>= xRet;
+ }
+#endif
+ break;
+
+ case SwServiceType::TypeFootnote :
+ xRet = SwXFootnote::CreateXFootnote(rDoc, nullptr);
+ break;
+ case SwServiceType::TypeEndnote :
+ xRet = SwXFootnote::CreateXFootnote(rDoc, nullptr, true);
+ 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 = SwXDocumentIndexMark::CreateXDocumentIndexMark(rDoc, nullptr, eType);
+ }
+ 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 = SwXDocumentIndex::CreateXDocumentIndex(rDoc, nullptr, eType);
+ }
+ break;
+ case SwServiceType::IndexHeaderSection :
+ case SwServiceType::TextSection :
+ xRet = SwXTextSection::CreateXTextSection(nullptr,
+ (SwServiceType::IndexHeaderSection == nObjectType));
+
+ break;
+ case SwServiceType::ReferenceMark :
+ xRet = SwXReferenceMark::CreateXReferenceMark(rDoc, nullptr);
+ 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 = SwXTextField::CreateXTextField(nullptr, nullptr, nObjectType);
+ break;
+ case SwServiceType::FieldTypeAnnotation:
+ xRet = SwXTextField::CreateXTextField(&rDoc, nullptr, nObjectType);
+ 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 = SwXFieldMaster::CreateXFieldMaster(&rDoc, nullptr, nResId);
+ }
+ break;
+ case SwServiceType::FieldMasterBibliography:
+ {
+ SwFieldType* pType = rDoc.getIDocumentFieldsAccess().GetFieldType(SwFieldIds::TableOfAuthorities, OUString(), true);
+ if(!pType)
+ {
+ SwAuthorityFieldType aType(&rDoc);
+ pType = rDoc.getIDocumentFieldsAccess().InsertFieldType(aType);
+ }
+ xRet = SwXFieldMaster::CreateXFieldMaster(&rDoc, pType);
+ }
+ break;
+ case SwServiceType::Paragraph:
+ xRet = SwXParagraph::CreateXParagraph(rDoc, nullptr);
+ break;
+ case SwServiceType::NumberingRules:
+ xRet = static_cast<cppu::OWeakObject*>(new SwXNumberingRules(rDoc));
+ break;
+ case SwServiceType::TextColumns:
+ xRet = static_cast<cppu::OWeakObject*>(new SwXTextColumns);
+ break;
+ case SwServiceType::Defaults:
+ xRet = static_cast<cppu::OWeakObject*>(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 = static_cast<cppu::OWeakObject*>(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 = SwXMeta::CreateXMeta(rDoc, false);
+ break;
+ case SwServiceType::FieldTypeMetafield:
+ xRet = SwXMeta::CreateXMeta(rDoc, true);
+ 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;
+ uno::Any aRet;
+ if (!IsValid())
+ throw uno::RuntimeException();
+
+ if (nInputIndex < 0)
+ throw IndexOutOfBoundsException();
+
+ SwAutoFormatGetDocNode aGetHt( &GetDoc()->GetNodes() );
+ size_t nIndex = static_cast<size_t>(nInputIndex);
+ size_t nCurrentIndex = 0;
+
+ for (SwFrameFormat* const & pFormat : *GetDoc()->GetTableFrameFormats())
+ {
+ if (!pFormat->GetInfo(aGetHt))
+ {
+ if (nCurrentIndex == nIndex)
+ {
+ uno::Reference<XTextTable> xTable = SwXTextTables::GetObject(*pFormat);
+ aRet <<= xTable;
+ return aRet;
+ }
+ else
+ nCurrentIndex++;
+ }
+ }
+ throw IndexOutOfBoundsException();
+}
+
+uno::Any SwXTextTables::getByName(const OUString& rItemName)
+{
+ SolarMutexGuard aGuard;
+ uno::Any aRet;
+ if(!IsValid())
+ throw uno::RuntimeException();
+
+ 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;
+ if(!IsValid())
+ throw uno::RuntimeException();
+ 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;
+ if(!IsValid())
+ throw uno::RuntimeException();
+
+ 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;
+ if(!IsValid())
+ throw uno::RuntimeException();
+ 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::makeAny(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::makeAny(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::makeAny(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* const pDoc);
+
+ //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* const pDoc)
+ : m_aFrames()
+{
+ SolarMutexGuard aGuard;
+ const SwFrameFormats* const pFormats = pDoc->GetSpzFrameFormats();
+ if(pFormats->empty())
+ return;
+ // #i104937#
+ const size_t nSize = pFormats->size();
+ // #i104937#
+ SwFrameFormat* pFormat( nullptr );
+ for( size_t i = 0; i < nSize; ++i )
+ {
+ // #i104937#
+ pFormat = (*pFormats)[i];
+ 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 = pDoc->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;
+ if(!IsValid())
+ throw uno::RuntimeException();
+ 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;
+ if(!IsValid())
+ throw uno::RuntimeException();
+ // 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(!IsValid())
+ throw uno::RuntimeException();
+ 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;
+ if(!IsValid())
+ throw uno::RuntimeException();
+ 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;
+ if(!IsValid())
+ throw uno::RuntimeException();
+ 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;
+ if(!IsValid())
+ throw uno::RuntimeException();
+ 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;
+ if(!IsValid())
+ throw uno::RuntimeException();
+ 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;
+ if(!IsValid())
+ throw uno::RuntimeException();
+ 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)
+{
+ SolarMutexGuard aGuard;
+ uno::Reference< XTextSection > xRet;
+ if(!IsValid())
+ throw uno::RuntimeException();
+
+ SwSectionFormats& rFormats = GetDoc()->GetSections();
+
+ const SwSectionFormats& rSectFormats = GetDoc()->GetSections();
+ const size_t nCount = rSectFormats.size();
+ for(size_t i = 0; i < nCount; ++i)
+ {
+ if( !rSectFormats[i]->IsInNodesArr())
+ nIndex ++;
+ else if(static_cast<size_t>(nIndex) == i)
+ break;
+ if(static_cast<size_t>(nIndex) == i)
+ break;
+ }
+ if(!(nIndex >= 0 && o3tl::make_unsigned(nIndex) < rFormats.size()))
+ throw IndexOutOfBoundsException();
+
+ SwSectionFormat* pFormat = rFormats[nIndex];
+ xRet = GetObject(*pFormat);
+
+ return makeAny(xRet);
+}
+
+uno::Any SwXTextSections::getByName(const OUString& rName)
+{
+ SolarMutexGuard aGuard;
+ uno::Any aRet;
+ if(!IsValid())
+ throw uno::RuntimeException();
+
+ 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;
+ if(!IsValid())
+ throw uno::RuntimeException();
+ size_t nCount = GetDoc()->GetSections().size();
+ SwSectionFormats& rSectFormats = GetDoc()->GetSections();
+ for(size_t i = nCount; i; --i)
+ {
+ if( !rSectFormats[i - 1]->IsInNodesArr())
+ nCount--;
+ }
+
+ uno::Sequence<OUString> aSeq(nCount);
+ if(nCount)
+ {
+ SwSectionFormats& rFormats = GetDoc()->GetSections();
+ OUString* pArray = aSeq.getArray();
+ size_t nIndex = 0;
+ for( size_t i = 0; i < nCount; ++i, ++nIndex)
+ {
+ const SwSectionFormat* pFormat = rFormats[nIndex];
+ while(!pFormat->IsInNodesArr())
+ {
+ pFormat = rFormats[++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;
+ if(!IsValid())
+ throw uno::RuntimeException();
+
+ 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;
+ if(!IsValid())
+ throw uno::RuntimeException();
+
+ 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;
+ if(!IsValid())
+ throw uno::RuntimeException();
+ IDocumentMarkAccess* const pMarkAccess = GetDoc()->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(*GetDoc(), *ppMark);
+ aRet <<= xRef;
+ return aRet;
+ }
+ ++count; // only count real bookmarks
+ }
+ }
+ throw IndexOutOfBoundsException();
+}
+
+uno::Any SwXBookmarks::getByName(const OUString& rName)
+{
+ SolarMutexGuard aGuard;
+ if(!IsValid())
+ throw uno::RuntimeException();
+
+ IDocumentMarkAccess* const pMarkAccess = GetDoc()->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(*GetDoc(), *ppBkmk);
+ aRet <<= xRef;
+ return aRet;
+}
+
+uno::Sequence< OUString > SwXBookmarks::getElementNames()
+{
+ SolarMutexGuard aGuard;
+ if(!IsValid())
+ throw uno::RuntimeException();
+
+ 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;
+ if(!IsValid())
+ throw uno::RuntimeException();
+
+ 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;
+ if(!IsValid())
+ throw uno::RuntimeException();
+
+ 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;
+ if(!IsValid())
+ throw uno::RuntimeException();
+ return GetDoc()->GetNumRuleTable().size();
+}
+
+uno::Any SwXNumberingRulesCollection::getByIndex(sal_Int32 nIndex)
+{
+ SolarMutexGuard aGuard;
+ uno::Any aRet;
+ if(!IsValid())
+ throw uno::RuntimeException();
+
+ uno::Reference< XIndexReplace > xRef;
+ if ( o3tl::make_unsigned(nIndex) < GetDoc()->GetNumRuleTable().size() )
+ {
+ xRef = new SwXNumberingRules( *GetDoc()->GetNumRuleTable()[ nIndex ], GetDoc());
+ aRet <<= xRef;
+ }
+
+ if(!xRef.is())
+ throw IndexOutOfBoundsException();
+
+ return aRet;
+}
+
+uno::Type SAL_CALL SwXNumberingRulesCollection::getElementType()
+{
+ return cppu::UnoType<XIndexReplace>::get();
+}
+
+sal_Bool SwXNumberingRulesCollection::hasElements()
+{
+ SolarMutexGuard aGuard;
+ if(!IsValid())
+ throw uno::RuntimeException();
+ 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;
+ if(!IsValid())
+ throw uno::RuntimeException();
+ sal_Int32 nCount = 0;
+ const size_t nFootnoteCnt = GetDoc()->GetFootnoteIdxs().size();
+ SwTextFootnote* pTextFootnote;
+ for( size_t n = 0; n < nFootnoteCnt; ++n )
+ {
+ pTextFootnote = GetDoc()->GetFootnoteIdxs()[ 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;
+ if(!IsValid())
+ throw uno::RuntimeException();
+
+ const size_t nFootnoteCnt = GetDoc()->GetFootnoteIdxs().size();
+ SwTextFootnote* pTextFootnote;
+ uno::Reference< XFootnote > xRef;
+ for( size_t n = 0; n < nFootnoteCnt; ++n )
+ {
+ pTextFootnote = GetDoc()->GetFootnoteIdxs()[ n ];
+ const SwFormatFootnote& rFootnote = pTextFootnote->GetFootnote();
+ if ( rFootnote.IsEndNote() != m_bEndnote )
+ continue;
+
+ if(nCount == nIndex)
+ {
+ xRef = SwXFootnote::CreateXFootnote(*GetDoc(),
+ &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;
+ if(!IsValid())
+ throw uno::RuntimeException();
+ 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;
+ if(!IsValid())
+ throw uno::RuntimeException();
+ return GetDoc()->GetRefMarks();
+}
+
+uno::Any SwXReferenceMarks::getByIndex(sal_Int32 nIndex)
+{
+ SolarMutexGuard aGuard;
+ uno::Any aRet;
+ if(!IsValid())
+ throw uno::RuntimeException();
+ uno::Reference< XTextContent > xRef;
+ if(0 <= nIndex && nIndex < SAL_MAX_UINT16)
+ {
+ SwFormatRefMark *const pMark = const_cast<SwFormatRefMark*>(
+ GetDoc()->GetRefMark(static_cast<sal_uInt16>(nIndex)));
+ if(pMark)
+ {
+ xRef = SwXReferenceMark::CreateXReferenceMark(*GetDoc(), pMark);
+ aRet <<= xRef;
+ }
+ }
+ if(!xRef.is())
+ throw IndexOutOfBoundsException();
+ return aRet;
+}
+
+uno::Any SwXReferenceMarks::getByName(const OUString& rName)
+{
+ SolarMutexGuard aGuard;
+ uno::Any aRet;
+ if(!IsValid())
+ throw uno::RuntimeException();
+
+ SwFormatRefMark *const pMark =
+ const_cast<SwFormatRefMark*>(GetDoc()->GetRefMark(rName));
+ if(!pMark)
+ throw NoSuchElementException();
+
+ uno::Reference<XTextContent> const xRef =
+ SwXReferenceMark::CreateXReferenceMark(*GetDoc(), pMark);
+ aRet <<= xRef;
+
+ return aRet;
+}
+
+uno::Sequence< OUString > SwXReferenceMarks::getElementNames()
+{
+ SolarMutexGuard aGuard;
+ uno::Sequence<OUString> aRet;
+ if(!IsValid())
+ throw uno::RuntimeException();
+
+ 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;
+ if(!IsValid())
+ throw uno::RuntimeException();
+ return nullptr != GetDoc()->GetRefMark( rName);
+}
+
+uno::Type SAL_CALL SwXReferenceMarks::getElementType()
+{
+ return cppu::UnoType<XTextContent>::get();
+}
+
+sal_Bool SwXReferenceMarks::hasElements()
+{
+ SolarMutexGuard aGuard;
+ if(!IsValid())
+ throw uno::RuntimeException();
+ return 0 != GetDoc()->GetRefMarks();
+}
+
+void SwUnoCollection::Invalidate()
+{
+ m_bObjectValid = false;
+ m_pDoc = nullptr;
+}
+
+/* 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 000000000..76bdb939b
--- /dev/null
+++ b/sw/source/core/unocore/unocrsr.cxx
@@ -0,0 +1,214 @@
+/* -*- 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* pDoc = GetDoc();
+ if( !pDoc->IsInDtor() )
+ {
+ assert(!m_aNotifier.HasListeners());
+ }
+
+ // delete the whole ring
+ while( GetNext() != this )
+ {
+ Ring* pNxt = GetNextInRing();
+ pNxt->MoveTo(nullptr); // remove from chain
+ delete pNxt; // and delete
+ }
+}
+
+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* pDoc = GetDoc();
+ SwNodeIndex aOldIdx( *pDoc->GetNodes()[ GetSavePos()->nNode ] );
+ SwNodeIndex& rPtIdx = GetPoint()->nNode;
+ SwStartNode *pOldSttNd = aOldIdx.GetNode().StartOfSectionNode(),
+ *pNewSttNd = rPtIdx.GetNode().StartOfSectionNode();
+ if( pOldSttNd != pNewSttNd )
+ {
+ bool bMoveDown = GetSavePos()->nNode < rPtIdx.GetIndex();
+ 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( rPtIdx > *pOldSttNd &&
+ rPtIdx < pOldSttNd->EndOfSectionIndex() )
+ {
+ // check if it a valid move inside this section
+ // (only over SwSection's !)
+ const SwStartNode* pInvalidNode;
+ do {
+ pInvalidNode = nullptr;
+ pNewSttNd = rPtIdx.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 )
+ {
+ rPtIdx.Assign( *pInvalidNode->EndOfSectionNode(), 1 );
+
+ if( !rPtIdx.GetNode().IsContentNode() &&
+ ( !pDoc->GetNodes().GoNextSection( &rPtIdx ) ||
+ rPtIdx > pOldSttNd->EndOfSectionIndex() ) )
+ break;
+ }
+ else
+ {
+ rPtIdx.Assign( *pInvalidNode, -1 );
+
+ if( !rPtIdx.GetNode().IsContentNode() &&
+ ( !SwNodes::GoPrevSection( &rPtIdx ) ||
+ rPtIdx < *pOldSttNd ) )
+ break;
+ }
+ }
+ else
+ bValidPos = true;
+ } while ( pInvalidNode );
+ }
+
+ if( bValidPos )
+ {
+ SwContentNode* pCNd = GetContentNode();
+ GetPoint()->nContent.Assign( pCNd, (pCNd && !bMoveDown) ? pCNd->Len() : 0);
+ }
+ else
+ {
+ rPtIdx = GetSavePos()->nNode;
+ GetPoint()->nContent.Assign( GetContentNode(), 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()->nNode.GetNode().FindTableNode();
+ bRet = !(pTNd == GetDoc()->GetNodes()[ GetSavePos()->nNode ]->
+ FindTableNode() && (!HasMark() ||
+ pTNd == GetMark()->nNode.GetNode().FindTableNode() ));
+ }
+ return bRet;
+}
+
+void SwUnoTableCursor::MakeBoxSels()
+{
+ const SwContentNode* pCNd;
+ bool bMakeTableCursors = true;
+ if( GetPoint()->nNode.GetIndex() && GetMark()->nNode.GetIndex() &&
+ nullptr != ( pCNd = GetContentNode() ) && pCNd->getLayoutFrame( pCNd->GetDoc()->getIDocumentLayoutAccess().GetCurrentLayout() ) &&
+ nullptr != ( pCNd = GetContentNode(false) ) && 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()->nNode.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 000000000..a82e7a1c2
--- /dev/null
+++ b/sw/source/core/unocore/unocrsrhelper.cxx
@@ -0,0 +1,1507 @@
+/* -*- 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 <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 <docary.hxx>
+#include <swtable.hxx>
+#include <tox.hxx>
+#include <doctxm.hxx>
+#include <fchrfmt.hxx>
+#include <editeng/editids.hrc>
+#include <editeng/flstitem.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(
+ ::sw::UnoTunnelGetImplementation<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);
+ if (!xTunnel.is()) // everything below needs tunnel
+ {
+ return;
+ }
+
+ SwXShape *const pShape(::sw::UnoTunnelGetImplementation<SwXShape>(xTunnel));
+ if (pShape)
+ {
+ uno::Reference<uno::XAggregation> const xAgg(
+ pShape->GetAggregationInterface());
+ if (xAgg.is())
+ {
+ SvxShape *const pSvxShape(
+ ::sw::UnoTunnelGetImplementation<SvxShape>(xTunnel));
+ 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;
+ }
+
+ OTextCursorHelper *const pCursor(
+ ::sw::UnoTunnelGetImplementation<OTextCursorHelper>(xTunnel));
+ if (pCursor)
+ {
+ if (pCursor->GetDoc() == &rTargetDoc)
+ {
+ o_rpPaM = lcl_createPamCopy(*pCursor->GetPaM());
+ }
+ return;
+ }
+
+ SwXTextRanges* const pRanges(
+ ::sw::UnoTunnelGetImplementation<SwXTextRanges>(xTunnel));
+ 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(
+ ::sw::UnoTunnelGetImplementation<SwXFrame>(xTunnel));
+ 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(
+ ::sw::UnoTunnelGetImplementation<SwXTextTable>(xTunnel));
+ if (pTextTable)
+ {
+ SwFrameFormat *const pFrameFormat(pTextTable->GetFrameFormat());
+ if (pFrameFormat && pFrameFormat->GetDoc() == &rTargetDoc)
+ {
+ o_rTableName = pFrameFormat->GetName();
+ }
+ return;
+ }
+
+ SwXCell *const pCell(
+ ::sw::UnoTunnelGetImplementation<SwXCell>(xTunnel));
+ 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)
+ {
+ SwPosition const aPos(*pBox->GetSttNd());
+ SwPaM aPam(aPos);
+ 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(
+ ::sw::UnoTunnelGetImplementation<SwXCellRange>(xTunnel));
+ 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, xTunnel));
+ 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
+ SwTextNode::GetTextAttrMode const eMode( bParent
+ ? SwTextNode::PARENT : SwTextNode::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();
+ }
+ SfxItemSet const& rSet(*pFormat->GetStyleHandle());
+ 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& rEntry : rMap.getPropertyEntries())
+ {
+ if (rPropSet.getPropertyState(rEntry, rSet) == PropertyState_DIRECT_VALUE)
+ {
+ Any value;
+ rPropSet.getPropertyValue(rEntry, rSet, value);
+ props.emplace_back(rEntry.sName, value);
+ }
+ }
+ return uno::makeAny(comphelper::containerToSequence(props));
+}
+
+// Read the special properties of the cursor
+bool getCursorPropertyValue(const SfxItemPropertySimpleEntry& 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.GetNode().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.GetNode().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.GetNode().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.GetNode().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.GetNode().IsTextNode())
+ {
+ marks = rPam.GetNode().GetTextNode()->GetTextAttrsAt(
+ rPam.GetPoint()->nContent.GetIndex(), 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->nNode.GetIndex()]->GetTextNode();
+ const SwTextAttr* pTextAttr = pTextNd
+ ? pTextNd->GetFieldTextAttrAt( pPos->nContent.GetIndex(), true )
+ : 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.GetNode().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.GetNode().StartOfSectionNode();
+ SwStartNodeType eType = pSttNode->GetStartNodeType();
+
+ SwFrameFormat* pFormat;
+ if(eType == SwFlyStartNode && nullptr != (pFormat = pSttNode->GetFlyFormat()))
+ {
+ if( pAny )
+ {
+ 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()->nNode.GetNode().GetTextNode();
+ if (pTextNode)
+ {
+ if (pAny)
+ {
+ uno::Reference<text::XTextContent> xParagraph = SwXParagraph::CreateXParagraph(*pTextNode->GetDoc(), pTextNode);
+ *pAny <<= xParagraph;
+ }
+ }
+ else
+ eNewState = PropertyState_DEFAULT_VALUE;
+ }
+ break;
+ case FN_UNO_ENDNOTE:
+ case FN_UNO_FOOTNOTE:
+ {
+ SwTextAttr *const pTextAttr = rPam.GetNode().IsTextNode() ?
+ rPam.GetNode().GetTextNode()->GetTextAttrForCharAt(
+ rPam.GetPoint()->nContent.GetIndex(), 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.GetNode().IsTextNode())
+ {
+ marks = rPam.GetNode().GetTextNode()->GetTextAttrsAt(
+ rPam.GetPoint()->nContent.GetIndex(), 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.GetNode().IsTextNode()
+ ? GetNestedTextContent(*rPam.GetNode().GetTextNode(),
+ rPam.GetPoint()->nContent.GetIndex(), false)
+ : nullptr);
+ if (xRet.is())
+ {
+ if (pAny)
+ {
+ (*pAny) <<= xRet;
+ }
+ }
+ else
+ {
+ eNewState = PropertyState_DEFAULT_VALUE;
+ }
+ }
+ break;
+ case FN_UNO_CHARFMT_SEQUENCE:
+ {
+
+ SwTextNode *const pTextNode = rPam.GetNode().GetTextNode();
+ if (&rPam.GetNode() == &rPam.GetNode(false)
+ && pTextNode && pTextNode->GetpSwpHints())
+ {
+ sal_Int32 nPaMStart = rPam.GetPoint()->nContent.GetIndex();
+ sal_Int32 nPaMEnd = rPam.GetMark() ? rPam.GetMark()->nContent.GetIndex() : nPaMStart;
+ if(nPaMStart > nPaMEnd)
+ {
+ std::swap(nPaMStart, nPaMEnd);
+ }
+ 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.GetNode().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 = comphelper::getUnoTunnelImplementation<SwXNumberingRules>(xIndexReplace);
+ if(pSwNum)
+ {
+ SwDoc* pDoc = 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 = pDoc->GetCharFormats()->size();
+ SwCharFormat* pCharFormat = nullptr;
+ for(size_t nCharFormat = 0; nCharFormat < nChCount; ++nCharFormat)
+ {
+ SwCharFormat& rChFormat = *((*(pDoc->GetCharFormats()))[nCharFormat]);
+ if(rChFormat.GetName() == pNewCharStyles[i])
+ {
+ pCharFormat = &rChFormat;
+ break;
+ }
+ }
+
+ if(!pCharFormat)
+ {
+ SfxStyleSheetBasePool* pPool = pDoc->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* >(pDoc->GetDocShell()
+ ->GetItem( SID_ATTR_CHAR_FONTLIST ));
+ const FontList* pList = pFontListItem->GetFontList();
+
+ FontMetric aFontMetric = pList->Get(
+ pBulletFontNames[i],WEIGHT_NORMAL, ITALIC_NONE);
+ vcl::Font aFont(aFontMetric);
+ aFormat.SetBulletFont(&aFont);
+ }
+ aRule.Set( i, aFormat );
+ }
+ UnoActionContext aAction(pDoc);
+
+ if( rPam.GetNext() != &rPam ) // Multiple selection?
+ {
+ pDoc->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
+ pDoc->SetNumRule( aRangeArr.SetPam( n, aPam ), aRule, false );
+ }
+ pDoc->GetIDocumentUndoRedo().EndUndo( SwUndoId::END, nullptr );
+ }
+ else
+ {
+ // no start of a new list
+ pDoc->SetNumRule( rPam, aRule, false );
+ }
+
+ }
+ else if(!pSwNum->GetCreatedNumRuleName().isEmpty())
+ {
+ UnoActionContext aAction( pDoc );
+ SwNumRule* pRule = pDoc->FindNumRulePtr( pSwNum->GetCreatedNumRuleName() );
+ if ( !pRule )
+ throw RuntimeException();
+ // no start of a new list
+ pDoc->SetNumRule( rPam, *pRule, false );
+ }
+ else
+ {
+ // #i103817#
+ // outline numbering
+ UnoActionContext aAction(pDoc);
+ SwNumRule* pRule = pDoc->GetOutlineNumRule();
+ if(!pRule)
+ throw RuntimeException();
+ pDoc->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.GetContentNode())
+ 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.GetContentNode()->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 SfxItemPropertySimpleEntry& rEntry, SwPaM& rPam)
+{
+ SwDoc* pDoc = 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(pDoc);
+
+ if( rPam.GetNext() != &rPam ) // Multiple selection?
+ {
+ pDoc->GetIDocumentUndoRedo().StartUndo( SwUndoId::START, nullptr );
+ SwPamRanges aRangeArr( rPam );
+ SwPaM aPam( *rPam.GetPoint() );
+ for( size_t n = 0; n < aRangeArr.Count(); ++n )
+ pDoc->SetNodeNumStart( *aRangeArr.SetPam( n, aPam ).GetPoint(), 1 );
+ pDoc->GetIDocumentUndoRedo().EndUndo( SwUndoId::END, nullptr );
+ }
+ else
+ pDoc->SetNodeNumStart( *rPam.GetPoint(), 0 );
+ }
+
+ break;
+ case FN_UNO_NUM_LEVEL :
+ break;
+ case FN_UNO_NUM_RULES:
+ break;
+ case FN_UNO_CHARFMT_SEQUENCE:
+ {
+ std::set<sal_uInt16> aWhichIds;
+ aWhichIds.insert( RES_TXTATR_CHARFMT);
+ pDoc->ResetAttrs(rPam, true, aWhichIds);
+ }
+ break;
+ }
+}
+
+void InsertFile(SwUnoCursor* pUnoCursor, const OUString& rURL,
+ const uno::Sequence< beans::PropertyValue >& rOptions)
+{
+ std::unique_ptr<SfxMedium> pMed;
+ SwDoc* pDoc = pUnoCursor->GetDoc();
+ SwDocShell* pDocSh = pDoc->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( 2 );
+ aArgs[0] <<= xInputStream;
+ aArgs[1] <<= 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?
+ {
+ SwReaderPtr pRdr;
+ SfxItemSet* pSet = pMed->GetItemSet();
+ pSet->Put(SfxBoolItem(FN_API_CALL, true));
+ if(!sPassword.isEmpty())
+ pSet->Put(SfxStringItem(SID_PASSWORD, sPassword));
+ Reader *pRead = pDocSh->StartConvertFrom( *pMed, pRdr, nullptr, pUnoCursor);
+ if( pRead )
+ {
+
+ UnoActionContext aContext(pDoc);
+
+ if(pUnoCursor->HasMark())
+ pDoc->getIDocumentContentOperations().DeleteAndJoin(*pUnoCursor);
+
+ SwNodeIndex aSave( pUnoCursor->GetPoint()->nNode, -1 );
+ sal_Int32 nContent = pUnoCursor->GetPoint()->nContent.GetIndex();
+
+ ErrCode nErrno = pRdr->Read( *pRead ); // and paste the document
+
+ if(!nErrno)
+ {
+ ++aSave;
+ pUnoCursor->SetMark();
+ pUnoCursor->GetMark()->nNode = aSave;
+
+ SwContentNode* pCntNode = aSave.GetNode().GetContentNode();
+ if( !pCntNode )
+ nContent = 0;
+ pUnoCursor->GetMark()->nContent.Assign( pCntNode, 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,
+ const OUString &rText,
+ const bool bForceExpandHints )
+{
+ bool bOK = true;
+
+ for (sal_Int32 i = 0; i < rText.getLength(); ++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()->nNode.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();
+
+ sal_Int32 nIdx = rText.indexOf( '\r', nStartIdx );
+ if( ( nIdx == -1 && nMaxLength < rText.getLength() ) ||
+ ( nIdx != -1 && nMaxLength < nIdx ) )
+ {
+ nIdx = nMaxLength;
+ }
+ while (nIdx != -1 )
+ {
+ OSL_ENSURE( nIdx - nStartIdx >= 0, "index negative!" );
+ aText = rText.copy( 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.indexOf( '\r', nStartIdx );
+ }
+ aText = rText.copy( 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,
+ const OUString& rRedlineType,
+ const uno::Sequence< beans::PropertyValue >& rRedlineProperties )
+{
+ IDocumentRedlineAccess* pRedlineAccess = &rPaM.GetDoc()->getIDocumentRedlineAccess();
+
+ RedlineType eType;
+ if ( rRedlineType == "Insert" )
+ eType = RedlineType::Insert;
+ else if ( rRedlineType == "Delete" )
+ eType = RedlineType::Delete;
+ else if ( rRedlineType == "Format" )
+ eType = RedlineType::Format;
+ else if ( rRedlineType == "TextTable" )
+ eType = RedlineType::Table;
+ else if ( rRedlineType == "ParagraphFormat" )
+ eType = RedlineType::ParagraphFormat;
+ else
+ throw lang::IllegalArgumentException();
+
+ //todo: what about REDLINE_FMTCOLL?
+ 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( aStamp));
+ }
+
+ std::unique_ptr<SwRedlineExtraData_FormatColl> xRedlineExtraData;
+
+ // Read the 'Redline Revert Properties' from the parameters
+ uno::Sequence< beans::PropertyValue > aRevertProperties;
+ // Check if the value exists
+ if ( aPropMap.getValue("RedlineRevertProperties") >>= aRevertProperties )
+ {
+ 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 *const pDoc = rPaM.GetDoc();
+
+ // Build set of attributes we want to fetch
+ std::vector<sal_uInt16> aWhichPairs;
+ std::vector<SfxItemPropertySimpleEntry 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;
+ SfxItemPropertySimpleEntry const* pEntry = rPropSet.getPropertyMap().getByName(rPropertyName);
+
+ if (!pEntry)
+ {
+ // unknown property
+ break;
+ }
+ else if (pEntry->nFlags & beans::PropertyAttribute::READONLY)
+ {
+ break;
+ }
+ else if (rPropertyName == "NumberingRules")
+ {
+ aWhichPairs.push_back(RES_PARATR_NUMRULE);
+ aWhichPairs.push_back(RES_PARATR_NUMRULE);
+ nNumId = aEntries.size();
+ }
+ else
+ {
+ // FIXME: we should have some nice way of merging ranges surely ?
+ aWhichPairs.push_back(pEntry->nWID);
+ aWhichPairs.push_back(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;
+ aWhichPairs.push_back(0); // terminate
+ SfxItemSet aItemSet(pDoc->GetAttrPool(), aWhichPairs.data());
+
+ for (size_t i = 0; i < aEntries.size(); ++i)
+ {
+ SfxItemPropertySimpleEntry const*const pEntry = aEntries[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 = pDoc->FindNumRulePtr(
+ xNumberingRules->getName());
+ if (pRule)
+ pRule->SetUsedByRedline(true);
+ }
+ }
+ else
+ {
+ rPropSet.setPropertyValue(*pEntry, rValue, aItemSet);
+ if (i == nStyleId)
+ rValue >>= sParaStyleName;
+ }
+ }
+
+ if (eType == RedlineType::ParagraphFormat && sParaStyleName.isEmpty())
+ nStylePoolId = RES_POOLCOLL_STANDARD;
+
+ xRedlineExtraData.reset(new SwRedlineExtraData_FormatColl( sParaStyleName, nStylePoolId, &aItemSet ));
+ }
+ else if (eType == RedlineType::ParagraphFormat)
+ xRedlineExtraData.reset(new SwRedlineExtraData_FormatColl( "", RES_POOLCOLL_STANDARD, nullptr ));
+ }
+ }
+
+ SwRangeRedline* pRedline = new SwRangeRedline( aRedlineData, rPaM );
+ RedlineFlags nPrevMode = pRedlineAccess->GetRedlineFlags( );
+ // xRedlineExtraData is copied here
+ pRedline->SetExtraData( xRedlineExtraData.get() );
+
+ pRedlineAccess->SetRedlineFlags_intern(RedlineFlags::On);
+ auto const result(pRedlineAccess->AppendRedline(pRedline, false));
+ pRedlineAccess->SetRedlineFlags_intern( nPrevMode );
+ if (IDocumentRedlineAccess::AppendResult::IGNORED == result)
+ throw lang::IllegalArgumentException();
+}
+
+void makeTableRowRedline( SwTableLine& rTableLine,
+ const OUString& rRedlineType,
+ const uno::Sequence< beans::PropertyValue >& rRedlineProperties )
+{
+ IDocumentRedlineAccess* pRedlineAccess = &rTableLine.GetFrameFormat()->GetDoc()->getIDocumentRedlineAccess();
+
+ RedlineType eType;
+ if ( rRedlineType == "TableRowInsert" )
+ {
+ eType = RedlineType::TableRowInsert;
+ }
+ else if ( rRedlineType == "TableRowDelete" )
+ {
+ eType = RedlineType::TableRowDelete;
+ }
+ else
+ {
+ throw lang::IllegalArgumentException();
+ }
+
+ 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,
+ const OUString& rRedlineType,
+ const uno::Sequence< beans::PropertyValue >& rRedlineProperties )
+{
+ IDocumentRedlineAccess* pRedlineAccess = &rTableBox.GetFrameFormat()->GetDoc()->getIDocumentRedlineAccess();
+
+ RedlineType eType;
+ if ( rRedlineType == "TableCellInsert" )
+ {
+ eType = RedlineType::TableCellInsert;
+ }
+ else if ( rRedlineType == "TableCellDelete" )
+ {
+ eType = RedlineType::TableCellDelete;
+ }
+ else
+ {
+ throw lang::IllegalArgumentException();
+ }
+
+ 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 000000000..3c1949063
--- /dev/null
+++ b/sw/source/core/unocore/unodraw.cxx
@@ -0,0 +1,2854 @@
+/* -*- 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 <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 <svx/shapepropertynotifier.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 <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/IndexOutOfBoundsException.hpp>
+
+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 bOpaque;
+ uno::Reference< text::XTextRange > 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:
+ bool bInitializedPropertyNotifier;
+
+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.
+ , bOpaque(false)
+ // #i26791#
+ , m_pFollowTextFlow( new SwFormatFollowTextFlow(false) )
+ // #i28701# #i35017#
+ , m_pWrapInfluenceOnObjPos( new SwFormatWrapInfluenceOnObjPos(
+ text::WrapInfluenceOnPosition::ONCE_CONCURRENT) )
+ // #i28749#
+ , mnPositionLayoutDir(text::PositionLayoutDir::PositionInLayoutDirOfAnchor)
+ , bInitializedPropertyNotifier(false)
+ {}
+
+ 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 xTextRange;
+ }
+ bool IsOpaque() const
+ {
+ return bOpaque;
+ }
+ const bool& GetOpaque() const
+ {
+ return 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){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( SdrPage* pPage ) :
+ SvxFmDrawPage( pPage ), pPageView(nullptr)
+{
+}
+
+SwFmDrawPage::~SwFmDrawPage() throw ()
+{
+ 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(!pPageView)
+ pPageView = mpView->ShowSdrPage( mpPage );
+ return pPageView;
+}
+
+void SwFmDrawPage::RemovePageView()
+{
+ if(pPageView && mpView)
+ mpView->HideSdrPage();
+ pPageView = nullptr;
+}
+
+uno::Reference<drawing::XShape> SwFmDrawPage::GetShape(SdrObject* pObj)
+{
+ if(!pObj)
+ return nullptr;
+ SwFrameFormat* pFormat = ::FindFrameFormat( pObj );
+ SwFmDrawPage* pPage = dynamic_cast<SwFmDrawPage*>(pFormat);
+ if(!pPage || pPage->m_vShapes.empty())
+ return uno::Reference<drawing::XShape>(pObj->getUnoShape(), uno::UNO_QUERY);
+ for(auto pShape : pPage->m_vShapes)
+ {
+ SvxShape* pSvxShape = pShape->GetSvxShape();
+ if (pSvxShape && pSvxShape->GetSdrObject() == pObj)
+ return uno::Reference<drawing::XShape>(static_cast<::cppu::OWeakObject*>(pShape), uno::UNO_QUERY);
+ }
+ 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(SwXTextFrame::CreateXTextFrame(*pDoc, pFlyFormat),
+ uno::UNO_QUERY);
+ }
+ else if( pNd->IsGrfNode() )
+ {
+ xRet.set(SwXTextGraphicObject::CreateXTextGraphicObject(
+ *pDoc, pFlyFormat), uno::UNO_QUERY);
+ }
+ else if( pNd->IsOLENode() )
+ {
+ xRet.set(SwXTextEmbeddedObject::CreateXTextEmbeddedObject(
+ *pDoc, pFlyFormat), 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 = SvxFmDrawPage::CreateShape( pObj );
+ }
+ uno::Reference< XUnoTunnel > xShapeTunnel(xRet, uno::UNO_QUERY);
+ //don't create an SwXShape if it already exists
+ SwXShape* pShape = nullptr;
+ if(xShapeTunnel.is())
+ pShape = reinterpret_cast< SwXShape * >(
+ sal::static_int_cast< sal_IntPtr >( xShapeTunnel->getSomething(SwXShape::getUnoTunnelId()) ));
+ if(!pShape)
+ {
+ xShapeTunnel = nullptr;
+ uno::Reference< uno::XInterface > xCreate(xRet, uno::UNO_QUERY);
+ xRet = nullptr;
+ if ( pObj->IsGroupObject() && (!pObj->Is3DObj() || (dynamic_cast<const E3dScene*>( pObj) != nullptr)) )
+ pShape = new SwXGroupShape(xCreate, nullptr);
+ else
+ pShape = new SwXShape(xCreate, nullptr);
+ uno::Reference<beans::XPropertySet> xPrSet = pShape;
+ xRet.set(xPrSet, uno::UNO_QUERY);
+ }
+ const_cast<std::vector<SwXShape*>*>(&m_vShapes)->push_back(pShape);
+ pShape->m_pPage = this;
+ }
+ return xRet;
+}
+
+namespace
+{
+ class SwXShapesEnumeration
+ : public SwSimpleEnumeration_Base
+ {
+ private:
+ std::vector< css::uno::Any > m_aShapes;
+ protected:
+ virtual ~SwXShapesEnumeration() override {};
+ public:
+ explicit SwXShapesEnumeration(SwXDrawPage* 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(SwXDrawPage* const pDrawPage)
+ : m_aShapes()
+{
+ 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::makeAny(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 > SwXDrawPage::createEnumeration()
+{
+ SolarMutexGuard aGuard;
+ return uno::Reference< container::XEnumeration >(
+ new SwXShapesEnumeration(this));
+}
+
+OUString SwXDrawPage::getImplementationName()
+{
+ return "SwXDrawPage";
+}
+
+sal_Bool SwXDrawPage::supportsService(const OUString& rServiceName)
+{
+ return cppu::supportsService(this, rServiceName);
+}
+
+uno::Sequence< OUString > SwXDrawPage::getSupportedServiceNames()
+{
+ return { "com.sun.star.drawing.GenericDrawPage" };
+}
+
+SwXDrawPage::SwXDrawPage(SwDoc* pDc) :
+ pDoc(pDc),
+ pDrawPage(nullptr)
+{
+}
+
+SwXDrawPage::~SwXDrawPage()
+{
+ if(xPageAgg.is())
+ {
+ uno::Reference< uno::XInterface > xInt;
+ xPageAgg->setDelegator(xInt);
+ }
+}
+
+uno::Any SwXDrawPage::queryInterface( const uno::Type& aType )
+{
+ uno::Any aRet = SwXDrawPageBaseClass::queryInterface(aType);
+ if(!aRet.hasValue())
+ {
+ // secure with checking if page exists. This may not be the case
+ // either for new SW docs with no yet graphics usage or when
+ // the doc is closed and someone else still holds a UNO reference
+ // to the XDrawPage (in that case, pDoc is set to 0)
+ SwFmDrawPage* pPage = GetSvxPage();
+
+ if(pPage)
+ {
+ aRet = pPage->queryAggregation(aType);
+ }
+ }
+ return aRet;
+}
+
+uno::Sequence< uno::Type > SwXDrawPage::getTypes()
+{
+ return comphelper::concatSequences(
+ SwXDrawPageBaseClass::getTypes(),
+ GetSvxPage()->getTypes(),
+ uno::Sequence { cppu::UnoType<form::XFormsSupplier2>::get() });
+}
+
+sal_Int32 SwXDrawPage::getCount()
+{
+ SolarMutexGuard aGuard;
+ if(!pDoc)
+ throw uno::RuntimeException();
+ if(!pDoc->getIDocumentDrawModelAccess().GetDrawModel())
+ return 0;
+ else
+ {
+ GetSvxPage();
+ return SwTextBoxHelper::getCount(pDrawPage->GetSdrPage());
+ }
+}
+
+uno::Any SwXDrawPage::getByIndex(sal_Int32 nIndex)
+{
+ SolarMutexGuard aGuard;
+ if(!pDoc)
+ throw uno::RuntimeException();
+ if(!pDoc->getIDocumentDrawModelAccess().GetDrawModel())
+ throw lang::IndexOutOfBoundsException();
+
+ GetSvxPage();
+ return SwTextBoxHelper::getByIndex(pDrawPage->GetSdrPage(), nIndex);
+}
+
+uno::Type SwXDrawPage::getElementType()
+{
+ return cppu::UnoType<drawing::XShape>::get();
+}
+
+sal_Bool SwXDrawPage::hasElements()
+{
+ SolarMutexGuard aGuard;
+ if(!pDoc)
+ throw uno::RuntimeException();
+ if(!pDoc->getIDocumentDrawModelAccess().GetDrawModel())
+ return false;
+ else
+ return GetSvxPage()->hasElements();
+}
+
+void SwXDrawPage::add(const uno::Reference< drawing::XShape > & xShape)
+{
+ SolarMutexGuard aGuard;
+ if(!pDoc)
+ throw uno::RuntimeException();
+ uno::Reference< lang::XUnoTunnel > xShapeTunnel(xShape, uno::UNO_QUERY);
+ SwXShape* pShape = nullptr;
+ SvxShape* pSvxShape = nullptr;
+ if(xShapeTunnel.is())
+ {
+ pShape = reinterpret_cast< SwXShape * >(
+ sal::static_int_cast< sal_IntPtr >( xShapeTunnel->getSomething(SwXShape::getUnoTunnelId()) ));
+ pSvxShape = reinterpret_cast< SvxShape * >(
+ sal::static_int_cast< sal_IntPtr >( xShapeTunnel->getSomething(SvxShape::getUnoTunnelId()) ));
+ }
+
+ // this is not a writer shape
+ if(!pShape)
+ throw uno::RuntimeException("illegal object",
+ static_cast< cppu::OWeakObject * > ( this ) );
+
+ // we're already registered in the model / SwXDrawPage::add() already called
+ if(pShape->m_pPage || pShape->m_pFormat || !pShape->m_bDescriptor )
+ return;
+
+ // we're inserted elsewhere already
+ if ( pSvxShape->GetSdrObject() )
+ {
+ if ( pSvxShape->GetSdrObject()->IsInserted() )
+ {
+ return;
+ }
+ }
+ GetSvxPage()->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();
+
+ SfxItemSet aSet( pDoc->GetAttrPool(), svl::Items<RES_FRMATR_BEGIN,
+ RES_FRMATR_END-1>{} );
+ 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 = convertMm100ToTwip(aMM100Pos.X);
+ 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 = convertMm100ToTwip(aMM100Pos.Y);
+ 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 ? pDoc->getIDocumentDrawModelAccess().GetInvisibleHeavenId() : pDoc->getIDocumentDrawModelAccess().GetInvisibleHellId() );
+ else
+ pObj->SetLayer(pDoc->getIDocumentDrawModelAccess().GetInvisibleControlsId());
+
+ std::unique_ptr<SwPaM> pPam(new SwPaM(pDoc->GetNodes().GetEndOfContent()));
+ std::unique_ptr<SwUnoInternalPaM> pInternalPam;
+ uno::Reference< text::XTextRange > xRg;
+ if( pDesc && (xRg = pDesc->GetTextRange()).is() )
+ {
+ pInternalPam.reset(new SwUnoInternalPaM(*pDoc));
+ if (!::sw::XTextRangeToSwPaM(*pInternalPam, xRg))
+ throw uno::RuntimeException();
+
+ if(RndStdIds::FLY_AT_FLY == aAnchor.GetAnchorId() &&
+ !pInternalPam->GetNode().FindFlyStartNode())
+ {
+ aAnchor.SetType(RndStdIds::FLY_AS_CHAR);
+ }
+ else if (RndStdIds::FLY_AT_PAGE == aAnchor.GetAnchorId())
+ {
+ aAnchor.SetAnchor(pInternalPam->Start());
+ }
+
+ }
+ else if ((aAnchor.GetAnchorId() != RndStdIds::FLY_AT_PAGE) && pDoc->getIDocumentLayoutAccess().GetCurrentLayout())
+ {
+ SwCursorMoveState aState( CursorMoveState::SetOnlyText );
+ Point aTmp(convertMm100ToTwip(aMM100Pos.X), convertMm100ToTwip(aMM100Pos.Y));
+ 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.get();
+ UnoActionContext aAction(pDoc);
+ pDoc->getIDocumentContentOperations().InsertDrawObj( *pTemp, *pObj, aSet );
+
+ if (pSvxShape->GetSdrObject()->GetName().isEmpty())
+ {
+ pSvxShape->GetSdrObject()->SetName(pDoc->GetUniqueShapeName());
+ }
+
+ SwFrameFormat* pFormat = ::FindFrameFormat( pObj );
+ if (pFormat)
+ {
+ if (pFormat->GetName().isEmpty())
+ {
+ pFormat->SetName(pSvxShape->GetSdrObject()->GetName(), false);
+ }
+ pShape->SetFrameFormat(pFormat);
+ }
+ pShape->m_bDescriptor = false;
+
+ pPam.reset();
+ pInternalPam.reset();
+}
+
+void SwXDrawPage::remove(const uno::Reference< drawing::XShape > & xShape)
+{
+ SolarMutexGuard aGuard;
+ if(!pDoc)
+ throw uno::RuntimeException();
+ uno::Reference<lang::XComponent> xComp(xShape, uno::UNO_QUERY);
+ xComp->dispose();
+}
+
+uno::Reference< drawing::XShapeGroup > SwXDrawPage::group(const uno::Reference< drawing::XShapes > & xShapes)
+{
+ SolarMutexGuard aGuard;
+ if(!pDoc || !xShapes.is())
+ throw uno::RuntimeException();
+ uno::Reference< drawing::XShapeGroup > xRet;
+ if(xPageAgg.is())
+ {
+
+ SwFmDrawPage* pPage = GetSvxPage();
+ if(pPage) //TODO: can this be Null?
+ {
+ // mark and return MarkList
+ const SdrMarkList& rMarkList = pPage->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 uno::RuntimeException(); // FlyInCnt!
+ }
+ }
+
+ UnoActionContext aContext(pDoc);
+ pDoc->GetIDocumentUndoRedo().StartUndo( SwUndoId::START, nullptr );
+
+ SwDrawContact* pContact = pDoc->GroupSelection( *pPage->GetDrawView() );
+ pDoc->ChgAnchor(
+ pPage->GetDrawView()->GetMarkedObjectList(),
+ RndStdIds::FLY_AT_PARA,
+ true, false );
+
+ pPage->GetDrawView()->UnmarkAll();
+ if(pContact)
+ xRet = SwFmDrawPage::GetShapeGroup( pContact->GetMaster() );
+ pDoc->GetIDocumentUndoRedo().EndUndo( SwUndoId::END, nullptr );
+ }
+ pPage->RemovePageView();
+ }
+ }
+ return xRet;
+}
+
+void SwXDrawPage::ungroup(const uno::Reference< drawing::XShapeGroup > & rShapeGroup)
+{
+ SolarMutexGuard aGuard;
+ if(!pDoc)
+ throw uno::RuntimeException();
+ if(xPageAgg.is())
+ {
+ SwFmDrawPage* pPage = GetSvxPage();
+ if(pPage) //TODO: can this be Null?
+ {
+ pPage->PreUnGroup(rShapeGroup);
+ UnoActionContext aContext(pDoc);
+ pDoc->GetIDocumentUndoRedo().StartUndo( SwUndoId::START, nullptr );
+
+ pDoc->UnGroupSelection( *pPage->GetDrawView() );
+ pDoc->ChgAnchor( pPage->GetDrawView()->GetMarkedObjectList(),
+ RndStdIds::FLY_AT_PARA,
+ true, false );
+ pDoc->GetIDocumentUndoRedo().EndUndo( SwUndoId::END, nullptr );
+ pPage->RemovePageView();
+ }
+ }
+}
+
+SwFmDrawPage* SwXDrawPage::GetSvxPage()
+{
+ if(!xPageAgg.is() && pDoc)
+ {
+ SolarMutexGuard aGuard;
+ // #i52858#
+ SwDrawModel* pModel = pDoc->getIDocumentDrawModelAccess().GetOrCreateDrawModel();
+ SdrPage* pPage = pModel->GetPage( 0 );
+
+ {
+ // We need a Ref to the object during queryInterface or else
+ // it will be deleted
+ pDrawPage = new SwFmDrawPage(pPage);
+ uno::Reference< drawing::XDrawPage > xPage = pDrawPage;
+ uno::Any aAgg = xPage->queryInterface(cppu::UnoType<uno::XAggregation>::get());
+ aAgg >>= xPageAgg;
+ }
+ if( xPageAgg.is() )
+ xPageAgg->setDelegator( static_cast<cppu::OWeakObject*>(this) );
+ }
+ return pDrawPage;
+}
+
+/**
+ * Renamed and outlined to detect where it's called
+ */
+void SwXDrawPage::InvalidateSwDoc()
+{
+ pDoc = nullptr;
+}
+
+namespace
+{
+ class theSwXShapeUnoTunnelId : public rtl::Static< UnoTunnelIdInit, theSwXShapeUnoTunnelId > {};
+}
+
+const uno::Sequence< sal_Int8 > & SwXShape::getUnoTunnelId()
+{
+ return theSwXShapeUnoTunnelId::get().getSeq();
+}
+
+sal_Int64 SAL_CALL SwXShape::getSomething( const uno::Sequence< sal_Int8 >& rId )
+{
+ if( isUnoTunnelId<SwXShape>(rId) )
+ {
+ return sal::static_int_cast< sal_Int64 >( reinterpret_cast< sal_IntPtr >(this) );
+ }
+
+ if( xShapeAgg.is() )
+ {
+ const uno::Type& rTunnelType = cppu::UnoType<lang::XUnoTunnel>::get();
+ uno::Any aAgg = xShapeAgg->queryAggregation( rTunnelType );
+ if(auto xAggTunnel = o3tl::tryAccess<uno::Reference<lang::XUnoTunnel>>(
+ aAgg))
+ {
+ if(xAggTunnel->is())
+ return (*xAggTunnel)->getSomething(rId);
+ }
+ }
+ return 0;
+}
+namespace
+{
+ void lcl_addShapePropertyEventFactories( SdrObject& _rObj, SwXShape& _rShape )
+ {
+ auto pProvider = std::make_shared<svx::PropertyValueProvider>( _rShape, "AnchorType" );
+ _rObj.getShapePropertyChangeNotifier().registerProvider( svx::ShapeProperty::TextDocAnchor, pProvider );
+ }
+}
+
+SwXShape::SwXShape(
+ uno::Reference<uno::XInterface> & xShape,
+ SwDoc const*const pDoc)
+ : m_pPage(nullptr)
+ , m_pFormat(nullptr)
+ , m_pPropSet(aSwMapProvider.GetPropertySet(PROPERTY_MAP_TEXT_SHAPE))
+ , m_pPropertyMapEntries(aSwMapProvider.GetPropertyMapEntries(PROPERTY_MAP_TEXT_SHAPE))
+ , 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 >>= xShapeAgg;
+ // #i31698#
+ if ( xShapeAgg.is() )
+ {
+ 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( xShapeAgg.is() )
+ xShapeAgg->setDelegator( static_cast<cppu::OWeakObject*>(this) );
+ osl_atomic_decrement(&m_refCount);
+
+ SvxShape* pShape = comphelper::getUnoTunnelImplementation<SvxShape>(xShapeAgg);
+
+ SdrObject* pObj = pShape ? pShape->GetSdrObject() : nullptr;
+ if(pObj)
+ {
+ auto pFormat = ::FindFrameFormat( pObj );
+ if(pFormat)
+ SetFrameFormat(pFormat);
+
+ lcl_addShapePropertyEventFactories( *pObj, *this );
+ pImpl->bInitializedPropertyNotifier = true;
+ }
+
+}
+
+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::getUnoTunnelImplementation<SwXShape>(pCurrent->getWeakUnoShape());
+ if ( pSwShape )
+ {
+ if ( pSwShape->m_bDescriptor )
+ {
+ auto pFormat = ::FindFrameFormat( pCurrent );
+ if ( pFormat )
+ pSwShape->SetFrameFormat(pFormat);
+ pSwShape->m_bDescriptor = false;
+ }
+
+ if ( !pSwShape->pImpl->bInitializedPropertyNotifier )
+ {
+ lcl_addShapePropertyEventFactories( *pCurrent, *pSwShape );
+ pSwShape->pImpl->bInitializedPropertyNotifier = true;
+ }
+ }
+ }
+}
+
+SwXShape::~SwXShape()
+{
+ SolarMutexGuard aGuard;
+ if (xShapeAgg.is())
+ {
+ uno::Reference< uno::XInterface > xRef;
+ xShapeAgg->setDelegator(xRef);
+ }
+ pImpl.reset();
+ EndListeningAll();
+ if(m_pPage)
+ const_cast<SwFmDrawPage*>(m_pPage)->RemoveShape(this);
+ m_pPage = nullptr;
+}
+
+uno::Any SwXShape::queryInterface( const uno::Type& aType )
+{
+ uno::Any aRet = SwTextBoxHelper::queryInterface(GetFrameFormat(), aType);
+ 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() && xShapeAgg.is())
+ {
+ if(aType == cppu::UnoType<XShape>::get())
+ aRet <<= uno::Reference<XShape>(this);
+ else
+ aRet = xShapeAgg->queryAggregation(aType);
+ }
+ return aRet;
+}
+
+uno::Sequence< uno::Type > SwXShape::getTypes( )
+{
+ uno::Sequence< uno::Type > aRet = SwXShapeBaseClass::getTypes();
+ if(xShapeAgg.is())
+ {
+ uno::Any aProv = 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;
+ uno::Reference< beans::XPropertySetInfo > aRet;
+ if(xShapeAgg.is())
+ {
+ const uno::Type& rPropSetType = cppu::UnoType<beans::XPropertySet>::get();
+ uno::Any aPSet = 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();
+ aRet = new SfxExtItemPropertySetInfo( m_pPropertyMapEntries, aPropSeq );
+ }
+ }
+ if(!aRet.is())
+ aRet = m_pPropSet->getPropertySetInfo();
+ return aRet;
+}
+
+void SwXShape::setPropertyValue(const OUString& rPropertyName, const uno::Any& aValue)
+{
+ SolarMutexGuard aGuard;
+ SwFrameFormat* pFormat = GetFrameFormat();
+ const SfxItemPropertySimpleEntry* pEntry = m_pPropSet->getPropertyMap().getByName( rPropertyName );
+ if(xShapeAgg.is())
+ {
+ if(pEntry)
+ {
+ if ( pEntry->nFlags & beans::PropertyAttribute::READONLY)
+ throw beans::PropertyVetoException ("Property is read-only: " + rPropertyName, static_cast < cppu::OWeakObject * > ( this ) );
+ // 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 = comphelper::getUnoTunnelImplementation<SwXFrame>(xFrame);
+ if(pFrame && pFrame->GetFrameFormat() &&
+ pFrame->GetFrameFormat()->GetDoc() == pDoc)
+ {
+ UnoActionContext aCtx(pDoc);
+ SfxItemSet aItemSet( pDoc->GetAttrPool(),
+ svl::Items<RES_FRMATR_BEGIN, RES_FRMATR_END - 1>{} );
+ 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.
+ const SwPosition *pPos = aAnchor.GetContentAnchor();
+ SwTextNode *pTextNode = pPos->nNode.GetNode().GetTextNode();
+ SAL_WARN_IF( !pTextNode->HasHints(), "sw.uno", "Missing FlyInCnt-Hint." );
+ const sal_Int32 nIdx = pPos->nContent.GetIndex();
+ 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->GetNode().GetTextNode();
+ SAL_WARN_IF( !pNd, "sw.uno", "Cursor not at TextNode." );
+ SwFormatFlyCnt aFormat( pFormat );
+ pNd->InsertItem(aFormat, pInternalPam->GetPoint()
+ ->nContent.GetIndex(), 0 );
+ }
+ else
+ {
+ aAnchor.SetAnchor( pInternalPam->GetPoint() );
+ aSet.Put(aAnchor);
+ pFormat->SetFormatAttr(aSet);
+ }
+ }
+ else if (pEntry->nWID == FN_TEXT_BOX)
+ {
+ bool bValue(false);
+ aValue >>= bValue;
+ if (bValue)
+ SwTextBoxHelper::create(pFormat);
+ else
+ SwTextBoxHelper::destroy(pFormat);
+
+ }
+ 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);
+ }
+ // #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.
+ const SwPosition *pPos = rOldAnchor.GetContentAnchor();
+ SwTextNode *pTextNode = pPos->nNode.GetNode().GetTextNode();
+ SAL_WARN_IF( !pTextNode->HasHints(), "sw.uno", "Missing FlyInCnt-Hint." );
+ const sal_Int32 nIdx = pPos->nContent.GetIndex();
+ 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( dynamic_cast< const SwFormatAnchor& >( 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.GetNode().GetTextNode();
+ SAL_WARN_IF( !pNd, "sw.uno", "Cursor is not in a TextNode." );
+ SwFormatFlyCnt aFormat( pFlyFormat );
+ pNd->InsertItem(aFormat,
+ aPam.GetPoint()->nContent.GetIndex(), 0 );
+ --aPam.GetPoint()->nContent; // InsertItem moved it
+ SwFormatAnchor aNewAnchor(
+ dynamic_cast<const SwFormatAnchor&>(
+ aSet.Get(RES_ANCHOR)));
+ aNewAnchor.SetAnchor( aPam.GetPoint() );
+ aSet.Put( aNewAnchor );
+ }
+ if( bSetAttr )
+ pFormat->SetFormatAttr(aSet);
+ }
+ 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);
+ }
+ else
+ {
+ SfxPoolItem* pItem = nullptr;
+ switch(pEntry->nWID)
+ {
+ case RES_ANCHOR:
+ pItem = pImpl->GetAnchor(true);
+ break;
+ case RES_HORI_ORIENT:
+ pItem = pImpl->GetHOrient(true);
+ break;
+ case RES_VERT_ORIENT:
+ pItem = pImpl->GetVOrient(true);
+ break;
+ case RES_LR_SPACE:
+ pItem = pImpl->GetLRSpace(true);
+ break;
+ case RES_UL_SPACE:
+ pItem = pImpl->GetULSpace(true);
+ break;
+ case RES_SURROUND:
+ pItem = pImpl->GetSurround(true);
+ break;
+ case FN_TEXT_RANGE:
+ if(auto tr = o3tl::tryAccess<
+ uno::Reference<text::XTextRange>>(aValue))
+ {
+ uno::Reference< text::XTextRange > & rRange = pImpl->GetTextRange();
+ rRange = *tr;
+ }
+ break;
+ case RES_OPAQUE :
+ pImpl->SetOpaque(*o3tl::doAccess<bool>(aValue));
+ break;
+ // #i26791#
+ case RES_FOLLOW_TEXT_FLOW:
+ {
+ pItem = pImpl->GetFollowTextFlow( true );
+ }
+ break;
+ // #i28701#
+ case RES_WRAP_INFLUENCE_ON_OBJPOS:
+ {
+ pItem = pImpl->GetWrapInfluenceOnObjPos( true );
+ }
+ break;
+ // #i28749#
+ case FN_SHAPE_POSITION_LAYOUT_DIR :
+ {
+ sal_Int16 nPositionLayoutDir = 0;
+ aValue >>= nPositionLayoutDir;
+ pImpl->SetPositionLayoutDir( nPositionLayoutDir );
+ }
+ break;
+ }
+ if(pItem)
+ pItem->PutValue(aValue, pEntry->nMemberId);
+ }
+ }
+ else
+ {
+ const uno::Type& rPSetType =
+ cppu::UnoType<beans::XPropertySet>::get();
+ uno::Any aPSet = 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);
+ }
+
+ // #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(xShapeAgg.is())
+ {
+ const SfxItemPropertySimpleEntry* 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.GetContentAnchor() )
+ {
+ const uno::Reference< text::XTextRange > xTextRange
+ = SwXTextRange::CreateXTextRange(
+ *pFormat->GetDoc(),
+ *aAnchor.GetContentAnchor(),
+ nullptr );
+ aRet <<= xTextRange;
+ }
+ else
+ {
+ // return nothing
+ uno::Any aAny;
+ aRet = aAny;
+ }
+ }
+ }
+ else if (pEntry->nWID == FN_TEXT_BOX)
+ {
+ bool bValue = SwTextBoxHelper::isTextBox(pFormat, RES_DRAWFRMFMT);
+ aRet <<= bValue;
+ }
+ 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 = pImpl->GetAnchor();
+ break;
+ case RES_HORI_ORIENT:
+ pItem = pImpl->GetHOrient();
+ break;
+ case RES_VERT_ORIENT:
+ pItem = pImpl->GetVOrient();
+ break;
+ case RES_LR_SPACE:
+ pItem = pImpl->GetLRSpace();
+ break;
+ case RES_UL_SPACE:
+ pItem = pImpl->GetULSpace();
+ break;
+ case RES_SURROUND:
+ pItem = pImpl->GetSurround();
+ break;
+ case FN_TEXT_RANGE :
+ aRet <<= pImpl->GetTextRange();
+ break;
+ case RES_OPAQUE :
+ aRet <<= pImpl->GetOpaque();
+ break;
+ case FN_ANCHOR_POSITION :
+ {
+ aRet <<= awt::Point();
+ }
+ break;
+ // #i26791#
+ case RES_FOLLOW_TEXT_FLOW :
+ {
+ pItem = pImpl->GetFollowTextFlow();
+ }
+ break;
+ // #i28701#
+ case RES_WRAP_INFLUENCE_ON_OBJPOS:
+ {
+ pItem = 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 <<= 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 = 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(!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 SfxItemPropertySimpleEntry* 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))
+ 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 = pImpl->GetAnchor();
+ break;
+ case RES_HORI_ORIENT:
+ pItem = pImpl->GetHOrient();
+ break;
+ case RES_VERT_ORIENT:
+ pItem = pImpl->GetVOrient();
+ break;
+ case RES_LR_SPACE:
+ pItem = pImpl->GetLRSpace();
+ break;
+ case RES_UL_SPACE:
+ pItem = pImpl->GetULSpace();
+ break;
+ case RES_SURROUND:
+ pItem = pImpl->GetSurround();
+ break;
+ // #i28701#
+ case RES_WRAP_INFLUENCE_ON_OBJPOS:
+ {
+ pItem = 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 = 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(!xShapeAgg.is())
+ throw uno::RuntimeException();
+
+ const SfxItemPropertySimpleEntry* pEntry = m_pPropSet->getPropertyMap().getByName( rPropertyName );
+ if(pEntry)
+ {
+ if ( pEntry->nFlags & beans::PropertyAttribute::READONLY)
+ throw uno::RuntimeException("Property is read-only: " + rPropertyName, static_cast < cppu::OWeakObject * > ( this ) );
+ 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: pImpl->RemoveAnchor(); break;
+ case RES_HORI_ORIENT: pImpl->RemoveHOrient(); break;
+ case RES_VERT_ORIENT: pImpl->RemoveVOrient(); break;
+ case RES_LR_SPACE: pImpl->RemoveLRSpace(); break;
+ case RES_UL_SPACE: pImpl->RemoveULSpace(); break;
+ case RES_SURROUND: pImpl->RemoveSurround();break;
+ case RES_OPAQUE : pImpl->SetOpaque(false); break;
+ case FN_TEXT_RANGE :
+ break;
+ // #i26791#
+ case RES_FOLLOW_TEXT_FLOW:
+ {
+ pImpl->RemoveFollowTextFlow();
+ }
+ break;
+ // #i28701#
+ case RES_WRAP_INFLUENCE_ON_OBJPOS:
+ {
+ pImpl->RemoveWrapInfluenceOnObjPos();
+ }
+ break;
+ }
+ }
+ }
+ else
+ {
+ const uno::Type& rPStateType = cppu::UnoType<XPropertyState>::get();
+ uno::Any aPState = 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(!xShapeAgg.is())
+ throw uno::RuntimeException();
+
+ const SfxItemPropertySimpleEntry* 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 = 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 ( !xShapeAgg.is() )
+ throw uno::RuntimeException("no shape aggregate", *this );
+
+ // must be handled by the aggregate
+ uno::Reference< beans::XPropertySet > xShapeProps;
+ if ( 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 ( !xShapeAgg.is() )
+ throw uno::RuntimeException("no shape aggregate", *this );
+
+ // must be handled by the aggregate
+ uno::Reference< beans::XPropertySet > xShapeProps;
+ if ( 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::Notify(const SfxHint& rHint)
+{
+ if(rHint.GetId() == SfxHintId::Dying)
+ {
+ m_pFormat = nullptr;
+ EndListeningAll();
+ }
+}
+
+void SwXShape::attach(const uno::Reference< text::XTextRange > & xTextRange)
+{
+ SolarMutexGuard aGuard;
+
+ // get access to SwDoc
+ // (see also SwXTextRange::XTextRangeToSwPaM)
+ const SwDoc* pDoc = nullptr;
+ uno::Reference<lang::XUnoTunnel> xRangeTunnel( xTextRange, uno::UNO_QUERY);
+ if(xRangeTunnel.is())
+ {
+ SwXTextRange* pRange = nullptr;
+ OTextCursorHelper* pCursor = nullptr;
+ SwXTextPortion* pPortion = nullptr;
+ SwXText* pText = nullptr;
+ SwXParagraph* pParagraph = nullptr;
+
+ pRange = reinterpret_cast< SwXTextRange * >(
+ sal::static_int_cast< sal_IntPtr >( xRangeTunnel->getSomething( SwXTextRange::getUnoTunnelId()) ));
+ pText = reinterpret_cast< SwXText * >(
+ sal::static_int_cast< sal_IntPtr >( xRangeTunnel->getSomething( SwXText::getUnoTunnelId()) ));
+ pCursor = reinterpret_cast< OTextCursorHelper * >(
+ sal::static_int_cast< sal_IntPtr >( xRangeTunnel->getSomething( OTextCursorHelper::getUnoTunnelId()) ));
+ pPortion = reinterpret_cast< SwXTextPortion * >(
+ sal::static_int_cast< sal_IntPtr >( xRangeTunnel->getSomething( SwXTextPortion::getUnoTunnelId()) ));
+ pParagraph = reinterpret_cast< SwXParagraph * >(
+ sal::static_int_cast< sal_IntPtr >( xRangeTunnel->getSomething( SwXParagraph::getUnoTunnelId( ) ) ) );
+
+ if (pRange)
+ pDoc = &pRange->GetDoc();
+ else if (pText)
+ pDoc = pText->GetDoc();
+ else if (pCursor)
+ pDoc = pCursor->GetDoc();
+ else if (pPortion)
+ pDoc = pPortion->GetCursor().GetDoc();
+ else if (pParagraph && pParagraph->GetTextNode())
+ pDoc = pParagraph->GetTextNode()->GetDoc();
+
+ }
+
+ if(!pDoc)
+ throw uno::RuntimeException();
+ if (const SwDocShell* pDocSh = pDoc->GetDocShell())
+ {
+ 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( static_cast<cppu::OWeakObject*>(this), 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.GetContentAnchor() && !rAnchor.GetPageNum()))
+ {
+ const SwPosition &rPos = *(pFormat->GetAnchor().GetContentAnchor());
+ if (rAnchor.GetAnchorId() == RndStdIds::FLY_AT_PARA)
+ { // ensure that SwXTextRange has SwIndex
+ aRef = SwXTextRange::CreateXTextRange(*pFormat->GetDoc(), SwPosition(rPos.nNode), nullptr);
+ }
+ else
+ {
+ aRef = SwXTextRange::CreateXTextRange(*pFormat->GetDoc(), rPos, nullptr);
+ }
+ }
+ }
+ else
+ aRef = pImpl->GetTextRange();
+ 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() )
+ {
+ if (pFormat->GetAnchor().GetAnchorId() == RndStdIds::FLY_AS_CHAR)
+ {
+ const SwPosition &rPos = *(pFormat->GetAnchor().GetContentAnchor());
+ SwTextNode *pTextNode = rPos.nNode.GetNode().GetTextNode();
+ const sal_Int32 nIdx = rPos.nContent.GetIndex();
+ pTextNode->DeleteAttributes( RES_TXTATR_FLYCNT, nIdx );
+ }
+ else
+ pFormat->GetDoc()->getIDocumentLayoutAccess().DelLayoutFormat( pFormat );
+ }
+ }
+ if(xShapeAgg.is())
+ {
+ uno::Any aAgg(xShapeAgg->queryAggregation( cppu::UnoType<XComponent>::get()));
+ uno::Reference<XComponent> xComp;
+ aAgg >>= xComp;
+ if(xComp.is())
+ xComp->dispose();
+ }
+ if(m_pPage)
+ const_cast<SwFmDrawPage*>(m_pPage)->RemoveShape(this);
+ m_pPage = nullptr;
+}
+
+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<OUStringLiteral>{ "com.sun.star.drawing.Shape" });
+}
+
+SvxShape* SwXShape::GetSvxShape()
+{
+ if(xShapeAgg.is())
+ return comphelper::getUnoTunnelImplementation<SvxShape>(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::getUnoTunnelImplementation<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::makeAny(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 );
+ aTempMatrix.set(2, 0, aMatrix.Line3.Column1 );
+ aTempMatrix.set(2, 1, aMatrix.Line3.Column2 );
+ aTempMatrix.set(2, 2, aMatrix.Line3.Column3 );
+ // #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 = aTempMatrix.get(2, 0);
+ aMatrix.Line3.Column2 = aTempMatrix.get(2, 1);
+ aMatrix.Line3.Column3 = aTempMatrix.get(2, 2);
+ }
+ }
+ }
+
+ 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
+ const OUString aHoriPosPropStr("HoriOrientPosition");
+ 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
+ const OUString aHoriOrientPropStr("HoriOrient");
+ 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
+ const OUString aVertPosPropStr("VertOrientPosition");
+ 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
+ const OUString aVertOrientPropStr("VertOrient");
+ 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 : aConvertedPath.Coordinates)
+ {
+ for(awt::Point& rPoint : 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(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( ) throw()
+{
+ SwXShape::acquire();
+}
+
+void SwXGroupShape::release( ) throw()
+{
+ 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( xShapeAgg.is() )
+ {
+ const uno::Type& rType = cppu::UnoType<XShapes>::get();
+ uno::Any aAgg = 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 = nullptr;
+ if(xShape.is())
+ pSwShape = reinterpret_cast< SwXShape * >(
+ sal::static_int_cast< sal_IntPtr >( xTunnel->getSomething(SwXShape::getUnoTunnelId()) ));
+ if(pSwShape && pSwShape->m_bDescriptor)
+ {
+ SvxShape* pAddShape = reinterpret_cast< SvxShape * >(
+ sal::static_int_cast< sal_IntPtr >( xTunnel->getSomething(SvxShape::getUnoTunnelId()) ));
+ 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->pImpl->GetOpaque()
+ ? pDoc->getIDocumentDrawModelAccess().GetInvisibleHeavenId()
+ : pDoc->getIDocumentDrawModelAccess().GetInvisibleHellId() );
+ }
+ else
+ {
+ pObj->SetLayer(pDoc->getIDocumentDrawModelAccess().GetInvisibleControlsId());
+ }
+ }
+ }
+ pSwShape->m_bDescriptor = false;
+ //add the group member to the format of the group
+ SwFrameFormat* pShapeFormat = ::FindFrameFormat( pSvxShape->GetSdrObject() );
+
+ if(pShapeFormat)
+ pSwShape->SetFrameFormat(pShapeFormat);
+ }
+
+}
+
+void SwXGroupShape::remove( const uno::Reference< XShape >& xShape )
+{
+ SolarMutexGuard aGuard;
+ uno::Reference<XShapes> xShapes;
+ if( xShapeAgg.is() )
+ {
+ const uno::Type& rType = cppu::UnoType<XShapes>::get();
+ uno::Any aAgg = 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( xShapeAgg.is() )
+ {
+ const uno::Type& rType = cppu::UnoType<XIndexAccess>::get();
+ uno::Any aAgg = 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( xShapeAgg.is() )
+ {
+ const uno::Type& rType = cppu::UnoType<XIndexAccess>::get();
+ uno::Any aAgg = 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( xShapeAgg.is() )
+ {
+ const uno::Type& rType = cppu::UnoType<XIndexAccess>::get();
+ uno::Any aAgg = 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( xShapeAgg.is() )
+ {
+ const uno::Type& rType = cppu::UnoType<XIndexAccess>::get();
+ uno::Any aAgg = 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 000000000..7ca58df40
--- /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),
+ rFrame(rFrameRef)
+{
+}
+
+SwFrameEventDescriptor::SwFrameEventDescriptor(
+ SwXTextGraphicObject& rGraphicRef ) :
+ SvEventDescriptor(static_cast<text::XTextContent&>(rGraphicRef), aGraphicEvents),
+ rFrame(static_cast<SwXFrame&>(rGraphicRef))
+{
+}
+
+SwFrameEventDescriptor::SwFrameEventDescriptor(
+ SwXTextEmbeddedObject& rObjectRef ) :
+ SvEventDescriptor(static_cast<text::XTextContent&>(rObjectRef), aOLEEvents),
+ rFrame(static_cast<SwXFrame&>(rObjectRef))
+{
+}
+
+SwFrameEventDescriptor::~SwFrameEventDescriptor()
+{
+}
+
+void SwFrameEventDescriptor::setMacroItem(const SvxMacroItem& rItem)
+{
+ rFrame.GetFrameFormat()->SetFormatAttr(rItem);
+}
+
+const SvxMacroItem& SwFrameEventDescriptor::getMacroItem()
+{
+ return 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);
+}
+
+static 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 000000000..d6c9e5a92
--- /dev/null
+++ b/sw/source/core/unocore/unofield.cxx
@@ -0,0 +1,3034 @@
+/* -*- 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 <swtypes.hxx>
+#include <cmdid.h>
+#include <doc.hxx>
+#include <IDocumentFieldsAccess.hxx>
+#include <IDocumentStatistics.hxx>
+#include <IDocumentStylePoolAccess.hxx>
+#include <IDocumentLayoutAccess.hxx>
+#include <IDocumentState.hxx>
+#include <hints.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/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 <osl/mutex.hxx>
+#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)
+#define COM_TEXT_FLDMASTER_CC "com.sun.star.text.fieldmaster."
+
+// note: this thing is indexed as an array, so do not insert/remove entries!
+static 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;
+};
+
+}
+
+static 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 (size_t i=0; i<SAL_N_ELEMENTS(aServiceToRes); ++i)
+ if (aServiceToRes[i].nServiceId == nServiceId)
+ return aServiceToRes[i].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(const OUString& 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( const OUString& rProperty, const SwFieldType& rTyp )
+{
+ sal_uInt16 nId = lcl_GetPropMapIdForFieldType( rTyp.Which() );
+ const SfxItemPropertySet* pSet = aSwMapProvider.GetPropertySet( nId );
+ if( !pSet )
+ nId = USHRT_MAX;
+ else
+ {
+ const SfxItemPropertySimpleEntry* 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
+{
+private:
+ ::osl::Mutex m_Mutex; // just for OInterfaceContainerHelper2
+
+public:
+ uno::WeakReference<uno::XInterface> m_wThis;
+ ::comphelper::OInterfaceContainerHelper2 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_EventListeners(m_Mutex)
+ , 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_EventListeners(m_Mutex)
+ , 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;
+};
+
+namespace
+{
+ class theSwXFieldMasterUnoTunnelId : public rtl::Static< UnoTunnelIdInit, theSwXFieldMasterUnoTunnelId > {};
+}
+
+const uno::Sequence< sal_Int8 > & SwXFieldMaster::getUnoTunnelId()
+{
+ return theSwXFieldMasterUnoTunnelId::get().getSeq();
+}
+
+sal_Int64 SAL_CALL
+SwXFieldMaster::getSomething(const uno::Sequence< sal_Int8 >& rId)
+{
+ return ::sw::UnoTunnelImpl<SwXFieldMaster>(rId, this);
+}
+
+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 *const pDoc, SwFieldIds const nResId)
+ : m_pImpl(new Impl(pDoc->getIDocumentStylePoolAccess().GetPageDescFromPool(RES_POOLPAGE_STANDARD), pDoc, nResId))
+{
+}
+
+SwXFieldMaster::SwXFieldMaster(SwFieldType& rType, SwDoc * pDoc)
+ : m_pImpl(new Impl(&rType, pDoc, rType.Which()))
+{
+}
+
+SwXFieldMaster::~SwXFieldMaster()
+{
+}
+
+uno::Reference<beans::XPropertySet>
+SwXFieldMaster::CreateXFieldMaster(SwDoc * pDoc, SwFieldType *const pType,
+ SwFieldIds nResId)
+{
+ // re-use existing SwXFieldMaster
+ uno::Reference<beans::XPropertySet> xFM;
+ if (pType)
+ {
+ xFM = pType->GetXObject();
+ }
+ 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;
+ }
+ 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,
+ static_cast< cppu::OWeakObject * >( this ) );
+ }
+
+ 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, static_cast < cppu::OWeakObject * > ( this ) );
+ }
+ }
+}
+
+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, 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.begin(),
+ [this](SwFormatField* pF) { return uno::Reference<text::XDependentTextField>(SwXTextField::CreateXTextField(m_pImpl->m_pDoc, pF), uno::UNO_QUERY); });
+ 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,
+ static_cast<cppu::OWeakObject *>(this));
+ }
+ 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, static_cast < cppu::OWeakObject * > ( this ) );
+ }
+ }
+ }
+ 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)
+{
+ // no need to lock here as m_pImpl is const and container threadsafe
+ m_pImpl->m_EventListeners.addInterface(xListener);
+}
+
+void SAL_CALL SwXFieldMaster::removeEventListener(
+ const uno::Reference<lang::XEventListener> & xListener)
+{
+ // no need to lock here as m_pImpl is const and container threadsafe
+ m_pImpl->m_EventListeners.removeInterface(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);
+ m_EventListeners.disposeAndClear(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.copy(sSource.getLength());
+ }
+ }
+ return rFormula;
+}
+
+namespace {
+
+struct SwFieldProperties_Impl
+{
+ OUString sPar1;
+ OUString sPar2;
+ OUString sPar3;
+ OUString sPar4;
+ 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_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),
+ nSHORT1(0),
+ nByte1(0),
+ bFormatIsDefault(true),
+ bBool1(false),
+ bBool2(false),
+ bBool3(false),
+ bBool4(true) //Automatic language
+ {}
+};
+
+}
+
+class SwXTextField::Impl
+ : public SvtListener
+{
+private:
+ ::osl::Mutex m_Mutex; // just for OInterfaceContainerHelper2
+ SwFieldType* m_pFieldType;
+ SwFormatField* m_pFormatField;
+
+public:
+ uno::WeakReference<uno::XInterface> m_wThis;
+ ::comphelper::OInterfaceContainerHelper2 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_EventListeners(m_Mutex)
+ , 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;
+};
+
+namespace
+{
+ class theSwXTextFieldUnoTunnelId : public rtl::Static< UnoTunnelIdInit, theSwXTextFieldUnoTunnelId > {};
+}
+
+const uno::Sequence< sal_Int8 > & SwXTextField::getUnoTunnelId()
+{
+ return theSwXTextFieldUnoTunnelId::get().getSeq();
+}
+
+sal_Int64 SAL_CALL
+SwXTextField::getSomething(const uno::Sequence< sal_Int8 >& rId)
+{
+ return ::sw::UnoTunnelImpl<SwXTextField>(rId, this);
+}
+
+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()
+{
+}
+
+uno::Reference<text::XTextField>
+SwXTextField::CreateXTextField(SwDoc *const pDoc, SwFormatField const* pFormat,
+ SwServiceType nServiceId)
+{
+ assert(!pFormat || pDoc);
+ assert(pFormat || nServiceId != SwServiceType::Invalid);
+ // re-use existing SwXTextField
+ uno::Reference<text::XTextField> 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;
+ }
+ 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));
+ uno::Reference<text::XTextField> const xField(
+ rField.GetFormatField()->GetXTextField());
+ SwXTextField *const pXField = xField.is()
+ ? reinterpret_cast<SwXTextField*>(
+ sal::static_int_cast<sal_IntPtr>(
+ uno::Reference<lang::XUnoTunnel>(xField, uno::UNO_QUERY_THROW)
+ ->getSomething(getUnoTunnelId())))
+ : nullptr;
+ 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()->nContent.GetIndex());
+ 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, true));
+ 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 (xField.is())
+ {
+ pXField->m_pImpl->SetFormatField(const_cast<SwFormatField*>(&rNewFormat), rNode.GetDoc());
+ const_cast<SwFormatField&>(rNewFormat).SetXTextField(xField);
+ }
+}
+
+void SAL_CALL SwXTextField::attachTextFieldMaster(
+ const uno::Reference< beans::XPropertySet > & xFieldMaster)
+{
+ SolarMutexGuard aGuard;
+
+ if (!m_pImpl->IsDescriptor())
+ throw uno::RuntimeException();
+ uno::Reference< lang::XUnoTunnel > xMasterTunnel(xFieldMaster, uno::UNO_QUERY);
+ if (!xMasterTunnel.is())
+ throw lang::IllegalArgumentException();
+ SwXFieldMaster* pMaster = reinterpret_cast< SwXFieldMaster * >(
+ sal::static_int_cast< sal_IntPtr >( xMasterTunnel->getSomething( SwXFieldMaster::getUnoTunnelId()) ));
+
+ 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();
+ 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())
+ {
+ uno::Reference<lang::XUnoTunnel> xRangeTunnel( xTextRange, uno::UNO_QUERY);
+ SwXTextRange* pRange = nullptr;
+ OTextCursorHelper* pCursor = nullptr;
+ if(xRangeTunnel.is())
+ {
+ pRange = reinterpret_cast< SwXTextRange * >(
+ sal::static_int_cast< sal_IntPtr >( xRangeTunnel->getSomething( SwXTextRange::getUnoTunnelId()) ));
+ pCursor = reinterpret_cast< OTextCursorHelper * >(
+ sal::static_int_cast< sal_IntPtr >( xRangeTunnel->getSomething( OTextCursorHelper::getUnoTunnelId()) ));
+ }
+
+ 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);
+ }
+ 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
+ );
+ 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:
+ {
+ 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));
+ 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 <<= 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)),
+ OUString()));
+ 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.GetNode().GetTextNode()->GetFieldTextAttrAt( aPam.GetPoint()->nContent.GetIndex()-1, true );
+
+ // What about updating the fields? (see fldmgr.cxx)
+ if (!pTextAttr)
+ throw uno::RuntimeException("no SwTextAttr inserted?"); // could theoretically happen, if paragraph is full
+
+ 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->ClearFieldType();
+ 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 )
+ {
+ SwUnoInternalPaM aIntPam( *m_pImpl->m_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( m_pImpl->m_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() );
+ m_pImpl->m_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();
+ m_pImpl->m_pDoc->getIDocumentContentOperations().DeleteAndJoin(aPam);
+ }
+ // keep inserted annotation
+ {
+ SwTextField* pTextAttr = aEnd.GetNode().GetTextNode()->GetFieldTextAttrAt( aEnd.End()->nContent.GetIndex()-1, true );
+ if ( pTextAttr != nullptr )
+ {
+ m_pImpl->SetFormatField(const_cast<SwFormatField*>(&pTextAttr->GetFormatField()), m_pImpl->m_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;
+ }
+ }
+ }
+
+ uno::Reference<text::XTextRange> 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)
+{
+ // no need to lock here as m_pImpl is const and container threadsafe
+ m_pImpl->m_EventListeners.addInterface(xListener);
+}
+
+void SAL_CALL SwXTextField::removeEventListener(
+ const uno::Reference<lang::XEventListener> & xListener)
+{
+ // no need to lock here as m_pImpl is const and container threadsafe
+ m_pImpl->m_EventListeners.removeInterface(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 SfxItemPropertySimpleEntry* pEntry = _pPropSet->getPropertyMap().getByName(rPropertyName);
+
+ if (!pEntry)
+ throw beans::UnknownPropertyException( "Unknown property: " + rPropertyName, static_cast < cppu::OWeakObject * > ( this ) );
+ if ( pEntry->nFlags & beans::PropertyAttribute::READONLY)
+ throw beans::PropertyVetoException( "Property is read-only: " + rPropertyName, static_cast < cppu::OWeakObject * > ( this ) );
+
+ 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() );
+ aPosition.nContent = 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_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:
+ {
+ sal_Int16 nVal = 0;
+ rValue >>= nVal;
+ if( FIELD_PROP_USHORT1 == pEntry->nWID)
+ m_pImpl->m_pProps->nUSHORT1 = nVal;
+ else
+ m_pImpl->m_pProps->nUSHORT2 = 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)
+ {
+ auto b = o3tl::tryAccess<bool>(rValue);
+ if( !b )
+ 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 SfxItemPropertySimpleEntry* 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, static_cast < cppu::OWeakObject * > ( this ) );
+
+ 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(1);
+ text::TextContentAnchorType* pArray = aTypes.getArray();
+ pArray[0] = 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.get());
+ 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_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_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()->ModifyNotification(nullptr, nullptr);
+ }
+ 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), ".textfield.docinfo." );
+ nIdx = sServiceNameCC.indexOf( aOldNamePart2 );
+ if (nIdx >= 0)
+ sServiceNameCC = sServiceNameCC.replaceAt( nIdx, strlen(aOldNamePart2), ".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);
+ m_EventListeners.disposeAndClear(ev);
+}
+
+void SwXTextField::Impl::Notify(const SfxHint& rHint)
+{
+
+ if(rHint.GetId() == SfxHintId::Dying)
+ Invalidate();
+ else if (auto pLegacyHint = dynamic_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(RTL_CONSTASCII_LENGTH(COM_TEXT_FLDMASTER_CC));
+
+ 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;
+ if(!GetDoc())
+ throw uno::RuntimeException();
+
+ 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()));
+ SwFieldType* pType = GetDoc()->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(GetDoc(), pType));
+ return uno::makeAny(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;
+ if(!GetDoc())
+ throw uno::RuntimeException();
+
+ 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;
+ if(!GetDoc())
+ throw uno::RuntimeException();
+
+ 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
+{
+private:
+ ::osl::Mutex m_Mutex; // just for OInterfaceContainerHelper2
+
+public:
+ ::comphelper::OInterfaceContainerHelper2 m_RefreshListeners;
+
+ Impl() : m_RefreshListeners(m_Mutex) { }
+};
+
+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(static_cast< ::cppu::OWeakObject&>(*this));
+ m_pImpl->m_RefreshListeners.disposeAndClear(ev);
+}
+
+uno::Reference< container::XEnumeration > SwXTextFieldTypes::createEnumeration()
+{
+ SolarMutexGuard aGuard;
+ if(!IsValid())
+ throw uno::RuntimeException();
+ 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;
+ if (!IsValid())
+ throw uno::RuntimeException();
+ UnoActionContext aContext(GetDoc());
+ GetDoc()->getIDocumentStatistics().UpdateDocStat( false, true );
+ GetDoc()->getIDocumentFieldsAccess().UpdateFields(false);
+ }
+ // call refresh listeners (without SolarMutex locked)
+ lang::EventObject const event(static_cast< ::cppu::OWeakObject*>(this));
+ m_pImpl->m_RefreshListeners.notifyEach(
+ & util::XRefreshListener::refreshed, event);
+}
+
+void SAL_CALL SwXTextFieldTypes::addRefreshListener(
+ const uno::Reference<util::XRefreshListener> & xListener)
+{
+ // no need to lock here as m_pImpl is const and container threadsafe
+ m_pImpl->m_RefreshListeners.addInterface(xListener);
+}
+
+void SAL_CALL SwXTextFieldTypes::removeRefreshListener(
+ const uno::Reference<util::XRefreshListener> & xListener)
+{
+ // no need to lock here as m_pImpl is const and container threadsafe
+ m_pImpl->m_RefreshListeners.removeInterface(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 );
+ }
+}
+
+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 000000000..15ffb4441
--- /dev/null
+++ b/sw/source/core/unocore/unoflatpara.cxx
@@ -0,0 +1,593 @@
+/* -*- 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 <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 <IGrammarContact.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, const OUString& aExpandText, const ModelToViewHelper& rMap )
+ : SwXFlatParagraph_Base(& rTextNode, rMap)
+ , maExpandText(aExpandText)
+{
+}
+
+SwXFlatParagraph::~SwXFlatParagraph()
+{
+}
+
+
+// XPropertySet
+uno::Reference< beans::XPropertySetInfo > SAL_CALL
+SwXFlatParagraph::getPropertySetInfo()
+{
+ static 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(), -1, css::uno::Type(), 0, 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",
+ static_cast< ::cppu::OWeakObject*>(this), 0);
+}
+
+uno::Any SAL_CALL
+SwXFlatParagraph::getPropertyValue(const OUString& rPropertyName)
+{
+ SolarMutexGuard g;
+
+ if (rPropertyName == "FieldPositions")
+ {
+ return uno::makeAny( comphelper::containerToSequence( GetConversionMap().getFieldPositions() ) );
+ }
+ else if (rPropertyName == "FootnotePositions")
+ {
+ return uno::makeAny( comphelper::containerToSequence( GetConversionMap().getFootnotePositions() ) );
+ }
+ 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())
+ {
+ if ( text::TextMarkupType::SPELLCHECK == nType )
+ {
+ GetTextNode()->SetWrongDirty(
+ bVal ? SwTextNode::WrongState::DONE : SwTextNode::WrongState::TODO);
+ }
+ else if ( text::TextMarkupType::SMARTTAG == nType )
+ GetTextNode()->SetSmartTagDirty( !bVal );
+ else if( text::TextMarkupType::PROOFREADING == nType )
+ {
+ GetTextNode()->SetGrammarCheckDirty( !bVal );
+ if( bVal )
+ ::finishGrammarCheck( *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 nullptr == GetTextNode();
+}
+
+// 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 uno::Reference< text::XTextRange > xRange =
+ SwXTextRange::CreateXTextRange(
+ *GetTextNode()->GetDoc(), *aPaM.GetPoint(), aPaM.GetMark() );
+ uno::Reference< beans::XPropertySet > xPropSet( xRange, uno::UNO_QUERY );
+ if ( xPropSet.is() )
+ {
+ for ( const auto& rAttribute : aAttributes )
+ xPropSet->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 uno::Reference< text::XTextRange > xRange =
+ SwXTextRange::CreateXTextRange(
+ *GetTextNode()->GetDoc(), *aPaM.GetPoint(), aPaM.GetMark() );
+ uno::Reference< beans::XPropertySet > xPropSet( xRange, uno::UNO_QUERY );
+ if ( xPropSet.is() )
+ {
+ for ( const auto& rAttribute : aAttributes )
+ xPropSet->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>();
+}
+
+namespace
+{
+ class theSwXFlatParagraphUnoTunnelId : public rtl::Static< UnoTunnelIdInit, theSwXFlatParagraphUnoTunnelId > {};
+}
+
+const uno::Sequence< sal_Int8 >&
+SwXFlatParagraph::getUnoTunnelId()
+{
+ return theSwXFlatParagraphUnoTunnelId::get().getSeq();
+}
+
+sal_Int64 SAL_CALL
+SwXFlatParagraph::getSomething(
+ const uno::Sequence< sal_Int8 >& rId)
+{
+ return sw::UnoTunnelImpl(rId, this);
+}
+
+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 sal_uLong nMaxNodes = rNodes.Count();
+
+ while ( mnCurrentNode < mnEndNode && mnCurrentNode < nMaxNodes )
+ {
+ SwNode* pNd = rNodes[ mnCurrentNode ];
+
+ ++mnCurrentNode;
+
+ pRet = dynamic_cast<SwTextNode*>(pNd);
+ if ( pRet )
+ break;
+
+ if ( mnCurrentNode == mnEndNode )
+ {
+ mnCurrentNode = 0;
+ mnEndNode = 0;
+ }
+ }
+ }
+
+ if ( pRet )
+ {
+ // Expand the string:
+ const ModelToViewHelper aConversionMap(*pRet, mpDoc->getIDocumentLayoutAccess().GetCurrentLayout());
+ const OUString& aExpandText = aConversionMap.getViewText();
+
+ xRet = new SwXFlatParagraph( *pRet, aExpandText, aConversionMap );
+ // keep hard references...
+ m_aFlatParaList.insert( xRet );
+ }
+
+ 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;
+
+ const uno::Reference<lang::XUnoTunnel> xFPTunnel(xPara, uno::UNO_QUERY);
+ SAL_WARN_IF(!xFPTunnel.is(), "sw.core", "invalid argument");
+ SwXFlatParagraph* const pFlatParagraph(sw::UnoTunnelGetImplementation<SwXFlatParagraph>(xFPTunnel));
+
+ if ( !pFlatParagraph )
+ return xRet;
+
+ SwTextNode const*const pCurrentNode = pFlatParagraph->GetTextNode();
+
+ if ( !pCurrentNode )
+ return xRet;
+
+ SwTextNode* pNextTextNode = nullptr;
+ const SwNodes& rNodes = pCurrentNode->GetDoc()->GetNodes();
+
+ for( sal_uLong nCurrentNode = pCurrentNode->GetIndex() + 1; nCurrentNode < rNodes.Count(); ++nCurrentNode )
+ {
+ SwNode* pNd = rNodes[ nCurrentNode ];
+ pNextTextNode = dynamic_cast<SwTextNode*>(pNd);
+ 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 );
+ // keep hard references...
+ m_aFlatParaList.insert( xRet );
+ }
+
+ 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;
+
+ const uno::Reference<lang::XUnoTunnel> xFPTunnel(xPara, uno::UNO_QUERY);
+
+ SAL_WARN_IF(!xFPTunnel.is(), "sw.core", "invalid argument");
+ SwXFlatParagraph* const pFlatParagraph(sw::UnoTunnelGetImplementation<SwXFlatParagraph>(xFPTunnel));
+
+ if ( !pFlatParagraph )
+ return xRet;
+
+ SwTextNode const*const pCurrentNode = pFlatParagraph->GetTextNode();
+
+ if ( !pCurrentNode )
+ return xRet;
+
+ SwTextNode* pPrevTextNode = nullptr;
+ const SwNodes& rNodes = pCurrentNode->GetDoc()->GetNodes();
+
+ for( sal_uLong nCurrentNode = pCurrentNode->GetIndex() - 1; nCurrentNode > 0; --nCurrentNode )
+ {
+ SwNode* pNd = rNodes[ nCurrentNode ];
+ pPrevTextNode = dynamic_cast<SwTextNode*>(pNd);
+ 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 );
+ // keep hard references...
+ m_aFlatParaList.insert( xRet );
+ }
+
+ 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 000000000..c96dc6676
--- /dev/null
+++ b/sw/source/core/unocore/unoframe.cxx
@@ -0,0 +1,3656 @@
+/* -*- 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/svxids.hrc>
+#include <svx/xfillit0.hxx>
+#include <svx/xflgrit.hxx>
+#include <svx/sdtaitm.hxx>
+#include <svx/xflclit.hxx>
+#include <tools/globname.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 <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 <osl/mutex.hxx>
+#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/servicehelper.hxx>
+#include <cppuhelper/supportsservice.hxx>
+#include <sal/log.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>
+
+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 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)
+{
+ aAnyMap.SetValue( nWID, nMemberId, rVal );
+}
+
+bool BaseFrameProperties_Impl::GetProperty(sal_uInt16 nWID, sal_uInt8 nMemberId, const uno::Any*& rpAny)
+{
+ return 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* pAnchorPgNo;
+ if(GetProperty(RES_ANCHOR, MID_ANCHOR_PAGENUM, pAnchorPgNo))
+ bRet &= static_cast<SfxPoolItem&>(aAnchor).PutValue(*pAnchorPgNo, MID_ANCHOR_PAGENUM);
+ const ::uno::Any* pAnchorType;
+ if(GetProperty(RES_ANCHOR, MID_ANCHOR_ANCHORTYPE, pAnchorType))
+ bRet &= static_cast<SfxPoolItem&>(aAnchor).PutValue(*pAnchorType, MID_ANCHOR_ANCHORTYPE);
+ }
+
+ 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)
+ {
+ const XGradient aNullGrad(COL_BLACK, COL_WHITE);
+ 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)
+ {
+ const Graphic aNullGraphic;
+ XFillBitmapItem aXFillBitmapItem(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)
+ {
+ const XGradient aNullGrad(COL_BLACK, COL_WHITE);
+ 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;
+ awt::Size aSize;
+ aSize.Width = 2 * MM50;
+ aSize.Height = 2 * MM50;
+ ::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);
+ }
+ }
+
+ 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() :
+ SwFrameProperties_Impl(/*aSwMapProvider.GetPropertyMap(PROPERTY_MAP_EMBEDDED_OBJECT)*/ ){}
+
+ 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
+{
+private:
+ ::osl::Mutex m_Mutex; // just for OInterfaceContainerHelper2
+
+public:
+ uno::WeakReference<uno::XInterface> m_wThis;
+ ::comphelper::OInterfaceContainerHelper2 m_EventListeners;
+
+ Impl() : m_EventListeners(m_Mutex) { }
+};
+
+namespace
+{
+ class theSwXFrameUnoTunnelId : public rtl::Static< UnoTunnelIdInit, theSwXFrameUnoTunnelId > {};
+}
+
+const ::uno::Sequence< sal_Int8 > & SwXFrame::getUnoTunnelId()
+{
+ return theSwXFrameUnoTunnelId::get().getSeq();
+}
+
+sal_Int64 SAL_CALL SwXFrame::getSomething( const ::uno::Sequence< sal_Int8 >& rId )
+{
+ if( isUnoTunnelId<SwXFrame>(rId) )
+ {
+ return sal::static_int_cast< sal_Int64 >( reinterpret_cast< sal_IntPtr >(this) );
+ }
+ return 0;
+}
+
+
+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)
+ , eType(eSet)
+ , 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(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)
+ , eType(eSet)
+ , 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 Interface, class NameLookupIsHard>
+uno::Reference<Interface>
+SwXFrame::CreateXFrame(SwDoc & rDoc, SwFrameFormat *const pFrameFormat)
+{
+ assert(!pFrameFormat || &rDoc == pFrameFormat->GetDoc());
+ uno::Reference<Interface> xFrame;
+ if (pFrameFormat)
+ {
+ xFrame.set(pFrameFormat->GetXObject(), uno::UNO_QUERY); // cached?
+ }
+ if (!xFrame.is())
+ {
+ NameLookupIsHard *const pNew(pFrameFormat
+ ? new NameLookupIsHard(*pFrameFormat)
+ : new NameLookupIsHard(&rDoc));
+ xFrame.set(pNew);
+ if (pFrameFormat)
+ {
+ pFrameFormat->SetXObject(xFrame);
+ }
+ // need a permanent Reference to initialize m_wThis
+ pNew->SwXFrame::m_pImpl->m_wThis = xFrame;
+ }
+ return xFrame;
+}
+
+OUString SwXFrame::getName()
+{
+ SolarMutexGuard aGuard;
+ SwFrameFormat* pFormat = GetFrameFormat();
+ if(pFormat)
+ return pFormat->GetName();
+ if(!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();
+ }
+ }
+ else if(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(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();
+ const ::SfxItemPropertySimpleEntry* pEntry = m_pPropSet->getPropertyMap().getByName(rPropertyName);
+
+ if (!pEntry)
+ throw beans::UnknownPropertyException( "Unknown property: " + rPropertyName, static_cast < cppu::OWeakObject * > ( this ) );
+
+ 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 : GetFrameFormat()->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, static_cast < cppu::OWeakObject * > ( this ) );
+
+ SwDoc* pDoc = pFormat->GetDoc();
+ if ( ((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(static_cast<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( static_cast<sal_uInt16>(nPoints) );
+ for(sal_Int32 j = 0; j < nPoints; j++)
+ {
+ Point aPoint(pPoints[j].X, pPoints[j].Y);
+ aSet.SetPoint(aPoint, static_cast<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);
+ }
+ // 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::unique_ptr<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 )
+ {
+ const ::SfxPoolItem* pItem;
+ if( SfxItemState::SET == pFrameFormat->GetItemState( RES_ANCHOR, false, &pItem ))
+ {
+ pSet.reset(new SfxItemSet( pDoc->GetAttrPool(), aFrameFormatSetRange ));
+ pSet->Put( *pItem );
+ if ( pFormat->GetDoc()->GetEditShell() != nullptr
+ && !sw_ChkAndSetNewAnchor( *pFly, *pSet ) )
+ {
+ pSet.reset();
+ }
+ }
+ }
+ }
+
+ pFormat->GetDoc()->SetFrameFormatToFly( *pFormat, *pFrameFormat, pSet.get() );
+ }
+ 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 = comphelper::getUnoTunnelImplementation<SwXFrame>(xFrame);
+ if(pFrame && this != pFrame && pFrame->GetFrameFormat() && pFrame->GetFrameFormat()->GetDoc() == pDoc)
+ {
+ SfxItemSet aSet( pDoc->GetAttrPool(),
+ svl::Items<RES_FRMATR_BEGIN, RES_FRMATR_END - 1>{} );
+ 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
+ SfxItemSet aSet( pDoc->GetAttrPool(),
+ svl::Items<RES_FRMATR_BEGIN, RES_FRMATR_END - 1,
+ RES_UNKNOWNATR_CONTAINER, RES_UNKNOWNATR_CONTAINER,
+
+ // FillAttribute support
+ XATTR_FILL_FIRST, XATTR_FILL_LAST>{});
+ 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:
+ {
+ const Graphic aNullGraphic;
+ XFillBitmapItem aXFillBitmapItem(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 ::SwPosition* pPosition = aAnchor.GetContentAnchor();
+ SwFrameFormat* pFlyFormat = pPosition ? pPosition->nNode.GetNode().GetFlyFormat() : nullptr;
+ if(!pFlyFormat || pFlyFormat->Which() == RES_DRAWFRMFMT)
+ {
+ lang::IllegalArgumentException aExcept;
+ aExcept.Message = "Anchor to frame: no frame found";
+ throw aExcept;
+ }
+ else
+ {
+ SwPosition aPos = *pPosition;
+ aPos.nNode = *pFlyFormat->GetContent().GetContentIdx();
+ aAnchor.SetAnchor(&aPos);
+ aSet.Put(aAnchor);
+ }
+ }
+ else if ((aAnchor.GetAnchorId() != RndStdIds::FLY_AT_PAGE) &&
+ !aAnchor.GetContentAnchor())
+ {
+ 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)
+ {
+ const ::SfxPoolItem* pItem;
+ if( SfxItemState::SET == aSet.GetItemState( RES_ANCHOR, false, &pItem ))
+ {
+ 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
+ {
+ 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();
+ }
+ }
+ else
+ throw uno::RuntimeException();
+}
+
+uno::Any SwXFrame::getPropertyValue(const OUString& rPropertyName)
+{
+ SolarMutexGuard aGuard;
+ uno::Any aAny;
+ SwFrameFormat* pFormat = GetFrameFormat();
+ const SfxItemPropertySimpleEntry* pEntry = m_pPropSet->getPropertyMap().getByName(rPropertyName);
+ if (!pEntry)
+ throw beans::UnknownPropertyException( "Unknown property: " + rPropertyName, static_cast < cppu::OWeakObject * > ( this ) );
+
+ const sal_uInt8 nMemberId(pEntry->nMemberId);
+
+ if(FN_UNO_ANCHOR_TYPES == pEntry->nWID)
+ {
+ uno::Sequence<text::TextContentAnchorType> aTypes(5);
+ text::TextContentAnchorType* pArray = aTypes.getArray();
+ pArray[0] = text::TextContentAnchorType_AT_PARAGRAPH;
+ pArray[1] = text::TextContentAnchorType_AS_CHARACTER;
+ pArray[2] = text::TextContentAnchorType_AT_PAGE;
+ pArray[3] = text::TextContentAnchorType_AT_FRAME;
+ pArray[4] = text::TextContentAnchorType_AT_CHARACTER;
+ aAny <<= aTypes;
+ }
+ else if(pFormat)
+ {
+ if( ((eType == FLYCNTTYPE_GRF) || (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 )
+ {
+ 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)
+ {
+ const SwEditShell* pEditShell = pDoc->GetEditShell();
+ if (pEditShell)
+ {
+ 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());
+ 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();
+ }
+ // 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(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
+ pFormat->GetDoc()->GetEditShell()->CalcLayout();
+
+ SwFrame* pTmpFrame = SwIterator<SwFrame,SwFormat>( *pFormat ).First();
+ if ( pTmpFrame )
+ {
+ OSL_ENSURE( pTmpFrame->isFrameAreaDefinitionValid(), "frame not valid" );
+ const SwRect &rRect = pTmpFrame->getFrameArea();
+ Size aMM100Size = OutputDevice::LogicToLogic(
+ Size( rRect.Width(), rRect.Height() ),
+ MapMode( MapUnit::MapTwip ), MapMode( MapUnit::Map100thMM ));
+ aAny <<= awt::Size( aMM100Size.Width(), aMM100Size.Height() );
+ }
+ }
+ else if(pEntry->nWID == FN_UNO_PARENT_TEXT)
+ {
+ if (!m_xParentText.is())
+ {
+ const SwPosition* pContentAnchor = pFormat->GetAnchor().GetContentAnchor();
+ if (pContentAnchor)
+ {
+ m_xParentText = sw::CreateParentXText(*pFormat->GetDoc(), *pContentAnchor);
+ }
+ }
+ 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());
+ beans::PropertyState* pStates = aStates.getArray();
+ SwFrameFormat* pFormat = GetFrameFormat();
+ if(pFormat)
+ {
+ const OUString* pNames = aPropertyNames.getConstArray();
+ const SwAttrSet& rFormatSet = pFormat->GetAttrSet();
+ for(int i = 0; i < aPropertyNames.getLength(); i++)
+ {
+ const SfxItemPropertySimpleEntry* pEntry = m_pPropSet->getPropertyMap().getByName(pNames[i]);
+ if (!pEntry)
+ throw beans::UnknownPropertyException("Unknown property: " + pNames[i], static_cast < cppu::OWeakObject * > ( this ) );
+
+ 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 ((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(aStates.begin(), aStates.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 SfxItemPropertySimpleEntry* pEntry = m_pPropSet->getPropertyMap().getByName(rPropertyName);
+ if (!pEntry)
+ throw beans::UnknownPropertyException( "Unknown property: " + rPropertyName, static_cast < cppu::OWeakObject * > ( this ) );
+ if ( pEntry->nFlags & beans::PropertyAttribute::READONLY)
+ throw uno::RuntimeException("setPropertyToDefault: property is read-only: " + rPropertyName, static_cast < cppu::OWeakObject * > ( this ) );
+
+ bool bNextFrame;
+ if(OWN_ATTR_FILLBMP_MODE == pEntry->nWID)
+ {
+ SwDoc* pDoc = pFormat->GetDoc();
+ SfxItemSet aSet(pDoc->GetAttrPool(), svl::Items<XATTR_FILL_FIRST, XATTR_FILL_LAST>{});
+ aSet.SetParent(&pFormat->GetAttrSet());
+
+ aSet.ClearItem(XATTR_FILLBMP_STRETCH);
+ aSet.ClearItem(XATTR_FILLBMP_TILE);
+
+ pFormat->SetFormatAttr(aSet);
+ }
+ else if( pEntry->nWID &&
+ pEntry->nWID != FN_UNO_ANCHOR_TYPES &&
+ pEntry->nWID != FN_PARAM_LINK_DISPLAY_NAME)
+ {
+ if ( (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
+ {
+ SwDoc* pDoc = pFormat->GetDoc();
+ SfxItemSet aSet( pDoc->GetAttrPool(),
+ svl::Items<RES_FRMATR_BEGIN, RES_FRMATR_END - 1>{} );
+ aSet.SetParent(&pFormat->GetAttrSet());
+ aSet.ClearItem(pEntry->nWID);
+ if(rPropertyName != UNO_NAME_ANCHOR_TYPE)
+ pFormat->SetFormatAttr(aSet);
+ }
+ }
+ else
+ {
+ 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 SfxItemPropertySimpleEntry* pEntry = m_pPropSet->getPropertyMap().getByName(rPropertyName);
+ if(!pEntry)
+ throw beans::UnknownPropertyException( "Unknown property: " + rPropertyName, static_cast < cppu::OWeakObject * > ( this ) );
+
+ 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)
+{
+ // no need to lock here as m_pImpl is const and container threadsafe
+ m_pImpl->m_EventListeners.addInterface(xListener);
+}
+
+void SAL_CALL SwXFrame::removeEventListener(
+ const uno::Reference<lang::XEventListener> & xListener)
+{
+ // no need to lock here as m_pImpl is const and container threadsafe
+ m_pImpl->m_EventListeners.removeInterface(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);
+ m_pImpl->m_EventListeners.disposeAndClear(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)
+ {
+ 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() ) ) )
+ {
+ if (pFormat->GetAnchor().GetAnchorId() == RndStdIds::FLY_AS_CHAR)
+ {
+ const SwPosition &rPos = *(pFormat->GetAnchor().GetContentAnchor());
+ SwTextNode *pTextNode = rPos.nNode.GetNode().GetTextNode();
+ const sal_Int32 nIdx = rPos.nContent.GetIndex();
+ pTextNode->DeleteAttributes( RES_TXTATR_FLYCNT, nIdx, nIdx );
+ }
+ else
+ pFormat->GetDoc()->getIDocumentLayoutAccess().DelLayoutFormat(pFormat);
+ }
+ }
+
+}
+
+uno::Reference< text::XTextRange > SwXFrame::getAnchor()
+{
+ SolarMutexGuard aGuard;
+ uno::Reference< text::XTextRange > 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.GetContentAnchor() && !rAnchor.GetPageNum()))
+ {
+ const SwPosition &rPos = *(rAnchor.GetContentAnchor());
+ if (rAnchor.GetAnchorId() == RndStdIds::FLY_AT_PARA)
+ { // ensure that SwXTextRange has SwIndex
+ aRef = SwXTextRange::CreateXTextRange(*pFormat->GetDoc(), SwPosition(rPos.nNode), nullptr);
+ }
+ else
+ {
+ aRef = SwXTextRange::CreateXTextRange(*pFormat->GetDoc(), rPos, nullptr);
+ }
+ }
+
+ return aRef;
+}
+
+void SwXFrame::ResetDescriptor()
+{
+ 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();
+ uno::Reference<lang::XUnoTunnel> xRangeTunnel( xTextRange, uno::UNO_QUERY);
+ SwXTextRange* pRange = nullptr;
+ OTextCursorHelper* pCursor = nullptr;
+ if(xRangeTunnel.is())
+ {
+ pRange = reinterpret_cast< SwXTextRange * >(
+ sal::static_int_cast< sal_IntPtr >( xRangeTunnel->getSomething( SwXTextRange::getUnoTunnelId()) ));
+ pCursor = reinterpret_cast< OTextCursorHelper * >(
+ sal::static_int_cast< sal_IntPtr >( xRangeTunnel->getSomething( OTextCursorHelper::getUnoTunnelId()) ));
+ }
+
+ 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 );
+ static sal_uInt16 const aFrameAttrRange[] =
+ {
+ 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,
+ 0
+ };
+ static sal_uInt16 const aGrAttrRange[] =
+ {
+ RES_GRFATR_BEGIN, RES_GRFATR_END-1,
+ 0
+ };
+ SfxItemSet aGrSet(pDoc->GetAttrPool(), aGrAttrRange );
+
+ SfxItemSet aFrameSet(pDoc->GetAttrPool(), aFrameAttrRange );
+
+ // 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();
+ }
+
+ const SfxPoolItem* pItem;
+ RndStdIds eAnchorId = RndStdIds::FLY_AT_PARA;
+ if(SfxItemState::SET == aFrameSet.GetItemState(RES_ANCHOR, false, &pItem) )
+ {
+ eAnchorId = static_cast<const SwFormatAnchor*>(pItem)->GetAnchorId();
+ if( RndStdIds::FLY_AT_FLY == eAnchorId &&
+ !aPam.GetNode().FindFlyStartNode())
+ {
+ // framebound only where a frame exists
+ SwFormatAnchor aAnchor(RndStdIds::FLY_AT_PARA);
+ aFrameSet.Put(aAnchor);
+ }
+ else if ((RndStdIds::FLY_AT_PAGE == eAnchorId) &&
+ 0 == static_cast<const SwFormatAnchor*>(pItem)->GetPageNum() )
+ {
+ SwFormatAnchor aAnchor( *static_cast<const SwFormatAnchor*>(pItem) );
+ 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( 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 ));
+ }
+
+ aPam.DeleteMark(); // mark position node will be deleted!
+ aIntPam.DeleteMark(); // mark position node will be deleted!
+ pFormat = pDoc->MakeFlyAndMove( *pCopySource, aFrameSet,
+ nullptr,
+ pParentFrameFormat );
+ if(pAnchorItem && pFormat)
+ {
+ pFormat->DelFrames();
+ pAnchorItem->SetAnchor( pCopySource->Start() );
+ SfxItemSet aAnchorSet( pDoc->GetAttrPool(), svl::Items<RES_ANCHOR, RES_ANCHOR>{} );
+ aAnchorSet.Put( *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( bIsDescriptor ? m_pDoc : GetFrameFormat()->GetDoc() );
+ }
+ else if( 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 ) )
+ {
+ lang::IllegalArgumentException aExcept;
+ aExcept.Message = "CLSID invalid";
+ throw aExcept;
+ }
+
+ 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
+ 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;
+
+ SwFrameFormat* pFormat;
+ if(IsDescriptor())
+ attachToRange(xTextRange);
+ else if(nullptr != (pFormat = GetFrameFormat()))
+ {
+ SwDoc* pDoc = pFormat->GetDoc();
+ SwUnoInternalPaM aIntPam(*pDoc);
+ if (!::sw::XTextRangeToSwPaM(aIntPam, xTextRange))
+ throw lang::IllegalArgumentException();
+
+ SfxItemSet aSet( pDoc->GetAttrPool(), svl::Items<RES_ANCHOR, RES_ANCHOR>{} );
+ 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()
+{
+ SolarMutexGuard aGuard;
+ uno::RuntimeException aRuntime;
+ aRuntime.Message = "position cannot be determined with this method";
+ throw aRuntime;
+}
+
+void SwXFrame::setPosition(const awt::Point& /*aPosition*/)
+{
+ SolarMutexGuard aGuard;
+ uno::RuntimeException aRuntime;
+ aRuntime.Message = "position cannot be changed with this method";
+ throw aRuntime;
+}
+
+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 ) :
+ SwXText(nullptr, CursorType::Frame),
+ SwXFrame(FLYCNTTYPE_FRM, aSwMapProvider.GetPropertySet(PROPERTY_MAP_TEXT_FRAME), _pDoc )
+{
+}
+
+SwXTextFrame::SwXTextFrame(SwFrameFormat& rFormat) :
+ SwXText(rFormat.GetDoc(), CursorType::Frame),
+ SwXFrame(rFormat, FLYCNTTYPE_FRM, aSwMapProvider.GetPropertySet(PROPERTY_MAP_TEXT_FRAME))
+{
+
+}
+
+SwXTextFrame::~SwXTextFrame()
+{
+}
+
+uno::Reference<text::XTextFrame>
+SwXTextFrame::CreateXTextFrame(SwDoc & rDoc, SwFrameFormat *const pFrameFormat)
+{
+ return CreateXFrame<text::XTextFrame, SwXTextFrame>(rDoc, pFrameFormat);
+}
+
+void SAL_CALL SwXTextFrame::acquire( )throw()
+{
+ SwXFrame::acquire();
+}
+
+void SAL_CALL SwXTextFrame::release( )throw()
+{
+ 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;
+}
+
+uno::Reference< text::XTextCursor >
+SwXTextFrame::CreateCursor()
+{
+ return createTextCursor();
+}
+
+uno::Reference< text::XTextCursor > SwXTextFrame::createTextCursor()
+{
+ SolarMutexGuard aGuard;
+ uno::Reference< text::XTextCursor > aRef;
+ 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.GetNode().FindTableNode();
+ SwContentNode* pCont = nullptr;
+ while( pTableNode )
+ {
+ aPam.GetPoint()->nNode = *pTableNode->EndOfSectionNode();
+ pCont = GetDoc()->GetNodes().GoNext(&aPam.GetPoint()->nNode);
+ pTableNode = pCont->FindTableNode();
+ }
+ if(pCont)
+ aPam.GetPoint()->nContent.Assign(pCont, 0);
+
+ const SwStartNode* pNewStartNode =
+ aPam.GetNode().FindSttNodeByType(SwFlyStartNode);
+ if(!pNewStartNode || pNewStartNode != pOwnStartNode)
+ {
+ uno::RuntimeException aExcept;
+ aExcept.Message = "no text available";
+ throw aExcept;
+ }
+
+ SwXTextCursor *const pXCursor = new SwXTextCursor(
+ *pFormat->GetDoc(), this, CursorType::Frame, *aPam.GetPoint());
+ aRef = static_cast<text::XWordCursor*>(pXCursor);
+
+ return aRef;
+}
+
+uno::Reference< text::XTextCursor > SwXTextFrame::createTextCursorByRange(const uno::Reference< text::XTextRange > & aTextPosition)
+{
+ SolarMutexGuard aGuard;
+ SwFrameFormat* pFormat = GetFrameFormat();
+ if (!pFormat)
+ throw uno::RuntimeException();
+ SwUnoInternalPaM aPam(*GetDoc());
+ if (!::sw::XTextRangeToSwPaM(aPam, aTextPosition))
+ throw uno::RuntimeException();
+
+ uno::Reference<text::XTextCursor> aRef;
+ SwNode& rNode = pFormat->GetContent().GetContentIdx()->GetNode();
+ if(aPam.GetNode().FindFlyStartNode() == rNode.FindFlyStartNode())
+ {
+ aRef = static_cast<text::XWordCursor*>(
+ 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 );
+}
+
+sal_Int64 SAL_CALL SwXTextFrame::getSomething( const uno::Sequence< sal_Int8 >& rId )
+{
+ sal_Int64 nRet = SwXFrame::getSomething( rId );
+ if( !nRet )
+ nRet = SwXText::getSomething( rId );
+
+ return nRet;
+}
+
+::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()
+{
+}
+
+uno::Reference<text::XTextContent>
+SwXTextGraphicObject::CreateXTextGraphicObject(SwDoc & rDoc, SwFrameFormat *const pFrameFormat)
+{
+ return CreateXFrame<text::XTextContent, 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()
+{
+}
+
+uno::Reference<text::XTextContent>
+SwXTextEmbeddedObject::CreateXTextEmbeddedObject(SwDoc & rDoc, SwFrameFormat *const pFrameFormat)
+{
+ return CreateXFrame<text::XTextContent, 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 > const & xOLE)
+ : m_pOLEFormat(&rOLEFormat)
+ , m_xOLEModel(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 000000000..f9efe7742
--- /dev/null
+++ b/sw/source/core/unocore/unoftn.cxx
@@ -0,0 +1,575 @@
+/* -*- 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/interfacecontainer2.hxx>
+#include <comphelper/sequence.hxx>
+#include <comphelper/servicehelper.hxx>
+#include <cppuhelper/supportsservice.hxx>
+#include <svl/listener.hxx>
+#include <osl/mutex.hxx>
+
+#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.begin(),
+ [](const char* pService) -> OUString { return OUString::createFromAscii(pService); });
+
+ return ret;
+}
+
+}
+
+class SwXFootnote::Impl
+ : public SvtListener
+{
+private:
+ ::osl::Mutex m_Mutex; // just for OInterfaceContainerHelper2
+
+public:
+
+ SwXFootnote& m_rThis;
+ uno::WeakReference<uno::XInterface> m_wThis;
+ const bool m_bIsEndnote;
+ ::comphelper::OInterfaceContainerHelper2 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_EventListeners(m_Mutex)
+ , 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);
+ m_EventListeners.disposeAndClear(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()
+{
+}
+
+uno::Reference<text::XFootnote>
+SwXFootnote::CreateXFootnote(SwDoc & rDoc, SwFormatFootnote *const pFootnoteFormat,
+ bool const isEndnote)
+{
+ // i#105557: do not iterate over the registered clients: race condition
+ uno::Reference<text::XFootnote> xNote;
+ if (pFootnoteFormat)
+ {
+ xNote = pFootnoteFormat->GetXFootnote();
+ }
+ if (!xNote.is())
+ {
+ SwXFootnote *const pNote(pFootnoteFormat
+ ? new SwXFootnote(rDoc, *pFootnoteFormat)
+ : new SwXFootnote(isEndnote));
+ xNote.set(pNote);
+ if (pFootnoteFormat)
+ {
+ pFootnoteFormat->SetXFootnote(xNote);
+ }
+ // need a permanent Reference to initialize m_wThis
+ pNote->m_pImpl->m_wThis = xNote;
+ }
+ return xNote;
+}
+
+namespace
+{
+ class theSwXFootnoteUnoTunnelId : public rtl::Static< UnoTunnelIdInit, theSwXFootnoteUnoTunnelId > {};
+}
+
+const uno::Sequence< sal_Int8 > & SwXFootnote::getUnoTunnelId()
+{
+ return theSwXFootnoteUnoTunnelId::get().getSeq();
+}
+
+sal_Int64 SAL_CALL
+SwXFootnote::getSomething(const uno::Sequence< sal_Int8 >& rId)
+{
+ const sal_Int64 nRet( ::sw::UnoTunnelImpl<SwXFootnote>(rId, this) );
+ return nRet ? nRet : SwXText::getSomething(rId);
+}
+
+OUString SAL_CALL
+SwXFootnote::getImplementationName()
+{
+ return "SwXFootnote";
+}
+
+static 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!
+};
+
+static const size_t g_nServicesEndnote( SAL_N_ELEMENTS(g_ServicesFootnote) );
+
+static 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();
+ }
+ const uno::Reference<lang::XUnoTunnel> xRangeTunnel(
+ xTextRange, uno::UNO_QUERY);
+ SwXTextRange *const pRange =
+ ::sw::UnoTunnelGetImplementation<SwXTextRange>(xRangeTunnel);
+ OTextCursorHelper *const pCursor =
+ ::sw::UnoTunnelGetImplementation<OTextCursorHelper>(xRangeTunnel);
+ 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.GetNode().GetTextNode()->GetTextAttrForCharAt(
+ aPam.GetPoint()->nContent.GetIndex()-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
+ m_pImpl->m_EventListeners.addInterface(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
+ m_pImpl->m_EventListeners.removeInterface(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;
+}
+
+uno::Reference< text::XTextCursor >
+SwXFootnote::CreateCursor()
+{
+ return createTextCursor();
+}
+
+uno::Reference< text::XTextCursor > SAL_CALL
+SwXFootnote::createTextCursor()
+{
+ SolarMutexGuard aGuard;
+
+ SwFormatFootnote const& rFormat( m_pImpl->GetFootnoteFormatOrThrow() );
+
+ SwTextFootnote const*const pTextFootnote = rFormat.GetTextFootnote();
+ SwPosition aPos( *pTextFootnote->GetStartNode() );
+ SwXTextCursor *const pXCursor =
+ new SwXTextCursor(*GetDoc(), this, CursorType::Footnote, aPos);
+ auto& rUnoCursor(pXCursor->GetCursor());
+ rUnoCursor.Move(fnMoveForward, GoInNode);
+ const uno::Reference< text::XTextCursor > xRet =
+ static_cast<text::XWordCursor*>(pXCursor);
+ return xRet;
+}
+
+uno::Reference< text::XTextCursor > SAL_CALL
+SwXFootnote::createTextCursorByRange(
+ const uno::Reference< text::XTextRange > & xTextPosition)
+{
+ SolarMutexGuard aGuard;
+
+ 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.GetNode().FindFootnoteStartNode();
+ if (pStart != pFootnoteStartNode)
+ {
+ throw uno::RuntimeException();
+ }
+
+ const uno::Reference< text::XTextCursor > xRet =
+ static_cast<text::XWordCursor*>(
+ 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
+ {
+ beans::UnknownPropertyException aExcept;
+ aExcept.Message = rPropertyName;
+ throw aExcept;
+ }
+ }
+ 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 000000000..873058e98
--- /dev/null
+++ b/sw/source/core/unocore/unoidx.cxx
@@ -0,0 +1,3118 @@
+/* -*- 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 <osl/mutex.hxx>
+#include <cppuhelper/interfacecontainer.h>
+#include <comphelper/interfacecontainer2.hxx>
+#include <cppuhelper/supportsservice.hxx>
+#include <vcl/svapp.hxx>
+#include <i18nlangtag/languagetag.hxx>
+#include <editeng/memberids.h>
+#include <hints.hxx>
+#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>
+
+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* pDoc, SwTOXBase& rTOXBase, const OUString& rNewName)
+{
+ const sal_uInt16 nUserCount = pDoc->GetTOXTypeCount( TOX_USER );
+ const SwTOXType* pNewType = nullptr;
+ for(sal_uInt16 nUser = 0; nUser < nUserCount; nUser++)
+ {
+ const SwTOXType* pType = pDoc->GetTOXType( TOX_USER, nUser );
+ if (pType->GetTypeName()==rNewName)
+ {
+ pNewType = pType;
+ break;
+ }
+ }
+ if(!pNewType)
+ {
+ SwTOXType aNewType(*pDoc, TOX_USER, rNewName);
+ pNewType = pDoc->InsertTOXType( aNewType );
+ }
+
+ rTOXBase.RegisterToTOXType( *const_cast<SwTOXType*>(pNewType) );
+}
+
+static const char cUserDefined[] = "User-Defined";
+static 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.matchAsciiL(cUserDefined, sizeof(cUserDefined)) &&
+ rTmp.matchAsciiL(cUserSuffix, sizeof(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:
+ ::osl::Mutex m_Mutex; // just for OInterfaceContainerHelper2
+ SwSectionFormat* m_pFormat;
+
+public:
+ uno::WeakReference<uno::XInterface> m_wThis;
+ ::cppu::OMultiTypeInterfaceContainerHelper m_Listeners;
+ SfxItemPropertySet const& m_rPropSet;
+ const TOXTypes m_eTOXType;
+ bool m_bIsDescriptor;
+ SwDoc* m_pDoc;
+ std::unique_ptr<SwDocIndexDescriptorProperties_Impl> m_pProps;
+ 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_Listeners(m_Mutex)
+ , m_rPropSet(*aSwMapProvider.GetPropertySet(lcl_TypeToPropertyMap_Index(eType)))
+ , m_eTOXType(eType)
+ , m_bIsDescriptor(nullptr == pBaseSection)
+ , m_pDoc(&rDoc)
+ , m_pProps(m_bIsDescriptor
+ ? new SwDocIndexDescriptorProperties_Impl(rDoc.GetTOXType(eType, 0))
+ : nullptr)
+ {
+ 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
+ ? &m_pProps->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(auto pLegacy = dynamic_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();
+ 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_Listeners.disposeAndClear(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()
+{
+}
+
+uno::Reference<text::XDocumentIndex>
+SwXDocumentIndex::CreateXDocumentIndex(
+ SwDoc & rDoc, SwTOXBaseSection * pSection, TOXTypes const eTypes)
+{
+ // re-use existing SwXDocumentIndex
+ // #i105557#: do not iterate over the registered clients: race condition
+ uno::Reference<text::XDocumentIndex> xIndex;
+ if (pSection)
+ {
+ SwSectionFormat const *const pFormat = pSection->GetFormat();
+ xIndex.set(pFormat->GetXObject(), uno::UNO_QUERY);
+ }
+ if (!xIndex.is())
+ {
+ SwXDocumentIndex *const pIndex(pSection
+ ? new SwXDocumentIndex(*pSection, rDoc)
+ : new SwXDocumentIndex(eTypes, rDoc));
+ xIndex.set(pIndex);
+ if (pSection)
+ {
+ pSection->GetFormat()->SetXObject(xIndex);
+ }
+ // need a permanent Reference to initialize m_wThis
+ pIndex->m_pImpl->m_wThis = xIndex;
+ }
+ return xIndex;
+}
+
+namespace
+{
+ class theSwXDocumentIndexUnoTunnelId : public rtl::Static< UnoTunnelIdInit, theSwXDocumentIndexUnoTunnelId > {};
+}
+
+const uno::Sequence< sal_Int8 > & SwXDocumentIndex::getUnoTunnelId()
+{
+ return theSwXDocumentIndexUnoTunnelId::get().getSeq();
+}
+
+sal_Int64 SAL_CALL
+SwXDocumentIndex::getSomething(const uno::Sequence< sal_Int8 >& rId)
+{
+ return ::sw::UnoTunnelImpl<SwXDocumentIndex>(rId, this);
+}
+
+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;
+
+ SfxItemPropertySimpleEntry const*const pEntry =
+ m_pImpl->m_rPropSet.getPropertyMap().getByName(rPropertyName);
+ if (!pEntry)
+ {
+ throw beans::UnknownPropertyException(
+ "Unknown property: " + rPropertyName,
+ static_cast<cppu::OWeakObject *>(this));
+ }
+ if (pEntry->nFlags & beans::PropertyAttribute::READONLY)
+ {
+ throw beans::PropertyVetoException(
+ "Property is read-only: " + rPropertyName,
+ static_cast<cppu::OWeakObject *>(this));
+ }
+
+ 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_pProps->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_INDEX_ENTRY_TYPE:
+ {
+ rTOXBase.SetEntryTypeName(lcl_AnyToType<OUString>(rValue));
+ nCreate = SwTOXElement::IndexEntryType;
+ 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_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;
+ SfxItemPropertySimpleEntry const*const pEntry =
+ m_pImpl->m_rPropSet.getPropertyMap().getByName(rPropertyName);
+ if (!pEntry)
+ {
+ throw beans::UnknownPropertyException(
+ "Unknown property: " + rPropertyName,
+ static_cast< cppu::OWeakObject * >(this));
+ }
+ // 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_pProps->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_pProps->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_INDEX_ENTRY_TYPE :
+ aRet <<= pTOXBase->GetEntryTypeName();
+ 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_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();
+ SwTOXMark::InsertTOXMarks( aMarks, *pType );
+ 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",
+ static_cast< ::cppu::OWeakObject*>(this));
+ }
+ 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();
+ }
+
+ ::cppu::OInterfaceContainerHelper *const pContainer(
+ m_pImpl->m_Listeners.getContainer(
+ cppu::UnoType<util::XRefreshListener>::get()));
+ if (pContainer)
+ {
+ lang::EventObject const event(static_cast< ::cppu::OWeakObject*>(this));
+ pContainer->notifyEach(& 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
+ m_pImpl->m_Listeners.addInterface(
+ cppu::UnoType<util::XRefreshListener>::get(), 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
+ m_pImpl->m_Listeners.removeInterface(
+ cppu::UnoType<util::XRefreshListener>::get(), xListener);
+}
+
+void SAL_CALL
+SwXDocumentIndex::attach(const uno::Reference< text::XTextRange > & xTextRange)
+{
+ SolarMutexGuard aGuard;
+
+ if (!m_pImpl->m_bIsDescriptor)
+ {
+ throw uno::RuntimeException();
+ }
+ const uno::Reference<XUnoTunnel> xRangeTunnel( xTextRange, uno::UNO_QUERY);
+ SwXTextRange *const pRange =
+ ::sw::UnoTunnelGetImplementation<SwXTextRange>(xRangeTunnel);
+ OTextCursorHelper *const pCursor =
+ ::sw::UnoTunnelGetImplementation<OTextCursorHelper>(xRangeTunnel);
+
+ 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_pProps->GetTOXBase();
+ SwTOXType const*const pTOXType = rTOXBase.GetTOXType();
+ if ((TOX_USER == pTOXType->GetType()) &&
+ m_pImpl->m_pProps->GetTypeName() != pTOXType->GetTypeName())
+ {
+ lcl_ReAssignTOXType(pDoc, rTOXBase, m_pImpl->m_pProps->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_pProps->GetTOXBase().GetTOXName());
+
+ // update page numbers
+ m_pImpl->SetSectionFormat(*pTOX->GetFormat());
+ pTOX->GetFormat()->SetXObject(static_cast< ::cppu::OWeakObject*>(this));
+ pTOX->UpdatePageNum();
+
+ m_pImpl->m_pProps.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();
+ }
+
+ uno::Reference< text::XTextRange > 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()->nNode = *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
+ m_pImpl->m_Listeners.addInterface(
+ cppu::UnoType<lang::XEventListener>::get(), 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
+ m_pImpl->m_Listeners.removeInterface(
+ cppu::UnoType<lang::XEventListener>::get(), xListener);
+}
+
+OUString SAL_CALL SwXDocumentIndex::getName()
+{
+ SolarMutexGuard g;
+
+ SwSectionFormat *const pSectionFormat( m_pImpl->GetSectionFormat() );
+ if (m_pImpl->m_bIsDescriptor)
+ {
+ return m_pImpl->m_pProps->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_pProps->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:
+ ::osl::Mutex m_Mutex; // just for OInterfaceContainerHelper2
+ SwXDocumentIndexMark & m_rThis;
+ bool m_bInReplaceMark;
+
+public:
+
+ uno::WeakReference<uno::XInterface> m_wThis;
+ SfxItemPropertySet const& m_rPropSet;
+ const TOXTypes m_eTOXType;
+ ::comphelper::OInterfaceContainerHelper2 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_aEntryTypeName;
+ 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_EventListeners(m_Mutex)
+ , 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(SwTOXType & rTOXType, SwTOXMark & rMark, SwPaM & rPam,
+ SwXTextCursor const*const pTextCursor);
+
+ void ReplaceTOXMark(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(
+ static_cast< ::cppu::OWeakObject&>(m_rThis));
+ m_EventListeners.disposeAndClear(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!
+ {
+ uno::Reference<uno::XInterface> 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);
+ m_EventListeners.disposeAndClear(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,
+ SwTOXType & rType, SwTOXMark & rMark)
+ : m_pImpl( new SwXDocumentIndexMark::Impl(*this, &rDoc, rType.GetType(),
+ &rType, &rMark) )
+{
+}
+
+SwXDocumentIndexMark::~SwXDocumentIndexMark()
+{
+}
+
+uno::Reference<text::XDocumentIndexMark>
+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
+ uno::Reference<text::XDocumentIndexMark> xTOXMark;
+ if (pMark)
+ {
+ xTOXMark = pMark->GetXTOXMark();
+ }
+ if (!xTOXMark.is())
+ {
+ SwXDocumentIndexMark *const pNew(pMark
+ ? new SwXDocumentIndexMark(rDoc,
+ *const_cast<SwTOXType*>(pMark->GetTOXType()), *pMark)
+ : new SwXDocumentIndexMark(eType));
+ xTOXMark.set(pNew);
+ if (pMark)
+ {
+ pMark->SetXTOXMark(xTOXMark);
+ }
+ // need a permanent Reference to initialize m_wThis
+ pNew->m_pImpl->m_wThis = xTOXMark;
+ }
+ return xTOXMark;
+}
+
+namespace
+{
+ class theSwXDocumentIndexMarkUnoTunnelId : public rtl::Static< UnoTunnelIdInit, theSwXDocumentIndexMarkUnoTunnelId > {};
+}
+
+const uno::Sequence< sal_Int8 > & SwXDocumentIndexMark::getUnoTunnelId()
+{
+ return theSwXDocumentIndexMarkUnoTunnelId::get().getSeq();
+}
+
+sal_Int64 SAL_CALL
+SwXDocumentIndexMark::getSomething(const uno::Sequence< sal_Int8 >& rId)
+{
+ return ::sw::UnoTunnelImpl<SwXDocumentIndexMark>(rId, this);
+}
+
+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()->nContent = *pTextMark->End();
+ }
+ else
+ ++aPam.GetPoint()->nContent;
+
+ 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();
+ }
+
+ const uno::Reference<XUnoTunnel> xRangeTunnel(xTextRange, uno::UNO_QUERY);
+ SwXTextRange *const pRange =
+ ::sw::UnoTunnelGetImplementation<SwXTextRange>(xRangeTunnel);
+ OTextCursorHelper *const pCursor =
+ ::sw::UnoTunnelGetImplementation<OTextCursorHelper>(xRangeTunnel);
+ 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(
+ SwTOXType & rTOXType, SwTOXMark & rMark, SwPaM & rPam,
+ SwXTextCursor const*const pTextCursor)
+{
+ SwDoc *const pDoc( rPam.GetDoc() );
+ UnoActionContext aAction(pDoc);
+ 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;
+ pDoc->getIDocumentContentOperations().InsertPoolItem(rPam, rMark, nInsertFlags,
+ /*pLayout*/nullptr, /*bExpandCharToPara*/false, &pNewTextAttr);
+ if (bMark && *rPam.GetPoint() > *rPam.GetMark())
+ {
+ rPam.Exchange();
+ }
+
+ if (!pNewTextAttr)
+ {
+ throw uno::RuntimeException(
+ "SwXDocumentIndexMark::InsertTOXMark(): cannot insert attribute",
+ nullptr);
+ }
+
+ m_pDoc = pDoc;
+ 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()->nContent = *pTextMark->End();
+ }
+ else
+ {
+ ++aPam.GetPoint()->nContent;
+ }
+ 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
+ m_pImpl->m_EventListeners.addInterface(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
+ m_pImpl->m_EventListeners.removeInterface(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;
+
+ SfxItemPropertySimpleEntry const*const pEntry =
+ m_pImpl->m_rPropSet.getPropertyMap().getByName(rPropertyName);
+ if (!pEntry)
+ {
+ throw beans::UnknownPropertyException(
+ "Unknown property: " + rPropertyName,
+ static_cast<cppu::OWeakObject *>(this));
+ }
+ if (pEntry->nFlags & beans::PropertyAttribute::READONLY)
+ {
+ throw beans::PropertyVetoException(
+ "Property is read-only: " + rPropertyName,
+ static_cast<cppu::OWeakObject *>(this));
+ }
+
+ 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_INDEX_ENTRY_TYPE :
+ aMark.SetEntryTypeName(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()->nContent = *pTextMark->End();
+ }
+ else
+ {
+ ++aPam.GetPoint()->nContent;
+ }
+
+ 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_INDEX_ENTRY_TYPE :
+ {
+ m_pImpl->m_aEntryTypeName = 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;
+ SfxItemPropertySimpleEntry const*const pEntry =
+ m_pImpl->m_rPropSet.getPropertyMap().getByName(rPropertyName);
+ if (!pEntry)
+ {
+ throw beans::UnknownPropertyException(
+ "Unknown property: " + rPropertyName,
+ static_cast<cppu::OWeakObject *>(this));
+ }
+ 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_INDEX_ENTRY_TYPE :
+ aRet <<= m_pImpl->m_pTOXMark->GetEntryTypeName();
+ 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_INDEX_ENTRY_TYPE :
+ aRet <<= m_pImpl->m_aEntryTypeName;
+ 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;
+
+ if(!IsValid())
+ throw uno::RuntimeException();
+
+ 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;
+
+ if(!IsValid())
+ throw uno::RuntimeException();
+
+ sal_Int32 nIdx = 0;
+
+ const SwSectionFormats& rFormats = GetDoc()->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(
+ *GetDoc(), 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;
+
+ if(!IsValid())
+ throw uno::RuntimeException();
+
+ const SwSectionFormats& rFormats = GetDoc()->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(
+ *GetDoc(), static_cast<SwTOXBaseSection *>(pSect));
+ uno::Any aRet;
+ aRet <<= xTmp;
+ return aRet;
+ }
+ }
+ throw container::NoSuchElementException();
+}
+
+uno::Sequence< OUString > SAL_CALL
+SwXDocumentIndexes::getElementNames()
+{
+ SolarMutexGuard aGuard;
+
+ if(!IsValid())
+ throw uno::RuntimeException();
+
+ 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;
+
+ if(!IsValid())
+ throw uno::RuntimeException();
+
+ 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(), static_cast<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(static_cast<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;
+};
+
+}
+
+static 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 = convertMm100ToTwip(nPosition);
+ 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::ISBN)
+ {
+ lang::IllegalArgumentException aExcept;
+ aExcept.Message = "BibliographyDataField - wrong value";
+ aExcept.ArgumentPosition = static_cast< sal_Int16 >(j);
+ throw aExcept;
+ }
+ 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(static_cast<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(static_cast<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/unomap.cxx b/sw/source/core/unocore/unomap.cxx
new file mode 100644
index 000000000..8da991f62
--- /dev/null
+++ b/sw/source/core/unocore/unomap.cxx
@@ -0,0 +1,1569 @@
+/* -*- 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/style/VerticalAlignment.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/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/colritem.hxx>
+#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 \
+ { OUString(UNO_NAME_IS_FIELD_USED), FIELD_PROP_IS_FIELD_USED, cppu::UnoType<float>::get(), PropertyAttribute::READONLY, 0},\
+ { OUString(UNO_NAME_IS_FIELD_DISPLAYED), FIELD_PROP_IS_FIELD_DISPLAYED, cppu::UnoType<sal_Int16>::get(), PropertyAttribute::READONLY, 0},\
+
+const SfxItemPropertyMapEntry* SwUnoPropertyMapProvider::GetPropertyMapEntries(sal_uInt16 nPropertyId)
+{
+ OSL_ENSURE(nPropertyId < PROPERTY_MAP_END, "Id ?" );
+ if( !m_aMapEntriesArr[ nPropertyId ] )
+ {
+ 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 [] =
+ {
+ { OUString(UNO_NAME_RUBY_ADJUST), RES_TXTATR_CJK_RUBY, cppu::UnoType<sal_Int16>::get(), PropertyAttribute::MAYBEVOID, MID_RUBY_ADJUST },
+ { OUString(UNO_NAME_RUBY_IS_ABOVE), RES_TXTATR_CJK_RUBY, cppu::UnoType<bool>::get(), PropertyAttribute::MAYBEVOID, MID_RUBY_ABOVE },
+ { OUString(UNO_NAME_RUBY_POSITION), RES_TXTATR_CJK_RUBY, cppu::UnoType<sal_Int16>::get(), PropertyAttribute::MAYBEVOID, MID_RUBY_POSITION },
+ { OUString(), 0, css::uno::Type(), 0, 0 }
+ };
+ 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 [] =
+ {
+ { OUString(UNO_NAME_NUMBERING_RULES), FN_UNO_NUM_RULES, cppu::UnoType<css::container::XIndexReplace>::get(), PROPERTY_NONE, CONVERT_TWIPS},
+ { OUString(UNO_NAME_IS_PHYSICAL), FN_UNO_IS_PHYSICAL, cppu::UnoType<bool>::get(), PropertyAttribute::READONLY, 0},
+ { OUString(UNO_NAME_DISPLAY_NAME), FN_UNO_DISPLAY_NAME, cppu::UnoType<OUString>::get(), PropertyAttribute::READONLY, 0},
+ { OUString(UNO_NAME_HIDDEN), FN_UNO_HIDDEN, cppu::UnoType<bool>::get(), PROPERTY_NONE, 0},
+ { OUString(UNO_NAME_STYLE_INTEROP_GRAB_BAG), FN_UNO_STYLE_INTEROP_GRAB_BAG, cppu::UnoType< cppu::UnoSequenceType<css::beans::PropertyValue> >::get(), PROPERTY_NONE, 0},
+ { OUString(), 0, css::uno::Type(), 0, 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[] =
+ {
+ { OUString(UNO_NAME_BACK_COLOR), RES_BACKGROUND, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE , MID_BACK_COLOR },
+ { OUString(UNO_NAME_BACK_GRAPHIC_URL), RES_BACKGROUND, cppu::UnoType<OUString>::get(), PROPERTY_NONE ,MID_GRAPHIC_URL },
+ { OUString(UNO_NAME_BACK_GRAPHIC), RES_BACKGROUND, cppu::UnoType<graphic::XGraphic>::get(), PROPERTY_NONE, MID_GRAPHIC },
+ { OUString(UNO_NAME_BACK_GRAPHIC_FILTER), RES_BACKGROUND, cppu::UnoType<OUString>::get(), PROPERTY_NONE ,MID_GRAPHIC_FILTER },
+ { OUString(UNO_NAME_BACK_GRAPHIC_LOCATION), RES_BACKGROUND, cppu::UnoType<css::style::GraphicLocation>::get(), PROPERTY_NONE ,MID_GRAPHIC_POSITION},
+ { OUString(UNO_NAME_BACK_TRANSPARENT), RES_BACKGROUND, cppu::UnoType<bool>::get(), PROPERTY_NONE , MID_GRAPHIC_TRANSPARENT },
+ { OUString(UNO_NAME_NUMBER_FORMAT), RES_BOXATR_FORMAT, cppu::UnoType<sal_Int32>::get(), PropertyAttribute::MAYBEVOID ,0 },
+ { OUString(UNO_NAME_LEFT_BORDER), RES_BOX, cppu::UnoType<css::table::BorderLine>::get(), 0, LEFT_BORDER |CONVERT_TWIPS },
+ { OUString(UNO_NAME_RIGHT_BORDER), RES_BOX, cppu::UnoType<css::table::BorderLine>::get(), 0, RIGHT_BORDER |CONVERT_TWIPS },
+ { OUString(UNO_NAME_TOP_BORDER), RES_BOX, cppu::UnoType<css::table::BorderLine>::get(), 0, TOP_BORDER |CONVERT_TWIPS },
+ { OUString(UNO_NAME_BOTTOM_BORDER), RES_BOX, cppu::UnoType<css::table::BorderLine>::get(), 0, BOTTOM_BORDER|CONVERT_TWIPS },
+ { OUString(UNO_NAME_BORDER_DISTANCE), RES_BOX, cppu::UnoType<sal_Int32>::get(), 0, BORDER_DISTANCE|CONVERT_TWIPS },
+ { OUString(UNO_NAME_LEFT_BORDER_DISTANCE), RES_BOX, cppu::UnoType<sal_Int32>::get(), 0, LEFT_BORDER_DISTANCE |CONVERT_TWIPS },
+ { OUString(UNO_NAME_RIGHT_BORDER_DISTANCE), RES_BOX, cppu::UnoType<sal_Int32>::get(), 0, RIGHT_BORDER_DISTANCE |CONVERT_TWIPS },
+ { OUString(UNO_NAME_TOP_BORDER_DISTANCE), RES_BOX, cppu::UnoType<sal_Int32>::get(), 0, TOP_BORDER_DISTANCE |CONVERT_TWIPS },
+ { OUString(UNO_NAME_BOTTOM_BORDER_DISTANCE), RES_BOX, cppu::UnoType<sal_Int32>::get(), 0, BOTTOM_BORDER_DISTANCE|CONVERT_TWIPS },
+ { OUString(UNO_NAME_USER_DEFINED_ATTRIBUTES), RES_UNKNOWNATR_CONTAINER, cppu::UnoType<css::container::XNameContainer>::get(), PropertyAttribute::MAYBEVOID, 0 },
+ { OUString(UNO_NAME_TEXT_SECTION), FN_UNO_TEXT_SECTION, cppu::UnoType<css::text::XTextSection>::get(), PropertyAttribute::MAYBEVOID|PropertyAttribute::READONLY ,0 },
+ { OUString(UNO_NAME_IS_PROTECTED), RES_PROTECT, cppu::UnoType<bool>::get(), 0, MID_PROTECT_CONTENT},
+ { OUString(UNO_NAME_CELL_NAME), FN_UNO_CELL_NAME, cppu::UnoType<OUString>::get(), PropertyAttribute::READONLY,0},
+ { OUString(UNO_NAME_VERT_ORIENT), RES_VERT_ORIENT, cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE ,MID_VERTORIENT_ORIENT },
+ { OUString(UNO_NAME_WRITING_MODE), RES_FRAMEDIR, cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE, 0 },
+ { OUString(UNO_NAME_ROW_SPAN), FN_UNO_CELL_ROW_SPAN, cppu::UnoType<sal_Int32>::get(), 0, 0 },
+ { OUString(UNO_NAME_CELL_INTEROP_GRAB_BAG), RES_FRMATR_GRABBAG, cppu::UnoType< cppu::UnoSequenceType<css::beans::PropertyValue> >::get(), PROPERTY_NONE, 0 },
+ { OUString(UNO_NAME_PARENT_TEXT), FN_UNO_PARENT_TEXT, cppu::UnoType<text::XText>::get(), PropertyAttribute::MAYBEVOID | PropertyAttribute::READONLY, 0 },
+ REDLINE_NODE_PROPERTIES
+ { OUString(), 0, css::uno::Type(), 0, 0 }
+ };
+ 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[] =
+ {
+ { OUString(UNO_NAME_SEARCH_ALL), WID_SEARCH_ALL, cppu::UnoType<bool>::get() , PROPERTY_NONE, 0},
+ { OUString(UNO_NAME_SEARCH_BACKWARDS), WID_BACKWARDS, cppu::UnoType<bool>::get() , PROPERTY_NONE, 0},
+ { OUString(UNO_NAME_SEARCH_CASE_SENSITIVE), WID_CASE_SENSITIVE, cppu::UnoType<bool>::get() , PROPERTY_NONE, 0},
+ { OUString(UNO_NAME_SEARCH_REGULAR_EXPRESSION), WID_REGULAR_EXPRESSION, cppu::UnoType<bool>::get() , PROPERTY_NONE, 0},
+ { OUString(UNO_NAME_SEARCH_SIMILARITY), WID_SIMILARITY, cppu::UnoType<bool>::get() , PROPERTY_NONE, 0},
+ { OUString(UNO_NAME_SEARCH_SIMILARITY_ADD), WID_SIMILARITY_ADD, cppu::UnoType<sal_Int16>::get() , PROPERTY_NONE, 0},
+ { OUString(UNO_NAME_SEARCH_SIMILARITY_EXCHANGE), WID_SIMILARITY_EXCHANGE,cppu::UnoType<sal_Int16>::get() , PROPERTY_NONE, 0},
+ { OUString(UNO_NAME_SEARCH_SIMILARITY_RELAX), WID_SIMILARITY_RELAX, cppu::UnoType<bool>::get() , PROPERTY_NONE, 0},
+ { OUString(UNO_NAME_SEARCH_SIMILARITY_REMOVE), WID_SIMILARITY_REMOVE, cppu::UnoType<sal_Int16>::get() , PROPERTY_NONE, 0},
+ { OUString(UNO_NAME_SEARCH_STYLES), WID_STYLES, cppu::UnoType<bool>::get() , PROPERTY_NONE, 0},
+ { OUString(UNO_NAME_SEARCH_WORDS), WID_WORDS, cppu::UnoType<bool>::get() , PROPERTY_NONE, 0},
+ { OUString(), 0, css::uno::Type(), 0, 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_SHAPE:
+ {
+ static SfxItemPropertyMapEntry const aShapeMap_Impl[] =
+ {
+ { OUString(UNO_NAME_ANCHOR_PAGE_NO), RES_ANCHOR, cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE|PropertyAttribute::MAYBEVOID, MID_ANCHOR_PAGENUM },
+ { OUString(UNO_NAME_ANCHOR_TYPE), RES_ANCHOR, cppu::UnoType<css::text::TextContentAnchorType>::get(), PROPERTY_NONE|PropertyAttribute::MAYBEVOID, MID_ANCHOR_ANCHORTYPE},
+ { OUString(UNO_NAME_ANCHOR_FRAME), RES_ANCHOR, cppu::UnoType<css::text::XTextFrame>::get(), PropertyAttribute::MAYBEVOID, MID_ANCHOR_ANCHORFRAME},
+ { OUString(UNO_NAME_HORI_ORIENT), RES_HORI_ORIENT, cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE|PropertyAttribute::MAYBEVOID ,MID_HORIORIENT_ORIENT },
+ { OUString(UNO_NAME_HORI_ORIENT_POSITION), RES_HORI_ORIENT, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE|PropertyAttribute::MAYBEVOID ,MID_HORIORIENT_POSITION|CONVERT_TWIPS },
+ { OUString(UNO_NAME_HORI_ORIENT_RELATION), RES_HORI_ORIENT, cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE|PropertyAttribute::MAYBEVOID ,MID_HORIORIENT_RELATION },
+ { OUString(UNO_NAME_LEFT_MARGIN), RES_LR_SPACE, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE|PropertyAttribute::MAYBEVOID, MID_L_MARGIN|CONVERT_TWIPS},
+ { OUString(UNO_NAME_RIGHT_MARGIN), RES_LR_SPACE, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE|PropertyAttribute::MAYBEVOID, MID_R_MARGIN|CONVERT_TWIPS},
+ { OUString(UNO_NAME_SURROUND), RES_SURROUND, cppu::UnoType<css::text::WrapTextMode>::get(), PROPERTY_NONE|PropertyAttribute::MAYBEVOID, MID_SURROUND_SURROUNDTYPE },
+ { OUString(UNO_NAME_TEXT_WRAP), RES_SURROUND, cppu::UnoType<css::text::WrapTextMode>::get(), PROPERTY_NONE, MID_SURROUND_SURROUNDTYPE },
+ { OUString(UNO_NAME_SURROUND_ANCHORONLY), RES_SURROUND, cppu::UnoType<bool>::get(), PROPERTY_NONE|PropertyAttribute::MAYBEVOID, MID_SURROUND_ANCHORONLY },
+ { OUString(UNO_NAME_SURROUND_CONTOUR), RES_SURROUND, cppu::UnoType<bool>::get(), PROPERTY_NONE, MID_SURROUND_CONTOUR },
+ { OUString(UNO_NAME_CONTOUR_OUTSIDE), RES_SURROUND, cppu::UnoType<bool>::get(), PROPERTY_NONE, MID_SURROUND_CONTOUROUTSIDE },
+ { OUString(UNO_NAME_TOP_MARGIN), RES_UL_SPACE, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE, MID_UP_MARGIN|CONVERT_TWIPS},
+ { OUString(UNO_NAME_BOTTOM_MARGIN), RES_UL_SPACE, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE, MID_LO_MARGIN|CONVERT_TWIPS},
+ { OUString(UNO_NAME_VERT_ORIENT), RES_VERT_ORIENT, cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE|PropertyAttribute::MAYBEVOID ,MID_VERTORIENT_ORIENT },
+ { OUString(UNO_NAME_VERT_ORIENT_POSITION), RES_VERT_ORIENT, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE|PropertyAttribute::MAYBEVOID ,MID_VERTORIENT_POSITION|CONVERT_TWIPS },
+ { OUString(UNO_NAME_VERT_ORIENT_RELATION), RES_VERT_ORIENT, cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE|PropertyAttribute::MAYBEVOID ,MID_VERTORIENT_RELATION },
+ { OUString(UNO_NAME_TEXT_RANGE), FN_TEXT_RANGE, cppu::UnoType<css::text::XTextRange>::get(), PROPERTY_NONE, 0},
+ { OUString(UNO_NAME_OPAQUE), RES_OPAQUE, cppu::UnoType<bool>::get(), PROPERTY_NONE, 0},
+ { OUString(UNO_NAME_ANCHOR_POSITION), FN_ANCHOR_POSITION, cppu::UnoType<css::awt::Point>::get(), PropertyAttribute::READONLY, 0},
+ // #i26791#
+ { OUString(UNO_NAME_IS_FOLLOWING_TEXT_FLOW), RES_FOLLOW_TEXT_FLOW, cppu::UnoType<bool>::get(), PROPERTY_NONE, MID_FOLLOW_TEXT_FLOW},
+ // #i28701#
+ { OUString(UNO_NAME_WRAP_INFLUENCE_ON_POSITION), RES_WRAP_INFLUENCE_ON_OBJPOS, cppu::UnoType<sal_Int8>::get(), PROPERTY_NONE, MID_WRAP_INFLUENCE},
+ { OUString(UNO_NAME_ALLOW_OVERLAP), RES_WRAP_INFLUENCE_ON_OBJPOS, cppu::UnoType<bool>::get(), PROPERTY_NONE, MID_ALLOW_OVERLAP},
+ // #i28749#
+ { OUString(UNO_NAME_TRANSFORMATION_IN_HORI_L2R),
+ FN_SHAPE_TRANSFORMATION_IN_HORI_L2R,
+ cppu::UnoType<css::drawing::HomogenMatrix3>::get(),
+ PropertyAttribute::READONLY, 0},
+ { OUString(UNO_NAME_POSITION_LAYOUT_DIR),
+ FN_SHAPE_POSITION_LAYOUT_DIR,
+ cppu::UnoType<sal_Int16>::get(),
+ PROPERTY_NONE, 0},
+ // #i36248#
+ { OUString(UNO_NAME_STARTPOSITION_IN_HORI_L2R),
+ FN_SHAPE_STARTPOSITION_IN_HORI_L2R,
+ cppu::UnoType<css::awt::Point>::get(),
+ PropertyAttribute::READONLY, 0},
+ { OUString(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>
+ { OUString(UNO_NAME_PAGE_TOGGLE), RES_HORI_ORIENT, cppu::UnoType<bool>::get(), PROPERTY_NONE ,MID_HORIORIENT_PAGETOGGLE },
+ { OUString(UNO_NAME_RELATIVE_HEIGHT), RES_FRM_SIZE, cppu::UnoType<sal_Int16>::get() , PROPERTY_NONE, MID_FRMSIZE_REL_HEIGHT },
+ { OUString(UNO_NAME_RELATIVE_HEIGHT_RELATION), RES_FRM_SIZE, cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE, MID_FRMSIZE_REL_HEIGHT_RELATION },
+ { OUString(UNO_NAME_RELATIVE_WIDTH), RES_FRM_SIZE, cppu::UnoType<sal_Int16>::get() , PROPERTY_NONE, MID_FRMSIZE_REL_WIDTH },
+ { OUString(UNO_NAME_RELATIVE_WIDTH_RELATION), RES_FRM_SIZE, cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE, MID_FRMSIZE_REL_WIDTH_RELATION },
+ { OUString(UNO_NAME_TEXT_BOX), FN_TEXT_BOX, cppu::UnoType<bool>::get(), PROPERTY_NONE, 0},
+ { OUString(UNO_NAME_CHAIN_NEXT_NAME), RES_CHAIN, cppu::UnoType<OUString>::get(), PropertyAttribute::MAYBEVOID ,MID_CHAIN_NEXTNAME},
+ { OUString(UNO_NAME_CHAIN_PREV_NAME), RES_CHAIN, cppu::UnoType<OUString>::get(), PropertyAttribute::MAYBEVOID ,MID_CHAIN_PREVNAME},
+ { OUString(UNO_NAME_CHAIN_NAME), RES_CHAIN, cppu::UnoType<OUString>::get(), PropertyAttribute::MAYBEVOID ,MID_CHAIN_NAME },
+ { OUString(), 0, css::uno::Type(), 0, 0 }
+ };
+ 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_
+ { OUString(UNO_NAME_CREATE_FROM_CHAPTER), WID_CREATE_FROM_CHAPTER , cppu::UnoType<bool>::get() , PROPERTY_NONE, 0},
+ { OUString(UNO_NAME_IS_PROTECTED), WID_PROTECTED , cppu::UnoType<bool>::get() , PROPERTY_NONE, 0},
+ { OUString(UNO_NAME_USE_ALPHABETICAL_SEPARATORS), WID_USE_ALPHABETICAL_SEPARATORS , cppu::UnoType<bool>::get() , PROPERTY_NONE, 0},
+ { OUString(UNO_NAME_USE_KEY_AS_ENTRY), WID_USE_KEY_AS_ENTRY , cppu::UnoType<bool>::get() , PROPERTY_NONE, 0},
+ { OUString(UNO_NAME_USE_COMBINED_ENTRIES), WID_USE_COMBINED_ENTRIES , cppu::UnoType<bool>::get() , PROPERTY_NONE, 0},
+ { OUString(UNO_NAME_IS_CASE_SENSITIVE), WID_IS_CASE_SENSITIVE , cppu::UnoType<bool>::get() , PROPERTY_NONE, 0},
+ { OUString(UNO_NAME_USE_P_P), WID_USE_P_P , cppu::UnoType<bool>::get() , PROPERTY_NONE, 0},
+ { OUString(UNO_NAME_USE_DASH), WID_USE_DASH , cppu::UnoType<bool>::get() , PROPERTY_NONE, 0},
+ { OUString(UNO_NAME_USE_UPPER_CASE), WID_USE_UPPER_CASE , cppu::UnoType<bool>::get() , PROPERTY_NONE, 0},
+ { OUString(UNO_NAME_LEVEL_FORMAT), WID_LEVEL_FORMAT , cppu::UnoType<css::container::XIndexReplace>::get() , PROPERTY_NONE, 0},
+ { OUString(UNO_NAME_MAIN_ENTRY_CHARACTER_STYLE_NAME), WID_MAIN_ENTRY_CHARACTER_STYLE_NAME , cppu::UnoType<OUString>::get() , PROPERTY_NONE, 0},
+ { OUString(UNO_NAME_TEXT_COLUMNS), RES_COL, cppu::UnoType<css::text::XTextColumns>::get(), PROPERTY_NONE, MID_COLUMNS},
+ { OUString(UNO_NAME_BACK_GRAPHIC_URL), RES_BACKGROUND, cppu::UnoType<OUString>::get(), PROPERTY_NONE ,MID_GRAPHIC_URL },
+ { OUString(UNO_NAME_BACK_GRAPHIC), RES_BACKGROUND, cppu::UnoType<graphic::XGraphic>::get(), PROPERTY_NONE, MID_GRAPHIC },
+ { OUString(UNO_NAME_BACK_GRAPHIC_FILTER), RES_BACKGROUND, cppu::UnoType<OUString>::get(), PROPERTY_NONE ,MID_GRAPHIC_FILTER },
+ { OUString(UNO_NAME_BACK_GRAPHIC_LOCATION), RES_BACKGROUND, cppu::UnoType<css::style::GraphicLocation>::get(), PROPERTY_NONE ,MID_GRAPHIC_POSITION},
+ { OUString(UNO_NAME_BACK_COLOR), RES_BACKGROUND, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE ,MID_BACK_COLOR },
+ { OUString(UNO_NAME_BACK_TRANSPARENT), RES_BACKGROUND, cppu::UnoType<bool>::get(), PROPERTY_NONE ,MID_GRAPHIC_TRANSPARENT },
+ { OUString(UNO_NAME_PARA_STYLEHEADING), WID_PARA_HEAD, cppu::UnoType<OUString>::get() , 0, 0},
+ { OUString(UNO_NAME_PARA_STYLESEPARATOR), WID_PARA_SEP, cppu::UnoType<OUString>::get() , 0, 0},
+ { OUString(UNO_NAME_PARA_STYLELEVEL1), WID_PARA_LEV1, cppu::UnoType<OUString>::get() , 0, 0},
+ { OUString(UNO_NAME_PARA_STYLELEVEL2), WID_PARA_LEV2, cppu::UnoType<OUString>::get() , 0, 0},
+ { OUString(UNO_NAME_PARA_STYLELEVEL3), WID_PARA_LEV3, cppu::UnoType<OUString>::get() , 0, 0},
+ { OUString(UNO_NAME_IS_COMMA_SEPARATED), WID_IS_COMMA_SEPARATED, cppu::UnoType<bool>::get(), PROPERTY_NONE ,0 },
+ { OUString(UNO_NAME_DOCUMENT_INDEX_MARKS), WID_INDEX_MARKS, cppu::UnoType< cppu::UnoSequenceType<css::text::XDocumentIndexMark> >::get(), PropertyAttribute::READONLY ,0 },
+ { OUString(UNO_NAME_IS_RELATIVE_TABSTOPS), WID_IS_RELATIVE_TABSTOPS, cppu::UnoType<bool>::get(), PROPERTY_NONE, 0},
+ { OUString(UNO_NAME_LOCALE), WID_IDX_LOCALE, cppu::UnoType<css::lang::Locale>::get(), PROPERTY_NONE, 0},
+ { OUString(UNO_NAME_SORT_ALGORITHM), WID_IDX_SORT_ALGORITHM, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ { OUString(UNO_NAME_INDEX_ENTRY_TYPE), WID_INDEX_ENTRY_TYPE, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ { OUString(), 0, css::uno::Type(), 0, 0 }
+ };
+ m_aMapEntriesArr[nPropertyId] = aTOXIndexMap_Impl;
+ }
+ break;
+ case PROPERTY_MAP_INDEX_CNTNT:
+ {
+ static SfxItemPropertyMapEntry const aTOXContentMap_Impl[] =
+ {
+ BASE_INDEX_PROPERTIES_
+ { OUString(UNO_NAME_LEVEL), WID_LEVEL , cppu::UnoType<sal_Int16>::get() , PROPERTY_NONE, 0},
+ { OUString(UNO_NAME_CREATE_FROM_MARKS), WID_CREATE_FROM_MARKS , cppu::UnoType<bool>::get() , PROPERTY_NONE, 0},
+ { OUString(UNO_NAME_HIDE_TAB_LEADER_AND_PAGE_NUMBERS), WID_HIDE_TABLEADER_PAGENUMBERS , cppu::UnoType<bool>::get() , PROPERTY_NONE, 0},
+ { OUString(UNO_NAME_TAB_IN_TOC), WID_TAB_IN_TOC, cppu::UnoType<bool>::get(), PROPERTY_NONE, 0},
+ { OUString(UNO_NAME_TOC_BOOKMARK), WID_TOC_BOOKMARK, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ { OUString(UNO_NAME_TOC_NEWLINE), WID_TOC_NEWLINE, cppu::UnoType<bool>::get(), PROPERTY_NONE, 0},
+ { OUString(UNO_NAME_TOC_PARAGRAPH_OUTLINE_LEVEL), WID_TOC_PARAGRAPH_OUTLINE_LEVEL, cppu::UnoType<bool>::get(), PROPERTY_NONE, 0},
+ { OUString(UNO_NAME_CREATE_FROM_OUTLINE), WID_CREATE_FROM_OUTLINE , cppu::UnoType<bool>::get() , PROPERTY_NONE, 0},
+ { OUString(UNO_NAME_CREATE_FROM_CHAPTER), WID_CREATE_FROM_CHAPTER , cppu::UnoType<bool>::get() , PROPERTY_NONE, 0},
+ { OUString(UNO_NAME_IS_PROTECTED), WID_PROTECTED , cppu::UnoType<bool>::get() , PROPERTY_NONE, 0},
+ { OUString(UNO_NAME_LEVEL_FORMAT), WID_LEVEL_FORMAT , cppu::UnoType<css::container::XIndexReplace>::get() , PROPERTY_NONE, 0},
+ { OUString(UNO_NAME_LEVEL_PARAGRAPH_STYLES), WID_LEVEL_PARAGRAPH_STYLES , cppu::UnoType<css::container::XIndexReplace>::get() , PropertyAttribute::READONLY, 0},
+ { OUString(UNO_NAME_CREATE_FROM_LEVEL_PARAGRAPH_STYLES), WID_CREATE_FROM_PARAGRAPH_STYLES, cppu::UnoType<bool>::get(), PROPERTY_NONE, 0},
+ { OUString(UNO_NAME_TEXT_COLUMNS), RES_COL, cppu::UnoType<css::text::XTextColumns>::get(), PROPERTY_NONE, MID_COLUMNS},
+ { OUString(UNO_NAME_BACK_GRAPHIC_URL), RES_BACKGROUND, cppu::UnoType<OUString>::get(), PROPERTY_NONE ,MID_GRAPHIC_URL },
+ { OUString(UNO_NAME_BACK_GRAPHIC), RES_BACKGROUND, cppu::UnoType<graphic::XGraphic>::get(), PROPERTY_NONE, MID_GRAPHIC },
+ { OUString(UNO_NAME_BACK_GRAPHIC_FILTER), RES_BACKGROUND, cppu::UnoType<OUString>::get(), PROPERTY_NONE ,MID_GRAPHIC_FILTER },
+ { OUString(UNO_NAME_BACK_GRAPHIC_LOCATION), RES_BACKGROUND, cppu::UnoType<css::style::GraphicLocation>::get(), PROPERTY_NONE ,MID_GRAPHIC_POSITION},
+ { OUString(UNO_NAME_BACK_COLOR), RES_BACKGROUND, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE ,MID_BACK_COLOR },
+ { OUString(UNO_NAME_BACK_TRANSPARENT), RES_BACKGROUND, cppu::UnoType<bool>::get(), PROPERTY_NONE ,MID_GRAPHIC_TRANSPARENT },
+ { OUString(UNO_NAME_PARA_STYLEHEADING), WID_PARA_HEAD, cppu::UnoType<OUString>::get() , 0, 0},
+ { OUString(UNO_NAME_PARA_STYLELEVEL1), WID_PARA_LEV1, cppu::UnoType<OUString>::get() , 0, 0},
+ { OUString(UNO_NAME_PARA_STYLELEVEL2), WID_PARA_LEV2, cppu::UnoType<OUString>::get() , 0, 0},
+ { OUString(UNO_NAME_PARA_STYLELEVEL3), WID_PARA_LEV3, cppu::UnoType<OUString>::get() , 0, 0},
+ { OUString(UNO_NAME_PARA_STYLELEVEL4), WID_PARA_LEV4, cppu::UnoType<OUString>::get() , 0, 0},
+ { OUString(UNO_NAME_PARA_STYLELEVEL5), WID_PARA_LEV5, cppu::UnoType<OUString>::get() , 0, 0},
+ { OUString(UNO_NAME_PARA_STYLELEVEL6), WID_PARA_LEV6, cppu::UnoType<OUString>::get() , 0, 0},
+ { OUString(UNO_NAME_PARA_STYLELEVEL7), WID_PARA_LEV7, cppu::UnoType<OUString>::get() , 0, 0},
+ { OUString(UNO_NAME_PARA_STYLELEVEL8), WID_PARA_LEV8, cppu::UnoType<OUString>::get() , 0, 0},
+ { OUString(UNO_NAME_PARA_STYLELEVEL9), WID_PARA_LEV9, cppu::UnoType<OUString>::get() , 0, 0},
+ { OUString(UNO_NAME_PARA_STYLELEVEL10), WID_PARA_LEV10, cppu::UnoType<OUString>::get() , 0, 0},
+ { OUString(UNO_NAME_IS_RELATIVE_TABSTOPS), WID_IS_RELATIVE_TABSTOPS, cppu::UnoType<bool>::get(), PROPERTY_NONE, 0},
+ { OUString(UNO_NAME_DOCUMENT_INDEX_MARKS), WID_INDEX_MARKS, cppu::UnoType< cppu::UnoSequenceType<css::text::XDocumentIndexMark> >::get(), PropertyAttribute::READONLY ,0 },
+ { OUString(), 0, css::uno::Type(), 0, 0 }
+ };
+ m_aMapEntriesArr[nPropertyId] = aTOXContentMap_Impl;
+ }
+ break;
+ case PROPERTY_MAP_INDEX_USER:
+ {
+ static SfxItemPropertyMapEntry const aTOXUserMap_Impl[] =
+ {
+ BASE_INDEX_PROPERTIES_
+ { OUString(UNO_NAME_CREATE_FROM_MARKS), WID_CREATE_FROM_MARKS , cppu::UnoType<bool>::get() , PROPERTY_NONE, 0},
+ { OUString(UNO_NAME_HIDE_TAB_LEADER_AND_PAGE_NUMBERS), WID_HIDE_TABLEADER_PAGENUMBERS , cppu::UnoType<bool>::get() , PROPERTY_NONE, 0},
+ { OUString(UNO_NAME_TAB_IN_TOC), WID_TAB_IN_TOC, cppu::UnoType<bool>::get(), PROPERTY_NONE, 0},
+ { OUString(UNO_NAME_TOC_BOOKMARK), WID_TOC_BOOKMARK, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ { OUString(UNO_NAME_TOC_NEWLINE), WID_TOC_NEWLINE, cppu::UnoType<bool>::get(), PROPERTY_NONE, 0},
+ { OUString(UNO_NAME_TOC_PARAGRAPH_OUTLINE_LEVEL), WID_TOC_PARAGRAPH_OUTLINE_LEVEL, cppu::UnoType<bool>::get(), PROPERTY_NONE, 0},
+ { OUString(UNO_NAME_CREATE_FROM_CHAPTER), WID_CREATE_FROM_CHAPTER , cppu::UnoType<bool>::get() , PROPERTY_NONE, 0},
+ { OUString(UNO_NAME_IS_PROTECTED), WID_PROTECTED , cppu::UnoType<bool>::get() , PROPERTY_NONE, 0},
+ { OUString(UNO_NAME_USE_LEVEL_FROM_SOURCE), WID_USE_LEVEL_FROM_SOURCE , cppu::UnoType<bool>::get() , PROPERTY_NONE, 0},
+ { OUString(UNO_NAME_LEVEL_FORMAT), WID_LEVEL_FORMAT , cppu::UnoType<css::container::XIndexReplace>::get() , PROPERTY_NONE,0},
+ { OUString(UNO_NAME_LEVEL_PARAGRAPH_STYLES), WID_LEVEL_PARAGRAPH_STYLES , cppu::UnoType<css::container::XIndexReplace>::get() , PropertyAttribute::READONLY,0},
+ { OUString(UNO_NAME_CREATE_FROM_LEVEL_PARAGRAPH_STYLES), WID_CREATE_FROM_PARAGRAPH_STYLES, cppu::UnoType<bool>::get(), PROPERTY_NONE, 0},
+ { OUString(UNO_NAME_CREATE_FROM_TABLES), WID_CREATE_FROM_TABLES , cppu::UnoType<bool>::get() , PROPERTY_NONE, 0},
+ { OUString(UNO_NAME_CREATE_FROM_TEXT_FRAMES), WID_CREATE_FROM_TEXT_FRAMES , cppu::UnoType<bool>::get() , PROPERTY_NONE, 0},
+ { OUString(UNO_NAME_CREATE_FROM_GRAPHIC_OBJECTS), WID_CREATE_FROM_GRAPHIC_OBJECTS , cppu::UnoType<bool>::get() , PROPERTY_NONE, 0},
+ { OUString(UNO_NAME_CREATE_FROM_EMBEDDED_OBJECTS), WID_CREATE_FROM_EMBEDDED_OBJECTS , cppu::UnoType<bool>::get() , PROPERTY_NONE, 0},
+ { OUString(UNO_NAME_TEXT_COLUMNS), RES_COL, cppu::UnoType<css::text::XTextColumns>::get(), PROPERTY_NONE, MID_COLUMNS},
+ { OUString(UNO_NAME_BACK_GRAPHIC_URL), RES_BACKGROUND, cppu::UnoType<OUString>::get(), PROPERTY_NONE ,MID_GRAPHIC_URL },
+ { OUString(UNO_NAME_BACK_GRAPHIC), RES_BACKGROUND, cppu::UnoType<graphic::XGraphic>::get(), PROPERTY_NONE, MID_GRAPHIC },
+ { OUString(UNO_NAME_BACK_GRAPHIC_FILTER), RES_BACKGROUND, cppu::UnoType<OUString>::get(), PROPERTY_NONE ,MID_GRAPHIC_FILTER },
+ { OUString(UNO_NAME_BACK_GRAPHIC_LOCATION), RES_BACKGROUND, cppu::UnoType<css::style::GraphicLocation>::get(), PROPERTY_NONE ,MID_GRAPHIC_POSITION},
+ { OUString(UNO_NAME_BACK_COLOR), RES_BACKGROUND, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE ,MID_BACK_COLOR },
+ { OUString(UNO_NAME_BACK_TRANSPARENT), RES_BACKGROUND, cppu::UnoType<bool>::get(), PROPERTY_NONE ,MID_GRAPHIC_TRANSPARENT },
+ { OUString(UNO_NAME_PARA_STYLEHEADING), WID_PARA_HEAD, cppu::UnoType<OUString>::get() , 0, 0},
+ { OUString(UNO_NAME_PARA_STYLELEVEL1), WID_PARA_LEV1, cppu::UnoType<OUString>::get() , 0, 0},
+ { OUString(UNO_NAME_PARA_STYLELEVEL2), WID_PARA_LEV2, cppu::UnoType<OUString>::get() , 0, 0},
+ { OUString(UNO_NAME_PARA_STYLELEVEL3), WID_PARA_LEV3, cppu::UnoType<OUString>::get() , 0, 0},
+ { OUString(UNO_NAME_PARA_STYLELEVEL4), WID_PARA_LEV4, cppu::UnoType<OUString>::get() , 0, 0},
+ { OUString(UNO_NAME_PARA_STYLELEVEL5), WID_PARA_LEV5, cppu::UnoType<OUString>::get() , 0, 0},
+ { OUString(UNO_NAME_PARA_STYLELEVEL6), WID_PARA_LEV6, cppu::UnoType<OUString>::get() , 0, 0},
+ { OUString(UNO_NAME_PARA_STYLELEVEL7), WID_PARA_LEV7, cppu::UnoType<OUString>::get() , 0, 0},
+ { OUString(UNO_NAME_PARA_STYLELEVEL8), WID_PARA_LEV8, cppu::UnoType<OUString>::get() , 0, 0},
+ { OUString(UNO_NAME_PARA_STYLELEVEL9), WID_PARA_LEV9, cppu::UnoType<OUString>::get() , 0, 0},
+ { OUString(UNO_NAME_PARA_STYLELEVEL10), WID_PARA_LEV10, cppu::UnoType<OUString>::get() , 0, 0},
+ { OUString(UNO_NAME_DOCUMENT_INDEX_MARKS), WID_INDEX_MARKS, cppu::UnoType< cppu::UnoSequenceType<css::text::XDocumentIndexMark> >::get(), PropertyAttribute::READONLY ,0 },
+ { OUString(UNO_NAME_IS_RELATIVE_TABSTOPS), WID_IS_RELATIVE_TABSTOPS, cppu::UnoType<bool>::get(), PROPERTY_NONE, 0},
+ { OUString(UNO_NAME_USER_INDEX_NAME), WID_USER_IDX_NAME, cppu::UnoType<OUString>::get() , PROPERTY_NONE, 0},
+ { OUString(), 0, css::uno::Type(), 0, 0 }
+ };
+ m_aMapEntriesArr[nPropertyId] = aTOXUserMap_Impl;
+ }
+ break;
+ case PROPERTY_MAP_INDEX_TABLES:
+ {
+ static SfxItemPropertyMapEntry const aTOXTablesMap_Impl[] =
+ {
+ BASE_INDEX_PROPERTIES_
+ { OUString(UNO_NAME_CREATE_FROM_CHAPTER), WID_CREATE_FROM_CHAPTER , cppu::UnoType<bool>::get() , PROPERTY_NONE, 0},
+ { OUString(UNO_NAME_CREATE_FROM_LABELS), WID_CREATE_FROM_LABELS , cppu::UnoType<bool>::get() , PROPERTY_NONE, 0},
+ { OUString(UNO_NAME_IS_PROTECTED), WID_PROTECTED , cppu::UnoType<bool>::get() , PROPERTY_NONE, 0},
+ { OUString(UNO_NAME_LABEL_CATEGORY), WID_LABEL_CATEGORY , cppu::UnoType<OUString>::get() , PROPERTY_NONE, 0},
+ { OUString(UNO_NAME_LABEL_DISPLAY_TYPE), WID_LABEL_DISPLAY_TYPE , cppu::UnoType<sal_Int16>::get() , PROPERTY_NONE, 0},
+ { OUString(UNO_NAME_LEVEL_FORMAT), WID_LEVEL_FORMAT , cppu::UnoType<css::container::XIndexReplace>::get() , PROPERTY_NONE,0},
+ { OUString(UNO_NAME_TEXT_COLUMNS), RES_COL, cppu::UnoType<css::text::XTextColumns>::get(), PROPERTY_NONE, MID_COLUMNS},
+ { OUString(UNO_NAME_BACK_GRAPHIC_URL), RES_BACKGROUND, cppu::UnoType<OUString>::get(), PROPERTY_NONE ,MID_GRAPHIC_URL },
+ { OUString(UNO_NAME_BACK_GRAPHIC), RES_BACKGROUND, cppu::UnoType<graphic::XGraphic>::get(), PROPERTY_NONE, MID_GRAPHIC },
+ { OUString(UNO_NAME_BACK_GRAPHIC_FILTER), RES_BACKGROUND, cppu::UnoType<OUString>::get(), PROPERTY_NONE ,MID_GRAPHIC_FILTER },
+ { OUString(UNO_NAME_BACK_GRAPHIC_LOCATION), RES_BACKGROUND, cppu::UnoType<css::style::GraphicLocation>::get(), PROPERTY_NONE ,MID_GRAPHIC_POSITION},
+ { OUString(UNO_NAME_BACK_COLOR), RES_BACKGROUND, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE ,MID_BACK_COLOR },
+ { OUString(UNO_NAME_BACK_TRANSPARENT), RES_BACKGROUND, cppu::UnoType<bool>::get(), PROPERTY_NONE ,MID_GRAPHIC_TRANSPARENT },
+ { OUString(UNO_NAME_PARA_STYLEHEADING), WID_PARA_HEAD, cppu::UnoType<OUString>::get() , 0, 0},
+ { OUString(UNO_NAME_PARA_STYLELEVEL1), WID_PARA_LEV1, cppu::UnoType<OUString>::get() , 0, 0},
+ { OUString(UNO_NAME_IS_RELATIVE_TABSTOPS), WID_IS_RELATIVE_TABSTOPS, cppu::UnoType<bool>::get(), PROPERTY_NONE, 0},
+ { OUString(), 0, css::uno::Type(), 0, 0 }
+ };
+ m_aMapEntriesArr[nPropertyId] = aTOXTablesMap_Impl;
+ }
+ break;
+ case PROPERTY_MAP_INDEX_OBJECTS:
+ {
+ static SfxItemPropertyMapEntry const aTOXObjectsMap_Impl[] =
+ {
+ BASE_INDEX_PROPERTIES_
+ { OUString(UNO_NAME_CREATE_FROM_CHAPTER), WID_CREATE_FROM_CHAPTER , cppu::UnoType<bool>::get() , PROPERTY_NONE, 0},
+ { OUString(UNO_NAME_IS_PROTECTED), WID_PROTECTED , cppu::UnoType<bool>::get() , PROPERTY_NONE, 0},
+ { OUString(UNO_NAME_USE_ALPHABETICAL_SEPARATORS), WID_USE_ALPHABETICAL_SEPARATORS , cppu::UnoType<bool>::get() , PROPERTY_NONE, 0},
+ { OUString(UNO_NAME_LEVEL_FORMAT), WID_LEVEL_FORMAT , cppu::UnoType<css::container::XIndexReplace>::get() , PROPERTY_NONE,0},
+ { OUString(UNO_NAME_CREATE_FROM_STAR_MATH), WID_CREATE_FROM_STAR_MATH , cppu::UnoType<bool>::get() , PROPERTY_NONE, 0},
+ { OUString(UNO_NAME_CREATE_FROM_STAR_CHART), WID_CREATE_FROM_STAR_CHART , cppu::UnoType<bool>::get() , PROPERTY_NONE, 0},
+ { OUString(UNO_NAME_CREATE_FROM_STAR_CALC), WID_CREATE_FROM_STAR_CALC , cppu::UnoType<bool>::get() , PROPERTY_NONE, 0},
+ { OUString(UNO_NAME_CREATE_FROM_STAR_DRAW), WID_CREATE_FROM_STAR_DRAW , cppu::UnoType<bool>::get() , PROPERTY_NONE, 0},
+ { OUString(UNO_NAME_CREATE_FROM_OTHER_EMBEDDED_OBJECTS), WID_CREATE_FROM_OTHER_EMBEDDED_OBJECTS , cppu::UnoType<bool>::get() , PROPERTY_NONE, 0},
+ { OUString(UNO_NAME_TEXT_COLUMNS), RES_COL, cppu::UnoType<css::text::XTextColumns>::get(), PROPERTY_NONE, MID_COLUMNS},
+ { OUString(UNO_NAME_BACK_GRAPHIC_URL), RES_BACKGROUND, cppu::UnoType<OUString>::get(), PROPERTY_NONE ,MID_GRAPHIC_URL },
+ { OUString(UNO_NAME_BACK_GRAPHIC), RES_BACKGROUND, cppu::UnoType<graphic::XGraphic>::get(), PROPERTY_NONE, MID_GRAPHIC },
+ { OUString(UNO_NAME_BACK_GRAPHIC_FILTER), RES_BACKGROUND, cppu::UnoType<OUString>::get(), PROPERTY_NONE ,MID_GRAPHIC_FILTER },
+ { OUString(UNO_NAME_BACK_GRAPHIC_LOCATION), RES_BACKGROUND, cppu::UnoType<css::style::GraphicLocation>::get(), PROPERTY_NONE ,MID_GRAPHIC_POSITION},
+ { OUString(UNO_NAME_BACK_COLOR), RES_BACKGROUND, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE ,MID_BACK_COLOR },
+ { OUString(UNO_NAME_BACK_TRANSPARENT), RES_BACKGROUND, cppu::UnoType<bool>::get(), PROPERTY_NONE ,MID_GRAPHIC_TRANSPARENT },
+ { OUString(UNO_NAME_PARA_STYLEHEADING), WID_PARA_HEAD, cppu::UnoType<OUString>::get() , 0, 0},
+ { OUString(UNO_NAME_PARA_STYLELEVEL1), WID_PARA_LEV1, cppu::UnoType<OUString>::get() , 0, 0},
+ { OUString(UNO_NAME_IS_RELATIVE_TABSTOPS), WID_IS_RELATIVE_TABSTOPS, cppu::UnoType<bool>::get(), PROPERTY_NONE, 0},
+ { OUString(), 0, css::uno::Type(), 0, 0 }
+ };
+ m_aMapEntriesArr[nPropertyId] = aTOXObjectsMap_Impl;
+ }
+ break;
+ case PROPERTY_MAP_INDEX_ILLUSTRATIONS:
+ {
+ static SfxItemPropertyMapEntry const aTOXIllustrationsMap_Impl[] =
+ {
+ BASE_INDEX_PROPERTIES_
+ { OUString(UNO_NAME_CREATE_FROM_CHAPTER), WID_CREATE_FROM_CHAPTER , cppu::UnoType<bool>::get() , PROPERTY_NONE, 0},
+ { OUString(UNO_NAME_CREATE_FROM_LABELS), WID_CREATE_FROM_LABELS , cppu::UnoType<bool>::get() , PROPERTY_NONE, 0},
+ { OUString(UNO_NAME_IS_PROTECTED), WID_PROTECTED , cppu::UnoType<bool>::get() , PROPERTY_NONE, 0},
+ { OUString(UNO_NAME_USE_ALPHABETICAL_SEPARATORS), WID_USE_ALPHABETICAL_SEPARATORS , cppu::UnoType<bool>::get() , PROPERTY_NONE, 0},
+ { OUString(UNO_NAME_LABEL_CATEGORY), WID_LABEL_CATEGORY , cppu::UnoType<OUString>::get() , PROPERTY_NONE, 0},
+ { OUString(UNO_NAME_LABEL_DISPLAY_TYPE), WID_LABEL_DISPLAY_TYPE , cppu::UnoType<sal_Int16>::get() , PROPERTY_NONE, 0},
+ { OUString(UNO_NAME_LEVEL_FORMAT), WID_LEVEL_FORMAT , cppu::UnoType<css::container::XIndexReplace>::get() , PROPERTY_NONE,0},
+ { OUString(UNO_NAME_TEXT_COLUMNS), RES_COL, cppu::UnoType<css::text::XTextColumns>::get(), PROPERTY_NONE, MID_COLUMNS},
+ { OUString(UNO_NAME_BACK_GRAPHIC_URL), RES_BACKGROUND, cppu::UnoType<OUString>::get(), PROPERTY_NONE ,MID_GRAPHIC_URL },
+ { OUString(UNO_NAME_BACK_GRAPHIC), RES_BACKGROUND, cppu::UnoType<graphic::XGraphic>::get(), PROPERTY_NONE, MID_GRAPHIC },
+ { OUString(UNO_NAME_BACK_GRAPHIC_FILTER), RES_BACKGROUND, cppu::UnoType<OUString>::get(), PROPERTY_NONE ,MID_GRAPHIC_FILTER },
+ { OUString(UNO_NAME_BACK_GRAPHIC_LOCATION), RES_BACKGROUND, cppu::UnoType<css::style::GraphicLocation>::get(), PROPERTY_NONE ,MID_GRAPHIC_POSITION},
+ { OUString(UNO_NAME_BACK_COLOR), RES_BACKGROUND, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE ,MID_BACK_COLOR },
+ { OUString(UNO_NAME_BACK_TRANSPARENT), RES_BACKGROUND, cppu::UnoType<bool>::get(), PROPERTY_NONE ,MID_GRAPHIC_TRANSPARENT },
+ { OUString(UNO_NAME_PARA_STYLEHEADING), WID_PARA_HEAD, cppu::UnoType<OUString>::get() , 0, 0},
+ { OUString(UNO_NAME_PARA_STYLELEVEL1), WID_PARA_LEV1, cppu::UnoType<OUString>::get() , 0, 0},
+ { OUString(UNO_NAME_IS_RELATIVE_TABSTOPS), WID_IS_RELATIVE_TABSTOPS, cppu::UnoType<bool>::get(), PROPERTY_NONE, 0},
+ { OUString(), 0, css::uno::Type(), 0, 0 }
+ };
+ m_aMapEntriesArr[nPropertyId] = aTOXIllustrationsMap_Impl;
+ }
+ break;
+ case PROPERTY_MAP_TEXT_TABLE_ROW:
+ {
+ static SfxItemPropertyMapEntry const aTableRowPropertyMap_Impl[] =
+ {
+ { OUString(UNO_NAME_BACK_COLOR), RES_BACKGROUND, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE ,MID_BACK_COLOR },
+ { OUString(UNO_NAME_BACK_GRAPHIC_URL), RES_BACKGROUND, cppu::UnoType<OUString>::get(), PROPERTY_NONE ,MID_GRAPHIC_URL },
+ { OUString(UNO_NAME_BACK_GRAPHIC), RES_BACKGROUND, cppu::UnoType<graphic::XGraphic>::get(), PROPERTY_NONE, MID_GRAPHIC },
+ { OUString(UNO_NAME_BACK_GRAPHIC_FILTER), RES_BACKGROUND, cppu::UnoType<OUString>::get(), PROPERTY_NONE ,MID_GRAPHIC_FILTER },
+ { OUString(UNO_NAME_BACK_GRAPHIC_LOCATION), RES_BACKGROUND, cppu::UnoType<css::style::GraphicLocation>::get(), PROPERTY_NONE ,MID_GRAPHIC_POSITION},
+ { OUString(UNO_NAME_BACK_TRANSPARENT), RES_BACKGROUND, cppu::UnoType<bool>::get(), PROPERTY_NONE ,MID_GRAPHIC_TRANSPARENT },
+ { OUString(UNO_NAME_TABLE_COLUMN_SEPARATORS), FN_UNO_TABLE_COLUMN_SEPARATORS, cppu::UnoType< cppu::UnoSequenceType<css::text::TableColumnSeparator> >::get(), PropertyAttribute::MAYBEVOID, 0 },
+ { OUString(UNO_NAME_HEIGHT), FN_UNO_ROW_HEIGHT, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE ,CONVERT_TWIPS },
+ { OUString(UNO_NAME_IS_AUTO_HEIGHT), FN_UNO_ROW_AUTO_HEIGHT, cppu::UnoType<bool>::get(), PROPERTY_NONE , 0 },
+ { OUString(UNO_NAME_SIZE_TYPE), RES_FRM_SIZE, cppu::UnoType<sal_Int16>::get() , PROPERTY_NONE, MID_FRMSIZE_SIZE_TYPE },
+ { OUString(UNO_NAME_WIDTH_TYPE), RES_FRM_SIZE, cppu::UnoType<sal_Int16>::get() , PROPERTY_NONE, MID_FRMSIZE_WIDTH_TYPE },
+ { OUString(UNO_NAME_IS_SPLIT_ALLOWED), RES_ROW_SPLIT, cppu::UnoType<bool>::get() , PropertyAttribute::MAYBEVOID, 0},
+ { OUString(UNO_NAME_ROW_INTEROP_GRAB_BAG), RES_FRMATR_GRABBAG, cppu::UnoType< cppu::UnoSequenceType<css::beans::PropertyValue> >::get(), PROPERTY_NONE, 0 },
+ { OUString(), 0, css::uno::Type(), 0, 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_PARAGRAPH_EXTENSIONS:
+ {
+ m_aMapEntriesArr[nPropertyId] = GetParagraphExtensionsPropertyMap();
+ }
+ break;
+ case PROPERTY_MAP_BIBLIOGRAPHY :
+ {
+ static SfxItemPropertyMapEntry const aBibliographyMap_Impl[] =
+ {
+ BASE_INDEX_PROPERTIES_
+ { OUString(UNO_NAME_IS_PROTECTED), WID_PROTECTED , cppu::UnoType<bool>::get() , PROPERTY_NONE, 0},
+ { OUString(UNO_NAME_TEXT_COLUMNS), RES_COL, cppu::UnoType<css::text::XTextColumns>::get(), PROPERTY_NONE, MID_COLUMNS},
+ { OUString(UNO_NAME_BACK_GRAPHIC_URL), RES_BACKGROUND, cppu::UnoType<OUString>::get(), PROPERTY_NONE ,MID_GRAPHIC_URL },
+ { OUString(UNO_NAME_BACK_GRAPHIC), RES_BACKGROUND, cppu::UnoType<graphic::XGraphic>::get(), PROPERTY_NONE, MID_GRAPHIC },
+ { OUString(UNO_NAME_BACK_GRAPHIC_FILTER), RES_BACKGROUND, cppu::UnoType<OUString>::get(), PROPERTY_NONE ,MID_GRAPHIC_FILTER },
+ { OUString(UNO_NAME_BACK_GRAPHIC_LOCATION), RES_BACKGROUND, cppu::UnoType<css::style::GraphicLocation>::get(), PROPERTY_NONE ,MID_GRAPHIC_POSITION},
+ { OUString(UNO_NAME_BACK_COLOR), RES_BACKGROUND, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE ,MID_BACK_COLOR },
+ { OUString(UNO_NAME_BACK_TRANSPARENT), RES_BACKGROUND, cppu::UnoType<bool>::get(), PROPERTY_NONE ,MID_GRAPHIC_TRANSPARENT },
+ { OUString(UNO_NAME_PARA_STYLEHEADING), WID_PARA_HEAD, cppu::UnoType<OUString>::get() , 0, 0},
+ { OUString(UNO_NAME_PARA_STYLELEVEL1), WID_PARA_LEV1, cppu::UnoType<OUString>::get() , 0, 0},
+ { OUString(UNO_NAME_LEVEL_FORMAT), WID_LEVEL_FORMAT , cppu::UnoType<css::container::XIndexReplace>::get() , PROPERTY_NONE,0},
+ { OUString(UNO_NAME_LOCALE), WID_IDX_LOCALE, cppu::UnoType<css::lang::Locale>::get(), PROPERTY_NONE, 0},
+ { OUString(UNO_NAME_SORT_ALGORITHM), WID_IDX_SORT_ALGORITHM, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ { OUString(), 0, css::uno::Type(), 0, 0 }
+ };
+ m_aMapEntriesArr[nPropertyId] = aBibliographyMap_Impl;
+ }
+ break;
+ case PROPERTY_MAP_TEXT_DOCUMENT:
+ {
+ static SfxItemPropertyMapEntry const aDocMap_Impl[] =
+ {
+ { OUString(UNO_NAME_BASIC_LIBRARIES), WID_DOC_BASIC_LIBRARIES, cppu::UnoType<css::script::XLibraryContainer>::get(), PropertyAttribute::READONLY, 0},
+ { OUString(UNO_NAME_CHAR_FONT_NAME), RES_CHRATR_FONT, cppu::UnoType<OUString>::get(), PropertyAttribute::MAYBEVOID, MID_FONT_FAMILY_NAME },
+ { OUString(UNO_NAME_CHAR_FONT_STYLE_NAME), RES_CHRATR_FONT, cppu::UnoType<OUString>::get(), PropertyAttribute::MAYBEVOID, MID_FONT_STYLE_NAME },
+ { OUString(UNO_NAME_CHAR_FONT_FAMILY), RES_CHRATR_FONT, cppu::UnoType<sal_Int16>::get(), PropertyAttribute::MAYBEVOID, MID_FONT_FAMILY },
+ { OUString(UNO_NAME_CHAR_FONT_CHAR_SET), RES_CHRATR_FONT, cppu::UnoType<sal_Int16>::get(), PropertyAttribute::MAYBEVOID, MID_FONT_CHAR_SET },
+ { OUString(UNO_NAME_CHAR_FONT_PITCH), RES_CHRATR_FONT, cppu::UnoType<sal_Int16>::get(), PropertyAttribute::MAYBEVOID, MID_FONT_PITCH },
+ { OUString(UNO_NAME_CHAR_FONT_NAME_ASIAN), RES_CHRATR_CJK_FONT, cppu::UnoType<OUString>::get(), PropertyAttribute::MAYBEVOID, MID_FONT_FAMILY_NAME },
+ { OUString(UNO_NAME_CHAR_FONT_STYLE_NAME_ASIAN), RES_CHRATR_CJK_FONT, cppu::UnoType<OUString>::get(), PropertyAttribute::MAYBEVOID, MID_FONT_STYLE_NAME },
+ { OUString(UNO_NAME_CHAR_FONT_FAMILY_ASIAN), RES_CHRATR_CJK_FONT, cppu::UnoType<sal_Int16>::get(), PropertyAttribute::MAYBEVOID, MID_FONT_FAMILY },
+ { OUString(UNO_NAME_CHAR_FONT_CHAR_SET_ASIAN), RES_CHRATR_CJK_FONT, cppu::UnoType<sal_Int16>::get(), PropertyAttribute::MAYBEVOID, MID_FONT_CHAR_SET },
+ { OUString(UNO_NAME_CHAR_FONT_PITCH_ASIAN), RES_CHRATR_CJK_FONT, cppu::UnoType<sal_Int16>::get(), PropertyAttribute::MAYBEVOID, MID_FONT_PITCH },
+ { OUString(UNO_NAME_CHAR_FONT_NAME_COMPLEX), RES_CHRATR_CTL_FONT, cppu::UnoType<OUString>::get(), PropertyAttribute::MAYBEVOID, MID_FONT_FAMILY_NAME },
+ { OUString(UNO_NAME_CHAR_FONT_STYLE_NAME_COMPLEX), RES_CHRATR_CTL_FONT, cppu::UnoType<OUString>::get(), PropertyAttribute::MAYBEVOID, MID_FONT_STYLE_NAME },
+ { OUString(UNO_NAME_CHAR_FONT_FAMILY_COMPLEX), RES_CHRATR_CTL_FONT, cppu::UnoType<sal_Int16>::get(), PropertyAttribute::MAYBEVOID, MID_FONT_FAMILY },
+ { OUString(UNO_NAME_CHAR_FONT_CHAR_SET_COMPLEX), RES_CHRATR_CTL_FONT, cppu::UnoType<sal_Int16>::get(), PropertyAttribute::MAYBEVOID, MID_FONT_CHAR_SET },
+ { OUString(UNO_NAME_CHAR_FONT_PITCH_COMPLEX), RES_CHRATR_CTL_FONT, cppu::UnoType<sal_Int16>::get(), PropertyAttribute::MAYBEVOID, MID_FONT_PITCH },
+ { OUString(UNO_NAME_CHAR_LOCALE), RES_CHRATR_LANGUAGE , cppu::UnoType<css::lang::Locale>::get(), PropertyAttribute::MAYBEVOID, MID_LANG_LOCALE },
+ { OUString(UNO_NAME_CHARACTER_COUNT), WID_DOC_CHAR_COUNT, cppu::UnoType<sal_Int32>::get(), PropertyAttribute::READONLY, 0},
+ { OUString(UNO_NAME_DIALOG_LIBRARIES), WID_DOC_DIALOG_LIBRARIES, cppu::UnoType<css::script::XLibraryContainer>::get(), PropertyAttribute::READONLY, 0},
+ { OUString(UNO_NAME_VBA_DOCOBJ), WID_DOC_VBA_DOCOBJ, cppu::UnoType<OUString>::get(), PropertyAttribute::READONLY, 0},
+ { OUString(UNO_NAME_INDEX_AUTO_MARK_FILE_U_R_L), WID_DOC_AUTO_MARK_URL, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ { OUString(UNO_NAME_PARAGRAPH_COUNT), WID_DOC_PARA_COUNT, cppu::UnoType<sal_Int32>::get(), PropertyAttribute::READONLY, 0},
+ { OUString(UNO_NAME_RECORD_CHANGES), WID_DOC_CHANGES_RECORD, cppu::UnoType<bool>::get(), PROPERTY_NONE, 0},
+ { OUString(UNO_NAME_SHOW_CHANGES), WID_DOC_CHANGES_SHOW, cppu::UnoType<bool>::get(), PROPERTY_NONE, 0},
+ { OUString(UNO_NAME_WORD_COUNT), WID_DOC_WORD_COUNT, cppu::UnoType<sal_Int32>::get(), PropertyAttribute::READONLY, 0},
+ { OUString(UNO_NAME_IS_TEMPLATE), WID_DOC_ISTEMPLATEID, cppu::UnoType<bool>::get(), PropertyAttribute::READONLY, 0},
+ { OUString(UNO_NAME_WORD_SEPARATOR), WID_DOC_WORD_SEPARATOR, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ { OUString(UNO_NAME_HIDE_FIELD_TIPS), WID_DOC_HIDE_TIPS, cppu::UnoType<bool>::get(), PROPERTY_NONE, 0},
+ { OUString(UNO_NAME_REDLINE_DISPLAY_TYPE), WID_DOC_REDLINE_DISPLAY, cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE, 0},
+ { OUString(UNO_NAME_REDLINE_PROTECTION_KEY), WID_DOC_CHANGES_PASSWORD, cppu::UnoType< cppu::UnoSequenceType<sal_Int8> >::get(), PROPERTY_NONE, 0 },
+ { OUString(UNO_NAME_FORBIDDEN_CHARACTERS), WID_DOC_FORBIDDEN_CHARS, cppu::UnoType<css::i18n::XForbiddenCharacters>::get(), PROPERTY_NONE, 0},
+ { OUString(UNO_NAME_TWO_DIGIT_YEAR), WID_DOC_TWO_DIGIT_YEAR, cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE, 0},
+ { OUString(UNO_NAME_AUTOMATIC_CONTROL_FOCUS), WID_DOC_AUTOMATIC_CONTROL_FOCUS, cppu::UnoType<bool>::get(), PROPERTY_NONE, 0},
+ { OUString(UNO_NAME_APPLY_FORM_DESIGN_MODE), WID_DOC_APPLY_FORM_DESIGN_MODE, cppu::UnoType<bool>::get(), PROPERTY_NONE, 0},
+ { OUString(UNO_NAME_RUNTIME_UID), WID_DOC_RUNTIME_UID, cppu::UnoType<OUString>::get(), PropertyAttribute::READONLY, 0},
+ { OUString(UNO_NAME_LOCK_UPDATES), WID_DOC_LOCK_UPDATES, cppu::UnoType<bool>::get(), PROPERTY_NONE, 0},
+ { OUString("UndocumentedWriterfilterHack"), WID_DOC_WRITERFILTER, cppu::UnoType<bool>::get(), PROPERTY_NONE, 0},
+ { OUString(UNO_NAME_HAS_VALID_SIGNATURES), WID_DOC_HAS_VALID_SIGNATURES, cppu::UnoType<bool>::get(), PropertyAttribute::READONLY, 0},
+ { OUString(UNO_NAME_BUILDID), WID_DOC_BUILDID, cppu::UnoType<OUString>::get(), 0, 0},
+ { OUString(UNO_NAME_DOC_INTEROP_GRAB_BAG), WID_DOC_INTEROP_GRAB_BAG, cppu::UnoType< cppu::UnoSequenceType<css::beans::PropertyValue> >::get(), PROPERTY_NONE, 0 },
+ { OUString(UNO_NAME_DEFAULT_PAGE_MODE), WID_DOC_DEFAULT_PAGE_MODE, cppu::UnoType<bool>::get(), PROPERTY_NONE, 0},
+ { OUString(), 0, css::uno::Type(), 0, 0 }
+ };
+ m_aMapEntriesArr[nPropertyId] = aDocMap_Impl;
+ }
+ break;
+ case PROPERTY_MAP_LINK_TARGET:
+ {
+ static SfxItemPropertyMapEntry const aLinkTargetMap_Impl[] =
+ {
+ { OUString(UNO_LINK_DISPLAY_BITMAP), 0, cppu::UnoType<css::awt::XBitmap>::get(), PropertyAttribute::READONLY, 0xbf},
+ { OUString(UNO_LINK_DISPLAY_NAME), 0, cppu::UnoType<OUString>::get(), PropertyAttribute::READONLY, 0xbf},
+ { OUString(), 0, css::uno::Type(), 0, 0 }
+ };
+ m_aMapEntriesArr[nPropertyId] = aLinkTargetMap_Impl;
+ }
+ break;
+ case PROPERTY_MAP_AUTO_TEXT_GROUP :
+ {
+ static SfxItemPropertyMapEntry const aAutoTextGroupMap_Impl[] =
+ {
+ { OUString(UNO_NAME_FILE_PATH), WID_GROUP_PATH, cppu::UnoType<OUString>::get(), PropertyAttribute::READONLY, 0},
+ { OUString(UNO_NAME_TITLE), WID_GROUP_TITLE, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ { OUString(), 0, css::uno::Type(), 0, 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_TEXT_COLUMS :
+ {
+ static SfxItemPropertyMapEntry const aTextColumns_Impl[] =
+ {
+ {OUString(UNO_NAME_IS_AUTOMATIC), WID_TXTCOL_IS_AUTOMATIC, cppu::UnoType<bool>::get(),PropertyAttribute::READONLY, 0},
+ {OUString(UNO_NAME_AUTOMATIC_DISTANCE), WID_TXTCOL_AUTO_DISTANCE, cppu::UnoType<sal_Int32>::get(),PROPERTY_NONE, 0},
+ {OUString(UNO_NAME_SEPARATOR_LINE_WIDTH), WID_TXTCOL_LINE_WIDTH, cppu::UnoType<sal_Int32>::get(),PROPERTY_NONE, 0},
+ {OUString(UNO_NAME_SEPARATOR_LINE_COLOR), WID_TXTCOL_LINE_COLOR, cppu::UnoType<sal_Int32>::get(),PROPERTY_NONE, 0},
+ {OUString(UNO_NAME_SEPARATOR_LINE_RELATIVE_HEIGHT), WID_TXTCOL_LINE_REL_HGT, cppu::UnoType<sal_Int32>::get(),PROPERTY_NONE, 0},
+ {OUString(UNO_NAME_SEPARATOR_LINE_VERTIVAL_ALIGNMENT), WID_TXTCOL_LINE_ALIGN, cppu::UnoType<css::style::VerticalAlignment>::get(),PROPERTY_NONE, 0},
+ {OUString(UNO_NAME_SEPARATOR_LINE_IS_ON), WID_TXTCOL_LINE_IS_ON, cppu::UnoType<bool>::get(),PROPERTY_NONE, 0},
+ {OUString(UNO_NAME_SEPARATOR_LINE_STYLE), WID_TXTCOL_LINE_STYLE, cppu::UnoType<sal_Int8>::get(),PROPERTY_NONE, 0},
+ { OUString(), 0, css::uno::Type(), 0, 0 }
+ };
+ m_aMapEntriesArr[nPropertyId] = aTextColumns_Impl;
+ }
+ break;
+ case PROPERTY_MAP_REDLINE :
+ {
+ m_aMapEntriesArr[nPropertyId] = GetRedlinePropertyMap();
+ }
+ break;
+ case PROPERTY_MAP_TEXT_DEFAULT :
+ {
+ SfxItemPropertyMapEntry* aTextDefaultMap_Impl = GetTextDefaultPropertyMap();
+ m_aMapEntriesArr[nPropertyId] = aTextDefaultMap_Impl;
+ for( SfxItemPropertyMapEntry * pMap = aTextDefaultMap_Impl;
+ !pMap->aName.isEmpty(); ++pMap )
+ {
+ // OUString(UNO_NAME_PAGE_DESC_NAME) should keep its MAYBEVOID flag
+ if (!(RES_PAGEDESC == pMap->nWID && MID_PAGEDESC_PAGEDESCNAME == pMap->nMemberId))
+ pMap->nFlags &= ~PropertyAttribute::MAYBEVOID;
+ }
+ }
+ break;
+ case PROPERTY_MAP_REDLINE_PORTION :
+ {
+ m_aMapEntriesArr[nPropertyId] = GetRedlinePortionPropertyMap();
+ }
+ break;
+ case PROPERTY_MAP_FLDTYP_DATETIME:
+ {
+ static SfxItemPropertyMapEntry const aDateTimeFieldPropMap[] =
+ {
+ {OUString(UNO_NAME_ADJUST), FIELD_PROP_SUBTYPE, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE, 0},
+ {OUString(UNO_NAME_DATE_TIME_VALUE), FIELD_PROP_DATE_TIME, cppu::UnoType<css::util::DateTime>::get(), PROPERTY_NONE, 0},
+ {OUString(UNO_NAME_IS_FIXED), FIELD_PROP_BOOL1, cppu::UnoType<bool>::get() , PROPERTY_NONE,0},
+ {OUString(UNO_NAME_IS_DATE), FIELD_PROP_BOOL2, cppu::UnoType<bool>::get() , PROPERTY_NONE,0},
+ {OUString(UNO_NAME_NUMBER_FORMAT), FIELD_PROP_FORMAT, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE, 0},
+ {OUString(UNO_NAME_IS_FIXED_LANGUAGE), FIELD_PROP_BOOL4, cppu::UnoType<bool>::get(), PROPERTY_NONE, 0},
+ COMMON_FLDTYP_PROPERTIES
+ { OUString(), 0, css::uno::Type(), 0, 0 }
+ };
+ m_aMapEntriesArr[nPropertyId] = aDateTimeFieldPropMap;
+ }
+ break;
+ case PROPERTY_MAP_FLDTYP_USER :
+ {
+ static SfxItemPropertyMapEntry const aUserFieldPropMap[] =
+ {
+ {OUString(UNO_NAME_IS_SHOW_FORMULA), FIELD_PROP_BOOL2, cppu::UnoType<bool>::get(), PROPERTY_NONE, 0},
+ {OUString(UNO_NAME_IS_VISIBLE), FIELD_PROP_BOOL1, cppu::UnoType<bool>::get(), PROPERTY_NONE, 0},
+ {OUString(UNO_NAME_NUMBER_FORMAT), FIELD_PROP_FORMAT, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE, 0},
+ {OUString(UNO_NAME_IS_FIXED_LANGUAGE), FIELD_PROP_BOOL4, cppu::UnoType<bool>::get(), PROPERTY_NONE, 0},
+ COMMON_FLDTYP_PROPERTIES
+ { OUString(), 0, css::uno::Type(), 0, 0 }
+ };
+
+ m_aMapEntriesArr[nPropertyId] = aUserFieldPropMap;
+ }
+ break;
+ case PROPERTY_MAP_FLDTYP_SET_EXP :
+ {
+ static SfxItemPropertyMapEntry const aSetExpFieldPropMap [] =
+ {
+ {OUString(UNO_NAME_CONTENT), FIELD_PROP_PAR2, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ {OUString(UNO_NAME_CURRENT_PRESENTATION), FIELD_PROP_PAR4, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ {OUString(UNO_NAME_HINT), FIELD_PROP_PAR3, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ {OUString(UNO_NAME_NUMBER_FORMAT), FIELD_PROP_FORMAT, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE, 0},
+ {OUString(UNO_NAME_NUMBERING_TYPE), FIELD_PROP_USHORT2, cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE, 0},
+ {OUString(UNO_NAME_IS_INPUT), FIELD_PROP_BOOL1, cppu::UnoType<bool>::get(), PROPERTY_NONE, 0},
+ // #i69733# wrong name - OUString(UNO_NAME_IS_INPUT) expanded to "Input" instead of "IsInput"
+ {OUString(UNO_NAME_INPUT), FIELD_PROP_BOOL1, cppu::UnoType<bool>::get(), PROPERTY_NONE, 0},
+ {OUString(UNO_NAME_IS_SHOW_FORMULA), FIELD_PROP_BOOL3, cppu::UnoType<bool>::get(), PROPERTY_NONE, 0},
+ {OUString(UNO_NAME_IS_VISIBLE), FIELD_PROP_BOOL2, cppu::UnoType<bool>::get(), PROPERTY_NONE, 0},
+ {OUString(UNO_NAME_SEQUENCE_VALUE), FIELD_PROP_USHORT1, cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE, 0},
+ {OUString(UNO_NAME_SUB_TYPE), FIELD_PROP_SUBTYPE, cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE, 0},
+ {OUString(UNO_NAME_VALUE), FIELD_PROP_DOUBLE, cppu::UnoType<double>::get(), PROPERTY_NONE, 0},
+ {OUString(UNO_NAME_VARIABLE_NAME), FIELD_PROP_PAR1, cppu::UnoType<OUString>::get(), PropertyAttribute::READONLY, 0},
+ {OUString(UNO_NAME_IS_FIXED_LANGUAGE), FIELD_PROP_BOOL4, cppu::UnoType<bool>::get(), PROPERTY_NONE, 0},
+ COMMON_FLDTYP_PROPERTIES
+ { OUString(), 0, css::uno::Type(), 0, 0 }
+ };
+ m_aMapEntriesArr[nPropertyId] = aSetExpFieldPropMap;
+ }
+ break;
+ case PROPERTY_MAP_FLDTYP_GET_EXP :
+ {
+ static SfxItemPropertyMapEntry const aGetExpFieldPropMap [] =
+ {
+ {OUString(UNO_NAME_CONTENT), FIELD_PROP_PAR1, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ {OUString(UNO_NAME_CURRENT_PRESENTATION), FIELD_PROP_PAR4, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ {OUString(UNO_NAME_IS_SHOW_FORMULA), FIELD_PROP_BOOL2, cppu::UnoType<bool>::get(), PROPERTY_NONE, 0},
+ {OUString(UNO_NAME_NUMBER_FORMAT), FIELD_PROP_FORMAT, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE, 0},
+ {OUString(UNO_NAME_SUB_TYPE), FIELD_PROP_SUBTYPE, cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE, 0},
+ {OUString(UNO_NAME_VALUE), FIELD_PROP_DOUBLE, cppu::UnoType<double>::get(), PropertyAttribute::READONLY, 0},
+ {OUString(UNO_NAME_VARIABLE_SUBTYPE), FIELD_PROP_USHORT1, cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE, 0},
+ {OUString(UNO_NAME_IS_FIXED_LANGUAGE), FIELD_PROP_BOOL4, cppu::UnoType<bool>::get(), PROPERTY_NONE, 0},
+ COMMON_FLDTYP_PROPERTIES
+ { OUString(), 0, css::uno::Type(), 0, 0 }
+ };
+ m_aMapEntriesArr[nPropertyId] = aGetExpFieldPropMap;
+ }
+ break;
+ case PROPERTY_MAP_FLDTYP_FILE_NAME:
+ {
+ static SfxItemPropertyMapEntry const aFileNameFieldPropMap [] =
+ {
+ {OUString(UNO_NAME_CURRENT_PRESENTATION), FIELD_PROP_PAR3, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ {OUString(UNO_NAME_FILE_FORMAT), FIELD_PROP_FORMAT, cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE, 0},
+ {OUString(UNO_NAME_IS_FIXED), FIELD_PROP_BOOL2, cppu::UnoType<bool>::get(), PROPERTY_NONE, 0},
+ COMMON_FLDTYP_PROPERTIES
+ { OUString(), 0, css::uno::Type(), 0, 0 }
+ };
+ m_aMapEntriesArr[nPropertyId] = aFileNameFieldPropMap;
+ }
+ break;
+ case PROPERTY_MAP_FLDTYP_PAGE_NUM :
+ {
+ static SfxItemPropertyMapEntry const aPageNumFieldPropMap [] =
+ {
+ {OUString(UNO_NAME_NUMBERING_TYPE), FIELD_PROP_FORMAT, cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE, 0},
+ {OUString(UNO_NAME_OFFSET), FIELD_PROP_USHORT1, cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE, 0},
+ {OUString(UNO_NAME_SUB_TYPE), FIELD_PROP_SUBTYPE, cppu::UnoType<css::text::PageNumberType>::get(), PROPERTY_NONE, 0},
+ {OUString(UNO_NAME_USERTEXT), FIELD_PROP_PAR1, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ COMMON_FLDTYP_PROPERTIES
+ { OUString(), 0, css::uno::Type(), 0, 0 }
+ };
+ m_aMapEntriesArr[nPropertyId] = aPageNumFieldPropMap;
+ }
+ break;
+ case PROPERTY_MAP_FLDTYP_AUTHOR :
+ {
+ static SfxItemPropertyMapEntry const aAuthorFieldPropMap [] =
+ {
+ {OUString(UNO_NAME_CONTENT), FIELD_PROP_PAR1, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ {OUString(UNO_NAME_CURRENT_PRESENTATION), FIELD_PROP_PAR1, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ {OUString(UNO_NAME_IS_FIXED), FIELD_PROP_BOOL2, cppu::UnoType<bool>::get(), PROPERTY_NONE, 0},
+ {OUString(UNO_NAME_FULL_NAME),FIELD_PROP_BOOL1, cppu::UnoType<bool>::get(), PROPERTY_NONE, 0},
+ COMMON_FLDTYP_PROPERTIES
+ { OUString(), 0, css::uno::Type(), 0, 0 }
+ };
+ m_aMapEntriesArr[nPropertyId] = aAuthorFieldPropMap;
+ }
+ break;
+ case PROPERTY_MAP_FLDTYP_CHAPTER :
+ {
+ static SfxItemPropertyMapEntry const aChapterFieldPropMap [] =
+ {
+ {OUString(UNO_NAME_CHAPTER_FORMAT),FIELD_PROP_USHORT1, cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE, 0},
+ {OUString(UNO_NAME_LEVEL),FIELD_PROP_BYTE1, cppu::UnoType<sal_Int8>::get(), PROPERTY_NONE, 0},
+ COMMON_FLDTYP_PROPERTIES
+ { OUString(), 0, css::uno::Type(), 0, 0 }
+ };
+ m_aMapEntriesArr[nPropertyId] = aChapterFieldPropMap;
+ }
+ break;
+ case PROPERTY_MAP_FLDTYP_GET_REFERENCE :
+ {
+ static SfxItemPropertyMapEntry const aGetRefFieldPropMap [] =
+ {
+ {OUString(UNO_NAME_CURRENT_PRESENTATION), FIELD_PROP_PAR3, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ {OUString(UNO_NAME_REFERENCE_FIELD_PART),FIELD_PROP_USHORT1, cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE, 0},
+ {OUString(UNO_NAME_REFERENCE_FIELD_SOURCE),FIELD_PROP_USHORT2, cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE, 0},
+ {OUString(UNO_NAME_SEQUENCE_NUMBER), FIELD_PROP_SHORT1, cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE, 0},
+ {OUString(UNO_NAME_SOURCE_NAME), FIELD_PROP_PAR1, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ {OUString(UNO_NAME_REFERENCE_FIELD_LANGUAGE), FIELD_PROP_PAR4, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ COMMON_FLDTYP_PROPERTIES
+ { OUString(), 0, css::uno::Type(), 0, 0 }
+ };
+ m_aMapEntriesArr[nPropertyId] = aGetRefFieldPropMap;
+ }
+ break;
+ case PROPERTY_MAP_FLDTYP_CONDITIONED_TEXT :
+ {
+ static SfxItemPropertyMapEntry const aConditionedTextFieldPropMap [] =
+ {
+ {OUString(UNO_NAME_CONDITION), FIELD_PROP_PAR1, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ {OUString(UNO_NAME_FALSE_CONTENT), FIELD_PROP_PAR3, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ {OUString(UNO_NAME_IS_CONDITION_TRUE) , FIELD_PROP_BOOL1, cppu::UnoType<bool>::get(), PROPERTY_NONE, 0},
+ {OUString(UNO_NAME_TRUE_CONTENT) , FIELD_PROP_PAR2, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ {OUString(UNO_NAME_CURRENT_PRESENTATION), FIELD_PROP_PAR4, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ COMMON_FLDTYP_PROPERTIES
+ { OUString(), 0, css::uno::Type(), 0, 0 }
+ };
+ m_aMapEntriesArr[nPropertyId] = aConditionedTextFieldPropMap;
+ }
+ break;
+ case PROPERTY_MAP_FLDTYP_HIDDEN_TEXT :
+ {
+ static SfxItemPropertyMapEntry const aHiddenTextFieldPropMap [] =
+ {
+ {OUString(UNO_NAME_CONDITION), FIELD_PROP_PAR1, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ {OUString(UNO_NAME_CONTENT) , FIELD_PROP_PAR2, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ {OUString(UNO_NAME_IS_HIDDEN) , FIELD_PROP_BOOL1, cppu::UnoType<bool>::get(), PROPERTY_NONE, 0},
+ {OUString(UNO_NAME_CURRENT_PRESENTATION), FIELD_PROP_PAR4, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ COMMON_FLDTYP_PROPERTIES
+ { OUString(), 0, css::uno::Type(), 0, 0 }
+ };
+ m_aMapEntriesArr[nPropertyId] = aHiddenTextFieldPropMap;
+ }
+ break;
+ case PROPERTY_MAP_FLDTYP_ANNOTATION :
+ {
+ static SfxItemPropertyMapEntry const aAnnotationFieldPropMap [] =
+ {
+ {OUString(UNO_NAME_AUTHOR), FIELD_PROP_PAR1, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ {OUString(UNO_NAME_CONTENT), FIELD_PROP_PAR2, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ {OUString(UNO_NAME_INITIALS), FIELD_PROP_PAR3, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ {OUString(UNO_NAME_NAME), FIELD_PROP_PAR4, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ {OUString(UNO_NAME_RESOLVED), FIELD_PROP_BOOL1, cppu::UnoType<bool>::get(), PROPERTY_NONE, 0},
+ {OUString(UNO_NAME_DATE_TIME_VALUE), FIELD_PROP_DATE_TIME, cppu::UnoType<css::util::DateTime>::get(), PROPERTY_NONE, 0},
+ {OUString(UNO_NAME_DATE), FIELD_PROP_DATE, cppu::UnoType<css::util::Date>::get(), PROPERTY_NONE, 0},
+ {OUString(UNO_NAME_TEXT_RANGE), FIELD_PROP_TEXT, cppu::UnoType<css::uno::XInterface>::get(), PropertyAttribute::READONLY, 0},
+ COMMON_FLDTYP_PROPERTIES
+ { OUString(), 0, css::uno::Type(), 0, 0 }
+ };
+ m_aMapEntriesArr[nPropertyId] = aAnnotationFieldPropMap;
+ }
+ break;
+ case PROPERTY_MAP_FLDTYP_INPUT:
+ {
+ static SfxItemPropertyMapEntry const aInputFieldPropMap [] =
+ {
+ {OUString(UNO_NAME_CONTENT), FIELD_PROP_PAR1, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ {OUString(UNO_NAME_HINT), FIELD_PROP_PAR2, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ {OUString(UNO_NAME_HELP), FIELD_PROP_PAR3, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ {OUString(UNO_NAME_TOOLTIP), FIELD_PROP_PAR4, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ COMMON_FLDTYP_PROPERTIES
+ { OUString(), 0, css::uno::Type(), 0, 0 }
+ };
+ m_aMapEntriesArr[nPropertyId] = aInputFieldPropMap;
+ }
+ break;
+ case PROPERTY_MAP_FLDTYP_MACRO :
+ {
+ static SfxItemPropertyMapEntry const aMacroFieldPropMap [] =
+ {
+ {OUString(UNO_NAME_HINT), FIELD_PROP_PAR2, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ {OUString(UNO_NAME_MACRO_NAME),FIELD_PROP_PAR1, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ {OUString(UNO_NAME_MACRO_LIBRARY),FIELD_PROP_PAR3, cppu::UnoType<OUString>::get(),PROPERTY_NONE, 0},
+ {OUString(UNO_NAME_SCRIPT_URL),FIELD_PROP_PAR4, cppu::UnoType<OUString>::get(),PROPERTY_NONE, 0},
+ COMMON_FLDTYP_PROPERTIES
+ { OUString(), 0, css::uno::Type(), 0, 0 }
+ };
+ m_aMapEntriesArr[nPropertyId] = aMacroFieldPropMap;
+ }
+ break;
+ case PROPERTY_MAP_FLDTYP_DDE :
+ {
+ static SfxItemPropertyMapEntry const aDDEFieldPropMap [] =
+ {
+ COMMON_FLDTYP_PROPERTIES
+ { OUString(), 0, css::uno::Type(), 0, 0 }
+ };
+ m_aMapEntriesArr[nPropertyId] = aDDEFieldPropMap;
+ }
+ break;
+ case PROPERTY_MAP_FLDTYP_DROPDOWN :
+ {
+ static SfxItemPropertyMapEntry const aDropDownMap [] =
+ {
+ {OUString(UNO_NAME_ITEMS), FIELD_PROP_STRINGS, cppu::UnoType< cppu::UnoSequenceType<OUString> >::get(), PROPERTY_NONE, 0},
+ {OUString(UNO_NAME_SELITEM), FIELD_PROP_PAR1, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ {OUString(UNO_NAME_NAME), FIELD_PROP_PAR2, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ {OUString(UNO_NAME_HELP), FIELD_PROP_PAR3, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ {OUString(UNO_NAME_TOOLTIP), FIELD_PROP_PAR4, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ COMMON_FLDTYP_PROPERTIES
+ { OUString(), 0, css::uno::Type(), 0, 0 }
+ };
+ m_aMapEntriesArr[nPropertyId] = aDropDownMap;
+ }
+ break;
+ case PROPERTY_MAP_FLDTYP_HIDDEN_PARA :
+ {
+ static SfxItemPropertyMapEntry const aHiddenParaFieldPropMap [] =
+ {
+ {OUString(UNO_NAME_CONDITION),FIELD_PROP_PAR1, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ {OUString(UNO_NAME_IS_HIDDEN) , FIELD_PROP_BOOL1, cppu::UnoType<bool>::get(), PROPERTY_NONE, 0},
+ COMMON_FLDTYP_PROPERTIES
+ { OUString(), 0, css::uno::Type(), 0, 0 }
+ };
+ m_aMapEntriesArr[nPropertyId] = aHiddenParaFieldPropMap;
+ }
+ break;
+ case PROPERTY_MAP_FLDTYP_DOC_INFO :
+ {
+ static SfxItemPropertyMapEntry const aDocInfoFieldPropMap [] =
+ {
+ {OUString(UNO_NAME_IS_FIXED), FIELD_PROP_BOOL1, cppu::UnoType<bool>::get(), PROPERTY_NONE, 0},
+ {OUString(UNO_NAME_INFO_FORMAT), FIELD_PROP_USHORT2, cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE, 0},
+ {OUString(UNO_NAME_INFO_TYPE), FIELD_PROP_USHORT1, cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE, 0},
+ COMMON_FLDTYP_PROPERTIES
+ { OUString(), 0, css::uno::Type(), 0, 0 }
+ };
+ m_aMapEntriesArr[nPropertyId] = aDocInfoFieldPropMap;
+ }
+ break;
+ case PROPERTY_MAP_FLDTYP_TEMPLATE_NAME :
+ {
+ static SfxItemPropertyMapEntry const aTmplNameFieldPropMap [] =
+ {
+ {OUString(UNO_NAME_FILE_FORMAT), FIELD_PROP_FORMAT, cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE, 0},
+ COMMON_FLDTYP_PROPERTIES
+ { OUString(), 0, css::uno::Type(), 0, 0 }
+ };
+ m_aMapEntriesArr[nPropertyId] = aTmplNameFieldPropMap;
+ }
+ break;
+ case PROPERTY_MAP_FLDTYP_USER_EXT :
+ {
+ static SfxItemPropertyMapEntry const aUsrExtFieldPropMap [] =
+ {
+ {OUString(UNO_NAME_CONTENT), FIELD_PROP_PAR1, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ {OUString(UNO_NAME_CURRENT_PRESENTATION), FIELD_PROP_PAR1, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ {OUString(UNO_NAME_IS_FIXED), FIELD_PROP_BOOL1, cppu::UnoType<bool>::get(), PROPERTY_NONE, 0},
+ {OUString(UNO_NAME_USER_DATA_TYPE), FIELD_PROP_USHORT1, cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE, 0},
+ COMMON_FLDTYP_PROPERTIES
+ { OUString(), 0, css::uno::Type(), 0, 0 }
+ };
+ m_aMapEntriesArr[nPropertyId]= aUsrExtFieldPropMap;
+ }
+ break;
+ case PROPERTY_MAP_FLDTYP_REF_PAGE_SET :
+ {
+ static SfxItemPropertyMapEntry const aRefPgSetFieldPropMap [] =
+ {
+ {OUString(UNO_NAME_OFFSET), FIELD_PROP_USHORT1, cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE, 0},
+ {OUString(UNO_NAME_ON), FIELD_PROP_BOOL1, cppu::UnoType<bool>::get(), PROPERTY_NONE, 0},
+ COMMON_FLDTYP_PROPERTIES
+ { OUString(), 0, css::uno::Type(), 0, 0 }
+ };
+ m_aMapEntriesArr[nPropertyId] = aRefPgSetFieldPropMap;
+ }
+ break;
+ case PROPERTY_MAP_FLDTYP_REF_PAGE_GET :
+ {
+ static SfxItemPropertyMapEntry const aRefPgGetFieldPropMap [] =
+ {
+ {OUString(UNO_NAME_CURRENT_PRESENTATION), FIELD_PROP_PAR1, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ {OUString(UNO_NAME_NUMBERING_TYPE), FIELD_PROP_USHORT1, cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE, 0},
+ COMMON_FLDTYP_PROPERTIES
+ { OUString(), 0, css::uno::Type(), 0, 0 }
+ };
+ m_aMapEntriesArr[nPropertyId] = aRefPgGetFieldPropMap;
+ }
+ break;
+ case PROPERTY_MAP_FLDTYP_JUMP_EDIT :
+ {
+ static SfxItemPropertyMapEntry const aJumpEdtFieldPropMap [] =
+ {
+ {OUString(UNO_NAME_HINT), FIELD_PROP_PAR1, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ {OUString(UNO_NAME_PLACEHOLDER), FIELD_PROP_PAR2, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ {OUString(UNO_NAME_PLACEHOLDER_TYPE), FIELD_PROP_USHORT1, cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE, 0},
+ COMMON_FLDTYP_PROPERTIES
+ { OUString(), 0, css::uno::Type(), 0, 0 }
+ };
+ m_aMapEntriesArr[nPropertyId] = aJumpEdtFieldPropMap;
+ }
+ break;
+ case PROPERTY_MAP_FLDTYP_SCRIPT :
+ {
+ static SfxItemPropertyMapEntry const aScriptFieldPropMap [] =
+ {
+ {OUString(UNO_NAME_CONTENT), FIELD_PROP_PAR2, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ {OUString(UNO_NAME_SCRIPT_TYPE), FIELD_PROP_PAR1, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ {OUString(UNO_NAME_URL_CONTENT), FIELD_PROP_BOOL1, cppu::UnoType<bool>::get(), PROPERTY_NONE, 0},
+ COMMON_FLDTYP_PROPERTIES
+ { OUString(), 0, css::uno::Type(), 0, 0 }
+ };
+ 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.
+
+ {OUString(UNO_NAME_DATA_BASE_NAME) , FIELD_PROP_PAR1, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ {OUString(UNO_NAME_DATA_TABLE_NAME) , FIELD_PROP_PAR2, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ {OUString(UNO_NAME_CONDITION) , FIELD_PROP_PAR3, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ {OUString(UNO_NAME_DATA_BASE_URL) , FIELD_PROP_PAR1, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ {OUString(UNO_NAME_DATA_COMMAND_TYPE), FIELD_PROP_SHORT1, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE, 0},
+ COMMON_FLDTYP_PROPERTIES
+ { OUString(), 0, css::uno::Type(), 0, 0 }
+ };
+ 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.
+
+ {OUString(UNO_NAME_DATA_BASE_NAME) , FIELD_PROP_PAR1, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ {OUString(UNO_NAME_DATA_TABLE_NAME), FIELD_PROP_PAR2, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ {OUString(UNO_NAME_CONDITION), FIELD_PROP_PAR3, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ {OUString(UNO_NAME_DATA_BASE_URL) , FIELD_PROP_PAR1, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ {OUString(UNO_NAME_DATA_COMMAND_TYPE), FIELD_PROP_SHORT1, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE, 0},
+ {OUString(UNO_NAME_SET_NUMBER), FIELD_PROP_FORMAT, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE, 0},
+ COMMON_FLDTYP_PROPERTIES
+ { OUString(), 0, css::uno::Type(), 0, 0 }
+ };
+ 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.
+
+ {OUString(UNO_NAME_DATA_BASE_NAME) , FIELD_PROP_PAR1, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ {OUString(UNO_NAME_DATA_TABLE_NAME) , FIELD_PROP_PAR2, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ {OUString(UNO_NAME_DATA_BASE_URL) , FIELD_PROP_PAR1, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ {OUString(UNO_NAME_DATA_COMMAND_TYPE), FIELD_PROP_SHORT1, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE, 0},
+ {OUString(UNO_NAME_NUMBERING_TYPE), FIELD_PROP_USHORT1, cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE, 0},
+ {OUString(UNO_NAME_SET_NUMBER), FIELD_PROP_FORMAT, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE, 0},
+ {OUString(UNO_NAME_IS_VISIBLE), FIELD_PROP_BOOL2, cppu::UnoType<bool>::get(), PROPERTY_NONE, 0},
+ COMMON_FLDTYP_PROPERTIES
+ { OUString(), 0, css::uno::Type(), 0, 0 }
+ };
+ m_aMapEntriesArr[nPropertyId] = aDBSetNumFieldPropMap;
+ }
+ break;
+ case PROPERTY_MAP_FLDTYP_DATABASE :
+ {
+ static SfxItemPropertyMapEntry const aDBFieldPropMap [] =
+ {
+ {OUString(UNO_NAME_CONTENT), FIELD_PROP_PAR1, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ {OUString(UNO_NAME_CURRENT_PRESENTATION), FIELD_PROP_PAR1, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ {OUString(UNO_NAME_FIELD_CODE), FIELD_PROP_PAR2, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ {OUString(UNO_NAME_IS_DATA_BASE_FORMAT),FIELD_PROP_BOOL1, cppu::UnoType<bool>::get() , PROPERTY_NONE,0},
+ {OUString(UNO_NAME_NUMBER_FORMAT), FIELD_PROP_FORMAT, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE, 0},
+ {OUString(UNO_NAME_IS_VISIBLE), FIELD_PROP_BOOL2, cppu::UnoType<bool>::get(), PROPERTY_NONE, 0},
+ COMMON_FLDTYP_PROPERTIES
+ { OUString(), 0, css::uno::Type(), 0, 0 }
+ };
+ 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.
+
+ {OUString(UNO_NAME_DATA_BASE_NAME) , FIELD_PROP_PAR1, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ {OUString(UNO_NAME_DATA_TABLE_NAME) , FIELD_PROP_PAR2, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ {OUString(UNO_NAME_DATA_BASE_URL) , FIELD_PROP_PAR1, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ {OUString(UNO_NAME_DATA_COMMAND_TYPE), FIELD_PROP_SHORT1, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE, 0},
+ {OUString(UNO_NAME_IS_VISIBLE), FIELD_PROP_BOOL2, cppu::UnoType<bool>::get(), PROPERTY_NONE, 0},
+ COMMON_FLDTYP_PROPERTIES
+ { OUString(), 0, css::uno::Type(), 0, 0 }
+ };
+ m_aMapEntriesArr[nPropertyId] = aDBNameFieldPropMap;
+ }
+ break;
+ case PROPERTY_MAP_FLDTYP_DOCSTAT:
+ {
+ static SfxItemPropertyMapEntry const aDocstatFieldPropMap [] =
+ {
+ {OUString(UNO_NAME_NUMBERING_TYPE), FIELD_PROP_USHORT2, cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE, 0},
+ // {OUString(UNO_NAME_STATISTIC_TYPE_ID),FIELD_PROP_USHORT1, cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE, 0},
+ COMMON_FLDTYP_PROPERTIES
+ { OUString(), 0, css::uno::Type(), 0, 0 }
+ };
+ m_aMapEntriesArr[nPropertyId] = aDocstatFieldPropMap;
+ }
+ break;
+ case PROPERTY_MAP_FLDTYP_DOCINFO_AUTHOR:
+ {
+ static SfxItemPropertyMapEntry const aDocInfoAuthorPropMap [] =
+ {
+ {OUString(UNO_NAME_AUTHOR), FIELD_PROP_PAR1, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ {OUString(UNO_NAME_CURRENT_PRESENTATION), FIELD_PROP_PAR3, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ {OUString(UNO_NAME_IS_FIXED), FIELD_PROP_BOOL1, cppu::UnoType<bool>::get() , PROPERTY_NONE,0},
+ COMMON_FLDTYP_PROPERTIES
+ { OUString(), 0, css::uno::Type(), 0, 0 }
+ };
+ m_aMapEntriesArr[nPropertyId] = aDocInfoAuthorPropMap;
+ }
+ break;
+ case PROPERTY_MAP_FLDTYP_DOCINFO_DATE_TIME:
+ {
+ static SfxItemPropertyMapEntry const aDocInfoDateTimePropMap [] =
+ {
+ {OUString(UNO_NAME_CURRENT_PRESENTATION), FIELD_PROP_PAR3, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ {OUString(UNO_NAME_DATE_TIME_VALUE), FIELD_PROP_DOUBLE, cppu::UnoType<double>::get(), PropertyAttribute::READONLY, 0},
+ {OUString(UNO_NAME_IS_DATE), FIELD_PROP_BOOL2, cppu::UnoType<bool>::get() , PROPERTY_NONE,0},
+ {OUString(UNO_NAME_NUMBER_FORMAT),FIELD_PROP_FORMAT, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE, 0},
+ {OUString(UNO_NAME_IS_FIXED), FIELD_PROP_BOOL1, cppu::UnoType<bool>::get() , PROPERTY_NONE, 0},
+ {OUString(UNO_NAME_IS_FIXED_LANGUAGE), FIELD_PROP_BOOL4, cppu::UnoType<bool>::get(), PROPERTY_NONE, 0},
+ { OUString(), 0, css::uno::Type(), 0, 0 }
+ };
+ m_aMapEntriesArr[nPropertyId] = aDocInfoDateTimePropMap;
+ }
+ break;
+ case PROPERTY_MAP_FLDTYP_DOCINFO_EDIT_TIME :
+ {
+ static SfxItemPropertyMapEntry const aDocInfoEditTimePropMap [] =
+ {
+ {OUString(UNO_NAME_CURRENT_PRESENTATION), FIELD_PROP_PAR3, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ {OUString(UNO_NAME_DATE_TIME_VALUE), FIELD_PROP_DOUBLE, cppu::UnoType<double>::get(), PropertyAttribute::READONLY, 0},
+ {OUString(UNO_NAME_NUMBER_FORMAT),FIELD_PROP_FORMAT, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE, 0},
+ {OUString(UNO_NAME_IS_FIXED), FIELD_PROP_BOOL1, cppu::UnoType<bool>::get() , PROPERTY_NONE, 0},
+ {OUString(UNO_NAME_IS_FIXED_LANGUAGE), FIELD_PROP_BOOL4, cppu::UnoType<bool>::get(), PROPERTY_NONE, 0},
+ COMMON_FLDTYP_PROPERTIES
+ { OUString(), 0, css::uno::Type(), 0, 0 }
+ };
+ m_aMapEntriesArr[nPropertyId] = aDocInfoEditTimePropMap;
+ }
+ break;
+ case PROPERTY_MAP_FLDTYP_DOCINFO_MISC:
+ {
+ static SfxItemPropertyMapEntry const aDocInfoStringContentPropMap [] =
+ {
+ {OUString(UNO_NAME_CONTENT), FIELD_PROP_PAR1, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ {OUString(UNO_NAME_CURRENT_PRESENTATION), FIELD_PROP_PAR3, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ {OUString(UNO_NAME_IS_FIXED), FIELD_PROP_BOOL1, cppu::UnoType<bool>::get() , PROPERTY_NONE,0},
+ COMMON_FLDTYP_PROPERTIES
+ { OUString(), 0, css::uno::Type(), 0, 0 }
+ };
+ m_aMapEntriesArr[nPropertyId] = aDocInfoStringContentPropMap;
+ }
+ break;
+ case PROPERTY_MAP_FLDTYP_DOCINFO_CUSTOM:
+ {
+ static SfxItemPropertyMapEntry const aDocInfoCustomPropMap [] =
+ {
+ {OUString(UNO_NAME_NAME), FIELD_PROP_PAR4, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ {OUString(UNO_NAME_CURRENT_PRESENTATION), FIELD_PROP_PAR3, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ {OUString(UNO_NAME_IS_FIXED), FIELD_PROP_BOOL1, cppu::UnoType<bool>::get() , PROPERTY_NONE,0},
+ {OUString(UNO_NAME_NUMBER_FORMAT), FIELD_PROP_FORMAT, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE, 0},
+ {OUString(UNO_NAME_IS_FIXED_LANGUAGE), FIELD_PROP_BOOL4, cppu::UnoType<bool>::get(), PROPERTY_NONE, 0},
+ COMMON_FLDTYP_PROPERTIES
+ { OUString(), 0, css::uno::Type(), 0, 0 }
+ };
+ m_aMapEntriesArr[nPropertyId] = aDocInfoCustomPropMap;
+ }
+ break;
+ case PROPERTY_MAP_FLDTYP_DOCINFO_REVISION :
+ {
+ static SfxItemPropertyMapEntry const aDocInfoRevisionPropMap [] =
+ {
+ {OUString(UNO_NAME_CURRENT_PRESENTATION), FIELD_PROP_PAR3, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ {OUString(UNO_NAME_REVISION), FIELD_PROP_USHORT1, cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE, 0},
+ {OUString(UNO_NAME_IS_FIXED), FIELD_PROP_BOOL1, cppu::UnoType<bool>::get() , PROPERTY_NONE,0},
+ COMMON_FLDTYP_PROPERTIES
+ { OUString(), 0, css::uno::Type(), 0, 0 }
+ };
+ m_aMapEntriesArr[nPropertyId] = aDocInfoRevisionPropMap;
+ }
+ break;
+ case PROPERTY_MAP_FLDTYP_COMBINED_CHARACTERS:
+ {
+ static SfxItemPropertyMapEntry const aCombinedCharactersPropMap[] =
+ {
+ {OUString(UNO_NAME_CONTENT), FIELD_PROP_PAR1, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ COMMON_FLDTYP_PROPERTIES
+ { OUString(), 0, css::uno::Type(), 0, 0 }
+ };
+ m_aMapEntriesArr[nPropertyId] = aCombinedCharactersPropMap;
+ }
+ break;
+ case PROPERTY_MAP_FLDTYP_TABLE_FORMULA:
+ {
+ static SfxItemPropertyMapEntry const aTableFormulaPropMap[] =
+ {
+ {OUString(UNO_NAME_CURRENT_PRESENTATION), FIELD_PROP_PAR1, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ {OUString(UNO_NAME_CONTENT), FIELD_PROP_PAR2, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ {OUString(UNO_NAME_IS_SHOW_FORMULA), FIELD_PROP_BOOL1, cppu::UnoType<bool>::get(), PROPERTY_NONE, 0},
+ {OUString(UNO_NAME_NUMBER_FORMAT), FIELD_PROP_FORMAT, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE, 0},
+ COMMON_FLDTYP_PROPERTIES
+ { OUString(), 0, css::uno::Type(), 0, 0 }
+ };
+ m_aMapEntriesArr[nPropertyId] = aTableFormulaPropMap;
+ }
+ break;
+ case PROPERTY_MAP_FLDTYP_DUMMY_0:
+ {
+ static SfxItemPropertyMapEntry const aEmptyPropMap [] =
+ {
+ COMMON_FLDTYP_PROPERTIES
+ { OUString(), 0, css::uno::Type(), 0, 0 }
+ };
+ m_aMapEntriesArr[nPropertyId] = aEmptyPropMap;
+ }
+ break;
+ case PROPERTY_MAP_FLDMSTR_USER :
+ {
+ static SfxItemPropertyMapEntry const aUserFieldTypePropMap[] =
+ {
+ {OUString(UNO_NAME_DEPENDENT_TEXT_FIELDS), FIELD_PROP_PROP_SEQ, cppu::UnoType< cppu::UnoSequenceType<css::text::XDependentTextField> >::get(), PropertyAttribute::READONLY, 0},
+ {OUString(UNO_NAME_IS_EXPRESSION), FIELD_PROP_BOOL1, cppu::UnoType<bool>::get(), PROPERTY_NONE, 0},
+ {OUString(UNO_NAME_NAME), FIELD_PROP_PAR1, cppu::UnoType<OUString>::get(), PropertyAttribute::MAYBEVOID, 0},
+ {OUString(UNO_NAME_VALUE), FIELD_PROP_DOUBLE, cppu::UnoType<double>::get(), PROPERTY_NONE, 0},
+ {OUString(UNO_NAME_CONTENT), FIELD_PROP_PAR2, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ {OUString(UNO_NAME_INSTANCE_NAME), FIELD_PROP_PAR3, cppu::UnoType<OUString>::get(), PropertyAttribute::READONLY, 0},
+ { OUString(), 0, css::uno::Type(), 0, 0 }
+ };
+ m_aMapEntriesArr[nPropertyId] = aUserFieldTypePropMap;
+ }
+ break;
+ case PROPERTY_MAP_FLDMSTR_DDE :
+ {
+ static SfxItemPropertyMapEntry const aDDEFieldTypePropMap[] =
+ {
+ {OUString(UNO_NAME_DDE_COMMAND_ELEMENT), FIELD_PROP_PAR2, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ {OUString(UNO_NAME_DDE_COMMAND_FILE), FIELD_PROP_PAR4, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ {OUString(UNO_NAME_DDE_COMMAND_TYPE), FIELD_PROP_SUBTYPE, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ {OUString(UNO_NAME_DEPENDENT_TEXT_FIELDS), FIELD_PROP_PROP_SEQ, cppu::UnoType< cppu::UnoSequenceType<css::text::XDependentTextField> >::get(), PropertyAttribute::READONLY, 0},
+ {OUString(UNO_NAME_IS_AUTOMATIC_UPDATE), FIELD_PROP_BOOL1, cppu::UnoType<bool>::get(), PROPERTY_NONE, 0},
+ {OUString(UNO_NAME_NAME), FIELD_PROP_PAR1, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ {OUString(UNO_NAME_INSTANCE_NAME), FIELD_PROP_PAR3, cppu::UnoType<OUString>::get(), PropertyAttribute::READONLY, 0},
+ {OUString(UNO_NAME_CONTENT), FIELD_PROP_PAR5, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ { OUString(), 0, css::uno::Type(), 0, 0 }
+ };
+ m_aMapEntriesArr[nPropertyId] = aDDEFieldTypePropMap;
+ }
+ break;
+ case PROPERTY_MAP_FLDMSTR_SET_EXP :
+ {
+ static SfxItemPropertyMapEntry const aSetExpFieldTypePropMap[] =
+ {
+ {OUString(UNO_NAME_CHAPTER_NUMBERING_LEVEL),FIELD_PROP_SHORT1, cppu::UnoType<sal_Int8>::get(), PROPERTY_NONE, 0},
+ {OUString(UNO_NAME_DEPENDENT_TEXT_FIELDS), FIELD_PROP_PROP_SEQ, cppu::UnoType< cppu::UnoSequenceType<css::text::XDependentTextField> >::get(), PropertyAttribute::READONLY, 0},
+ {OUString(UNO_NAME_NAME), FIELD_PROP_PAR1, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ {OUString(UNO_NAME_NUMBERING_SEPARATOR), FIELD_PROP_PAR2, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ {OUString(UNO_NAME_SUB_TYPE), FIELD_PROP_SUBTYPE, cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE, 0},
+ {OUString(UNO_NAME_INSTANCE_NAME), FIELD_PROP_PAR3, cppu::UnoType<OUString>::get(), PropertyAttribute::READONLY, 0},
+ { OUString(), 0, css::uno::Type(), 0, 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.
+
+ {OUString(UNO_NAME_DATA_BASE_NAME) , FIELD_PROP_PAR1, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ {OUString(UNO_NAME_NAME), FIELD_PROP_PAR3, cppu::UnoType<OUString>::get(), PropertyAttribute::MAYBEVOID, 0},
+ {OUString(UNO_NAME_DATA_TABLE_NAME), FIELD_PROP_PAR2, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ {OUString(UNO_NAME_DATA_COLUMN_NAME), FIELD_PROP_PAR3, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ {OUString(UNO_NAME_INSTANCE_NAME), FIELD_PROP_PAR4, cppu::UnoType<OUString>::get(), PropertyAttribute::READONLY, 0},
+ {OUString(UNO_NAME_DATA_BASE_URL) , FIELD_PROP_PAR1, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ {OUString(UNO_NAME_DATA_COMMAND_TYPE), FIELD_PROP_SHORT1, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE, 0},
+ {OUString(UNO_NAME_DEPENDENT_TEXT_FIELDS), FIELD_PROP_PROP_SEQ, cppu::UnoType< cppu::UnoSequenceType<css::text::XDependentTextField> >::get(), PropertyAttribute::READONLY, 0},
+ { OUString(), 0, css::uno::Type(), 0, 0 }
+ };
+ m_aMapEntriesArr[nPropertyId] = aDBFieldTypePropMap;
+ }
+ break;
+ case PROPERTY_MAP_FLDMSTR_DUMMY0 :
+ {
+ static SfxItemPropertyMapEntry const aStandardFieldMasterMap[] =
+ {
+ {OUString(UNO_NAME_DEPENDENT_TEXT_FIELDS), 0, cppu::UnoType< cppu::UnoSequenceType<css::text::XDependentTextField> >::get(), PropertyAttribute::READONLY, 0},
+ {OUString(UNO_NAME_NAME), 0, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ {OUString(UNO_NAME_INSTANCE_NAME), 0, cppu::UnoType<OUString>::get(), PropertyAttribute::READONLY, 0},
+ { OUString(), 0, css::uno::Type(), 0, 0 }
+ };
+ m_aMapEntriesArr[nPropertyId] = aStandardFieldMasterMap;
+ }
+ break;
+ case PROPERTY_MAP_FLDTYP_BIBLIOGRAPHY:
+ {
+ static SfxItemPropertyMapEntry const aBibliographyFieldMap[] =
+ {
+ {OUString(UNO_NAME_FIELDS) , FIELD_PROP_PROP_SEQ, cppu::UnoType< cppu::UnoSequenceType<css::beans::PropertyValue> >::get(),PROPERTY_NONE, 0},
+ COMMON_FLDTYP_PROPERTIES
+ { OUString(), 0, css::uno::Type(), 0, 0 }
+ };
+ m_aMapEntriesArr[nPropertyId] = aBibliographyFieldMap;
+ }
+ break;
+ case PROPERTY_MAP_FLDMSTR_BIBLIOGRAPHY:
+ {
+ static SfxItemPropertyMapEntry const aBibliographyFieldMasterMap[] =
+ {
+ {OUString(UNO_NAME_BRACKET_BEFORE) , FIELD_PROP_PAR1, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ {OUString(UNO_NAME_BRACKET_AFTER) , FIELD_PROP_PAR2, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ {OUString(UNO_NAME_IS_NUMBER_ENTRIES) , FIELD_PROP_BOOL1, cppu::UnoType<bool>::get(), PROPERTY_NONE, 0},
+ {OUString(UNO_NAME_IS_SORT_BY_POSITION) , FIELD_PROP_BOOL2, cppu::UnoType<bool>::get(), PROPERTY_NONE, 0},
+ {OUString(UNO_NAME_LOCALE), FIELD_PROP_LOCALE, cppu::UnoType<css::lang::Locale>::get() , PROPERTY_NONE, 0},
+ {OUString(UNO_NAME_SORT_ALGORITHM), FIELD_PROP_PAR3, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ {OUString(UNO_NAME_SORT_KEYS) , FIELD_PROP_PROP_SEQ, cppu::UnoType< cppu::UnoSequenceType<css::beans::PropertyValues> >::get(), PROPERTY_NONE, 0},
+ {OUString(UNO_NAME_INSTANCE_NAME), FIELD_PROP_PAR4, cppu::UnoType<OUString>::get(), PropertyAttribute::READONLY, 0},
+ { OUString(), 0, css::uno::Type(), 0, 0 }
+ };
+ m_aMapEntriesArr[nPropertyId] = aBibliographyFieldMasterMap;
+ }
+ break;
+ case PROPERTY_MAP_TEXT :
+ {
+ static SfxItemPropertyMapEntry const aTextMap[] =
+ {
+ REDLINE_NODE_PROPERTIES
+ { OUString(), 0, css::uno::Type(), 0, 0 }
+ };
+ m_aMapEntriesArr[nPropertyId] = aTextMap;
+ }
+ break;
+ case PROPERTY_MAP_MAILMERGE :
+ {
+ static SfxItemPropertyMapEntry const aMailMergeMap[] =
+ {
+ { OUString(UNO_NAME_SELECTION), WID_SELECTION, cppu::UnoType< cppu::UnoSequenceType<css::uno::Any> >::get(), PROPERTY_NONE, 0},
+ { OUString(UNO_NAME_RESULT_SET), WID_RESULT_SET, cppu::UnoType<css::sdbc::XResultSet>::get(), PROPERTY_NONE, 0},
+ { OUString(UNO_NAME_CONNECTION), WID_CONNECTION, cppu::UnoType<css::sdbc::XConnection>::get(), PROPERTY_NONE, 0},
+ { OUString(UNO_NAME_MODEL), WID_MODEL, cppu::UnoType<css::frame::XModel>::get(), PropertyAttribute::READONLY, 0},
+ { OUString(UNO_NAME_DATA_SOURCE_NAME), WID_DATA_SOURCE_NAME, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ { OUString(UNO_NAME_DAD_COMMAND), WID_DATA_COMMAND, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ { OUString(UNO_NAME_FILTER), WID_FILTER, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ { OUString(UNO_NAME_DOCUMENT_URL), WID_DOCUMENT_URL, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ { OUString(UNO_NAME_OUTPUT_URL), WID_OUTPUT_URL, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ { OUString(UNO_NAME_DAD_COMMAND_TYPE), WID_DATA_COMMAND_TYPE, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE, 0},
+ { OUString(UNO_NAME_OUTPUT_TYPE), WID_OUTPUT_TYPE, cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE, 0},
+ { OUString(UNO_NAME_ESCAPE_PROCESSING), WID_ESCAPE_PROCESSING, cppu::UnoType<bool>::get(), PROPERTY_NONE, 0},
+ { OUString(UNO_NAME_SINGLE_PRINT_JOBS), WID_SINGLE_PRINT_JOBS, cppu::UnoType<bool>::get(), PROPERTY_NONE, 0},
+ { OUString(UNO_NAME_FILE_NAME_FROM_COLUMN), WID_FILE_NAME_FROM_COLUMN, cppu::UnoType<bool>::get(), PROPERTY_NONE, 0},
+ { OUString(UNO_NAME_FILE_NAME_PREFIX), WID_FILE_NAME_PREFIX, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ { OUString(UNO_NAME_SUBJECT), WID_MAIL_SUBJECT, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ { OUString(UNO_NAME_ADDRESS_FROM_COLUMN), WID_ADDRESS_FROM_COLUMN, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ { OUString(UNO_NAME_SEND_AS_HTML), WID_SEND_AS_HTML, cppu::UnoType<bool>::get(), PROPERTY_NONE, 0},
+ { OUString(UNO_NAME_SEND_AS_ATTACHMENT), WID_SEND_AS_ATTACHMENT, cppu::UnoType<bool>::get(), PROPERTY_NONE, 0},
+ { OUString(UNO_NAME_MAIL_BODY), WID_MAIL_BODY, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ { OUString(UNO_NAME_ATTACHMENT_NAME), WID_ATTACHMENT_NAME, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ { OUString(UNO_NAME_ATTACHMENT_FILTER), WID_ATTACHMENT_FILTER, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ { OUString(UNO_NAME_PRINT_OPTIONS), WID_PRINT_OPTIONS, cppu::UnoType< cppu::UnoSequenceType<css::beans::PropertyValue> >::get(), PROPERTY_NONE, 0},
+ { OUString(UNO_NAME_SAVE_AS_SINGLE_FILE), WID_SAVE_AS_SINGLE_FILE, cppu::UnoType<bool>::get(), PROPERTY_NONE, 0},
+ { OUString(UNO_NAME_SAVE_FILTER), WID_SAVE_FILTER, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ { OUString(UNO_NAME_SAVE_FILTER_OPTIONS), WID_SAVE_FILTER_OPTIONS, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ { OUString(UNO_NAME_SAVE_FILTER_DATA), WID_SAVE_FILTER_DATA, cppu::UnoType< cppu::UnoSequenceType<css::beans::PropertyValue> >::get(), PROPERTY_NONE, 0},
+ { OUString(UNO_NAME_COPIES_TO), WID_COPIES_TO, cppu::UnoType< cppu::UnoSequenceType<OUString> >::get(), PROPERTY_NONE, 0},
+ { OUString(UNO_NAME_BLIND_COPIES_TO), WID_BLIND_COPIES_TO, cppu::UnoType< cppu::UnoSequenceType<OUString> >::get(), PROPERTY_NONE, 0},
+ { OUString(UNO_NAME_IN_SERVER_PASSWORD), WID_IN_SERVER_PASSWORD, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ { OUString(UNO_NAME_OUT_SERVER_PASSWORD), WID_OUT_SERVER_PASSWORD, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ { OUString(), 0, css::uno::Type(), 0, 0 }
+ };
+ m_aMapEntriesArr[nPropertyId] = aMailMergeMap;
+ }
+ break;
+ case PROPERTY_MAP_TEXT_VIEW :
+ {
+ static SfxItemPropertyMapEntry pTextViewMap[] =
+ {
+ {OUString(UNO_NAME_PAGE_COUNT), WID_PAGE_COUNT, cppu::UnoType<sal_Int32>::get(), PropertyAttribute::READONLY, 0},
+ {OUString(UNO_NAME_LINE_COUNT), WID_LINE_COUNT, cppu::UnoType<sal_Int32>::get(), PropertyAttribute::READONLY, 0},
+ {OUString(UNO_NAME_IS_CONSTANT_SPELLCHECK), WID_IS_CONSTANT_SPELLCHECK, cppu::UnoType<bool>::get(), PROPERTY_NONE, 0},
+ {OUString(UNO_NAME_IS_HIDE_SPELL_MARKS), WID_IS_HIDE_SPELL_MARKS, cppu::UnoType<bool>::get(), PROPERTY_NONE, 0}, // deprecated #i91949
+ { OUString(), 0, css::uno::Type(), 0, 0 }
+ };
+ m_aMapEntriesArr[nPropertyId] = pTextViewMap;
+ }
+ break;
+ case PROPERTY_MAP_CHART2_DATA_SEQUENCE :
+ {
+ static SfxItemPropertyMapEntry const aChart2DataSequenceMap[] =
+ {
+ {OUString(UNO_NAME_ROLE), 0, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0 },
+ { OUString(), 0, css::uno::Type(), 0, 0 }
+ };
+ m_aMapEntriesArr[nPropertyId] = aChart2DataSequenceMap;
+ }
+ break;
+ case PROPERTY_MAP_METAFIELD:
+ {
+ static SfxItemPropertyMapEntry const aMetaFieldMap[] =
+ {
+ { OUString(UNO_NAME_NUMBER_FORMAT), 0,
+ cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE, 0 },
+ { OUString(UNO_NAME_IS_FIXED_LANGUAGE), 0,
+ cppu::UnoType<bool>::get(), PROPERTY_NONE, 0 },
+ { OUString(), 0, css::uno::Type(), 0, 0 }
+ };
+ m_aMapEntriesArr[nPropertyId] = aMetaFieldMap;
+ }
+ break;
+ case PROPERTY_MAP_TABLE_STYLE:
+ {
+ static SfxItemPropertyMapEntry const aTableStyleMap[] =
+ {
+ { OUString(UNO_NAME_TABLE_FIRST_ROW_END_COLUMN), 0, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0 },
+ { OUString(UNO_NAME_TABLE_FIRST_ROW_START_COLUMN), 0, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0 },
+ { OUString(UNO_NAME_TABLE_LAST_ROW_END_COLUMN), 0, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0 },
+ { OUString(UNO_NAME_TABLE_LAST_ROW_START_COLUMN), 0, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0 },
+ { OUString(), 0, css::uno::Type(), 0, 0 }
+ };
+ m_aMapEntriesArr[nPropertyId] = aTableStyleMap;
+ }
+ break;
+ case PROPERTY_MAP_CELL_STYLE:
+ {
+ static SfxItemPropertyMapEntry const aCellStyleMap[] =
+ {
+ // SvxBrushItem
+ { OUString(UNO_NAME_BACK_COLOR), RES_BACKGROUND, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE, 0 },
+ // SvxBoxItem
+ { OUString(UNO_NAME_LEFT_BORDER), RES_BOX, cppu::UnoType<css::table::BorderLine>::get(), PROPERTY_NONE, LEFT_BORDER|CONVERT_TWIPS },
+ { OUString(UNO_NAME_RIGHT_BORDER), RES_BOX, cppu::UnoType<css::table::BorderLine>::get(), PROPERTY_NONE, RIGHT_BORDER|CONVERT_TWIPS },
+ { OUString(UNO_NAME_TOP_BORDER), RES_BOX, cppu::UnoType<css::table::BorderLine>::get(), PROPERTY_NONE, TOP_BORDER|CONVERT_TWIPS },
+ { OUString(UNO_NAME_BOTTOM_BORDER), RES_BOX, cppu::UnoType<css::table::BorderLine>::get(), PROPERTY_NONE, BOTTOM_BORDER|CONVERT_TWIPS },
+ { OUString(UNO_NAME_BORDER_DISTANCE), RES_BOX, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE, BORDER_DISTANCE|CONVERT_TWIPS },
+ { OUString(UNO_NAME_LEFT_BORDER_DISTANCE), RES_BOX, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE, LEFT_BORDER_DISTANCE |CONVERT_TWIPS },
+ { OUString(UNO_NAME_RIGHT_BORDER_DISTANCE), RES_BOX, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE, RIGHT_BORDER_DISTANCE |CONVERT_TWIPS },
+ { OUString(UNO_NAME_TOP_BORDER_DISTANCE), RES_BOX, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE, TOP_BORDER_DISTANCE |CONVERT_TWIPS },
+ { OUString(UNO_NAME_BOTTOM_BORDER_DISTANCE), RES_BOX, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE, BOTTOM_BORDER_DISTANCE|CONVERT_TWIPS },
+ // SwFormatVertOrient
+ { OUString(UNO_NAME_VERT_ORIENT), RES_VERT_ORIENT, cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE, MID_VERTORIENT_ORIENT },
+ // SvxFrameDirectionItem
+ { OUString(UNO_NAME_WRITING_MODE), RES_FRAMEDIR, cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE, 0 },
+ // SvNumberformat
+ { OUString(UNO_NAME_NUMBER_FORMAT), RES_BOXATR_FORMAT, cppu::UnoType<sal_Int32>::get(),PropertyAttribute::MAYBEVOID, 0 },
+ // SvxAdjustItem
+ { OUString(UNO_NAME_PARA_ADJUST), RES_PARATR_ADJUST, cppu::UnoType<sal_Int16>::get(),PropertyAttribute::MAYBEVOID, MID_PARA_ADJUST },
+ // SvxColorItem
+ { OUString(UNO_NAME_CHAR_COLOR), RES_CHRATR_COLOR, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE, 0 },
+ // SvxShadowedItem
+ { OUString(UNO_NAME_CHAR_SHADOWED), RES_CHRATR_SHADOWED, cppu::UnoType<bool>::get(), PROPERTY_NONE, 0 },
+ // SvxContouredItem
+ { OUString(UNO_NAME_CHAR_CONTOURED), RES_CHRATR_CONTOUR, cppu::UnoType<bool>::get(), PROPERTY_NONE, 0 },
+ // SvxCrossedOutItem
+ { OUString(UNO_NAME_CHAR_STRIKEOUT), RES_CHRATR_CROSSEDOUT, cppu::UnoType<sal_Int16>::get(),PropertyAttribute::MAYBEVOID, MID_CROSS_OUT },
+ // SvxUnderlineItem
+ { OUString(UNO_NAME_CHAR_UNDERLINE), RES_CHRATR_UNDERLINE, cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE, MID_TL_STYLE },
+ { OUString(UNO_NAME_CHAR_UNDERLINE_COLOR), RES_CHRATR_UNDERLINE,cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE, MID_TL_COLOR },
+ { OUString(UNO_NAME_CHAR_UNDERLINE_HAS_COLOR), RES_CHRATR_UNDERLINE, cppu::UnoType<bool>::get(), PROPERTY_NONE, MID_TL_HASCOLOR },
+ // standard font
+ // SvxFontHeightItem
+ { OUString(UNO_NAME_CHAR_HEIGHT), RES_CHRATR_FONTSIZE, cppu::UnoType<float>::get(),PropertyAttribute::MAYBEVOID, MID_FONTHEIGHT|CONVERT_TWIPS },
+ // SvxWeightItem
+ { OUString(UNO_NAME_CHAR_WEIGHT), RES_CHRATR_WEIGHT, cppu::UnoType<float>::get(),PropertyAttribute::MAYBEVOID, MID_WEIGHT },
+ // SvxPostureItem
+ { OUString(UNO_NAME_CHAR_POSTURE), RES_CHRATR_POSTURE, cppu::UnoType<css::awt::FontSlant>::get(),PropertyAttribute::MAYBEVOID, MID_POSTURE },
+ // SvxFontItem
+ { OUString(UNO_NAME_CHAR_FONT_NAME), RES_CHRATR_FONT, cppu::UnoType<OUString>::get(), PropertyAttribute::MAYBEVOID, MID_FONT_FAMILY_NAME },
+ { OUString(UNO_NAME_CHAR_FONT_STYLE_NAME), RES_CHRATR_FONT, cppu::UnoType<OUString>::get(), PropertyAttribute::MAYBEVOID, MID_FONT_STYLE_NAME },
+ { OUString(UNO_NAME_CHAR_FONT_FAMILY), RES_CHRATR_FONT, cppu::UnoType<sal_Int16>::get(), PropertyAttribute::MAYBEVOID, MID_FONT_FAMILY },
+ { OUString(UNO_NAME_CHAR_FONT_CHAR_SET), RES_CHRATR_FONT, cppu::UnoType<sal_Int16>::get(), PropertyAttribute::MAYBEVOID, MID_FONT_CHAR_SET },
+ { OUString(UNO_NAME_CHAR_FONT_PITCH), RES_CHRATR_FONT, cppu::UnoType<sal_Int16>::get(), PropertyAttribute::MAYBEVOID, MID_FONT_PITCH },
+ // cjk font
+ { OUString(UNO_NAME_CHAR_HEIGHT_ASIAN), RES_CHRATR_CJK_FONTSIZE, cppu::UnoType<float>::get(), PropertyAttribute::MAYBEVOID, MID_FONTHEIGHT|CONVERT_TWIPS },
+ { OUString(UNO_NAME_CHAR_WEIGHT_ASIAN), RES_CHRATR_CJK_WEIGHT, cppu::UnoType<float>::get(), PropertyAttribute::MAYBEVOID, MID_WEIGHT },
+ { OUString(UNO_NAME_CHAR_POSTURE_ASIAN), RES_CHRATR_CJK_POSTURE, cppu::UnoType<css::awt::FontSlant>::get(), PropertyAttribute::MAYBEVOID, MID_POSTURE },
+ { OUString(UNO_NAME_CHAR_FONT_NAME_ASIAN), RES_CHRATR_CJK_FONT, cppu::UnoType<OUString>::get(), PropertyAttribute::MAYBEVOID, MID_FONT_FAMILY_NAME },
+ { OUString(UNO_NAME_CHAR_FONT_STYLE_NAME_ASIAN), RES_CHRATR_CJK_FONT, cppu::UnoType<OUString>::get(), PropertyAttribute::MAYBEVOID, MID_FONT_STYLE_NAME },
+ { OUString(UNO_NAME_CHAR_FONT_FAMILY_ASIAN), RES_CHRATR_CJK_FONT, cppu::UnoType<sal_Int16>::get(), PropertyAttribute::MAYBEVOID, MID_FONT_FAMILY },
+ { OUString(UNO_NAME_CHAR_FONT_CHAR_SET_ASIAN), RES_CHRATR_CJK_FONT, cppu::UnoType<sal_Int16>::get(), PropertyAttribute::MAYBEVOID, MID_FONT_CHAR_SET },
+ { OUString(UNO_NAME_CHAR_FONT_PITCH_ASIAN), RES_CHRATR_CJK_FONT, cppu::UnoType<sal_Int16>::get(), PropertyAttribute::MAYBEVOID, MID_FONT_PITCH },
+ // ctl font
+ { OUString(UNO_NAME_CHAR_HEIGHT_COMPLEX), RES_CHRATR_CTL_FONTSIZE, cppu::UnoType<float>::get(), PropertyAttribute::MAYBEVOID, MID_FONTHEIGHT|CONVERT_TWIPS },
+ { OUString(UNO_NAME_CHAR_WEIGHT_COMPLEX), RES_CHRATR_CTL_WEIGHT, cppu::UnoType<float>::get(), PropertyAttribute::MAYBEVOID, MID_WEIGHT },
+ { OUString(UNO_NAME_CHAR_POSTURE_COMPLEX), RES_CHRATR_CTL_POSTURE, cppu::UnoType<css::awt::FontSlant>::get(), PropertyAttribute::MAYBEVOID, MID_POSTURE },
+ { OUString(UNO_NAME_CHAR_FONT_NAME_COMPLEX), RES_CHRATR_CTL_FONT, cppu::UnoType<OUString>::get(), PropertyAttribute::MAYBEVOID, MID_FONT_FAMILY_NAME },
+ { OUString(UNO_NAME_CHAR_FONT_STYLE_NAME_COMPLEX), RES_CHRATR_CTL_FONT, cppu::UnoType<OUString>::get(), PropertyAttribute::MAYBEVOID, MID_FONT_STYLE_NAME },
+ { OUString(UNO_NAME_CHAR_FONT_FAMILY_COMPLEX), RES_CHRATR_CTL_FONT, cppu::UnoType<sal_Int16>::get(), PropertyAttribute::MAYBEVOID, MID_FONT_FAMILY },
+ { OUString(UNO_NAME_CHAR_FONT_CHAR_SET_COMPLEX), RES_CHRATR_CTL_FONT, cppu::UnoType<sal_Int16>::get(), PropertyAttribute::MAYBEVOID, MID_FONT_CHAR_SET },
+ { OUString(UNO_NAME_CHAR_FONT_PITCH_COMPLEX), RES_CHRATR_CTL_FONT, cppu::UnoType<sal_Int16>::get(), PropertyAttribute::MAYBEVOID, MID_FONT_PITCH },
+ { OUString(), 0, css::uno::Type(), 0, 0 }
+ };
+ m_aMapEntriesArr[nPropertyId] = aCellStyleMap;
+ }
+ 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 000000000..909f183bb
--- /dev/null
+++ b/sw/source/core/unocore/unomap1.cxx
@@ -0,0 +1,1665 @@
+/* -*- 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/svxids.hrc>
+#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 <unomap.hxx>
+#include <unoprnms.hxx>
+#include <unomid.h>
+#include <cmdid.h>
+#include <editeng/colritem.hxx>
+#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_aMapEntriesArr[i] = nullptr;
+ m_aPropertySetArr[i] = nullptr;
+ }
+}
+
+SwUnoPropertyMapProvider::~SwUnoPropertyMapProvider()
+{
+}
+
+const SfxItemPropertyMapEntry* SwUnoPropertyMapProvider::GetTextCursorPropertyMap()
+{
+ static SfxItemPropertyMapEntry const aCharAndParaMap_Impl[] =
+ {
+ COMPLETE_TEXT_CURSOR_MAP
+ { OUString(), 0, css::uno::Type(), 0, 0 }
+ };
+
+ return aCharAndParaMap_Impl;
+}
+
+const SfxItemPropertyMapEntry* SwUnoPropertyMapProvider::GetAccessibilityTextAttrPropertyMap()
+{
+ static SfxItemPropertyMapEntry const aAccessibilityTextAttrMap_Impl[] =
+ {
+ COMMON_ACCESSIBILITY_TEXT_ATTRIBUTE
+ { OUString(), 0, css::uno::Type(), 0, 0 }
+ };
+
+ return aAccessibilityTextAttrMap_Impl;
+}
+
+const SfxItemPropertyMapEntry* SwUnoPropertyMapProvider::GetParagraphPropertyMap()
+{
+ static SfxItemPropertyMapEntry const aParagraphMap_Impl[] =
+ {
+ COMMON_CRSR_PARA_PROPERTIES_2
+ TABSTOPS_MAP_ENTRY
+ COMMON_TEXT_CONTENT_PROPERTIES
+ { OUString(UNO_NAME_CHAR_STYLE_NAME), RES_TXTATR_CHARFMT, cppu::UnoType<OUString>::get(), PropertyAttribute::MAYBEVOID, 0},
+ { OUString(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
+ { OUString(), 0, css::uno::Type(), 0, 0 }
+ };
+
+ return aParagraphMap_Impl;
+}
+
+const SfxItemPropertyMapEntry* SwUnoPropertyMapProvider::GetAutoParaStylePropertyMap()
+{
+ static SfxItemPropertyMapEntry const aAutoParaStyleMap [] =
+ {
+ { OUString(UNO_NAME_PARA_STYLE_NAME), RES_FRMATR_STYLE_NAME, cppu::UnoType<OUString>::get(), PropertyAttribute::MAYBEVOID, 0},
+ { OUString(UNO_NAME_PAGE_STYLE_NAME), FN_UNO_PAGE_STYLE, cppu::UnoType<OUString>::get(), PropertyAttribute::MAYBEVOID|PropertyAttribute::READONLY, 0},
+ { OUString(UNO_NAME_NUMBERING_IS_NUMBER), FN_UNO_IS_NUMBER, cppu::UnoType<bool>::get() , PropertyAttribute::MAYBEVOID, 0},
+ { OUString(UNO_NAME_NUMBERING_LEVEL), FN_UNO_NUM_LEVEL, cppu::UnoType<sal_Int16>::get(), PropertyAttribute::MAYBEVOID, 0},
+ { OUString(UNO_NAME_NUMBERING_START_VALUE), FN_UNO_NUM_START_VALUE, cppu::UnoType<sal_Int16>::get(), PropertyAttribute::MAYBEVOID, CONVERT_TWIPS},
+ { OUString(UNO_NAME_DOCUMENT_INDEX), FN_UNO_DOCUMENT_INDEX, cppu::UnoType<css::text::XDocumentIndex>::get(), PropertyAttribute::MAYBEVOID|PropertyAttribute::READONLY ,0 },
+ { OUString(UNO_NAME_TEXT_TABLE), FN_UNO_TEXT_TABLE, cppu::UnoType<css::text::XTextTable>::get(), PropertyAttribute::MAYBEVOID|PropertyAttribute::READONLY ,0 },
+ { OUString(UNO_NAME_CELL), FN_UNO_CELL, cppu::UnoType<css::table::XCell>::get(), PropertyAttribute::MAYBEVOID|PropertyAttribute::READONLY ,0 },
+ { OUString(UNO_NAME_TEXT_FRAME), FN_UNO_TEXT_FRAME, cppu::UnoType<css::text::XTextFrame>::get(), PropertyAttribute::MAYBEVOID|PropertyAttribute::READONLY ,0 },
+ { OUString(UNO_NAME_TEXT_SECTION), FN_UNO_TEXT_SECTION, cppu::UnoType<css::text::XTextSection>::get(), PropertyAttribute::MAYBEVOID|PropertyAttribute::READONLY ,0 },
+ { OUString(UNO_NAME_PARA_CHAPTER_NUMBERING_LEVEL), FN_UNO_PARA_CHAPTER_NUMBERING_LEVEL,cppu::UnoType<sal_Int8>::get(), PropertyAttribute::MAYBEVOID, 0},
+ { OUString(UNO_NAME_PARA_CONDITIONAL_STYLE_NAME), RES_FRMATR_CONDITIONAL_STYLE_NAME, cppu::UnoType<OUString>::get(), PropertyAttribute::MAYBEVOID|PropertyAttribute::READONLY, 0},
+ { OUString(UNO_NAME_PARA_IS_NUMBERING_RESTART), FN_NUMBER_NEWSTART, cppu::UnoType<bool>::get(), PropertyAttribute::MAYBEVOID, 0 },
+ // TODO add RES_PARATR_LIST_AUTOFMT?
+ { OUString(UNO_NAME_OUTLINE_LEVEL), RES_PARATR_OUTLINELEVEL, cppu::UnoType<sal_Int16>::get(), PropertyAttribute::MAYBEVOID, 0},
+ COMMON_CRSR_PARA_PROPERTIES_WITHOUT_FN
+ TABSTOPS_MAP_ENTRY
+ COMMON_TEXT_CONTENT_PROPERTIES
+ { OUString(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
+ { OUString(), 0, css::uno::Type(), 0, 0 }
+ };
+
+ return aAutoParaStyleMap;
+}
+
+const SfxItemPropertyMapEntry* SwUnoPropertyMapProvider::GetCharStylePropertyMap()
+{
+ static SfxItemPropertyMapEntry const aCharStyleMap [] =
+ {
+ { OUString(UNO_NAME_CHAR_AUTO_KERNING), RES_CHRATR_AUTOKERN , cppu::UnoType<bool>::get() , PROPERTY_NONE, 0},
+ { OUString(UNO_NAME_CHAR_BACK_TRANSPARENT), RES_CHRATR_BACKGROUND, cppu::UnoType<bool>::get(), PROPERTY_NONE ,MID_GRAPHIC_TRANSPARENT },
+ { OUString(UNO_NAME_CHAR_BACK_COLOR), RES_CHRATR_BACKGROUND, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE ,MID_BACK_COLOR },
+ { OUString(UNO_NAME_CHAR_HIGHLIGHT), RES_CHRATR_HIGHLIGHT, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE, MID_BACK_COLOR },
+ { OUString(UNO_NAME_CHAR_CASE_MAP), RES_CHRATR_CASEMAP, cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE, 0},
+ { OUString(UNO_NAME_CHAR_COLOR), RES_CHRATR_COLOR, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE, 0},
+ { OUString(UNO_NAME_CHAR_TRANSPARENCE), RES_CHRATR_COLOR, cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE, MID_COLOR_ALPHA},
+ { OUString(UNO_NAME_CHAR_STRIKEOUT), RES_CHRATR_CROSSEDOUT, cppu::UnoType<sal_Int16>::get(), PropertyAttribute::MAYBEVOID, MID_CROSS_OUT},
+ { OUString(UNO_NAME_CHAR_CROSSED_OUT), RES_CHRATR_CROSSEDOUT, cppu::UnoType<bool>::get() , PROPERTY_NONE, 0},
+ { OUString(UNO_NAME_CHAR_ESCAPEMENT), RES_CHRATR_ESCAPEMENT, cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE, MID_ESC },
+ { OUString(UNO_NAME_CHAR_ESCAPEMENT_HEIGHT), RES_CHRATR_ESCAPEMENT, cppu::UnoType<sal_Int8>::get() , PROPERTY_NONE, MID_ESC_HEIGHT},
+ { OUString(UNO_NAME_CHAR_FLASH), RES_CHRATR_BLINK , cppu::UnoType<bool>::get() , PROPERTY_NONE, 0},
+ { OUString(UNO_NAME_CHAR_HIDDEN), RES_CHRATR_HIDDEN, cppu::UnoType<bool>::get() , PROPERTY_NONE, 0},
+ STANDARD_FONT_PROPERTIES
+ CJK_FONT_PROPERTIES
+ CTL_FONT_PROPERTIES
+ { OUString(UNO_NAME_CHAR_UNDERLINE), RES_CHRATR_UNDERLINE , cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE, MID_TL_STYLE},
+ { OUString(UNO_NAME_CHAR_UNDERLINE_COLOR), RES_CHRATR_UNDERLINE , cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE, MID_TL_COLOR},
+ { OUString(UNO_NAME_CHAR_UNDERLINE_HAS_COLOR), RES_CHRATR_UNDERLINE , cppu::UnoType<bool>::get(), PROPERTY_NONE, MID_TL_HASCOLOR},
+ { OUString(UNO_NAME_CHAR_OVERLINE), RES_CHRATR_OVERLINE , cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE, MID_TL_STYLE},
+ { OUString(UNO_NAME_CHAR_OVERLINE_COLOR), RES_CHRATR_OVERLINE , cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE, MID_TL_COLOR},
+ { OUString(UNO_NAME_CHAR_OVERLINE_HAS_COLOR), RES_CHRATR_OVERLINE , cppu::UnoType<bool>::get(), PROPERTY_NONE, MID_TL_HASCOLOR},
+ { OUString(UNO_NAME_CHAR_KERNING), RES_CHRATR_KERNING , cppu::UnoType<sal_Int16>::get() , PROPERTY_NONE, CONVERT_TWIPS},
+ { OUString(UNO_NAME_CHAR_NO_HYPHENATION), RES_CHRATR_NOHYPHEN , cppu::UnoType<bool>::get() , PROPERTY_NONE, 0},
+ { OUString(UNO_NAME_CHAR_SHADOWED), RES_CHRATR_SHADOWED , cppu::UnoType<bool>::get() , PROPERTY_NONE, 0},
+ { OUString(UNO_NAME_CHAR_CONTOURED), RES_CHRATR_CONTOUR, cppu::UnoType<bool>::get() , PROPERTY_NONE, 0},
+ { OUString(UNO_NAME_CHAR_WORD_MODE), RES_CHRATR_WORDLINEMODE,cppu::UnoType<bool>::get() , PROPERTY_NONE, 0},
+ { OUString(UNO_NAME_USER_DEFINED_ATTRIBUTES), RES_UNKNOWNATR_CONTAINER, cppu::UnoType<css::container::XNameContainer>::get(), PropertyAttribute::MAYBEVOID, 0 },
+ { OUString(UNO_NAME_IS_PHYSICAL), FN_UNO_IS_PHYSICAL, cppu::UnoType<bool>::get(), PropertyAttribute::READONLY, 0},
+ { OUString(UNO_NAME_HIDDEN), FN_UNO_HIDDEN, cppu::UnoType<bool>::get(), PROPERTY_NONE, 0},
+ { OUString(UNO_NAME_STYLE_INTEROP_GRAB_BAG), FN_UNO_STYLE_INTEROP_GRAB_BAG, cppu::UnoType< cppu::UnoSequenceType<css::beans::PropertyValue> >::get(), PROPERTY_NONE, 0},
+ { OUString(UNO_NAME_DISPLAY_NAME), FN_UNO_DISPLAY_NAME, cppu::UnoType<OUString>::get(), PropertyAttribute::READONLY, 0},
+ { OUString(UNO_NAME_CHAR_COMBINE_IS_ON), RES_CHRATR_TWO_LINES, cppu::UnoType<bool>::get(), PROPERTY_NONE, MID_TWOLINES},
+ { OUString(UNO_NAME_CHAR_COMBINE_PREFIX), RES_CHRATR_TWO_LINES, cppu::UnoType<OUString>::get(), PROPERTY_NONE, MID_START_BRACKET},
+ { OUString(UNO_NAME_CHAR_COMBINE_SUFFIX), RES_CHRATR_TWO_LINES, cppu::UnoType<OUString>::get(), PROPERTY_NONE, MID_END_BRACKET},
+ { OUString(UNO_NAME_CHAR_EMPHASIS), RES_CHRATR_EMPHASIS_MARK, cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE, MID_EMPHASIS},
+ PROP_DIFF_FONTHEIGHT
+ { OUString(UNO_NAME_CHAR_ROTATION), RES_CHRATR_ROTATE, cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE, MID_ROTATE },
+ { OUString(UNO_NAME_CHAR_ROTATION_IS_FIT_TO_LINE), RES_CHRATR_ROTATE, cppu::UnoType<bool>::get(), PROPERTY_NONE, MID_FITTOLINE },
+ { OUString(UNO_NAME_CHAR_SCALE_WIDTH), RES_CHRATR_SCALEW, cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE, 0 },
+ { OUString(UNO_NAME_CHAR_RELIEF), RES_CHRATR_RELIEF, cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE, MID_RELIEF },
+ { OUString(UNO_NAME_CHAR_LEFT_BORDER), RES_CHRATR_BOX, cppu::UnoType<css::table::BorderLine>::get(), PROPERTY_NONE, LEFT_BORDER |CONVERT_TWIPS },
+ { OUString(UNO_NAME_CHAR_RIGHT_BORDER), RES_CHRATR_BOX, cppu::UnoType<css::table::BorderLine>::get(), PROPERTY_NONE, RIGHT_BORDER |CONVERT_TWIPS },
+ { OUString(UNO_NAME_CHAR_TOP_BORDER), RES_CHRATR_BOX, cppu::UnoType<css::table::BorderLine>::get(), PROPERTY_NONE, TOP_BORDER |CONVERT_TWIPS },
+ { OUString(UNO_NAME_CHAR_BOTTOM_BORDER), RES_CHRATR_BOX, cppu::UnoType<css::table::BorderLine>::get(), PROPERTY_NONE, BOTTOM_BORDER |CONVERT_TWIPS },
+ { OUString(UNO_NAME_CHAR_BORDER_DISTANCE), RES_CHRATR_BOX, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE, BORDER_DISTANCE |CONVERT_TWIPS },
+ { OUString(UNO_NAME_CHAR_LEFT_BORDER_DISTANCE), RES_CHRATR_BOX, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE, LEFT_BORDER_DISTANCE |CONVERT_TWIPS },
+ { OUString(UNO_NAME_CHAR_RIGHT_BORDER_DISTANCE), RES_CHRATR_BOX, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE, RIGHT_BORDER_DISTANCE |CONVERT_TWIPS },
+ { OUString(UNO_NAME_CHAR_TOP_BORDER_DISTANCE), RES_CHRATR_BOX, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE, TOP_BORDER_DISTANCE |CONVERT_TWIPS },
+ { OUString(UNO_NAME_CHAR_BOTTOM_BORDER_DISTANCE), RES_CHRATR_BOX, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE, BOTTOM_BORDER_DISTANCE|CONVERT_TWIPS },
+ { OUString(UNO_NAME_CHAR_SHADOW_FORMAT), RES_CHRATR_SHADOW, cppu::UnoType<css::table::ShadowFormat>::get(), PROPERTY_NONE, CONVERT_TWIPS},
+ { OUString(), 0, css::uno::Type(), 0, 0 }
+ };
+
+ return aCharStyleMap;
+}
+
+const SfxItemPropertyMapEntry* SwUnoPropertyMapProvider::GetAutoCharStylePropertyMap()
+{
+ // same as PROPERTY_MAP_TEXTPORTION_EXTENSIONS
+ static SfxItemPropertyMapEntry const aAutoCharStyleMap [] =
+ {
+ { OUString(UNO_NAME_CHAR_AUTO_KERNING), RES_CHRATR_AUTOKERN , cppu::UnoType<bool>::get() , PROPERTY_NONE, 0},
+ { OUString(UNO_NAME_CHAR_BACK_TRANSPARENT), RES_CHRATR_BACKGROUND, cppu::UnoType<bool>::get(), PROPERTY_NONE ,MID_GRAPHIC_TRANSPARENT },
+ { OUString(UNO_NAME_CHAR_BACK_COLOR), RES_CHRATR_BACKGROUND, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE ,MID_BACK_COLOR },
+ { OUString(UNO_NAME_CHAR_HIGHLIGHT), RES_CHRATR_HIGHLIGHT, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE, MID_BACK_COLOR },
+ { OUString(UNO_NAME_CHAR_CASE_MAP), RES_CHRATR_CASEMAP, cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE, 0},
+ { OUString(UNO_NAME_CHAR_COLOR), RES_CHRATR_COLOR, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE, 0},
+ { OUString(UNO_NAME_CHAR_TRANSPARENCE), RES_CHRATR_COLOR, cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE, MID_COLOR_ALPHA},
+ { OUString(UNO_NAME_CHAR_STRIKEOUT), RES_CHRATR_CROSSEDOUT, cppu::UnoType<sal_Int16>::get(), PropertyAttribute::MAYBEVOID, MID_CROSS_OUT},
+ { OUString(UNO_NAME_CHAR_CROSSED_OUT), RES_CHRATR_CROSSEDOUT, cppu::UnoType<bool>::get() , PROPERTY_NONE, 0},
+ { OUString(UNO_NAME_CHAR_ESCAPEMENT), RES_CHRATR_ESCAPEMENT, cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE, MID_ESC },
+ { OUString(UNO_NAME_CHAR_ESCAPEMENT_HEIGHT), RES_CHRATR_ESCAPEMENT, cppu::UnoType<sal_Int8>::get() , PROPERTY_NONE, MID_ESC_HEIGHT},
+ { OUString(UNO_NAME_CHAR_FLASH), RES_CHRATR_BLINK , cppu::UnoType<bool>::get() , PROPERTY_NONE, 0},
+ { OUString(UNO_NAME_CHAR_HIDDEN), RES_CHRATR_HIDDEN, cppu::UnoType<bool>::get() , PROPERTY_NONE, 0},
+ STANDARD_FONT_PROPERTIES
+ CJK_FONT_PROPERTIES
+ CTL_FONT_PROPERTIES
+ { OUString(UNO_NAME_CHAR_UNDERLINE), RES_CHRATR_UNDERLINE , cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE, MID_TL_STYLE},
+ { OUString(UNO_NAME_CHAR_UNDERLINE_COLOR), RES_CHRATR_UNDERLINE , cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE, MID_TL_COLOR},
+ { OUString(UNO_NAME_CHAR_UNDERLINE_HAS_COLOR), RES_CHRATR_UNDERLINE , cppu::UnoType<bool>::get(), PROPERTY_NONE, MID_TL_HASCOLOR},
+ { OUString(UNO_NAME_CHAR_OVERLINE), RES_CHRATR_OVERLINE , cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE, MID_TL_STYLE},
+ { OUString(UNO_NAME_CHAR_OVERLINE_COLOR), RES_CHRATR_OVERLINE , cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE, MID_TL_COLOR},
+ { OUString(UNO_NAME_CHAR_OVERLINE_HAS_COLOR), RES_CHRATR_OVERLINE , cppu::UnoType<bool>::get(), PROPERTY_NONE, MID_TL_HASCOLOR},
+ { OUString(UNO_NAME_CHAR_KERNING), RES_CHRATR_KERNING , cppu::UnoType<sal_Int16>::get() , PROPERTY_NONE, CONVERT_TWIPS},
+ { OUString(UNO_NAME_CHAR_NO_HYPHENATION), RES_CHRATR_NOHYPHEN , cppu::UnoType<bool>::get() , PROPERTY_NONE, 0},
+ { OUString(UNO_NAME_CHAR_SHADOWED), RES_CHRATR_SHADOWED , cppu::UnoType<bool>::get() , PROPERTY_NONE, 0},
+ { OUString(UNO_NAME_CHAR_CONTOURED), RES_CHRATR_CONTOUR, cppu::UnoType<bool>::get() , PROPERTY_NONE, 0},
+ { OUString(UNO_NAME_CHAR_WORD_MODE), RES_CHRATR_WORDLINEMODE,cppu::UnoType<bool>::get() , PROPERTY_NONE, 0},
+ { OUString(UNO_NAME_USER_DEFINED_ATTRIBUTES), RES_UNKNOWNATR_CONTAINER, cppu::UnoType<css::container::XNameContainer>::get(), PropertyAttribute::MAYBEVOID, 0 },
+ { OUString(UNO_NAME_TEXT_USER_DEFINED_ATTRIBUTES), RES_TXTATR_UNKNOWN_CONTAINER, cppu::UnoType<css::container::XNameContainer>::get(), PropertyAttribute::MAYBEVOID, 0 },
+ { OUString(UNO_NAME_IS_PHYSICAL), FN_UNO_IS_PHYSICAL, cppu::UnoType<bool>::get(), PropertyAttribute::READONLY, 0},
+ { OUString(UNO_NAME_DISPLAY_NAME), FN_UNO_DISPLAY_NAME, cppu::UnoType<OUString>::get(), PropertyAttribute::READONLY, 0},
+ { OUString(UNO_NAME_CHAR_COMBINE_IS_ON), RES_CHRATR_TWO_LINES, cppu::UnoType<bool>::get(), PROPERTY_NONE, MID_TWOLINES},
+ { OUString(UNO_NAME_CHAR_COMBINE_PREFIX), RES_CHRATR_TWO_LINES, cppu::UnoType<OUString>::get(), PROPERTY_NONE, MID_START_BRACKET},
+ { OUString(UNO_NAME_CHAR_COMBINE_SUFFIX), RES_CHRATR_TWO_LINES, cppu::UnoType<OUString>::get(), PROPERTY_NONE, MID_END_BRACKET},
+ { OUString(UNO_NAME_CHAR_EMPHASIS), RES_CHRATR_EMPHASIS_MARK, cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE, MID_EMPHASIS},
+ { OUString(UNO_NAME_CHAR_ROTATION), RES_CHRATR_ROTATE, cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE, MID_ROTATE },
+ { OUString(UNO_NAME_CHAR_ROTATION_IS_FIT_TO_LINE), RES_CHRATR_ROTATE, cppu::UnoType<bool>::get(), PROPERTY_NONE, MID_FITTOLINE },
+ { OUString(UNO_NAME_CHAR_SCALE_WIDTH), RES_CHRATR_SCALEW, cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE, 0 },
+ { OUString(UNO_NAME_CHAR_RELIEF), RES_CHRATR_RELIEF, cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE, MID_RELIEF },
+ { OUString(UNO_NAME_CHAR_AUTO_STYLE_NAME), RES_TXTATR_AUTOFMT, cppu::UnoType<OUString>::get(), PropertyAttribute::MAYBEVOID, 0},
+ { OUString(UNO_NAME_CHAR_SHADING_VALUE), RES_CHRATR_BACKGROUND, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE, MID_SHADING_VALUE },
+ { OUString(UNO_NAME_CHAR_LEFT_BORDER), RES_CHRATR_BOX, cppu::UnoType<css::table::BorderLine>::get(), PROPERTY_NONE, LEFT_BORDER |CONVERT_TWIPS },
+ { OUString(UNO_NAME_CHAR_RIGHT_BORDER), RES_CHRATR_BOX, cppu::UnoType<css::table::BorderLine>::get(), PROPERTY_NONE, RIGHT_BORDER |CONVERT_TWIPS },
+ { OUString(UNO_NAME_CHAR_TOP_BORDER), RES_CHRATR_BOX, cppu::UnoType<css::table::BorderLine>::get(), PROPERTY_NONE, TOP_BORDER |CONVERT_TWIPS },
+ { OUString(UNO_NAME_CHAR_BOTTOM_BORDER), RES_CHRATR_BOX, cppu::UnoType<css::table::BorderLine>::get(), PROPERTY_NONE, BOTTOM_BORDER |CONVERT_TWIPS },
+ { OUString(UNO_NAME_CHAR_BORDER_DISTANCE), RES_CHRATR_BOX, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE, BORDER_DISTANCE |CONVERT_TWIPS },
+ { OUString(UNO_NAME_CHAR_LEFT_BORDER_DISTANCE), RES_CHRATR_BOX, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE, LEFT_BORDER_DISTANCE |CONVERT_TWIPS },
+ { OUString(UNO_NAME_CHAR_RIGHT_BORDER_DISTANCE), RES_CHRATR_BOX, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE, RIGHT_BORDER_DISTANCE |CONVERT_TWIPS },
+ { OUString(UNO_NAME_CHAR_TOP_BORDER_DISTANCE), RES_CHRATR_BOX, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE, TOP_BORDER_DISTANCE |CONVERT_TWIPS },
+ { OUString(UNO_NAME_CHAR_BOTTOM_BORDER_DISTANCE), RES_CHRATR_BOX, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE, BOTTOM_BORDER_DISTANCE|CONVERT_TWIPS },
+ { OUString(UNO_NAME_CHAR_SHADOW_FORMAT), RES_CHRATR_SHADOW, cppu::UnoType<css::table::ShadowFormat>::get(), PROPERTY_NONE, CONVERT_TWIPS},
+ { OUString(), 0, css::uno::Type(), 0, 0 }
+ };
+
+ return aAutoCharStyleMap;
+}
+
+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
+ { OUString(), 0, css::uno::Type(), 0, 0 }
+ };
+
+ return aParaStyleMap;
+}
+
+const SfxItemPropertyMapEntry* SwUnoPropertyMapProvider::GetConditionalParaStylePropertyMap()
+{
+ static SfxItemPropertyMapEntry const aParaStyleMap [] =
+ {
+ COMMON_PARA_STYLE_PROPERTIES
+ { OUString(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
+
+ { OUString(), 0, css::uno::Type(), 0, 0 }
+ };
+
+ return aParaStyleMap;
+}
+
+const SfxItemPropertyMapEntry* SwUnoPropertyMapProvider::GetFrameStylePropertyMap()
+{
+ static SfxItemPropertyMapEntry const aFrameStyleMap [] =
+ {
+ { OUString(UNO_NAME_ANCHOR_PAGE_NO), RES_ANCHOR, cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE, MID_ANCHOR_PAGENUM },
+ { OUString(UNO_NAME_ANCHOR_TYPE), RES_ANCHOR, cppu::UnoType<css::text::TextContentAnchorType>::get(), PROPERTY_NONE, MID_ANCHOR_ANCHORTYPE},
+ { OUString(UNO_NAME_BACK_COLOR), RES_BACKGROUND, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE ,MID_BACK_COLOR },
+ { OUString(UNO_NAME_BACK_COLOR_R_G_B), RES_BACKGROUND, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE ,MID_BACK_COLOR_R_G_B},
+ { OUString(UNO_NAME_BACK_COLOR_TRANSPARENCY), RES_BACKGROUND, cppu::UnoType<sal_Int8>::get(), PROPERTY_NONE ,MID_BACK_COLOR_TRANSPARENCY},
+ { OUString(UNO_NAME_FRAME_INTEROP_GRAB_BAG), RES_FRMATR_GRABBAG, cppu::UnoType< cppu::UnoSequenceType<css::beans::PropertyValue> >::get(), PROPERTY_NONE, 0},
+ // { OUString(UNO_NAME_CHAIN_NEXT_NAME), RES_CHAIN, cppu::UnoType<OUString>::get(), PROPERTY_NONE ,MID_CHAIN_NEXTNAME},
+ // { OUString(UNO_NAME_CHAIN_PREV_NAME), RES_CHAIN, cppu::UnoType<OUString>::get(), PROPERTY_NONE ,MID_CHAIN_PREVNAME},
+ /*not impl*/ { OUString(UNO_NAME_CLIENT_MAP), RES_URL, cppu::UnoType<bool>::get(), PROPERTY_NONE ,MID_URL_CLIENTMAP },
+ { OUString(UNO_NAME_CONTENT_PROTECTED), RES_PROTECT, cppu::UnoType<bool>::get(), PROPERTY_NONE, MID_PROTECT_CONTENT },
+ { OUString(UNO_NAME_EDIT_IN_READONLY), RES_EDIT_IN_READONLY, cppu::UnoType<bool>::get(), PROPERTY_NONE, 0},
+ { OUString(UNO_NAME_BACK_GRAPHIC_URL), RES_BACKGROUND, cppu::UnoType<OUString>::get(), PROPERTY_NONE ,MID_GRAPHIC_URL },
+ { OUString(UNO_NAME_BACK_GRAPHIC), RES_BACKGROUND, cppu::UnoType<graphic::XGraphic>::get(), PROPERTY_NONE, MID_GRAPHIC },
+ { OUString(UNO_NAME_BACK_GRAPHIC_FILTER), RES_BACKGROUND, cppu::UnoType<OUString>::get(), PROPERTY_NONE ,MID_GRAPHIC_FILTER },
+ { OUString(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
+ { OUString(UNO_NAME_BACK_GRAPHIC_TRANSPARENCY), RES_BACKGROUND, cppu::UnoType<sal_Int8>::get(), PROPERTY_NONE ,MID_GRAPHIC_TRANSPARENCY},
+ { OUString(UNO_NAME_LEFT_MARGIN), RES_LR_SPACE, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE, MID_L_MARGIN|CONVERT_TWIPS},
+ { OUString(UNO_NAME_RIGHT_MARGIN), RES_LR_SPACE, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE, MID_R_MARGIN|CONVERT_TWIPS},
+ { OUString(UNO_NAME_HORI_ORIENT), RES_HORI_ORIENT, cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE ,MID_HORIORIENT_ORIENT },
+ { OUString(UNO_NAME_HORI_ORIENT_POSITION), RES_HORI_ORIENT, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE ,MID_HORIORIENT_POSITION|CONVERT_TWIPS },
+ { OUString(UNO_NAME_HORI_ORIENT_RELATION), RES_HORI_ORIENT, cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE ,MID_HORIORIENT_RELATION },
+ { OUString(UNO_NAME_HYPER_LINK_U_R_L), RES_URL, cppu::UnoType<OUString>::get(), PROPERTY_NONE ,MID_URL_URL},
+ { OUString(UNO_NAME_HYPER_LINK_TARGET), RES_URL, cppu::UnoType<OUString>::get(), PROPERTY_NONE ,MID_URL_TARGET},
+ { OUString(UNO_NAME_HYPER_LINK_NAME), RES_URL, cppu::UnoType<OUString>::get(), PROPERTY_NONE ,MID_URL_HYPERLINKNAME },
+ { OUString(UNO_NAME_OPAQUE), RES_OPAQUE, cppu::UnoType<bool>::get(), PROPERTY_NONE, 0},
+ { OUString(UNO_NAME_PAGE_TOGGLE), RES_HORI_ORIENT, cppu::UnoType<bool>::get(), PROPERTY_NONE ,MID_HORIORIENT_PAGETOGGLE },
+ { OUString(UNO_NAME_POSITION_PROTECTED), RES_PROTECT, cppu::UnoType<bool>::get(), PROPERTY_NONE, MID_PROTECT_POSITION},
+ { OUString(UNO_NAME_PRINT), RES_PRINT, cppu::UnoType<bool>::get(), PROPERTY_NONE, 0},
+ { OUString(UNO_NAME_WIDTH), RES_FRM_SIZE, cppu::UnoType<sal_Int32>::get() , PROPERTY_NONE, MID_FRMSIZE_WIDTH|CONVERT_TWIPS },
+ { OUString(UNO_NAME_HEIGHT), RES_FRM_SIZE, cppu::UnoType<sal_Int32>::get() , PROPERTY_NONE, MID_FRMSIZE_HEIGHT|CONVERT_TWIPS },
+ { OUString(UNO_NAME_RELATIVE_HEIGHT), RES_FRM_SIZE, cppu::UnoType<sal_Int16>::get() , PROPERTY_NONE, MID_FRMSIZE_REL_HEIGHT },
+ { OUString(UNO_NAME_RELATIVE_HEIGHT_RELATION), RES_FRM_SIZE, cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE, MID_FRMSIZE_REL_HEIGHT_RELATION },
+ { OUString(UNO_NAME_RELATIVE_WIDTH), RES_FRM_SIZE, cppu::UnoType<sal_Int16>::get() , PROPERTY_NONE, MID_FRMSIZE_REL_WIDTH },
+ { OUString(UNO_NAME_RELATIVE_WIDTH_RELATION), RES_FRM_SIZE, cppu::UnoType<sal_Int16>::get() , PROPERTY_NONE, MID_FRMSIZE_REL_WIDTH_RELATION },
+ { OUString(UNO_NAME_SIZE_TYPE), RES_FRM_SIZE, cppu::UnoType<sal_Int16>::get() , PROPERTY_NONE, MID_FRMSIZE_SIZE_TYPE },
+ { OUString(UNO_NAME_WIDTH_TYPE), RES_FRM_SIZE, cppu::UnoType<sal_Int16>::get() , PROPERTY_NONE, MID_FRMSIZE_WIDTH_TYPE },
+ { OUString(UNO_NAME_SIZE), RES_FRM_SIZE, cppu::UnoType<css::awt::Size>::get(), PROPERTY_NONE, MID_FRMSIZE_SIZE|CONVERT_TWIPS},
+ { OUString(UNO_NAME_IS_SYNC_WIDTH_TO_HEIGHT), RES_FRM_SIZE, cppu::UnoType<bool>::get() , PROPERTY_NONE, MID_FRMSIZE_IS_SYNC_WIDTH_TO_HEIGHT },
+ { OUString(UNO_NAME_IS_SYNC_HEIGHT_TO_WIDTH), RES_FRM_SIZE, cppu::UnoType<bool>::get() , PROPERTY_NONE, MID_FRMSIZE_IS_SYNC_HEIGHT_TO_WIDTH },
+ // { OUString(UNO_NAME_WIDTH), RES_FRM_SIZE, cppu::UnoType<sal_Int32>::get() , PROPERTY_NONE, MID_FRMSIZE_WIDTH },
+ { OUString(UNO_NAME_SHADOW_FORMAT), RES_SHADOW, cppu::UnoType<css::table::ShadowFormat>::get(), PROPERTY_NONE, CONVERT_TWIPS},
+ { OUString(UNO_NAME_SHADOW_TRANSPARENCE), RES_SHADOW, cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE, MID_SHADOW_TRANSPARENCE},
+ { OUString(UNO_NAME_SERVER_MAP), RES_URL, cppu::UnoType<bool>::get(), PROPERTY_NONE ,MID_URL_SERVERMAP },
+ { OUString(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
+ { OUString(UNO_NAME_SURROUND), RES_SURROUND, cppu::UnoType<css::text::WrapTextMode>::get(), PROPERTY_NONE, MID_SURROUND_SURROUNDTYPE },
+ { OUString(UNO_NAME_TEXT_WRAP), RES_SURROUND, cppu::UnoType<css::text::WrapTextMode>::get(), PROPERTY_NONE, MID_SURROUND_SURROUNDTYPE },
+ { OUString(UNO_NAME_SURROUND_ANCHORONLY), RES_SURROUND, cppu::UnoType<bool>::get(), PROPERTY_NONE, MID_SURROUND_ANCHORONLY },
+ { OUString(UNO_NAME_SURROUND_CONTOUR), RES_SURROUND, cppu::UnoType<bool>::get(), PROPERTY_NONE, MID_SURROUND_CONTOUR },
+ { OUString(UNO_NAME_CONTOUR_OUTSIDE), RES_SURROUND, cppu::UnoType<bool>::get(), PROPERTY_NONE, MID_SURROUND_CONTOUROUTSIDE },
+ { OUString(UNO_NAME_TEXT_COLUMNS), RES_COL, cppu::UnoType<css::text::XTextColumns>::get(), PROPERTY_NONE, MID_COLUMNS},
+ { OUString(UNO_NAME_TOP_MARGIN), RES_UL_SPACE, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE, MID_UP_MARGIN|CONVERT_TWIPS},
+ { OUString(UNO_NAME_BOTTOM_MARGIN), RES_UL_SPACE, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE, MID_LO_MARGIN|CONVERT_TWIPS},
+ { OUString(UNO_NAME_BACK_TRANSPARENT), RES_BACKGROUND, cppu::UnoType<bool>::get(), PROPERTY_NONE ,MID_GRAPHIC_TRANSPARENT },
+ { OUString(UNO_NAME_VERT_ORIENT), RES_VERT_ORIENT, cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE ,MID_VERTORIENT_ORIENT },
+ { OUString(UNO_NAME_VERT_ORIENT_POSITION), RES_VERT_ORIENT, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE ,MID_VERTORIENT_POSITION|CONVERT_TWIPS },
+ { OUString(UNO_NAME_VERT_ORIENT_RELATION), RES_VERT_ORIENT, cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE ,MID_VERTORIENT_RELATION },
+ { OUString(UNO_NAME_LEFT_BORDER), RES_BOX, cppu::UnoType<css::table::BorderLine>::get(), 0, LEFT_BORDER |CONVERT_TWIPS },
+ { OUString(UNO_NAME_RIGHT_BORDER), RES_BOX, cppu::UnoType<css::table::BorderLine>::get(), 0, RIGHT_BORDER |CONVERT_TWIPS },
+ { OUString(UNO_NAME_TOP_BORDER), RES_BOX, cppu::UnoType<css::table::BorderLine>::get(), 0, TOP_BORDER |CONVERT_TWIPS },
+ { OUString(UNO_NAME_BOTTOM_BORDER), RES_BOX, cppu::UnoType<css::table::BorderLine>::get(), 0, BOTTOM_BORDER|CONVERT_TWIPS },
+ { OUString(UNO_NAME_BORDER_DISTANCE), RES_BOX, cppu::UnoType<sal_Int32>::get(), 0, BORDER_DISTANCE|CONVERT_TWIPS },
+ { OUString(UNO_NAME_LEFT_BORDER_DISTANCE), RES_BOX, cppu::UnoType<sal_Int32>::get(), 0, LEFT_BORDER_DISTANCE |CONVERT_TWIPS },
+ { OUString(UNO_NAME_RIGHT_BORDER_DISTANCE), RES_BOX, cppu::UnoType<sal_Int32>::get(), 0, RIGHT_BORDER_DISTANCE |CONVERT_TWIPS },
+ { OUString(UNO_NAME_TOP_BORDER_DISTANCE), RES_BOX, cppu::UnoType<sal_Int32>::get(), 0, TOP_BORDER_DISTANCE |CONVERT_TWIPS },
+ { OUString(UNO_NAME_BOTTOM_BORDER_DISTANCE), RES_BOX, cppu::UnoType<sal_Int32>::get(), 0, BOTTOM_BORDER_DISTANCE|CONVERT_TWIPS },
+ { OUString(UNO_NAME_USER_DEFINED_ATTRIBUTES), RES_UNKNOWNATR_CONTAINER, cppu::UnoType<css::container::XNameContainer>::get(), PropertyAttribute::MAYBEVOID, 0 },
+ { OUString(UNO_NAME_IS_PHYSICAL), FN_UNO_IS_PHYSICAL, cppu::UnoType<bool>::get(), PropertyAttribute::READONLY, 0},
+ { OUString(UNO_NAME_IS_AUTO_UPDATE), FN_UNO_IS_AUTO_UPDATE, cppu::UnoType<bool>::get(), PROPERTY_NONE, 0},
+ { OUString(UNO_NAME_DISPLAY_NAME), FN_UNO_DISPLAY_NAME, cppu::UnoType<OUString>::get(), PropertyAttribute::READONLY, 0},
+ // #i18732#
+ { OUString(UNO_NAME_IS_FOLLOWING_TEXT_FLOW), RES_FOLLOW_TEXT_FLOW, cppu::UnoType<bool>::get(), PROPERTY_NONE, MID_FOLLOW_TEXT_FLOW},
+ // #i28701#
+ { OUString(UNO_NAME_WRAP_INFLUENCE_ON_POSITION), RES_WRAP_INFLUENCE_ON_OBJPOS, cppu::UnoType<sal_Int8>::get(), PROPERTY_NONE, MID_WRAP_INFLUENCE},
+ { OUString(UNO_NAME_ALLOW_OVERLAP), RES_WRAP_INFLUENCE_ON_OBJPOS, cppu::UnoType<bool>::get(), PROPERTY_NONE, MID_ALLOW_OVERLAP},
+ { OUString(UNO_NAME_WRITING_MODE), RES_FRAMEDIR, cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE, 0 },
+ { OUString(UNO_NAME_HIDDEN), FN_UNO_HIDDEN, cppu::UnoType<bool>::get(), PROPERTY_NONE, 0},
+ { OUString(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
+
+ { OUString(), 0, css::uno::Type(), 0, 0 }
+ };
+
+ return aFrameStyleMap;
+}
+
+const SfxItemPropertyMapEntry* SwUnoPropertyMapProvider::GetPageStylePropertyMap()
+{
+ static SfxItemPropertyMapEntry const aPageStyleMap [] =
+ {
+ { OUString(UNO_NAME_BACK_COLOR), RES_BACKGROUND, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE ,MID_BACK_COLOR },
+ { OUString(UNO_NAME_BACK_GRAPHIC_URL), RES_BACKGROUND, cppu::UnoType<OUString>::get(), PROPERTY_NONE ,MID_GRAPHIC_URL },
+ { OUString(UNO_NAME_BACK_GRAPHIC), RES_BACKGROUND, cppu::UnoType<graphic::XGraphic>::get(), PROPERTY_NONE, MID_GRAPHIC },
+ { OUString(UNO_NAME_BACK_GRAPHIC_FILTER), RES_BACKGROUND, cppu::UnoType<OUString>::get(), PROPERTY_NONE ,MID_GRAPHIC_FILTER },
+ { OUString(UNO_NAME_BACK_GRAPHIC_LOCATION), RES_BACKGROUND, cppu::UnoType<css::style::GraphicLocation>::get(), PROPERTY_NONE ,MID_GRAPHIC_POSITION},
+ { OUString(UNO_NAME_LEFT_MARGIN), RES_LR_SPACE, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE, MID_L_MARGIN|CONVERT_TWIPS},
+ { OUString(UNO_NAME_RIGHT_MARGIN), RES_LR_SPACE, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE, MID_R_MARGIN|CONVERT_TWIPS},
+ { OUString(UNO_NAME_BACK_TRANSPARENT), RES_BACKGROUND, cppu::UnoType<bool>::get(), PROPERTY_NONE ,MID_GRAPHIC_TRANSPARENT },
+ { OUString(UNO_NAME_LEFT_BORDER), RES_BOX, cppu::UnoType<css::table::BorderLine>::get(), 0, LEFT_BORDER |CONVERT_TWIPS },
+ { OUString(UNO_NAME_RIGHT_BORDER), RES_BOX, cppu::UnoType<css::table::BorderLine>::get(), 0, RIGHT_BORDER |CONVERT_TWIPS },
+ { OUString(UNO_NAME_TOP_BORDER), RES_BOX, cppu::UnoType<css::table::BorderLine>::get(), 0, TOP_BORDER |CONVERT_TWIPS },
+ { OUString(UNO_NAME_BOTTOM_BORDER), RES_BOX, cppu::UnoType<css::table::BorderLine>::get(), 0, BOTTOM_BORDER|CONVERT_TWIPS },
+ { OUString(UNO_NAME_BORDER_DISTANCE), RES_BOX, cppu::UnoType<sal_Int32>::get(), 0, BORDER_DISTANCE|CONVERT_TWIPS },
+ { OUString(UNO_NAME_LEFT_BORDER_DISTANCE), RES_BOX, cppu::UnoType<sal_Int32>::get(), 0, LEFT_BORDER_DISTANCE |CONVERT_TWIPS },
+ { OUString(UNO_NAME_RIGHT_BORDER_DISTANCE), RES_BOX, cppu::UnoType<sal_Int32>::get(), 0, RIGHT_BORDER_DISTANCE |CONVERT_TWIPS },
+ { OUString(UNO_NAME_TOP_BORDER_DISTANCE), RES_BOX, cppu::UnoType<sal_Int32>::get(), 0, TOP_BORDER_DISTANCE |CONVERT_TWIPS },
+ { OUString(UNO_NAME_BOTTOM_BORDER_DISTANCE), RES_BOX, cppu::UnoType<sal_Int32>::get(), 0, BOTTOM_BORDER_DISTANCE|CONVERT_TWIPS },
+ { OUString(UNO_NAME_SHADOW_FORMAT), RES_SHADOW, cppu::UnoType<css::table::ShadowFormat>::get(), PROPERTY_NONE, CONVERT_TWIPS},
+ { OUString(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
+ { OUString(UNO_NAME_HEADER_BACK_COLOR), RES_BACKGROUND, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE ,MID_BACK_COLOR },
+ { OUString(UNO_NAME_HEADER_GRAPHIC_URL), RES_BACKGROUND, cppu::UnoType<OUString>::get(), PROPERTY_NONE ,MID_GRAPHIC_URL },
+ { OUString(UNO_NAME_HEADER_GRAPHIC), RES_BACKGROUND, cppu::UnoType<graphic::XGraphic>::get(), PROPERTY_NONE, MID_GRAPHIC },
+ { OUString(UNO_NAME_HEADER_GRAPHIC_FILTER), RES_BACKGROUND, cppu::UnoType<OUString>::get(), PROPERTY_NONE ,MID_GRAPHIC_FILTER },
+ { OUString(UNO_NAME_HEADER_GRAPHIC_LOCATION), RES_BACKGROUND, cppu::UnoType<css::style::GraphicLocation>::get(), PROPERTY_NONE ,MID_GRAPHIC_POSITION},
+ { OUString(UNO_NAME_HEADER_LEFT_MARGIN), RES_LR_SPACE, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE, MID_L_MARGIN|CONVERT_TWIPS},
+ { OUString(UNO_NAME_HEADER_RIGHT_MARGIN), RES_LR_SPACE, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE, MID_R_MARGIN|CONVERT_TWIPS},
+ { OUString(UNO_NAME_HEADER_BACK_TRANSPARENT), RES_BACKGROUND, cppu::UnoType<bool>::get(), PROPERTY_NONE ,MID_GRAPHIC_TRANSPARENT },
+ { OUString(UNO_NAME_HEADER_LEFT_BORDER), RES_BOX, cppu::UnoType<css::table::BorderLine>::get(), 0, LEFT_BORDER |CONVERT_TWIPS },
+ { OUString(UNO_NAME_HEADER_RIGHT_BORDER), RES_BOX, cppu::UnoType<css::table::BorderLine>::get(), 0, RIGHT_BORDER |CONVERT_TWIPS },
+ { OUString(UNO_NAME_HEADER_TOP_BORDER), RES_BOX, cppu::UnoType<css::table::BorderLine>::get(), 0, TOP_BORDER |CONVERT_TWIPS },
+ { OUString(UNO_NAME_HEADER_BOTTOM_BORDER), RES_BOX, cppu::UnoType<css::table::BorderLine>::get(), 0, BOTTOM_BORDER|CONVERT_TWIPS },
+ { OUString(UNO_NAME_HEADER_BORDER_DISTANCE), RES_BOX, cppu::UnoType<sal_Int32>::get(), PropertyAttribute::MAYBEVOID, BORDER_DISTANCE|CONVERT_TWIPS },
+ { OUString(UNO_NAME_HEADER_LEFT_BORDER_DISTANCE), RES_BOX, cppu::UnoType<sal_Int32>::get(), 0, LEFT_BORDER_DISTANCE |CONVERT_TWIPS },
+ { OUString(UNO_NAME_HEADER_RIGHT_BORDER_DISTANCE), RES_BOX, cppu::UnoType<sal_Int32>::get(), 0, RIGHT_BORDER_DISTANCE |CONVERT_TWIPS },
+ { OUString(UNO_NAME_HEADER_TOP_BORDER_DISTANCE), RES_BOX, cppu::UnoType<sal_Int32>::get(), 0, TOP_BORDER_DISTANCE |CONVERT_TWIPS },
+ { OUString(UNO_NAME_HEADER_BOTTOM_BORDER_DISTANCE), RES_BOX, cppu::UnoType<sal_Int32>::get(), 0, BOTTOM_BORDER_DISTANCE|CONVERT_TWIPS },
+ { OUString(UNO_NAME_HEADER_SHADOW_FORMAT), RES_SHADOW, cppu::UnoType<css::table::ShadowFormat>::get(), PROPERTY_NONE, CONVERT_TWIPS},
+ { OUString(UNO_NAME_HEADER_BODY_DISTANCE), RES_UL_SPACE, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE ,MID_LO_MARGIN|CONVERT_TWIPS },
+ { OUString(UNO_NAME_HEADER_IS_DYNAMIC_HEIGHT), SID_ATTR_PAGE_DYNAMIC, cppu::UnoType<bool>::get(), PROPERTY_NONE ,0 },
+ { OUString(UNO_NAME_HEADER_IS_SHARED), SID_ATTR_PAGE_SHARED, cppu::UnoType<bool>::get(), PROPERTY_NONE ,0 },
+ { OUString(UNO_NAME_HEADER_HEIGHT), SID_ATTR_PAGE_SIZE, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE ,MID_SIZE_HEIGHT|CONVERT_TWIPS },
+ { OUString(UNO_NAME_HEADER_IS_ON), SID_ATTR_PAGE_ON, cppu::UnoType<bool>::get(), PROPERTY_NONE ,0 },
+ { OUString(UNO_NAME_HEADER_DYNAMIC_SPACING), RES_HEADER_FOOTER_EAT_SPACING, cppu::UnoType<bool>::get(), PropertyAttribute::MAYBEVOID ,0 },
+
+
+ { OUString(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
+ { OUString(UNO_NAME_FOOTER_BACK_COLOR), RES_BACKGROUND, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE ,MID_BACK_COLOR },
+ { OUString(UNO_NAME_FOOTER_GRAPHIC_URL), RES_BACKGROUND, cppu::UnoType<OUString>::get(), PROPERTY_NONE ,MID_GRAPHIC_URL },
+ { OUString(UNO_NAME_FOOTER_GRAPHIC), RES_BACKGROUND, cppu::UnoType<graphic::XGraphic>::get(), PROPERTY_NONE, MID_GRAPHIC },
+ { OUString(UNO_NAME_FOOTER_GRAPHIC_FILTER), RES_BACKGROUND, cppu::UnoType<OUString>::get(), PROPERTY_NONE ,MID_GRAPHIC_FILTER },
+ { OUString(UNO_NAME_FOOTER_GRAPHIC_LOCATION), RES_BACKGROUND, cppu::UnoType<css::style::GraphicLocation>::get(), PROPERTY_NONE ,MID_GRAPHIC_POSITION},
+ { OUString(UNO_NAME_FOOTER_LEFT_MARGIN), RES_LR_SPACE, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE, MID_L_MARGIN|CONVERT_TWIPS},
+ { OUString(UNO_NAME_FOOTER_RIGHT_MARGIN), RES_LR_SPACE, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE, MID_R_MARGIN|CONVERT_TWIPS},
+ { OUString(UNO_NAME_FOOTER_BACK_TRANSPARENT), RES_BACKGROUND, cppu::UnoType<bool>::get(), PROPERTY_NONE ,MID_GRAPHIC_TRANSPARENT },
+ { OUString(UNO_NAME_FOOTER_LEFT_BORDER), RES_BOX, cppu::UnoType<css::table::BorderLine>::get(), 0, LEFT_BORDER |CONVERT_TWIPS },
+ { OUString(UNO_NAME_FOOTER_RIGHT_BORDER), RES_BOX, cppu::UnoType<css::table::BorderLine>::get(), 0, RIGHT_BORDER |CONVERT_TWIPS },
+ { OUString(UNO_NAME_FOOTER_TOP_BORDER), RES_BOX, cppu::UnoType<css::table::BorderLine>::get(), 0, TOP_BORDER |CONVERT_TWIPS },
+ { OUString(UNO_NAME_FOOTER_BOTTOM_BORDER), RES_BOX, cppu::UnoType<css::table::BorderLine>::get(), 0, BOTTOM_BORDER|CONVERT_TWIPS },
+ { OUString(UNO_NAME_FOOTER_BORDER_DISTANCE), RES_BOX, cppu::UnoType<sal_Int32>::get(), PropertyAttribute::MAYBEVOID, BORDER_DISTANCE|CONVERT_TWIPS },
+ { OUString(UNO_NAME_FOOTER_LEFT_BORDER_DISTANCE), RES_BOX, cppu::UnoType<sal_Int32>::get(), 0, LEFT_BORDER_DISTANCE |CONVERT_TWIPS },
+ { OUString(UNO_NAME_FOOTER_RIGHT_BORDER_DISTANCE), RES_BOX, cppu::UnoType<sal_Int32>::get(), 0, RIGHT_BORDER_DISTANCE |CONVERT_TWIPS },
+ { OUString(UNO_NAME_FOOTER_TOP_BORDER_DISTANCE), RES_BOX, cppu::UnoType<sal_Int32>::get(), 0, TOP_BORDER_DISTANCE |CONVERT_TWIPS },
+ { OUString(UNO_NAME_FOOTER_BOTTOM_BORDER_DISTANCE), RES_BOX, cppu::UnoType<sal_Int32>::get(), 0, BOTTOM_BORDER_DISTANCE|CONVERT_TWIPS },
+ { OUString(UNO_NAME_FOOTER_SHADOW_FORMAT), RES_SHADOW, cppu::UnoType<css::table::ShadowFormat>::get(), PROPERTY_NONE, CONVERT_TWIPS},
+ { OUString(UNO_NAME_FOOTER_BODY_DISTANCE), RES_UL_SPACE, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE ,MID_UP_MARGIN|CONVERT_TWIPS },
+ { OUString(UNO_NAME_FOOTER_IS_DYNAMIC_HEIGHT), SID_ATTR_PAGE_DYNAMIC, cppu::UnoType<bool>::get(), PROPERTY_NONE ,0 },
+ { OUString(UNO_NAME_FOOTER_IS_SHARED), SID_ATTR_PAGE_SHARED, cppu::UnoType<bool>::get(), PROPERTY_NONE ,0 },
+ { OUString(UNO_NAME_FOOTER_HEIGHT), SID_ATTR_PAGE_SIZE, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE ,MID_SIZE_HEIGHT|CONVERT_TWIPS },
+ { OUString(UNO_NAME_FOOTER_IS_ON), SID_ATTR_PAGE_ON, cppu::UnoType<bool>::get(), PROPERTY_NONE ,0 },
+ { OUString(UNO_NAME_FOOTER_DYNAMIC_SPACING), RES_HEADER_FOOTER_EAT_SPACING, cppu::UnoType<bool>::get(), PropertyAttribute::MAYBEVOID ,0 },
+
+ { OUString(UNO_NAME_IS_LANDSCAPE), SID_ATTR_PAGE, cppu::UnoType<bool>::get(), PROPERTY_NONE ,MID_PAGE_ORIENTATION },
+ { OUString(UNO_NAME_NUMBERING_TYPE), SID_ATTR_PAGE, cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE , MID_PAGE_NUMTYPE },
+ { OUString(UNO_NAME_PAGE_STYLE_LAYOUT), SID_ATTR_PAGE, cppu::UnoType<css::style::PageStyleLayout>::get(), PROPERTY_NONE ,MID_PAGE_LAYOUT },
+ { OUString(UNO_NAME_PRINTER_PAPER_TRAY), RES_PAPER_BIN, cppu::UnoType<OUString>::get(), PROPERTY_NONE , 0 },
+// { OUString(UNO_NAME_REGISTER_MODE_ACTIVE), SID_SWREGISTER_MODE, cppu::UnoType<bool>::get(), PROPERTY_NONE , 0 },
+ { OUString(UNO_NAME_REGISTER_PARAGRAPH_STYLE), SID_SWREGISTER_COLLECTION, cppu::UnoType<OUString>::get(), PROPERTY_NONE , 0 },
+ { OUString(UNO_NAME_SIZE), SID_ATTR_PAGE_SIZE, cppu::UnoType<css::awt::Size>::get(), PROPERTY_NONE, MID_SIZE_SIZE|CONVERT_TWIPS},
+ { OUString(UNO_NAME_WIDTH), SID_ATTR_PAGE_SIZE, cppu::UnoType<sal_Int32>::get() , PROPERTY_NONE, MID_SIZE_WIDTH|CONVERT_TWIPS},
+ { OUString(UNO_NAME_HEIGHT), SID_ATTR_PAGE_SIZE, cppu::UnoType<sal_Int32>::get() , PROPERTY_NONE, MID_SIZE_HEIGHT|CONVERT_TWIPS },
+ { OUString(UNO_NAME_TEXT_VERT_ADJUST), RES_TEXT_VERT_ADJUST, cppu::UnoType<css::drawing::TextVerticalAdjust>::get(), PROPERTY_NONE, 0 },
+ { OUString(UNO_NAME_TEXT_COLUMNS), RES_COL, cppu::UnoType<css::text::XTextColumns>::get(), PROPERTY_NONE, MID_COLUMNS},
+ { OUString(UNO_NAME_TOP_MARGIN), RES_UL_SPACE, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE, MID_UP_MARGIN|CONVERT_TWIPS},
+ { OUString(UNO_NAME_BOTTOM_MARGIN), RES_UL_SPACE, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE, MID_LO_MARGIN|CONVERT_TWIPS},
+ { OUString(UNO_NAME_HEADER_TEXT), FN_UNO_HEADER, cppu::UnoType<css::text::XText>::get(), PropertyAttribute::MAYBEVOID|PropertyAttribute::READONLY, 0},
+ { OUString(UNO_NAME_HEADER_TEXT_LEFT), FN_UNO_HEADER_LEFT, cppu::UnoType<css::text::XText>::get(), PropertyAttribute::MAYBEVOID|PropertyAttribute::READONLY, 0},
+ { OUString(UNO_NAME_HEADER_TEXT_RIGHT), FN_UNO_HEADER_RIGHT, cppu::UnoType<css::text::XText>::get(), PropertyAttribute::MAYBEVOID|PropertyAttribute::READONLY, 0},
+ { OUString(UNO_NAME_HEADER_TEXT_FIRST), FN_UNO_HEADER_FIRST, cppu::UnoType<css::text::XText>::get(), PropertyAttribute::MAYBEVOID|PropertyAttribute::READONLY, 0},
+ { OUString(UNO_NAME_FOOTER_TEXT), FN_UNO_FOOTER, cppu::UnoType<css::text::XText>::get(), PropertyAttribute::MAYBEVOID|PropertyAttribute::READONLY, 0},
+ { OUString(UNO_NAME_FOOTER_TEXT_LEFT), FN_UNO_FOOTER_LEFT, cppu::UnoType<css::text::XText>::get(), PropertyAttribute::MAYBEVOID|PropertyAttribute::READONLY, 0},
+ { OUString(UNO_NAME_FOOTER_TEXT_RIGHT), FN_UNO_FOOTER_RIGHT, cppu::UnoType<css::text::XText>::get(), PropertyAttribute::MAYBEVOID|PropertyAttribute::READONLY, 0},
+ { OUString(UNO_NAME_FOOTER_TEXT_FIRST), FN_UNO_FOOTER_FIRST, cppu::UnoType<css::text::XText>::get(), PropertyAttribute::MAYBEVOID|PropertyAttribute::READONLY, 0},
+ { OUString(UNO_NAME_FOLLOW_STYLE), FN_UNO_FOLLOW_STYLE, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ { OUString(UNO_NAME_USER_DEFINED_ATTRIBUTES), RES_UNKNOWNATR_CONTAINER, cppu::UnoType<css::container::XNameContainer>::get(), PropertyAttribute::MAYBEVOID, 0 },
+ { OUString(UNO_NAME_IS_PHYSICAL), FN_UNO_IS_PHYSICAL, cppu::UnoType<bool>::get(), PropertyAttribute::READONLY, 0},
+ { OUString(UNO_NAME_DISPLAY_NAME), FN_UNO_DISPLAY_NAME, cppu::UnoType<OUString>::get(), PropertyAttribute::READONLY, 0},
+ { OUString(UNO_NAME_FOOTNOTE_HEIGHT), FN_PARAM_FTN_INFO, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE , MID_FTN_HEIGHT|CONVERT_TWIPS},
+ { OUString(UNO_NAME_FOOTNOTE_LINE_WEIGHT), FN_PARAM_FTN_INFO, cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE , MID_LINE_WEIGHT|CONVERT_TWIPS},
+ { OUString(UNO_NAME_FOOTNOTE_LINE_COLOR), FN_PARAM_FTN_INFO, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE , MID_LINE_COLOR},
+ { OUString(UNO_NAME_FOOTNOTE_LINE_STYLE), FN_PARAM_FTN_INFO, cppu::UnoType<sal_Int8>::get(), PROPERTY_NONE , MID_FTN_LINE_STYLE},
+ { OUString(UNO_NAME_FOOTNOTE_LINE_RELATIVE_WIDTH), FN_PARAM_FTN_INFO, cppu::UnoType<sal_Int8>::get(), PROPERTY_NONE , MID_LINE_RELWIDTH },
+ { OUString(UNO_NAME_FOOTNOTE_LINE_ADJUST), FN_PARAM_FTN_INFO, cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE , MID_LINE_ADJUST },
+ { OUString(UNO_NAME_FOOTNOTE_LINE_TEXT_DISTANCE), FN_PARAM_FTN_INFO, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE , MID_LINE_TEXT_DIST |CONVERT_TWIPS },
+ { OUString(UNO_NAME_FOOTNOTE_LINE_DISTANCE), FN_PARAM_FTN_INFO, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE , MID_LINE_FOOTNOTE_DIST|CONVERT_TWIPS},
+ { OUString(UNO_NAME_WRITING_MODE), RES_FRAMEDIR, cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE, 0 },
+ // writing grid
+ { OUString(UNO_NAME_GRID_COLOR), RES_TEXTGRID, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE, MID_GRID_COLOR},
+ { OUString(UNO_NAME_GRID_LINES), RES_TEXTGRID, cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE, MID_GRID_LINES},
+ { OUString(UNO_NAME_GRID_BASE_HEIGHT), RES_TEXTGRID, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE, MID_GRID_BASEHEIGHT|CONVERT_TWIPS},
+ { OUString(UNO_NAME_GRID_RUBY_HEIGHT), RES_TEXTGRID, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE, MID_GRID_RUBYHEIGHT|CONVERT_TWIPS},
+ { OUString(UNO_NAME_GRID_MODE), RES_TEXTGRID, cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE, MID_GRID_TYPE},
+ { OUString(UNO_NAME_GRID_RUBY_BELOW), RES_TEXTGRID, cppu::UnoType<bool>::get(), PROPERTY_NONE, MID_GRID_RUBY_BELOW},
+ { OUString(UNO_NAME_GRID_PRINT), RES_TEXTGRID, cppu::UnoType<bool>::get(), PROPERTY_NONE, MID_GRID_PRINT},
+ { OUString(UNO_NAME_GRID_DISPLAY), RES_TEXTGRID, cppu::UnoType<bool>::get(), PROPERTY_NONE, MID_GRID_DISPLAY},
+ { OUString(UNO_NAME_GRID_BASE_WIDTH), RES_TEXTGRID, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE, MID_GRID_BASEWIDTH|CONVERT_TWIPS},
+ { OUString(UNO_NAME_GRID_SNAP_TO_CHARS), RES_TEXTGRID, cppu::UnoType<bool>::get(), PROPERTY_NONE, MID_GRID_SNAPTOCHARS},
+ { OUString(UNO_NAME_GRID_STANDARD_PAGE_MODE), RES_TEXTGRID, cppu::UnoType<bool>::get(), PROPERTY_NONE, MID_GRID_STANDARD_MODE},
+ { OUString(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
+
+ // 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'
+ { OUString(UNO_NAME_HEADER_FILLBMP_LOGICAL_SIZE), XATTR_FILLBMP_SIZELOG, cppu::UnoType<bool>::get() , 0, 0},
+ { OUString(UNO_NAME_HEADER_FILLBMP_OFFSET_X), XATTR_FILLBMP_TILEOFFSETX, cppu::UnoType<sal_Int32>::get() , 0, 0},
+ { OUString(UNO_NAME_HEADER_FILLBMP_OFFSET_Y), XATTR_FILLBMP_TILEOFFSETY, cppu::UnoType<sal_Int32>::get() , 0, 0},
+ { OUString(UNO_NAME_HEADER_FILLBMP_POSITION_OFFSET_X), XATTR_FILLBMP_POSOFFSETX, cppu::UnoType<sal_Int32>::get() , 0, 0},
+ { OUString(UNO_NAME_HEADER_FILLBMP_POSITION_OFFSET_Y), XATTR_FILLBMP_POSOFFSETY, cppu::UnoType<sal_Int32>::get() , 0, 0},
+ { OUString(UNO_NAME_HEADER_FILLBMP_RECTANGLE_POINT), XATTR_FILLBMP_POS, cppu::UnoType<css::drawing::RectanglePoint>::get() , 0, 0},
+ { OUString(UNO_NAME_HEADER_FILLBMP_SIZE_X), XATTR_FILLBMP_SIZEX, cppu::UnoType<sal_Int32>::get() , 0, 0, PropertyMoreFlags::METRIC_ITEM},
+ { OUString(UNO_NAME_HEADER_FILLBMP_SIZE_Y), XATTR_FILLBMP_SIZEY, cppu::UnoType<sal_Int32>::get() , 0, 0, PropertyMoreFlags::METRIC_ITEM},
+ { OUString(UNO_NAME_HEADER_FILLBMP_STRETCH), XATTR_FILLBMP_STRETCH, cppu::UnoType<bool>::get() , 0, 0},
+ { OUString(UNO_NAME_HEADER_FILLBMP_TILE), XATTR_FILLBMP_TILE, cppu::UnoType<bool>::get() , 0, 0},
+ { OUString(UNO_NAME_HEADER_FILLBMP_MODE), OWN_ATTR_FILLBMP_MODE, cppu::UnoType<css::drawing::BitmapMode>::get(), 0, 0},
+ { OUString(UNO_NAME_HEADER_FILLCOLOR), XATTR_FILLCOLOR, cppu::UnoType<sal_Int32>::get(), 0, 0},
+ { OUString(UNO_NAME_HEADER_FILLBACKGROUND), XATTR_FILLBACKGROUND, cppu::UnoType<bool>::get(), 0, 0},
+ { OUString(UNO_NAME_HEADER_FILLBITMAP), XATTR_FILLBITMAP, cppu::UnoType<css::awt::XBitmap>::get(), 0, MID_BITMAP},
+ { OUString(UNO_NAME_HEADER_FILLBITMAPNAME), XATTR_FILLBITMAP, cppu::UnoType<OUString>::get(), 0, MID_NAME },
+ { OUString(UNO_NAME_HEADER_FILLGRADIENTSTEPCOUNT), XATTR_GRADIENTSTEPCOUNT, cppu::UnoType<sal_Int16>::get(), 0, 0},
+ { OUString(UNO_NAME_HEADER_FILLGRADIENT), XATTR_FILLGRADIENT, cppu::UnoType<css::awt::Gradient>::get(), 0, MID_FILLGRADIENT},
+ { OUString(UNO_NAME_HEADER_FILLGRADIENTNAME), XATTR_FILLGRADIENT, cppu::UnoType<OUString>::get(), 0, MID_NAME },
+ { OUString(UNO_NAME_HEADER_FILLHATCH), XATTR_FILLHATCH, cppu::UnoType<css::drawing::Hatch>::get(), 0, MID_FILLHATCH},
+ { OUString(UNO_NAME_HEADER_FILLHATCHNAME), XATTR_FILLHATCH, cppu::UnoType<OUString>::get(), 0, MID_NAME },
+ { OUString(UNO_NAME_HEADER_FILLSTYLE), XATTR_FILLSTYLE, cppu::UnoType<css::drawing::FillStyle>::get(), 0, 0},
+ { OUString(UNO_NAME_HEADER_FILL_TRANSPARENCE), XATTR_FILLTRANSPARENCE, cppu::UnoType<sal_Int16>::get(), 0, 0},
+ { OUString(UNO_NAME_HEADER_FILLTRANSPARENCEGRADIENT), XATTR_FILLFLOATTRANSPARENCE, cppu::UnoType<css::awt::Gradient>::get(), 0, MID_FILLGRADIENT},
+ { OUString(UNO_NAME_HEADER_FILLTRANSPARENCEGRADIENTNAME), XATTR_FILLFLOATTRANSPARENCE, cppu::UnoType<OUString>::get(), 0, MID_NAME },
+ { OUString(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)
+ { OUString(UNO_NAME_FOOTER_FILLBMP_LOGICAL_SIZE), XATTR_FILLBMP_SIZELOG, cppu::UnoType<bool>::get() , 0, 0},
+ { OUString(UNO_NAME_FOOTER_FILLBMP_OFFSET_X), XATTR_FILLBMP_TILEOFFSETX, cppu::UnoType<sal_Int32>::get() , 0, 0},
+ { OUString(UNO_NAME_FOOTER_FILLBMP_OFFSET_Y), XATTR_FILLBMP_TILEOFFSETY, cppu::UnoType<sal_Int32>::get() , 0, 0},
+ { OUString(UNO_NAME_FOOTER_FILLBMP_POSITION_OFFSET_X), XATTR_FILLBMP_POSOFFSETX, cppu::UnoType<sal_Int32>::get() , 0, 0},
+ { OUString(UNO_NAME_FOOTER_FILLBMP_POSITION_OFFSET_Y), XATTR_FILLBMP_POSOFFSETY, cppu::UnoType<sal_Int32>::get() , 0, 0},
+ { OUString(UNO_NAME_FOOTER_FILLBMP_RECTANGLE_POINT), XATTR_FILLBMP_POS, cppu::UnoType<css::drawing::RectanglePoint>::get() , 0, 0},
+ { OUString(UNO_NAME_FOOTER_FILLBMP_SIZE_X), XATTR_FILLBMP_SIZEX, cppu::UnoType<sal_Int32>::get() , 0, 0, PropertyMoreFlags::METRIC_ITEM},
+ { OUString(UNO_NAME_FOOTER_FILLBMP_SIZE_Y), XATTR_FILLBMP_SIZEY, cppu::UnoType<sal_Int32>::get() , 0, 0, PropertyMoreFlags::METRIC_ITEM},
+ { OUString(UNO_NAME_FOOTER_FILLBMP_STRETCH), XATTR_FILLBMP_STRETCH, cppu::UnoType<bool>::get() , 0, 0},
+ { OUString(UNO_NAME_FOOTER_FILLBMP_TILE), XATTR_FILLBMP_TILE, cppu::UnoType<bool>::get() , 0, 0},
+ { OUString(UNO_NAME_FOOTER_FILLBMP_MODE), OWN_ATTR_FILLBMP_MODE, cppu::UnoType<css::drawing::BitmapMode>::get(), 0, 0},
+ { OUString(UNO_NAME_FOOTER_FILLCOLOR), XATTR_FILLCOLOR, cppu::UnoType<sal_Int32>::get(), 0, 0},
+ { OUString(UNO_NAME_FOOTER_FILLBACKGROUND), XATTR_FILLBACKGROUND, cppu::UnoType<bool>::get(), 0, 0},
+ { OUString(UNO_NAME_FOOTER_FILLBITMAP), XATTR_FILLBITMAP, cppu::UnoType<css::awt::XBitmap>::get(), 0, MID_BITMAP},
+ { OUString(UNO_NAME_FOOTER_FILLBITMAPNAME), XATTR_FILLBITMAP, cppu::UnoType<OUString>::get(), 0, MID_NAME },
+ { OUString(UNO_NAME_FOOTER_FILLGRADIENTSTEPCOUNT), XATTR_GRADIENTSTEPCOUNT, cppu::UnoType<sal_Int16>::get(), 0, 0},
+ { OUString(UNO_NAME_FOOTER_FILLGRADIENT), XATTR_FILLGRADIENT, cppu::UnoType<css::awt::Gradient>::get(), 0, MID_FILLGRADIENT},
+ { OUString(UNO_NAME_FOOTER_FILLGRADIENTNAME), XATTR_FILLGRADIENT, cppu::UnoType<OUString>::get(), 0, MID_NAME },
+ { OUString(UNO_NAME_FOOTER_FILLHATCH), XATTR_FILLHATCH, cppu::UnoType<css::drawing::Hatch>::get(), 0, MID_FILLHATCH},
+ { OUString(UNO_NAME_FOOTER_FILLHATCHNAME), XATTR_FILLHATCH, cppu::UnoType<OUString>::get(), 0, MID_NAME },
+ { OUString(UNO_NAME_FOOTER_FILLSTYLE), XATTR_FILLSTYLE, cppu::UnoType<css::drawing::FillStyle>::get(), 0, 0},
+ { OUString(UNO_NAME_FOOTER_FILL_TRANSPARENCE), XATTR_FILLTRANSPARENCE, cppu::UnoType<sal_Int16>::get(), 0, 0},
+ { OUString(UNO_NAME_FOOTER_FILLTRANSPARENCEGRADIENT), XATTR_FILLFLOATTRANSPARENCE, cppu::UnoType<css::awt::Gradient>::get(), 0, MID_FILLGRADIENT},
+ { OUString(UNO_NAME_FOOTER_FILLTRANSPARENCEGRADIENTNAME), XATTR_FILLFLOATTRANSPARENCE, cppu::UnoType<OUString>::get(), 0, MID_NAME },
+ { OUString(UNO_NAME_FOOTER_FILLCOLOR_2), XATTR_SECONDARYFILLCOLOR, cppu::UnoType<sal_Int32>::get(), 0, 0},
+
+ { OUString(), 0, css::uno::Type(), 0, 0 }
+ };
+
+ return aPageStyleMap;
+}
+
+const SfxItemPropertyMapEntry* SwUnoPropertyMapProvider::GetTablePropertyMap()
+{
+ static SfxItemPropertyMapEntry const aTablePropertyMap_Impl[] =
+ {
+ { OUString(UNO_NAME_BACK_COLOR), RES_BACKGROUND, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE,MID_BACK_COLOR },
+ { OUString(UNO_NAME_BREAK_TYPE), RES_BREAK, cppu::UnoType<css::style::BreakType>::get(), PROPERTY_NONE, 0},
+ { OUString(UNO_NAME_BACK_GRAPHIC_URL), RES_BACKGROUND, cppu::UnoType<OUString>::get(), PROPERTY_NONE ,MID_GRAPHIC_URL },
+ { OUString(UNO_NAME_BACK_GRAPHIC), RES_BACKGROUND, cppu::UnoType<graphic::XGraphic>::get(), PROPERTY_NONE, MID_GRAPHIC },
+ { OUString(UNO_NAME_BACK_GRAPHIC_FILTER), RES_BACKGROUND, cppu::UnoType<OUString>::get(), PROPERTY_NONE ,MID_GRAPHIC_FILTER },
+ { OUString(UNO_NAME_BACK_GRAPHIC_LOCATION), RES_BACKGROUND, cppu::UnoType<css::style::GraphicLocation>::get(), PROPERTY_NONE ,MID_GRAPHIC_POSITION},
+ { OUString(UNO_NAME_LEFT_MARGIN), RES_LR_SPACE, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE, MID_L_MARGIN|CONVERT_TWIPS},
+ { OUString(UNO_NAME_RIGHT_MARGIN), RES_LR_SPACE, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE, MID_R_MARGIN|CONVERT_TWIPS},
+ { OUString(UNO_NAME_HORI_ORIENT), RES_HORI_ORIENT, cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE ,MID_HORIORIENT_ORIENT },
+ { OUString(UNO_NAME_KEEP_TOGETHER), RES_KEEP, cppu::UnoType<bool>::get() , PROPERTY_NONE, 0},
+ { OUString(UNO_NAME_SPLIT), RES_LAYOUT_SPLIT, cppu::UnoType<bool>::get() , PROPERTY_NONE, 0},
+ { OUString(UNO_NAME_PAGE_NUMBER_OFFSET), RES_PAGEDESC, cppu::UnoType<sal_Int16>::get(), PropertyAttribute::MAYBEVOID, MID_PAGEDESC_PAGENUMOFFSET},
+ { OUString(UNO_NAME_PAGE_DESC_NAME), RES_PAGEDESC, cppu::UnoType<OUString>::get(), PropertyAttribute::MAYBEVOID, 0xbf},
+ { OUString(UNO_NAME_RELATIVE_WIDTH), FN_TABLE_RELATIVE_WIDTH,cppu::UnoType<sal_Int16>::get() , PROPERTY_NONE, 0xbf },
+ { OUString(UNO_NAME_REPEAT_HEADLINE), FN_TABLE_HEADLINE_REPEAT,cppu::UnoType<bool>::get(), PROPERTY_NONE, 0xbf},
+ { OUString(UNO_NAME_HEADER_ROW_COUNT), FN_TABLE_HEADLINE_COUNT, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE, 0xbf},
+ { OUString(UNO_NAME_SHADOW_FORMAT), RES_SHADOW, cppu::UnoType<css::table::ShadowFormat>::get(), PROPERTY_NONE, 0},
+ { OUString(UNO_NAME_SHADOW_TRANSPARENCE), RES_SHADOW, cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE, MID_SHADOW_TRANSPARENCE},
+ { OUString(UNO_NAME_TOP_MARGIN), RES_UL_SPACE, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE, MID_UP_MARGIN|CONVERT_TWIPS},
+ { OUString(UNO_NAME_BOTTOM_MARGIN), RES_UL_SPACE, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE, MID_LO_MARGIN|CONVERT_TWIPS},
+ { OUString(UNO_NAME_BACK_TRANSPARENT), RES_BACKGROUND, cppu::UnoType<bool>::get(), PROPERTY_NONE ,MID_GRAPHIC_TRANSPARENT },
+ { OUString(UNO_NAME_WIDTH), FN_TABLE_WIDTH, cppu::UnoType<sal_Int32>::get() , PROPERTY_NONE, 0xbf},
+ { OUString(UNO_NAME_IS_WIDTH_RELATIVE), FN_TABLE_IS_RELATIVE_WIDTH, cppu::UnoType<bool>::get() , PROPERTY_NONE, 0xbf},
+ { OUString(UNO_NAME_CHART_ROW_AS_LABEL), FN_UNO_RANGE_ROW_LABEL, cppu::UnoType<bool>::get(), PROPERTY_NONE, 0},
+ { OUString(UNO_NAME_CHART_COLUMN_AS_LABEL), FN_UNO_RANGE_COL_LABEL, cppu::UnoType<bool>::get() , PROPERTY_NONE, 0},
+ { OUString(UNO_NAME_TABLE_BORDER), FN_UNO_TABLE_BORDER, cppu::UnoType<css::table::TableBorder>::get(), PropertyAttribute::MAYBEVOID, CONVERT_TWIPS },
+ { OUString(UNO_NAME_TABLE_BORDER2), FN_UNO_TABLE_BORDER2, cppu::UnoType<css::table::TableBorder2>::get(), PropertyAttribute::MAYBEVOID, CONVERT_TWIPS },
+ { OUString(UNO_NAME_TABLE_BORDER_DISTANCES), FN_UNO_TABLE_BORDER_DISTANCES, cppu::UnoType<css::table::TableBorderDistances>::get(), PropertyAttribute::MAYBEVOID, CONVERT_TWIPS },
+ { OUString(UNO_NAME_TABLE_COLUMN_SEPARATORS), FN_UNO_TABLE_COLUMN_SEPARATORS, cppu::UnoType< cppu::UnoSequenceType<css::text::TableColumnSeparator> >::get(), PropertyAttribute::MAYBEVOID, 0 },
+ { OUString(UNO_NAME_TABLE_COLUMN_RELATIVE_SUM), FN_UNO_TABLE_COLUMN_RELATIVE_SUM, cppu::UnoType<sal_Int16>::get(), PropertyAttribute::READONLY, 0 },
+ COMMON_TEXT_CONTENT_PROPERTIES
+ { OUString(UNO_LINK_DISPLAY_NAME), FN_PARAM_LINK_DISPLAY_NAME, cppu::UnoType<OUString>::get(), PropertyAttribute::READONLY, 0xbf},
+ { OUString(UNO_NAME_USER_DEFINED_ATTRIBUTES), RES_UNKNOWNATR_CONTAINER, cppu::UnoType<css::container::XNameContainer>::get(), PropertyAttribute::MAYBEVOID, 0 },
+ { OUString(UNO_NAME_TEXT_SECTION), FN_UNO_TEXT_SECTION, cppu::UnoType<css::text::XTextSection>::get(), PropertyAttribute::MAYBEVOID|PropertyAttribute::READONLY ,0 },
+ { OUString(UNO_NAME_WRITING_MODE), RES_FRAMEDIR, cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE, 0 },
+ { OUString(UNO_NAME_TABLE_NAME), FN_UNO_TABLE_NAME, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0 },
+ { OUString(UNO_NAME_PAGE_STYLE_NAME), RES_PAGEDESC, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ { OUString(UNO_NAME_TABLE_TEMPLATE_NAME), FN_UNO_TABLE_TEMPLATE_NAME, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0 },
+ // #i29550#
+ { OUString(UNO_NAME_COLLAPSING_BORDERS), RES_COLLAPSING_BORDERS, cppu::UnoType<bool>::get(), PROPERTY_NONE, 0},
+ REDLINE_NODE_PROPERTIES
+ { OUString(UNO_NAME_TABLE_INTEROP_GRAB_BAG), RES_FRMATR_GRABBAG, cppu::UnoType< cppu::UnoSequenceType<css::beans::PropertyValue> >::get(), PROPERTY_NONE, 0 },
+ { OUString(), 0, css::uno::Type(), 0, 0 }
+ };
+
+ return aTablePropertyMap_Impl;
+}
+
+const SfxItemPropertyMapEntry* SwUnoPropertyMapProvider::GetRangePropertyMap()
+{
+ static SfxItemPropertyMapEntry const aRangePropertyMap_Impl[] =
+ {
+ COMMON_CRSR_PARA_PROPERTIES_WITHOUT_FN_01
+ TABSTOPS_MAP_ENTRY
+ { OUString(UNO_NAME_BACK_COLOR), FN_UNO_TABLE_CELL_BACKGROUND, cppu::UnoType<sal_Int32>::get(), PropertyAttribute::MAYBEVOID, MID_BACK_COLOR },
+ { OUString(UNO_NAME_BACK_GRAPHIC_URL), RES_BACKGROUND, cppu::UnoType<OUString>::get(), PropertyAttribute::MAYBEVOID ,MID_GRAPHIC_URL },
+ { OUString(UNO_NAME_BACK_GRAPHIC), RES_BACKGROUND, cppu::UnoType<graphic::XGraphic>::get(), PROPERTY_NONE, MID_GRAPHIC },
+ { OUString(UNO_NAME_BACK_GRAPHIC_FILTER), RES_BACKGROUND, cppu::UnoType<OUString>::get(), PropertyAttribute::MAYBEVOID ,MID_GRAPHIC_FILTER },
+ { OUString(UNO_NAME_BACK_GRAPHIC_LOCATION), FN_UNO_TABLE_CELL_BACKGROUND, cppu::UnoType<css::style::GraphicLocation>::get(), PropertyAttribute::MAYBEVOID, MID_GRAPHIC_POSITION},
+ { OUString(UNO_NAME_BACK_TRANSPARENT), FN_UNO_TABLE_CELL_BACKGROUND, cppu::UnoType<bool>::get(), PropertyAttribute::MAYBEVOID, MID_GRAPHIC_TRANSPARENT },
+ { OUString(UNO_NAME_NUMBER_FORMAT), RES_BOXATR_FORMAT, cppu::UnoType<sal_Int32>::get(), PropertyAttribute::MAYBEVOID ,0 },
+ { OUString(UNO_NAME_VERT_ORIENT), RES_VERT_ORIENT, cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE ,MID_VERTORIENT_ORIENT },
+ { OUString(UNO_NAME_CHART_ROW_AS_LABEL), FN_UNO_RANGE_ROW_LABEL, cppu::UnoType<bool>::get(), PropertyAttribute::MAYBEVOID, 0},
+ { OUString(UNO_NAME_CHART_COLUMN_AS_LABEL), FN_UNO_RANGE_COL_LABEL, cppu::UnoType<bool>::get() , PropertyAttribute::MAYBEVOID, 0},
+ { OUString(), 0, css::uno::Type(), 0, 0 }
+ };
+
+ return aRangePropertyMap_Impl;
+}
+
+const SfxItemPropertyMapEntry* SwUnoPropertyMapProvider::GetSectionPropertyMap()
+{
+ static SfxItemPropertyMapEntry const aSectionPropertyMap_Impl[] =
+ {
+ { OUString(UNO_NAME_CONDITION), WID_SECT_CONDITION, cppu::UnoType<OUString>::get() , PROPERTY_NONE, 0},
+ { OUString(UNO_NAME_DDE_COMMAND_FILE), WID_SECT_DDE_TYPE, cppu::UnoType<OUString>::get() , PROPERTY_NONE, 0},
+ { OUString(UNO_NAME_DDE_COMMAND_TYPE), WID_SECT_DDE_FILE, cppu::UnoType<OUString>::get() , PROPERTY_NONE, 0},
+ { OUString(UNO_NAME_DDE_COMMAND_ELEMENT), WID_SECT_DDE_ELEMENT, cppu::UnoType<OUString>::get() , PROPERTY_NONE, 0},
+ { OUString(UNO_NAME_IS_AUTOMATIC_UPDATE), WID_SECT_DDE_AUTOUPDATE, cppu::UnoType<bool>::get(), PROPERTY_NONE, 0},
+ { OUString(UNO_NAME_FILE_LINK), WID_SECT_LINK , cppu::UnoType<css::text::SectionFileLink>::get(), PROPERTY_NONE, 0},
+ { OUString(UNO_NAME_IS_VISIBLE), WID_SECT_VISIBLE , cppu::UnoType<bool>::get(), PROPERTY_NONE, 0},
+ { OUString(UNO_NAME_IS_PROTECTED), WID_SECT_PROTECTED, cppu::UnoType<bool>::get(), PROPERTY_NONE, 0},
+ { OUString(UNO_NAME_EDIT_IN_READONLY), WID_SECT_EDIT_IN_READONLY, cppu::UnoType<bool>::get(), PROPERTY_NONE, 0},
+ { OUString(UNO_NAME_LINK_REGION), WID_SECT_REGION , cppu::UnoType<OUString>::get() , PROPERTY_NONE, 0},
+ { OUString(UNO_NAME_TEXT_COLUMNS), RES_COL, cppu::UnoType<css::text::XTextColumns>::get(), PROPERTY_NONE, MID_COLUMNS},
+ { OUString(UNO_NAME_BACK_GRAPHIC_URL), RES_BACKGROUND, cppu::UnoType<OUString>::get(), PROPERTY_NONE ,MID_GRAPHIC_URL },
+ { OUString(UNO_NAME_BACK_GRAPHIC), RES_BACKGROUND, cppu::UnoType<graphic::XGraphic>::get(), PROPERTY_NONE, MID_GRAPHIC },
+ { OUString(UNO_NAME_BACK_GRAPHIC_FILTER), RES_BACKGROUND, cppu::UnoType<OUString>::get(), PROPERTY_NONE ,MID_GRAPHIC_FILTER },
+ { OUString(UNO_NAME_BACK_GRAPHIC_LOCATION), RES_BACKGROUND, cppu::UnoType<css::style::GraphicLocation>::get(), PROPERTY_NONE ,MID_GRAPHIC_POSITION},
+ { OUString(UNO_NAME_BACK_COLOR), RES_BACKGROUND, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE ,MID_BACK_COLOR },
+ { OUString(UNO_NAME_BACK_TRANSPARENT), RES_BACKGROUND, cppu::UnoType<bool>::get(), PROPERTY_NONE ,MID_GRAPHIC_TRANSPARENT },
+ { OUString(UNO_LINK_DISPLAY_NAME), FN_PARAM_LINK_DISPLAY_NAME, cppu::UnoType<OUString>::get(), PropertyAttribute::READONLY, 0xbf},
+ { OUString(UNO_NAME_USER_DEFINED_ATTRIBUTES), RES_UNKNOWNATR_CONTAINER, cppu::UnoType<css::container::XNameContainer>::get(), PropertyAttribute::MAYBEVOID, 0 },
+ { OUString(UNO_NAME_FOOTNOTE_IS_COLLECT_AT_TEXT_END), RES_FTN_AT_TXTEND, cppu::UnoType<bool>::get(), PROPERTY_NONE ,MID_COLLECT },
+ { OUString(UNO_NAME_FOOTNOTE_IS_RESTART_NUMBERING), RES_FTN_AT_TXTEND, cppu::UnoType<bool>::get(), PROPERTY_NONE , MID_RESTART_NUM },
+ { OUString(UNO_NAME_FOOTNOTE_RESTART_NUMBERING_AT), RES_FTN_AT_TXTEND, cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE , MID_NUM_START_AT},
+ { OUString(UNO_NAME_FOOTNOTE_IS_OWN_NUMBERING), RES_FTN_AT_TXTEND, cppu::UnoType<bool>::get(), PROPERTY_NONE , MID_OWN_NUM },
+ { OUString(UNO_NAME_FOOTNOTE_NUMBERING_TYPE), RES_FTN_AT_TXTEND, cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE , MID_NUM_TYPE },
+ { OUString(UNO_NAME_FOOTNOTE_NUMBERING_PREFIX), RES_FTN_AT_TXTEND, cppu::UnoType<OUString>::get() , PROPERTY_NONE, MID_PREFIX },
+ { OUString(UNO_NAME_FOOTNOTE_NUMBERING_SUFFIX), RES_FTN_AT_TXTEND, cppu::UnoType<OUString>::get() , PROPERTY_NONE, MID_SUFFIX },
+ { OUString(UNO_NAME_ENDNOTE_IS_COLLECT_AT_TEXT_END), RES_END_AT_TXTEND, cppu::UnoType<bool>::get(), PROPERTY_NONE , MID_COLLECT },
+ { OUString(UNO_NAME_ENDNOTE_IS_RESTART_NUMBERING), RES_END_AT_TXTEND, cppu::UnoType<bool>::get(), PROPERTY_NONE , MID_RESTART_NUM },
+ { OUString(UNO_NAME_ENDNOTE_RESTART_NUMBERING_AT), RES_END_AT_TXTEND, cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE , MID_NUM_START_AT },
+ { OUString(UNO_NAME_ENDNOTE_IS_OWN_NUMBERING), RES_END_AT_TXTEND, cppu::UnoType<bool>::get(), PROPERTY_NONE , MID_OWN_NUM },
+ { OUString(UNO_NAME_ENDNOTE_NUMBERING_TYPE), RES_END_AT_TXTEND, cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE ,MID_NUM_TYPE },
+ { OUString(UNO_NAME_ENDNOTE_NUMBERING_PREFIX), RES_END_AT_TXTEND, cppu::UnoType<OUString>::get() , PROPERTY_NONE, MID_PREFIX },
+ { OUString(UNO_NAME_ENDNOTE_NUMBERING_SUFFIX), RES_END_AT_TXTEND, cppu::UnoType<OUString>::get() , PROPERTY_NONE, MID_SUFFIX },
+ { OUString(UNO_NAME_DOCUMENT_INDEX), WID_SECT_DOCUMENT_INDEX, cppu::UnoType<css::text::XDocumentIndex>::get(), PropertyAttribute::READONLY | PropertyAttribute::MAYBEVOID, 0 },
+ { OUString(UNO_NAME_IS_GLOBAL_DOCUMENT_SECTION), WID_SECT_IS_GLOBAL_DOC_SECTION, cppu::UnoType<bool>::get(), PropertyAttribute::READONLY, 0 },
+ { OUString(UNO_NAME_PROTECTION_KEY), WID_SECT_PASSWORD, cppu::UnoType< cppu::UnoSequenceType<sal_Int8> >::get(), PROPERTY_NONE, 0 },
+ { OUString(UNO_NAME_DONT_BALANCE_TEXT_COLUMNS), RES_COLUMNBALANCE, cppu::UnoType<bool>::get(), PROPERTY_NONE, 0 },
+ COMMON_TEXT_CONTENT_PROPERTIES
+ REDLINE_NODE_PROPERTIES
+ { OUString(UNO_NAME_IS_CURRENTLY_VISIBLE), WID_SECT_CURRENTLY_VISIBLE, cppu::UnoType<bool>::get(), PROPERTY_NONE, 0},
+ { OUString(UNO_NAME_WRITING_MODE), RES_FRAMEDIR, cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE, 0 },
+ { OUString(UNO_NAME_SECT_LEFT_MARGIN), RES_LR_SPACE, cppu::UnoType<sal_Int32>::get(), PropertyAttribute::MAYBEVOID, MID_L_MARGIN|CONVERT_TWIPS},
+ { OUString(UNO_NAME_SECT_RIGHT_MARGIN), RES_LR_SPACE, cppu::UnoType<sal_Int32>::get(), PropertyAttribute::MAYBEVOID, MID_R_MARGIN|CONVERT_TWIPS},
+ { OUString(), 0, css::uno::Type(), 0, 0 }
+ };
+
+ return aSectionPropertyMap_Impl;
+}
+
+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
+ { OUString(UNO_NAME_CHAIN_NEXT_NAME), RES_CHAIN, cppu::UnoType<OUString>::get(), PropertyAttribute::MAYBEVOID ,MID_CHAIN_NEXTNAME},
+ { OUString(UNO_NAME_CHAIN_PREV_NAME), RES_CHAIN, cppu::UnoType<OUString>::get(), PropertyAttribute::MAYBEVOID ,MID_CHAIN_PREVNAME},
+ /*not impl*/ { OUString(UNO_NAME_CLIENT_MAP), RES_URL, cppu::UnoType<bool>::get(), PROPERTY_NONE ,MID_URL_CLIENTMAP },
+ { OUString(UNO_NAME_EDIT_IN_READONLY), RES_EDIT_IN_READONLY, cppu::UnoType<bool>::get(), PROPERTY_NONE, 0},
+ { OUString(UNO_NAME_TEXT_COLUMNS), RES_COL, cppu::UnoType<css::text::XTextColumns>::get(), PROPERTY_NONE, MID_COLUMNS},
+ //next elements are part of the service description
+ { OUString(UNO_NAME_FRAME_HEIGHT_ABSOLUTE), RES_FRM_SIZE, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE, MID_FRMSIZE_HEIGHT|CONVERT_TWIPS },
+ { OUString(UNO_NAME_FRAME_HEIGHT_PERCENT), RES_FRM_SIZE, cppu::UnoType<sal_Int8>::get(), PROPERTY_NONE, MID_FRMSIZE_REL_HEIGHT },
+ { OUString(UNO_NAME_FRAME_ISAUTOMATIC_HEIGHT), RES_FRM_SIZE, cppu::UnoType<bool>::get(), PROPERTY_NONE, MID_FRMSIZE_IS_AUTO_HEIGHT },
+ { OUString(UNO_NAME_FRAME_WIDTH_ABSOLUTE), RES_FRM_SIZE, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE, MID_FRMSIZE_WIDTH|CONVERT_TWIPS },
+ { OUString(UNO_NAME_FRAME_WIDTH_PERCENT), RES_FRM_SIZE, cppu::UnoType<sal_Int8>::get(), PROPERTY_NONE, MID_FRMSIZE_REL_WIDTH },
+ { OUString(UNO_NAME_SIZE_TYPE), RES_FRM_SIZE, cppu::UnoType<sal_Int16>::get() , PROPERTY_NONE, MID_FRMSIZE_SIZE_TYPE },
+ { OUString(UNO_NAME_WIDTH_TYPE), RES_FRM_SIZE, cppu::UnoType<sal_Int16>::get() , PROPERTY_NONE, MID_FRMSIZE_WIDTH_TYPE },
+ { OUString(UNO_NAME_WRITING_MODE), RES_FRAMEDIR, cppu::UnoType<sal_Int16>::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 FlyFrame import/export
+ FILL_PROPERTIES_SW
+
+ { OUString(), 0, css::uno::Type(), 0, 0 }
+ };
+
+ return aFramePropertyMap_Impl;
+}
+
+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
+ { OUString(UNO_NAME_SURROUND_CONTOUR), RES_SURROUND, cppu::UnoType<bool>::get(), PROPERTY_NONE, MID_SURROUND_CONTOUR },
+ { OUString(UNO_NAME_CONTOUR_OUTSIDE), RES_SURROUND, cppu::UnoType<bool>::get(), PROPERTY_NONE, MID_SURROUND_CONTOUROUTSIDE },
+ { OUString(UNO_NAME_GRAPHIC_CROP), RES_GRFATR_CROPGRF, cppu::UnoType<css::text::GraphicCrop>::get(), PROPERTY_NONE, CONVERT_TWIPS },
+ { OUString(UNO_NAME_HORI_MIRRORED_ON_EVEN_PAGES), RES_GRFATR_MIRRORGRF, cppu::UnoType<bool>::get(), PROPERTY_NONE, MID_MIRROR_HORZ_EVEN_PAGES },
+ { OUString(UNO_NAME_HORI_MIRRORED_ON_ODD_PAGES), RES_GRFATR_MIRRORGRF, cppu::UnoType<bool>::get(), PROPERTY_NONE, MID_MIRROR_HORZ_ODD_PAGES },
+ { OUString(UNO_NAME_VERT_MIRRORED), RES_GRFATR_MIRRORGRF, cppu::UnoType<bool>::get(), PROPERTY_NONE, MID_MIRROR_VERT },
+ { OUString(UNO_NAME_REPLACEMENT_GRAPHIC), FN_UNO_REPLACEMENT_GRAPHIC, cppu::UnoType<css::graphic::XGraphic>::get(), 0, 0 },
+ { OUString(UNO_NAME_GRAPHIC_FILTER), FN_UNO_GRAPHIC_FILTER, cppu::UnoType<OUString>::get(), 0, 0 },
+ { OUString(UNO_NAME_GRAPHIC), FN_UNO_GRAPHIC, cppu::UnoType<css::graphic::XGraphic>::get(), 0, 0 },
+ { OUString(UNO_NAME_GRAPHIC_URL), FN_UNO_GRAPHIC_URL, cppu::UnoType<css::uno::Any>::get(), 0, 0 },
+ { OUString(UNO_NAME_TRANSFORMED_GRAPHIC), FN_UNO_TRANSFORMED_GRAPHIC, cppu::UnoType<css::graphic::XGraphic>::get(), 0, 0 },
+ { OUString(UNO_NAME_ACTUAL_SIZE), FN_UNO_ACTUAL_SIZE, cppu::UnoType<css::awt::Size>::get(), PropertyAttribute::READONLY, CONVERT_TWIPS},
+ { OUString(UNO_NAME_CONTOUR_POLY_POLYGON), FN_PARAM_CONTOUR_PP, cppu::UnoType<css::drawing::PointSequenceSequence>::get(), PropertyAttribute::MAYBEVOID, 0 },
+ { OUString(UNO_NAME_IS_PIXEL_CONTOUR), FN_UNO_IS_PIXEL_CONTOUR, cppu::UnoType<bool>::get(), PROPERTY_NONE, 0 },
+ { OUString(UNO_NAME_IS_AUTOMATIC_CONTOUR), FN_UNO_IS_AUTOMATIC_CONTOUR , cppu::UnoType<bool>::get(), PROPERTY_NONE, 0 },
+ { OUString(UNO_NAME_GRAPHIC_ROTATION), RES_GRFATR_ROTATION, cppu::UnoType<sal_Int16>::get(), 0, 0},
+ { OUString(UNO_NAME_ADJUST_LUMINANCE), RES_GRFATR_LUMINANCE, cppu::UnoType<sal_Int16>::get(), 0, 0},
+ { OUString(UNO_NAME_ADJUST_CONTRAST), RES_GRFATR_CONTRAST, cppu::UnoType<sal_Int16>::get(), 0, 0},
+ { OUString(UNO_NAME_ADJUST_RED), RES_GRFATR_CHANNELR, cppu::UnoType<sal_Int16>::get(), 0, 0},
+ { OUString(UNO_NAME_ADJUST_GREEN), RES_GRFATR_CHANNELG, cppu::UnoType<sal_Int16>::get(), 0, 0},
+ { OUString(UNO_NAME_ADJUST_BLUE), RES_GRFATR_CHANNELB, cppu::UnoType<sal_Int16>::get(), 0, 0},
+ { OUString(UNO_NAME_GAMMA), RES_GRFATR_GAMMA, cppu::UnoType<double>::get(), 0, 0},
+ { OUString(UNO_NAME_GRAPHIC_IS_INVERTED), RES_GRFATR_INVERT, cppu::UnoType<bool>::get(), 0, 0},
+ { OUString(UNO_NAME_TRANSPARENCY), RES_GRFATR_TRANSPARENCY, cppu::UnoType<sal_Int16>::get(), 0, 0},
+ { OUString(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
+
+ { OUString(), 0, css::uno::Type(), 0, 0 }
+ };
+
+ return aGraphicPropertyMap_Impl;
+}
+
+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
+ { OUString(UNO_NAME_SURROUND_CONTOUR), RES_SURROUND, cppu::UnoType<bool>::get(), PROPERTY_NONE, MID_SURROUND_CONTOUR },
+ { OUString(UNO_NAME_CONTOUR_OUTSIDE), RES_SURROUND, cppu::UnoType<bool>::get(), PROPERTY_NONE, MID_SURROUND_CONTOUROUTSIDE},
+ { OUString(UNO_NAME_CONTOUR_POLY_POLYGON), FN_PARAM_CONTOUR_PP, cppu::UnoType<css::drawing::PointSequenceSequence>::get(), PropertyAttribute::MAYBEVOID, 0 },
+ { OUString(UNO_NAME_IS_PIXEL_CONTOUR), FN_UNO_IS_PIXEL_CONTOUR, cppu::UnoType<bool>::get(), PROPERTY_NONE, 0 },
+ { OUString(UNO_NAME_IS_AUTOMATIC_CONTOUR), FN_UNO_IS_AUTOMATIC_CONTOUR , cppu::UnoType<bool>::get(), PROPERTY_NONE, 0 },
+ { OUString(UNO_NAME_CLSID), FN_UNO_CLSID, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0 },
+ { OUString(UNO_NAME_STREAM_NAME), FN_UNO_STREAM_NAME, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0 },
+ { OUString(UNO_NAME_MODEL), FN_UNO_MODEL, cppu::UnoType<css::frame::XModel>::get(), PropertyAttribute::READONLY|PropertyAttribute::MAYBEVOID, 0},
+ { OUString(UNO_NAME_GRAPHIC_URL), FN_UNO_REPLACEMENT_GRAPHIC_URL, cppu::UnoType<OUString>::get(), PropertyAttribute::MAYBEVOID, 0 },
+ { OUString(UNO_NAME_GRAPHIC), FN_UNO_REPLACEMENT_GRAPHIC, cppu::UnoType<css::graphic::XGraphic>::get(), PropertyAttribute::MAYBEVOID, 0 },
+ { OUString(UNO_NAME_COMPONENT),FN_UNO_COMPONENT, cppu::UnoType<css::lang::XComponent>::get(), PropertyAttribute::READONLY, 0},
+ { OUString(UNO_NAME_EMBEDDED_OBJECT),FN_EMBEDDED_OBJECT, cppu::UnoType<css::embed::XEmbeddedObject>::get(), PROPERTY_NONE, 0},
+ { OUString(UNO_NAME_DRAW_ASPECT),FN_UNO_DRAW_ASPECT, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0 },
+ { OUString(UNO_NAME_VISIBLE_AREA_WIDTH),FN_UNO_VISIBLE_AREA_WIDTH, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0 },
+ { OUString(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
+
+ { OUString(), 0, css::uno::Type(), 0, 0 }
+ };
+
+ return aEmbeddedPropertyMap_Impl;
+}
+
+const SfxItemPropertyMapEntry* SwUnoPropertyMapProvider::GetIndexMarkPropertyMap()
+{
+ static SfxItemPropertyMapEntry const aIdxMarkMap_Impl[] =
+ {
+ { OUString(UNO_NAME_ALTERNATIVE_TEXT), WID_ALT_TEXT, cppu::UnoType<OUString>::get() , PROPERTY_NONE, 0},
+ { OUString(UNO_NAME_PRIMARY_KEY), WID_PRIMARY_KEY, cppu::UnoType<OUString>::get() , PROPERTY_NONE, 0},
+ { OUString(UNO_NAME_SECONDARY_KEY), WID_SECONDARY_KEY, cppu::UnoType<OUString>::get() , PROPERTY_NONE, 0},
+ { OUString(UNO_NAME_TEXT_READING), WID_TEXT_READING, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ { OUString(UNO_NAME_PRIMARY_KEY_READING), WID_PRIMARY_KEY_READING, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ { OUString(UNO_NAME_SECONDARY_KEY_READING), WID_SECONDARY_KEY_READING, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ { OUString(UNO_NAME_IS_MAIN_ENTRY), WID_MAIN_ENTRY, cppu::UnoType<bool>::get() , PROPERTY_NONE, 0},
+ COMMON_TEXT_CONTENT_PROPERTIES
+ { OUString(), 0, css::uno::Type(), 0, 0 }
+ };
+
+ return aIdxMarkMap_Impl;
+}
+
+const SfxItemPropertyMapEntry* SwUnoPropertyMapProvider::GetContentMarkPropertyMap()
+{
+ static SfxItemPropertyMapEntry const aContentMarkMap_Impl[] =
+ {
+ { OUString(UNO_NAME_ALTERNATIVE_TEXT), WID_ALT_TEXT, cppu::UnoType<OUString>::get() , PROPERTY_NONE, 0},
+ { OUString(UNO_NAME_LEVEL), WID_LEVEL , cppu::UnoType<sal_Int16>::get() , PROPERTY_NONE, 0},
+ COMMON_TEXT_CONTENT_PROPERTIES
+ { OUString(), 0, css::uno::Type(), 0, 0 }
+ };
+
+ return aContentMarkMap_Impl;
+}
+
+const SfxItemPropertyMapEntry* SwUnoPropertyMapProvider::GetUserMarkPropertyMap()
+{
+ static SfxItemPropertyMapEntry const aUserMarkMap_Impl[] =
+ {
+ { OUString(UNO_NAME_ALTERNATIVE_TEXT), WID_ALT_TEXT, cppu::UnoType<OUString>::get() , PROPERTY_NONE, 0},
+ { OUString(UNO_NAME_LEVEL), WID_LEVEL , cppu::UnoType<sal_Int16>::get() , PROPERTY_NONE, 0},
+ { OUString(UNO_NAME_USER_INDEX_NAME), WID_USER_IDX_NAME, cppu::UnoType<OUString>::get() , PROPERTY_NONE, 0},
+ COMMON_TEXT_CONTENT_PROPERTIES
+ { OUString(), 0, css::uno::Type(), 0, 0 }
+ };
+
+ return aUserMarkMap_Impl;
+}
+
+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:
+ { OUString(UNO_NAME_BACK_COLOR), FN_UNO_TABLE_CELL_BACKGROUND, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE , MID_BACK_COLOR },
+ { OUString(UNO_NAME_BACK_GRAPHIC_URL), RES_BACKGROUND, cppu::UnoType<OUString>::get(), PROPERTY_NONE ,MID_GRAPHIC_URL },
+ { OUString(UNO_NAME_BACK_GRAPHIC), RES_BACKGROUND, cppu::UnoType<graphic::XGraphic>::get(), PROPERTY_NONE, MID_GRAPHIC },
+ { OUString(UNO_NAME_BACK_GRAPHIC_FILTER), RES_BACKGROUND, cppu::UnoType<OUString>::get(), PROPERTY_NONE ,MID_GRAPHIC_FILTER },
+ { OUString(UNO_NAME_BACK_GRAPHIC_LOCATION), FN_UNO_TABLE_CELL_BACKGROUND, cppu::UnoType<css::style::GraphicLocation>::get(), PROPERTY_NONE ,MID_GRAPHIC_POSITION},
+ { OUString(UNO_NAME_NUMBER_FORMAT), RES_BOXATR_FORMAT, cppu::UnoType<sal_Int32>::get(), PropertyAttribute::MAYBEVOID ,0 },
+ { OUString(UNO_NAME_BACK_TRANSPARENT), FN_UNO_TABLE_CELL_BACKGROUND, cppu::UnoType<bool>::get(), PROPERTY_NONE , MID_GRAPHIC_TRANSPARENT },
+ { OUString(UNO_NAME_USER_DEFINED_ATTRIBUTES), RES_UNKNOWNATR_CONTAINER, cppu::UnoType<css::container::XNameContainer>::get(), PropertyAttribute::MAYBEVOID, 0 },
+ { OUString(UNO_NAME_TEXT_SECTION), FN_UNO_TEXT_SECTION, cppu::UnoType<css::text::XTextSection>::get(), PropertyAttribute::MAYBEVOID|PropertyAttribute::READONLY ,0 },
+ { OUString(UNO_NAME_IS_PROTECTED), RES_PROTECT, cppu::UnoType<bool>::get(), 0, MID_PROTECT_CONTENT},
+ { OUString(UNO_NAME_VERT_ORIENT), RES_VERT_ORIENT, cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE ,MID_VERTORIENT_ORIENT },
+ { OUString(), 0, css::uno::Type(), 0, 0 }
+ };
+
+ return aTableCursorPropertyMap_Impl;
+}
+
+const SfxItemPropertyMapEntry* SwUnoPropertyMapProvider::GetBookmarkPropertyMap()
+{
+ static SfxItemPropertyMapEntry const aBookmarkPropertyMap_Impl [] =
+ {
+ { OUString(UNO_LINK_DISPLAY_NAME), FN_PARAM_LINK_DISPLAY_NAME, cppu::UnoType<OUString>::get(), PropertyAttribute::READONLY, 0xbf},
+ COMMON_TEXT_CONTENT_PROPERTIES
+ { OUString(UNO_NAME_BOOKMARK_HIDDEN), FN_BOOKMARK_HIDDEN, cppu::UnoType<bool>::get(), PROPERTY_NONE, 0 },
+ { OUString(UNO_NAME_BOOKMARK_CONDITION), FN_BOOKMARK_CONDITION, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0 },
+ { OUString(), 0, css::uno::Type(), 0, 0 }
+ };
+
+ return aBookmarkPropertyMap_Impl;
+}
+
+const SfxItemPropertyMapEntry* SwUnoPropertyMapProvider::GetParagraphExtensionsPropertyMap()
+{
+ static SfxItemPropertyMapEntry const aParagraphExtensionsMap_Impl[] =
+ {
+ COMMON_TEXT_CONTENT_PROPERTIES
+ { OUString(), 0, css::uno::Type(), 0, 0 }
+ };
+
+ return aParagraphExtensionsMap_Impl;
+}
+
+const SfxItemPropertyMapEntry* SwUnoPropertyMapProvider::GetTextPortionExtensionPropertyMap()
+{
+ static SfxItemPropertyMapEntry const aTextPortionExtensionMap_Impl[] =
+ {
+ COMPLETE_TEXT_CURSOR_MAP
+ {OUString(UNO_NAME_BOOKMARK), FN_UNO_BOOKMARK, cppu::UnoType<css::text::XTextContent>::get(), PropertyAttribute::MAYBEVOID|PropertyAttribute::READONLY ,0 },
+ {OUString(UNO_NAME_CONTROL_CHARACTER), FN_UNO_CONTROL_CHARACTER, cppu::UnoType<sal_Int16>::get(), PropertyAttribute::MAYBEVOID|PropertyAttribute::READONLY, MID_HYPHEN_MIN_LEAD },
+ {OUString(UNO_NAME_IS_COLLAPSED), FN_UNO_IS_COLLAPSED, cppu::UnoType<bool>::get(), PropertyAttribute::MAYBEVOID|PropertyAttribute::READONLY, 0 },
+ {OUString(UNO_NAME_IS_START), FN_UNO_IS_START, cppu::UnoType<bool>::get(), PropertyAttribute::MAYBEVOID|PropertyAttribute::READONLY, 0 },
+ //REDLINE_PROPERTIES
+ {OUString(UNO_NAME_TEXT_PORTION_TYPE), FN_UNO_TEXT_PORTION_TYPE, cppu::UnoType<OUString>::get(), PropertyAttribute::READONLY, 0},
+ {OUString(UNO_NAME_META), FN_UNO_META, cppu::UnoType<css::text::XTextContent>::get(), PropertyAttribute::MAYBEVOID|PropertyAttribute::READONLY, 0 },
+ { OUString(), 0, css::uno::Type(), 0, 0 }
+ };
+
+ return aTextPortionExtensionMap_Impl;
+}
+
+const SfxItemPropertyMapEntry* SwUnoPropertyMapProvider::GetFootnotePropertyMap()
+{
+ static SfxItemPropertyMapEntry const aFootnoteMap_Impl[] =
+ {
+ {OUString(UNO_NAME_REFERENCE_ID), 0, cppu::UnoType<sal_Int16>::get(),PropertyAttribute::READONLY|PropertyAttribute::MAYBEVOID, 0},
+ COMMON_TEXT_CONTENT_PROPERTIES
+ REDLINE_NODE_PROPERTIES
+ { OUString(), 0, css::uno::Type(), 0, 0 }
+ };
+
+ return aFootnoteMap_Impl;
+}
+
+const SfxItemPropertyMapEntry* SwUnoPropertyMapProvider::GetRedlinePropertyMap()
+{
+ static SfxItemPropertyMapEntry const aRedlineMap_Impl[] =
+ {
+ REDLINE_PROPERTIES
+ REDLINE_NODE_PROPERTIES
+ {OUString(UNO_NAME_REDLINE_START), 0, cppu::UnoType<css::uno::XInterface>::get(), PropertyAttribute::READONLY, 0},
+ {OUString(UNO_NAME_REDLINE_END), 0, cppu::UnoType<css::uno::XInterface>::get(), PropertyAttribute::MAYBEVOID|PropertyAttribute::READONLY, 0},
+ { OUString(), 0, css::uno::Type(), 0, 0 }
+ };
+
+ return aRedlineMap_Impl;
+}
+
+SfxItemPropertyMapEntry* SwUnoPropertyMapProvider::GetTextDefaultPropertyMap()
+{
+ static SfxItemPropertyMapEntry aTextDefaultMap_Impl[] =
+ {
+ { OUString(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
+ { OUString(UNO_NAME_CHAR_STYLE_NAME), RES_TXTATR_CHARFMT, cppu::UnoType<OUString>::get(), PropertyAttribute::MAYBEVOID, 0},
+ { OUString(UNO_NAME_IS_SPLIT_ALLOWED), RES_ROW_SPLIT, cppu::UnoType<bool>::get() , PropertyAttribute::MAYBEVOID, 0},
+ // #i29550#
+ { OUString(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
+ { OUString(UNO_NAME_GRID_STANDARD_PAGE_MODE), RES_TEXTGRID, cppu::UnoType<bool>::get(), PROPERTY_NONE, MID_GRID_STANDARD_MODE},
+ { OUString(), 0, css::uno::Type(), 0, 0 }
+ };
+
+ return aTextDefaultMap_Impl;
+}
+
+const SfxItemPropertyMapEntry* SwUnoPropertyMapProvider::GetRedlinePortionPropertyMap()
+{
+ static SfxItemPropertyMapEntry const aRedlinePortionMap_Impl[] =
+ {
+ COMPLETE_TEXT_CURSOR_MAP
+ {OUString(UNO_NAME_BOOKMARK), FN_UNO_BOOKMARK, cppu::UnoType<css::text::XTextContent>::get(), PropertyAttribute::MAYBEVOID|PropertyAttribute::READONLY ,0 },
+ {OUString(UNO_NAME_CONTROL_CHARACTER), FN_UNO_CONTROL_CHARACTER, cppu::UnoType<sal_Int16>::get(), PropertyAttribute::MAYBEVOID|PropertyAttribute::READONLY, MID_HYPHEN_MIN_LEAD },
+ {OUString(UNO_NAME_IS_COLLAPSED), FN_UNO_IS_COLLAPSED, cppu::UnoType<bool>::get(), PropertyAttribute::MAYBEVOID|PropertyAttribute::READONLY, 0 },
+ {OUString(UNO_NAME_IS_START), FN_UNO_IS_START, cppu::UnoType<bool>::get(), PropertyAttribute::MAYBEVOID|PropertyAttribute::READONLY, 0 },
+ REDLINE_PROPERTIES
+ {OUString(UNO_NAME_TEXT_PORTION_TYPE), FN_UNO_TEXT_PORTION_TYPE, cppu::UnoType<OUString>::get(), PropertyAttribute::READONLY, 0},
+ { OUString(), 0, css::uno::Type(), 0, 0 }
+ };
+
+ return aRedlinePortionMap_Impl;
+}
+
+const SfxItemPropertySet* SwUnoPropertyMapProvider::GetPropertySet( sal_uInt16 nPropertyId)
+{
+ if( !m_aPropertySetArr[nPropertyId] )
+ {
+ 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_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_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_TEXT_COLUMS :
+ {
+ static SfxItemPropertySet aPROPERTY_MAP_TEXT_COLUMS(pEntries);
+ m_aPropertySetArr[nPropertyId] = &aPROPERTY_MAP_TEXT_COLUMS;
+ }
+ 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;
+ }
+ }
+ 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 000000000..0b211f392
--- /dev/null
+++ b/sw/source/core/unocore/unomapproperties.hxx
@@ -0,0 +1,529 @@
+/* -*- 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 \
+ { OUString(UNO_NAME_CHAR_HEIGHT), RES_CHRATR_FONTSIZE , cppu::UnoType<float>::get(), PropertyAttribute::MAYBEVOID, MID_FONTHEIGHT|CONVERT_TWIPS}, \
+ { OUString(UNO_NAME_CHAR_WEIGHT), RES_CHRATR_WEIGHT , cppu::UnoType<float>::get(), PropertyAttribute::MAYBEVOID, MID_WEIGHT}, \
+ { OUString(UNO_NAME_CHAR_FONT_NAME), RES_CHRATR_FONT, cppu::UnoType<OUString>::get(), PropertyAttribute::MAYBEVOID, MID_FONT_FAMILY_NAME }, \
+ { OUString(UNO_NAME_CHAR_FONT_STYLE_NAME), RES_CHRATR_FONT, cppu::UnoType<OUString>::get(), PropertyAttribute::MAYBEVOID, MID_FONT_STYLE_NAME }, \
+ { OUString(UNO_NAME_CHAR_FONT_FAMILY), RES_CHRATR_FONT, cppu::UnoType<sal_Int16>::get(), PropertyAttribute::MAYBEVOID, MID_FONT_FAMILY }, \
+ { OUString(UNO_NAME_CHAR_FONT_CHAR_SET), RES_CHRATR_FONT, cppu::UnoType<sal_Int16>::get(), PropertyAttribute::MAYBEVOID, MID_FONT_CHAR_SET }, \
+ { OUString(UNO_NAME_CHAR_FONT_PITCH), RES_CHRATR_FONT, cppu::UnoType<sal_Int16>::get(), PropertyAttribute::MAYBEVOID, MID_FONT_PITCH }, \
+ { OUString(UNO_NAME_CHAR_POSTURE), RES_CHRATR_POSTURE , cppu::UnoType<css::awt::FontSlant>::get(), PropertyAttribute::MAYBEVOID, MID_POSTURE}, \
+ { OUString(UNO_NAME_RSID), RES_CHRATR_RSID, cppu::UnoType<sal_Int32>::get(), PropertyAttribute::MAYBEVOID, 0 }, \
+ { OUString(UNO_NAME_CHAR_LOCALE), RES_CHRATR_LANGUAGE, cppu::UnoType<css::lang::Locale>::get(), PropertyAttribute::MAYBEVOID, MID_LANG_LOCALE }, \
+ { OUString(UNO_NAME_CHAR_INTEROP_GRAB_BAG), RES_CHRATR_GRABBAG, cppu::UnoType< cppu::UnoSequenceType<css::beans::PropertyValue> >::get(), PROPERTY_NONE, 0 }, \
+
+#define CJK_FONT_PROPERTIES \
+ { OUString(UNO_NAME_CHAR_HEIGHT_ASIAN), RES_CHRATR_CJK_FONTSIZE , cppu::UnoType<float>::get(), PropertyAttribute::MAYBEVOID, MID_FONTHEIGHT|CONVERT_TWIPS}, \
+ { OUString(UNO_NAME_CHAR_WEIGHT_ASIAN), RES_CHRATR_CJK_WEIGHT , cppu::UnoType<float>::get(), PropertyAttribute::MAYBEVOID, MID_WEIGHT}, \
+ { OUString(UNO_NAME_CHAR_FONT_NAME_ASIAN), RES_CHRATR_CJK_FONT, cppu::UnoType<OUString>::get(), PropertyAttribute::MAYBEVOID, MID_FONT_FAMILY_NAME }, \
+ { OUString(UNO_NAME_CHAR_FONT_STYLE_NAME_ASIAN), RES_CHRATR_CJK_FONT, cppu::UnoType<OUString>::get(), PropertyAttribute::MAYBEVOID, MID_FONT_STYLE_NAME }, \
+ { OUString(UNO_NAME_CHAR_FONT_FAMILY_ASIAN), RES_CHRATR_CJK_FONT, cppu::UnoType<sal_Int16>::get(), PropertyAttribute::MAYBEVOID, MID_FONT_FAMILY }, \
+ { OUString(UNO_NAME_CHAR_FONT_CHAR_SET_ASIAN), RES_CHRATR_CJK_FONT, cppu::UnoType<sal_Int16>::get(), PropertyAttribute::MAYBEVOID, MID_FONT_CHAR_SET }, \
+ { OUString(UNO_NAME_CHAR_FONT_PITCH_ASIAN), RES_CHRATR_CJK_FONT, cppu::UnoType<sal_Int16>::get(), PropertyAttribute::MAYBEVOID, MID_FONT_PITCH }, \
+ { OUString(UNO_NAME_CHAR_POSTURE_ASIAN), RES_CHRATR_CJK_POSTURE , cppu::UnoType<css::awt::FontSlant>::get(), PropertyAttribute::MAYBEVOID, MID_POSTURE}, \
+ { OUString(UNO_NAME_CHAR_LOCALE_ASIAN), RES_CHRATR_CJK_LANGUAGE , cppu::UnoType<css::lang::Locale>::get() , PropertyAttribute::MAYBEVOID, MID_LANG_LOCALE },
+
+#define CTL_FONT_PROPERTIES \
+ { OUString(UNO_NAME_CHAR_HEIGHT_COMPLEX), RES_CHRATR_CTL_FONTSIZE , cppu::UnoType<float>::get(), PropertyAttribute::MAYBEVOID, MID_FONTHEIGHT|CONVERT_TWIPS},\
+ { OUString(UNO_NAME_CHAR_WEIGHT_COMPLEX), RES_CHRATR_CTL_WEIGHT , cppu::UnoType<float>::get(), PropertyAttribute::MAYBEVOID, MID_WEIGHT}, \
+ { OUString(UNO_NAME_CHAR_FONT_NAME_COMPLEX), RES_CHRATR_CTL_FONT, cppu::UnoType<OUString>::get(), PropertyAttribute::MAYBEVOID, MID_FONT_FAMILY_NAME }, \
+ { OUString(UNO_NAME_CHAR_FONT_STYLE_NAME_COMPLEX), RES_CHRATR_CTL_FONT, cppu::UnoType<OUString>::get(), PropertyAttribute::MAYBEVOID, MID_FONT_STYLE_NAME }, \
+ { OUString(UNO_NAME_CHAR_FONT_FAMILY_COMPLEX), RES_CHRATR_CTL_FONT, cppu::UnoType<sal_Int16>::get(), PropertyAttribute::MAYBEVOID, MID_FONT_FAMILY }, \
+ { OUString(UNO_NAME_CHAR_FONT_CHAR_SET_COMPLEX), RES_CHRATR_CTL_FONT, cppu::UnoType<sal_Int16>::get(), PropertyAttribute::MAYBEVOID, MID_FONT_CHAR_SET }, \
+ { OUString(UNO_NAME_CHAR_FONT_PITCH_COMPLEX), RES_CHRATR_CTL_FONT, cppu::UnoType<sal_Int16>::get(), PropertyAttribute::MAYBEVOID, MID_FONT_PITCH }, \
+ { OUString(UNO_NAME_CHAR_POSTURE_COMPLEX), RES_CHRATR_CTL_POSTURE , cppu::UnoType<css::awt::FontSlant>::get(), PropertyAttribute::MAYBEVOID, MID_POSTURE}, \
+ { OUString(UNO_NAME_CHAR_LOCALE_COMPLEX), RES_CHRATR_CTL_LANGUAGE , cppu::UnoType<css::lang::Locale>::get() , PropertyAttribute::MAYBEVOID, MID_LANG_LOCALE },
+
+#define REDLINE_NODE_PROPERTIES \
+ { OUString(UNO_NAME_START_REDLINE), FN_UNO_REDLINE_NODE_START , cppu::UnoType< cppu::UnoSequenceType<css::beans::PropertyValue> >::get(), PropertyAttribute::MAYBEVOID|PropertyAttribute::READONLY, 0xbf }, \
+ { OUString(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 \
+ {OUString(UNO_NAME_REDLINE_AUTHOR), 0, cppu::UnoType<OUString>::get(), PropertyAttribute::MAYBEVOID|PropertyAttribute::READONLY, 0},\
+ {OUString(UNO_NAME_REDLINE_DATE_TIME), 0, cppu::UnoType<css::util::DateTime>::get(), PropertyAttribute::MAYBEVOID|PropertyAttribute::READONLY, 0},\
+ {OUString(UNO_NAME_REDLINE_COMMENT), 0, cppu::UnoType<OUString>::get(), PropertyAttribute::MAYBEVOID|PropertyAttribute::READONLY, 0},\
+ {OUString(UNO_NAME_REDLINE_DESCRIPTION), 0, cppu::UnoType<OUString>::get(), PropertyAttribute::MAYBEVOID | PropertyAttribute::READONLY, 0}, \
+ {OUString(UNO_NAME_REDLINE_TYPE), 0, cppu::UnoType<OUString>::get(), PropertyAttribute::MAYBEVOID|PropertyAttribute::READONLY, 0},\
+ {OUString(UNO_NAME_REDLINE_SUCCESSOR_DATA), 0, cppu::UnoType< cppu::UnoSequenceType<css::beans::PropertyValue> >::get(), PropertyAttribute::MAYBEVOID|PropertyAttribute::READONLY, 0},\
+ {OUString(UNO_NAME_REDLINE_IDENTIFIER), 0, cppu::UnoType<OUString>::get(), PropertyAttribute::MAYBEVOID|PropertyAttribute::READONLY, 0},\
+ {OUString(UNO_NAME_IS_IN_HEADER_FOOTER), 0, cppu::UnoType<bool>::get(), PropertyAttribute::MAYBEVOID|PropertyAttribute::READONLY, 0},\
+ {OUString(UNO_NAME_REDLINE_TEXT), 0, cppu::UnoType<css::text::XText>::get(), PropertyAttribute::MAYBEVOID|PropertyAttribute::READONLY, 0},\
+ {OUString(UNO_NAME_MERGE_LAST_PARA), 0, cppu::UnoType<bool>::get(), PropertyAttribute::MAYBEVOID|PropertyAttribute::READONLY, 0},
+
+#define COMMON_CRSR_PARA_PROPERTIES_FN_ONLY \
+ { OUString(UNO_NAME_PARA_STYLE_NAME), FN_UNO_PARA_STYLE, cppu::UnoType<OUString>::get(), PropertyAttribute::MAYBEVOID, 0}, \
+ { OUString(UNO_NAME_PAGE_STYLE_NAME), FN_UNO_PAGE_STYLE, cppu::UnoType<OUString>::get(), PropertyAttribute::MAYBEVOID|PropertyAttribute::READONLY, 0}, \
+ { OUString(UNO_NAME_NUMBERING_IS_NUMBER), FN_UNO_IS_NUMBER, cppu::UnoType<bool>::get() , PropertyAttribute::MAYBEVOID, 0}, \
+ { OUString(UNO_NAME_NUMBERING_LEVEL), FN_UNO_NUM_LEVEL, cppu::UnoType<sal_Int16>::get(), PropertyAttribute::MAYBEVOID, 0}, \
+ { OUString(UNO_NAME_NUMBERING_RULES), FN_UNO_NUM_RULES, cppu::UnoType<css::container::XIndexReplace>::get(), PropertyAttribute::MAYBEVOID, CONVERT_TWIPS}, \
+ { OUString(UNO_NAME_NUMBERING_START_VALUE), FN_UNO_NUM_START_VALUE, cppu::UnoType<sal_Int16>::get(), PropertyAttribute::MAYBEVOID, CONVERT_TWIPS}, \
+ { OUString(UNO_NAME_DOCUMENT_INDEX), FN_UNO_DOCUMENT_INDEX, cppu::UnoType<css::text::XDocumentIndex>::get(), PropertyAttribute::MAYBEVOID|PropertyAttribute::READONLY ,0 }, \
+ { OUString(UNO_NAME_TEXT_TABLE), FN_UNO_TEXT_TABLE, cppu::UnoType<css::text::XTextTable>::get(), PropertyAttribute::MAYBEVOID|PropertyAttribute::READONLY ,0 }, \
+ { OUString(UNO_NAME_CELL), FN_UNO_CELL, cppu::UnoType<css::table::XCell>::get(), PropertyAttribute::MAYBEVOID|PropertyAttribute::READONLY ,0 }, \
+ { OUString(UNO_NAME_TEXT_FRAME), FN_UNO_TEXT_FRAME, cppu::UnoType<css::text::XTextFrame>::get(), PropertyAttribute::MAYBEVOID|PropertyAttribute::READONLY ,0 }, \
+ { OUString(UNO_NAME_TEXT_SECTION), FN_UNO_TEXT_SECTION, cppu::UnoType<css::text::XTextSection>::get(), PropertyAttribute::MAYBEVOID|PropertyAttribute::READONLY ,0 }, \
+ { OUString(UNO_NAME_TEXT_PARAGRAPH), FN_UNO_TEXT_PARAGRAPH, cppu::UnoType<css::text::XTextContent>::get(), PropertyAttribute::MAYBEVOID|PropertyAttribute::READONLY ,0 }, \
+ { OUString(UNO_NAME_PARA_CHAPTER_NUMBERING_LEVEL), FN_UNO_PARA_CHAPTER_NUMBERING_LEVEL,cppu::UnoType<sal_Int8>::get(), PropertyAttribute::MAYBEVOID, 0}, \
+ { OUString(UNO_NAME_PARA_CONDITIONAL_STYLE_NAME), FN_UNO_PARA_CONDITIONAL_STYLE_NAME, cppu::UnoType<OUString>::get(), PropertyAttribute::READONLY, 0}, \
+ { OUString(UNO_NAME_LIST_ID), FN_UNO_LIST_ID, cppu::UnoType<OUString>::get(), PropertyAttribute::MAYBEVOID, 0}, \
+ { OUString(UNO_NAME_PARA_IS_NUMBERING_RESTART), FN_NUMBER_NEWSTART, cppu::UnoType<bool>::get(), PropertyAttribute::MAYBEVOID, 0 }, \
+ { OUString(UNO_NAME_PARA_CONTINUEING_PREVIOUS_SUB_TREE), FN_UNO_PARA_CONT_PREV_SUBTREE, cppu::UnoType<bool>::get(), PropertyAttribute::READONLY, 0 }, \
+ { OUString(UNO_NAME_PARA_LIST_LABEL_STRING), FN_UNO_PARA_NUM_STRING, cppu::UnoType<OUString>::get(), PropertyAttribute::READONLY, 0 }, \
+ { OUString(UNO_NAME_PARA_LIST_AUTO_FORMAT), FN_UNO_PARA_NUM_AUTO_FORMAT, cppu::UnoType<cppu::UnoSequenceType<css::beans::NamedValue>>::get(), PropertyAttribute::MAYBEVOID, 0 }, \
+ { OUString(UNO_NAME_OUTLINE_LEVEL), RES_PARATR_OUTLINELEVEL, cppu::UnoType<sal_Int16>::get(), PropertyAttribute::MAYBEVOID, 0},
+
+#define COMMON_HYPERLINK_PROPERTIES \
+ { OUString(UNO_NAME_HYPER_LINK_U_R_L), RES_TXTATR_INETFMT, cppu::UnoType<OUString>::get(), PropertyAttribute::MAYBEVOID ,MID_URL_URL}, \
+ { OUString(UNO_NAME_HYPER_LINK_TARGET), RES_TXTATR_INETFMT, cppu::UnoType<OUString>::get(), PropertyAttribute::MAYBEVOID ,MID_URL_TARGET}, \
+ { OUString(UNO_NAME_HYPER_LINK_NAME), RES_TXTATR_INETFMT, cppu::UnoType<OUString>::get(), PropertyAttribute::MAYBEVOID ,MID_URL_HYPERLINKNAME }, \
+ { OUString(UNO_NAME_UNVISITED_CHAR_STYLE_NAME), RES_TXTATR_INETFMT, cppu::UnoType<OUString>::get(), PropertyAttribute::MAYBEVOID ,MID_URL_UNVISITED_FMT }, \
+ { OUString(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
+// OUString(UNO_NAME_BREAK_TYPE) and OUString(UNO_NAME_PAGE_DESC_NAME) which can not be used
+// by the SwXTextTableCursor
+#define COMMON_CRSR_PARA_PROPERTIES_WITHOUT_FN_01 \
+ { OUString(UNO_NAME_PARRSID), RES_PARATR_RSID, cppu::UnoType<sal_Int32>::get(), PropertyAttribute::MAYBEVOID, 0 }, \
+ { OUString(UNO_NAME_PARA_IS_HYPHENATION), RES_PARATR_HYPHENZONE, cppu::UnoType<bool>::get(), PropertyAttribute::MAYBEVOID, MID_IS_HYPHEN }, \
+ { OUString(UNO_NAME_PARA_HYPHENATION_NO_CAPS), RES_PARATR_HYPHENZONE, cppu::UnoType<bool>::get(), PropertyAttribute::MAYBEVOID, MID_HYPHEN_NO_CAPS }, \
+ { OUString(UNO_NAME_PARA_HYPHENATION_MAX_LEADING_CHARS), RES_PARATR_HYPHENZONE, cppu::UnoType<sal_Int16>::get(), PropertyAttribute::MAYBEVOID, MID_HYPHEN_MIN_LEAD }, \
+ { OUString(UNO_NAME_PARA_HYPHENATION_MAX_TRAILING_CHARS), RES_PARATR_HYPHENZONE, cppu::UnoType<sal_Int16>::get(), PropertyAttribute::MAYBEVOID, MID_HYPHEN_MIN_TRAIL }, \
+ { OUString(UNO_NAME_PARA_HYPHENATION_MAX_HYPHENS), RES_PARATR_HYPHENZONE, cppu::UnoType<sal_Int16>::get(), PropertyAttribute::MAYBEVOID, MID_HYPHEN_MAX_HYPHENS }, \
+ { OUString(UNO_NAME_CHAR_AUTO_KERNING), RES_CHRATR_AUTOKERN, cppu::UnoType<bool>::get(), PropertyAttribute::MAYBEVOID, 0 }, \
+ { OUString(UNO_NAME_CHAR_BACK_COLOR), RES_CHRATR_BACKGROUND, cppu::UnoType<sal_Int32>::get(), PropertyAttribute::MAYBEVOID, MID_BACK_COLOR }, \
+ { OUString(UNO_NAME_CHAR_HIGHLIGHT), RES_CHRATR_HIGHLIGHT, cppu::UnoType<sal_Int32>::get(), PropertyAttribute::MAYBEVOID, MID_BACK_COLOR }, \
+ { OUString(UNO_NAME_PARA_BACK_COLOR), RES_BACKGROUND, cppu::UnoType<sal_Int32>::get(), PropertyAttribute::MAYBEVOID, MID_BACK_COLOR }, \
+ { OUString(UNO_NAME_CHAR_CASE_MAP), RES_CHRATR_CASEMAP, cppu::UnoType<sal_Int16>::get(), PropertyAttribute::MAYBEVOID, 0 }, \
+ { OUString(UNO_NAME_CHAR_COLOR), RES_CHRATR_COLOR, cppu::UnoType<sal_Int32>::get(), PropertyAttribute::MAYBEVOID, 0 }, \
+ { OUString(UNO_NAME_CHAR_TRANSPARENCE), RES_CHRATR_COLOR, cppu::UnoType<sal_Int16>::get(), PropertyAttribute::MAYBEVOID, MID_COLOR_ALPHA }, \
+ { OUString(UNO_NAME_CHAR_STRIKEOUT), RES_CHRATR_CROSSEDOUT, cppu::UnoType<sal_Int16>::get(), PropertyAttribute::MAYBEVOID, MID_CROSS_OUT }, \
+ { OUString(UNO_NAME_CHAR_CROSSED_OUT), RES_CHRATR_CROSSEDOUT, cppu::UnoType<bool>::get(), PropertyAttribute::MAYBEVOID, MID_CROSSED_OUT }, \
+ { OUString(UNO_NAME_CHAR_ESCAPEMENT), RES_CHRATR_ESCAPEMENT, cppu::UnoType<sal_Int16>::get(), PropertyAttribute::MAYBEVOID, MID_ESC }, \
+ { OUString(UNO_NAME_CHAR_ESCAPEMENT_HEIGHT), RES_CHRATR_ESCAPEMENT, cppu::UnoType<sal_Int8>::get(), PropertyAttribute::MAYBEVOID, MID_ESC_HEIGHT }, \
+ { OUString(UNO_NAME_CHAR_AUTO_ESCAPEMENT), RES_CHRATR_ESCAPEMENT, cppu::UnoType<bool>::get(), PropertyAttribute::MAYBEVOID, MID_AUTO_ESC }, \
+ { OUString(UNO_NAME_CHAR_FLASH), RES_CHRATR_BLINK, cppu::UnoType<bool>::get(), PropertyAttribute::MAYBEVOID, 0 }, \
+ { OUString(UNO_NAME_CHAR_HIDDEN), RES_CHRATR_HIDDEN, cppu::UnoType<bool>::get(), PropertyAttribute::MAYBEVOID, 0 }, \
+ { OUString(UNO_NAME_CHAR_UNDERLINE), RES_CHRATR_UNDERLINE, cppu::UnoType<sal_Int16>::get(), PropertyAttribute::MAYBEVOID, MID_TL_STYLE }, \
+ { OUString(UNO_NAME_CHAR_UNDERLINE_COLOR), RES_CHRATR_UNDERLINE, cppu::UnoType<sal_Int32>::get(), PropertyAttribute::MAYBEVOID, MID_TL_COLOR }, \
+ { OUString(UNO_NAME_CHAR_UNDERLINE_HAS_COLOR), RES_CHRATR_UNDERLINE, cppu::UnoType<bool>::get(), PropertyAttribute::MAYBEVOID, MID_TL_HASCOLOR }, \
+ { OUString(UNO_NAME_CHAR_OVERLINE), RES_CHRATR_OVERLINE, cppu::UnoType<sal_Int16>::get(), PropertyAttribute::MAYBEVOID, MID_TL_STYLE }, \
+ { OUString(UNO_NAME_CHAR_OVERLINE_COLOR), RES_CHRATR_OVERLINE, cppu::UnoType<sal_Int32>::get(), PropertyAttribute::MAYBEVOID, MID_TL_COLOR }, \
+ { OUString(UNO_NAME_CHAR_OVERLINE_HAS_COLOR), RES_CHRATR_OVERLINE, cppu::UnoType<bool>::get(), PropertyAttribute::MAYBEVOID, MID_TL_HASCOLOR }, \
+ { OUString(UNO_NAME_PARA_GRAPHIC_URL), RES_BACKGROUND, cppu::UnoType<OUString>::get(), PropertyAttribute::MAYBEVOID, MID_GRAPHIC_URL }, \
+ { OUString(UNO_NAME_PARA_GRAPHIC), RES_BACKGROUND, cppu::UnoType<css::graphic::XGraphic>::get(), PropertyAttribute::MAYBEVOID, MID_GRAPHIC }, \
+ { OUString(UNO_NAME_PARA_GRAPHIC_FILTER), RES_BACKGROUND, cppu::UnoType<OUString>::get(), PropertyAttribute::MAYBEVOID, MID_GRAPHIC_FILTER }, \
+ { OUString(UNO_NAME_PARA_GRAPHIC_LOCATION), RES_BACKGROUND, cppu::UnoType<css::style::GraphicLocation>::get(), PropertyAttribute::MAYBEVOID, MID_GRAPHIC_POSITION }, \
+ { OUString(UNO_NAME_PARA_LEFT_MARGIN), RES_LR_SPACE, cppu::UnoType<sal_Int32>::get(), PropertyAttribute::MAYBEVOID, MID_TXT_LMARGIN | CONVERT_TWIPS }, \
+ { OUString(UNO_NAME_PARA_RIGHT_MARGIN), RES_LR_SPACE, cppu::UnoType<sal_Int32>::get(), PropertyAttribute::MAYBEVOID, MID_R_MARGIN | CONVERT_TWIPS }, \
+ { OUString(UNO_NAME_PARA_IS_AUTO_FIRST_LINE_INDENT), RES_LR_SPACE, cppu::UnoType<bool>::get(), PropertyAttribute::MAYBEVOID, MID_FIRST_AUTO }, \
+ { OUString(UNO_NAME_PARA_FIRST_LINE_INDENT), RES_LR_SPACE, cppu::UnoType<sal_Int32>::get(), PropertyAttribute::MAYBEVOID, MID_FIRST_LINE_INDENT | CONVERT_TWIPS }, \
+ STANDARD_FONT_PROPERTIES \
+ CJK_FONT_PROPERTIES \
+ CTL_FONT_PROPERTIES \
+ { OUString(UNO_NAME_CHAR_KERNING), RES_CHRATR_KERNING, cppu::UnoType<sal_Int16>::get(), PropertyAttribute::MAYBEVOID, CONVERT_TWIPS }, \
+ { OUString(UNO_NAME_CHAR_NO_HYPHENATION), RES_CHRATR_NOHYPHEN, cppu::UnoType<bool>::get(), PropertyAttribute::MAYBEVOID, 0 }, \
+ { OUString(UNO_NAME_CHAR_SHADOWED), RES_CHRATR_SHADOWED, cppu::UnoType<bool>::get(), PropertyAttribute::MAYBEVOID, 0 }, \
+ { OUString(UNO_NAME_CHAR_CONTOURED), RES_CHRATR_CONTOUR, cppu::UnoType<bool>::get(), PropertyAttribute::MAYBEVOID, 0 }, \
+ { OUString(UNO_NAME_DROP_CAP_FORMAT), RES_PARATR_DROP, cppu::UnoType<css::style::DropCapFormat>::get(), PropertyAttribute::MAYBEVOID, MID_DROPCAP_FORMAT | CONVERT_TWIPS }, \
+ { OUString(UNO_NAME_DROP_CAP_WHOLE_WORD), RES_PARATR_DROP, cppu::UnoType<bool>::get(), PropertyAttribute::MAYBEVOID, MID_DROPCAP_WHOLE_WORD }, \
+ { OUString(UNO_NAME_DROP_CAP_CHAR_STYLE_NAME), RES_PARATR_DROP, cppu::UnoType<OUString>::get(), PropertyAttribute::MAYBEVOID, MID_DROPCAP_CHAR_STYLE_NAME }, \
+ { OUString(UNO_NAME_PARA_KEEP_TOGETHER), RES_KEEP, cppu::UnoType<bool>::get(), PropertyAttribute::MAYBEVOID, 0 }, \
+ { OUString(UNO_NAME_PARA_SPLIT), RES_PARATR_SPLIT, cppu::UnoType<bool>::get(), PropertyAttribute::MAYBEVOID, 0 }, \
+ { OUString(UNO_NAME_PARA_WIDOWS), RES_PARATR_WIDOWS, cppu::UnoType<sal_Int8>::get(), PropertyAttribute::MAYBEVOID, 0 }, \
+ { OUString(UNO_NAME_PARA_ORPHANS), RES_PARATR_ORPHANS, cppu::UnoType<sal_Int8>::get(), PropertyAttribute::MAYBEVOID, 0 }, \
+ { OUString(UNO_NAME_PAGE_NUMBER_OFFSET), RES_PAGEDESC, cppu::UnoType<sal_Int16>::get(), PropertyAttribute::MAYBEVOID, MID_PAGEDESC_PAGENUMOFFSET }, \
+ { OUString(UNO_NAME_PARA_ADJUST), RES_PARATR_ADJUST, cppu::UnoType<sal_Int16>::get(), PropertyAttribute::MAYBEVOID, MID_PARA_ADJUST }, \
+ { OUString(UNO_NAME_PARA_EXPAND_SINGLE_WORD), RES_PARATR_ADJUST, cppu::UnoType<bool>::get(), PropertyAttribute::MAYBEVOID, MID_EXPAND_SINGLE }, \
+ { OUString(UNO_NAME_PARA_LAST_LINE_ADJUST), RES_PARATR_ADJUST, cppu::UnoType<sal_Int16>::get(), PropertyAttribute::MAYBEVOID, MID_LAST_LINE_ADJUST }, \
+ { OUString(UNO_NAME_PARA_LINE_NUMBER_COUNT), RES_LINENUMBER, cppu::UnoType<bool>::get(), PropertyAttribute::MAYBEVOID, MID_LINENUMBER_COUNT }, \
+ { OUString(UNO_NAME_PARA_LINE_NUMBER_START_VALUE), RES_LINENUMBER, cppu::UnoType<sal_Int32>::get(), PropertyAttribute::MAYBEVOID, MID_LINENUMBER_STARTVALUE }, \
+ { OUString(UNO_NAME_PARA_LINE_SPACING), RES_PARATR_LINESPACING, cppu::UnoType<css::style::LineSpacing>::get(), PropertyAttribute::MAYBEVOID, CONVERT_TWIPS }, \
+ { OUString(UNO_NAME_PARA_REGISTER_MODE_ACTIVE), RES_PARATR_REGISTER, cppu::UnoType<bool>::get(), PropertyAttribute::MAYBEVOID, 0 }, \
+ { OUString(UNO_NAME_PARA_TOP_MARGIN), RES_UL_SPACE, cppu::UnoType<sal_Int32>::get(), PropertyAttribute::MAYBEVOID, MID_UP_MARGIN | CONVERT_TWIPS }, \
+ { OUString(UNO_NAME_PARA_BOTTOM_MARGIN), RES_UL_SPACE, cppu::UnoType<sal_Int32>::get(), PropertyAttribute::MAYBEVOID, MID_LO_MARGIN | CONVERT_TWIPS }, \
+ { OUString(UNO_NAME_PARA_CONTEXT_MARGIN), RES_UL_SPACE, cppu::UnoType<bool>::get(), PropertyAttribute::MAYBEVOID, MID_CTX_MARGIN }, \
+ { OUString(UNO_NAME_CHAR_BACK_TRANSPARENT), RES_CHRATR_BACKGROUND, cppu::UnoType<bool>::get(), PropertyAttribute::MAYBEVOID, MID_GRAPHIC_TRANSPARENT }, \
+ { OUString(UNO_NAME_PARA_BACK_TRANSPARENT), RES_BACKGROUND, cppu::UnoType<bool>::get(), PropertyAttribute::MAYBEVOID, MID_GRAPHIC_TRANSPARENT }, \
+ { OUString(UNO_NAME_NUMBERING_STYLE_NAME), RES_PARATR_NUMRULE, cppu::UnoType<OUString>::get(), PropertyAttribute::MAYBEVOID, 0 }, \
+ { OUString(UNO_NAME_CHAR_WORD_MODE), RES_CHRATR_WORDLINEMODE, cppu::UnoType<bool>::get(), PropertyAttribute::MAYBEVOID, 0 }, \
+ { OUString(UNO_NAME_CHAR_LEFT_BORDER), RES_CHRATR_BOX, cppu::UnoType<css::table::BorderLine>::get(), PropertyAttribute::MAYBEVOID, LEFT_BORDER | CONVERT_TWIPS }, \
+ { OUString(UNO_NAME_CHAR_RIGHT_BORDER), RES_CHRATR_BOX, cppu::UnoType<css::table::BorderLine>::get(), PropertyAttribute::MAYBEVOID, RIGHT_BORDER | CONVERT_TWIPS }, \
+ { OUString(UNO_NAME_CHAR_TOP_BORDER), RES_CHRATR_BOX, cppu::UnoType<css::table::BorderLine>::get(), PropertyAttribute::MAYBEVOID, TOP_BORDER | CONVERT_TWIPS }, \
+ { OUString(UNO_NAME_CHAR_BOTTOM_BORDER), RES_CHRATR_BOX, cppu::UnoType<css::table::BorderLine>::get(), PropertyAttribute::MAYBEVOID, BOTTOM_BORDER | CONVERT_TWIPS }, \
+ { OUString(UNO_NAME_CHAR_BORDER_DISTANCE), RES_CHRATR_BOX, cppu::UnoType<sal_Int32>::get(), PropertyAttribute::MAYBEVOID, BORDER_DISTANCE | CONVERT_TWIPS }, \
+ { OUString(UNO_NAME_CHAR_LEFT_BORDER_DISTANCE), RES_CHRATR_BOX, cppu::UnoType<sal_Int32>::get(), PropertyAttribute::MAYBEVOID, LEFT_BORDER_DISTANCE | CONVERT_TWIPS }, \
+ { OUString(UNO_NAME_CHAR_RIGHT_BORDER_DISTANCE), RES_CHRATR_BOX, cppu::UnoType<sal_Int32>::get(), PropertyAttribute::MAYBEVOID, RIGHT_BORDER_DISTANCE | CONVERT_TWIPS }, \
+ { OUString(UNO_NAME_CHAR_TOP_BORDER_DISTANCE), RES_CHRATR_BOX, cppu::UnoType<sal_Int32>::get(), PropertyAttribute::MAYBEVOID, TOP_BORDER_DISTANCE | CONVERT_TWIPS }, \
+ { OUString(UNO_NAME_CHAR_BOTTOM_BORDER_DISTANCE), RES_CHRATR_BOX, cppu::UnoType<sal_Int32>::get(), PropertyAttribute::MAYBEVOID, BOTTOM_BORDER_DISTANCE | CONVERT_TWIPS }, \
+ { OUString(UNO_NAME_CHAR_SHADOW_FORMAT), RES_CHRATR_SHADOW, cppu::UnoType<css::table::ShadowFormat>::get(), PropertyAttribute::MAYBEVOID, CONVERT_TWIPS }, \
+ { OUString(UNO_NAME_LEFT_BORDER), RES_BOX, cppu::UnoType<css::table::BorderLine>::get(), PropertyAttribute::MAYBEVOID, LEFT_BORDER | CONVERT_TWIPS }, \
+ { OUString(UNO_NAME_RIGHT_BORDER), RES_BOX, cppu::UnoType<css::table::BorderLine>::get(), PropertyAttribute::MAYBEVOID, RIGHT_BORDER | CONVERT_TWIPS }, \
+ { OUString(UNO_NAME_TOP_BORDER), RES_BOX, cppu::UnoType<css::table::BorderLine>::get(), PropertyAttribute::MAYBEVOID, TOP_BORDER | CONVERT_TWIPS }, \
+ { OUString(UNO_NAME_BOTTOM_BORDER), RES_BOX, cppu::UnoType<css::table::BorderLine>::get(), PropertyAttribute::MAYBEVOID, BOTTOM_BORDER | CONVERT_TWIPS }, \
+ { OUString(UNO_NAME_BORDER_DISTANCE), RES_BOX, cppu::UnoType<sal_Int32>::get(), PropertyAttribute::MAYBEVOID, BORDER_DISTANCE | CONVERT_TWIPS }, \
+ { OUString(UNO_NAME_LEFT_BORDER_DISTANCE), RES_BOX, cppu::UnoType<sal_Int32>::get(), PropertyAttribute::MAYBEVOID, LEFT_BORDER_DISTANCE | CONVERT_TWIPS }, \
+ { OUString(UNO_NAME_RIGHT_BORDER_DISTANCE), RES_BOX, cppu::UnoType<sal_Int32>::get(), PropertyAttribute::MAYBEVOID, RIGHT_BORDER_DISTANCE | CONVERT_TWIPS }, \
+ { OUString(UNO_NAME_TOP_BORDER_DISTANCE), RES_BOX, cppu::UnoType<sal_Int32>::get(), PropertyAttribute::MAYBEVOID, TOP_BORDER_DISTANCE | CONVERT_TWIPS }, \
+ { OUString(UNO_NAME_BOTTOM_BORDER_DISTANCE), RES_BOX, cppu::UnoType<sal_Int32>::get(), PropertyAttribute::MAYBEVOID, BOTTOM_BORDER_DISTANCE | CONVERT_TWIPS }, \
+ { OUString(UNO_NAME_PARA_USER_DEFINED_ATTRIBUTES), RES_UNKNOWNATR_CONTAINER, cppu::UnoType<css::container::XNameContainer>::get(), PropertyAttribute::MAYBEVOID, 0 }, \
+ { OUString(UNO_NAME_TEXT_USER_DEFINED_ATTRIBUTES), RES_TXTATR_UNKNOWN_CONTAINER, cppu::UnoType<css::container::XNameContainer>::get(), PropertyAttribute::MAYBEVOID, 0 }, \
+ { OUString(UNO_NAME_PARA_SHADOW_FORMAT), RES_SHADOW, cppu::UnoType<css::table::ShadowFormat>::get(), PROPERTY_NONE, CONVERT_TWIPS }, \
+ { OUString(UNO_NAME_CHAR_COMBINE_IS_ON), RES_CHRATR_TWO_LINES, cppu::UnoType<bool>::get(), PropertyAttribute::MAYBEVOID, MID_TWOLINES }, \
+ { OUString(UNO_NAME_CHAR_COMBINE_PREFIX), RES_CHRATR_TWO_LINES, cppu::UnoType<OUString>::get(), PropertyAttribute::MAYBEVOID, MID_START_BRACKET }, \
+ { OUString(UNO_NAME_CHAR_COMBINE_SUFFIX), RES_CHRATR_TWO_LINES, cppu::UnoType<OUString>::get(), PropertyAttribute::MAYBEVOID, MID_END_BRACKET }, \
+ { OUString(UNO_NAME_CHAR_EMPHASIS), RES_CHRATR_EMPHASIS_MARK, cppu::UnoType<sal_Int16>::get(), PropertyAttribute::MAYBEVOID, MID_EMPHASIS }, \
+ { OUString(UNO_NAME_PARA_IS_HANGING_PUNCTUATION), RES_PARATR_HANGINGPUNCTUATION, cppu::UnoType<bool>::get(), PropertyAttribute::MAYBEVOID, 0 }, \
+ { OUString(UNO_NAME_PARA_IS_CHARACTER_DISTANCE), RES_PARATR_SCRIPTSPACE, cppu::UnoType<bool>::get(), PropertyAttribute::MAYBEVOID, 0 }, \
+ { OUString(UNO_NAME_PARA_IS_FORBIDDEN_RULES), RES_PARATR_FORBIDDEN_RULES, cppu::UnoType<bool>::get(), PropertyAttribute::MAYBEVOID, 0 }, \
+ { OUString(UNO_NAME_PARA_VERT_ALIGNMENT), RES_PARATR_VERTALIGN, cppu::UnoType<sal_Int16>::get(), PropertyAttribute::MAYBEVOID, 0 }, \
+ { OUString(UNO_NAME_CHAR_ROTATION), RES_CHRATR_ROTATE, cppu::UnoType<sal_Int16>::get(), PropertyAttribute::MAYBEVOID, MID_ROTATE }, \
+ { OUString(UNO_NAME_CHAR_ROTATION_IS_FIT_TO_LINE), RES_CHRATR_ROTATE, cppu::UnoType<bool>::get(), PropertyAttribute::MAYBEVOID, MID_FITTOLINE }, \
+ { OUString(UNO_NAME_CHAR_SCALE_WIDTH), RES_CHRATR_SCALEW, cppu::UnoType<sal_Int16>::get(), PropertyAttribute::MAYBEVOID, 0 }, \
+ { OUString(UNO_NAME_RUBY_TEXT), RES_TXTATR_CJK_RUBY, cppu::UnoType<OUString>::get(), PropertyAttribute::MAYBEVOID, MID_RUBY_TEXT }, \
+ { OUString(UNO_NAME_RUBY_ADJUST), RES_TXTATR_CJK_RUBY, cppu::UnoType<sal_Int16>::get(), PropertyAttribute::MAYBEVOID, MID_RUBY_ADJUST }, \
+ { OUString(UNO_NAME_RUBY_CHAR_STYLE_NAME), RES_TXTATR_CJK_RUBY, cppu::UnoType<OUString>::get(), PropertyAttribute::MAYBEVOID, MID_RUBY_CHARSTYLE }, \
+ { OUString(UNO_NAME_RUBY_POSITION), RES_TXTATR_CJK_RUBY, cppu::UnoType<sal_Int16>::get(), PropertyAttribute::MAYBEVOID, MID_RUBY_POSITION}, \
+ { OUString(UNO_NAME_RUBY_IS_ABOVE), RES_TXTATR_CJK_RUBY, cppu::UnoType<bool>::get(), PropertyAttribute::MAYBEVOID, MID_RUBY_ABOVE }, \
+ { OUString(UNO_NAME_CHAR_RELIEF), RES_CHRATR_RELIEF, cppu::UnoType<sal_Int16>::get(), PropertyAttribute::MAYBEVOID, MID_RELIEF }, \
+ { OUString(UNO_NAME_SNAP_TO_GRID), RES_PARATR_SNAPTOGRID, cppu::UnoType<bool>::get(), PropertyAttribute::MAYBEVOID, 0 }, \
+ { OUString(UNO_NAME_PARA_IS_CONNECT_BORDER), RES_PARATR_CONNECT_BORDER, cppu::UnoType<bool>::get(), PropertyAttribute::MAYBEVOID, 0 }, \
+ { OUString(UNO_NAME_WRITING_MODE), RES_FRAMEDIR, cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE, 0 }, \
+ { OUString(UNO_NAME_CHAR_SHADING_VALUE), RES_CHRATR_BACKGROUND, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE, MID_SHADING_VALUE }, \
+ { OUString(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 \
+ { OUString(UNO_NAME_BREAK_TYPE), RES_BREAK, cppu::UnoType<css::style::BreakType>::get(), PropertyAttribute::MAYBEVOID, 0}, \
+ { OUString(UNO_NAME_PAGE_DESC_NAME), RES_PAGEDESC, cppu::UnoType<OUString>::get(), PropertyAttribute::MAYBEVOID, MID_PAGEDESC_PAGEDESCNAME },
+
+#define TABSTOPS_MAP_ENTRY { OUString(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 \
+ { OUString(UNO_NAME_CHAR_STYLE_NAME), RES_TXTATR_CHARFMT, cppu::UnoType<OUString>::get(), PropertyAttribute::MAYBEVOID, 0},\
+ { OUString(UNO_NAME_CHAR_STYLE_NAMES), FN_UNO_CHARFMT_SEQUENCE, cppu::UnoType< cppu::UnoSequenceType<OUString> >::get(), PropertyAttribute::MAYBEVOID, 0}, \
+ { OUString(UNO_NAME_CHAR_AUTO_STYLE_NAME), RES_TXTATR_AUTOFMT, cppu::UnoType<OUString>::get(), PropertyAttribute::MAYBEVOID, 0},\
+ { OUString(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\
+ { OUString(UNO_NAME_DOCUMENT_INDEX_MARK), FN_UNO_DOCUMENT_INDEX_MARK, cppu::UnoType<css::text::XDocumentIndexMark>::get(), PropertyAttribute::MAYBEVOID|PropertyAttribute::READONLY ,0 },\
+ { OUString(UNO_NAME_TEXT_FIELD), FN_UNO_TEXT_FIELD, cppu::UnoType<css::text::XTextField>::get(), PropertyAttribute::MAYBEVOID|PropertyAttribute::READONLY ,0 },\
+ { OUString(UNO_NAME_REFERENCE_MARK), FN_UNO_REFERENCE_MARK, cppu::UnoType<css::text::XTextContent>::get(), PropertyAttribute::MAYBEVOID|PropertyAttribute::READONLY, 0 },\
+ { OUString(UNO_NAME_FOOTNOTE), FN_UNO_FOOTNOTE, cppu::UnoType<css::text::XFootnote>::get(), PropertyAttribute::MAYBEVOID|PropertyAttribute::READONLY ,0 },\
+ { OUString(UNO_NAME_ENDNOTE), FN_UNO_ENDNOTE, cppu::UnoType<css::text::XFootnote>::get(), PropertyAttribute::MAYBEVOID|PropertyAttribute::READONLY ,0 },\
+ { OUString(UNO_NAME_HYPER_LINK_EVENTS), RES_TXTATR_INETFMT, cppu::UnoType<css::container::XNameReplace>::get(), PropertyAttribute::MAYBEVOID, MID_URL_HYPERLINKEVENTS},\
+ { OUString(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_\
+ { OUString(UNO_NAME_TITLE), WID_IDX_TITLE, cppu::UnoType<OUString>::get() , PROPERTY_NONE, 0},\
+ { OUString(UNO_NAME_NAME), WID_IDX_NAME, cppu::UnoType<OUString>::get() , PROPERTY_NONE, 0},\
+ { OUString(UNO_NAME_CONTENT_SECTION), WID_IDX_CONTENT_SECTION, cppu::UnoType<css::text::XTextSection>::get() , PropertyAttribute::READONLY, 0},\
+ { OUString(UNO_NAME_HEADER_SECTION), WID_IDX_HEADER_SECTION, cppu::UnoType<css::text::XTextSection>::get() , PropertyAttribute::MAYBEVOID|PropertyAttribute::READONLY, 0},\
+
+#define ANCHOR_TYPES_PROPERTY { OUString(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 \
+ { OUString(UNO_NAME_ANCHOR_PAGE_NO), RES_ANCHOR, cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE, MID_ANCHOR_PAGENUM }, \
+ { OUString(UNO_NAME_ANCHOR_TYPE), RES_ANCHOR, cppu::UnoType<css::text::TextContentAnchorType>::get(), PROPERTY_NONE, MID_ANCHOR_ANCHORTYPE}, \
+ { OUString(UNO_NAME_ANCHOR_FRAME), RES_ANCHOR, cppu::UnoType<css::text::XTextFrame>::get(), PropertyAttribute::MAYBEVOID, MID_ANCHOR_ANCHORFRAME}, \
+ ANCHOR_TYPES_PROPERTY\
+ { OUString(UNO_NAME_BACK_COLOR), RES_BACKGROUND, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE ,MID_BACK_COLOR }, \
+ { OUString(UNO_NAME_BACK_COLOR_R_G_B), RES_BACKGROUND, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE ,MID_BACK_COLOR_R_G_B}, \
+ { OUString(UNO_NAME_BACK_COLOR_TRANSPARENCY), RES_BACKGROUND, cppu::UnoType<sal_Int8>::get(), PROPERTY_NONE ,MID_BACK_COLOR_TRANSPARENCY}, \
+ { OUString(UNO_NAME_FRAME_INTEROP_GRAB_BAG), RES_FRMATR_GRABBAG, cppu::UnoType< cppu::UnoSequenceType<css::beans::PropertyValue> >::get(), PROPERTY_NONE, 0}, \
+ { OUString(UNO_NAME_CONTENT_PROTECTED), RES_PROTECT, cppu::UnoType<bool>::get(), PROPERTY_NONE, MID_PROTECT_CONTENT }, \
+ { OUString(UNO_NAME_FRAME_STYLE_NAME), FN_UNO_FRAME_STYLE_NAME,cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0}, \
+ { OUString(UNO_NAME_BACK_GRAPHIC_URL), RES_BACKGROUND, cppu::UnoType<OUString>::get(), PROPERTY_NONE ,MID_GRAPHIC_URL }, \
+ { OUString(UNO_NAME_BACK_GRAPHIC), RES_BACKGROUND, cppu::UnoType<css::graphic::XGraphic>::get(), PROPERTY_NONE, MID_GRAPHIC }, \
+ { OUString(UNO_NAME_BACK_GRAPHIC_FILTER), RES_BACKGROUND, cppu::UnoType<OUString>::get(), PROPERTY_NONE ,MID_GRAPHIC_FILTER }, \
+ { OUString(UNO_NAME_BACK_GRAPHIC_LOCATION), RES_BACKGROUND, cppu::UnoType<css::style::GraphicLocation>::get(), PROPERTY_NONE ,MID_GRAPHIC_POSITION}, \
+ { OUString(UNO_NAME_BACK_GRAPHIC_TRANSPARENCY), RES_BACKGROUND, cppu::UnoType<sal_Int8>::get(), PROPERTY_NONE ,MID_GRAPHIC_TRANSPARENCY}, \
+ { OUString(UNO_NAME_LEFT_MARGIN), RES_LR_SPACE, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE, MID_L_MARGIN|CONVERT_TWIPS}, \
+ { OUString(UNO_NAME_RIGHT_MARGIN), RES_LR_SPACE, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE, MID_R_MARGIN|CONVERT_TWIPS}, \
+ { OUString(UNO_NAME_WIDTH), RES_FRM_SIZE, cppu::UnoType<sal_Int32>::get() , PROPERTY_NONE, MID_FRMSIZE_WIDTH|CONVERT_TWIPS},\
+ { OUString(UNO_NAME_HEIGHT), RES_FRM_SIZE, cppu::UnoType<sal_Int32>::get() , PROPERTY_NONE, MID_FRMSIZE_HEIGHT|CONVERT_TWIPS},\
+ { OUString(UNO_NAME_HORI_ORIENT), RES_HORI_ORIENT, cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE ,MID_HORIORIENT_ORIENT }, \
+ { OUString(UNO_NAME_HORI_ORIENT_POSITION), RES_HORI_ORIENT, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE ,MID_HORIORIENT_POSITION|CONVERT_TWIPS }, \
+ { OUString(UNO_NAME_HORI_ORIENT_RELATION), RES_HORI_ORIENT, cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE ,MID_HORIORIENT_RELATION }, \
+ { OUString(UNO_NAME_HYPER_LINK_U_R_L), RES_URL, cppu::UnoType<OUString>::get(), PROPERTY_NONE ,MID_URL_URL}, \
+ { OUString(UNO_NAME_HYPER_LINK_TARGET), RES_URL, cppu::UnoType<OUString>::get(), PROPERTY_NONE ,MID_URL_TARGET}, \
+ { OUString(UNO_NAME_HYPER_LINK_NAME), RES_URL, cppu::UnoType<OUString>::get(), PROPERTY_NONE ,MID_URL_HYPERLINKNAME }, \
+ { OUString(UNO_NAME_OPAQUE), RES_OPAQUE, cppu::UnoType<bool>::get(), PROPERTY_NONE, 0}, \
+ { OUString(UNO_NAME_PAGE_TOGGLE), RES_HORI_ORIENT, cppu::UnoType<bool>::get(), PROPERTY_NONE ,MID_HORIORIENT_PAGETOGGLE }, \
+ { OUString(UNO_NAME_POSITION_PROTECTED), RES_PROTECT, cppu::UnoType<bool>::get(), PROPERTY_NONE, MID_PROTECT_POSITION}, \
+ { OUString(UNO_NAME_PRINT), RES_PRINT, cppu::UnoType<bool>::get(), PROPERTY_NONE, 0}, \
+ { OUString(UNO_NAME_RELATIVE_HEIGHT), RES_FRM_SIZE, cppu::UnoType<sal_Int16>::get() , PROPERTY_NONE, MID_FRMSIZE_REL_HEIGHT }, \
+ { OUString(UNO_NAME_RELATIVE_HEIGHT_RELATION), RES_FRM_SIZE, cppu::UnoType<sal_Int16>::get() , PROPERTY_NONE, MID_FRMSIZE_REL_HEIGHT_RELATION }, \
+ { OUString(UNO_NAME_RELATIVE_WIDTH), RES_FRM_SIZE, cppu::UnoType<sal_Int16>::get() , PROPERTY_NONE, MID_FRMSIZE_REL_WIDTH }, \
+ { OUString(UNO_NAME_RELATIVE_WIDTH_RELATION), RES_FRM_SIZE, cppu::UnoType<sal_Int16>::get() , PROPERTY_NONE, MID_FRMSIZE_REL_WIDTH_RELATION }, \
+ { OUString(UNO_NAME_SHADOW_FORMAT), RES_SHADOW, cppu::UnoType<css::table::ShadowFormat>::get(), PROPERTY_NONE, CONVERT_TWIPS}, \
+ { OUString(UNO_NAME_SHADOW_TRANSPARENCE), RES_SHADOW, cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE, MID_SHADOW_TRANSPARENCE}, \
+ { OUString(UNO_NAME_IMAGE_MAP), RES_URL, cppu::UnoType<css::container::XIndexContainer>::get(), PROPERTY_NONE, MID_URL_CLIENTMAP}, \
+ { OUString(UNO_NAME_SERVER_MAP), RES_URL, cppu::UnoType<bool>::get(), PROPERTY_NONE ,MID_URL_SERVERMAP }, \
+ { OUString(UNO_NAME_SIZE), RES_FRM_SIZE, cppu::UnoType<css::awt::Size>::get(), PROPERTY_NONE, MID_FRMSIZE_SIZE|CONVERT_TWIPS}, \
+ { OUString(UNO_NAME_SIZE_PROTECTED), RES_PROTECT, cppu::UnoType<bool>::get(), PROPERTY_NONE, MID_PROTECT_SIZE }, \
+ { OUString(UNO_NAME_IS_SYNC_WIDTH_TO_HEIGHT), RES_FRM_SIZE, cppu::UnoType<bool>::get() , PROPERTY_NONE, MID_FRMSIZE_IS_SYNC_WIDTH_TO_HEIGHT }, \
+ { OUString(UNO_NAME_IS_SYNC_HEIGHT_TO_WIDTH), RES_FRM_SIZE, cppu::UnoType<bool>::get() , PROPERTY_NONE, MID_FRMSIZE_IS_SYNC_HEIGHT_TO_WIDTH }, \
+ { OUString(UNO_NAME_TEXT_WRAP), RES_SURROUND, cppu::UnoType<css::text::WrapTextMode>::get(), PROPERTY_NONE, MID_SURROUND_SURROUNDTYPE }, \
+ { OUString(UNO_NAME_SURROUND), RES_SURROUND, cppu::UnoType<css::text::WrapTextMode>::get(), PROPERTY_NONE, MID_SURROUND_SURROUNDTYPE }, \
+ { OUString(UNO_NAME_SURROUND_ANCHORONLY), RES_SURROUND, cppu::UnoType<bool>::get(), PROPERTY_NONE, MID_SURROUND_ANCHORONLY }, \
+ { OUString(UNO_NAME_TOP_MARGIN), RES_UL_SPACE, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE, MID_UP_MARGIN|CONVERT_TWIPS}, \
+ { OUString(UNO_NAME_BOTTOM_MARGIN), RES_UL_SPACE, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE, MID_LO_MARGIN|CONVERT_TWIPS}, \
+ { OUString(UNO_NAME_BACK_TRANSPARENT), RES_BACKGROUND, cppu::UnoType<bool>::get(), PROPERTY_NONE ,MID_GRAPHIC_TRANSPARENT }, \
+ { OUString(UNO_NAME_VERT_ORIENT), RES_VERT_ORIENT, cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE ,MID_VERTORIENT_ORIENT }, \
+ { OUString(UNO_NAME_VERT_ORIENT_POSITION), RES_VERT_ORIENT, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE ,MID_VERTORIENT_POSITION|CONVERT_TWIPS }, \
+ { OUString(UNO_NAME_VERT_ORIENT_RELATION), RES_VERT_ORIENT, cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE ,MID_VERTORIENT_RELATION }, \
+ { OUString(UNO_NAME_LEFT_BORDER), RES_BOX, cppu::UnoType<css::table::BorderLine>::get(), 0, LEFT_BORDER |CONVERT_TWIPS }, \
+ { OUString(UNO_NAME_RIGHT_BORDER), RES_BOX, cppu::UnoType<css::table::BorderLine>::get(), 0, RIGHT_BORDER |CONVERT_TWIPS }, \
+ { OUString(UNO_NAME_TOP_BORDER), RES_BOX, cppu::UnoType<css::table::BorderLine>::get(), 0, TOP_BORDER |CONVERT_TWIPS }, \
+ { OUString(UNO_NAME_BOTTOM_BORDER), RES_BOX, cppu::UnoType<css::table::BorderLine>::get(), 0, BOTTOM_BORDER|CONVERT_TWIPS }, \
+ { OUString(UNO_NAME_BORDER_DISTANCE), RES_BOX, cppu::UnoType<sal_Int32>::get(), 0, BORDER_DISTANCE|CONVERT_TWIPS }, \
+ { OUString(UNO_NAME_LEFT_BORDER_DISTANCE), RES_BOX, cppu::UnoType<sal_Int32>::get(), 0, LEFT_BORDER_DISTANCE |CONVERT_TWIPS }, \
+ { OUString(UNO_NAME_RIGHT_BORDER_DISTANCE), RES_BOX, cppu::UnoType<sal_Int32>::get(), 0, RIGHT_BORDER_DISTANCE |CONVERT_TWIPS }, \
+ { OUString(UNO_NAME_TOP_BORDER_DISTANCE), RES_BOX, cppu::UnoType<sal_Int32>::get(), 0, TOP_BORDER_DISTANCE |CONVERT_TWIPS }, \
+ { OUString(UNO_NAME_BOTTOM_BORDER_DISTANCE), RES_BOX, cppu::UnoType<sal_Int32>::get(), 0, BOTTOM_BORDER_DISTANCE|CONVERT_TWIPS }, \
+ { OUString(UNO_LINK_DISPLAY_NAME), FN_PARAM_LINK_DISPLAY_NAME, cppu::UnoType<OUString>::get(), PropertyAttribute::READONLY, 0xbf}, \
+ { OUString(UNO_NAME_USER_DEFINED_ATTRIBUTES), RES_UNKNOWNATR_CONTAINER, cppu::UnoType<css::container::XNameContainer>::get(), PropertyAttribute::MAYBEVOID, 0 },\
+ { OUString(UNO_NAME_Z_ORDER), FN_UNO_Z_ORDER, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE, 0}, \
+ { OUString(UNO_NAME_IS_FOLLOWING_TEXT_FLOW), RES_FOLLOW_TEXT_FLOW, cppu::UnoType<bool>::get(), PROPERTY_NONE, MID_FOLLOW_TEXT_FLOW}, \
+ { OUString(UNO_NAME_PARENT_TEXT), FN_UNO_PARENT_TEXT, cppu::UnoType<text::XText>::get(), PropertyAttribute::MAYBEVOID | PropertyAttribute::READONLY, 0 }, \
+ { OUString(UNO_NAME_WRAP_INFLUENCE_ON_POSITION), RES_WRAP_INFLUENCE_ON_OBJPOS, cppu::UnoType<sal_Int8>::get(), PROPERTY_NONE, MID_WRAP_INFLUENCE}, \
+ { OUString(UNO_NAME_ALLOW_OVERLAP), RES_WRAP_INFLUENCE_ON_OBJPOS, cppu::UnoType<bool>::get(), PROPERTY_NONE, MID_ALLOW_OVERLAP}, \
+ { OUString(UNO_NAME_TITLE), FN_UNO_TITLE, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0}, \
+ { OUString(UNO_NAME_DESCRIPTION), FN_UNO_DESCRIPTION, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0}, \
+ { OUString(UNO_NAME_LAYOUT_SIZE), WID_LAYOUT_SIZE, cppu::UnoType<css::awt::Size>::get(), PropertyAttribute::MAYBEVOID | PropertyAttribute::READONLY, 0 }, \
+ { OUString(UNO_NAME_LINE_STYLE), RES_BOX, cppu::UnoType<css::drawing::LineStyle>::get(), 0, LINE_STYLE }, \
+ { OUString(UNO_NAME_LINE_WIDTH), RES_BOX, cppu::UnoType<sal_Int32>::get(), 0, LINE_WIDTH |CONVERT_TWIPS }, \
+ { OUString(UNO_NAME_TEXT_VERT_ADJUST), RES_TEXT_VERT_ADJUST, cppu::UnoType<css::drawing::TextVerticalAdjust>::get(), PROPERTY_NONE ,0},
+
+#define COMMON_TEXT_CONTENT_PROPERTIES \
+ { OUString(UNO_NAME_ANCHOR_TYPE), FN_UNO_ANCHOR_TYPE, cppu::UnoType<css::text::TextContentAnchorType>::get(), PropertyAttribute::READONLY, MID_ANCHOR_ANCHORTYPE},\
+ ANCHOR_TYPES_PROPERTY\
+ { OUString(UNO_NAME_TEXT_WRAP), FN_UNO_TEXT_WRAP, cppu::UnoType<css::text::WrapTextMode>::get(), PropertyAttribute::READONLY, MID_SURROUND_SURROUNDTYPE },
+
+#define PROP_DIFF_FONTHEIGHT \
+ { OUString(UNO_NAME_CHAR_PROP_HEIGHT), RES_CHRATR_FONTSIZE , cppu::UnoType<float>::get(), PROPERTY_NONE , MID_FONTHEIGHT_PROP},\
+ { OUString(UNO_NAME_CHAR_DIFF_HEIGHT), RES_CHRATR_FONTSIZE , cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE , MID_FONTHEIGHT_DIFF|CONVERT_TWIPS},\
+ { OUString(UNO_NAME_CHAR_PROP_HEIGHT_ASIAN), RES_CHRATR_CJK_FONTSIZE , cppu::UnoType<float>::get(), PROPERTY_NONE , MID_FONTHEIGHT_PROP},\
+ { OUString(UNO_NAME_CHAR_DIFF_HEIGHT_ASIAN), RES_CHRATR_CJK_FONTSIZE , cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE , MID_FONTHEIGHT_DIFF|CONVERT_TWIPS},\
+ { OUString(UNO_NAME_CHAR_PROP_HEIGHT_COMPLEX), RES_CHRATR_CTL_FONTSIZE , cppu::UnoType<float>::get(), PROPERTY_NONE , MID_FONTHEIGHT_PROP},\
+ { OUString(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 \
+ { OUString(UNO_NAME_BREAK_TYPE), RES_BREAK, cppu::UnoType<css::style::BreakType>::get(), PROPERTY_NONE, 0},\
+ { OUString(UNO_NAME_PAGE_DESC_NAME), RES_PAGEDESC, cppu::UnoType<OUString>::get(), PropertyAttribute::MAYBEVOID, MID_PAGEDESC_PAGEDESCNAME },\
+ { OUString(UNO_NAME_PAGE_NUMBER_OFFSET), RES_PAGEDESC, cppu::UnoType<sal_Int16>::get(), PropertyAttribute::MAYBEVOID, MID_PAGEDESC_PAGENUMOFFSET},\
+ { OUString(UNO_NAME_CHAR_AUTO_KERNING), RES_CHRATR_AUTOKERN , cppu::UnoType<bool>::get() , PROPERTY_NONE, 0},\
+ { OUString(UNO_NAME_CHAR_BACK_TRANSPARENT), RES_CHRATR_BACKGROUND, cppu::UnoType<bool>::get(), PROPERTY_NONE ,MID_GRAPHIC_TRANSPARENT },\
+ { OUString(UNO_NAME_CHAR_BACK_COLOR), RES_CHRATR_BACKGROUND, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE ,MID_BACK_COLOR },\
+ { OUString(UNO_NAME_CHAR_HIGHLIGHT), RES_CHRATR_HIGHLIGHT, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE ,MID_BACK_COLOR },\
+ { OUString(UNO_NAME_PARA_BACK_COLOR), RES_BACKGROUND, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE ,MID_BACK_COLOR },\
+ { OUString(UNO_NAME_PARA_BACK_TRANSPARENT), RES_BACKGROUND, cppu::UnoType<bool>::get(), PROPERTY_NONE ,MID_GRAPHIC_TRANSPARENT },\
+ { OUString(UNO_NAME_PARA_GRAPHIC_URL), RES_BACKGROUND, cppu::UnoType<OUString>::get(), PROPERTY_NONE ,MID_GRAPHIC_URL },\
+ { OUString(UNO_NAME_PARA_GRAPHIC), RES_BACKGROUND, cppu::UnoType<css::graphic::XGraphic>::get(), PROPERTY_NONE ,MID_GRAPHIC },\
+ { OUString(UNO_NAME_PARA_GRAPHIC_FILTER), RES_BACKGROUND, cppu::UnoType<OUString>::get(), PROPERTY_NONE ,MID_GRAPHIC_FILTER },\
+ { OUString(UNO_NAME_PARA_GRAPHIC_LOCATION), RES_BACKGROUND, cppu::UnoType<css::style::GraphicLocation>::get(), PROPERTY_NONE ,MID_GRAPHIC_POSITION}, \
+ { OUString(UNO_NAME_CHAR_CASE_MAP), RES_CHRATR_CASEMAP, cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE, 0},\
+ { OUString(UNO_NAME_CHAR_COLOR), RES_CHRATR_COLOR, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE, 0},\
+ { OUString(UNO_NAME_CHAR_TRANSPARENCE), RES_CHRATR_COLOR, cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE, MID_COLOR_ALPHA},\
+ { OUString(UNO_NAME_CHAR_STRIKEOUT), RES_CHRATR_CROSSEDOUT, cppu::UnoType<sal_Int16>::get(), PropertyAttribute::MAYBEVOID, MID_CROSS_OUT},\
+ { OUString(UNO_NAME_CHAR_CROSSED_OUT), RES_CHRATR_CROSSEDOUT, cppu::UnoType<bool>::get() , PROPERTY_NONE, 0},\
+ { OUString(UNO_NAME_CHAR_ESCAPEMENT), RES_CHRATR_ESCAPEMENT, cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE, MID_ESC },\
+ { OUString(UNO_NAME_CHAR_ESCAPEMENT_HEIGHT), RES_CHRATR_ESCAPEMENT, cppu::UnoType<sal_Int8>::get() , PROPERTY_NONE, MID_ESC_HEIGHT},\
+ { OUString(UNO_NAME_CHAR_FLASH), RES_CHRATR_BLINK , cppu::UnoType<bool>::get() , PROPERTY_NONE, 0},\
+ { OUString(UNO_NAME_CHAR_HIDDEN), RES_CHRATR_HIDDEN, cppu::UnoType<bool>::get() , PROPERTY_NONE, 0},\
+ STANDARD_FONT_PROPERTIES\
+ CJK_FONT_PROPERTIES\
+ CTL_FONT_PROPERTIES\
+ { OUString(UNO_NAME_CHAR_UNDERLINE), RES_CHRATR_UNDERLINE , cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE, MID_TL_STYLE},\
+ { OUString(UNO_NAME_CHAR_UNDERLINE_COLOR), RES_CHRATR_UNDERLINE , cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE, MID_TL_COLOR},\
+ { OUString(UNO_NAME_CHAR_UNDERLINE_HAS_COLOR), RES_CHRATR_UNDERLINE , cppu::UnoType<bool>::get(), PROPERTY_NONE, MID_TL_HASCOLOR},\
+ { OUString(UNO_NAME_CHAR_OVERLINE), RES_CHRATR_OVERLINE , cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE, MID_TL_STYLE},\
+ { OUString(UNO_NAME_CHAR_OVERLINE_COLOR), RES_CHRATR_OVERLINE , cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE, MID_TL_COLOR},\
+ { OUString(UNO_NAME_CHAR_OVERLINE_HAS_COLOR), RES_CHRATR_OVERLINE , cppu::UnoType<bool>::get(), PROPERTY_NONE, MID_TL_HASCOLOR},\
+ { OUString(UNO_NAME_PARA_LEFT_MARGIN), RES_LR_SPACE, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE, MID_TXT_LMARGIN|CONVERT_TWIPS},\
+ { OUString(UNO_NAME_PARA_RIGHT_MARGIN), RES_LR_SPACE, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE, MID_R_MARGIN|CONVERT_TWIPS},\
+ { OUString(UNO_NAME_PARA_LEFT_MARGIN_RELATIVE), RES_LR_SPACE, cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE, MID_L_REL_MARGIN},\
+ { OUString(UNO_NAME_PARA_RIGHT_MARGIN_RELATIVE), RES_LR_SPACE, cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE, MID_R_REL_MARGIN},\
+ { OUString(UNO_NAME_PARA_IS_AUTO_FIRST_LINE_INDENT), RES_LR_SPACE, cppu::UnoType<bool>::get(), PROPERTY_NONE, MID_FIRST_AUTO},\
+ { OUString(UNO_NAME_PARA_FIRST_LINE_INDENT), RES_LR_SPACE, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE, MID_FIRST_LINE_INDENT|CONVERT_TWIPS},\
+ { OUString(UNO_NAME_PARA_FIRST_LINE_INDENT_RELATIVE), RES_LR_SPACE, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE, MID_FIRST_LINE_REL_INDENT|CONVERT_TWIPS},\
+ { OUString(UNO_NAME_CHAR_KERNING), RES_CHRATR_KERNING , cppu::UnoType<sal_Int16>::get() , PROPERTY_NONE, CONVERT_TWIPS},\
+ { OUString(UNO_NAME_CHAR_NO_HYPHENATION), RES_CHRATR_NOHYPHEN , cppu::UnoType<bool>::get() , PROPERTY_NONE, 0},\
+ { OUString(UNO_NAME_CHAR_SHADOWED), RES_CHRATR_SHADOWED , cppu::UnoType<bool>::get() , PROPERTY_NONE, 0},\
+ { OUString(UNO_NAME_CHAR_CONTOURED), RES_CHRATR_CONTOUR, cppu::UnoType<bool>::get() , PROPERTY_NONE, 0},\
+ { OUString(UNO_NAME_DROP_CAP_FORMAT), RES_PARATR_DROP, cppu::UnoType<css::style::DropCapFormat>::get() , PROPERTY_NONE, MID_DROPCAP_FORMAT|CONVERT_TWIPS },\
+ { OUString(UNO_NAME_DROP_CAP_WHOLE_WORD), RES_PARATR_DROP, cppu::UnoType<bool>::get() , PROPERTY_NONE, MID_DROPCAP_WHOLE_WORD },\
+ { OUString(UNO_NAME_DROP_CAP_CHAR_STYLE_NAME), RES_PARATR_DROP, cppu::UnoType<OUString>::get() , PropertyAttribute::MAYBEVOID, MID_DROPCAP_CHAR_STYLE_NAME },\
+ { OUString(UNO_NAME_PARA_KEEP_TOGETHER), RES_KEEP, cppu::UnoType<bool>::get() , PROPERTY_NONE, 0},\
+ { OUString(UNO_NAME_PARA_SPLIT), RES_PARATR_SPLIT, cppu::UnoType<bool>::get() , PROPERTY_NONE, 0},\
+ { OUString(UNO_NAME_PARA_WIDOWS), RES_PARATR_WIDOWS, cppu::UnoType<sal_Int8>::get(),PropertyAttribute::MAYBEVOID, 0},\
+ { OUString(UNO_NAME_PARA_ORPHANS), RES_PARATR_ORPHANS, cppu::UnoType<sal_Int8>::get(),PropertyAttribute::MAYBEVOID, 0},\
+ { OUString(UNO_NAME_PARA_EXPAND_SINGLE_WORD), RES_PARATR_ADJUST, cppu::UnoType<bool>::get() , PROPERTY_NONE, MID_EXPAND_SINGLE },\
+ { OUString(UNO_NAME_PARA_LAST_LINE_ADJUST), RES_PARATR_ADJUST, cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE, MID_LAST_LINE_ADJUST},\
+ { OUString(UNO_NAME_PARA_LINE_NUMBER_COUNT), RES_LINENUMBER, cppu::UnoType<bool>::get(), PROPERTY_NONE ,MID_LINENUMBER_COUNT },\
+ { OUString(UNO_NAME_PARA_LINE_NUMBER_START_VALUE), RES_LINENUMBER, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE ,MID_LINENUMBER_STARTVALUE},\
+ { OUString(UNO_NAME_PARA_LINE_SPACING), RES_PARATR_LINESPACING, cppu::UnoType<css::style::LineSpacing>::get(),PROPERTY_NONE, CONVERT_TWIPS},\
+ { OUString(UNO_NAME_PARA_ADJUST), RES_PARATR_ADJUST, cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE, MID_PARA_ADJUST},\
+ { OUString(UNO_NAME_PARA_REGISTER_MODE_ACTIVE), RES_PARATR_REGISTER, cppu::UnoType<bool>::get() , PROPERTY_NONE, 0},\
+ { OUString(UNO_NAME_PARA_TOP_MARGIN), RES_UL_SPACE, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE, MID_UP_MARGIN|CONVERT_TWIPS},\
+ { OUString(UNO_NAME_PARA_BOTTOM_MARGIN), RES_UL_SPACE, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE, MID_LO_MARGIN|CONVERT_TWIPS},\
+ { OUString(UNO_NAME_PARA_CONTEXT_MARGIN), RES_UL_SPACE, cppu::UnoType<bool>::get(), PROPERTY_NONE, MID_CTX_MARGIN},\
+ { OUString(UNO_NAME_PARA_TOP_MARGIN_RELATIVE), RES_UL_SPACE, cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE, MID_UP_REL_MARGIN},\
+ { OUString(UNO_NAME_PARA_BOTTOM_MARGIN_RELATIVE), RES_UL_SPACE, cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE, MID_LO_REL_MARGIN},\
+ TABSTOPS_MAP_ENTRY\
+ { OUString(UNO_NAME_CHAR_WORD_MODE), RES_CHRATR_WORDLINEMODE,cppu::UnoType<bool>::get() , PROPERTY_NONE, 0},\
+ { OUString(UNO_NAME_CHAR_SHADING_VALUE), RES_CHRATR_BACKGROUND, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE, MID_SHADING_VALUE }, \
+ { OUString(UNO_NAME_CHAR_LEFT_BORDER), RES_CHRATR_BOX, cppu::UnoType<css::table::BorderLine>::get(), PROPERTY_NONE, LEFT_BORDER |CONVERT_TWIPS },\
+ { OUString(UNO_NAME_CHAR_RIGHT_BORDER), RES_CHRATR_BOX, cppu::UnoType<css::table::BorderLine>::get(), PROPERTY_NONE, RIGHT_BORDER |CONVERT_TWIPS },\
+ { OUString(UNO_NAME_CHAR_TOP_BORDER), RES_CHRATR_BOX, cppu::UnoType<css::table::BorderLine>::get(), PROPERTY_NONE, TOP_BORDER |CONVERT_TWIPS },\
+ { OUString(UNO_NAME_CHAR_BOTTOM_BORDER), RES_CHRATR_BOX, cppu::UnoType<css::table::BorderLine>::get(), PROPERTY_NONE, BOTTOM_BORDER |CONVERT_TWIPS },\
+ { OUString(UNO_NAME_CHAR_BORDER_DISTANCE), RES_CHRATR_BOX, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE, BORDER_DISTANCE |CONVERT_TWIPS },\
+ { OUString(UNO_NAME_CHAR_LEFT_BORDER_DISTANCE), RES_CHRATR_BOX, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE, LEFT_BORDER_DISTANCE |CONVERT_TWIPS },\
+ { OUString(UNO_NAME_CHAR_RIGHT_BORDER_DISTANCE), RES_CHRATR_BOX, cppu::UnoType<sal_Int32>::get(),PROPERTY_NONE, RIGHT_BORDER_DISTANCE |CONVERT_TWIPS },\
+ { OUString(UNO_NAME_CHAR_TOP_BORDER_DISTANCE), RES_CHRATR_BOX, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE, TOP_BORDER_DISTANCE |CONVERT_TWIPS },\
+ { OUString(UNO_NAME_CHAR_BOTTOM_BORDER_DISTANCE), RES_CHRATR_BOX, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE, BOTTOM_BORDER_DISTANCE|CONVERT_TWIPS },\
+ { OUString(UNO_NAME_CHAR_SHADOW_FORMAT), RES_CHRATR_SHADOW, cppu::UnoType<css::table::ShadowFormat>::get(), PROPERTY_NONE, CONVERT_TWIPS},\
+ { OUString(UNO_NAME_LEFT_BORDER), RES_BOX, cppu::UnoType<css::table::BorderLine>::get(), 0, LEFT_BORDER |CONVERT_TWIPS },\
+ { OUString(UNO_NAME_RIGHT_BORDER), RES_BOX, cppu::UnoType<css::table::BorderLine>::get(), 0, RIGHT_BORDER |CONVERT_TWIPS },\
+ { OUString(UNO_NAME_TOP_BORDER), RES_BOX, cppu::UnoType<css::table::BorderLine>::get(), 0, TOP_BORDER |CONVERT_TWIPS },\
+ { OUString(UNO_NAME_BOTTOM_BORDER), RES_BOX, cppu::UnoType<css::table::BorderLine>::get(), 0, BOTTOM_BORDER|CONVERT_TWIPS },\
+ { OUString(UNO_NAME_BORDER_DISTANCE), RES_BOX, cppu::UnoType<sal_Int32>::get(), 0, BORDER_DISTANCE|CONVERT_TWIPS },\
+ { OUString(UNO_NAME_LEFT_BORDER_DISTANCE), RES_BOX, cppu::UnoType<sal_Int32>::get(), 0, LEFT_BORDER_DISTANCE |CONVERT_TWIPS },\
+ { OUString(UNO_NAME_RIGHT_BORDER_DISTANCE), RES_BOX, cppu::UnoType<sal_Int32>::get(), 0, RIGHT_BORDER_DISTANCE |CONVERT_TWIPS },\
+ { OUString(UNO_NAME_TOP_BORDER_DISTANCE), RES_BOX, cppu::UnoType<sal_Int32>::get(), 0, TOP_BORDER_DISTANCE |CONVERT_TWIPS },\
+ { OUString(UNO_NAME_BOTTOM_BORDER_DISTANCE), RES_BOX, cppu::UnoType<sal_Int32>::get(), 0, BOTTOM_BORDER_DISTANCE|CONVERT_TWIPS },\
+ { OUString(UNO_NAME_PARA_IS_HYPHENATION), RES_PARATR_HYPHENZONE, cppu::UnoType<bool>::get(), PropertyAttribute::MAYBEVOID, MID_IS_HYPHEN },\
+ { OUString(UNO_NAME_PARA_HYPHENATION_NO_CAPS), RES_PARATR_HYPHENZONE, cppu::UnoType<bool>::get(), PropertyAttribute::MAYBEVOID, MID_HYPHEN_NO_CAPS },\
+ { OUString(UNO_NAME_PARA_HYPHENATION_MAX_LEADING_CHARS), RES_PARATR_HYPHENZONE, cppu::UnoType<sal_Int16>::get(), PropertyAttribute::MAYBEVOID, MID_HYPHEN_MIN_LEAD },\
+ { OUString(UNO_NAME_PARA_HYPHENATION_MAX_TRAILING_CHARS), RES_PARATR_HYPHENZONE, cppu::UnoType<sal_Int16>::get(), PropertyAttribute::MAYBEVOID, MID_HYPHEN_MIN_TRAIL },\
+ { OUString(UNO_NAME_PARA_HYPHENATION_MAX_HYPHENS), RES_PARATR_HYPHENZONE, cppu::UnoType<sal_Int16>::get(), PropertyAttribute::MAYBEVOID, MID_HYPHEN_MAX_HYPHENS},\
+ { OUString(UNO_NAME_NUMBERING_STYLE_NAME), RES_PARATR_NUMRULE, cppu::UnoType<OUString>::get(), PropertyAttribute::MAYBEVOID, 0},\
+ { OUString(UNO_NAME_PARA_USER_DEFINED_ATTRIBUTES), RES_UNKNOWNATR_CONTAINER, cppu::UnoType<css::container::XNameContainer>::get(), PropertyAttribute::MAYBEVOID, 0 },\
+ { OUString(UNO_NAME_PARA_SHADOW_FORMAT), RES_SHADOW, cppu::UnoType<css::table::ShadowFormat>::get(), PROPERTY_NONE, CONVERT_TWIPS},\
+ { OUString(UNO_NAME_CHAR_COMBINE_IS_ON), RES_CHRATR_TWO_LINES, cppu::UnoType<bool>::get(), PROPERTY_NONE, MID_TWOLINES},\
+ { OUString(UNO_NAME_CHAR_COMBINE_PREFIX), RES_CHRATR_TWO_LINES, cppu::UnoType<OUString>::get(), PROPERTY_NONE, MID_START_BRACKET},\
+ { OUString(UNO_NAME_CHAR_COMBINE_SUFFIX), RES_CHRATR_TWO_LINES, cppu::UnoType<OUString>::get(), PROPERTY_NONE, MID_END_BRACKET},\
+ { OUString(UNO_NAME_CHAR_EMPHASIS), RES_CHRATR_EMPHASIS_MARK, cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE, MID_EMPHASIS},\
+ { OUString(UNO_NAME_PARA_IS_HANGING_PUNCTUATION), RES_PARATR_HANGINGPUNCTUATION, cppu::UnoType<bool>::get(), PROPERTY_NONE ,0 },\
+ { OUString(UNO_NAME_PARA_IS_CHARACTER_DISTANCE), RES_PARATR_SCRIPTSPACE, cppu::UnoType<bool>::get(), PROPERTY_NONE ,0 },\
+ { OUString(UNO_NAME_PARA_IS_FORBIDDEN_RULES), RES_PARATR_FORBIDDEN_RULES, cppu::UnoType<bool>::get(), PROPERTY_NONE ,0 },\
+ { OUString(UNO_NAME_PARA_VERT_ALIGNMENT), RES_PARATR_VERTALIGN, cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE , 0 },\
+ { OUString(UNO_NAME_CHAR_ROTATION), RES_CHRATR_ROTATE, cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE, MID_ROTATE },\
+ { OUString(UNO_NAME_CHAR_ROTATION_IS_FIT_TO_LINE), RES_CHRATR_ROTATE, cppu::UnoType<bool>::get(), PROPERTY_NONE, MID_FITTOLINE },\
+ { OUString(UNO_NAME_CHAR_SCALE_WIDTH), RES_CHRATR_SCALEW, cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE, 0 },\
+ { OUString(UNO_NAME_CHAR_RELIEF), RES_CHRATR_RELIEF, cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE, MID_RELIEF },\
+ PROP_DIFF_FONTHEIGHT\
+ { OUString(UNO_NAME_FOLLOW_STYLE), FN_UNO_FOLLOW_STYLE, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},\
+ { OUString(UNO_NAME_IS_PHYSICAL), FN_UNO_IS_PHYSICAL, cppu::UnoType<bool>::get(), PropertyAttribute::READONLY, 0},\
+ { OUString(UNO_NAME_IS_AUTO_UPDATE), FN_UNO_IS_AUTO_UPDATE, cppu::UnoType<bool>::get(), PROPERTY_NONE, 0},\
+ { OUString(UNO_NAME_DISPLAY_NAME), FN_UNO_DISPLAY_NAME, cppu::UnoType<OUString>::get(), PropertyAttribute::READONLY, 0},\
+ { OUString(UNO_NAME_CATEGORY), FN_UNO_CATEGORY, cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE , 0 },\
+ { OUString(UNO_NAME_WRITING_MODE), RES_FRAMEDIR, cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE, 0 },\
+ { OUString(UNO_NAME_PARA_IS_CONNECT_BORDER), RES_PARATR_CONNECT_BORDER, cppu::UnoType<bool>::get(), PropertyAttribute::MAYBEVOID, 0},\
+ { OUString(UNO_NAME_SNAP_TO_GRID), RES_PARATR_SNAPTOGRID, cppu::UnoType<bool>::get(), PropertyAttribute::MAYBEVOID, 0 }, \
+ { OUString(UNO_NAME_OUTLINE_LEVEL), RES_PARATR_OUTLINELEVEL,cppu::UnoType<sal_Int16>::get(), PropertyAttribute::MAYBEVOID, 0}, \
+ { OUString(UNO_NAME_HIDDEN), FN_UNO_HIDDEN, cppu::UnoType<bool>::get(), PROPERTY_NONE, 0}, \
+ { OUString(UNO_NAME_STYLE_INTEROP_GRAB_BAG), FN_UNO_STYLE_INTEROP_GRAB_BAG, cppu::UnoType< cppu::UnoSequenceType<css::beans::PropertyValue> >::get(), PROPERTY_NONE, 0}, \
+ { OUString(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 \
+ { OUString(UNO_NAME_CHAR_BACK_COLOR), RES_CHRATR_BACKGROUND, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE ,MID_BACK_COLOR }, \
+ { OUString(UNO_NAME_CHAR_COLOR), RES_CHRATR_COLOR, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE, 0}, \
+ { OUString(UNO_NAME_CHAR_TRANSPARENCE), RES_CHRATR_COLOR, cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE, MID_COLOR_ALPHA }, \
+ { OUString(UNO_NAME_CHAR_CONTOURED), RES_CHRATR_CONTOUR, cppu::UnoType<bool>::get() , PROPERTY_NONE, 0}, \
+ { OUString(UNO_NAME_CHAR_EMPHASIS), RES_CHRATR_EMPHASIS_MARK, cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE, MID_EMPHASIS}, \
+ { OUString(UNO_NAME_CHAR_ESCAPEMENT), RES_CHRATR_ESCAPEMENT, cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE, MID_ESC }, \
+ { OUString(UNO_NAME_CHAR_FONT_NAME), RES_CHRATR_FONT, cppu::UnoType<OUString>::get(), PropertyAttribute::MAYBEVOID, MID_FONT_FAMILY_NAME }, \
+ { OUString(UNO_NAME_CHAR_HEIGHT), RES_CHRATR_FONTSIZE , cppu::UnoType<float>::get(), PropertyAttribute::MAYBEVOID, MID_FONTHEIGHT|CONVERT_TWIPS}, \
+ { OUString(UNO_NAME_CHAR_POSTURE), RES_CHRATR_POSTURE , cppu::UnoType<css::awt::FontSlant>::get(), PropertyAttribute::MAYBEVOID, MID_POSTURE}, \
+ { OUString(UNO_NAME_CHAR_SHADOWED), RES_CHRATR_SHADOWED , cppu::UnoType<bool>::get() , PROPERTY_NONE, 0}, \
+ { OUString(UNO_NAME_CHAR_STRIKEOUT), RES_CHRATR_CROSSEDOUT, cppu::UnoType<sal_Int16>::get(), PropertyAttribute::MAYBEVOID, MID_CROSS_OUT}, \
+ { OUString(UNO_NAME_CHAR_UNDERLINE_COLOR), RES_CHRATR_UNDERLINE , cppu::UnoType<sal_Int32>::get(), PropertyAttribute::MAYBEVOID, MID_TL_COLOR}, \
+ { OUString(UNO_NAME_CHAR_WEIGHT), RES_CHRATR_WEIGHT , cppu::UnoType<float>::get(), PropertyAttribute::MAYBEVOID, MID_WEIGHT}, \
+ { OUString(UNO_NAME_NUMBERING_LEVEL), RES_PARATR_LIST_LEVEL,cppu::UnoType<sal_Int16>::get(), PropertyAttribute::MAYBEVOID, 0}, \
+ { OUString(UNO_NAME_CHAR_UNDERLINE), RES_CHRATR_UNDERLINE , cppu::UnoType<sal_Int16>::get(), PropertyAttribute::MAYBEVOID, MID_TL_STYLE}, \
+ { OUString(UNO_NAME_NUMBERING_RULES), RES_PARATR_NUMRULE,cppu::UnoType<sal_Int16>::get(), PropertyAttribute::MAYBEVOID, CONVERT_TWIPS}, \
+ { OUString(UNO_NAME_PARA_ADJUST), RES_PARATR_ADJUST, cppu::UnoType<sal_Int16>::get(), PropertyAttribute::MAYBEVOID, MID_PARA_ADJUST}, \
+ { OUString(UNO_NAME_PARA_BOTTOM_MARGIN), RES_UL_SPACE, cppu::UnoType<sal_Int32>::get(), PropertyAttribute::MAYBEVOID, MID_LO_MARGIN|CONVERT_TWIPS}, \
+ { OUString(UNO_NAME_PARA_FIRST_LINE_INDENT), RES_LR_SPACE, cppu::UnoType<sal_Int32>::get(), PropertyAttribute::MAYBEVOID, MID_FIRST_LINE_INDENT|CONVERT_TWIPS}, \
+ { OUString(UNO_NAME_PARA_LEFT_MARGIN), RES_LR_SPACE, cppu::UnoType<sal_Int32>::get(), PropertyAttribute::MAYBEVOID, MID_TXT_LMARGIN|CONVERT_TWIPS}, \
+ { OUString(UNO_NAME_PARA_LINE_SPACING), RES_PARATR_LINESPACING, cppu::UnoType<css::style::LineSpacing>::get(), PropertyAttribute::MAYBEVOID, CONVERT_TWIPS}, \
+ { OUString(UNO_NAME_PARA_RIGHT_MARGIN), RES_LR_SPACE, cppu::UnoType<sal_Int32>::get(), PropertyAttribute::MAYBEVOID, MID_R_MARGIN|CONVERT_TWIPS}, \
+ { OUString(UNO_NAME_TABSTOPS), RES_PARATR_TABSTOP, cppu::UnoType< cppu::UnoSequenceType<css::style::TabStop> >::get(), PropertyAttribute::MAYBEVOID, CONVERT_TWIPS}, \
+
+#define FILL_PROPERTIES_SW_BMP \
+ { OUString(UNO_NAME_SW_FILLBMP_LOGICAL_SIZE), XATTR_FILLBMP_SIZELOG, cppu::UnoType<bool>::get(), 0, 0}, \
+ { OUString(UNO_NAME_SW_FILLBMP_OFFSET_X), XATTR_FILLBMP_TILEOFFSETX, cppu::UnoType<sal_Int32>::get(), 0, 0}, \
+ { OUString(UNO_NAME_SW_FILLBMP_OFFSET_Y), XATTR_FILLBMP_TILEOFFSETY, cppu::UnoType<sal_Int32>::get(), 0, 0}, \
+ { OUString(UNO_NAME_SW_FILLBMP_POSITION_OFFSET_X), XATTR_FILLBMP_POSOFFSETX, cppu::UnoType<sal_Int32>::get(), 0, 0}, \
+ { OUString(UNO_NAME_SW_FILLBMP_POSITION_OFFSET_Y), XATTR_FILLBMP_POSOFFSETY, cppu::UnoType<sal_Int32>::get(), 0, 0}, \
+ { OUString(UNO_NAME_SW_FILLBMP_RECTANGLE_POINT), XATTR_FILLBMP_POS, cppu::UnoType<css::drawing::RectanglePoint>::get(), 0, 0}, \
+ { OUString(UNO_NAME_SW_FILLBMP_SIZE_X), XATTR_FILLBMP_SIZEX, cppu::UnoType<sal_Int32>::get(), 0, 0, PropertyMoreFlags::METRIC_ITEM}, \
+ { OUString(UNO_NAME_SW_FILLBMP_SIZE_Y), XATTR_FILLBMP_SIZEY, cppu::UnoType<sal_Int32>::get(), 0, 0, PropertyMoreFlags::METRIC_ITEM}, \
+ { OUString(UNO_NAME_SW_FILLBMP_STRETCH), XATTR_FILLBMP_STRETCH, cppu::UnoType<bool>::get(), 0, 0}, \
+ { OUString(UNO_NAME_SW_FILLBMP_TILE), XATTR_FILLBMP_TILE, cppu::UnoType<bool>::get(), 0, 0},\
+ { OUString(UNO_NAME_SW_FILLBMP_MODE), OWN_ATTR_FILLBMP_MODE, cppu::UnoType<drawing::BitmapMode>::get(), 0, 0}, \
+
+#define FILL_PROPERTIES_SW_DEFAULTS \
+ { OUString(UNO_NAME_SW_FILLCOLOR), XATTR_FILLCOLOR, cppu::UnoType<sal_Int32>::get(), 0, 0}, \
+
+#define FILL_PROPERTIES_SW \
+ FILL_PROPERTIES_SW_BMP \
+ FILL_PROPERTIES_SW_DEFAULTS \
+ { OUString(UNO_NAME_SW_FILLBACKGROUND), XATTR_FILLBACKGROUND, cppu::UnoType<bool>::get(), 0, 0}, \
+ { OUString(UNO_NAME_SW_FILLBITMAP), XATTR_FILLBITMAP, cppu::UnoType<css::awt::XBitmap>::get(), 0, MID_BITMAP}, \
+ { OUString(UNO_NAME_SW_FILLBITMAPURL), XATTR_FILLBITMAP, cppu::UnoType<OUString>::get(), 0, MID_BITMAP }, \
+ { OUString(UNO_NAME_SW_FILLBITMAPNAME), XATTR_FILLBITMAP, cppu::UnoType<OUString>::get(), 0, MID_NAME }, \
+ { OUString(UNO_NAME_SW_FILLGRADIENTSTEPCOUNT), XATTR_GRADIENTSTEPCOUNT, cppu::UnoType<sal_Int16>::get(), 0, 0}, \
+ { OUString(UNO_NAME_SW_FILLGRADIENT), XATTR_FILLGRADIENT, cppu::UnoType<css::awt::Gradient>::get(), 0, MID_FILLGRADIENT}, \
+ { OUString(UNO_NAME_SW_FILLGRADIENTNAME), XATTR_FILLGRADIENT, cppu::UnoType<OUString>::get(), 0, MID_NAME }, \
+ { OUString(UNO_NAME_SW_FILLHATCH), XATTR_FILLHATCH, cppu::UnoType<css::drawing::Hatch>::get(), 0, MID_FILLHATCH}, \
+ { OUString(UNO_NAME_SW_FILLHATCHNAME), XATTR_FILLHATCH, cppu::UnoType<OUString>::get(), 0, MID_NAME }, \
+ { OUString(UNO_NAME_SW_FILLSTYLE), XATTR_FILLSTYLE, cppu::UnoType<css::drawing::FillStyle>::get(), 0, 0}, \
+ { OUString(UNO_NAME_SW_FILL_TRANSPARENCE), XATTR_FILLTRANSPARENCE, cppu::UnoType<sal_Int16>::get(), 0, 0}, \
+ { OUString(UNO_NAME_SW_FILLTRANSPARENCEGRADIENT), XATTR_FILLFLOATTRANSPARENCE, cppu::UnoType<css::awt::Gradient>::get(), 0, MID_FILLGRADIENT}, \
+ { OUString(UNO_NAME_SW_FILLTRANSPARENCEGRADIENTNAME), XATTR_FILLFLOATTRANSPARENCE, cppu::UnoType<OUString>::get(), 0, MID_NAME }, \
+ { OUString(UNO_NAME_SW_FILLCOLOR_2), XATTR_SECONDARYFILLCOLOR, cppu::UnoType<sal_Int32>::get(), 0, 0}, \
+
+#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 000000000..a70466608
--- /dev/null
+++ b/sw/source/core/unocore/unoobj.cxx
@@ -0,0 +1,2948 @@
+/* -*- 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 <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 <swundo.hxx>
+#include <rootfrm.hxx>
+#include <paratr.hxx>
+#include <pam.hxx>
+#include <shellio.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 <unotext.hxx>
+#include <com/sun/star/text/TextMarkupType.hpp>
+#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/servicehelper.hxx>
+#include <comphelper/profilezone.hxx>
+
+using namespace ::com::sun::star;
+
+// Helper classes
+SwUnoInternalPaM::SwUnoInternalPaM(SwDoc& rDoc) :
+ SwPaM(rDoc.GetNodes())
+{
+}
+
+SwUnoInternalPaM::~SwUnoInternalPaM()
+{
+ while( GetNext() != this)
+ {
+ 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_bExportPargraphNumbering = 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();
+
+ 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 *const pDoc, const uno::Any & rValue, SfxItemSet & rSet)
+{
+ SwDocShell *const pDocSh = pDoc->GetDocShell();
+ if(pDocSh)
+ {
+ 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 *const pDoc = rPaM.GetDoc();
+ SwDocShell *const pDocSh = pDoc->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(pDoc);
+ pDoc->GetIDocumentUndoRedo().StartUndo( SwUndoId::START, nullptr );
+ SwPaM *pTmpCursor = &rPaM;
+ do {
+ pDoc->SetTextFormatColl(*pTmpCursor, pLocal);
+ pTmpCursor = pTmpCursor->GetNext();
+ } while ( pTmpCursor != &rPaM );
+ pDoc->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;
+ const SfxPoolItem* pItem;
+ if(SfxItemState::SET == rSet.GetItemState( RES_PAGEDESC, true, &pItem ) )
+ {
+ pNewDesc.reset(new SwFormatPageDesc(
+ *static_cast<const 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(*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 : static_cast<sal_uInt16>(nTmp));
+ SwDoc* pDoc = rCursor.GetDoc();
+ UnoActionContext aAction(pDoc);
+
+ if( rCursor.GetNext() != &rCursor ) // MultiSelection?
+ {
+ pDoc->GetIDocumentUndoRedo().StartUndo( SwUndoId::START, nullptr );
+ SwPamRanges aRangeArr( rCursor );
+ SwPaM aPam( *rCursor.GetPoint() );
+ for( size_t n = 0; n < aRangeArr.Count(); ++n )
+ {
+ pDoc->SetNumRuleStart(*aRangeArr.SetPam( n, aPam ).GetPoint());
+ pDoc->SetNodeNumStart(*aRangeArr.SetPam( n, aPam ).GetPoint(),
+ nStt );
+ }
+ pDoc->GetIDocumentUndoRedo().EndUndo( SwUndoId::END, nullptr );
+ }
+ else
+ {
+ pDoc->SetNumRuleStart( *rCursor.GetPoint());
+ pDoc->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
+ SfxItemSet aSet(rPam.GetDoc()->GetAttrPool(),
+ svl::Items<RES_TXTATR_CHARFMT, RES_TXTATR_CHARFMT>{});
+ 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 *const pDoc = rPam.GetDoc();
+ //default character style must not be set as default format
+ SwDocStyleSheet *const pStyle = static_cast<SwDocStyleSheet*>(
+ pDoc->GetDocShell()
+ ->GetStyleSheetPool()->Find(sStyle, SfxStyleFamily::Char));
+ if (!pStyle || pStyle->GetCharFormat() == pDoc->GetDfltCharFormat())
+ {
+ throw lang::IllegalArgumentException();
+ }
+ std::unique_ptr<SwFormatDrop> pDrop;
+ SfxPoolItem const* pItem(nullptr);
+ if (SfxItemState::SET ==
+ rItemSet.GetItemState(RES_PARATR_DROP, true, &pItem))
+ {
+ pDrop.reset(new SwFormatDrop(*static_cast<const SwFormatDrop*>(pItem)));
+ }
+ if (!pDrop)
+ {
+ pDrop.reset(new SwFormatDrop);
+ }
+ const rtl::Reference<SwDocStyleSheet> xStyle(new SwDocStyleSheet(*pStyle));
+ pDrop->SetCharFormat(xStyle->GetCharFormat());
+ rItemSet.Put(*pDrop);
+}
+
+static void
+lcl_setRubyCharstyle(SfxItemSet & rItemSet, uno::Any const& rValue)
+{
+ OUString sTmp;
+ if (!(rValue >>= sTmp))
+ {
+ throw lang::IllegalArgumentException();
+ }
+
+ std::unique_ptr<SwFormatRuby> pRuby;
+ const SfxPoolItem* pItem;
+ if (SfxItemState::SET ==
+ rItemSet.GetItemState(RES_TXTATR_CJK_RUBY, true, &pItem))
+ {
+ pRuby.reset(new SwFormatRuby(*static_cast<const 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(*pRuby);
+}
+
+bool
+SwUnoCursorHelper::SetCursorPropertyValue(
+ SfxItemPropertySimpleEntry 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.GetNode().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)
+ {
+ uno::Sequence<beans::NamedValue> props;
+ if (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());
+ SfxItemSet items( rPam.GetDoc()->GetAttrPool(),
+ svl::Items<RES_CHRATR_BEGIN, RES_CHRATR_END-1,
+ RES_TXTATR_CHARFMT, RES_TXTATR_CHARFMT,
+ RES_UNKNOWNATR_BEGIN, RES_UNKNOWNATR_END-1>{} );
+
+ for (beans::NamedValue const & prop : std::as_const(props))
+ {
+ SfxItemPropertySimpleEntry 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);
+ }
+
+ SwFormatAutoFormat item(RES_PARATR_LIST_AUTOFMT);
+ // TODO: for ODF export we'd need to add it to the autostyle pool
+ // 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(std::make_shared<SfxItemSet>(items));
+ 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 sal_uLong nSttNd = pTmpCursor->Start()->nNode.GetIndex();
+ const sal_uLong nEndNd = pTmpCursor->End()->nNode.GetIndex();
+
+ if( nEndNd - nSttNd >= nMaxLookup )
+ {
+ pFormat = nullptr;
+ break;
+ }
+
+ const SwNodes& rNds = rPaM.GetDoc()->GetNodes();
+ for( sal_uLong 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;
+}
+
+class SwXTextCursor::Impl
+{
+
+public:
+ const SfxItemPropertySet & m_rPropSet;
+ const CursorType m_eType;
+ const uno::Reference< text::XText > m_xParentText;
+ sw::UnoCursorPointer m_pUnoCursor;
+
+ Impl( SwDoc & rDoc,
+ const CursorType eType,
+ uno::Reference<text::XText> const & xParent,
+ SwPosition const& rPoint, SwPosition const*const pMark)
+ : m_rPropSet(*aSwMapProvider.GetPropertySet(PROPERTY_MAP_TEXT_CURSOR))
+ , m_eType(eType)
+ , m_xParentText(xParent)
+ , m_pUnoCursor(rDoc.CreateUnoCursor(rPoint))
+ {
+ if (pMark)
+ {
+ m_pUnoCursor->SetMark();
+ *m_pUnoCursor->GetMark() = *pMark;
+ }
+ }
+
+ SwUnoCursor& GetCursorOrThrow() {
+ if(!m_pUnoCursor)
+ throw uno::RuntimeException("SwXTextCursor: disposed or invalid", nullptr);
+ return *m_pUnoCursor;
+ }
+};
+
+SwUnoCursor& SwXTextCursor::GetCursor()
+ { return *m_pImpl->m_pUnoCursor; }
+
+SwPaM const* SwXTextCursor::GetPaM() const
+ { return m_pImpl->m_pUnoCursor.get(); }
+
+SwPaM* SwXTextCursor::GetPaM()
+ { return m_pImpl->m_pUnoCursor.get(); }
+
+SwDoc const* SwXTextCursor::GetDoc() const
+ { return m_pImpl->m_pUnoCursor ? m_pImpl->m_pUnoCursor->GetDoc() : nullptr; }
+
+SwDoc* SwXTextCursor::GetDoc()
+ { return m_pImpl->m_pUnoCursor ? m_pImpl->m_pUnoCursor->GetDoc() : nullptr; }
+
+SwXTextCursor::SwXTextCursor(
+ SwDoc & rDoc,
+ uno::Reference< text::XText > const& xParent,
+ const CursorType eType,
+ const SwPosition& rPos,
+ SwPosition const*const pMark)
+ : m_pImpl( new Impl(rDoc, eType, xParent, rPos, pMark) )
+{
+}
+
+SwXTextCursor::SwXTextCursor(uno::Reference< text::XText > const& xParent,
+ SwPaM const& rSourceCursor, const CursorType eType)
+ : m_pImpl( new Impl(*rSourceCursor.GetDoc(), eType,
+ xParent, *rSourceCursor.GetPoint(),
+ rSourceCursor.HasMark() ? rSourceCursor.GetMark() : nullptr) )
+{
+}
+
+SwXTextCursor::~SwXTextCursor()
+{
+}
+
+void SwXTextCursor::DeleteAndInsert(const OUString& rText,
+ const bool bForceExpandHints)
+{
+ auto pUnoCursor = static_cast<SwCursor*>(m_pImpl->m_pUnoCursor.get());
+ if (pUnoCursor)
+ {
+ // Start/EndAction
+ SwDoc* pDoc = pUnoCursor->GetDoc();
+ UnoActionContext aAction(pDoc);
+ const sal_Int32 nTextLen = rText.getLength();
+ pDoc->GetIDocumentUndoRedo().StartUndo(SwUndoId::INSERT, nullptr);
+ auto pCurrent = pUnoCursor;
+ do
+ {
+ if (pCurrent->HasMark())
+ {
+ pDoc->getIDocumentContentOperations().DeleteAndJoin(*pCurrent);
+ }
+ if(nTextLen)
+ {
+ const bool bSuccess(
+ SwUnoCursorHelper::DocInsertStringSplitCR(
+ *pDoc, *pCurrent, rText, bForceExpandHints ) );
+ OSL_ENSURE( bSuccess, "Doc->Insert(Str) failed." );
+
+ SwUnoCursorHelper::SelectPam(*pUnoCursor, true);
+ pCurrent->Left(rText.getLength());
+ }
+ pCurrent = pCurrent->GetNext();
+ } while (pCurrent != pUnoCursor);
+ pDoc->GetIDocumentUndoRedo().EndUndo(SwUndoId::INSERT, nullptr);
+ }
+}
+
+namespace {
+
+enum ForceIntoMetaMode { META_CHECK_BOTH, META_INIT_START, META_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;
+}
+
+bool SwXTextCursor::IsAtEndOfMeta() const
+{
+ if (CursorType::Meta == m_pImpl->m_eType)
+ {
+ auto pCursor( m_pImpl->m_pUnoCursor );
+ SwXMeta const*const pXMeta(
+ dynamic_cast<SwXMeta*>(m_pImpl->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;
+}
+
+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"
+ };
+}
+
+namespace
+{
+ class theSwXTextCursorUnoTunnelId : public rtl::Static< UnoTunnelIdInit, theSwXTextCursorUnoTunnelId > {};
+}
+
+const uno::Sequence< sal_Int8 > & SwXTextCursor::getUnoTunnelId()
+{
+ return theSwXTextCursorUnoTunnelId::get().getSeq();
+}
+
+sal_Int64 SAL_CALL
+SwXTextCursor::getSomething(const uno::Sequence< sal_Int8 >& rId)
+{
+ const sal_Int64 nRet( ::sw::UnoTunnelImpl<SwXTextCursor>(rId, this) );
+ return nRet ? nRet : OTextCursorHelper::getSomething(rId);
+}
+
+void SAL_CALL SwXTextCursor::collapseToStart()
+{
+ SolarMutexGuard aGuard;
+
+ SwUnoCursor & rUnoCursor( m_pImpl->GetCursorOrThrow() );
+
+ if (rUnoCursor.HasMark())
+ {
+ if (*rUnoCursor.GetPoint() > *rUnoCursor.GetMark())
+ {
+ rUnoCursor.Exchange();
+ }
+ rUnoCursor.DeleteMark();
+ }
+}
+
+void SAL_CALL SwXTextCursor::collapseToEnd()
+{
+ SolarMutexGuard aGuard;
+
+ SwUnoCursor & rUnoCursor( m_pImpl->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_pImpl->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( m_pImpl->GetCursorOrThrow() );
+
+ SwUnoCursorHelper::SelectPam(rUnoCursor, Expand);
+ bool bRet = rUnoCursor.Left( nCount);
+ if (CursorType::Meta == m_pImpl->m_eType)
+ {
+ bRet = lcl_ForceIntoMeta(rUnoCursor, m_pImpl->m_xParentText,
+ META_CHECK_BOTH)
+ && bRet;
+ }
+ return bRet;
+}
+
+sal_Bool SAL_CALL
+SwXTextCursor::goRight(sal_Int16 nCount, sal_Bool Expand)
+{
+ SolarMutexGuard aGuard;
+
+ SwUnoCursor & rUnoCursor( m_pImpl->GetCursorOrThrow() );
+
+ SwUnoCursorHelper::SelectPam(rUnoCursor, Expand);
+ bool bRet = rUnoCursor.Right(nCount);
+ if (CursorType::Meta == m_pImpl->m_eType)
+ {
+ bRet = lcl_ForceIntoMeta(rUnoCursor, m_pImpl->m_xParentText,
+ META_CHECK_BOTH)
+ && bRet;
+ }
+ return bRet;
+}
+
+void SAL_CALL
+SwXTextCursor::gotoStart(sal_Bool Expand)
+{
+ SolarMutexGuard aGuard;
+ comphelper::ProfileZone aZone("gotoStart");
+
+ SwUnoCursor & rUnoCursor( m_pImpl->GetCursorOrThrow() );
+
+ SwUnoCursorHelper::SelectPam(rUnoCursor, Expand);
+ if (CursorType::Body == m_pImpl->m_eType)
+ {
+ rUnoCursor.Move( fnMoveBackward, GoInDoc );
+ //check, that the cursor is not in a table
+ SwTableNode * pTableNode = rUnoCursor.GetNode().FindTableNode();
+ SwContentNode * pCNode = nullptr;
+ while (pTableNode)
+ {
+ rUnoCursor.GetPoint()->nNode = *pTableNode->EndOfSectionNode();
+ pCNode = GetDoc()->GetNodes().GoNext(&rUnoCursor.GetPoint()->nNode);
+ pTableNode = pCNode ? pCNode->FindTableNode() : nullptr;
+ }
+ if (pCNode)
+ {
+ rUnoCursor.GetPoint()->nContent.Assign(pCNode, 0);
+ }
+ SwStartNode const*const pTmp =
+ rUnoCursor.GetNode().StartOfSectionNode();
+ if (pTmp->IsSectionNode())
+ {
+ SwSectionNode const*const pSectionStartNode =
+ static_cast<SwSectionNode const*>(pTmp);
+ if (pSectionStartNode->GetSection().IsHiddenFlag())
+ {
+ pCNode = GetDoc()->GetNodes().GoNextSection(
+ &rUnoCursor.GetPoint()->nNode, true, false);
+ if (pCNode)
+ {
+ rUnoCursor.GetPoint()->nContent.Assign(pCNode, 0);
+ }
+ }
+ }
+ }
+ else if ( (CursorType::Frame == m_pImpl->m_eType)
+ || (CursorType::TableText == m_pImpl->m_eType)
+ || (CursorType::Header == m_pImpl->m_eType)
+ || (CursorType::Footer == m_pImpl->m_eType)
+ || (CursorType::Footnote== m_pImpl->m_eType)
+ || (CursorType::Redline == m_pImpl->m_eType))
+ {
+ rUnoCursor.MoveSection(GoCurrSection, fnSectionStart);
+ }
+ else if (CursorType::Meta == m_pImpl->m_eType)
+ {
+ lcl_ForceIntoMeta(rUnoCursor, m_pImpl->m_xParentText, META_INIT_START);
+ }
+}
+
+void SAL_CALL
+SwXTextCursor::gotoEnd(sal_Bool Expand)
+{
+ SolarMutexGuard aGuard;
+ comphelper::ProfileZone aZone("gotoEnd");
+
+ SwUnoCursor & rUnoCursor( m_pImpl->GetCursorOrThrow() );
+
+ SwUnoCursorHelper::SelectPam(rUnoCursor, Expand);
+ if (CursorType::Body == m_pImpl->m_eType)
+ {
+ rUnoCursor.Move( fnMoveForward, GoInDoc );
+ }
+ else if ( (CursorType::Frame == m_pImpl->m_eType)
+ || (CursorType::TableText == m_pImpl->m_eType)
+ || (CursorType::Header == m_pImpl->m_eType)
+ || (CursorType::Footer == m_pImpl->m_eType)
+ || (CursorType::Footnote== m_pImpl->m_eType)
+ || (CursorType::Redline == m_pImpl->m_eType))
+ {
+ rUnoCursor.MoveSection( GoCurrSection, fnSectionEnd);
+ }
+ else if (CursorType::Meta == m_pImpl->m_eType)
+ {
+ lcl_ForceIntoMeta(rUnoCursor, m_pImpl->m_xParentText, META_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( m_pImpl->GetCursorOrThrow() );
+
+ uno::Reference<lang::XUnoTunnel> xRangeTunnel( xRange, uno::UNO_QUERY);
+ SwXTextRange* pRange = nullptr;
+ OTextCursorHelper* pCursor = nullptr;
+ if(xRangeTunnel.is())
+ {
+ pRange = ::sw::UnoTunnelGetImplementation<SwXTextRange>(xRangeTunnel);
+ pCursor =
+ ::sw::UnoTunnelGetImplementation<OTextCursorHelper>(xRangeTunnel);
+ }
+
+ 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_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:
+ ;
+ }
+
+ const SwStartNode* pOwnStartNode = rOwnCursor.GetNode().FindSttNodeByType(eSearchNodeType);
+ while ( pOwnStartNode != nullptr
+ && pOwnStartNode->IsSectionNode())
+ {
+ pOwnStartNode = pOwnStartNode->StartOfSectionNode();
+ }
+
+ const SwStartNode* pTmp =
+ pPam->GetNode().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_pImpl->m_eType)
+ {
+ SwPaM CopyPam(*pPam->GetMark(), *pPam->GetPoint());
+ const bool bNotForced( lcl_ForceIntoMeta(
+ CopyPam, m_pImpl->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));
+ }
+ }
+
+ // 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( m_pImpl->GetCursorOrThrow() );
+
+ const bool bRet =
+ rUnoCursor.IsStartWordWT( i18n::WordType::DICTIONARY_WORD );
+ return bRet;
+}
+
+sal_Bool SAL_CALL SwXTextCursor::isEndOfWord()
+{
+ SolarMutexGuard aGuard;
+
+ SwUnoCursor & rUnoCursor( m_pImpl->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( m_pImpl->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->nNode.GetNode();
+ sal_Int32 const nOldIndex = pPoint->nContent.GetIndex();
+
+ SwUnoCursorHelper::SelectPam(rUnoCursor, Expand);
+ // end of paragraph
+ if (rUnoCursor.GetContentNode() &&
+ (pPoint->nContent == rUnoCursor.GetContentNode()->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->nNode.GetNode() != pOldNode) ||
+ (pPoint->nContent.GetIndex() != nOldIndex);
+ if (bRet && (CursorType::Meta == m_pImpl->m_eType))
+ {
+ bRet = lcl_ForceIntoMeta(rUnoCursor, m_pImpl->m_xParentText,
+ META_CHECK_BOTH);
+ }
+
+ return bRet;
+}
+
+sal_Bool SAL_CALL
+SwXTextCursor::gotoPreviousWord(sal_Bool Expand)
+{
+ SolarMutexGuard aGuard;
+
+ SwUnoCursor & rUnoCursor( m_pImpl->GetCursorOrThrow() );
+
+ // white spaces create problems on the paragraph start
+ bool bRet = false;
+ SwPosition *const pPoint = rUnoCursor.GetPoint();
+ SwNode *const pOldNode = &pPoint->nNode.GetNode();
+ sal_Int32 const nOldIndex = pPoint->nContent.GetIndex();
+
+ SwUnoCursorHelper::SelectPam(rUnoCursor, Expand);
+ // start of paragraph?
+ if (pPoint->nContent == 0)
+ {
+ rUnoCursor.Left(1);
+ }
+ else
+ {
+ rUnoCursor.GoPrevWordWT( i18n::WordType::DICTIONARY_WORD );
+ if (pPoint->nContent == 0)
+ {
+ rUnoCursor.Left(1);
+ }
+ }
+
+ // return true if cursor has moved
+ bRet = (&pPoint->nNode.GetNode() != pOldNode) ||
+ (pPoint->nContent.GetIndex() != nOldIndex);
+ if (bRet && (CursorType::Meta == m_pImpl->m_eType))
+ {
+ bRet = lcl_ForceIntoMeta(rUnoCursor, m_pImpl->m_xParentText,
+ META_CHECK_BOTH);
+ }
+
+ return bRet;
+}
+
+sal_Bool SAL_CALL
+SwXTextCursor::gotoEndOfWord(sal_Bool Expand)
+{
+ SolarMutexGuard aGuard;
+
+ SwUnoCursor & rUnoCursor( m_pImpl->GetCursorOrThrow() );
+
+ bool bRet = false;
+ SwPosition *const pPoint = rUnoCursor.GetPoint();
+ SwNode & rOldNode = pPoint->nNode.GetNode();
+ sal_Int32 const nOldIndex = pPoint->nContent.GetIndex();
+
+ 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->nNode = rOldNode;
+ pPoint->nContent = nOldIndex;
+ }
+ else if (CursorType::Meta == m_pImpl->m_eType)
+ {
+ bRet = lcl_ForceIntoMeta(rUnoCursor, m_pImpl->m_xParentText,
+ META_CHECK_BOTH);
+ }
+
+ return bRet;
+}
+
+sal_Bool SAL_CALL
+SwXTextCursor::gotoStartOfWord(sal_Bool Expand)
+{
+ SolarMutexGuard aGuard;
+
+ SwUnoCursor & rUnoCursor( m_pImpl->GetCursorOrThrow() );
+
+ bool bRet = false;
+ SwPosition *const pPoint = rUnoCursor.GetPoint();
+ SwNode & rOldNode = pPoint->nNode.GetNode();
+ sal_Int32 const nOldIndex = pPoint->nContent.GetIndex();
+
+ 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->nNode = rOldNode;
+ pPoint->nContent = nOldIndex;
+ }
+ else if (CursorType::Meta == m_pImpl->m_eType)
+ {
+ bRet = lcl_ForceIntoMeta(rUnoCursor, m_pImpl->m_xParentText,
+ META_CHECK_BOTH);
+ }
+
+ return bRet;
+}
+
+sal_Bool SAL_CALL
+SwXTextCursor::isStartOfSentence()
+{
+ SolarMutexGuard aGuard;
+
+ SwUnoCursor & rUnoCursor( m_pImpl->GetCursorOrThrow() );
+
+ // start of paragraph?
+ bool bRet = rUnoCursor.GetPoint()->nContent == 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( m_pImpl->GetCursorOrThrow() );
+
+ // end of paragraph?
+ bool bRet = rUnoCursor.GetContentNode() &&
+ (rUnoCursor.GetPoint()->nContent == rUnoCursor.GetContentNode()->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( m_pImpl->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_pImpl->m_eType)
+ {
+ bRet = lcl_ForceIntoMeta(rUnoCursor, m_pImpl->m_xParentText,
+ META_CHECK_BOTH)
+ && bRet;
+ }
+ return bRet;
+}
+
+sal_Bool SAL_CALL
+SwXTextCursor::gotoPreviousSentence(sal_Bool Expand)
+{
+ SolarMutexGuard aGuard;
+
+ SwUnoCursor & rUnoCursor( m_pImpl->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_pImpl->m_eType)
+ {
+ bRet = lcl_ForceIntoMeta(rUnoCursor, m_pImpl->m_xParentText,
+ META_CHECK_BOTH)
+ && bRet;
+ }
+ return bRet;
+}
+
+sal_Bool SAL_CALL
+SwXTextCursor::gotoStartOfSentence(sal_Bool Expand)
+{
+ SolarMutexGuard aGuard;
+
+ SwUnoCursor & rUnoCursor( m_pImpl->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_pImpl->m_eType)
+ {
+ bRet = lcl_ForceIntoMeta(rUnoCursor, m_pImpl->m_xParentText,
+ META_CHECK_BOTH)
+ && bRet;
+ }
+ return bRet;
+}
+
+sal_Bool SAL_CALL
+SwXTextCursor::gotoEndOfSentence(sal_Bool Expand)
+{
+ SolarMutexGuard aGuard;
+
+ SwUnoCursor & rUnoCursor( m_pImpl->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_pImpl->m_eType)
+ {
+ bRet = lcl_ForceIntoMeta(rUnoCursor, m_pImpl->m_xParentText,
+ META_CHECK_BOTH)
+ && bRet;
+ }
+ return bRet;
+}
+
+sal_Bool SAL_CALL
+SwXTextCursor::isStartOfParagraph()
+{
+ SolarMutexGuard aGuard;
+
+ SwUnoCursor & rUnoCursor( m_pImpl->GetCursorOrThrow() );
+
+ const bool bRet = SwUnoCursorHelper::IsStartOfPara(rUnoCursor);
+ return bRet;
+}
+
+sal_Bool SAL_CALL
+SwXTextCursor::isEndOfParagraph()
+{
+ SolarMutexGuard aGuard;
+
+ SwUnoCursor & rUnoCursor( m_pImpl->GetCursorOrThrow() );
+
+ const bool bRet = SwUnoCursorHelper::IsEndOfPara(rUnoCursor);
+ return bRet;
+}
+
+sal_Bool SAL_CALL
+SwXTextCursor::gotoStartOfParagraph(sal_Bool Expand)
+{
+ SolarMutexGuard aGuard;
+
+ SwUnoCursor & rUnoCursor( m_pImpl->GetCursorOrThrow() );
+
+ if (CursorType::Meta == m_pImpl->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( m_pImpl->GetCursorOrThrow() );
+
+ if (CursorType::Meta == m_pImpl->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( m_pImpl->GetCursorOrThrow() );
+
+ if (CursorType::Meta == m_pImpl->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( m_pImpl->GetCursorOrThrow() );
+
+ if (CursorType::Meta == m_pImpl->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_pImpl->m_xParentText;
+}
+
+uno::Reference< text::XTextRange > SAL_CALL
+SwXTextCursor::getStart()
+{
+ SolarMutexGuard aGuard;
+
+ SwUnoCursor & rUnoCursor( m_pImpl->GetCursorOrThrow() );
+
+ uno::Reference< text::XTextRange > xRet;
+ SwPaM aPam(*rUnoCursor.Start());
+ const uno::Reference< text::XText > xParent = getText();
+ if (CursorType::Meta == m_pImpl->m_eType)
+ {
+ // return cursor to prevent modifying SwXTextRange for META
+ SwXTextCursor * const pXCursor(
+ new SwXTextCursor(*rUnoCursor.GetDoc(), xParent, CursorType::Meta,
+ *rUnoCursor.GetPoint()) );
+ pXCursor->gotoStart(false);
+ xRet = static_cast<text::XWordCursor*>(pXCursor);
+ }
+ else
+ {
+ xRet = new SwXTextRange(aPam, xParent);
+ }
+ return xRet;
+}
+
+uno::Reference< text::XTextRange > SAL_CALL
+SwXTextCursor::getEnd()
+{
+ SolarMutexGuard aGuard;
+
+ SwUnoCursor & rUnoCursor( m_pImpl->GetCursorOrThrow() );
+
+ uno::Reference< text::XTextRange > xRet;
+ SwPaM aPam(*rUnoCursor.End());
+ const uno::Reference< text::XText > xParent = getText();
+ if (CursorType::Meta == m_pImpl->m_eType)
+ {
+ // return cursor to prevent modifying SwXTextRange for META
+ SwXTextCursor * const pXCursor(
+ new SwXTextCursor(*rUnoCursor.GetDoc(), xParent, CursorType::Meta,
+ *rUnoCursor.GetPoint()) );
+ pXCursor->gotoEnd(false);
+ xRet = static_cast<text::XWordCursor*>(pXCursor);
+ }
+ else
+ {
+ xRet = new SwXTextRange(aPam, xParent);
+ }
+ return xRet;
+}
+
+OUString SAL_CALL SwXTextCursor::getString()
+{
+ SolarMutexGuard aGuard;
+
+ SwUnoCursor & rUnoCursor( m_pImpl->GetCursorOrThrow() );
+
+ OUString aText;
+ SwUnoCursorHelper::GetTextFromPam(rUnoCursor, aText);
+ return aText;
+}
+
+void SAL_CALL
+SwXTextCursor::setString(const OUString& aString)
+{
+ SolarMutexGuard aGuard;
+
+ m_pImpl->GetCursorOrThrow(); // just to check if valid
+
+ const bool bForceExpandHints( (CursorType::Meta == m_pImpl->m_eType)
+ && dynamic_cast<SwXMeta*>(m_pImpl->m_xParentText.get())
+ ->CheckForOwnMemberMeta(*GetPaM(), true) );
+ DeleteAndInsert(aString, bForceExpandHints);
+}
+
+uno::Any SwUnoCursorHelper::GetPropertyValue(
+ SwPaM& rPaM, const SfxItemPropertySet& rPropSet,
+ const OUString& rPropertyName)
+{
+ uno::Any aAny;
+ SfxItemPropertySimpleEntry const*const pEntry =
+ rPropSet.getPropertyMap().getByName(rPropertyName);
+
+ if (!pEntry)
+ {
+ throw beans::UnknownPropertyException(
+ "Unknown property: " + rPropertyName,
+ static_cast<cppu::OWeakObject *>(nullptr));
+ }
+
+ beans::PropertyState eTemp;
+ const bool bDone = SwUnoCursorHelper::getCursorPropertyValue(
+ *pEntry, rPaM, &aAny, eTemp );
+
+ if (!bDone)
+ {
+ SfxItemSet aSet(
+ rPaM.GetDoc()->GetAttrPool(),
+ svl::Items<
+ RES_CHRATR_BEGIN, RES_FRMATR_END - 1,
+ RES_UNKNOWNATR_CONTAINER, RES_UNKNOWNATR_CONTAINER>{});
+ 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)
+{
+ uno::Sequence< beans::PropertyValue > aValues(1);
+ aValues[0].Name = rPropertyName;
+ aValues[0].Value = rValue;
+ SetPropertyValues(rPaM, rPropSet, aValues, 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)
+{
+ if (!rPropertyValues.hasElements())
+ return;
+
+ SwDoc *const pDoc = rPaM.GetDoc();
+ OUString aUnknownExMsg, aPropertyVetoExMsg;
+
+ // Build set of attributes we want to fetch
+ const sal_uInt16 zero = 0;
+ SfxItemSet aItemSet(pDoc->GetAttrPool(), &zero);
+ std::vector<std::pair<const SfxItemPropertySimpleEntry*, const uno::Any&>> aEntries;
+ aEntries.reserve(rPropertyValues.getLength());
+ for (const auto& rPropVal : rPropertyValues)
+ {
+ const OUString &rPropertyName = rPropVal.Name;
+
+ SfxItemPropertySimpleEntry 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;
+ }
+ aItemSet.MergeRange(pEntry->nWID, pEntry->nWID);
+ aEntries.emplace_back(pEntry, rPropVal.Value);
+ }
+
+ if (!aEntries.empty())
+ {
+ // Fetch, overwrite, and re-set the attributes from the core
+
+ bool bPreviousPropertyCausesSideEffectsInNodes = false;
+ for (size_t i = 0; i < aEntries.size(); ++i)
+ {
+ SfxItemPropertySimpleEntry const*const pEntry = aEntries[i].first;
+ bool bPropertyCausesSideEffectsInNodes =
+ propertyCausesSideEffectsInNodes(pEntry->nWID);
+
+ // we need to get up-to-date item set from nodes
+ if (i == 0 || bPreviousPropertyCausesSideEffectsInNodes)
+ {
+ aItemSet.ClearItem();
+ SwUnoCursorHelper::GetCursorAttr(rPaM, aItemSet);
+ }
+
+ const uno::Any &rValue = aEntries[i].second;
+ // this can set some attributes in nodes' mpAttrSet
+ if (!SwUnoCursorHelper::SetCursorPropertyValue(*pEntry, rValue, rPaM, aItemSet))
+ rPropSet.setPropertyValue(*pEntry, rValue, aItemSet);
+
+ if (i + 1 == aEntries.size() || bPropertyCausesSideEffectsInNodes)
+ SwUnoCursorHelper::SetCursorAttr(rPaM, aItemSet, nAttrMode, false/*bTableMode*/);
+
+ bPreviousPropertyCausesSideEffectsInNodes = bPropertyCausesSideEffectsInNodes;
+ }
+ }
+
+ if (!aUnknownExMsg.isEmpty())
+ throw beans::UnknownPropertyException(aUnknownExMsg, static_cast<cppu::OWeakObject *>(nullptr));
+ if (!aPropertyVetoExMsg.isEmpty())
+ throw beans::PropertyVetoException(aPropertyVetoExMsg, static_cast<cppu::OWeakObject *>(nullptr));
+}
+
+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::unique_ptr<SfxItemSet> pSet;
+ std::unique_ptr<SfxItemSet> pSetParent;
+
+ for (sal_Int32 i = 0, nEnd = rPropertyNames.getLength(); i < nEnd; i++)
+ {
+ SfxItemPropertySimpleEntry 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)
+ {
+ 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],
+ static_cast<cppu::OWeakObject *>(nullptr));
+ }
+ }
+ 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 (!pSet)
+ {
+ switch ( eCaller )
+ {
+ case SW_PROPERTY_STATE_CALLER_SWX_TEXT_PORTION_TOLERANT:
+ case SW_PROPERTY_STATE_CALLER_SWX_TEXT_PORTION:
+ pSet.reset(
+ new SfxItemSet( rPaM.GetDoc()->GetAttrPool(),
+ svl::Items<RES_CHRATR_BEGIN, RES_TXTATR_END>{} ));
+ break;
+ case SW_PROPERTY_STATE_CALLER_SINGLE_VALUE_ONLY:
+ pSet.reset(
+ new SfxItemSet( rPaM.GetDoc()->GetAttrPool(),
+ {{pEntry->nWID, pEntry->nWID}} ));
+ break;
+ default:
+ pSet.reset( new SfxItemSet(
+ rPaM.GetDoc()->GetAttrPool(),
+ svl::Items<
+ RES_CHRATR_BEGIN, RES_FRMATR_END - 1,
+ RES_UNKNOWNATR_CONTAINER,
+ RES_UNKNOWNATR_CONTAINER>{}));
+ }
+ // #i63870#
+ SwUnoCursorHelper::GetCursorAttr( rPaM, *pSet );
+ }
+
+ pStates[i] = ( pSet->Count() )
+ ? rPropSet.getPropertyState( *pEntry, *pSet )
+ : beans::PropertyState_DEFAULT_VALUE;
+
+ //try again to find out if a value has been inherited
+ if( beans::PropertyState_DIRECT_VALUE == pStates[i] )
+ {
+ if (!pSetParent)
+ {
+ pSetParent = pSet->Clone( false );
+ // #i63870#
+ SwUnoCursorHelper::GetCursorAttr(
+ rPaM, *pSetParent, true, false );
+ }
+
+ pStates[i] = ( pSetParent->Count() )
+ ? rPropSet.getPropertyState( *pEntry, *pSetParent )
+ : 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,
+ std::set<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,
+ const OUString& rPropertyName)
+{
+ SwDoc & rDoc = *rPaM.GetDoc();
+ SfxItemPropertySimpleEntry const*const pEntry =
+ rPropSet.getPropertyMap().getByName(rPropertyName);
+ if (!pEntry)
+ {
+ throw beans::UnknownPropertyException(
+ "Unknown property: " + rPropertyName,
+ static_cast<cppu::OWeakObject *>(nullptr));
+ }
+
+ if (pEntry->nFlags & beans::PropertyAttribute::READONLY)
+ {
+ throw uno::RuntimeException(
+ "setPropertyToDefault: property is read-only: "
+ + rPropertyName, nullptr);
+ }
+
+ if (pEntry->nWID < RES_FRMATR_END)
+ {
+ std::set<sal_uInt16> aWhichIds;
+ aWhichIds.insert( 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,
+ const OUString& rPropertyName)
+{
+ SfxItemPropertySimpleEntry const*const pEntry =
+ rPropSet.getPropertyMap().getByName(rPropertyName);
+ if (!pEntry)
+ {
+ throw beans::UnknownPropertyException(
+ "Unknown property: " + rPropertyName, static_cast<cppu::OWeakObject *>(nullptr));
+ }
+
+ 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[] =
+ {
+ { OUString(UNO_NAME_IS_SKIP_HIDDEN_TEXT), FN_SKIP_HIDDEN_TEXT, cppu::UnoType<bool>::get(), PROPERTY_NONE, 0},
+ { OUString(UNO_NAME_IS_SKIP_PROTECTED_TEXT), FN_SKIP_PROTECTED_TEXT, cppu::UnoType<bool>::get(), PROPERTY_NONE, 0},
+ { OUString(), 0, css::uno::Type(), 0, 0 }
+ };
+ const uno::Reference< beans::XPropertySetInfo > xInfo =
+ m_pImpl->m_rPropSet.getPropertySetInfo();
+ // extend PropertySetInfo!
+ const uno::Sequence<beans::Property> aPropSeq = xInfo->getProperties();
+ return new SfxExtItemPropertySetInfo(
+ aCursorExtMap_Impl,
+ aPropSeq );
+ }();
+ return xRef;
+}
+
+void SAL_CALL
+SwXTextCursor::setPropertyValue(
+ const OUString& rPropertyName, const uno::Any& rValue)
+{
+ SolarMutexGuard aGuard;
+
+ SwUnoCursor & rUnoCursor( m_pImpl->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
+ {
+ SwUnoCursorHelper::SetPropertyValue(rUnoCursor,
+ m_pImpl->m_rPropSet, rPropertyName, rValue);
+ }
+}
+
+uno::Any SAL_CALL
+SwXTextCursor::getPropertyValue(const OUString& rPropertyName)
+{
+ SolarMutexGuard aGuard;
+
+ SwUnoCursor & rUnoCursor( m_pImpl->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_pImpl->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( m_pImpl->GetCursorOrThrow() );
+
+ const beans::PropertyState eRet = SwUnoCursorHelper::GetPropertyState(
+ rUnoCursor, m_pImpl->m_rPropSet, rPropertyName);
+ return eRet;
+}
+
+uno::Sequence< beans::PropertyState > SAL_CALL
+SwXTextCursor::getPropertyStates(
+ const uno::Sequence< OUString >& rPropertyNames)
+{
+ SolarMutexGuard aGuard;
+
+ SwUnoCursor & rUnoCursor( m_pImpl->GetCursorOrThrow() );
+
+ return SwUnoCursorHelper::GetPropertyStates(
+ rUnoCursor, m_pImpl->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( m_pImpl->GetCursorOrThrow() );
+
+ // a little lame to have to copy into this.
+ uno::Sequence< beans::PropertyValue > aPropertyValues( aValues.getLength() );
+ 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();
+ }
+ aPropertyValues[ i ].Name = aPropertyNames[ i ];
+ aPropertyValues[ i ].Value = aValues[ i ];
+ }
+ try
+ {
+ SwUnoCursorHelper::SetPropertyValues( rUnoCursor, m_pImpl->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.begin(),
+ [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, std::set<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( rWhichIds.end(), nId );
+ }
+ }
+}
+
+void SAL_CALL
+SwXTextCursor::setAllPropertiesToDefault()
+{
+ SolarMutexGuard aGuard;
+
+ SwUnoCursor & rUnoCursor( m_pImpl->GetCursorOrThrow() );
+
+ std::set<sal_uInt16> aParaWhichIds;
+ std::set<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( m_pImpl->GetCursorOrThrow() );
+
+ if ( rPropertyNames.hasElements() )
+ {
+ SwDoc & rDoc = *rUnoCursor.GetDoc();
+ std::set<sal_uInt16> aWhichIds;
+ std::set<sal_uInt16> aParaWhichIds;
+ for (const OUString& rName : rPropertyNames)
+ {
+ SfxItemPropertySimpleEntry const*const pEntry =
+ m_pImpl->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,
+ static_cast<cppu::OWeakObject *>(this));
+ }
+ if (pEntry->nFlags & beans::PropertyAttribute::READONLY)
+ {
+ throw uno::RuntimeException(
+ "setPropertiesToDefault: property is read-only: " + rName,
+ static_cast<cppu::OWeakObject *>(this));
+ }
+
+ 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( m_pImpl->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++)
+ {
+ SfxItemPropertySimpleEntry const*const pEntry =
+ m_pImpl->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)
+ {
+ continue;
+ }
+ throw beans::UnknownPropertyException(
+ "Unknown property: " + pNames[i],
+ static_cast<cppu::OWeakObject *>(nullptr));
+ }
+ 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( m_pImpl->GetCursorOrThrow() );
+
+ SwNode& node = rUnoCursor.GetNode();
+
+ SwTextNode* txtNode = node.GetTextNode();
+
+ if (txtNode == nullptr) return;
+
+ if ( text::TextMarkupType::SPELLCHECK == nType )
+ {
+ txtNode->SetWrongDirty(SwTextNode::WrongState::TODO);
+ txtNode->SetWrong(nullptr);
+ }
+ else if( text::TextMarkupType::PROOFREADING == nType )
+ {
+ txtNode->SetGrammarCheckDirty(true);
+ txtNode->SetGrammarCheck(nullptr);
+ }
+ else if ( text::TextMarkupType::SMARTTAG == nType )
+ {
+ txtNode->SetSmartTagDirty(true);
+ txtNode->SetSmartTags(nullptr);
+ }
+ else return;
+
+ SwFormatColl* fmtColl=txtNode->GetFormatColl();
+
+ if (fmtColl == nullptr) return;
+
+ SwFormatChg aNew( fmtColl );
+ txtNode->NotifyClients( nullptr, &aNew );
+}
+
+void SAL_CALL
+SwXTextCursor::makeRedline(
+ const OUString& rRedlineType,
+ const uno::Sequence< beans::PropertyValue >& rRedlineProperties)
+{
+ SolarMutexGuard aGuard;
+
+ SwUnoCursor & rUnoCursor( m_pImpl->GetCursorOrThrow() );
+
+ SwUnoCursorHelper::makeRedline(rUnoCursor, rRedlineType, rRedlineProperties);
+}
+
+void SAL_CALL SwXTextCursor::insertDocumentFromURL(const OUString& rURL,
+ const uno::Sequence< beans::PropertyValue >& rOptions)
+{
+ SolarMutexGuard aGuard;
+
+ SwUnoCursor & rUnoCursor( m_pImpl->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);
+
+ uno::Sequence< table::TableSortField > aFields(3);
+ table::TableSortField* pFields = aFields.getArray();
+
+ 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];
+ }
+
+ pFields[0].Field = 1;
+ pFields[0].IsAscending = true;
+ pFields[0].IsCaseSensitive = false;
+ pFields[0].FieldType = table::TableSortFieldType_ALPHANUMERIC;
+ pFields[0].CollatorLocale = aLang;
+ pFields[0].CollatorAlgorithm = aCollAlg;
+
+ pFields[1].Field = 1;
+ pFields[1].IsAscending = true;
+ pFields[1].IsCaseSensitive = false;
+ pFields[1].FieldType = table::TableSortFieldType_ALPHANUMERIC;
+ pFields[1].CollatorLocale = aLang;
+ pFields[1].CollatorAlgorithm = aCollAlg;
+
+ pFields[2].Field = 1;
+ pFields[2].IsAscending = true;
+ pFields[2].IsCaseSensitive = false;
+ pFields[2].FieldType = table::TableSortFieldType_ALPHANUMERIC;
+ pFields[2].CollatorLocale = aLang;
+ pFields[2].CollatorAlgorithm = 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 !!
+
+ std::unique_ptr<SwSortKey> pKey1(new SwSortKey);
+ pKey1->nColumnId = USHRT_MAX;
+ pKey1->bIsNumeric = true;
+ pKey1->eSortOrder = SwSortOrder::Ascending;
+
+ std::unique_ptr<SwSortKey> pKey2(new SwSortKey);
+ pKey2->nColumnId = USHRT_MAX;
+ pKey2->bIsNumeric = true;
+ pKey2->eSortOrder = SwSortOrder::Ascending;
+
+ std::unique_ptr<SwSortKey> pKey3(new SwSortKey);
+ pKey3->nColumnId = USHRT_MAX;
+ pKey3->bIsNumeric = true;
+ pKey3->eSortOrder = SwSortOrder::Ascending;
+ SwSortKey* aKeys[3] = {pKey1.get(), pKey2.get(), pKey3.get()};
+
+ 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';
+ auto bTemp = o3tl::tryAccess<bool>(aValue);
+ if (bTemp && 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';
+ auto bTemp = o3tl::tryAccess<bool>(aValue);
+ if (bTemp && 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 =
+ static_cast<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 (pKey1->nColumnId != USHRT_MAX)
+ {
+ rSortOpt.aKeys.push_back(std::move(pKey1));
+ }
+ if (pKey2->nColumnId != USHRT_MAX)
+ {
+ rSortOpt.aKeys.push_back(std::move(pKey2));
+ }
+ if (pKey3->nColumnId != USHRT_MAX)
+ {
+ rSortOpt.aKeys.push_back(std::move(pKey3));
+ }
+
+ return bRet && !rSortOpt.aKeys.empty();
+}
+
+void SAL_CALL
+SwXTextCursor::sort(const uno::Sequence< beans::PropertyValue >& rDescriptor)
+{
+ SolarMutexGuard aGuard;
+
+ SwUnoCursor & rUnoCursor( m_pImpl->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.nNode, -1 );
+ const sal_uLong nOffset = rEnd.nNode.GetIndex() - rStart.nNode.GetIndex();
+ const sal_Int32 nCntStt = rStart.nContent.GetIndex();
+
+ rUnoCursor.GetDoc()->SortText(rUnoCursor, aSortOpt);
+
+ // update selection
+ rUnoCursor.DeleteMark();
+ rUnoCursor.GetPoint()->nNode.Assign( aPrevIdx.GetNode(), +1 );
+ SwContentNode *const pCNd = rUnoCursor.GetContentNode();
+ sal_Int32 nLen = pCNd->Len();
+ if (nLen > nCntStt)
+ {
+ nLen = nCntStt;
+ }
+ rUnoCursor.GetPoint()->nContent.Assign(pCNd, nLen );
+ rUnoCursor.SetMark();
+
+ rUnoCursor.GetPoint()->nNode += nOffset;
+ SwContentNode *const pCNd2 = rUnoCursor.GetContentNode();
+ rUnoCursor.GetPoint()->nContent.Assign( pCNd2, 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( m_pImpl->GetCursorOrThrow() );
+ return SwXParaFrameEnumeration::Create(rUnoCursor, PARAFRAME_PORTION_TEXTRANGE);
+}
+
+uno::Reference< container::XEnumeration > SAL_CALL
+SwXTextCursor::createEnumeration()
+{
+ SolarMutexGuard g;
+
+ SwUnoCursor & rUnoCursor( m_pImpl->GetCursorOrThrow() );
+
+ SwXText* pParentText = comphelper::getUnoTunnelImplementation<SwXText>(m_pImpl->m_xParentText);
+ 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_pImpl->m_eType)
+ ? CursorType::SelectionInTable : CursorType::Selection;
+ SwTableNode const*const pStartNode( (CursorType::TableText == m_pImpl->m_eType)
+ ? rUnoCursor.GetPoint()->nNode.GetNode().FindTableNode()
+ : nullptr);
+ SwTable const*const pTable(
+ pStartNode ? & pStartNode->GetTable() : nullptr );
+ return SwXParagraphEnumeration::Create(pParentText, pNewCursor, eSetType, pStartNode, pTable);
+}
+
+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;
+}
+
+IMPLEMENT_FORWARD_REFCOUNT( SwXTextCursor,SwXTextCursor_Base )
+
+uno::Any SAL_CALL
+SwXTextCursor::queryInterface(const uno::Type& rType)
+{
+ return (rType == cppu::UnoType<lang::XUnoTunnel>::get())
+ ? OTextCursorHelper::queryInterface(rType)
+ : SwXTextCursor_Base::queryInterface(rType);
+}
+
+/* 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 000000000..9f0dc5d8e
--- /dev/null
+++ b/sw/source/core/unocore/unoobj2.cxx
@@ -0,0 +1,1692 @@
+/* -*- 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 <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 <swundo.hxx>
+#include <rootfrm.hxx>
+#include <ftnidx.hxx>
+#include <docary.hxx>
+#include <pam.hxx>
+#include <swtblfmt.hxx>
+#include <docsh.hxx>
+#include <pagedesc.hxx>
+#include <cntfrm.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)
+ {
+ 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(rFormat.GetAnchor().GetAnchorId() == nAnchorType)
+ {
+ const auto nIdx =
+ rFormat.GetAnchor().GetContentAnchor()->nContent.GetIndex();
+ const auto nOrder = rFormat.GetAnchor().GetOrder();
+ FrameClientSortListEntry entry(nIdx, nOrder, std::make_shared<sw::FrameClient>(&rFormat));
+ rFrames.push_back(entry);
+ }
+ }
+ }
+}
+
+
+void CollectFrameAtNode( const SwNodeIndex& rIdx,
+ 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
+ SwDoc* pDoc = rIdx.GetNode().GetDoc();
+
+ const auto nChkType = bAtCharAnchoredObjs ? RndStdIds::FLY_AT_CHAR : RndStdIds::FLY_AT_PARA;
+ const SwContentFrame* pCFrame;
+ const SwContentNode* pCNd;
+ if( pDoc->getIDocumentLayoutAccess().GetCurrentViewShell() &&
+ nullptr != (pCNd = rIdx.GetNode().GetContentNode()) &&
+ nullptr != (pCFrame = pCNd->getLayoutFrame( pDoc->getIDocumentLayoutAccess().GetCurrentLayout())) )
+ {
+ lcl_CollectFrameAtNodeWithLayout(pCFrame, rFrames, nChkType);
+ }
+ else
+ {
+ const SwFrameFormats& rFormats = *pDoc->GetSpzFrameFormats();
+ const size_t nSize = rFormats.size();
+ for ( size_t i = 0; i < nSize; i++)
+ {
+ const SwFrameFormat* pFormat = rFormats[ i ];
+ const SwFormatAnchor& rAnchor = pFormat->GetAnchor();
+ const SwPosition* pAnchorPos;
+ if( rAnchor.GetAnchorId() == nChkType &&
+ nullptr != (pAnchorPos = rAnchor.GetContentAnchor()) &&
+ pAnchorPos->nNode == rIdx )
+ {
+
+ // OD 2004-05-07 #i28701# - determine insert position for
+ // sorted <rFrameArr>
+ const sal_Int32 nIndex = pAnchorPos->nContent.GetIndex();
+ sal_uInt32 nOrder = rAnchor.GetOrder();
+
+ FrameClientSortListEntry entry(nIndex, nOrder, std::make_shared<sw::FrameClient>(const_cast<SwFrameFormat*>(pFormat)));
+ rFrames.push_back(entry);
+ }
+ }
+ 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.GetNode().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* pDoc = rPam.GetDoc();
+ //StartEndAction
+ UnoActionContext aAction(pDoc);
+ if (rPam.GetNext() != &rPam) // Ring of Cursors
+ {
+ pDoc->GetIDocumentUndoRedo().StartUndo(SwUndoId::INSATTR, nullptr);
+
+ for(SwPaM& rCurrent : rPam.GetRingContainer())
+ {
+ if (rCurrent.HasMark() &&
+ ( bTableMode ||
+ (*rCurrent.GetPoint() != *rCurrent.GetMark()) ))
+ {
+ pDoc->getIDocumentContentOperations().InsertItemSet(rCurrent, rSet, nFlags);
+ }
+ }
+
+ pDoc->GetIDocumentUndoRedo().EndUndo(SwUndoId::INSATTR, nullptr);
+ }
+ else
+ {
+ pDoc->getIDocumentContentOperations().InsertItemSet( rPam, rSet, nFlags );
+ }
+
+ if( rSet.GetItemState( RES_PARATR_OUTLINELEVEL, false ) >= SfxItemState::DEFAULT )
+ {
+ SwTextNode * pTmpNode = rPam.GetNode().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 sal_uLong nSttNd = rStart.nNode.GetIndex();
+ const sal_uLong nEndNd = rEnd .nNode.GetIndex();
+
+ if (nEndNd - nSttNd >= 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 (sal_uLong 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.nContent.GetIndex() : 0;
+ const sal_Int32 nEnd = (n == nEndNd)
+ ? rEnd.nContent.GetIndex()
+ : 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 sal_uLong 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 > const& xParent,
+ const std::shared_ptr<SwUnoCursor>& pCursor,
+ const CursorType eType,
+ SwStartNode const*const pStartNode, SwTable const*const pTable)
+ : m_xParentText( 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()->nNode.GetIndex() )
+ , m_nFirstParaStart( -1 )
+ , m_nLastParaEnd( -1 )
+ , m_bFirstParagraph( true )
+ , m_pCursor(pCursor)
+ {
+ OSL_ENSURE(m_xParentText.is(), "SwXParagraphEnumeration: no parent?");
+ OSL_ENSURE( !((CursorType::SelectionInTable == eType) ||
+ (CursorType::TableText == eType))
+ || (m_pOwnTable && m_pOwnStartNode),
+ "SwXParagraphEnumeration: table type but no start node or table?");
+
+ if ((CursorType::Selection == m_eCursorType) ||
+ (CursorType::SelectionInTable == m_eCursorType))
+ {
+ SwUnoCursor & rCursor = GetCursor();
+ rCursor.Normalize();
+ m_nFirstParaStart = rCursor.GetPoint()->nContent.GetIndex();
+ m_nLastParaEnd = rCursor.GetMark()->nContent.GetIndex();
+ rCursor.DeleteMark();
+ }
+ }
+
+ virtual ~SwXParagraphEnumerationImpl() override
+ { m_pCursor.reset(nullptr); }
+ virtual void SAL_CALL release() throw () 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);
+};
+
+}
+
+SwXParagraphEnumeration* SwXParagraphEnumeration::Create(
+ uno::Reference< text::XText > const& xParent,
+ const std::shared_ptr<SwUnoCursor>& pCursor,
+ const CursorType eType,
+ SwStartNode const*const pStartNode,
+ SwTable const*const pTable)
+{
+ 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()->nNode.GetIndex() &&
+ pUnoCursor->End()->nNode.GetIndex() <= 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 paragaph start).
+
+ if (rCursor.Start()->nNode.GetIndex() != 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->GetNode().FindTableNode();
+ bool bMovedFromTable = false;
+ if (CursorType::SelectionInTable != m_eCursorType && pTableNode)
+ {
+ aNewCursor->GetPoint()->nNode = pTableNode->EndOfSectionIndex();
+ aNewCursor->Move(fnMoveForward, GoInNode);
+ bMovedFromTable = true;
+ }
+ else
+ {
+ aNewCursor->MovePara(GoNextPara, fnParaStart);
+ }
+ if (m_nEndIndex < aNewCursor->Start()->nNode.GetIndex())
+ {
+ 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.GetNode().FindTableNode();
+ pTableNode = lcl_FindTopLevelTable( pTableNode, m_pOwnTable );
+ if (pTableNode && (&pTableNode->GetTable() != m_pOwnTable))
+ {
+ // this is a foreign table: go to end
+ rUnoCursor.GetPoint()->nNode = 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()->nNode.GetIndex() > m_nEndIndex)
+ return nullptr;
+ }
+
+ SwPosition* pStart = rUnoCursor.Start();
+ const sal_Int32 nFirstContent =
+ m_bFirstParagraph ? m_nFirstParaStart : -1;
+ const sal_Int32 nLastContent =
+ (m_nEndIndex == pStart->nNode.GetIndex()) ? m_nLastParaEnd : -1;
+
+ // position in a table, or in a simple paragraph?
+ SwTableNode * pTableNode = rUnoCursor.GetNode().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->nNode.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_pTableFormat;
+ const ::sw::mark::IMark* m_pMark;
+
+ Impl(SwDoc& rDoc, const enum RangePosition eRange,
+ SwFrameFormat* const pTableFormat,
+ const uno::Reference<text::XText>& xParent = nullptr)
+ : m_rPropSet(*aSwMapProvider.GetPropertySet(PROPERTY_MAP_TEXT_CURSOR))
+ , m_eRangePosition(eRange)
+ , m_rDoc(rDoc)
+ , m_xParentText(xParent)
+ , m_pTableFormat(pTableFormat)
+ , m_pMark(nullptr)
+ {
+ m_pTableFormat && StartListening(pTableFormat->GetNotifier());
+ }
+
+ 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_pTableFormat = nullptr;
+ EndListeningAll();
+ }
+
+ const ::sw::mark::IMark* GetBookmark() const { return m_pMark; }
+ void SetMark(::sw::mark::IMark& rMark)
+ {
+ EndListeningAll();
+ m_pTableFormat = 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_pTableFormat = 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(SwFrameFormat& rTableFormat)
+ : m_pImpl(
+ new SwXTextRange::Impl(*rTableFormat.GetDoc(), RANGE_IS_TABLE, &rTableFormat) )
+{
+ SwTable *const pTable = SwTable::FindTable( &rTableFormat );
+ SwTableNode *const pTableNode = pTable->GetTableNode();
+ SwPosition aPosition( *pTableNode );
+ SwPaM aPam( aPosition );
+
+ SetPositions( aPam );
+}
+
+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);
+ m_pImpl->SetMark(*pMark);
+}
+
+void SwXTextRange::DeleteAndInsert(
+ const OUString& rText, const bool bForceExpandHints)
+{
+ if (RANGE_IS_TABLE == m_pImpl->m_eRangePosition)
+ {
+ // setString on table not allowed
+ throw uno::RuntimeException();
+ }
+
+ const SwPosition aPos(GetDoc().GetNodes().GetEndOfContent());
+ SwCursor aCursor(aPos, nullptr);
+ if (GetPositions(aCursor))
+ {
+ UnoActionContext aAction(& m_pImpl->m_rDoc);
+ m_pImpl->m_rDoc.GetIDocumentUndoRedo().StartUndo(SwUndoId::INSERT, nullptr);
+ if (aCursor.HasMark())
+ {
+ m_pImpl->m_rDoc.getIDocumentContentOperations().DeleteAndJoin(aCursor);
+ }
+
+ if (!rText.isEmpty())
+ {
+ SwUnoCursorHelper::DocInsertStringSplitCR(
+ m_pImpl->m_rDoc, aCursor, rText, bForceExpandHints);
+
+ SwUnoCursorHelper::SelectPam(aCursor, true);
+ aCursor.Left(rText.getLength());
+ }
+ SetPositions(aCursor);
+ m_pImpl->m_rDoc.GetIDocumentUndoRedo().EndUndo(SwUndoId::INSERT, nullptr);
+ }
+}
+
+namespace
+{
+ class theSwXTextRangeUnoTunnelId : public rtl::Static< UnoTunnelIdInit, theSwXTextRangeUnoTunnelId > {};
+}
+
+const uno::Sequence< sal_Int8 > & SwXTextRange::getUnoTunnelId()
+{
+ return theSwXTextRangeUnoTunnelId::get().getSeq();
+}
+
+// XUnoTunnel
+sal_Int64 SAL_CALL
+SwXTextRange::getSomething(const uno::Sequence< sal_Int8 >& rId)
+{
+ return ::sw::UnoTunnelImpl<SwXTextRange>(rId, this);
+}
+
+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())
+ {
+ if (m_pImpl->m_eRangePosition == RANGE_IS_TABLE &&
+ m_pImpl->m_pTableFormat)
+ {
+ SwTable const*const pTable = SwTable::FindTable( m_pImpl->m_pTableFormat );
+ SwTableNode const*const pTableNode = pTable->GetTableNode();
+ const SwPosition aPosition( *pTableNode );
+ m_pImpl->m_xParentText =
+ ::sw::CreateParentXText(m_pImpl->m_rDoc, aPosition);
+ }
+ }
+ 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
+ {
+ throw uno::RuntimeException();
+ }
+ 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
+ {
+ throw uno::RuntimeException();
+ }
+ 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) && aPaM.HasMark())
+ {
+ SwUnoCursorHelper::GetTextFromPam(aPaM, sRet);
+ }
+ return sRet;
+}
+
+void SAL_CALL SwXTextRange::setString(const OUString& rString)
+{
+ SolarMutexGuard aGuard;
+
+ DeleteAndInsert(rString, false);
+}
+
+bool SwXTextRange::GetPositions(SwPaM& rToFill) const
+{
+ ::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)
+{
+ bool bRet = false;
+
+ uno::Reference<lang::XUnoTunnel> xRangeTunnel( xTextRange, uno::UNO_QUERY);
+ SwXTextRange* pRange = nullptr;
+ OTextCursorHelper* pCursor = nullptr;
+ SwXTextPortion* pPortion = nullptr;
+ SwXText* pText = nullptr;
+ SwXParagraph* pPara = nullptr;
+ if(xRangeTunnel.is())
+ {
+ pRange = ::sw::UnoTunnelGetImplementation<SwXTextRange>(xRangeTunnel);
+ pCursor =
+ ::sw::UnoTunnelGetImplementation<OTextCursorHelper>(xRangeTunnel);
+ pPortion=
+ ::sw::UnoTunnelGetImplementation<SwXTextPortion>(xRangeTunnel);
+ pText = ::sw::UnoTunnelGetImplementation<SwXText>(xRangeTunnel);
+ pPara = ::sw::UnoTunnelGetImplementation<SwXParagraph>(xRangeTunnel);
+ }
+
+ // 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
+ uno::Reference< text::XTextCursor > xTextCursor;
+ if (pText)
+ {
+ xTextCursor.set( pText->CreateCursor() );
+ xTextCursor->gotoEnd(true);
+ pCursor =
+ comphelper::getUnoTunnelImplementation<OTextCursorHelper>(xTextCursor);
+ }
+ if(pRange && &pRange->GetDoc() == rToFill.GetDoc())
+ {
+ bRet = pRange->GetPositions(rToFill);
+ }
+ else
+ {
+ if (pPara)
+ {
+ bRet = pPara->SelectPaM(rToFill);
+ }
+ else
+ {
+ SwDoc* const pDoc = pCursor ? pCursor->GetDoc()
+ : (pPortion ? pPortion->GetCursor().GetDoc() : nullptr);
+ const SwPaM* const pUnoCursor = pCursor ? pCursor->GetPaM()
+ : (pPortion ? &pPortion->GetCursor() : nullptr);
+ 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();
+ 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
+
+uno::Reference< text::XTextRange >
+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()) );
+ const uno::Reference< text::XTextRange > xRet(
+ new SwXTextRange(*pNewCursor, xParentText,
+ isCell ? RANGE_IN_CELL : RANGE_IN_TEXT) );
+ return xRet;
+}
+
+namespace sw {
+
+uno::Reference< text::XText >
+CreateParentXText(SwDoc & rDoc, const SwPosition& rPos)
+{
+ uno::Reference< text::XText > xParentText;
+ SwStartNode* pSttNode = rPos.nNode.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.set(SwXTextFrame::CreateXTextFrame(rDoc, pFormat),
+ uno::UNO_QUERY);
+ }
+ }
+ 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.set(SwXFootnote::CreateXFootnote(rDoc,
+ &const_cast<SwFormatFootnote&>(rFootnote)), uno::UNO_QUERY);
+ break;
+ }
+ }
+ }
+ break;
+ default:
+ {
+ // then it is the body text
+ const uno::Reference<frame::XModel> xModel =
+ rDoc.GetDocShell()->GetBaseModel();
+ const uno::Reference< text::XTextDocument > xDoc(
+ xModel, uno::UNO_QUERY);
+ xParentText = xDoc->getText();
+ }
+ }
+ 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();
+ }
+
+ if (!m_pImpl->GetBookmark())
+ {
+ throw uno::RuntimeException();
+ }
+ const SwPosition aPos(GetDoc().GetNodes().GetEndOfContent());
+ const auto pNewCursor(m_pImpl->m_rDoc.CreateUnoCursor(aPos));
+ if (!GetPositions(*pNewCursor))
+ {
+ throw uno::RuntimeException();
+ }
+
+ return SwXParaFrameEnumeration::Create(*pNewCursor, PARAFRAME_PORTION_TEXTRANGE);
+}
+
+uno::Reference< container::XEnumeration > SAL_CALL
+SwXTextRange::createEnumeration()
+{
+ SolarMutexGuard g;
+
+ if (!m_pImpl->GetBookmark())
+ {
+ throw uno::RuntimeException();
+ }
+ const SwPosition aPos(GetDoc().GetNodes().GetEndOfContent());
+ auto pNewCursor(m_pImpl->m_rDoc.CreateUnoCursor(aPos));
+ if (!GetPositions(*pNewCursor))
+ {
+ throw uno::RuntimeException();
+ }
+ 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();
+ }
+ 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();
+ }
+ 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();
+ }
+ 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();
+ }
+ 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();
+ }
+ 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();
+ }
+ 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();
+ }
+ SwPaM aPaM(GetDoc().GetNodes());
+ SwXTextRange::GetPositions(aPaM);
+ SwUnoCursorHelper::makeRedline( aPaM, rRedlineType, rRedlineProperties );
+}
+
+namespace {
+
+struct SwXTextRangesImpl final : public SwXTextRanges
+{
+
+ // XUnoTunnel
+ virtual sal_Int64 SAL_CALL getSomething( const css::uno::Sequence< sal_Int8 >& rIdentifier) override;
+
+ // 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() throw () override
+ {
+ SolarMutexGuard g;
+ OWeakObject::release();
+ }
+ virtual SwUnoCursor* GetCursor() override
+ { return &(*m_pUnoCursor); };
+ void MakeRanges();
+ std::vector< uno::Reference< text::XTextRange > > m_Ranges;
+ sw::UnoCursorPointer m_pUnoCursor;
+};
+
+}
+
+void SwXTextRangesImpl::MakeRanges()
+{
+ if (GetCursor())
+ {
+ for(SwPaM& rTmpCursor : GetCursor()->GetRingContainer())
+ {
+ const uno::Reference< text::XTextRange > xRange(
+ SwXTextRange::CreateXTextRange(
+ *rTmpCursor.GetDoc(),
+ *rTmpCursor.GetPoint(), rTmpCursor.GetMark()));
+ if (xRange.is())
+ {
+ m_Ranges.push_back(xRange);
+ }
+ }
+ }
+}
+
+SwXTextRanges* SwXTextRanges::Create(SwPaM *const pPaM)
+ { return new SwXTextRangesImpl(pPaM); }
+
+namespace
+{
+ class theSwXTextRangesUnoTunnelId : public rtl::Static< UnoTunnelIdInit, theSwXTextRangesUnoTunnelId > {};
+}
+
+const uno::Sequence< sal_Int8 > & SwXTextRanges::getUnoTunnelId()
+ { return theSwXTextRangesUnoTunnelId::get().getSeq(); }
+
+sal_Int64 SAL_CALL
+SwXTextRangesImpl::getSomething(const uno::Sequence< sal_Int8 >& rId)
+{
+ return ::sw::UnoTunnelImpl<SwXTextRanges>(rId, this);
+}
+
+/*
+ * 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;
+ ret <<= m_Ranges.at(nIndex);
+ return ret;
+}
+
+void SwUnoCursorHelper::SetString(SwCursor & rCursor, const OUString& rString)
+{
+ // Start/EndAction
+ SwDoc *const pDoc = rCursor.GetDoc();
+ UnoActionContext aAction(pDoc);
+ pDoc->GetIDocumentUndoRedo().StartUndo(SwUndoId::INSERT, nullptr);
+ if (rCursor.HasMark())
+ {
+ pDoc->getIDocumentContentOperations().DeleteAndJoin(rCursor);
+ }
+ if (!rString.isEmpty())
+ {
+ const bool bSuccess( SwUnoCursorHelper::DocInsertStringSplitCR(
+ *pDoc, rCursor, rString, false ) );
+ OSL_ENSURE( bSuccess, "DocInsertStringSplitCR" );
+ SwUnoCursorHelper::SelectPam(rCursor, true);
+ rCursor.Left(rString.getLength());
+ }
+ pDoc->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() throw () 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
+ const auto iter = std::remove_if(m_vFrames.begin(), m_vFrames.end(),
+ [] (std::shared_ptr<sw::FrameClient>& rEntry) -> bool { return !rEntry->GetRegisteredIn(); });
+ m_vFrames.erase(iter, m_vFrames.end());
+ }
+ }
+ void FillFrame();
+ bool CreateNextObject();
+ uno::Reference< text::XTextContent > m_xNextObject;
+ FrameClientList_t m_vFrames;
+ ::sw::UnoCursorPointer m_pUnoCursor;
+};
+
+}
+
+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()->nNode, vFrames, false);
+ std::transform(vFrames.begin(), vFrames.end(),
+ std::back_inserter(m_vFrames),
+ [] (const FrameClientSortListEntry& rEntry) { return rEntry.pFrameClient; });
+ }
+ else if (pFormat)
+ {
+ m_vFrames.push_back(std::make_shared<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 auto& pFlyFrame : rPaM.GetDoc()->GetAllFlyFormats(&GetCursor(), false, true))
+ {
+ const auto pFrameFormat = const_cast<SwFrameFormat*>(&pFlyFrame->GetFormat());
+ m_vFrames.push_back(std::make_shared<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->GetNode().IsTextNode())
+ return;
+ // search for objects at the cursor - anchored at/as char
+ const auto pTextAttr = m_pUnoCursor->GetNode().GetTextNode()->GetTextAttrForCharAt(
+ m_pUnoCursor->GetPoint()->nContent.GetIndex(), RES_TXTATR_FLYCNT);
+ if(!pTextAttr)
+ return;
+ const SwFormatFlyCnt& rFlyCnt = pTextAttr->GetFlyCnt();
+ SwFrameFormat* const pFrameFormat = rFlyCnt.GetFrameFormat();
+ m_vFrames.push_back(std::make_shared<sw::FrameClient>(pFrameFormat));
+}
+
+bool SwXParaFrameEnumerationImpl::CreateNextObject()
+{
+ if (m_vFrames.empty())
+ return false;
+
+ SwFrameFormat* const pFormat = static_cast<SwFrameFormat*>(
+ m_vFrames.front()->GetRegisteredIn());
+ m_vFrames.pop_front();
+ // 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)
+ m_xNextObject.set(pObject->getUnoShape(), uno::UNO_QUERY);
+ }
+ else
+ {
+ const SwNodeIndex* pIdx = pFormat->GetContent().GetContentIdx();
+ OSL_ENSURE(pIdx, "where is the index?");
+ SwNode const*const pNd =
+ m_pUnoCursor->GetDoc()->GetNodes()[ pIdx->GetIndex() + 1 ];
+
+ if (!pNd->IsNoTextNode())
+ {
+ m_xNextObject.set(SwXTextFrame::CreateXTextFrame(
+ *pFormat->GetDoc(), pFormat));
+ }
+ else if (pNd->IsGrfNode())
+ {
+ m_xNextObject.set(SwXTextGraphicObject::CreateXTextGraphicObject(
+ *pFormat->GetDoc(), pFormat));
+ }
+ else
+ {
+ assert(pNd->IsOLENode());
+ m_xNextObject.set(SwXTextEmbeddedObject::CreateXTextEmbeddedObject(
+ *pFormat->GetDoc(), pFormat));
+ }
+ }
+ return m_xNextObject.is();
+}
+
+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 000000000..3fef41218
--- /dev/null
+++ b/sw/source/core/unocore/unoparagraph.cxx
@@ -0,0 +1,1417 @@
+/* -*- 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/interfacecontainer2.hxx>
+#include <cppuhelper/exc_hlp.hxx>
+#include <cppuhelper/supportsservice.hxx>
+#include <osl/diagnose.h>
+
+#include <cmdid.h>
+#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 <osl/mutex.hxx>
+#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/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()->nContent != 0)
+ {
+ m_rCursor.MovePara(GoCurrPara, fnParaStart);
+ }
+ // or at the end already?
+ if (m_rCursor.GetPoint()->nContent != m_rCursor.GetContentNode()->Len())
+ {
+ m_rCursor.SetMark();
+ m_rCursor.MovePara(GoCurrPara, fnParaEnd);
+ }
+}
+
+SwParaSelection::~SwParaSelection()
+{
+ if (m_rCursor.GetPoint()->nContent != 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 SfxItemPropertySimpleEntry& rEntry,
+ bool &rAttrSetFetched );
+
+class SwXParagraph::Impl
+ : public SvtListener
+{
+private:
+ ::osl::Mutex m_Mutex; // just for OInterfaceContainerHelper2
+
+public:
+ SwXParagraph& m_rThis;
+ uno::WeakReference<uno::XInterface> m_wThis;
+ ::comphelper::OInterfaceContainerHelper2 m_EventListeners;
+ SfxItemPropertySet const& m_rPropSet;
+ bool m_bIsDescriptor;
+ sal_Int32 m_nSelectionStartPos;
+ sal_Int32 m_nSelectionEndPos;
+ OUString m_sText;
+ uno::Reference<text::XText> m_xParentText;
+ SwTextNode* m_pTextNode;
+
+ Impl(SwXParagraph& rThis,
+ SwTextNode* const pTextNode = nullptr, uno::Reference<text::XText> const& xParent = nullptr,
+ const sal_Int32 nSelStart = -1, const sal_Int32 nSelEnd = -1)
+ : m_rThis(rThis)
+ , m_EventListeners(m_Mutex)
+ , m_rPropSet(*aSwMapProvider.GetPropertySet(PROPERTY_MAP_PARAGRAPH))
+ , m_bIsDescriptor(nullptr == pTextNode)
+ , m_nSelectionStartPos(nSelStart)
+ , m_nSelectionEndPos(nSelEnd)
+ , m_xParentText(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 SfxItemPropertySimpleEntry& 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;
+ 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(ev);
+ }
+}
+
+SwXParagraph::SwXParagraph()
+ : m_pImpl( new SwXParagraph::Impl(*this) )
+{
+}
+
+SwXParagraph::SwXParagraph(
+ uno::Reference< text::XText > 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();
+}
+
+uno::Reference<text::XTextContent>
+SwXParagraph::CreateXParagraph(SwDoc & rDoc, SwTextNode *const pTextNode,
+ uno::Reference< text::XText> 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
+ uno::Reference<text::XTextContent> xParagraph;
+ if (pTextNode && (-1 == nSelStart) && (-1 == nSelEnd))
+ { // only use cache if no selection!
+ xParagraph.set(pTextNode->GetXParagraph());
+ }
+ if (xParagraph.is())
+ {
+ return xParagraph;
+ }
+
+ // create new SwXParagraph
+ uno::Reference<text::XText> xParentText(i_xParent);
+ if (!xParentText.is() && pTextNode)
+ {
+ SwPosition Pos(*pTextNode);
+ xParentText.set(::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;
+ return xParagraph;
+}
+
+bool SwXParagraph::SelectPaM(SwPaM & rPaM)
+{
+ SwTextNode const*const pTextNode( GetTextNode() );
+
+ if (!pTextNode)
+ {
+ return false;
+ }
+
+ *rPaM.GetPoint() = SwPosition( *pTextNode );
+ // set selection to the whole paragraph
+ rPaM.SetMark();
+ rPaM.GetMark()->nContent = pTextNode->GetText().getLength();
+ return true;
+}
+
+namespace
+{
+ class theSwXParagraphUnoTunnelId : public rtl::Static< UnoTunnelIdInit, theSwXParagraphUnoTunnelId > {};
+}
+
+const uno::Sequence< sal_Int8 > & SwXParagraph::getUnoTunnelId()
+{
+ return theSwXParagraphUnoTunnelId::get().getSeq();
+}
+
+sal_Int64 SAL_CALL
+SwXParagraph::getSomething(const uno::Sequence< sal_Int8 >& rId)
+{
+ return ::sw::UnoTunnelImpl<SwXParagraph>(rId, this);
+}
+
+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)
+ {
+ m_pImpl->m_bIsDescriptor = false;
+ m_pImpl->EndListeningAll();
+ m_pImpl->StartListening(rTextNode.GetNotifier());
+ rTextNode.SetXParagraph(uno::Reference<text::XTextContent>(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;
+ uno::Sequence<OUString> aPropertyNames { rPropertyName };
+ uno::Sequence<uno::Any> aValues(1);
+ aValues.getArray()[0] = rValue;
+ m_pImpl->SetPropertyValues_Impl( aPropertyNames, aValues );
+}
+
+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 );
+ const OUString* pPropertyNames = rPropertyNames.getConstArray();
+ const uno::Any* pValues = rValues.getConstArray();
+ const SfxItemPropertyMap &rMap = m_rPropSet.getPropertyMap();
+ SwParaSelection aParaSel( aCursor );
+
+ uno::Sequence< beans::PropertyValue > aValues( rPropertyNames.getLength() );
+ for (sal_Int32 nProp = 0; nProp < rPropertyNames.getLength(); nProp++)
+ {
+ SfxItemPropertySimpleEntry const*const pEntry =
+ rMap.getByName( pPropertyNames[nProp] );
+ if (!pEntry)
+ {
+ throw beans::UnknownPropertyException(
+ "Unknown property: " + pPropertyNames[nProp],
+ static_cast< cppu::OWeakObject * >(&m_rThis));
+ }
+ if (pEntry->nFlags & beans::PropertyAttribute::READONLY)
+ {
+ throw beans::PropertyVetoException(
+ "Property is read-only: " + pPropertyNames[nProp],
+ static_cast< cppu::OWeakObject * >(&m_rThis));
+ }
+ aValues[nProp].Name = pPropertyNames[nProp];
+ aValues[nProp].Value = pValues[nProp];
+ }
+ SwUnoCursorHelper::SetPropertyValues(aCursor, m_rPropSet, aValues);
+}
+
+void SAL_CALL SwXParagraph::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 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 SfxItemPropertySimpleEntry& 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)
+ {
+ // 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)
+ {
+ 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());
+ SwPosition aPos( rTextNode );
+ SwPaM aPam( aPos );
+ 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++)
+ {
+ SfxItemPropertySimpleEntry const*const pEntry =
+ rMap.getByName( pPropertyNames[nProp] );
+ if (!pEntry)
+ {
+ throw beans::UnknownPropertyException(
+ "Unknown property: " + pPropertyNames[nProp],
+ static_cast< cppu::OWeakObject * >(&m_rThis));
+ }
+ 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",
+ static_cast < cppu::OWeakObject * > ( this ), anyEx );
+ }
+ catch (lang::WrappedTargetException &)
+ {
+ css::uno::Any anyEx = cppu::getCaughtException();
+ throw css::lang::WrappedTargetRuntimeException("WrappedTargetException caught",
+ static_cast < cppu::OWeakObject * > ( this ), 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()->nNode.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];
+
+ SfxItemPropertySimpleEntry 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
+ OSL_FAIL( "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;
+
+ 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.begin());
+ 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;
+
+ SfxItemPropertySimpleEntry 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 ) )
+ {
+ SwPosition aPos( rTextNode );
+ SwPaM aPam( aPos );
+ // 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
+ OSL_FAIL( "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, const OUString& 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(1);
+ text::TextContentAnchorType* pArray = aTypes.getArray();
+ pArray[0] = 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 SfxItemPropertySimpleEntry& 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;
+ SfxItemPropertySimpleEntry const*const pEntry =
+ m_pImpl->m_rPropSet.getPropertyMap().getByName(rPropertyName);
+ if (!pEntry)
+ {
+ throw beans::UnknownPropertyException(
+ "Unknown property: " + rPropertyName,
+ static_cast<cppu::OWeakObject *>(this));
+ }
+ 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)
+ {
+ SfxItemPropertySimpleEntry const*const pEntry =
+ rMap.getByName( *pNames );
+ if (!pEntry)
+ {
+ throw beans::UnknownPropertyException(
+ "Unknown property: " + *pNames,
+ static_cast<cppu::OWeakObject *>(this));
+ }
+
+ 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 );
+ SfxItemPropertySimpleEntry const*const pEntry =
+ m_pImpl->m_rPropSet.getPropertyMap().getByName( rPropertyName );
+ if (!pEntry)
+ {
+ throw beans::UnknownPropertyException(
+ "Unknown property: " + rPropertyName,
+ static_cast<cppu::OWeakObject *>(this));
+ }
+
+ if (pEntry->nFlags & beans::PropertyAttribute::READONLY)
+ {
+ throw uno::RuntimeException(
+ "Property is read-only: " + rPropertyName,
+ static_cast<cppu::OWeakObject *>(this));
+ }
+
+ const bool bBelowFrameAtrEnd(pEntry->nWID < RES_FRMATR_END);
+ const bool bDrawingLayerRange(XATTR_FILL_FIRST <= pEntry->nWID && XATTR_FILL_LAST >= pEntry->nWID);
+
+ if(bBelowFrameAtrEnd || bDrawingLayerRange)
+ {
+ std::set<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;
+ }
+
+ SfxItemPropertySimpleEntry const*const pEntry =
+ m_pImpl->m_rPropSet.getPropertyMap().getByName(rPropertyName);
+ if (!pEntry)
+ {
+ throw beans::UnknownPropertyException(
+ "Unknown property: " + rPropertyName,
+ static_cast<cppu::OWeakObject *>(this));
+ }
+
+ 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*/)
+{
+ SolarMutexGuard aGuard;
+ // 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(static_cast< ::cppu::OWeakObject&>(*this));
+ m_pImpl->m_EventListeners.disposeAndClear(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
+ m_pImpl->m_EventListeners.addInterface(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
+ m_pImpl->m_EventListeners.removeInterface(xListener);
+}
+
+uno::Reference< container::XEnumeration > SAL_CALL
+SwXParagraph::createEnumeration()
+{
+ SolarMutexGuard aGuard;
+
+ SwTextNode & rTextNode(m_pImpl->GetTextNodeOrThrow());
+
+ SwPosition aPos( rTextNode );
+ SwPaM aPam ( aPos );
+ const uno::Reference< container::XEnumeration > xRef =
+ new SwXTextPortionEnumeration(aPam, m_pImpl->m_xParentText,
+ m_pImpl->m_nSelectionStartPos, m_pImpl->m_nSelectionEndPos);
+ return xRef;
+}
+
+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());
+
+ SwPosition aPos( rTextNode );
+ SwPaM aPam( aPos );
+ 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 000000000..07af7a238
--- /dev/null
+++ b/sw/source/core/unocore/unoport.cxx
@@ -0,0 +1,825 @@
+/* -*- 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 <vcl/svapp.hxx>
+#include <svl/itemprop.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 > const& rParent,
+ SwTextPortionType eType)
+ : m_pPropSet(aSwMapProvider.GetPropertySet(
+ (PORTION_REDLINE_START == eType ||
+ PORTION_REDLINE_END == eType)
+ ? PROPERTY_MAP_REDLINE_PORTION
+ : PROPERTY_MAP_TEXTPORTION_EXTENSIONS))
+ , m_xParentText(rParent)
+ , m_pFrameFormat(nullptr)
+ , m_ePortionType(eType)
+ , m_bIsCollapsed(false)
+{
+ init( pPortionCursor);
+}
+
+SwXTextPortion::SwXTextPortion(
+ const SwUnoCursor* pPortionCursor,
+ uno::Reference< text::XText > const& rParent,
+ SwFrameFormat& rFormat )
+ : m_pPropSet(aSwMapProvider.GetPropertySet(
+ PROPERTY_MAP_TEXTPORTION_EXTENSIONS))
+ , m_xParentText(rParent)
+ , m_pFrameFormat(&rFormat)
+ , m_ePortionType(PORTION_FRAME)
+ , m_bIsCollapsed(false)
+{
+ StartListening(rFormat.GetNotifier());
+ init( pPortionCursor);
+}
+
+SwXTextPortion::SwXTextPortion(
+ const SwUnoCursor* pPortionCursor,
+ SwTextRuby const& rAttr,
+ uno::Reference< text::XText > const& xParent,
+ bool bIsEnd )
+ : m_pPropSet(aSwMapProvider.GetPropertySet(
+ PROPERTY_MAP_TEXTPORTION_EXTENSIONS))
+ , m_xParentText(xParent)
+ , m_pRubyText ( bIsEnd ? nullptr : new uno::Any )
+ , m_pRubyStyle ( bIsEnd ? nullptr : new uno::Any )
+ , m_pRubyAdjust ( bIsEnd ? nullptr : new uno::Any )
+ , m_pRubyIsAbove( bIsEnd ? nullptr : new uno::Any )
+ , m_pRubyPosition( bIsEnd ? nullptr : new uno::Any )
+ , m_pFrameFormat(nullptr)
+ , m_ePortionType( bIsEnd ? PORTION_RUBY_END : PORTION_RUBY_START )
+ , m_bIsCollapsed(false)
+{
+ init( pPortionCursor);
+
+ if (!bIsEnd)
+ {
+ const SfxPoolItem& rItem = rAttr.GetAttr();
+ rItem.QueryValue(*m_pRubyText);
+ rItem.QueryValue(*m_pRubyStyle, MID_RUBY_CHARSTYLE);
+ rItem.QueryValue(*m_pRubyAdjust, MID_RUBY_ADJUST);
+ rItem.QueryValue(*m_pRubyIsAbove, MID_RUBY_ABOVE);
+ rItem.QueryValue(*m_pRubyPosition, 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.GetNode().GetTextNode();
+ if ( pTextNd )
+ {
+ const sal_Int32 nStt = rUnoCursor.Start()->nContent.GetIndex();
+ aText = pTextNd->GetExpandText(nullptr, nStt,
+ rUnoCursor.End()->nContent.GetIndex() - nStt );
+ }
+ 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 SfxItemPropertySimpleEntry& rEntry,
+ SwUnoCursor *pUnoCursor,
+ std::unique_ptr<SfxItemSet> &pSet )
+{
+ OSL_ENSURE( pUnoCursor, "UNO cursor missing" );
+ if (!pUnoCursor)
+ return;
+ switch(rEntry.nWID)
+ {
+ case FN_UNO_TEXT_PORTION_TYPE:
+ {
+ const char* pRet;
+ switch (m_ePortionType)
+ {
+ case PORTION_TEXT: pRet = "Text";break;
+ case PORTION_FIELD: pRet = "TextField";break;
+ case PORTION_FRAME: pRet = "Frame";break;
+ case PORTION_FOOTNOTE: pRet = "Footnote";break;
+ case PORTION_REFMARK_START:
+ case PORTION_REFMARK_END: pRet = UNO_NAME_REFERENCE_MARK;break;
+ case PORTION_TOXMARK_START:
+ case PORTION_TOXMARK_END: pRet = UNO_NAME_DOCUMENT_INDEX_MARK;break;
+ case PORTION_BOOKMARK_START :
+ case PORTION_BOOKMARK_END : pRet = UNO_NAME_BOOKMARK;break;
+ case PORTION_REDLINE_START:
+ case PORTION_REDLINE_END: pRet = "Redline";break;
+ case PORTION_RUBY_START:
+ case PORTION_RUBY_END: pRet = "Ruby";break;
+ case PORTION_SOFT_PAGEBREAK:pRet = "SoftPageBreak";break;
+ case PORTION_META: pRet = UNO_NAME_META; break;
+ case PORTION_FIELD_START:pRet = "TextFieldStart";break;
+ case PORTION_FIELD_SEP: pRet = "TextFieldSeparator";break;
+ case PORTION_FIELD_END:pRet = "TextFieldEnd";break;
+ case PORTION_FIELD_START_END:pRet = "TextFieldStartEnd";break;
+ case PORTION_ANNOTATION:
+ pRet = "Annotation";
+ break;
+ case PORTION_ANNOTATION_END:
+ pRet = "AnnotationEnd";
+ break;
+ default:
+ pRet = nullptr;
+ }
+
+ OUString sRet;
+ if( pRet )
+ sRet = OUString::createFromAscii( pRet );
+ 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_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 uno::Any* pToSet = nullptr;
+ switch(rEntry.nMemberId)
+ {
+ case MID_RUBY_TEXT : pToSet = m_pRubyText.get(); break;
+ case MID_RUBY_ADJUST : pToSet = m_pRubyAdjust.get(); break;
+ case MID_RUBY_CHARSTYLE:pToSet = m_pRubyStyle.get(); break;
+ case MID_RUBY_ABOVE : pToSet = m_pRubyIsAbove.get();break;
+ case MID_RUBY_POSITION: pToSet = m_pRubyPosition.get();break;
+ }
+ if(pToSet)
+ rVal = *pToSet;
+ }
+ break;
+ default:
+ beans::PropertyState eTemp;
+ bool bDone = SwUnoCursorHelper::getCursorPropertyValue(
+ rEntry, *pUnoCursor, &rVal, eTemp );
+ if(!bDone)
+ {
+ if(!pSet)
+ {
+ pSet = std::make_unique<SfxItemSet>(
+ pUnoCursor->GetDoc()->GetAttrPool(),
+ svl::Items<
+ RES_CHRATR_BEGIN, RES_FRMATR_END - 1,
+ RES_UNKNOWNATR_CONTAINER,
+ RES_UNKNOWNATR_CONTAINER>{});
+ 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 SfxItemPropertySimpleEntry* pEntry = rMap.getByName(pPropertyNames[nProp]);
+ if(!pEntry)
+ throw beans::UnknownPropertyException( "Unknown property: " + pPropertyNames[nProp], static_cast < cppu::OWeakObject * > ( this ) );
+ 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 )
+{
+ 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() );
+ for(sal_Int32 nProp = 0; nProp < rPropertyNames.getLength(); nProp++)
+ {
+ const SfxItemPropertySimpleEntry* pEntry = rMap.getByName(pPropertyNames[nProp]);
+ if (!pEntry)
+ throw beans::UnknownPropertyException( "Unknown property: " + pPropertyNames[nProp], static_cast < cppu::OWeakObject * > ( this ) );
+ if ( pEntry->nFlags & beans::PropertyAttribute::READONLY)
+ throw beans::PropertyVetoException ("Property is read-only: " + pPropertyNames[nProp], static_cast < cppu::OWeakObject * > ( this ) );
+
+ aValues[nProp].Name = pPropertyNames[nProp];
+ aValues[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",
+ static_cast < cppu::OWeakObject * > ( this ), anyEx );
+ }
+ catch (lang::WrappedTargetException &)
+ {
+ css::uno::Any anyEx = cppu::getCaughtException();
+ throw lang::WrappedTargetRuntimeException("WrappedTargetException caught",
+ static_cast < cppu::OWeakObject * > ( this ), 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 SfxItemPropertySimpleEntry* 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
+ OSL_FAIL( "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 SwXTextPortion::getPropertyValuesTolerant(
+ const uno::Sequence< OUString >& rPropertyNames )
+{
+ SolarMutexGuard aGuard;
+
+ 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.begin());
+ 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 =
+ 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 SfxItemPropertySimpleEntry* pEntry = rPropMap.getByName( pProp[i] );
+ if (!pEntry)
+ throw beans::UnknownPropertyException( "Unknown property: " + pProp[i], static_cast < cppu::OWeakObject * > ( this ) );
+ 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
+ OSL_FAIL( "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);
+}
+
+namespace
+{
+ class theSwXTextPortionUnoTunnelId : public rtl::Static< UnoTunnelIdInit, theSwXTextPortionUnoTunnelId > {};
+}
+
+const uno::Sequence< sal_Int8 > & SwXTextPortion::getUnoTunnelId()
+{
+ return theSwXTextPortionUnoTunnelId::get().getSeq();
+}
+
+sal_Int64 SwXTextPortion::getSomething( const uno::Sequence< sal_Int8 >& rId )
+{
+ if( isUnoTunnelId<SwXTextPortion>(rId) )
+ {
+ return sal::static_int_cast< sal_Int64 >( reinterpret_cast< sal_IntPtr >(this) );
+ }
+ return 0;
+}
+
+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 000000000..8b968bb82
--- /dev/null
+++ b/sw/source/core/unocore/unoportenum.cxx
@@ -0,0 +1,1489 @@
+/* -*- 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 <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 <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;
+using namespace ::std;
+
+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,
+ uno::Reference< text::XText > const& i_xParentText,
+ SwUnoCursor* pUnoCursor,
+ FrameClientSortList_t & i_rFrames,
+ const sal_Int32 i_nStartPos, const sal_Int32 i_nEndPos );
+
+namespace
+{
+ enum class BkmType {
+ Start, End, StartEnd
+ };
+
+ struct SwXBookmarkPortion_Impl
+ {
+ Reference<XTextContent> xBookmark;
+ BkmType nBkmType;
+ const SwPosition aPosition;
+
+ SwXBookmarkPortion_Impl(uno::Reference<text::XTextContent> const& xMark,
+ const BkmType nType, SwPosition const& rPosition)
+ : xBookmark ( xMark )
+ , nBkmType ( nType )
+ , aPosition ( rPosition )
+ {
+ }
+ sal_Int32 getIndex () const
+ {
+ return aPosition.nContent.GetIndex();
+ }
+ };
+ 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 nOwnNode
+ void lcl_FillBookmark(sw::mark::IMark* const pBkmk, const SwNodeIndex& nOwnNode, SwDoc& rDoc, SwXBookmarkPortion_ImplList& rBkmArr)
+ {
+ bool const hasOther = pBkmk->IsExpanded();
+
+ const SwPosition& rStartPos = pBkmk->GetMarkStart();
+ if(rStartPos.nNode == nOwnNode)
+ {
+ // #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.nNode == nOwnNode)
+ {
+ unique_ptr<SwPosition> pCrossRefEndPos;
+ 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
+ pCrossRefEndPos = std::make_unique<SwPosition>(rEndPos);
+ pCrossRefEndPos->nContent = pCrossRefEndPos->nNode.GetNode().GetTextNode()->Len();
+ pEndPos = pCrossRefEndPos.get();
+ }
+ 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;
+
+ const SwNodeIndex nOwnNode = rUnoCursor.GetPoint()->nNode;
+ SwTextNode* pTextNode = nOwnNode.GetNode().GetTextNode();
+ if (!pTextNode)
+ {
+ // no need to consider marks starting after aEndOfPara
+ SwPosition aEndOfPara(*rUnoCursor.GetPoint());
+ aEndOfPara.nContent = aEndOfPara.nNode.GetNode().GetTextNode()->Len();
+ const IDocumentMarkAccess::const_iterator_t pCandidatesEnd =
+ pMarkAccess->findFirstBookmarkStartsAfter(aEndOfPara);
+
+ // search for all bookmarks that start or end in this paragraph
+ for(IDocumentMarkAccess::const_iterator_t ppMark = pMarkAccess->getBookmarksBegin();
+ ppMark != pCandidatesEnd;
+ ++ppMark)
+ {
+ ::sw::mark::IMark* const pBkmk = *ppMark;
+ lcl_FillBookmark(pBkmk, nOwnNode, rDoc, rBkmArr);
+ }
+ }
+ else
+ {
+ // A text node already knows its marks via its SwIndexes.
+ o3tl::sorted_vector<const sw::mark::IMark*> aSeenMarks;
+ for (const SwIndex* 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, nOwnNode, rDoc, rBkmArr);
+ }
+ }
+ }
+
+ class theSwXTextPortionEnumerationUnoTunnelId : public rtl::Static< UnoTunnelIdInit, theSwXTextPortionEnumerationUnoTunnelId > {};
+ struct SwAnnotationStartPortion_Impl
+ {
+
+ uno::Reference< text::XTextField > mxAnnotationField;
+ const SwPosition maPosition;
+
+ SwAnnotationStartPortion_Impl(
+ uno::Reference< text::XTextField > const& xAnnotationField,
+ SwPosition const& rPosition)
+ : mxAnnotationField ( xAnnotationField )
+ , maPosition ( rPosition )
+ {
+ }
+
+ sal_Int32 getIndex () const
+ {
+ return maPosition.nContent.GetIndex();
+ }
+ };
+ 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
+ SwPosition aEndOfPara(*rUnoCursor.GetPoint());
+ aEndOfPara.nContent = aEndOfPara.nNode.GetNode().GetTextNode()->Len();
+ const IDocumentMarkAccess::const_iterator_t pCandidatesEnd =
+ pMarkAccess->findFirstAnnotationStartsAfter(aEndOfPara);
+
+ // search for all annotation marks that have its start position in this paragraph
+ const SwNodeIndex nOwnNode = rUnoCursor.GetPoint()->nNode;
+ 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.nNode != nOwnNode)
+ 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));
+ }
+ }
+}
+
+const uno::Sequence< sal_Int8 > & SwXTextPortionEnumeration::getUnoTunnelId()
+{
+ return theSwXTextPortionEnumerationUnoTunnelId::get().getSeq();
+}
+
+sal_Int64 SAL_CALL SwXTextPortionEnumeration::getSomething(
+ const uno::Sequence< sal_Int8 >& rId )
+{
+ if( isUnoTunnelId<SwXTextPortionEnumeration>(rId) )
+ {
+ return sal::static_int_cast< sal_Int64 >( reinterpret_cast< sal_IntPtr >( this ) );
+ }
+ return 0;
+}
+
+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,
+ uno::Reference< XText > const & xParentText,
+ const sal_Int32 nStart,
+ const sal_Int32 nEnd )
+ : m_Portions()
+{
+ m_pUnoCursor = rParaCursor.GetDoc()->CreateUnoCursor(*rParaCursor.GetPoint());
+
+ OSL_ENSURE(nEnd == -1 || (nStart <= nEnd &&
+ nEnd <= m_pUnoCursor->Start()->nNode.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()->nNode, frames, true);
+ lcl_CreatePortions(m_Portions, xParentText, &*m_pUnoCursor, frames, nStart, nEnd);
+}
+
+SwXTextPortionEnumeration::SwXTextPortionEnumeration(
+ SwPaM& rParaCursor,
+ TextRangeList_t const & rPortions )
+ : m_Portions( rPortions )
+{
+ m_pUnoCursor = rParaCursor.GetDoc()->CreateUnoCursor(*rParaCursor.GetPoint());
+}
+
+SwXTextPortionEnumeration::~SwXTextPortionEnumeration()
+{
+ SolarMutexGuard aGuard;
+ 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 <<= 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()->nNode.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 uno::Reference<text::XTextRange>
+lcl_ExportFieldMark(
+ uno::Reference< text::XText > const & i_xParentText,
+ SwUnoCursor * const pUnoCursor,
+ const SwTextNode * const pTextNode )
+{
+ uno::Reference<text::XTextRange> xRef;
+ SwDoc* pDoc = 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()->nContent.GetIndex();
+ OSL_ENSURE(pUnoCursor->End()->nContent.GetIndex() == 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;
+ if (pDoc)
+ {
+ pFieldmark = pDoc->getIDocumentMarkAccess()->
+ getFieldmarkAt(*pUnoCursor->GetMark());
+ }
+ SwXTextPortion* pPortion = new SwXTextPortion(
+ pUnoCursor, i_xParentText, PORTION_FIELD_START);
+ xRef = pPortion;
+ if (pFieldmark && pDoc)
+ {
+ pPortion->SetBookmark(
+ SwXFieldmark::CreateXFieldmark(*pDoc, pFieldmark));
+ }
+ }
+ else if (CH_TXT_ATR_FIELDSEP == Char)
+ {
+ // TODO how to get the field?
+ SwXTextPortion* pPortion = new SwXTextPortion(
+ pUnoCursor, i_xParentText, PORTION_FIELD_SEP);
+ xRef = pPortion;
+ }
+ else if (CH_TXT_ATR_FIELDEND == Char)
+ {
+ ::sw::mark::IFieldmark* pFieldmark = nullptr;
+ if (pDoc)
+ {
+ pFieldmark = pDoc->getIDocumentMarkAccess()->
+ getFieldmarkAt(*pUnoCursor->GetMark());
+ }
+ SwXTextPortion* pPortion = new SwXTextPortion(
+ pUnoCursor, i_xParentText, PORTION_FIELD_END);
+ xRef = pPortion;
+ if (pFieldmark && pDoc)
+ {
+ pPortion->SetBookmark(
+ SwXFieldmark::CreateXFieldmark(*pDoc, pFieldmark));
+ }
+ }
+ else if (CH_TXT_ATR_FORMELEMENT == Char)
+ {
+ ::sw::mark::IFieldmark* pFieldmark = nullptr;
+ if (pDoc)
+ {
+ pFieldmark = pDoc->getIDocumentMarkAccess()->getFieldmarkAt(*pUnoCursor->GetMark());
+ }
+ SwXTextPortion* pPortion = new SwXTextPortion(
+ pUnoCursor, i_xParentText, PORTION_FIELD_START_END);
+ xRef = pPortion;
+ if (pFieldmark && pDoc)
+ {
+ pPortion->SetBookmark(
+ SwXFieldmark::CreateXFieldmark(*pDoc, pFieldmark));
+ }
+ }
+ else
+ {
+ OSL_FAIL("no fieldmark found?");
+ }
+ return xRef;
+}
+
+static Reference<XTextRange>
+lcl_CreateRefMarkPortion(
+ Reference<XText> const& xParent,
+ const SwUnoCursor * const pUnoCursor,
+ const SwTextAttr & rAttr, const bool bEnd)
+{
+ SwDoc* pDoc = pUnoCursor->GetDoc();
+ SwFormatRefMark& rRefMark = const_cast<SwFormatRefMark&>(
+ static_cast<const SwFormatRefMark&>(rAttr.GetAttr()));
+ Reference<XTextContent> xContent;
+ if (!xContent.is())
+ {
+ xContent = SwXReferenceMark::CreateXReferenceMark(*pDoc, &rRefMark);
+ }
+
+ SwXTextPortion* pPortion = nullptr;
+ 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)
+{
+ SwXTextPortion* pPortion = new SwXTextPortion(pUnoCursor,
+ static_txtattr_cast<const SwTextRuby&>(rAttr), xParent, bEnd);
+ rPortions.emplace_back(pPortion);
+ pPortion->SetCollapsed(rAttr.End() == nullptr);
+}
+
+static Reference<XTextRange>
+lcl_CreateTOXMarkPortion(
+ Reference<XText> const& xParent,
+ const SwUnoCursor * const pUnoCursor,
+ SwTextAttr & rAttr, const bool bEnd)
+{
+ SwDoc* pDoc = pUnoCursor->GetDoc();
+ SwTOXMark & rTOXMark = static_cast<SwTOXMark&>(rAttr.GetAttr());
+
+ const Reference<XTextContent> xContent =
+ SwXDocumentIndexMark::CreateXDocumentIndexMark(*pDoc, & rTOXMark);
+
+ SwXTextPortion* pPortion = nullptr;
+ 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 uno::Reference<text::XTextRange>
+lcl_CreateMetaPortion(
+ uno::Reference<text::XText> const& xParent,
+ const SwUnoCursor * const pUnoCursor,
+ SwTextAttr & rAttr, std::unique_ptr<TextRangeList_t const> && pPortions)
+{
+ const uno::Reference<rdf::XMetadatable> xMeta( SwXMeta::CreateXMeta(
+ *static_cast<SwFormatMeta &>(rAttr.GetAttr()).GetMeta(),
+ xParent, std::move(pPortions)));
+ SwXTextPortion * pPortion(nullptr);
+ if (RES_TXTATR_META == rAttr.Which())
+ {
+ const uno::Reference<text::XTextContent> xContent(xMeta,
+ uno::UNO_QUERY);
+ pPortion = new SwXTextPortion(pUnoCursor, xParent, PORTION_META);
+ pPortion->SetMeta(xContent);
+ }
+ else
+ {
+ const uno::Reference<text::XTextField> xField(xMeta, uno::UNO_QUERY);
+ pPortion = new SwXTextPortion(pUnoCursor, xParent, PORTION_FIELD);
+ pPortion->SetTextField(xField);
+ }
+ 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 std::set<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
+ 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)
+ {
+ 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 ( SwSoftPageBreakList::iterator aIter = rBreakArr.begin(),
+ aEnd = rBreakArr.end();
+ aIter != aEnd; )
+ {
+ 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()->nContent.GetIndex()
+ : m_pRedline->End() ->nContent.GetIndex();
+ }
+};
+
+}
+
+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 Reference<XTextRange>
+lcl_ExportHints(
+ PortionStack_t & rPortionStack,
+ const Reference<XText> & 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)
+ // otherwise, the portion for the attribute is inserted into rPortions!
+ Reference<XTextRange> xRef;
+ SwDoc* pDoc = pUnoCursor->GetDoc();
+ //search for special text attributes - first some ends
+ size_t nEndIndex = 0;
+ sal_Int32 nNextEnd = 0;
+ while(nEndIndex < pHints->Count() &&
+ (!pHints->GetSortedByEnd(nEndIndex)->GetEnd() ||
+ nCurrentIndex >= (nNextEnd = (*pHints->GetSortedByEnd(nEndIndex)->GetEnd()))))
+ {
+ if(pHints->GetSortedByEnd(nEndIndex)->GetEnd())
+ {
+ SwTextAttr * const pAttr = pHints->GetSortedByEnd(nEndIndex);
+ if (nNextEnd == nCurrentIndex)
+ {
+ const sal_uInt16 nWhich( pAttr->Which() );
+ switch (nWhich)
+ {
+ case RES_TXTATR_TOXMARK:
+ {
+ Reference<XTextRange> xTmp = lcl_CreateTOXMarkPortion(
+ xParent, pUnoCursor, *pAttr, true);
+ rPortionStack.top().first->push_back(xTmp);
+ }
+ break;
+ case RES_TXTATR_REFMARK:
+ {
+ Reference<XTextRange> 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();
+ const uno::Reference<text::XTextRange> xPortion(
+ lcl_CreateMetaPortion(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 < pHints->Count() &&
+ 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;
+ SwXTextPortion* pPortion;
+ xRef = pPortion =
+ new SwXTextPortion(
+ pUnoCursor, xParent, PORTION_FIELD);
+ Reference<XTextField> const xField =
+ SwXTextField::CreateXTextField(pDoc,
+ &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 )
+ {
+ SwXTextPortion* pPortion = new SwXTextPortion( pUnoCursor, xParent, PORTION_ANNOTATION_END );
+ pPortion->SetBookmark(SwXBookmark::CreateXBookmark(
+ *pDoc, pAnnotationMark));
+ xRef = pPortion;
+ }
+ else
+ {
+ SwXTextPortion* pPortion = new SwXTextPortion( pUnoCursor, xParent, PORTION_ANNOTATION );
+ Reference<XTextField> xField =
+ SwXTextField::CreateXTextField(pDoc,
+ &pAttr->GetFormatField());
+ pPortion->SetTextField(xField);
+ xRef = pPortion;
+ }
+ }
+ break;
+
+ case RES_TXTATR_INPUTFIELD:
+ if(!bRightMoveForbidden)
+ {
+
+ pUnoCursor->Right(
+ pAttr->GetFormatField().GetField()->ExpandField(true, nullptr).getLength() + 2 );
+ if( *pUnoCursor->GetMark() == *pUnoCursor->GetPoint() )
+ break;
+ SwXTextPortion* pPortion =
+ new SwXTextPortion( pUnoCursor, xParent, PORTION_FIELD);
+ xRef = pPortion;
+ Reference<XTextField> xField =
+ SwXTextField::CreateXTextField(pDoc,
+ &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();
+ xRef = new SwXTextPortion( pUnoCursor, xParent, PORTION_FRAME);
+ }
+ break;
+
+ case RES_TXTATR_FTN:
+ {
+ if(!bRightMoveForbidden)
+ {
+ pUnoCursor->Right(1);
+ if( *pUnoCursor->GetMark() == *pUnoCursor->GetPoint() )
+ break;
+ SwXTextPortion* pPortion;
+ xRef = pPortion = new SwXTextPortion(
+ pUnoCursor, xParent, PORTION_FOOTNOTE);
+ Reference<XFootnote> xContent =
+ SwXFootnotes::GetObject(*pDoc, 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);
+ }
+ Reference<XTextRange> 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();
+ xRef = 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:
+ 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_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 (xRef.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;
+ 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 xRef;
+}
+
+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->GetContentNode()->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()->nContent = 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 )
+ {
+ const SwPosition* pStart = rUnoCursor.GetPoint();
+ const SwNodeIndex nOwnNode = pStart->nNode;
+
+ for(size_t nRed = 0; nRed < nRedTableCount; ++nRed)
+ {
+ const SwRangeRedline* pRedline = rRedTable[nRed];
+ const SwPosition* pRedStart = pRedline->Start();
+ const SwNodeIndex nRedNode = pRedStart->nNode;
+ if ( nOwnNode == nRedNode )
+ rRedArr.insert( std::make_shared<SwXRedlinePortion_Impl>(
+ pRedline, true ) );
+ if( pRedline->HasMark() && pRedline->End()->nNode == nOwnNode )
+ rRedArr.insert( std::make_shared<SwXRedlinePortion_Impl>(
+ pRedline, false ) );
+ }
+ }
+}
+
+static void lcl_FillSoftPageBreakArray(
+ SwUnoCursor const & rUnoCursor,
+ SwSoftPageBreakList& rBreakArr )
+{
+ const SwTextNode *pTextNode =
+ rUnoCursor.GetPoint()->nNode.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 std::set<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 std::set<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)
+ {
+ 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,
+ std::set<sal_Int32>& rFramePositions)
+{
+ for (const auto& rFrame : rFrames)
+ {
+ if (rFrame.nIndex < nCurrentIndex)
+ continue;
+
+ if (rFrame.nIndex > nCurrentIndex)
+ break;
+
+ const SwModify* pFrame = rFrame.pFrameClient->GetRegisteredIn();
+ if (!pFrame)
+ continue;
+
+ auto& rFormat = *static_cast<SwFrameFormat*>(const_cast<SwModify*>(pFrame));
+ const SwFormatAnchor& rAnchor = rFormat.GetAnchor();
+ const SwPosition* pPosition = rAnchor.GetContentAnchor();
+ if (!pPosition)
+ continue;
+
+ rFramePositions.insert(pPosition->nContent.GetIndex());
+ }
+}
+
+/**
+ * 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
+ {
+ const SwModify * const pFrame =
+ i_rFrames.front().pFrameClient->GetRegisteredIn();
+ if (pFrame) // Frame could be disposed
+ {
+ SwXTextPortion* pPortion = new SwXTextPortion(i_pUnoCursor, i_xParent,
+ *static_cast<SwFrameFormat*>( const_cast<SwModify*>( 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,
+ uno::Reference< text::XText > const & i_xParentText,
+ SwUnoCursor * const pUnoCursor,
+ FrameClientSortList_t & i_rFrames,
+ const sal_Int32 i_nStartPos,
+ const sal_Int32 i_nEndPos )
+{
+ if (!pUnoCursor)
+ return;
+
+ // set the start if a selection should be exported
+ if ((i_nStartPos > 0) &&
+ (pUnoCursor->Start()->nContent.GetIndex() != i_nStartPos))
+ {
+ pUnoCursor->DeleteMark();
+ OSL_ENSURE(pUnoCursor->Start()->nNode.GetNode().GetTextNode() &&
+ (i_nStartPos <= pUnoCursor->Start()->nNode.GetNode().GetTextNode()->
+ GetText().getLength()), "Incorrect start position" );
+ // ??? should this be i_nStartPos - current position ?
+ pUnoCursor->Right(i_nStartPos);
+ }
+
+ SwDoc * const pDoc = pUnoCursor->GetDoc();
+
+ std::deque<sal_Int32> FieldMarks;
+ lcl_FillFieldMarkArray(FieldMarks, *pUnoCursor, i_nStartPos);
+
+ SwXBookmarkPortion_ImplList Bookmarks;
+ lcl_FillBookmarkArray(*pDoc, *pUnoCursor, Bookmarks);
+
+ SwXRedlinePortion_ImplList Redlines;
+ lcl_FillRedlineArray(*pDoc, *pUnoCursor, Redlines);
+
+ SwSoftPageBreakList SoftPageBreaks;
+ lcl_FillSoftPageBreakArray(*pUnoCursor, SoftPageBreaks);
+
+ SwAnnotationStartPortion_ImplList AnnotationStarts;
+ lcl_FillAnnotationStartArray( *pDoc, *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->GetNode().GetTextNode();
+ if (!pTextNode)
+ {
+ OSL_FAIL("lcl_CreatePortions: no TextNode - what now ?");
+ return;
+ }
+
+ SwpHints * const pHints = pTextNode->GetpSwpHints();
+ const sal_Int32 nCurrentIndex =
+ pUnoCursor->GetPoint()->nContent.GetIndex();
+ // this contains the portion which consumes the character in the
+ // text at nCurrentIndex; i.e. it must be set _once_ per iteration
+ uno::Reference< XTextRange > xRef;
+
+ SwUnoCursorHelper::SelectPam(*pUnoCursor, true); // set mark
+
+ // First remember the frame positions.
+ std::set<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);
+ }
+
+ 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 000000000..615b1b04c
--- /dev/null
+++ b/sw/source/core/unocore/unoredline.cxx
@@ -0,0 +1,587 @@
+/* -*- 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 <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 <IDocumentStylePoolAccess.hxx>
+#include <docary.hxx>
+
+using namespace ::com::sun::star;
+
+SwXRedlineText::SwXRedlineText(SwDoc* _pDoc, const SwNodeIndex& aIndex) :
+ SwXText(_pDoc, CursorType::Redline),
+ aNodeIndex(aIndex)
+{
+}
+
+const SwStartNode* SwXRedlineText::GetStartNode() const
+{
+ return 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>();
+}
+
+uno::Reference<text::XTextCursor> SwXRedlineText::createTextCursor()
+{
+ SolarMutexGuard aGuard;
+
+ SwPosition aPos(aNodeIndex);
+ SwXTextCursor *const 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.GetNode().FindTableNode();
+ SwContentNode* pContentNode = nullptr;
+ bool bTable = pTableNode != nullptr;
+ while( pTableNode != nullptr )
+ {
+ rUnoCursor.GetPoint()->nNode = *(pTableNode->EndOfSectionNode());
+ pContentNode = GetDoc()->GetNodes().GoNext(&rUnoCursor.GetPoint()->nNode);
+ pTableNode = pContentNode->FindTableNode();
+ }
+ if( pContentNode != nullptr )
+ rUnoCursor.GetPoint()->nContent.Assign( pContentNode, 0 );
+ if( bTable && rUnoCursor.GetNode().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.
+ uno::RuntimeException aExcept;
+ aExcept.Message =
+ "No content node found that is inside this change section "
+ "but outside of a table";
+ throw aExcept;
+ }
+
+ return static_cast<text::XWordCursor*>(pXCursor);
+}
+
+uno::Reference<text::XTextCursor> SwXRedlineText::createTextCursorByRange(
+ const uno::Reference<text::XTextRange> & aTextRange)
+{
+ uno::Reference<text::XTextCursor> xCursor = createTextCursor();
+ xCursor->gotoRange(aTextRange->getStart(), false);
+ xCursor->gotoRange(aTextRange->getEnd(), true);
+ return xCursor;
+}
+
+uno::Reference<container::XEnumeration> SwXRedlineText::createEnumeration()
+{
+ SolarMutexGuard aGuard;
+ SwPaM aPam(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)
+{
+ uno::Sequence<beans::PropertyValue> aValues(4);
+
+ const SwRedlineData* pNext = rRedline.GetRedlineData().Next();
+ if(pNext)
+ {
+ beans::PropertyValue* pValues = aValues.getArray();
+ pValues[0].Name = UNO_NAME_REDLINE_AUTHOR;
+ // GetAuthorString(n) walks the SwRedlineData* chain;
+ // here we always need element 1
+ pValues[0].Value <<= rRedline.GetAuthorString(1);
+ pValues[1].Name = UNO_NAME_REDLINE_DATE_TIME;
+ pValues[1].Value <<= pNext->GetTimeStamp().GetUNODateTime();
+ pValues[2].Name = UNO_NAME_REDLINE_COMMENT;
+ pValues[2].Value <<= pNext->GetComment();
+ pValues[3].Name = UNO_NAME_REDLINE_TYPE;
+ pValues[3].Value <<= SwRedlineTypeToOUString(pNext->GetType());
+ }
+ return aValues;
+}
+
+uno::Any SwXRedlinePortion::getPropertyValue( const OUString& rPropertyName )
+{
+ SolarMutexGuard aGuard;
+ Validate();
+ uno::Any aRet;
+ if(rPropertyName == UNO_NAME_REDLINE_TEXT)
+ {
+ SwNodeIndex* pNodeIdx = m_rRedline.GetContentIdx();
+ if(pNodeIdx )
+ {
+ if ( 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;
+}
+
+void SwXRedlinePortion::Validate()
+{
+ SwUnoCursor& rUnoCursor = GetCursor();
+ //search for the redline
+ SwDoc* pDoc = rUnoCursor.GetDoc();
+ const SwRedlineTable& rRedTable = pDoc->getIDocumentRedlineAccess().GetRedlineTable();
+ bool bFound = false;
+ for(size_t nRed = 0; nRed < rRedTable.size() && !bFound; nRed++)
+ bFound = &m_rRedline == rRedTable[nRed];
+ if(!bFound)
+ throw uno::RuntimeException();
+}
+
+uno::Sequence< sal_Int8 > SAL_CALL SwXRedlinePortion::getImplementationId( )
+{
+ return css::uno::Sequence<sal_Int8>();
+}
+
+uno::Any SwXRedlinePortion::GetPropertyValue( const OUString& 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_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()->nNode );
+ }
+ 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();
+
+ SwNodeIndex* pNodeIdx = rRedline.GetContentIdx();
+ if(pNodeIdx )
+ {
+ if ( 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),
+ pDoc(&rDoc),
+ pRedline(&rRedline)
+{
+ StartListening(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(!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;
+ 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(!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 = &pRedline->GetNode();
+ if(!bStart && pRedline->HasMark())
+ pNode = &pRedline->GetNode(false);
+ 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 || !pRedline->HasMark())
+ pPoint = pRedline->GetPoint();
+ else
+ pPoint = pRedline->GetMark();
+ const uno::Reference<text::XTextRange> xRange =
+ SwXTextRange::CreateXTextRange(*pDoc, *pPoint, nullptr);
+ xRet = xRange.get();
+ }
+ break;
+ default:
+ OSL_FAIL("illegal node type");
+ }
+ aRet <<= xRet;
+ }
+ else if(rPropertyName == UNO_NAME_REDLINE_TEXT)
+ {
+ SwNodeIndex* pNodeIdx = pRedline->GetContentIdx();
+ if( pNodeIdx )
+ {
+ if ( 1 < ( pNodeIdx->GetNode().EndOfSectionIndex() - pNodeIdx->GetNode().GetIndex() ) )
+ {
+ uno::Reference<text::XText> xRet = new SwXRedlineText(pDoc, *pNodeIdx);
+ aRet <<= xRet;
+ }
+ else {
+ OSL_FAIL("Empty section in redline portion! (end node immediately follows start node)");
+ }
+ }
+ }
+ else
+ aRet = SwXRedlinePortion::GetPropertyValue(rPropertyName, *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)
+ {
+ pDoc = nullptr;
+ 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(!pDoc)
+ throw uno::RuntimeException();
+
+ SwNodeIndex* pNodeIndex = 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(!pDoc)
+ throw uno::RuntimeException();
+ return nullptr != pRedline->GetContentIdx();
+}
+
+uno::Reference< text::XTextCursor > SwXRedline::createTextCursor()
+{
+ SolarMutexGuard aGuard;
+ if(!pDoc)
+ throw uno::RuntimeException();
+
+ uno::Reference< text::XTextCursor > xRet;
+ SwNodeIndex* pNodeIndex = pRedline->GetContentIdx();
+ if(!pNodeIndex)
+ {
+ throw uno::RuntimeException();
+ }
+
+ SwPosition aPos(*pNodeIndex);
+ SwXTextCursor *const pXCursor =
+ new SwXTextCursor(*pDoc, this, CursorType::Redline, aPos);
+ auto& rUnoCursor(pXCursor->GetCursor());
+ rUnoCursor.Move(fnMoveForward, GoInNode);
+
+ // is here a table?
+ SwTableNode* pTableNode = rUnoCursor.GetNode().FindTableNode();
+ SwContentNode* pCont = nullptr;
+ while( pTableNode )
+ {
+ rUnoCursor.GetPoint()->nNode = *pTableNode->EndOfSectionNode();
+ pCont = GetDoc()->GetNodes().GoNext(&rUnoCursor.GetPoint()->nNode);
+ pTableNode = pCont->FindTableNode();
+ }
+ if(pCont)
+ rUnoCursor.GetPoint()->nContent.Assign(pCont, 0);
+ xRet = static_cast<text::XWordCursor*>(pXCursor);
+
+ return xRet;
+}
+
+uno::Reference< text::XTextCursor > SwXRedline::createTextCursorByRange(
+ 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 000000000..bbab06ed6
--- /dev/null
+++ b/sw/source/core/unocore/unoredlines.cxx
@@ -0,0 +1,168 @@
+/* -*- 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 <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;
+ if(!IsValid())
+ throw uno::RuntimeException();
+ const SwRedlineTable& rRedTable = GetDoc()->getIDocumentRedlineAccess().GetRedlineTable();
+ return rRedTable.size();
+}
+
+uno::Any SwXRedlines::getByIndex(sal_Int32 nIndex)
+{
+ SolarMutexGuard aGuard;
+ if(!IsValid())
+ throw uno::RuntimeException();
+ const SwRedlineTable& rRedTable = GetDoc()->getIDocumentRedlineAccess().GetRedlineTable();
+ if ((nIndex < 0) || (rRedTable.size() <= o3tl::make_unsigned(nIndex)))
+ throw lang::IndexOutOfBoundsException();
+
+ uno::Reference <beans::XPropertySet> xRet = SwXRedlines::GetObject( *rRedTable[nIndex], *GetDoc() );
+ return uno::Any(xRet);
+}
+
+uno::Reference< container::XEnumeration > SwXRedlines::createEnumeration()
+{
+ SolarMutexGuard aGuard;
+ if(!IsValid())
+ throw uno::RuntimeException();
+ return uno::Reference< container::XEnumeration >(new SwXRedlineEnumeration(*GetDoc()));
+}
+
+uno::Type SwXRedlines::getElementType( )
+{
+ return cppu::UnoType<beans::XPropertySet>::get();
+}
+
+sal_Bool SwXRedlines::hasElements( )
+{
+ SolarMutexGuard aGuard;
+ if(!IsValid())
+ throw uno::RuntimeException();
+ 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) :
+ pDoc(&rDoc),
+ nCurrentIndex(0)
+{
+ StartListening(pDoc->getIDocumentStylePoolAccess().GetPageDescFromPool(RES_POOLPAGE_STANDARD)->GetNotifier());
+}
+
+SwXRedlineEnumeration::~SwXRedlineEnumeration()
+{
+}
+
+sal_Bool SwXRedlineEnumeration::hasMoreElements()
+{
+ if(!pDoc)
+ throw uno::RuntimeException();
+ return pDoc->getIDocumentRedlineAccess().GetRedlineTable().size() > nCurrentIndex;
+}
+
+uno::Any SwXRedlineEnumeration::nextElement()
+{
+ if(!pDoc)
+ throw uno::RuntimeException();
+ const SwRedlineTable& rRedTable = pDoc->getIDocumentRedlineAccess().GetRedlineTable();
+ if( rRedTable.size() <= nCurrentIndex )
+ throw container::NoSuchElementException();
+ uno::Reference <beans::XPropertySet> xRet = SwXRedlines::GetObject( *rRedTable[nCurrentIndex++], *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)
+ 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 000000000..a69fd2cab
--- /dev/null
+++ b/sw/source/core/unocore/unorefmk.cxx
@@ -0,0 +1,1522 @@
+/* -*- 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/interfacecontainer2.hxx>
+#include <comphelper/processfactory.hxx>
+#include <comphelper/servicehelper.hxx>
+#include <cppuhelper/exc_hlp.hxx>
+#include <cppuhelper/supportsservice.hxx>
+#include <cppuhelper/weak.hxx>
+#include <osl/mutex.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
+{
+private:
+ ::osl::Mutex m_Mutex; // just for OInterfaceContainerHelper2
+
+public:
+ uno::WeakReference<uno::XInterface> m_wThis;
+ ::comphelper::OInterfaceContainerHelper2 m_EventListeners;
+ bool m_bIsDescriptor;
+ SwDoc* m_pDoc;
+ const SwFormatRefMark* m_pMarkFormat;
+ OUString m_sMarkName;
+
+ Impl(SwDoc* const pDoc, SwFormatRefMark* const pRefMark)
+ : m_EventListeners(m_Mutex)
+ , 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);
+ m_EventListeners.disposeAndClear(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()
+{
+}
+
+uno::Reference<text::XTextContent>
+SwXReferenceMark::CreateXReferenceMark(
+ SwDoc & rDoc, SwFormatRefMark *const pMarkFormat)
+{
+ // i#105557: do not iterate over the registered clients: race condition
+ uno::Reference<text::XTextContent> xMark;
+ if (pMarkFormat)
+ {
+ xMark = pMarkFormat->GetXRefMark();
+ }
+ if (!xMark.is())
+ {
+ SwXReferenceMark *const pMark(new SwXReferenceMark(&rDoc, pMarkFormat));
+ xMark.set(pMark);
+ if (pMarkFormat)
+ {
+ pMarkFormat->SetXRefMark(xMark);
+ }
+ // need a permanent Reference to initialize m_wThis
+ pMark->m_pImpl->m_wThis = xMark;
+ }
+ return xMark;
+}
+
+namespace
+{
+ class theSwXReferenceMarkUnoTunnelId : public rtl::Static< UnoTunnelIdInit, theSwXReferenceMarkUnoTunnelId > {};
+}
+
+const uno::Sequence< sal_Int8 > & SwXReferenceMark::getUnoTunnelId()
+{
+ return theSwXReferenceMarkUnoTunnelId::get().getSeq();
+}
+
+sal_Int64 SAL_CALL
+SwXReferenceMark::getSomething(const uno::Sequence< sal_Int8 >& rId)
+{
+ return ::sw::UnoTunnelImpl<SwXReferenceMark>(rId, this);
+}
+
+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 *pDoc2 = rPam.GetDoc();
+
+ UnoActionContext aCont(pDoc2);
+ 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.GetNode().GetTextNode()->GetTextAttrsAt(
+ rPam.GetPoint()->nContent.GetIndex(), RES_TXTATR_REFMARK);
+ }
+
+ pDoc2->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.GetNode().GetTextNode()->GetTextAttrsAt(
+ rPam.GetPoint()->nContent.GetIndex(), 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.GetNode().GetTextNode();
+ assert(pTextNd);
+ pTextAttr = pTextNd ? rPam.GetNode().GetTextNode()->GetTextAttrForCharAt(
+ rPam.GetPoint()->nContent.GetIndex() - 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();
+ }
+ uno::Reference<lang::XUnoTunnel> xRangeTunnel( xTextRange, uno::UNO_QUERY);
+ SwXTextRange* pRange = nullptr;
+ OTextCursorHelper* pCursor = nullptr;
+ if(xRangeTunnel.is())
+ {
+ pRange = ::sw::UnoTunnelGetImplementation<SwXTextRange>(xRangeTunnel);
+ pCursor =
+ ::sw::UnoTunnelGetImplementation<OTextCursorHelper>(xRangeTunnel);
+ }
+ 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 && (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 std::unique_ptr<SwPaM> pPam( (pTextMark->End())
+ ? new SwPaM( rTextNode, *pTextMark->End(),
+ rTextNode, pTextMark->GetStart())
+ : new SwPaM( 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 && (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
+ m_pImpl->m_EventListeners.addInterface(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
+ m_pImpl->m_EventListeners.removeInterface(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 && (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;
+ virtual uno::Reference< text::XTextCursor >
+ CreateCursor() override;
+
+public:
+ SwXMetaText(SwDoc & rDoc, SwXMeta & rMeta);
+
+ /// make available for SwXMeta
+ using SwXText::Invalidate;
+
+ // XInterface
+ virtual void SAL_CALL acquire() throw() override { cppu::OWeakObject::acquire(); }
+ virtual void SAL_CALL release() throw() override { cppu::OWeakObject::release(); }
+
+ // XTypeProvider
+ virtual uno::Sequence< sal_Int8 > SAL_CALL
+ getImplementationId() override;
+
+ // XText
+ virtual uno::Reference< text::XTextCursor > SAL_CALL
+ createTextCursor() override;
+ virtual uno::Reference< text::XTextCursor > SAL_CALL
+ createTextCursorByRange(
+ const uno::Reference< text::XTextRange > & xTextPosition) override;
+
+};
+
+}
+
+SwXMetaText::SwXMetaText(SwDoc & rDoc, SwXMeta & rMeta)
+ : SwXText(&rDoc, CursorType::Meta)
+ , m_rMeta(rMeta)
+{
+}
+
+const SwStartNode *SwXMetaText::GetStartNode() const
+{
+ SwXText const * const pParent(
+ dynamic_cast<SwXText*>(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);
+}
+
+uno::Reference< text::XTextCursor > SwXMetaText::CreateCursor()
+{
+ uno::Reference< text::XTextCursor > 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 = static_cast<text::XWordCursor*>(
+ 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
+uno::Reference< text::XTextCursor > SAL_CALL
+SwXMetaText::createTextCursor()
+{
+ return CreateCursor();
+}
+
+uno::Reference< text::XTextCursor > SAL_CALL
+SwXMetaText::createTextCursorByRange(
+ const uno::Reference<text::XTextRange> & xTextPosition)
+{
+ const uno::Reference<text::XTextCursor> xCursor( CreateCursor() );
+ 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
+class SwXMeta::Impl : public SvtListener
+{
+private:
+ ::osl::Mutex m_Mutex; // just for OInterfaceContainerHelper2
+
+public:
+ uno::WeakReference<uno::XInterface> m_wThis;
+ ::comphelper::OInterfaceContainerHelper2 m_EventListeners;
+ std::unique_ptr<const TextRangeList_t> m_pTextPortions;
+ // 3 possible states: not attached, attached, disposed
+ bool m_bIsDisposed;
+ bool m_bIsDescriptor;
+ uno::Reference<text::XText> m_xParentText;
+ rtl::Reference<SwXMetaText> m_xText;
+ sw::Meta* m_pMeta;
+
+ Impl(SwXMeta& rThis, SwDoc& rDoc,
+ ::sw::Meta* const pMeta,
+ uno::Reference<text::XText> const& xParentText,
+ std::unique_ptr<TextRangeList_t const> pPortions)
+ : m_EventListeners(m_Mutex)
+ , m_pTextPortions(std::move(pPortions))
+ , m_bIsDisposed(false)
+ , m_bIsDescriptor(nullptr == pMeta)
+ , m_xParentText(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;
+}
+
+// SwModify
+void SwXMeta::Impl::Notify(const SfxHint& rHint)
+{
+ m_pTextPortions.reset(); // throw away cache (SwTextNode changed)
+ if(rHint.GetId() == SfxHintId::Dying || rHint.GetId() == SfxHintId::Deinitializing)
+ {
+ 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);
+ m_EventListeners.disposeAndClear(ev);
+ }
+}
+
+uno::Reference<text::XText> const & SwXMeta::GetParentText() const
+{
+ return m_pImpl->m_xParentText;
+}
+
+SwXMeta::SwXMeta(SwDoc *const pDoc, ::sw::Meta *const pMeta,
+ uno::Reference<text::XText> 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()
+{
+}
+
+uno::Reference<rdf::XMetadatable>
+SwXMeta::CreateXMeta(SwDoc & rDoc, bool const isField)
+{
+ SwXMeta *const pXMeta(isField
+ ? new SwXMetaField(& rDoc) : new SwXMeta(& rDoc));
+ // this is why the constructor is private: need to acquire pXMeta here
+ uno::Reference<rdf::XMetadatable> const xMeta(pXMeta);
+ // need a permanent Reference to initialize m_wThis
+ pXMeta->m_pImpl->m_wThis = xMeta;
+ return xMeta;
+}
+
+uno::Reference<rdf::XMetadatable>
+SwXMeta::CreateXMeta(::sw::Meta & rMeta,
+ uno::Reference<text::XText> const& i_xParent,
+ std::unique_ptr<TextRangeList_t const> && pPortions)
+{
+ // re-use existing SwXMeta
+ // #i105557#: do not iterate over the registered clients: race condition
+ uno::Reference<rdf::XMetadatable> xMeta(rMeta.GetXMeta());
+ if (xMeta.is())
+ {
+ if (pPortions) // set cache in the XMeta to the given portions
+ {
+ SwXMeta *const pXMeta(
+ comphelper::getUnoTunnelImplementation<SwXMeta>(xMeta));
+ assert(pXMeta);
+ // 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!
+ pXMeta->m_pImpl->m_pTextPortions = std::move(pPortions);
+ // ??? is this necessary?
+ if (pXMeta->m_pImpl->m_xParentText.get() != i_xParent.get())
+ {
+ SAL_WARN("sw.uno", "SwXMeta with different parent?");
+ pXMeta->m_pImpl->m_xParentText.set(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; }
+ uno::Reference<text::XText> 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.set( ::sw::CreateParentXText(*pTextNode->GetDoc(), aPos) );
+ }
+ if (!xParentText.is()) { return nullptr; }
+ SwXMeta *const pXMeta( (RES_TXTATR_META == rMeta.GetFormatMeta()->Which())
+ ? new SwXMeta (pTextNode->GetDoc(), &rMeta, xParentText,
+ std::move(pPortions))
+ : new SwXMetaField(pTextNode->GetDoc(), &rMeta, xParentText,
+ std::move(pPortions)));
+ // this is why the constructor is private: need to acquire pXMeta here
+ xMeta.set(pXMeta);
+ // in order to initialize the weak pointer cache in the core object
+ rMeta.SetXMeta(xMeta);
+ // need a permanent Reference to initialize m_wThis
+ pXMeta->m_pImpl->m_wThis = xMeta;
+ 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->nNode.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->nContent.GetIndex());
+ // 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->nNode.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->nContent.GetIndex());
+ // 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;
+}
+
+namespace
+{
+ class theSwXMetaUnoTunnelId : public rtl::Static< UnoTunnelIdInit, theSwXMetaUnoTunnelId > {};
+}
+
+const uno::Sequence< sal_Int8 > & SwXMeta::getUnoTunnelId()
+{
+ return theSwXMetaUnoTunnelId::get().getSeq();
+}
+
+// XUnoTunnel
+sal_Int64 SAL_CALL
+SwXMeta::getSomething( const uno::Sequence< sal_Int8 > & i_rId )
+{
+ return ::sw::UnoTunnelImpl<SwXMeta>(i_rId, this);
+}
+
+// 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
+ m_pImpl->m_EventListeners.addInterface(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
+ m_pImpl->m_EventListeners.removeInterface(xListener);
+}
+
+void SAL_CALL
+SwXMeta::dispose()
+{
+ SolarMutexGuard g;
+
+ if (m_pImpl->m_bIsDescriptor)
+ {
+ m_pImpl->m_pTextPortions.reset();
+ lang::EventObject const ev(static_cast< ::cppu::OWeakObject&>(*this));
+ m_pImpl->m_EventListeners.disposeAndClear(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 * const pDoc( pTextNode->GetDoc() );
+ pDoc->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",
+ static_cast< ::cppu::OWeakObject* >(this));
+ }
+
+ uno::Reference<lang::XUnoTunnel> xRangeTunnel(i_xTextRange, uno::UNO_QUERY);
+ if (!xRangeTunnel.is())
+ {
+ throw lang::IllegalArgumentException(
+ "SwXMeta::attach(): argument is no XUnoTunnel",
+ static_cast< ::cppu::OWeakObject* >(this), 0);
+ }
+ SwXTextRange *const pRange(
+ ::sw::UnoTunnelGetImplementation<SwXTextRange>(xRangeTunnel));
+ OTextCursorHelper *const pCursor( pRange ? nullptr :
+ ::sw::UnoTunnelGetImplementation<OTextCursorHelper>(xRangeTunnel));
+ if (!pRange && !pCursor)
+ {
+ throw lang::IllegalArgumentException(
+ "SwXMeta::attach(): argument not supported type",
+ static_cast< ::cppu::OWeakObject* >(this), 0);
+ }
+
+ SwDoc * const pDoc(
+ pRange ? &pRange->GetDoc() : pCursor->GetDoc());
+ if (!pDoc)
+ {
+ throw lang::IllegalArgumentException(
+ "SwXMeta::attach(): argument has no SwDoc",
+ static_cast< ::cppu::OWeakObject* >(this), 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?",
+ static_cast< ::cppu::OWeakObject* >(this), 1);
+ }
+ if (!pTextAttr)
+ {
+ OSL_FAIL("meta inserted, but has no text attribute?");
+ throw uno::RuntimeException(
+ "SwXMeta::attach(): cannot create meta",
+ static_cast< ::cppu::OWeakObject* >(this));
+ }
+
+ m_pImpl->EndListeningAll();
+ m_pImpl->m_pMeta = pMeta.get();
+ m_pImpl->StartListening(pMeta->GetNotifier());
+ pMeta->SetXMeta(uno::Reference<rdf::XMetadatable>(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",
+ static_cast< ::cppu::OWeakObject* >(this));
+ }
+
+ 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",
+ static_cast< ::cppu::OWeakObject* >(this));
+ }
+
+ 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",
+ static_cast< ::cppu::OWeakObject* >(this));
+ }
+
+ 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, *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,
+ uno::Reference<text::XText> const& xParentText,
+ std::unique_ptr<TextRangeList_t const> pPortions)
+ : SwXMetaField_Base(pDoc, pMeta, xParentText, std::move(pPortions))
+{
+ OSL_ENSURE(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 bool bPrefix)
+{
+ 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);
+ return bPrefix ? xOdfPrefix : xOdfSuffix;
+}
+
+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)
+{
+ 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(true));
+ }
+ if (o_pSuffix)
+ {
+ *o_pSuffix = lcl_getPrefixOrSuffix(xRepo, xMeta, lcl_getURI(false));
+ }
+ } 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);
+ 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 000000000..831f0bda3
--- /dev/null
+++ b/sw/source/core/unocore/unosect.cxx
@@ -0,0 +1,1735 @@
+/* -*- 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 <com/sun/star/beans/PropertyAttribute.hpp>
+#include <com/sun/star/lang/WrappedTargetRuntimeException.hpp>
+#include <com/sun/star/text/SectionFileLink.hpp>
+
+#include <comphelper/interfacecontainer2.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/mutex.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 <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>
+
+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
+{
+private:
+ ::osl::Mutex m_Mutex; // just for OInterfaceContainerHelper2
+
+public:
+ SwXTextSection & m_rThis;
+ uno::WeakReference<uno::XInterface> m_wThis;
+ const SfxItemPropertySet & m_rPropSet;
+ ::comphelper::OInterfaceContainerHelper2 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)
+ : SvtListener()
+ , m_rThis(rThis)
+ , m_rPropSet(*aSwMapProvider.GetPropertySet(PROPERTY_MAP_SECTION))
+ , m_EventListeners(m_Mutex)
+ , 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);
+ m_EventListeners.disposeAndClear(ev);
+ }
+}
+
+SwSectionFormat * SwXTextSection::GetFormat() const
+{
+ return m_pImpl->GetSectionFormat();
+}
+
+uno::Reference< text::XTextSection >
+SwXTextSection::CreateXTextSection(
+ SwSectionFormat *const pFormat, const bool bIndexHeader)
+{
+ // re-use existing SwXTextSection
+ // #i105557#: do not iterate over the registered clients: race condition
+ uno::Reference< text::XTextSection > xSection;
+ if (pFormat)
+ {
+ xSection.set(pFormat->GetXTextSection());
+ }
+ if ( !xSection.is() )
+ {
+ SwXTextSection *const pNew = new SwXTextSection(pFormat, bIndexHeader);
+ xSection.set(pNew);
+ if (pFormat)
+ {
+ pFormat->SetXTextSection(xSection);
+ }
+ // need a permanent Reference to initialize m_wThis
+ pNew->m_pImpl->m_wThis = xSection;
+ }
+ return xSection;
+}
+
+SwXTextSection::SwXTextSection(
+ SwSectionFormat *const pFormat, const bool bIndexHeader)
+ : m_pImpl( new SwXTextSection::Impl(*this, pFormat, bIndexHeader) )
+{
+}
+
+SwXTextSection::~SwXTextSection()
+{
+}
+
+namespace
+{
+ class theSwXTextSectionUnoTunnelId : public rtl::Static< UnoTunnelIdInit, theSwXTextSectionUnoTunnelId > {};
+}
+
+const uno::Sequence< sal_Int8 > & SwXTextSection::getUnoTunnelId()
+{
+ return theSwXTextSectionUnoTunnelId::get().getSeq();
+}
+
+sal_Int64 SAL_CALL
+SwXTextSection::getSomething(const uno::Sequence< sal_Int8 >& rId)
+{
+ return ::sw::UnoTunnelImpl<SwXTextSection>(rId, this);
+}
+
+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();
+ }
+
+ uno::Reference<lang::XUnoTunnel> xRangeTunnel( xTextRange, uno::UNO_QUERY);
+ SwXTextRange* pRange = nullptr;
+ OTextCursorHelper* pCursor = nullptr;
+ if(xRangeTunnel.is())
+ {
+ pRange = ::sw::UnoTunnelGetImplementation<SwXTextRange>(xRangeTunnel);
+ pCursor =
+ ::sw::UnoTunnelGetImplementation<OTextCursorHelper>(xRangeTunnel);
+ }
+
+ 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);
+
+ SfxItemSet aSet(
+ pDoc->GetAttrPool(),
+ svl::Items<
+ 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>{});
+ 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",
+ static_cast< ::cppu::OWeakObject*>(this), 0);
+ }
+ m_pImpl->Attach(pRet->GetFormat());
+ pRet->GetFormat()->SetXObject(static_cast< ::cppu::OWeakObject*>(this));
+
+ // 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;
+
+ uno::Reference< text::XTextRange > 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() )
+ {
+ SwPaM aPaM(*pIdx);
+ aPaM.Move( fnMoveForward, GoInContent );
+
+ const SwEndNode* pEndNode = pIdx->GetNode().EndOfSectionNode();
+ SwPaM aEnd(*pEndNode);
+ aEnd.Move( fnMoveBackward, GoInContent );
+ 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
+ m_pImpl->m_EventListeners.addInterface(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
+ m_pImpl->m_EventListeners.removeInterface(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::unique_ptr<SfxItemSet> const& pItemSet,
+ bool const bLinkModeChanged, bool const bLinkUpdateAlways = true)
+{
+ if (pFormat)
+ {
+ 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, pItemSet.get(),
+ 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::unique_ptr<SfxItemSet> pItemSet;
+ bool bLinkModeChanged = false;
+ bool bLinkMode = false;
+
+ for (sal_Int32 nProperty = 0; nProperty < rPropertyNames.getLength();
+ nProperty++)
+ {
+ SfxItemPropertySimpleEntry const*const pEntry =
+ m_rPropSet.getPropertyMap().getByName(pPropertyNames[nProperty]);
+ if (!pEntry)
+ {
+ throw beans::UnknownPropertyException(
+ "Unknown property: " + pPropertyNames[nProperty],
+ static_cast<cppu::OWeakObject *>(& m_rThis));
+ }
+ if (pEntry->nFlags & beans::PropertyAttribute::READONLY)
+ {
+ throw beans::PropertyVetoException(
+ "Property is read-only: " + pPropertyNames[nProperty],
+ static_cast<cppu::OWeakObject *>(& m_rThis));
+ }
+ 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) +
+ pSectionData->GetLinkFileName().getToken(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();
+ pItemSet.reset( new SfxItemSet(*rOldAttrSet.GetPool(), {{pEntry->nWID, pEntry->nWID}}));
+ pItemSet->Put(rOldAttrSet);
+ m_rPropSet.setPropertyValue(*pEntry,
+ pValues[nProperty], *pItemSet);
+ }
+ 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, pItemSet, 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;
+
+ uno::Sequence< OUString > aPropertyNames { rPropertyName };
+ uno::Sequence< uno::Any > aValues(1);
+ aValues.getArray()[0] = rValue;
+ m_pImpl->SetPropertyValues_Impl( aPropertyNames, aValues );
+}
+
+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++)
+ {
+ SfxItemPropertySimpleEntry const*const pEntry =
+ m_rPropSet.getPropertyMap().getByName(pPropertyNames[nProperty]);
+ if (!pEntry)
+ {
+ throw beans::UnknownPropertyException(
+ "Unknown property: " + pPropertyNames[nProperty],
+ static_cast<cppu::OWeakObject *>(& m_rThis));
+ }
+ 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], OUString(), 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->GetNode();
+ const SwNode& rRedMarkNode = pRedline->GetNode(false);
+ 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",
+ static_cast < cppu::OWeakObject * > ( this ), anyEx );
+ }
+ catch (lang::WrappedTargetException &)
+ {
+ css::uno::Any anyEx = cppu::getCaughtException();
+ throw lang::WrappedTargetRuntimeException("WrappedTargetException caught",
+ static_cast < cppu::OWeakObject * > ( this ), 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;
+ SfxItemPropertySimpleEntry const*const pEntry =
+ m_pImpl->m_rPropSet.getPropertyMap().getByName( pNames[i]);
+ if (!pEntry)
+ {
+ throw beans::UnknownPropertyException(
+ "Unknown property: " + pNames[i],
+ static_cast< cppu::OWeakObject* >(this));
+ }
+ 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();
+ }
+
+ SfxItemPropertySimpleEntry const*const pEntry =
+ m_pImpl->m_rPropSet.getPropertyMap().getByName(rPropertyName);
+ if (!pEntry)
+ {
+ throw beans::UnknownPropertyException(
+ "Unknown property: " + rPropertyName,
+ static_cast< cppu::OWeakObject* >(this));
+ }
+ if (pEntry->nFlags & beans::PropertyAttribute::READONLY)
+ {
+ throw uno::RuntimeException(
+ "Property is read-only: " + rPropertyName,
+ static_cast<cppu::OWeakObject *>(this));
+ }
+
+ std::unique_ptr<SwSectionData> const pSectionData(
+ pFormat ? new SwSectionData(*pFormat->GetSection()) : nullptr);
+
+ std::unique_ptr<SfxItemSet> pNewAttrSet;
+ 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();
+ pNewAttrSet.reset( new SfxItemSet(*rOldAttrSet.GetPool(), {{pEntry->nWID, pEntry->nWID}}));
+ pNewAttrSet->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, pNewAttrSet, bLinkModeChanged);
+}
+
+uno::Any SAL_CALL
+SwXTextSection::getPropertyDefault(const OUString& rPropertyName)
+{
+ SolarMutexGuard aGuard;
+
+ uno::Any aRet;
+ SwSectionFormat *const pFormat = m_pImpl->GetSectionFormat();
+ SfxItemPropertySimpleEntry const*const pEntry =
+ m_pImpl->m_rPropSet.getPropertyMap().getByName(rPropertyName);
+ if (!pEntry)
+ {
+ throw beans::UnknownPropertyException(
+ "Unknown property: " + rPropertyName,
+ static_cast<cppu::OWeakObject *>(this));
+ }
+
+ 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, OUString(), 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 000000000..81f1a6a2e
--- /dev/null
+++ b/sw/source/core/unocore/unosett.cxx
@@ -0,0 +1,2446 @@
+/* -*- 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 <unostyle.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 <fmtclds.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 <com/sun/star/style/VerticalAlignment.hpp>
+#include <o3tl/any.hxx>
+#include <o3tl/enumarray.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>
+#include <numeric>
+
+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();
+ }
+}
+// Constants for the css::text::ColumnSeparatorStyle
+#define API_COL_LINE_NONE 0
+#define API_COL_LINE_SOLID 1
+#define API_COL_LINE_DOTTED 2
+#define API_COL_LINE_DASHED 3
+
+#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[] =
+ {
+ { OUString(UNO_NAME_ANCHOR_CHAR_STYLE_NAME),WID_ANCHOR_CHARACTER_STYLE, ::cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ { OUString(UNO_NAME_BEGIN_NOTICE), WID_BEGIN_NOTICE, ::cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ { OUString(UNO_NAME_CHAR_STYLE_NAME), WID_CHARACTER_STYLE, ::cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ { OUString(UNO_NAME_END_NOTICE), WID_END_NOTICE , ::cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ { OUString(UNO_NAME_FOOTNOTE_COUNTING), WID_FOOTNOTE_COUNTING, ::cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE, 0},
+ { OUString(UNO_NAME_NUMBERING_TYPE), WID_NUMBERING_TYPE, ::cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE, 0},
+ { OUString(UNO_NAME_PAGE_STYLE_NAME), WID_PAGE_STYLE, ::cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ { OUString(UNO_NAME_PARA_STYLE_NAME), WID_PARAGRAPH_STYLE, ::cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ { OUString(UNO_NAME_POSITION_END_OF_DOC), WID_POSITION_END_OF_DOC,cppu::UnoType<bool>::get(), PROPERTY_NONE, 0},
+ { OUString(UNO_NAME_PREFIX), WID_PREFIX, ::cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ { OUString(UNO_NAME_START_AT), WID_START_AT , ::cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE, 0},
+ { OUString(UNO_NAME_SUFFIX), WID_SUFFIX, ::cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ { OUString(), 0, css::uno::Type(), 0, 0 }
+ };
+ static const SfxItemPropertySet aFootnoteSet_Impl(aFootnoteMap_Impl);
+ return &aFootnoteSet_Impl;
+}
+
+static const SfxItemPropertySet* GetEndnoteSet()
+{
+ static const SfxItemPropertyMapEntry aEndnoteMap_Impl[] =
+ {
+ { OUString(UNO_NAME_ANCHOR_CHAR_STYLE_NAME),WID_ANCHOR_CHARACTER_STYLE, ::cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ { OUString(UNO_NAME_CHAR_STYLE_NAME), WID_CHARACTER_STYLE, ::cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ { OUString(UNO_NAME_NUMBERING_TYPE), WID_NUMBERING_TYPE, ::cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE, 0},
+ { OUString(UNO_NAME_PAGE_STYLE_NAME), WID_PAGE_STYLE, ::cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ { OUString(UNO_NAME_PARA_STYLE_NAME), WID_PARAGRAPH_STYLE, ::cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ { OUString(UNO_NAME_PREFIX), WID_PREFIX, ::cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ { OUString(UNO_NAME_START_AT), WID_START_AT , ::cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE, 0},
+ { OUString(UNO_NAME_SUFFIX), WID_SUFFIX, ::cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ { OUString(), 0, css::uno::Type(), 0, 0 }
+ };
+ static const SfxItemPropertySet aEndnoteSet_Impl(aEndnoteMap_Impl);
+ return &aEndnoteSet_Impl;
+}
+
+static const SfxItemPropertySet* GetNumberingRulesSet()
+{
+ static const SfxItemPropertyMapEntry aNumberingRulesMap_Impl[] =
+ {
+ { OUString(UNO_NAME_IS_ABSOLUTE_MARGINS), WID_IS_ABS_MARGINS, cppu::UnoType<bool>::get(), PROPERTY_NONE, 0},
+ { OUString(UNO_NAME_IS_AUTOMATIC), WID_IS_AUTOMATIC, cppu::UnoType<bool>::get(), PROPERTY_NONE, 0},
+ { OUString(UNO_NAME_IS_CONTINUOUS_NUMBERING), WID_CONTINUOUS, cppu::UnoType<bool>::get(), PROPERTY_NONE, 0},
+ { OUString(UNO_NAME_NAME), WID_RULE_NAME , ::cppu::UnoType<OUString>::get(), PropertyAttribute::READONLY, 0},
+ { OUString(UNO_NAME_NUMBERING_IS_OUTLINE), WID_IS_OUTLINE, cppu::UnoType<bool>::get(), PROPERTY_NONE, 0},
+ { OUString(UNO_NAME_DEFAULT_LIST_ID), WID_DEFAULT_LIST_ID, ::cppu::UnoType<OUString>::get(), PropertyAttribute::READONLY, 0},
+ { OUString(), 0, css::uno::Type(), 0, 0 }
+ };
+ static const SfxItemPropertySet aNumberingRulesSet_Impl( aNumberingRulesMap_Impl );
+ return &aNumberingRulesSet_Impl;
+}
+
+static const SfxItemPropertySet* GetLineNumberingSet()
+{
+ static const SfxItemPropertyMapEntry aLineNumberingMap_Impl[] =
+ {
+ { OUString(UNO_NAME_CHAR_STYLE_NAME), WID_CHARACTER_STYLE, ::cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ { OUString(UNO_NAME_COUNT_EMPTY_LINES), WID_COUNT_EMPTY_LINES , cppu::UnoType<bool>::get(),PROPERTY_NONE, 0},
+ { OUString(UNO_NAME_COUNT_LINES_IN_FRAMES), WID_COUNT_LINES_IN_FRAMES, cppu::UnoType<bool>::get(),PROPERTY_NONE, 0},
+ { OUString(UNO_NAME_DISTANCE), WID_DISTANCE , ::cppu::UnoType<sal_Int32>::get(),PROPERTY_NONE, 0},
+ { OUString(UNO_NAME_IS_ON), WID_NUM_ON, cppu::UnoType<bool>::get() , PROPERTY_NONE, 0},
+ { OUString(UNO_NAME_INTERVAL), WID_INTERVAL , ::cppu::UnoType<sal_Int16>::get(),PROPERTY_NONE, 0},
+ { OUString(UNO_NAME_SEPARATOR_TEXT), WID_SEPARATOR_TEXT, ::cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
+ { OUString(UNO_NAME_NUMBER_POSITION), WID_NUMBER_POSITION, ::cppu::UnoType<sal_Int16>::get(),PROPERTY_NONE, 0},
+ { OUString(UNO_NAME_NUMBERING_TYPE), WID_NUMBERING_TYPE , ::cppu::UnoType<sal_Int16>::get(),PROPERTY_NONE, 0},
+ { OUString(UNO_NAME_RESTART_AT_EACH_PAGE), WID_RESTART_AT_EACH_PAGE, cppu::UnoType<bool>::get() , PROPERTY_NONE, 0},
+ { OUString(UNO_NAME_SEPARATOR_INTERVAL), WID_SEPARATOR_INTERVAL, ::cppu::UnoType<sal_Int16>::get(),PROPERTY_NONE, 0},
+ { OUString(), 0, css::uno::Type(), 0, 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, unsigned short> aSvxToUnoAdjust
+{
+ text::HoriOrientation::LEFT, //3
+ text::HoriOrientation::RIGHT, //1
+ USHRT_MAX,
+ text::HoriOrientation::CENTER, //2
+ USHRT_MAX,
+ USHRT_MAX
+};
+
+const unsigned short aUnoToSvxAdjust[] =
+{
+ USHRT_MAX,
+ static_cast<unsigned short>(SvxAdjust::Right), // 1
+ static_cast<unsigned short>(SvxAdjust::Center), // 3
+ static_cast<unsigned short>(SvxAdjust::Left), // 0
+ USHRT_MAX,
+ USHRT_MAX
+};
+
+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 SfxItemPropertySimpleEntry* pEntry = m_pPropertySet->getPropertyMap().getByName( rPropertyName );
+ if(!pEntry)
+ throw beans::UnknownPropertyException("Unknown property: " + rPropertyName, static_cast < cppu::OWeakObject * > ( this ) );
+
+ if ( pEntry->nFlags & PropertyAttribute::READONLY)
+ throw PropertyVetoException("Property is read-only: " + rPropertyName, static_cast < cppu::OWeakObject * > ( this ) );
+ 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 SfxItemPropertySimpleEntry* pEntry = m_pPropertySet->getPropertyMap().getByName( rPropertyName );
+ if(!pEntry)
+ throw UnknownPropertyException("Unknown property: " + rPropertyName, static_cast < cppu::OWeakObject * > ( this ) );
+
+ 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)
+ {
+ const SfxItemPropertySimpleEntry* pEntry = m_pPropertySet->getPropertyMap().getByName( rPropertyName );
+ if(!pEntry)
+ throw UnknownPropertyException("Unknown property: " + rPropertyName, static_cast < cppu::OWeakObject * > ( this ) );
+
+ if ( pEntry->nFlags & PropertyAttribute::READONLY)
+ throw PropertyVetoException("Property is read-only: " + rPropertyName, static_cast < cppu::OWeakObject * > ( this ) );
+ 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 SfxItemPropertySimpleEntry* pEntry = m_pPropertySet->getPropertyMap().getByName( rPropertyName );
+ if(!pEntry)
+ throw UnknownPropertyException("Unknown property: " + rPropertyName, static_cast < cppu::OWeakObject * > ( this ) );
+
+ 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 SfxItemPropertySimpleEntry* pEntry = m_pPropertySet->getPropertyMap().getByName( rPropertyName );
+ if(!pEntry)
+ throw UnknownPropertyException("Unknown property: " + rPropertyName, static_cast < cppu::OWeakObject * > ( this ) );
+
+ if ( pEntry->nFlags & PropertyAttribute::READONLY)
+ throw PropertyVetoException("Property is read-only: " + rPropertyName, static_cast < cppu::OWeakObject * > ( this ) );
+ 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 = convertMm100ToTwip(nVal);
+ if (nTmp > SAL_MAX_UINT16)
+ nTmp = SAL_MAX_UINT16;
+ aFontMetric.SetPosFromLeft( static_cast< sal_uInt16 >(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 SfxItemPropertySimpleEntry* pEntry = m_pPropertySet->getPropertyMap().getByName( rPropertyName );
+ if(!pEntry)
+ throw UnknownPropertyException("Unknown property: " + rPropertyName, static_cast < cppu::OWeakObject * > ( this ) );
+
+ 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");
+}
+
+static const char aInvalidStyle[] = "__XXX___invalid";
+
+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(const OUString &rName)
+{
+ return rName == aInvalidStyle;
+}
+
+namespace
+{
+ class theSwXNumberingRulesUnoTunnelId : public rtl::Static< UnoTunnelIdInit, theSwXNumberingRulesUnoTunnelId > {};
+}
+
+const uno::Sequence< sal_Int8 > & SwXNumberingRules::getUnoTunnelId()
+{
+ return theSwXNumberingRulesUnoTunnelId::get().getSeq();
+}
+
+// return implementation specific data
+sal_Int64 SwXNumberingRules::getSomething( const uno::Sequence< sal_Int8 > & rId )
+{
+ if( isUnoTunnelId<SwXNumberingRules>(rId) )
+ {
+ return sal::static_int_cast< sal_Int64 >( reinterpret_cast< sal_IntPtr >(this) );
+ }
+ return 0;
+}
+
+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)
+{
+ 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
+ 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() &&
+ m_sNewCharStyleNames[i] != UNO_NAME_CHARACTER_FORMAT_NONE &&
+ (!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();
+ }
+ 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;
+}
+
+static const char* 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( static_cast<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()));
+ }
+
+ //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())
+ {
+ //BulletId
+ nINT16 = rFormat.GetBulletChar();
+ aPropertyValues.push_back(comphelper::makePropertyValue("BulletId", nINT16));
+
+ const vcl::Font* pFont = rFormat.GetBulletFont();
+
+ //BulletChar
+ aUString = OUString(rFormat.GetBulletChar());
+ 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( static_cast<sal_uInt16>(nIndex) ));
+
+ OUString sHeadingStyleName;
+ OUString sParagraphStyleName;
+
+ SetPropertiesToNumFormat(aFormat, m_sNewCharStyleNames[nIndex],
+ &m_sNewBulletFontNames[nIndex],
+ &sHeadingStyleName, &sParagraphStyleName,
+ m_pDoc, 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(static_cast<sal_uInt16>(nIndex), aFormat);
+}
+
+void SwXNumberingRules::SetPropertiesToNumFormat(
+ SwNumFormat & aFormat,
+ OUString & rCharStyleName, OUString *const pBulletFontName,
+ OUString *const pHeadingStyleName,
+ OUString *const pParagraphStyleName,
+ SwDoc *const pDoc,
+ const uno::Sequence<beans::PropertyValue>& rProperties)
+{
+ 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;
+ if (nValue > text::HoriOrientation::NONE &&
+ nValue <= text::HoriOrientation::LEFT &&
+ USHRT_MAX != aUnoToSvxAdjust[nValue])
+ {
+ aFormat.SetNumAdjust(static_cast<SvxAdjust>(aUnoToSvxAdjust[nValue]));
+ }
+ else
+ bWrongArg = true;
+ }
+ 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 );
+ if (sCharFormatName == UNO_NAME_CHARACTER_FORMAT_NONE)
+ {
+ rCharStyleName = aInvalidStyle;
+ aFormat.SetCharFormat(nullptr);
+ }
+ else if(pDoc)
+ {
+ const SwCharFormats* pFormats = pDoc->GetCharFormats();
+ const size_t nChCount = pFormats->size();
+
+ SwCharFormat* pCharFormat = nullptr;
+ if (!sCharFormatName.isEmpty())
+ {
+ for(size_t j = 0; j< nChCount; ++j)
+ {
+ SwCharFormat* pTmp = (*pFormats)[j];
+ if(pTmp->GetName() == sCharFormatName)
+ {
+ pCharFormat = pTmp;
+ break;
+ }
+ }
+ if(!pCharFormat)
+ {
+
+ SfxStyleSheetBase* pBase;
+ SfxStyleSheetBasePool* pPool = pDoc->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(convertMm100ToTwip(nValue));
+ }
+ else if (rProp.Name == UNO_NAME_SYMBOL_TEXT_DISTANCE)
+ {
+ sal_Int32 nValue = 0;
+ rProp.Value >>= nValue;
+ if (nValue >= 0)
+ aFormat.SetCharTextDistance(static_cast<short>(convertMm100ToTwip(nValue)));
+ 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 = convertMm100ToTwip(nValue);
+ 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 = convertMm100ToTwip(nValue);
+ 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 = convertMm100ToTwip(nValue);
+ aFormat.SetFirstLineIndent( nValue );
+ }
+ else if (rProp.Name == UNO_NAME_INDENT_AT)
+ {
+ sal_Int32 nValue = 0;
+ rProp.Value >>= nValue;
+ nValue = convertMm100ToTwip(nValue);
+ 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* pLclDocShell = nullptr;
+ if( !sBulletFontName.isEmpty() && pDoc && (pLclDocShell = pDoc->GetDocShell()) )
+ {
+ 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.getLength() == 1)
+ {
+ aFormat.SetBulletChar(aChar.toChar());
+ }
+ else if(aChar.isEmpty())
+ {
+ // If w:lvlText's value is null - set bullet char to zero
+ aFormat.SetBulletChar(u'\0');
+ }
+ 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)
+ {
+ size.Width = convertMm100ToTwip(size.Width);
+ size.Height = convertMm100ToTwip(size.Height);
+ pSetSize->setWidth( size.Width );
+ pSetSize->setHeight( size.Height );
+ }
+ 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)
+ {
+ 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
+ {
+ // Invalid property name
+ SAL_WARN("sw.uno", "Unknown/incorrect property " << rProp.Name << ", failing");
+ throw uno::RuntimeException("Unknown/incorrect 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();
+ }
+}
+
+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*/)
+{
+ RuntimeException aExcept;
+ aExcept.Message = "readonly";
+ throw aExcept;
+}
+
+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()
+{
+}
+
+OUString SwXTextColumns::getImplementationName()
+{
+ return "SwXTextColumns";
+}
+
+sal_Bool SwXTextColumns::supportsService(const OUString& rServiceName)
+{
+ return cppu::supportsService(this, rServiceName);
+}
+
+Sequence< OUString > SwXTextColumns::getSupportedServiceNames()
+{
+ Sequence<OUString> aRet { "com.sun.star.text.TextColumns" };
+ return aRet;
+}
+
+SwXTextColumns::SwXTextColumns() :
+ m_nReference(0),
+ m_bIsAutomaticWidth(true),
+ m_nAutoDistance(0),
+ m_pPropSet(aSwMapProvider.GetPropertySet(PROPERTY_MAP_TEXT_COLUMS)),
+ m_nSepLineWidth(0),
+ m_nSepLineColor(0), //black
+ m_nSepLineHeightRelative(100),//full height
+ m_nSepLineVertAlign(style::VerticalAlignment_MIDDLE),
+ m_bSepLineIsOn(false),
+ m_nSepLineStyle(API_COL_LINE_NONE) // None
+{
+}
+
+SwXTextColumns::SwXTextColumns(const SwFormatCol& rFormatCol) :
+ m_nReference(0),
+ m_aTextColumns(rFormatCol.GetNumCols()),
+ m_bIsAutomaticWidth(rFormatCol.IsOrtho()),
+ m_pPropSet(aSwMapProvider.GetPropertySet(PROPERTY_MAP_TEXT_COLUMS))
+{
+ const sal_uInt16 nItemGutterWidth = rFormatCol.GetGutterWidth();
+ m_nAutoDistance = m_bIsAutomaticWidth ?
+ USHRT_MAX == nItemGutterWidth ? DEF_GUTTER_WIDTH : static_cast<sal_Int32>(nItemGutterWidth)
+ : 0;
+ m_nAutoDistance = convertTwipToMm100(m_nAutoDistance);
+
+ TextColumn* pColumns = m_aTextColumns.getArray();
+ const SwColumns& rCols = rFormatCol.GetColumns();
+ for(sal_Int32 i = 0; i < m_aTextColumns.getLength(); ++i)
+ {
+ const SwColumn* pCol = &rCols[i];
+
+ pColumns[i].Width = pCol->GetWishWidth();
+ m_nReference += pColumns[i].Width;
+ pColumns[i].LeftMargin = convertTwipToMm100(pCol->GetLeft ());
+ pColumns[i].RightMargin = convertTwipToMm100(pCol->GetRight());
+ }
+ if(!m_aTextColumns.hasElements())
+ m_nReference = USHRT_MAX;
+
+ m_nSepLineWidth = rFormatCol.GetLineWidth();
+ m_nSepLineColor = rFormatCol.GetLineColor();
+ m_nSepLineHeightRelative = rFormatCol.GetLineHeight();
+ m_bSepLineIsOn = rFormatCol.GetLineAdj() != COLADJ_NONE;
+ sal_Int8 nStyle = API_COL_LINE_NONE;
+ switch (rFormatCol.GetLineStyle())
+ {
+ case SvxBorderLineStyle::SOLID: nStyle = API_COL_LINE_SOLID; break;
+ case SvxBorderLineStyle::DOTTED: nStyle= API_COL_LINE_DOTTED; break;
+ case SvxBorderLineStyle::DASHED: nStyle= API_COL_LINE_DASHED; break;
+ default: break;
+ }
+ m_nSepLineStyle = nStyle;
+ switch(rFormatCol.GetLineAdj())
+ {
+ case COLADJ_TOP: m_nSepLineVertAlign = style::VerticalAlignment_TOP; break;
+ case COLADJ_BOTTOM: m_nSepLineVertAlign = style::VerticalAlignment_BOTTOM; break;
+ case COLADJ_CENTER:
+ case COLADJ_NONE: m_nSepLineVertAlign = style::VerticalAlignment_MIDDLE;
+ }
+}
+
+SwXTextColumns::~SwXTextColumns()
+{
+}
+
+sal_Int32 SwXTextColumns::getReferenceValue()
+{
+ SolarMutexGuard aGuard;
+ return m_nReference;
+}
+
+sal_Int16 SwXTextColumns::getColumnCount()
+{
+ SolarMutexGuard aGuard;
+ return static_cast< sal_Int16>( m_aTextColumns.getLength() );
+}
+
+void SwXTextColumns::setColumnCount(sal_Int16 nColumns)
+{
+ SolarMutexGuard aGuard;
+ if(nColumns <= 0)
+ throw uno::RuntimeException();
+ m_bIsAutomaticWidth = true;
+ m_aTextColumns.realloc(nColumns);
+ TextColumn* pCols = m_aTextColumns.getArray();
+ m_nReference = USHRT_MAX;
+ sal_Int32 nWidth = m_nReference / nColumns;
+ sal_Int32 nDiff = m_nReference - nWidth * nColumns;
+ sal_Int32 nDist = m_nAutoDistance / 2;
+ for(sal_Int16 i = 0; i < nColumns; i++)
+ {
+ pCols[i].Width = nWidth;
+ pCols[i].LeftMargin = i == 0 ? 0 : nDist;
+ pCols[i].RightMargin = i == nColumns - 1 ? 0 : nDist;
+ }
+ pCols[nColumns - 1].Width += nDiff;
+}
+
+uno::Sequence< TextColumn > SwXTextColumns::getColumns()
+{
+ SolarMutexGuard aGuard;
+ return m_aTextColumns;
+}
+
+void SwXTextColumns::setColumns(const uno::Sequence< TextColumn >& rColumns)
+{
+ SolarMutexGuard aGuard;
+ sal_Int32 nReferenceTemp = std::accumulate(rColumns.begin(), rColumns.end(), sal_Int32(0),
+ [](const sal_Int32 nSum, const TextColumn& rCol) { return nSum + rCol.Width; });
+ m_bIsAutomaticWidth = false;
+ m_nReference = !nReferenceTemp ? USHRT_MAX : nReferenceTemp;
+ m_aTextColumns = rColumns;
+}
+
+uno::Reference< XPropertySetInfo > SwXTextColumns::getPropertySetInfo( )
+{
+ static uno::Reference< beans::XPropertySetInfo > aRef = m_pPropSet->getPropertySetInfo();
+ return aRef;
+}
+
+void SwXTextColumns::setPropertyValue( const OUString& rPropertyName, const Any& aValue )
+{
+ const SfxItemPropertySimpleEntry* pEntry = m_pPropSet->getPropertyMap().getByName( rPropertyName );
+ if (!pEntry)
+ throw UnknownPropertyException("Unknown property: " + rPropertyName, static_cast < cppu::OWeakObject * > ( this ) );
+ if ( pEntry->nFlags & PropertyAttribute::READONLY)
+ throw PropertyVetoException("Property is read-only: " + rPropertyName, static_cast < cppu::OWeakObject * > ( this ) );
+
+ switch(pEntry->nWID)
+ {
+ case WID_TXTCOL_LINE_WIDTH:
+ {
+ sal_Int32 nTmp = 0;
+ aValue >>= nTmp;
+ if(nTmp < 0)
+ throw IllegalArgumentException();
+ m_nSepLineWidth = convertMm100ToTwip(nTmp);
+ }
+ break;
+ case WID_TXTCOL_LINE_COLOR:
+ aValue >>= m_nSepLineColor;
+ break;
+ case WID_TXTCOL_LINE_STYLE:
+ {
+ aValue >>= m_nSepLineStyle;
+ }
+ break;
+ case WID_TXTCOL_LINE_REL_HGT:
+ {
+ sal_Int8 nTmp = 0;
+ aValue >>= nTmp;
+ if(nTmp < 0)
+ throw IllegalArgumentException();
+ m_nSepLineHeightRelative = nTmp;
+ }
+ break;
+ case WID_TXTCOL_LINE_ALIGN:
+ {
+ style::VerticalAlignment eAlign;
+ if(!(aValue >>= eAlign) )
+ {
+ sal_Int8 nTmp = 0;
+ if (! ( aValue >>= nTmp ) )
+ throw IllegalArgumentException();
+ m_nSepLineVertAlign = static_cast<style::VerticalAlignment>(nTmp);
+ }
+ else
+ m_nSepLineVertAlign = eAlign;
+ }
+ break;
+ case WID_TXTCOL_LINE_IS_ON:
+ m_bSepLineIsOn = *o3tl::doAccess<bool>(aValue);
+ break;
+ case WID_TXTCOL_AUTO_DISTANCE:
+ {
+ sal_Int32 nTmp = 0;
+ aValue >>= nTmp;
+ if(nTmp < 0 || nTmp >= m_nReference)
+ throw IllegalArgumentException();
+ m_nAutoDistance = nTmp;
+ sal_Int32 nColumns = m_aTextColumns.getLength();
+ TextColumn* pCols = m_aTextColumns.getArray();
+ sal_Int32 nDist = m_nAutoDistance / 2;
+ for(sal_Int32 i = 0; i < nColumns; i++)
+ {
+ pCols[i].LeftMargin = i == 0 ? 0 : nDist;
+ pCols[i].RightMargin = i == nColumns - 1 ? 0 : nDist;
+ }
+ }
+ break;
+ }
+}
+
+Any SwXTextColumns::getPropertyValue( const OUString& rPropertyName )
+{
+ const SfxItemPropertySimpleEntry* pEntry = m_pPropSet->getPropertyMap().getByName( rPropertyName );
+ if (!pEntry)
+ throw UnknownPropertyException("Unknown property: " + rPropertyName, static_cast < cppu::OWeakObject * > ( this ) );
+
+ Any aRet;
+ switch(pEntry->nWID)
+ {
+ case WID_TXTCOL_LINE_WIDTH:
+ aRet <<= static_cast < sal_Int32 >(convertTwipToMm100(m_nSepLineWidth));
+ break;
+ case WID_TXTCOL_LINE_COLOR:
+ aRet <<= m_nSepLineColor;
+ break;
+ case WID_TXTCOL_LINE_STYLE:
+ aRet <<= m_nSepLineStyle;
+ break;
+ case WID_TXTCOL_LINE_REL_HGT:
+ aRet <<= m_nSepLineHeightRelative;
+ break;
+ case WID_TXTCOL_LINE_ALIGN:
+ aRet <<= m_nSepLineVertAlign;
+ break;
+ case WID_TXTCOL_LINE_IS_ON:
+ aRet <<= m_bSepLineIsOn;
+ break;
+ case WID_TXTCOL_IS_AUTOMATIC :
+ aRet <<= m_bIsAutomaticWidth;
+ break;
+ case WID_TXTCOL_AUTO_DISTANCE:
+ aRet <<= m_nAutoDistance;
+ break;
+ }
+ return aRet;
+}
+
+void SwXTextColumns::addPropertyChangeListener(
+ const OUString& /*rPropertyName*/, const uno::Reference< XPropertyChangeListener >& /*xListener*/ )
+{
+}
+
+void SwXTextColumns::removePropertyChangeListener(
+ const OUString& /*rPropertyName*/, const uno::Reference< XPropertyChangeListener >& /*xListener*/ )
+{
+}
+
+void SwXTextColumns::addVetoableChangeListener(
+ const OUString& /*rPropertyName*/, const uno::Reference< XVetoableChangeListener >& /*xListener*/ )
+{
+}
+
+void SwXTextColumns::removeVetoableChangeListener(
+ const OUString& /*rPropertyName*/, const uno::Reference< XVetoableChangeListener >& /*xListener*/ )
+{
+}
+
+namespace
+{
+ class theSwXTextColumnsUnoTunnelId : public rtl::Static< UnoTunnelIdInit, theSwXTextColumnsUnoTunnelId > {};
+}
+
+const uno::Sequence< sal_Int8 > & SwXTextColumns::getUnoTunnelId()
+{
+ return theSwXTextColumnsUnoTunnelId::get().getSeq();
+}
+
+sal_Int64 SAL_CALL SwXTextColumns::getSomething( const uno::Sequence< sal_Int8 >& rId )
+{
+ if( isUnoTunnelId<SwXTextColumns>(rId) )
+ {
+ return sal::static_int_cast< sal_Int64 >( reinterpret_cast< sal_IntPtr >(this) );
+ }
+ return 0;
+}
+
+/* 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 000000000..a4656104a
--- /dev/null
+++ b/sw/source/core/unocore/unosrch.cxx
@@ -0,0 +1,691 @@
+/* -*- 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>
+
+using namespace ::com::sun::star;
+
+class SwSearchProperties_Impl
+{
+ std::unique_ptr<std::unique_ptr<beans::PropertyValue>[]> pValueArr;
+ const PropertyEntryVector_t aPropertyEntries;
+
+ 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() :
+ aPropertyEntries( aSwMapProvider.GetPropertySet(PROPERTY_MAP_TEXT_CURSOR)->getPropertyMap().getPropertyEntries() )
+{
+ size_t nArrLen = aPropertyEntries.size();
+ pValueArr.reset( new std::unique_ptr<beans::PropertyValue>[nArrLen] );
+}
+
+void SwSearchProperties_Impl::SetProperties(const uno::Sequence< beans::PropertyValue >& aSearchAttribs)
+{
+ //delete all existing values
+ for(size_t i = 0; i < aPropertyEntries.size(); ++i)
+ {
+ pValueArr[i].reset();
+ }
+
+ for(const beans::PropertyValue& rSearchAttrib : aSearchAttribs)
+ {
+ const OUString& sName = rSearchAttrib.Name;
+ auto aIt = std::find_if(aPropertyEntries.begin(), aPropertyEntries.end(),
+ [&sName](const SfxItemPropertyNamedEntry& rProp) { return rProp.sName == sName; });
+ if( aIt == aPropertyEntries.end() )
+ throw beans::UnknownPropertyException(sName);
+ auto nIndex = static_cast<sal_uInt32>(std::distance(aPropertyEntries.begin(), aIt));
+ pValueArr[nIndex].reset( new beans::PropertyValue(rSearchAttrib) );
+ }
+}
+
+uno::Sequence< beans::PropertyValue > SwSearchProperties_Impl::GetProperties() const
+{
+ sal_uInt32 nPropCount = 0;
+ for( size_t i = 0; i < aPropertyEntries.size(); i++)
+ if(pValueArr[i])
+ nPropCount++;
+
+ uno::Sequence< beans::PropertyValue > aRet(nPropCount);
+ beans::PropertyValue* pProps = aRet.getArray();
+ nPropCount = 0;
+ for(size_t i = 0; i < aPropertyEntries.size(); i++)
+ {
+ if(pValueArr[i])
+ {
+ pProps[nPropCount++] = *(pValueArr[i]);
+ }
+ }
+ 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 ,
+ 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 ;
+
+ PropertyEntryVector_t::const_iterator aIt = aPropertyEntries.begin();
+ for(size_t i = 0; i < aPropertyEntries.size(); i++, ++aIt)
+ {
+ if(pValueArr[i])
+ {
+ SfxPoolItem* pTempItem = nullptr;
+ switch(aIt->nWID)
+ {
+ case RES_BOX:
+ if(!pBoxItem)
+ pBoxItem.reset(rSet.GetPool()->GetDefaultItem(aIt->nWID).Clone());
+ pTempItem = pBoxItem.get();
+ break;
+ case RES_CHRATR_BOX:
+ if(!pCharBoxItem)
+ pCharBoxItem.reset(rSet.GetPool()->GetDefaultItem(aIt->nWID).Clone());
+ pTempItem = pCharBoxItem.get();
+ break;
+ case RES_BREAK:
+ if(!pBreakItem)
+ pBreakItem.reset(rSet.GetPool()->GetDefaultItem(aIt->nWID).Clone());
+ pTempItem = pBreakItem.get();
+ break;
+ case RES_CHRATR_AUTOKERN:
+ if(!pAutoKernItem)
+ pAutoKernItem.reset(rSet.GetPool()->GetDefaultItem(aIt->nWID).Clone());
+ pTempItem = pAutoKernItem.get();
+ break;
+ case RES_CHRATR_BACKGROUND:
+ if(!pBrushItem)
+ pBrushItem.reset(rSet.GetPool()->GetDefaultItem(aIt->nWID).Clone());
+ pTempItem = pBrushItem.get();
+ break;
+ case RES_CHRATR_CASEMAP:
+ if(!pCasemapItem)
+ pCasemapItem.reset(rSet.GetPool()->GetDefaultItem(aIt->nWID).Clone());
+ pTempItem = pCasemapItem.get();
+ break;
+ case RES_CHRATR_COLOR:
+ if(!pCharColorItem)
+ pCharColorItem.reset(rSet.GetPool()->GetDefaultItem(aIt->nWID).Clone());
+ pTempItem = pCharColorItem.get();
+ break;
+ case RES_CHRATR_CONTOUR:
+ if(!pContourItem)
+ pContourItem.reset(rSet.GetPool()->GetDefaultItem(aIt->nWID).Clone());
+ pTempItem = pContourItem.get();
+ break;
+ case RES_CHRATR_CROSSEDOUT:
+ if(!pCrossedOutItem)
+ pCrossedOutItem.reset(rSet.GetPool()->GetDefaultItem(aIt->nWID).Clone());
+ pTempItem = pCrossedOutItem.get();
+ break;
+ case RES_CHRATR_ESCAPEMENT:
+ if(!pEscItem)
+ pEscItem.reset(rSet.GetPool()->GetDefaultItem(aIt->nWID).Clone());
+ pTempItem = pEscItem.get();
+ break;
+ case RES_CHRATR_BLINK:
+ if(!pBlinkItem)
+ pBlinkItem.reset(rSet.GetPool()->GetDefaultItem(aIt->nWID).Clone());
+ pTempItem = pBlinkItem.get();
+ break;
+ case RES_CHRATR_FONT:
+ if(!pFontItem)
+ pFontItem.reset(rSet.GetPool()->GetDefaultItem(aIt->nWID).Clone());
+ pTempItem = pFontItem.get();
+ break;
+ case RES_CHRATR_FONTSIZE:
+ if(!pFontSizeItem)
+ pFontSizeItem.reset(rSet.GetPool()->GetDefaultItem(aIt->nWID).Clone());
+ pTempItem = pFontSizeItem.get();
+ break;
+ case RES_CHRATR_KERNING:
+ if(!pKernItem)
+ pKernItem.reset(rSet.GetPool()->GetDefaultItem(aIt->nWID).Clone());
+ pTempItem = pKernItem.get();
+ break;
+ case RES_CHRATR_LANGUAGE:
+ if(!pLangItem)
+ pLangItem.reset(rSet.GetPool()->GetDefaultItem(aIt->nWID).Clone());
+ pTempItem = pLangItem.get();
+ break;
+ case RES_CHRATR_NOHYPHEN:
+ if(!pNHyphItem)
+ pNHyphItem.reset(rSet.GetPool()->GetDefaultItem(aIt->nWID).Clone());
+ pTempItem = pNHyphItem.get();
+ break;
+ case RES_CHRATR_POSTURE:
+ if(!pPostItem)
+ pPostItem.reset(rSet.GetPool()->GetDefaultItem(aIt->nWID).Clone());
+ pTempItem = pPostItem.get();
+ break;
+ case RES_CHRATR_SHADOWED:
+ if(!pShadItem)
+ pShadItem.reset(rSet.GetPool()->GetDefaultItem(aIt->nWID).Clone());
+ pTempItem = pShadItem.get();
+ break;
+ case RES_TXTATR_CHARFMT:
+ if(!pCharFormatItem)
+ pCharFormatItem.reset(rSet.GetPool()->GetDefaultItem(aIt->nWID).Clone());
+ pTempItem = pCharFormatItem.get();
+ break;
+ case RES_CHRATR_UNDERLINE:
+ if(!pULineItem)
+ pULineItem.reset(rSet.GetPool()->GetDefaultItem(aIt->nWID).Clone());
+ pTempItem = pULineItem.get();
+ break;
+ case RES_CHRATR_OVERLINE:
+ if(!pOLineItem)
+ pOLineItem.reset(rSet.GetPool()->GetDefaultItem(aIt->nWID).Clone());
+ pTempItem = pOLineItem.get();
+ break;
+ case RES_CHRATR_WEIGHT:
+ if(!pWeightItem)
+ pWeightItem.reset(rSet.GetPool()->GetDefaultItem(aIt->nWID).Clone());
+ pTempItem = pWeightItem.get();
+ break;
+ case RES_PARATR_DROP:
+ if(!pDropItem)
+ pDropItem.reset(rSet.GetPool()->GetDefaultItem(aIt->nWID).Clone());
+ pTempItem = pDropItem.get();
+ break;
+ case RES_TXTATR_INETFMT:
+ if(!pInetItem)
+ pInetItem.reset(rSet.GetPool()->GetDefaultItem(aIt->nWID).Clone());
+ pTempItem = pInetItem.get();
+ break;
+ case RES_PAGEDESC:
+ if(!pDescItem)
+ pDescItem.reset(rSet.GetPool()->GetDefaultItem(aIt->nWID).Clone());
+ pTempItem = pDescItem.get();
+ break;
+ case RES_PARATR_ADJUST:
+ if(!pAdjItem)
+ pAdjItem.reset(rSet.GetPool()->GetDefaultItem(aIt->nWID).Clone());
+ pTempItem = pAdjItem.get();
+ break;
+ case RES_BACKGROUND:
+ if(!pBackItem)
+ pBackItem.reset(rSet.GetPool()->GetDefaultItem(aIt->nWID).Clone());
+ pTempItem = pBackItem.get();
+ break;
+ case RES_UL_SPACE:
+ if(!pULItem)
+ pULItem.reset(rSet.GetPool()->GetDefaultItem(aIt->nWID).Clone());
+ pTempItem = pULItem.get();
+ break;
+ case RES_LR_SPACE:
+ if(!pLRItem)
+ pLRItem.reset(rSet.GetPool()->GetDefaultItem(aIt->nWID).Clone());
+ pTempItem = pLRItem.get();
+ break;
+ case RES_KEEP:
+ if(!pKeepItem)
+ pKeepItem.reset(rSet.GetPool()->GetDefaultItem(aIt->nWID).Clone());
+ pTempItem = pKeepItem.get();
+ break;
+ case RES_LINENUMBER:
+ if(!pLineNumItem)
+ pLineNumItem.reset(rSet.GetPool()->GetDefaultItem(aIt->nWID).Clone());
+ pTempItem = pLineNumItem.get();
+ break;
+ case RES_PARATR_LINESPACING:
+ if(!pLineSpaceItem)
+ pLineSpaceItem.reset(rSet.GetPool()->GetDefaultItem(aIt->nWID).Clone());
+ pTempItem = pLineSpaceItem.get();
+ break;
+ case RES_PARATR_REGISTER:
+ if(!pRegItem)
+ pRegItem.reset(rSet.GetPool()->GetDefaultItem(aIt->nWID).Clone());
+ pTempItem = pRegItem.get();
+ break;
+ case RES_PARATR_SPLIT:
+ if(!pSplitItem)
+ pSplitItem.reset(rSet.GetPool()->GetDefaultItem(aIt->nWID).Clone());
+ pTempItem = pSplitItem.get();
+ break;
+ case RES_PARATR_TABSTOP:
+ if(!pTabItem)
+ pTabItem.reset(rSet.GetPool()->GetDefaultItem(aIt->nWID).Clone());
+ pTempItem = pTabItem.get();
+ break;
+ case RES_CHRATR_WORDLINEMODE:
+ if(!pWLineItem)
+ pWLineItem.reset(rSet.GetPool()->GetDefaultItem(aIt->nWID).Clone());
+ pTempItem = pWLineItem.get();
+ break;
+ case RES_CHRATR_CJK_FONT:
+ if(!pFontCJKItem )
+ pFontCJKItem.reset(rSet.GetPool()->GetDefaultItem(aIt->nWID).Clone());
+ pTempItem = pFontCJKItem.get();
+ break;
+ case RES_CHRATR_CJK_FONTSIZE:
+ if(!pFontSizeCJKItem )
+ pFontSizeCJKItem.reset(rSet.GetPool()->GetDefaultItem(aIt->nWID).Clone());
+ pTempItem = pFontSizeCJKItem.get();
+ break;
+ case RES_CHRATR_CJK_LANGUAGE:
+ if(!pCJKLangItem )
+ pCJKLangItem.reset(rSet.GetPool()->GetDefaultItem(aIt->nWID).Clone());
+ pTempItem = pCJKLangItem.get();
+ break;
+ case RES_CHRATR_CJK_POSTURE:
+ if(!pCJKPostureItem )
+ pCJKPostureItem.reset(rSet.GetPool()->GetDefaultItem(aIt->nWID).Clone());
+ pTempItem = pCJKPostureItem.get();
+ break;
+ case RES_CHRATR_CJK_WEIGHT:
+ if(!pCJKWeightItem )
+ pCJKWeightItem.reset(rSet.GetPool()->GetDefaultItem(aIt->nWID).Clone());
+ pTempItem = pCJKWeightItem.get();
+ break;
+ case RES_CHRATR_CTL_FONT:
+ if(!pFontCTLItem )
+ pFontCTLItem.reset(rSet.GetPool()->GetDefaultItem(aIt->nWID).Clone());
+ pTempItem = pFontCTLItem.get();
+ break;
+ case RES_CHRATR_CTL_FONTSIZE:
+ if(!pFontSizeCTLItem )
+ pFontSizeCTLItem.reset(rSet.GetPool()->GetDefaultItem(aIt->nWID).Clone());
+ pTempItem = pFontSizeCTLItem.get();
+ break;
+ case RES_CHRATR_CTL_LANGUAGE:
+ if(!pCTLLangItem )
+ pCTLLangItem.reset(rSet.GetPool()->GetDefaultItem(aIt->nWID).Clone());
+ pTempItem = pCTLLangItem.get();
+ break;
+ case RES_CHRATR_CTL_POSTURE:
+ if(!pCTLPostureItem )
+ pCTLPostureItem.reset(rSet.GetPool()->GetDefaultItem(aIt->nWID).Clone());
+ pTempItem = pCTLPostureItem.get();
+ break;
+ case RES_CHRATR_CTL_WEIGHT:
+ if(!pCTLWeightItem )
+ pCTLWeightItem.reset(rSet.GetPool()->GetDefaultItem(aIt->nWID).Clone());
+ pTempItem = pCTLWeightItem.get();
+ break;
+ case RES_CHRATR_SHADOW:
+ if(!pShadowItem )
+ pShadowItem.reset(rSet.GetPool()->GetDefaultItem(aIt->nWID).Clone());
+ pTempItem = pShadowItem.get();
+ break;
+ }
+ if(pTempItem)
+ {
+ if(bIsValueSearch)
+ {
+ pTempItem->PutValue(pValueArr[i]->Value, aIt->nMemberId);
+ rSet.Put(*pTempItem);
+ }
+ else
+ rSet.InvalidateItem( pTempItem->Which() );
+ }
+ }
+ }
+}
+
+bool SwSearchProperties_Impl::HasAttributes() const
+{
+ for(size_t i = 0; i < aPropertyEntries.size(); i++)
+ if(pValueArr[i])
+ return true;
+ return false;
+}
+
+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
+{
+ class theSwXTextSearchUnoTunnelId : public rtl::Static< UnoTunnelIdInit, theSwXTextSearchUnoTunnelId > {};
+}
+
+const uno::Sequence< sal_Int8 > & SwXTextSearch::getUnoTunnelId()
+{
+ return theSwXTextSearchUnoTunnelId::get().getSeq();
+}
+
+sal_Int64 SAL_CALL SwXTextSearch::getSomething( const uno::Sequence< sal_Int8 >& rId )
+{
+ if( isUnoTunnelId<SwXTextSearch>(rId) )
+ {
+ return sal::static_int_cast< sal_Int64 >( reinterpret_cast< sal_IntPtr >(this) );
+ }
+ return 0;
+}
+
+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 SfxItemPropertySimpleEntry* pEntry = m_pPropSet->getPropertyMap().getByName(rPropertyName);
+ if(!pEntry)
+ throw beans::UnknownPropertyException("Unknown property: " + rPropertyName, static_cast < cppu::OWeakObject * > ( this ) );
+
+ if ( pEntry->nFlags & beans::PropertyAttribute::READONLY)
+ throw beans::PropertyVetoException ("Property is read-only: " + rPropertyName, static_cast < cppu::OWeakObject * > ( this ) );
+ 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 SfxItemPropertySimpleEntry* pEntry = m_pPropSet->getPropertyMap().getByName(rPropertyName);
+ bool bSet = false;
+ if(!pEntry)
+ throw beans::UnknownPropertyException("Unknown property: " + rPropertyName, static_cast < cppu::OWeakObject * > ( this ) );
+
+ 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.algorithmType = util::SearchAlgorithms_APPROXIMATE;
+ 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.algorithmType = util::SearchAlgorithms_REGEXP;
+ rSearchOpt.AlgorithmType2 = util::SearchAlgorithms2::REGEXP;
+ }
+ else
+ {
+ rSearchOpt.algorithmType = util::SearchAlgorithms_ABSOLUTE;
+ 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 000000000..fedbf6ece
--- /dev/null
+++ b/sw/source/core/unocore/unostyle.cxx
@@ -0,0 +1,5596 @@
+/* -*- 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 <svx/svxids.hrc>
+#include <hintids.hxx>
+#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/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 <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 <GetMetricVal.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 <cassert>
+#include <memory>
+#include <set>
+#include <limits>
+
+using namespace css;
+using namespace css::io;
+using namespace css::lang;
+using namespace css::uno;
+
+namespace {
+
+class SwXStyle;
+class SwStyleProperties_Impl;
+
+ struct StyleFamilyEntry
+ {
+ using GetCountOrName_t = std::function<sal_Int32 (const SwDoc&, OUString*, sal_Int32)>;
+ using CreateStyle_t = std::function<uno::Reference<css::style::XStyle>(SfxStyleSheetBasePool*, SwDocShell*, const OUString&)>;
+ using TranslateIndex_t = std::function<sal_uInt16(const sal_uInt16)>;
+ SfxStyleFamily m_eFamily;
+ sal_uInt16 m_nPropMapType;
+ uno::Reference<beans::XPropertySetInfo> m_xPSInfo;
+ SwGetPoolIdFromName m_aPoolId;
+ OUString m_sName;
+ const char* m_pResId;
+ GetCountOrName_t m_fGetCountOrName;
+ CreateStyle_t m_fCreateStyle;
+ TranslateIndex_t m_fTranslateIndex;
+ StyleFamilyEntry(SfxStyleFamily eFamily, sal_uInt16 nPropMapType, SwGetPoolIdFromName aPoolId, OUString const& sName, const char* pResId, GetCountOrName_t const & fGetCountOrName, CreateStyle_t const & fCreateStyle, TranslateIndex_t const & fTranslateIndex)
+ : m_eFamily(eFamily)
+ , m_nPropMapType(nPropMapType)
+ , m_xPSInfo(aSwMapProvider.GetPropertySet(nPropMapType)->getPropertySetInfo())
+ , m_aPoolId(aPoolId)
+ , m_sName(sName)
+ , m_pResId(pResId)
+ , m_fGetCountOrName(fGetCountOrName)
+ , m_fCreateStyle(fCreateStyle)
+ , m_fTranslateIndex(fTranslateIndex)
+ { }
+ };
+ static const std::vector<StyleFamilyEntry>* our_pStyleFamilyEntries;
+ // 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;
+ ParagraphStyleCategoryEntry(paragraphstyle_t eCategory, SfxStyleSearchBits nSwStyleBits, collectionbits_t nCollectionBits)
+ : m_eCategory(eCategory)
+ , m_nSwStyleBits(nSwStyleBits)
+ , m_nCollectionBits(nCollectionBits)
+ { }
+ };
+ static const std::vector<ParagraphStyleCategoryEntry>* our_pParagraphStyleCategoryEntries;
+}
+static const std::vector<StyleFamilyEntry>* lcl_GetStyleFamilyEntries();
+
+using namespace ::com::sun::star;
+
+namespace sw
+{
+ namespace {
+
+ 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(const OUString& rStyleName) const;
+ sal_Int32 GetCountOrName(OUString* pString, sal_Int32 nIndex = SAL_MAX_INT32)
+ { return m_rEntry.m_fGetCountOrName(*m_pDocShell->GetDoc(), pString, nIndex); };
+ static const StyleFamilyEntry& InitEntry(SfxStyleFamily eFamily)
+ {
+ auto pEntries = lcl_GetStyleFamilyEntries();
+ const auto pEntry = std::find_if(pEntries->begin(), pEntries->end(),
+ [eFamily] (const StyleFamilyEntry& e) { return e.m_eFamily == eFamily; });
+ assert(pEntry != pEntries->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" }; }
+ };
+
+ }
+}
+
+namespace {
+
+class SwStyleBase_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 SfxItemPropertySimpleEntry&, 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 SfxItemPropertySimpleEntry& rEntry, const SfxItemPropertySet& rPropSet, SwStyleBase_Impl& rBase);
+ uno::Any GetStyleProperty_Impl(const SfxItemPropertySimpleEntry& 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.m_eFamily;}
+
+ 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 SfxItemPropertySimpleEntry& rEntry, const SfxItemPropertySet& rPropSet, const uno::Any& rValue, SwStyleBase_Impl& rBase);
+ void PutItemToSet(const SvxSetItem* pSetItem, const SfxItemPropertySet& rPropSet, const SfxItemPropertySimpleEntry& rEntry, const uno::Any& rVal, SwStyleBase_Impl& rBaseImpl);
+};
+
+class SwXFrameStyle
+ : public SwXStyle
+ , public css::document::XEventsSupplier
+ , public sw::ICoreFrameStyle
+{
+public:
+ SwXFrameStyle(SfxStyleSheetBasePool& rPool,
+ SwDoc* pDoc,
+ const OUString& rStyleName) :
+ SwXStyle(&rPool, SfxStyleFamily::Frame, pDoc, rStyleName){}
+ explicit SwXFrameStyle(SwDoc *pDoc);
+
+ virtual void SAL_CALL acquire( ) throw() override {SwXStyle::acquire();}
+ virtual void SAL_CALL release( ) throw() override {SwXStyle::release();}
+
+ virtual css::uno::Sequence< css::uno::Type > SAL_CALL getTypes( ) override;
+ virtual css::uno::Any SAL_CALL queryInterface( const css::uno::Type& aType ) override;
+ 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;
+};
+
+}
+
+using sw::XStyleFamily;
+
+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 pEntries(lcl_GetStyleFamilyEntries());
+ const auto pEntry = std::find_if(pEntries->begin(), pEntries->end(),
+ [&Name] (const StyleFamilyEntry& e) { return e.m_sName == Name; });
+ if(pEntry == pEntries->end())
+ throw container::NoSuchElementException();
+ return getByIndex(pEntry-pEntries->begin());
+}
+
+uno::Sequence< OUString > SwXStyleFamilies::getElementNames()
+{
+ auto pEntries(lcl_GetStyleFamilyEntries());
+ uno::Sequence<OUString> aNames(pEntries->size());
+ std::transform(pEntries->begin(), pEntries->end(),
+ aNames.begin(), [] (const StyleFamilyEntry& e) { return e.m_sName; });
+ return aNames;
+}
+
+sal_Bool SwXStyleFamilies::hasByName(const OUString& Name)
+{
+ auto pEntries(lcl_GetStyleFamilyEntries());
+ return std::any_of(pEntries->begin(), pEntries->end(),
+ [&Name] (const StyleFamilyEntry& e) { return e.m_sName == Name; });
+}
+
+sal_Int32 SwXStyleFamilies::getCount()
+{
+ return lcl_GetStyleFamilyEntries()->size();
+}
+
+uno::Any SwXStyleFamilies::getByIndex(sal_Int32 nIndex)
+{
+ auto pEntries(lcl_GetStyleFamilyEntries());
+ SolarMutexGuard aGuard;
+ if(nIndex < 0 || nIndex >= static_cast<sal_Int32>(pEntries->size()))
+ throw lang::IndexOutOfBoundsException();
+ if(!IsValid())
+ throw uno::RuntimeException();
+ auto eFamily = (*pEntries)[nIndex].m_eFamily;
+ assert(eFamily != SfxStyleFamily::All);
+ auto& rxFamily = m_vFamilies[eFamily];
+ if(!rxFamily.is())
+ rxFamily = new XStyleFamily(m_pDocShell, eFamily);
+ return uno::makeAny(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)
+ aOpt.SetInputStream(xInputStream);
+ else
+ throw IllegalArgumentException("Parameter 'InputStream' could not be converted to "
+ "type 'com::sun::star::io::XInputStream'",
+ nullptr, 0);
+ }
+ }
+ const ErrCode nErr = m_pDocShell->LoadStylesFromFile( rURL, aOpt, true );
+ if(nErr)
+ throw io::IOException();
+}
+
+uno::Sequence< beans::PropertyValue > SwXStyleFamilies::getStyleLoaderOptions()
+{
+ SolarMutexGuard aGuard;
+ uno::Sequence< beans::PropertyValue > aSeq(5);
+ beans::PropertyValue* pArray = aSeq.getArray();
+ const uno::Any aVal(true);
+ pArray[0] = beans::PropertyValue(UNO_NAME_LOAD_TEXT_STYLES, -1, aVal, beans::PropertyState_DIRECT_VALUE);
+ pArray[1] = beans::PropertyValue(UNO_NAME_LOAD_FRAME_STYLES, -1, aVal, beans::PropertyState_DIRECT_VALUE);
+ pArray[2] = beans::PropertyValue(UNO_NAME_LOAD_PAGE_STYLES, -1, aVal, beans::PropertyState_DIRECT_VALUE);
+ pArray[3] = beans::PropertyValue(UNO_NAME_LOAD_NUMBERING_STYLES, -1, aVal, beans::PropertyState_DIRECT_VALUE);
+ pArray[4] = beans::PropertyValue(UNO_NAME_OVERWRITE_STYLES, -1, aVal, beans::PropertyState_DIRECT_VALUE);
+ return aSeq;
+}
+
+static bool lcl_GetHeaderFooterItem(
+ SfxItemSet const& rSet, OUString const& rPropName, bool const bFooter,
+ SvxSetItem const*& o_rpItem)
+{
+ SfxItemState eState = rSet.GetItemState(
+ bFooter ? SID_ATTR_PAGE_FOOTERSET : SID_ATTR_PAGE_HEADERSET,
+ false, reinterpret_cast<const SfxPoolItem**>(&o_rpItem));
+ if (SfxItemState::SET != eState &&
+ rPropName == UNO_NAME_FIRST_IS_SHARED)
+ { // fdo#79269 header may not exist, check footer then
+ eState = rSet.GetItemState(
+ (!bFooter) ? SID_ATTR_PAGE_FOOTERSET : SID_ATTR_PAGE_HEADERSET,
+ false, reinterpret_cast<const SfxPoolItem**>(&o_rpItem));
+ }
+ return SfxItemState::SET == eState;
+}
+
+template<enum SfxStyleFamily>
+static sal_Int32 lcl_GetCountOrName(const SwDoc&, OUString*, sal_Int32);
+
+template<>
+sal_Int32 lcl_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 lcl_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 lcl_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 lcl_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 lcl_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 lcl_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 lcl_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<SfxStyleFamily eFamily>
+static uno::Reference< css::style::XStyle> lcl_CreateStyle(SfxStyleSheetBasePool* pBasePool, SwDocShell* pDocShell, const OUString& sStyleName)
+ { return pBasePool ? new SwXStyle(pBasePool, eFamily, pDocShell->GetDoc(), sStyleName) : new SwXStyle(pDocShell->GetDoc(), eFamily, false); };
+
+template<>
+uno::Reference< css::style::XStyle> lcl_CreateStyle<SfxStyleFamily::Para>(SfxStyleSheetBasePool* pBasePool, SwDocShell* pDocShell, const OUString& sStyleName)
+ { return pBasePool ? new SwXStyle(pBasePool, SfxStyleFamily::Para, pDocShell->GetDoc(), sStyleName) : new SwXStyle(pDocShell->GetDoc(), SfxStyleFamily::Para, false); };
+template<>
+uno::Reference< css::style::XStyle> lcl_CreateStyle<SfxStyleFamily::Frame>(SfxStyleSheetBasePool* pBasePool, SwDocShell* pDocShell, const OUString& sStyleName)
+ { return pBasePool ? new SwXFrameStyle(*pBasePool, pDocShell->GetDoc(), sStyleName) : new SwXFrameStyle(pDocShell->GetDoc()); };
+
+template<>
+uno::Reference< css::style::XStyle> lcl_CreateStyle<SfxStyleFamily::Page>(SfxStyleSheetBasePool* pBasePool, SwDocShell* pDocShell, const OUString& sStyleName)
+ { return pBasePool ? new SwXPageStyle(*pBasePool, pDocShell, sStyleName) : new SwXPageStyle(pDocShell); };
+
+template<>
+uno::Reference< css::style::XStyle> lcl_CreateStyle<SfxStyleFamily::Table>(SfxStyleSheetBasePool* /*pBasePool*/, SwDocShell* pDocShell, const OUString& sStyleName)
+ { return SwXTextTableStyle::CreateXTextTableStyle(pDocShell, sStyleName); };
+
+template<>
+uno::Reference< css::style::XStyle> lcl_CreateStyle<SfxStyleFamily::Cell>(SfxStyleSheetBasePool* /*pBasePool*/, SwDocShell* pDocShell, const OUString& sStyleName)
+ { return SwXTextCellStyle::CreateXTextCellStyle(pDocShell, sStyleName); };
+
+uno::Reference<css::style::XStyle> SwXStyleFamilies::CreateStyle(SfxStyleFamily eFamily, SwDoc& rDoc)
+{
+ auto pEntries(lcl_GetStyleFamilyEntries());
+ const auto pEntry = std::find_if(pEntries->begin(), pEntries->end(),
+ [eFamily] (const StyleFamilyEntry& e) { return e.m_eFamily == eFamily; });
+ return pEntry == pEntries->end() ? nullptr : pEntry->m_fCreateStyle(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); };
+
+template<enum SfxStyleFamily>
+static sal_uInt16 lcl_TranslateIndex(const sal_uInt16 nIndex);
+
+template<>
+sal_uInt16 lcl_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 lcl_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 lcl_TranslateIndex<SfxStyleFamily::Table>(const sal_uInt16 nIndex)
+{
+ return nIndex;
+}
+
+template<>
+sal_uInt16 lcl_TranslateIndex<SfxStyleFamily::Cell>(const sal_uInt16 nIndex)
+{
+ return nIndex;
+}
+
+template<sal_uInt16 nRangeBegin, sal_uInt16 nRangeSize>
+static sal_uInt16 lcl_TranslateIndexRange(const sal_uInt16 nIndex)
+{
+ if(nIndex < nRangeSize)
+ return nIndex + nRangeBegin;
+ throw lang::IndexOutOfBoundsException();
+}
+
+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.m_fTranslateIndex(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.m_aPoolId);
+ if(!m_pBasePool)
+ throw uno::RuntimeException();
+ SfxStyleSheetBase* pBase = m_pBasePool->Find(sStyleName, m_rEntry.m_eFamily);
+ if(!pBase)
+ throw container::NoSuchElementException();
+ uno::Reference<style::XStyle> xStyle = FindStyle(sStyleName);
+ if(!xStyle.is())
+ xStyle = m_rEntry.m_fCreateStyle(m_pBasePool, m_pDocShell, m_rEntry.m_eFamily == SfxStyleFamily::Frame ? pBase->GetName() : sStyleName);
+ return uno::makeAny(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.m_eFamily);
+ for (SfxStyleSheetBase* pStyle = pIt->First(); pStyle; pStyle = pIt->Next())
+ {
+ OUString sName;
+ SwStyleNameMapper::FillProgName(pStyle->GetName(), sName, m_rEntry.m_aPoolId);
+ 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.m_aPoolId);
+ SfxStyleSheetBase* pBase = m_pBasePool->Find(sStyleName, m_rEntry.m_eFamily);
+ 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.m_aPoolId);
+ SfxStyleSheetBase* pBase = m_pBasePool->Find(sStyleName, m_rEntry.m_eFamily);
+ SfxStyleSheetBase* pUINameBase = m_pBasePool->Find(sStyleName, m_rEntry.m_eFamily);
+ if(pBase || pUINameBase)
+ throw container::ElementExistException();
+ if(rElement.getValueType().getTypeClass() != uno::TypeClass_INTERFACE)
+ throw lang::IllegalArgumentException();
+ if (SwGetPoolIdFromName::CellStyle == m_rEntry.m_aPoolId)
+ {
+ // 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.m_aPoolId)
+ {
+ // 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 = nullptr;
+ if(xStyleTunnel.is())
+ {
+ pNewStyle = reinterpret_cast< SwXStyle * >(
+ sal::static_int_cast< sal_IntPtr >( xStyleTunnel->getSomething( SwXStyle::getUnoTunnelId()) ));
+ }
+
+ if (!pNewStyle || !pNewStyle->IsDescriptor() || pNewStyle->GetFamily() != m_rEntry.m_eFamily)
+ throw lang::IllegalArgumentException();
+
+ SfxStyleSearchBits nMask = SfxStyleSearchBits::All;
+ if(m_rEntry.m_eFamily == SfxStyleFamily::Para && !pNewStyle->IsConditional())
+ nMask &= ~SfxStyleSearchBits::SwCondColl;
+ m_pBasePool->Make(sStyleName, m_rEntry.m_eFamily, nMask);
+ pNewStyle->SetDoc(m_pDocShell->GetDoc(), m_pBasePool);
+ pNewStyle->SetStyleName(sStyleName);
+ const OUString sParentStyleName(pNewStyle->GetParentStyleName());
+ if (!sParentStyleName.isEmpty())
+ {
+ SfxStyleSheetBase* pParentBase = m_pBasePool->Find(sParentStyleName, m_rEntry.m_eFamily);
+ if(pParentBase && pParentBase->GetFamily() == m_rEntry.m_eFamily &&
+ pParentBase->GetPool() == m_pBasePool)
+ m_pBasePool->SetParent(m_rEntry.m_eFamily, sStyleName, sParentStyleName);
+ }
+ // 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.m_aPoolId);
+ SfxStyleSheetBase* pBase = m_pBasePool->Find(sStyleName, m_rEntry.m_eFamily);
+ // replacements only for userdefined styles
+ if(!pBase)
+ throw container::NoSuchElementException();
+ if (SwGetPoolIdFromName::CellStyle == m_rEntry.m_aPoolId)
+ {
+ // 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.m_aPoolId)
+ {
+ // 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::getUnoTunnelImplementation<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.m_aPoolId);
+ SfxStyleSheetBase* pBase = m_pBasePool->Find(sName, m_rEntry.m_eFamily);
+ if(!pBase)
+ throw container::NoSuchElementException();
+ if (SwGetPoolIdFromName::CellStyle == m_rEntry.m_aPoolId)
+ {
+ // handle cell style
+ m_pDocShell->GetDoc()->GetCellStyles().RemoveBoxFormat(rName);
+ }
+ else if (SwGetPoolIdFromName::TabStyle == m_rEntry.m_aPoolId)
+ {
+ // 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, static_cast<OWeakObject *>(this) );
+ SolarMutexGuard aGuard;
+ return uno::makeAny(SwResId(m_rEntry.m_pResId));
+}
+
+
+SwXStyle* XStyleFamily::FindStyle(const OUString& rStyleName) const
+{
+ const size_t nLCount = m_pBasePool->GetSizeOfVector();
+ for(size_t i = 0; i < nLCount; ++i)
+ {
+ SfxListener* pListener = m_pBasePool->GetListener(i);
+ SwXStyle* pTempStyle = dynamic_cast<SwXStyle*>(pListener);
+ if(pTempStyle && pTempStyle->GetFamily() == m_rEntry.m_eFamily && pTempStyle->GetStyleName() == rStyleName)
+ return pTempStyle;
+ }
+ return nullptr;
+}
+
+static const std::vector<StyleFamilyEntry>* lcl_GetStyleFamilyEntries()
+{
+ if(!our_pStyleFamilyEntries)
+ {
+ our_pStyleFamilyEntries = new std::vector<StyleFamilyEntry>{
+ { SfxStyleFamily::Char, PROPERTY_MAP_CHAR_STYLE, SwGetPoolIdFromName::ChrFmt, "CharacterStyles", STR_STYLE_FAMILY_CHARACTER, &lcl_GetCountOrName<SfxStyleFamily::Char>, &lcl_CreateStyle<SfxStyleFamily::Char>, &lcl_TranslateIndex<SfxStyleFamily::Char> },
+ { SfxStyleFamily::Para, PROPERTY_MAP_PARA_STYLE, SwGetPoolIdFromName::TxtColl, "ParagraphStyles", STR_STYLE_FAMILY_PARAGRAPH, &lcl_GetCountOrName<SfxStyleFamily::Para>, &lcl_CreateStyle<SfxStyleFamily::Para>, &lcl_TranslateIndex<SfxStyleFamily::Para> },
+ { SfxStyleFamily::Page, PROPERTY_MAP_PAGE_STYLE, SwGetPoolIdFromName::PageDesc, "PageStyles", STR_STYLE_FAMILY_PAGE, &lcl_GetCountOrName<SfxStyleFamily::Page>, &lcl_CreateStyle<SfxStyleFamily::Page>, &lcl_TranslateIndexRange<RES_POOLPAGE_BEGIN, nPoolPageRange> },
+ { SfxStyleFamily::Frame, PROPERTY_MAP_FRAME_STYLE, SwGetPoolIdFromName::FrmFmt, "FrameStyles", STR_STYLE_FAMILY_FRAME, &lcl_GetCountOrName<SfxStyleFamily::Frame>, &lcl_CreateStyle<SfxStyleFamily::Frame>, &lcl_TranslateIndexRange<RES_POOLFRM_BEGIN, nPoolFrameRange> },
+ { SfxStyleFamily::Pseudo, PROPERTY_MAP_NUM_STYLE, SwGetPoolIdFromName::NumRule, "NumberingStyles", STR_STYLE_FAMILY_NUMBERING, &lcl_GetCountOrName<SfxStyleFamily::Pseudo>, &lcl_CreateStyle<SfxStyleFamily::Pseudo>, &lcl_TranslateIndexRange<RES_POOLNUMRULE_BEGIN, nPoolNumRange> },
+ { SfxStyleFamily::Table, PROPERTY_MAP_TABLE_STYLE, SwGetPoolIdFromName::TabStyle, "TableStyles", STR_STYLE_FAMILY_TABLE, &lcl_GetCountOrName<SfxStyleFamily::Table>, &lcl_CreateStyle<SfxStyleFamily::Table>, &lcl_TranslateIndex<SfxStyleFamily::Table> },
+ { SfxStyleFamily::Cell, PROPERTY_MAP_CELL_STYLE, SwGetPoolIdFromName::CellStyle,"CellStyles", STR_STYLE_FAMILY_CELL, &lcl_GetCountOrName<SfxStyleFamily::Cell>, &lcl_CreateStyle<SfxStyleFamily::Cell>, &lcl_TranslateIndex<SfxStyleFamily::Cell> }
+ };
+ }
+ return our_pStyleFamilyEntries;
+}
+
+static const std::vector<ParagraphStyleCategoryEntry>* lcl_GetParagraphStyleCategoryEntries()
+{
+ if(!our_pParagraphStyleCategoryEntries)
+ {
+ our_pParagraphStyleCategoryEntries = new std::vector<ParagraphStyleCategoryEntry>{
+ { 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 }
+ };
+ }
+ return our_pParagraphStyleCategoryEntries;
+}
+
+namespace {
+
+class SwStyleProperties_Impl
+{
+ const PropertyEntryVector_t aPropertyEntries;
+ std::map<OUString, uno::Any> m_vPropertyValues;
+public:
+ explicit SwStyleProperties_Impl(const SfxItemPropertyMap& rMap)
+ : aPropertyEntries(rMap.getPropertyEntries())
+ { }
+
+ bool AllowsKey(const OUString& rName)
+ {
+ return std::any_of(aPropertyEntries.begin(), aPropertyEntries.end(),
+ [rName] (const SfxItemPropertyNamedEntry& rEntry) {return rName == rEntry.sName;} );
+ }
+ 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);
+ }
+ }
+ static void GetProperty(const OUString &rPropertyName, const uno::Reference < beans::XPropertySet > &rxPropertySet, uno::Any& rAny )
+ {
+ rAny = rxPropertySet->getPropertyValue( rPropertyName );
+ }
+};
+
+}
+
+static SwGetPoolIdFromName lcl_GetSwEnumFromSfxEnum(SfxStyleFamily eFamily)
+{
+ auto pEntries(lcl_GetStyleFamilyEntries());
+ const auto pEntry = std::find_if(pEntries->begin(), pEntries->end(),
+ [eFamily] (const StyleFamilyEntry& e) { return e.m_eFamily == eFamily; });
+ if(pEntry != pEntries->end())
+ return pEntry->m_aPoolId;
+ SAL_WARN("sw.uno", "someone asking for all styles in unostyle.cxx!" );
+ return SwGetPoolIdFromName::ChrFmt;
+}
+
+namespace
+{
+ class theSwXStyleUnoTunnelId : public rtl::Static<UnoTunnelIdInit, theSwXStyleUnoTunnelId> {};
+}
+
+const uno::Sequence<sal_Int8>& SwXStyle::getUnoTunnelId()
+{
+ return theSwXStyleUnoTunnelId::get().getSeq();
+}
+
+sal_Int64 SAL_CALL SwXStyle::getSomething(const uno::Sequence<sal_Int8>& rId)
+{
+ if(isUnoTunnelId<SwXStyle>(rId))
+ {
+ return sal::static_int_cast<sal_Int64>(reinterpret_cast<sal_IntPtr>(this));
+ }
+ return 0;
+}
+
+
+uno::Sequence< OUString > SwXStyle::getSupportedServiceNames()
+{
+ long nCount = 1;
+ if(SfxStyleFamily::Para == m_rEntry.m_eFamily)
+ {
+ nCount = 5;
+ if(m_bIsConditional)
+ nCount++;
+ }
+ else if(SfxStyleFamily::Char == m_rEntry.m_eFamily)
+ nCount = 5;
+ else if(SfxStyleFamily::Page == m_rEntry.m_eFamily)
+ nCount = 3;
+ uno::Sequence< OUString > aRet(nCount);
+ OUString* pArray = aRet.getArray();
+ pArray[0] = "com.sun.star.style.Style";
+ switch(m_rEntry.m_eFamily)
+ {
+ 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.m_eFamily != SfxStyleFamily::Char
+ && rEntry.m_eFamily != SfxStyleFamily::Para
+ && rEntry.m_eFamily != 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.m_sName));
+ 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 pEntries = lcl_GetStyleFamilyEntries();
+ const auto pEntry = std::find_if(pEntries->begin(), pEntries->end(),
+ [eFamily] (const StyleFamilyEntry& e) { return e.m_eFamily == eFamily; });
+ assert(pEntry != pEntries->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.m_eFamily == 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.m_nPropMapType)->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.m_eFamily);
+ 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.m_eFamily ));
+ 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.m_eFamily);
+ 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.m_eFamily);
+ //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.m_eFamily, 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.m_eFamily);
+ OUString aString;
+ if(pBase)
+ aString = pBase->GetParent();
+ SwStyleNameMapper::FillProgName(aString, aString, lcl_GetSwEnumFromSfxEnum(m_rEntry.m_eFamily));
+ return aString;
+}
+
+void SwXStyle::setParentStyle(const OUString& rParentStyle)
+{
+ SolarMutexGuard aGuard;
+ OUString sParentStyle;
+ SwStyleNameMapper::FillUIName(rParentStyle, sParentStyle, lcl_GetSwEnumFromSfxEnum ( m_rEntry.m_eFamily ) );
+ 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.m_eFamily);
+ 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.m_eFamily == SfxStyleFamily::Para);
+ static uno::Reference<beans::XPropertySetInfo> xCondParaRef;
+ xCondParaRef = aSwMapProvider.GetPropertySet(PROPERTY_MAP_CONDITIONAL_PARA_STYLE)->getPropertySetInfo();
+ return xCondParaRef;
+ }
+ return m_rEntry.m_xPSInfo;
+}
+
+void SwXStyle::ApplyDescriptorProperties()
+{
+ m_bIsDescriptor = false;
+ m_xStyleData.clear();
+ m_xStyleFamily.clear();
+ m_pPropertiesImpl->Apply(*this);
+}
+
+namespace {
+
+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, const OUString& rName, const SwAttrSet* pParentStyle)
+ : m_rDoc(rSwDoc)
+ , m_pOldPageDesc(nullptr)
+ , m_pItemSet(nullptr)
+ , m_rStyleName(rName)
+ , 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; };
+ };
+};
+
+ const char* STR_POOLPAGE_ARY[] =
+ {
+ // Page styles
+ STR_POOLPAGE_STANDARD,
+ STR_POOLPAGE_FIRST,
+ STR_POOLPAGE_LEFT,
+ STR_POOLPAGE_RIGHT,
+ STR_POOLPAGE_JAKET,
+ 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 SfxItemPropertySimpleEntry& 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 SfxItemPropertySimpleEntry& 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 SfxItemPropertySimpleEntry& 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 SfxItemPropertySimpleEntry& 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 SfxItemPropertySimpleEntry& 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)
+ {
+ const Graphic aNullGraphic;
+ SfxItemSet& rStyleSet = o_rStyleBase.GetItemSet();
+ XFillBitmapItem aXFillBitmapItem(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 SfxItemPropertySimpleEntry& 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 SfxItemPropertySimpleEntry&, 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 SfxItemPropertySimpleEntry& 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::makeAny(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 SfxItemPropertySimpleEntry&, const SfxItemPropertySet&, const uno::Any& rValue, SwStyleBase_Impl& o_rStyleBase)
+{
+ if(!rValue.has<uno::Reference<container::XIndexReplace>>() || !rValue.has<uno::Reference<lang::XUnoTunnel>>())
+ throw lang::IllegalArgumentException();
+ auto xNumberTunnel(rValue.get<uno::Reference<lang::XUnoTunnel>>());
+ SwXNumberingRules* pSwXRules = reinterpret_cast<SwXNumberingRules*>(sal::static_int_cast<sal_IntPtr>(xNumberTunnel->getSomething(SwXNumberingRules::getUnoTunnelId())));
+ 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 SfxItemPropertySimpleEntry&, 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 SfxItemPropertySimpleEntry&, 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.m_aPoolId);
+ o_rStyleBase.getNewBase()->SetFollow(aString);
+}
+template<>
+void SwXStyle::SetPropertyValue<sal_uInt16(RES_PAGEDESC)>(const SfxItemPropertySimpleEntry& 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;
+ const SfxPoolItem* pItem;
+ if(SfxItemState::SET == rStyleSet.GetItemState(RES_PAGEDESC, true, &pItem))
+ pNewDesc.reset(new SwFormatPageDesc(*static_cast<const 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(*pNewDesc);
+ }
+}
+template<>
+void SwXStyle::SetPropertyValue<sal_uInt16(RES_TEXT_VERT_ADJUST)>(const SfxItemPropertySimpleEntry& rEntry, const SfxItemPropertySet& rPropSet, const uno::Any& rValue, SwStyleBase_Impl& o_rStyleBase)
+{
+ if(m_rEntry.m_eFamily != 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 SfxItemPropertySimpleEntry&, 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.m_eFamily)
+ o_rStyleBase.getNewBase()->GetCollection()->SetAutoUpdateFormat(bAuto);
+ else if(SfxStyleFamily::Frame == m_rEntry.m_eFamily)
+ o_rStyleBase.getNewBase()->GetFrameFormat()->SetAutoUpdateFormat(bAuto);
+}
+template<>
+void SwXStyle::SetPropertyValue<FN_UNO_PARA_STYLE_CONDITIONS>(const SfxItemPropertySimpleEntry&, 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.m_eFamily));
+
+ // 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 SfxItemPropertySimpleEntry&, const SfxItemPropertySet&, const uno::Any& rValue, SwStyleBase_Impl& o_rStyleBase)
+{
+ if(!o_rStyleBase.getNewBase()->IsUserDefined() || !rValue.has<paragraphstyle_t>())
+ throw lang::IllegalArgumentException();
+ static std::unique_ptr<std::map<paragraphstyle_t, SfxStyleSearchBits>> pUnoToCore;
+ if(!pUnoToCore)
+ {
+ pUnoToCore.reset(new std::map<paragraphstyle_t, SfxStyleSearchBits>);
+ auto pEntries = lcl_GetParagraphStyleCategoryEntries();
+ std::transform(pEntries->begin(), pEntries->end(), std::inserter(*pUnoToCore, pUnoToCore->end()),
+ [] (const ParagraphStyleCategoryEntry& rEntry) { return std::pair<paragraphstyle_t, SfxStyleSearchBits>(rEntry.m_eCategory, rEntry.m_nSwStyleBits); });
+ }
+ const auto pUnoToCoreIt(pUnoToCore->find(rValue.get<paragraphstyle_t>()));
+ if(pUnoToCoreIt == pUnoToCore->end())
+ throw lang::IllegalArgumentException();
+ o_rStyleBase.getNewBase()->SetMask( pUnoToCoreIt->second|SfxStyleSearchBits::UserDefined );
+}
+template<>
+void SwXStyle::SetPropertyValue<SID_SWREGISTER_COLLECTION>(const SfxItemPropertySimpleEntry&, 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 SfxItemPropertySimpleEntry& 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;
+ const SfxPoolItem* pItem;
+ if(SfxItemState::SET == rStyleSet.GetItemState(RES_TXTATR_CJK_RUBY, true, &pItem))
+ pRuby.reset(new SwFormatRuby(*static_cast<const SwFormatRuby*>(pItem)));
+ 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(*pRuby);
+ SetPropertyValue<HINT_BEGIN>(rEntry, rPropSet, rValue, o_rStyleBase);
+}
+template<>
+void SwXStyle::SetPropertyValue<sal_uInt16(RES_PARATR_DROP)>(const SfxItemPropertySimpleEntry& 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;
+ const SfxPoolItem* pItem;
+ if(SfxItemState::SET == rStyleSet.GetItemState(RES_PARATR_DROP, true, &pItem))
+ pDrop.reset(new SwFormatDrop(*static_cast<const SwFormatDrop*>(pItem)));
+ 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(*pDrop);
+}
+template<>
+void SwXStyle::SetPropertyValue<sal_uInt16(RES_PARATR_NUMRULE)>(const SfxItemPropertySimpleEntry& 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.m_eFamily &&
+ 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 SfxItemPropertySimpleEntry& 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 SfxItemPropertySimpleEntry&, const SfxItemPropertySet&, const uno::Any&, SwStyleBase_Impl&)>;
+ static std::unique_ptr<std::map<propertytype_t, coresetter_t>> pUnoToCore;
+ if(!pUnoToCore)
+ {
+ pUnoToCore.reset(new std::map<propertytype_t, coresetter_t> {
+ // 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>) },
+ { 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(pUnoToCore->find(rEntry.nWID));
+ if(pUnoToCoreIt != pUnoToCore->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_Int8 nPropSetId = m_bIsConditional ? PROPERTY_MAP_CONDITIONAL_PARA_STYLE : m_rEntry.m_nPropMapType;
+ 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.m_eFamily);
+ 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 SfxItemPropertySimpleEntry* pEntry = rMap.getByName(pNames[nProp]);
+ if(!pEntry || (!m_bIsConditional && pNames[nProp] == UNO_NAME_PARA_STYLE_CONDITIONS))
+ throw beans::UnknownPropertyException("Unknown property: " + pNames[nProp], static_cast<cppu::OWeakObject*>(this));
+ if(pEntry->nFlags & beans::PropertyAttribute::READONLY)
+ throw beans::PropertyVetoException ("Property is read-only: " + pNames[nProp], static_cast<cppu::OWeakObject*>(this));
+ 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.m_eFamily);
+ 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 SfxItemPropertySimpleEntry& rEntry, const SfxItemPropertySet& rPropSet, SwStyleBase_Impl& rBase);
+template<>
+uno::Any SwXStyle::GetStyleProperty<FN_UNO_IS_PHYSICAL>(const SfxItemPropertySimpleEntry&, const SfxItemPropertySet&, SwStyleBase_Impl&)
+{
+ SfxStyleSheetBase* pBase(GetStyleSheetBase());
+ if(!pBase)
+ return uno::makeAny(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::makeAny<bool>(bPhys);
+}
+template<>
+uno::Any SwXStyle::GetStyleProperty<FN_UNO_HIDDEN>(const SfxItemPropertySimpleEntry&, const SfxItemPropertySet&, SwStyleBase_Impl&)
+{
+ SfxStyleSheetBase* pBase(GetStyleSheetBase());
+ if(!pBase)
+ return uno::makeAny(false);
+ rtl::Reference<SwDocStyleSheet> xBase(new SwDocStyleSheet(*static_cast<SwDocStyleSheet*>(pBase)));
+ return uno::makeAny(xBase->IsHidden());
+}
+template<>
+uno::Any SwXStyle::GetStyleProperty<FN_UNO_STYLE_INTEROP_GRAB_BAG>(const SfxItemPropertySimpleEntry&, 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 SfxItemPropertySimpleEntry& 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::makeAny<OUString>("[From printer settings]");
+ SfxPrinter* pPrinter = GetDoc()->getIDocumentDeviceAccess().getPrinter(false);
+ if(!pPrinter)
+ return uno::Any();
+ return uno::makeAny(pPrinter->GetPaperBinName(nBin));
+}
+template<>
+uno::Any SwXStyle::GetStyleProperty<FN_UNO_NUM_RULES>(const SfxItemPropertySimpleEntry&, 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::makeAny<uno::Reference<container::XIndexReplace>>(xRules);
+}
+template<>
+uno::Any SwXStyle::GetStyleProperty<sal_uInt16(RES_PARATR_OUTLINELEVEL)>(const SfxItemPropertySimpleEntry&, const SfxItemPropertySet&, SwStyleBase_Impl& rBase)
+{
+ PrepareStyleBase(rBase);
+ SAL_WARN_IF(SfxStyleFamily::Para != GetFamily(), "sw.uno", "only paras");
+ return uno::makeAny<sal_Int16>(rBase.getNewBase()->GetCollection()->GetAttrOutlineLevel());
+}
+template<>
+uno::Any SwXStyle::GetStyleProperty<FN_UNO_FOLLOW_STYLE>(const SfxItemPropertySimpleEntry&, const SfxItemPropertySet&, SwStyleBase_Impl& rBase)
+{
+ PrepareStyleBase(rBase);
+ OUString aString;
+ SwStyleNameMapper::FillProgName(rBase.getNewBase()->GetFollow(), aString, lcl_GetSwEnumFromSfxEnum(GetFamily()));
+ return uno::makeAny(aString);
+}
+template<>
+uno::Any SwXStyle::GetStyleProperty<sal_uInt16(RES_PAGEDESC)>(const SfxItemPropertySimpleEntry& 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 SfxPoolItem* pItem;
+ if(SfxItemState::SET != rBase.GetItemSet().GetItemState(RES_PAGEDESC, true, &pItem))
+ return uno::Any();
+ const SwPageDesc* pDesc = static_cast<const SwFormatPageDesc*>(pItem)->GetPageDesc();
+ if(!pDesc)
+ return uno::Any();
+ OUString aString;
+ SwStyleNameMapper::FillProgName(pDesc->GetName(), aString, SwGetPoolIdFromName::PageDesc);
+ return uno::makeAny(aString);
+}
+template<>
+uno::Any SwXStyle::GetStyleProperty<FN_UNO_IS_AUTO_UPDATE>(const SfxItemPropertySimpleEntry&, const SfxItemPropertySet&, SwStyleBase_Impl& rBase)
+{
+ PrepareStyleBase(rBase);
+ switch(GetFamily())
+ {
+ case SfxStyleFamily::Para : return uno::makeAny<bool>(rBase.getNewBase()->GetCollection()->IsAutoUpdateFormat());
+ case SfxStyleFamily::Frame: return uno::makeAny<bool>(rBase.getNewBase()->GetFrameFormat()->IsAutoUpdateFormat());
+ default: return uno::Any();
+ }
+}
+template<>
+uno::Any SwXStyle::GetStyleProperty<FN_UNO_DISPLAY_NAME>(const SfxItemPropertySimpleEntry&, const SfxItemPropertySet&, SwStyleBase_Impl& rBase)
+{
+ PrepareStyleBase(rBase);
+ return uno::makeAny(rBase.getNewBase()->GetName());
+}
+template<>
+uno::Any SwXStyle::GetStyleProperty<FN_UNO_PARA_STYLE_CONDITIONS>(const SfxItemPropertySimpleEntry&, 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 : 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::makeAny(aSeq);
+}
+template<>
+uno::Any SwXStyle::GetStyleProperty<FN_UNO_CATEGORY>(const SfxItemPropertySimpleEntry&, const SfxItemPropertySet&, SwStyleBase_Impl& rBase)
+{
+ PrepareStyleBase(rBase);
+ static std::unique_ptr<std::map<collectionbits_t, paragraphstyle_t>> pUnoToCore;
+ if(!pUnoToCore)
+ {
+ pUnoToCore.reset(new std::map<collectionbits_t, paragraphstyle_t>);
+ auto pEntries = lcl_GetParagraphStyleCategoryEntries();
+ std::transform(pEntries->begin(), pEntries->end(), std::inserter(*pUnoToCore, pUnoToCore->end()),
+ [] (const ParagraphStyleCategoryEntry& rEntry) { return std::pair<collectionbits_t, paragraphstyle_t>(rEntry.m_nCollectionBits, rEntry.m_eCategory); });
+ }
+ const sal_uInt16 nPoolId = rBase.getNewBase()->GetCollection()->GetPoolFormatId();
+ const auto pUnoToCoreIt(pUnoToCore->find(COLL_GET_RANGE_BITS & nPoolId));
+ if(pUnoToCoreIt == pUnoToCore->end())
+ return uno::makeAny<sal_Int16>(-1);
+ return uno::makeAny(pUnoToCoreIt->second);
+}
+template<>
+uno::Any SwXStyle::GetStyleProperty<SID_SWREGISTER_COLLECTION>(const SfxItemPropertySimpleEntry&, const SfxItemPropertySet&, SwStyleBase_Impl& rBase)
+{
+ PrepareStyleBase(rBase);
+ const SwPageDesc *pPageDesc = rBase.getNewBase()->GetPageDesc();
+ if(!pPageDesc)
+ return uno::makeAny(OUString());
+ const SwTextFormatColl* pCol = pPageDesc->GetRegisterFormatColl();
+ if(!pCol)
+ return uno::makeAny(OUString());
+ OUString aName;
+ SwStyleNameMapper::FillProgName(pCol->GetName(), aName, SwGetPoolIdFromName::TxtColl);
+ return uno::makeAny(aName);
+}
+template<>
+uno::Any SwXStyle::GetStyleProperty<sal_uInt16(RES_BACKGROUND)>(const SfxItemPropertySimpleEntry& 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 SfxItemPropertySimpleEntry&, const SfxItemPropertySet&, SwStyleBase_Impl& rBase)
+{
+ PrepareStyleBase(rBase);
+ const SfxItemSet& rSet = rBase.GetItemSet();
+ if (rSet.Get(XATTR_FILLBMP_TILE).GetValue())
+ return uno::makeAny(drawing::BitmapMode_REPEAT);
+ if (rSet.Get(XATTR_FILLBMP_STRETCH).GetValue())
+ return uno::makeAny(drawing::BitmapMode_STRETCH);
+ return uno::makeAny(drawing::BitmapMode_NO_REPEAT);
+}
+template<>
+uno::Any SwXStyle::GetStyleProperty<HINT_BEGIN>(const SfxItemPropertySimpleEntry& 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 SfxItemPropertySimpleEntry& rEntry, const SfxItemPropertySet& rPropSet, SwStyleBase_Impl& rBase)
+{
+ using propertytype_t = decltype(rEntry.nWID);
+ using coresetter_t = std::function<uno::Any(SwXStyle&, const SfxItemPropertySimpleEntry&, const SfxItemPropertySet&, SwStyleBase_Impl&)>;
+ static std::unique_ptr<std::map<propertytype_t, coresetter_t>> pUnoToCore;
+ if(!pUnoToCore)
+ {
+ pUnoToCore.reset(new std::map<propertytype_t, coresetter_t> {
+ // 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>) },
+ { 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(pUnoToCore->find(rEntry.nWID));
+ if(pUnoToCoreIt != pUnoToCore->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 SfxItemPropertySimpleEntry* pEntry = rMap.getByName(rPropertyName);
+ if(!pEntry || (!m_bIsConditional && rPropertyName == UNO_NAME_PARA_STYLE_CONDITIONS))
+ throw beans::UnknownPropertyException("Unknown property: " + rPropertyName, static_cast<cppu::OWeakObject*>(this));
+ 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.m_eFamily)
+ {
+ case SfxStyleFamily::Pseudo:
+ throw uno::RuntimeException("No default value for: " + rPropertyName);
+ break;
+ case SfxStyleFamily::Para:
+ case SfxStyleFamily::Page:
+ SwStyleProperties_Impl::GetProperty(rPropertyName, m_xStyleData, aValue);
+ 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.m_eFamily == 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_Int8 nPropSetId = m_bIsConditional ? PROPERTY_MAP_CONDITIONAL_PARA_STYLE : m_rEntry.m_nPropMapType;
+ 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_Int8 nPropSetId = m_bIsConditional ? PROPERTY_MAP_CONDITIONAL_PARA_STYLE : m_rEntry.m_nPropMapType;
+ 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());
+ // workaround for bad designed API
+ try
+ {
+ for(sal_Int32 nProp = 0; nProp < rPropertyNames.getLength(); ++nProp)
+ aValues[nProp] = GetPropertyValue_Impl(pPropSet, aBase, rPropertyNames[nProp]);
+ }
+ catch(beans::UnknownPropertyException&)
+ {
+ css::uno::Any anyEx = cppu::getCaughtException();
+ throw css::lang::WrappedTargetRuntimeException("Unknown property exception caught",
+ static_cast < cppu::OWeakObject * > ( this ), anyEx );
+ }
+ catch(lang::WrappedTargetException&)
+ {
+ css::uno::Any anyEx = cppu::getCaughtException();
+ throw lang::WrappedTargetRuntimeException("WrappedTargetException caught",
+ static_cast < cppu::OWeakObject * > ( this ), 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, const OUString& rPropertyName)
+{
+ if(eFamily != SfxStyleFamily::Page)
+ return &rSet;
+ const bool isFooter = rPropertyName.startsWith("Footer");
+ if(!isFooter && !rPropertyName.startsWith("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.m_eFamily);
+
+ 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_Int8 nPropSetId = m_bIsConditional ? PROPERTY_MAP_CONDITIONAL_PARA_STYLE : m_rEntry.m_nPropMapType;
+
+ 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 SfxItemPropertySimpleEntry* pEntry = rMap.getByName(sPropName);
+
+ if(!pEntry)
+ throw beans::UnknownPropertyException("Unknown property: " + sPropName, static_cast<cppu::OWeakObject*>(this));
+
+ if(FN_UNO_NUM_RULES == pEntry->nWID || FN_UNO_FOLLOW_STYLE == pEntry->nWID)
+ {
+ // handle NumRules first, done
+ pStates[i] = beans::PropertyState_DIRECT_VALUE;
+ continue;
+ }
+ const SfxItemSet* pSourceSet = lcl_GetItemsetForProperty(rSet, m_rEntry.m_eFamily, 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 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.m_eFamily && 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.m_eFamily);
+ if(!pTargetFormat)
+ {
+ if(!m_bIsDescriptor)
+ return;
+ for(const auto& rName : aPropertyNames)
+ m_pPropertiesImpl->ClearProperty(rName);
+ return;
+ }
+ const sal_Int8 nPropSetId = m_bIsConditional ? PROPERTY_MAP_CONDITIONAL_PARA_STYLE : m_rEntry.m_nPropMapType;
+ const SfxItemPropertySet* pPropSet = aSwMapProvider.GetPropertySet(nPropSetId);
+ const SfxItemPropertyMap &rMap = pPropSet->getPropertyMap();
+ for(const auto& rName : aPropertyNames)
+ {
+ const SfxItemPropertySimpleEntry* pEntry = rMap.getByName(rName);
+ if(!pEntry)
+ throw beans::UnknownPropertyException("Unknown property: " + rName, static_cast<cppu::OWeakObject*>(this));
+ if(pEntry->nWID == FN_UNO_FOLLOW_STYLE || pEntry->nWID == FN_UNO_NUM_RULES)
+ throw uno::RuntimeException("Cannot reset: " + rName, static_cast<cppu::OWeakObject*>(this));
+ if(pEntry->nFlags & beans::PropertyAttribute::READONLY)
+ throw uno::RuntimeException("setPropertiesToDefault: property is read-only: " + rName, static_cast<cppu::OWeakObject*>(this));
+ 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();
+ SfxItemSet aSet(pDoc->GetAttrPool(), svl::Items<XATTR_FILL_FIRST, XATTR_FILL_LAST>{});
+ 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.m_eFamily)
+ {
+ 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.m_eFamily);
+ SwPageDesc& rPageDesc = m_pDoc->GetPageDesc(nPgDscPos);
+ rPageDesc.ResetAllMasterAttr();
+
+ SvxLRSpaceItem aLR(RES_LR_SPACE);
+ sal_Int32 nSize = GetMetricVal(CM_1) * 2;
+ aLR.SetLeft(nSize);
+ aLR.SetLeft(nSize);
+ SvxULSpaceItem aUL(RES_UL_SPACE);
+ aUL.SetUpper(static_cast<sal_uInt16>(nSize));
+ aUL.SetLower(static_cast<sal_uInt16>(nSize));
+ pPageFormat->SetFormatAttr(aLR);
+ pPageFormat->SetFormatAttr(aUL);
+ 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.m_eFamily)
+ {
+ if(xStyle->GetCollection())
+ xStyle->GetCollection()->DeleteAssignmentToListLevelOfOutlineStyle();
+ }
+ SwFormat* const pTargetFormat = lcl_GetFormatForStyle(m_pDoc, xStyle, m_rEntry.m_eFamily);
+ 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;
+ SfxStyleSheetBase* pBase = GetStyleSheetBase();
+ if(!pBase)
+ throw uno::RuntimeException();
+ rtl::Reference<SwDocStyleSheet> xStyle(new SwDocStyleSheet(*static_cast<SwDocStyleSheet*>(pBase)));
+ const sal_Int8 nPropSetId = m_bIsConditional ? PROPERTY_MAP_CONDITIONAL_PARA_STYLE : m_rEntry.m_nPropMapType;
+ 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 SfxItemPropertySimpleEntry* pEntry = rMap.getByName(aPropertyNames[i]);
+
+ if(!pEntry)
+ throw beans::UnknownPropertyException("Unknown property: " + aPropertyNames[i], static_cast < cppu::OWeakObject * >(this));
+ // 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, aRet[i]);
+ }
+ else if(pEntry->nWID != rSet.GetPool()->GetSlotId(pEntry->nWID))
+ {
+ const SfxPoolItem& rItem = rSet.GetPool()->GetDefaultItem(pEntry->nWID);
+ rItem.QueryValue(aRet[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.m_eFamily);
+ 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 SfxItemPropertySimpleEntry& rEntry, const uno::Any& rVal, SwStyleBase_Impl& rBaseImpl)
+{
+ // create a new SvxSetItem and get it's ItemSet as new target
+ const 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(*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 SfxItemPropertySimpleEntry* pEntry = rMap.getByName(rPropName);
+
+ if(!pEntry)
+ throw beans::UnknownPropertyException("Unknown property: " + rPropName, static_cast<cppu::OWeakObject*>(this));
+ if(pEntry->nFlags & beans::PropertyAttribute::READONLY)
+ throw beans::PropertyVetoException("Property is read-only: " + rPropName, static_cast<cppu::OWeakObject*>(this));
+
+ 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
+ if (SfxItemState::SET == aBaseImpl.GetItemSet().GetItemState(
+ bFooter ? SID_ATTR_PAGE_HEADERSET : SID_ATTR_PAGE_FOOTERSET,
+ false, reinterpret_cast<const SfxPoolItem**>(&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
+ SfxItemSet aTempSet(*aBaseImpl.GetItemSet().GetPool(),
+ svl::Items<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>{});
+
+ // set correct parent to get the XFILL_NONE FillStyle as needed
+ aTempSet.SetParent(&GetDoc()->GetDfltFrameFormat()->GetAttrSet());
+
+ aTempSet.Put(SfxBoolItem(SID_ATTR_PAGE_ON, true));
+ aTempSet.Put(SvxSizeItem(SID_ATTR_PAGE_SIZE, Size(MM50, MM50)));
+ 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 = nullptr;
+
+ if(SfxItemState::SET == aBaseImpl.GetItemSet().GetItemState(bFooter ? SID_ATTR_PAGE_FOOTERSET : SID_ATTR_PAGE_HEADERSET, false, reinterpret_cast<const SfxPoolItem**>(&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 paret at ItemSet from SetItem
+ rSetSet.SetParent(nullptr);
+
+ // set the new SvxSetItem at the real target and delete it
+ aBaseImpl.GetItemSet().Put(*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, static_cast<cppu::OWeakObject*>(this));
+ 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 SfxPoolItem& 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 uno::Reference<text::XText> 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);
+ 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())
+ SwStyleProperties_Impl::GetProperty(rPropertyNames[nProp], m_xStyleData, aRet[nProp]);
+ else
+ aRet[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 SfxItemPropertySimpleEntry* pEntry = rMap.getByName(rPropName);
+
+ if (!pEntry)
+ throw beans::UnknownPropertyException("Unknown property: " + rPropName, static_cast < cppu::OWeakObject * > ( this ) );
+ 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));
+ aRet[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
+ aRet[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;
+ if(SfxItemState::SET == rSet.GetItemState(bFooter ? SID_ATTR_PAGE_FOOTERSET : SID_ATTR_PAGE_HEADERSET, false, reinterpret_cast<const SfxPoolItem**>(&pSetItem)))
+ {
+ // set at SfxItemSet of the corresponding SfxSetItem
+ const SfxItemSet& rSetSet = pSetItem->GetItemSet();
+ {
+ SwStyleBase_Impl::ItemSetOverrider o(aBase, &const_cast<SfxItemSet&>(rSetSet));
+ aRet[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, static_cast < cppu::OWeakObject * > ( this ) );
+ 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())
+ aRet[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(aRet[nProp], pEntry->nMemberId);
+ }
+ break;
+ default:
+ aRet[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",
+ static_cast < cppu::OWeakObject * > ( this ), anyEx );
+ }
+ catch(lang::WrappedTargetException &)
+ {
+ css::uno::Any anyEx = cppu::getCaughtException();
+ throw lang::WrappedTargetRuntimeException("WrappedTargetException caught",
+ static_cast < cppu::OWeakObject * > ( this ), 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);
+ SetPropertyValues_Impl(aProperties, aValues);
+}
+
+SwXFrameStyle::SwXFrameStyle(SwDoc *pDoc)
+ : SwXStyle(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::Sequence<uno::Type> SwXFrameStyle::getTypes()
+{
+ return cppu::OTypeCollection(
+ cppu::UnoType<XEventsSupplier>::get(),
+ SwXStyle::getTypes()
+ ).getTypes();
+}
+
+uno::Any SwXFrameStyle::queryInterface(const uno::Type& rType)
+{
+ if(rType == cppu::UnoType<XEventsSupplier>::get())
+ return uno::makeAny(uno::Reference<XEventsSupplier>(this));
+ return SwXStyle::queryInterface(rType);
+}
+
+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 aIter;
+ SwDoc* pDoc;
+ IStyleAccess::SwAutoStyleFamily eFamily;
+public:
+ SwAutoStylesEnumImpl( SwDoc* pInitDoc, IStyleAccess::SwAutoStyleFamily eFam );
+ bool hasMoreElements() { return aIter != mAutoStyles.end(); }
+ std::shared_ptr<SfxItemSet> const & nextElement() { return *(aIter++); }
+ IStyleAccess::SwAutoStyleFamily getFamily() const { return eFamily; }
+ SwDoc* getDoc() const { return pDoc; }
+};
+
+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;
+}
+
+uno::Reference< style::XAutoStyle > SwXAutoStyleFamily::insertStyle(
+ const uno::Sequence< beans::PropertyValue >& Values )
+{
+ if (!m_pDocShell)
+ {
+ throw uno::RuntimeException();
+ }
+
+ const sal_uInt16* pRange = nullptr;
+ const SfxItemPropertySet* pPropSet = nullptr;
+ switch( m_eFamily )
+ {
+ case IStyleAccess::AUTO_STYLE_CHAR:
+ {
+ pRange = aCharAutoFormatSetRange;
+ pPropSet = aSwMapProvider.GetPropertySet(PROPERTY_MAP_CHAR_AUTO_STYLE);
+ break;
+ }
+ case IStyleAccess::AUTO_STYLE_RUBY:
+ {
+ pRange = nullptr;//aTextNodeSetRange;
+ pPropSet = aSwMapProvider.GetPropertySet(PROPERTY_MAP_RUBY_AUTO_STYLE);
+ break;
+ }
+ case IStyleAccess::AUTO_STYLE_PARA:
+ {
+ pRange = aTextNodeSetRange; // checked, already added support for [XATTR_FILL_FIRST, XATTR_FILL_LAST]
+ pPropSet = aSwMapProvider.GetPropertySet(PROPERTY_MAP_PARA_AUTO_STYLE);
+ break;
+ }
+ default: ;
+ }
+
+ if( !pPropSet)
+ throw uno::RuntimeException();
+
+ SwAttrSet aSet( m_pDocShell->GetDoc()->GetAttrPool(), pRange );
+ const bool bTakeCareOfDrawingLayerFillStyle(IStyleAccess::AUTO_STYLE_PARA == m_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(&m_pDocShell->GetDoc()->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 SfxItemPropertySimpleEntry* 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 = m_pDocShell->GetDoc()->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)
+ {
+ const Graphic aNullGraphic;
+ XFillBitmapItem aXFillBitmapItem(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, m_pDocShell->GetDoc()->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
+ m_pDocShell->GetDoc()->CheckForUniqueItemForLineFillNameOrIndex(aSet);
+
+ // AutomaticStyle creation
+ std::shared_ptr<SfxItemSet> pSet = m_pDocShell->GetDoc()->GetIStyleAccess().cacheAutomaticStyle( aSet, m_eFamily );
+ 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* pInitDoc, IStyleAccess::SwAutoStyleFamily eFam )
+: pDoc( pInitDoc ), 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 = pDoc->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<SfxItemSet>( rAttrPool, svl::Items<RES_TXTATR_CJK_RUBY, RES_TXTATR_CJK_RUBY>{} );
+ pItemSet->Put( *pRubyItem );
+ mAutoStyles.push_back( pItemSet );
+ }
+ }
+ }
+ else
+ {
+ pDoc->GetIStyleAccess().getAllStyles( mAutoStyles, eFamily );
+ }
+
+ aIter = mAutoStyles.begin();
+}
+
+SwXAutoStylesEnumerator::SwXAutoStylesEnumerator( SwDoc* pDoc, IStyleAccess::SwAutoStyleFamily eFam )
+: m_pImpl( new SwAutoStylesEnumImpl( pDoc, eFam ) )
+{
+ // Register ourselves as a listener to the document (via the page descriptor)
+ StartListening(pDoc->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> const & pInitSet,
+ IStyleAccess::SwAutoStyleFamily eFam)
+: mpSet(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 uno::Reference< beans::XPropertySetInfo > xCharRef;
+ if(!xCharRef.is())
+ {
+ xCharRef = aSwMapProvider.GetPropertySet(PROPERTY_MAP_CHAR_AUTO_STYLE)->getPropertySetInfo();
+ }
+ xRet = xCharRef;
+ }
+ break;
+ case IStyleAccess::AUTO_STYLE_RUBY:
+ {
+ static uno::Reference< beans::XPropertySetInfo > xRubyRef;
+ if(!xRubyRef.is())
+ {
+ const sal_uInt16 nMapId = PROPERTY_MAP_RUBY_AUTO_STYLE;
+ xRubyRef = aSwMapProvider.GetPropertySet(nMapId)->getPropertySetInfo();
+ }
+ xRet = xRubyRef;
+ }
+ break;
+ case IStyleAccess::AUTO_STYLE_PARA:
+ {
+ static uno::Reference< beans::XPropertySetInfo > xParaRef;
+ if(!xParaRef.is())
+ {
+ const sal_uInt16 nMapId = PROPERTY_MAP_PARA_AUTO_STYLE;
+ xParaRef = aSwMapProvider.GetPropertySet(nMapId)->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_Int8 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 SfxItemPropertySimpleEntry* pEntry = rMap.getByName(sPropName);
+ if(!pEntry)
+ {
+ throw beans::UnknownPropertyException("Unknown property: " + sPropName, static_cast < cppu::OWeakObject * > ( this ) );
+ }
+
+ 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", static_cast < cppu::OWeakObject * > ( this ), exc );
+ }
+ catch (lang::WrappedTargetException &)
+ {
+ css::uno::Any exc = cppu::getCaughtException();
+ throw lang::WrappedTargetRuntimeException("WrappedTargetException caught", static_cast < cppu::OWeakObject * > ( this ), 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_Int8 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 SfxItemPropertySimpleEntry* pEntry = rMap.getByName(sPropName);
+ if(!pEntry)
+ {
+ throw beans::UnknownPropertyException("Unknown property: " + sPropName, static_cast < cppu::OWeakObject * > ( this ) );
+ }
+
+ 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*/ )
+{
+ uno::Sequence< uno::Any > aRet(0);
+ return aRet;
+}
+
+uno::Sequence< beans::PropertyValue > SwXAutoStyle::getProperties()
+{
+ if( !mpSet )
+ throw uno::RuntimeException();
+ SolarMutexGuard aGuard;
+ std::vector< beans::PropertyValue > aPropertyVector;
+
+ sal_Int8 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();
+ PropertyEntryVector_t aPropVector = rMap.getPropertyEntries();
+
+ 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& rProp : aPropVector )
+ {
+ if ( rProp.nWID == nWID )
+ {
+ beans::PropertyValue aPropertyValue;
+ aPropertyValue.Name = rProp.sName;
+ pItem->QueryValue( aPropertyValue.Value, rProp.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;
+ uno::Reference<style::XStyle> xTextTableStyle;
+ SwTableAutoFormat* pAutoFormat = GetTableAutoFormat(pDocShell, rTableAutoFormatName);
+ if (pAutoFormat && pAutoFormat->GetName() == rTableAutoFormatName)
+ {
+ xTextTableStyle.set(pAutoFormat->GetXObject(), uno::UNO_QUERY);
+ 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]);
+ uno::Reference<style::XStyle> xCellStyle(pBoxFormat->GetXObject(), uno::UNO_QUERY);
+ 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, const OUString& 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]);
+ uno::Reference<style::XStyle> xCellStyle(pOldBoxFormat->GetXObject(), uno::UNO_QUERY);
+ if (!xCellStyle.is())
+ continue;
+ SwXTextCellStyle& rStyle = dynamic_cast<SwXTextCellStyle&>(*xCellStyle);
+ SwBoxAutoFormat& rNewBoxFormat = pTableAutoFormat->GetBoxFormat(aTableTemplateMap[i]);
+ rStyle.SetBoxFormat(&rNewBoxFormat);
+ rNewBoxFormat.SetXObject(xCellStyle);
+ }
+ m_pTableAutoFormat_Impl = nullptr;
+ m_pTableAutoFormat = pTableAutoFormat;
+ m_pTableAutoFormat->SetXObject(uno::Reference<style::XStyle>(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;
+
+ SwAutoFormatGetDocNode aGetHt( &m_pDocShell->GetDoc()->GetNodes() );
+
+ for (SwFrameFormat* const & pFormat : *m_pDocShell->GetDoc()->GetTableFrameFormats())
+ {
+ if (!pFormat->GetInfo(aGetHt))
+ {
+ 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::makeAny(m_pTableAutoFormat->GetName());
+ else
+ throw css::beans::UnknownPropertyException(rPropertyName);
+
+ return uno::makeAny(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();
+
+ return css::uno::Any(m_aCellStyles[(*iter).second]);
+}
+
+css::uno::Sequence<OUString> SAL_CALL SwXTextTableStyle::getElementNames()
+{
+ SolarMutexGuard aGuard;
+ return comphelper::mapKeysToSequence(GetCellStyleNameMap());
+}
+
+sal_Bool SAL_CALL SwXTextTableStyle::hasByName(const OUString& rName)
+{
+ SolarMutexGuard aGuard;
+ 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;
+
+ uno::Reference<style::XStyle> xStyle = rElement.get<uno::Reference<style::XStyle>>();
+ if (!xStyle.is())
+ throw lang::IllegalArgumentException();
+
+ SwXTextCellStyle* pStyleToReplaceWith = dynamic_cast<SwXTextCellStyle*>(xStyle.get());
+ if (!pStyleToReplaceWith)
+ throw lang::IllegalArgumentException();
+
+ // replace only with physical ...
+ if (!pStyleToReplaceWith->IsPhysical())
+ throw lang::IllegalArgumentException();
+
+ const auto& rTableTemplateMap = SwTableAutoFormat::GetTableTemplateMap();
+ const sal_Int32 nBoxFormat = rTableTemplateMap[nCellStyle];
+
+ // move SwBoxAutoFormat to dest. SwTableAutoFormat
+ m_pTableAutoFormat->SetBoxFormat(*pStyleToReplaceWith->GetBoxFormat(), nBoxFormat);
+ // remove unassigned SwBoxAutoFormat, which is not anymore in use anyways
+ m_pDocShell->GetDoc()->GetCellStyles().RemoveBoxFormat(xStyle->getName());
+ // make SwXTextCellStyle use new, moved SwBoxAutoFormat
+ pStyleToReplaceWith->SetBoxFormat(&m_pTableAutoFormat->GetBoxFormat(nBoxFormat));
+ m_pTableAutoFormat->GetBoxFormat(nBoxFormat).SetXObject(xStyle);
+ // make this SwXTextTableStyle use new SwXTextCellStyle
+ m_aCellStyles[nCellStyle] = xStyle;
+}
+
+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, const OUString& sParentStyle) :
+ m_pDocShell(pDocShell),
+ m_pBoxAutoFormat(pBoxAutoFormat),
+ m_sParentStyle(sParentStyle),
+ m_bPhysical(true)
+{ }
+
+SwXTextCellStyle::SwXTextCellStyle(SwDocShell* pDocShell, const OUString& sName) :
+ m_pDocShell(pDocShell),
+ m_pBoxAutoFormat_Impl(std::make_shared<SwBoxAutoFormat>()),
+ m_sName(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(uno::Reference<style::XStyle>(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, const OUString& sName, OUString* pParentName)
+{
+ if (sName.isEmpty())
+ return nullptr;
+
+ SwBoxAutoFormat* pBoxAutoFormat = pDocShell->GetDoc()->GetCellStyles().GetBoxFormat(sName);
+ if (!pBoxAutoFormat)
+ {
+ sal_Int32 nSeparatorIndex, nTemplateIndex;
+ OUString sParentName, sCellSubName;
+
+ nSeparatorIndex = sName.lastIndexOf('.');
+ if (0 >= nSeparatorIndex)
+ return nullptr;
+
+ sParentName = sName.copy(0, nSeparatorIndex);
+ sCellSubName = sName.copy(nSeparatorIndex+1);
+ nTemplateIndex = sCellSubName.toInt32()-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)
+{
+ uno::Reference<style::XStyle> 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.set(pBoxFormat->GetXObject(), uno::UNO_QUERY);
+ 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*/)
+{
+ SolarMutexGuard aGuard;
+ // 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 SfxItemPropertySimpleEntry *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 SfxItemPropertySimpleEntry *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 SfxItemPropertySimpleEntry* 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 SfxItemPropertySimpleEntry* pEntry = rMap.getByName(rPropertyName);
+ if(pEntry)
+ {
+ 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 000000000..762dcf73d
--- /dev/null
+++ b/sw/source/core/unocore/unotbl.cxx
@@ -0,0 +1,4194 @@
+/* -*- 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 <o3tl/any.hxx>
+#include <o3tl/safeint.hxx>
+#include <svx/svxids.hrc>
+#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 <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/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 <osl/mutex.hxx>
+#include <SwStyleNameMapper.hxx>
+#include <frmatr.hxx>
+#include <sortopt.hxx>
+#include <rtl/math.hxx>
+#include <sal/log.hxx>
+#include <editeng/frmdiritem.hxx>
+#include <comphelper/interfacecontainer2.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 <poolfmt.hxx>
+#include <frameformats.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 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(
+ uno::Reference<uno::XInterface> const& xSource,
+ ::comphelper::OInterfaceContainerHelper2& rListeners)
+ {
+ rListeners.notifyEach(
+ &chart::XChartDataChangeEventListener::chartDataChanged,
+ createChartEvent(xSource));
+ }
+
+ void lcl_SendChartEvent(
+ uno::Reference<uno::XInterface> const& xSource,
+ ::cppu::OMultiTypeInterfaceContainerHelper const& rListeners)
+ {
+ auto pContainer(rListeners.getContainer(cppu::UnoType<chart::XChartDataChangeEventListener>::get()));
+ if (pContainer)
+ pContainer->notifyEach(
+ &chart::XChartDataChangeEventListener::chartDataChanged,
+ createChartEvent(xSource));
+ }
+}
+
+#define UNO_TABLE_COLUMN_SUM 10000
+
+
+static bool lcl_LineToSvxLine(const table::BorderLine& rLine, SvxBorderLine& rSvxLine)
+{
+ rSvxLine.SetColor(Color(rLine.Color));
+
+ rSvxLine.GuessLinesWidths( SvxBorderLineStyle::NONE,
+ convertMm100ToTwip( rLine.OuterLineWidth ),
+ convertMm100ToTwip( rLine.InnerLineWidth ),
+ convertMm100ToTwip( rLine.LineDistance ) );
+
+ return rLine.InnerLineWidth > 0 || rLine.OuterLineWidth > 0;
+}
+
+/// @throws lang::IllegalArgumentException
+/// @throws uno::RuntimeException
+static void lcl_SetSpecialProperty(SwFrameFormat* pFormat,
+ const SfxItemPropertySimpleEntry* 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, static_cast<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 ( convertMm100ToTwip ( nWidth ) );
+ }
+ 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
+ {
+ lang::IllegalArgumentException aExcept;
+ aExcept.Message = "relative width cannot be switched on with this property";
+ throw aExcept;
+ }
+ }
+ 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 SfxItemPropertySimpleEntry* 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::makeAny<bool>(nRepeat > 0);
+ return uno::makeAny<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();
+ const SfxPoolItem* pItem;
+ if(SfxItemState::SET == rSet.GetItemState(RES_PAGEDESC, false, &pItem))
+ {
+ const SwPageDesc* pDsc = static_cast<const SwFormatPageDesc*>(pItem)->GetPageDesc();
+ if(pDsc)
+ return uno::makeAny<OUString>(SwStyleNameMapper::GetProgName(pDsc->GetName(), SwGetPoolIdFromName::PageDesc ));
+ }
+ return uno::makeAny(OUString());
+ }
+
+ case RES_ANCHOR:
+ return uno::makeAny(text::TextContentAnchorType_AT_PARAGRAPH);
+
+ case FN_UNO_ANCHOR_TYPES:
+ {
+ uno::Sequence<text::TextContentAnchorType> aTypes{text::TextContentAnchorType_AT_PARAGRAPH};
+ return uno::makeAny(aTypes);
+ }
+
+ case FN_UNO_WRAP :
+ return uno::makeAny(text::WrapTextMode_NONE);
+
+ case FN_PARAM_LINK_DISPLAY_NAME :
+ return uno::makeAny(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->GetNode();
+ const SwNode& rRedMarkNode = pRedline->GetNode(false);
+ if(&rRedPointNode == pTableNode || &rRedMarkNode == pTableNode)
+ {
+ const SwNode& rStartOfRedline = SwNodeIndex(rRedPointNode) <= SwNodeIndex(rRedMarkNode) ?
+ rRedPointNode : rRedMarkNode;
+ bool bIsStart = &rStartOfRedline == pTableNode;
+ return uno::makeAny(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(const OUString& rCellName, sal_Int32& o_rColumn, sal_Int32& o_rRow)
+{
+ o_rColumn = o_rRow = -1; // default return values indicating failure
+ const sal_Int32 nLen = rCellName.getLength();
+ if(!nLen)
+ {
+ SAL_WARN("sw.uno", "failed to get column or row index");
+ return;
+ }
+ sal_Int32 nRowPos = 0;
+ while (nRowPos<nLen)
+ {
+ if (rCellName[nRowPos]>='0' && rCellName[nRowPos]<='9')
+ {
+ break;
+ }
+ ++nRowPos;
+ }
+ if (nRowPos>0 && nRowPos<nLen)
+ {
+ sal_Int32 nColIdx = 0;
+ for (sal_Int32 i = 0; i < nRowPos; ++i)
+ {
+ nColIdx *= 52;
+ if (i < nRowPos - 1)
+ ++nColIdx;
+ const sal_Unicode cChar = rCellName[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 = rCellName.copy(nRowPos).toInt32() - 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( const OUString &rCellName1, const OUString &rCellName2 )
+{
+ sal_Int32 nCol1 = -1, nRow1 = -1, nCol2 = -1, nRow2 = -1;
+ SwXTextTable::GetCellPosition( rCellName1, nCol1, nRow1 );
+ SwXTextTable::GetCellPosition( rCellName2, 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( const OUString &rCellName1, const OUString &rCellName2 )
+{
+ sal_Int32 nCol1 = -1, nRow1 = -1, nCol2 = -1, nRow2 = -1;
+ SwXTextTable::GetCellPosition( rCellName1, nCol1, nRow1 );
+ SwXTextTable::GetCellPosition( rCellName2, 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(
+ const OUString &rRange1StartCell, const OUString &rRange1EndCell,
+ const OUString &rRange2StartCell, const OUString &rRange2EndCell,
+ bool bCmpColsFirst )
+{
+ int (*pCompareCells)( const OUString &, const OUString & ) =
+ bCmpColsFirst ? &sw_CompareCellsByColFirst : &sw_CompareCellsByRowFirst;
+
+ int nCmpResStartCells = pCompareCells( rRange1StartCell, rRange2StartCell );
+ if ((-1 == nCmpResStartCells ) ||
+ ( 0 == nCmpResStartCells &&
+ -1 == pCompareCells( rRange1EndCell, rRange2EndCell ) ))
+ return -1;
+ else if (0 == nCmpResStartCells &&
+ 0 == pCompareCells( rRange1EndCell, rRange2EndCell ))
+ 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 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();
+ 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
+ sal_uLong nNdPos = rCell.m_pBox->IsValidNumTextNd();
+ if(ULONG_MAX != nNdPos)
+ sw_setString( rCell, OUString(), true ); // true == keep number format
+ SwDoc* pDoc = rCell.GetDoc();
+ UnoActionContext aAction(pDoc);
+ SwFrameFormat* pBoxFormat = rCell.m_pBox->ClaimFrameFormat();
+ SfxItemSet aSet(pDoc->GetAttrPool(), svl::Items<RES_BOXATR_FORMAT, RES_BOXATR_VALUE>{});
+ const SfxPoolItem* pItem;
+
+ //!! 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
+ if(SfxItemState::SET != pBoxFormat->GetAttrSet().GetItemState(RES_BOXATR_FORMAT, true, &pItem)
+ || pDoc->GetNumberFormatter()->IsTextFormat(static_cast<const SwTableBoxNumFormat*>(pItem)->GetValue()))
+ {
+ aSet.Put(SwTableBoxNumFormat(0));
+ }
+
+ SwTableBoxValue aVal(nVal);
+ aSet.Put(aVal);
+ pDoc->SetTableBoxFormulaAttrs( *rCell.m_pBox, aSet );
+ // update table
+ SwTableFormulaUpdate aTableUpdate( SwTable::FindTable( rCell.GetFrameFormat() ));
+ pDoc->getIDocumentFieldsAccess().UpdateTableFields( &aTableUpdate );
+}
+
+
+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();
+}
+
+namespace
+{
+ class theSwXCellUnoTunnelId : public rtl::Static< UnoTunnelIdInit, theSwXCellUnoTunnelId > {};
+}
+
+const uno::Sequence< sal_Int8 > & SwXCell::getUnoTunnelId()
+{
+ return theSwXCellUnoTunnelId::get().getSeq();
+}
+
+sal_Int64 SAL_CALL SwXCell::getSomething( const uno::Sequence< sal_Int8 >& rId )
+{
+ if( isUnoTunnelId<SwXCell>(rId) )
+ {
+ return sal::static_int_cast< sal_Int64 >( reinterpret_cast< sal_IntPtr >(this) );
+ }
+ else
+ return SwXText::getSomething(rId);
+}
+
+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( ) throw()
+{
+ SwXCellBaseClass::acquire();
+}
+
+void SAL_CALL SwXCell::release( ) throw()
+{
+ SolarMutexGuard aGuard;
+
+ SwXCellBaseClass::release();
+}
+
+uno::Any SAL_CALL SwXCell::queryInterface( const uno::Type& aType )
+{
+ uno::Any aRet = SwXCellBaseClass::queryInterface(aType);
+ if(aRet.getValueType() == cppu::UnoType<void>::get())
+ aRet = SwXText::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;
+}
+
+uno::Reference< text::XTextCursor >
+SwXCell::CreateCursor()
+{
+ return createTextCursor();
+}
+
+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
+ sal_uInt32 nNdPos = m_pBox->IsValidNumTextNd();
+ if(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);
+ SfxItemSet aSet(pMyDoc->GetAttrPool(), svl::Items<RES_BOXATR_FORMAT, RES_BOXATR_FORMULA>{});
+ const SfxPoolItem* pItem;
+ SwFrameFormat* pBoxFormat = m_pBox->GetFrameFormat();
+ if(SfxItemState::SET != pBoxFormat->GetAttrSet().GetItemState(RES_BOXATR_FORMAT, true, &pItem)
+ || pMyDoc->GetNumberFormatter()->IsTextFormat(static_cast<const SwTableBoxNumFormat*>(pItem)->GetValue()))
+ {
+ aSet.Put(SwTableBoxNumFormat(0));
+ }
+ aSet.Put(aFormula);
+ GetDoc()->SetTableBoxFormulaAttrs( *m_pBox, aSet );
+ // update table
+ SwTableFormulaUpdate aTableUpdate( SwTable::FindTable( GetFrameFormat() ));
+ pMyDoc->getIDocumentFieldsAccess().UpdateTableFields( &aTableUpdate );
+}
+
+double SwXCell::getValue()
+{
+ SolarMutexGuard aGuard;
+ // #i112652# a table cell may contain NaN as a value, do not filter that
+ double fRet;
+ if(IsValid() && !getString().isEmpty())
+ fRet = m_pBox->GetFrameFormat()->GetTableBoxValue().GetValue();
+ else
+ ::rtl::math::setNan( &fRet );
+ return fRet;
+}
+
+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);
+}
+
+uno::Reference<text::XTextCursor> SwXCell::createTextCursor()
+{
+ SolarMutexGuard aGuard;
+ if(!m_pStartNode && !IsValid())
+ throw uno::RuntimeException();
+ const SwStartNode* pSttNd = m_pStartNode ? m_pStartNode : m_pBox->GetSttNd();
+ SwPosition aPos(*pSttNd);
+ SwXTextCursor* const pXCursor =
+ new SwXTextCursor(*GetDoc(), this, CursorType::TableText, aPos);
+ auto& rUnoCursor(pXCursor->GetCursor());
+ rUnoCursor.Move(fnMoveForward, GoInNode);
+ return static_cast<text::XWordCursor*>(pXCursor);
+}
+
+uno::Reference<text::XTextCursor> SwXCell::createTextCursorByRange(const uno::Reference< text::XTextRange > & xTextPosition)
+{
+ SolarMutexGuard aGuard;
+ 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.GetNode().StartOfSectionNode();
+ while(p1->IsSectionNode())
+ p1 = p1->StartOfSectionNode();
+ if( p1 != pSttNd )
+ return nullptr;
+ return static_cast<text::XWordCursor*>(
+ 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: ", static_cast<cppu::OWeakObject*>(this));
+
+ // Create a 'Table Cell Redline' object
+ SwUnoCursorHelper::makeTableCellRedline(*m_pBox, sRedlineType, tableCellProperties);
+
+
+ }
+ 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, static_cast<cppu::OWeakObject*>(this));
+ 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, static_cast<cppu::OWeakObject*>(this));
+ switch(pEntry->nWID)
+ {
+ case FN_UNO_CELL_ROW_SPAN:
+ return uno::makeAny(m_pBox->getRowSpan());
+ break;
+ 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::makeAny(SwXTextSections::GetObject(*rSect.GetFormat()));
+ }
+ break;
+ case FN_UNO_CELL_NAME:
+ return uno::makeAny(m_pBox->GetName());
+ break;
+ 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* pDoc = aPos.GetDoc();
+ if (!pDoc)
+ return uno::Any();
+
+ m_xParentText = sw::CreateParentXText(*pDoc, aPos);
+ }
+
+ return uno::makeAny(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", static_cast<cppu::OWeakObject*>(this)); };
+
+void SwXCell::removePropertyChangeListener(const OUString& /*rPropertyName*/, const uno::Reference< beans::XPropertyChangeListener > & /*xListener*/)
+ { throw uno::RuntimeException("not implemented", static_cast<cppu::OWeakObject*>(this)); };
+
+void SwXCell::addVetoableChangeListener(const OUString& /*rPropertyName*/, const uno::Reference< beans::XVetoableChangeListener > & /*xListener*/)
+ { throw uno::RuntimeException("not implemented", static_cast<cppu::OWeakObject*>(this)); };
+
+void SwXCell::removeVetoableChangeListener(const OUString& /*rPropertyName*/, const uno::Reference< beans::XVetoableChangeListener > & /*xListener*/)
+ { throw uno::RuntimeException("not implemented", static_cast<cppu::OWeakObject*>(this)); };
+
+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)
+ SwTable const*const pTable(&pSttNd->FindTableNode()->GetTable());
+ return SwXParagraphEnumeration::Create(this, pUnoCursor, CursorType::TableText, pSttNd, pTable);
+}
+
+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;
+ }
+}
+
+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 : 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
+ const SfxPoolItem* pItem;
+ auto pBoxFormat(GetTableBox()->GetFrameFormat());
+ SfxItemState eState = pBoxFormat->GetAttrSet().GetItemState(RES_BOXATR_FORMAT, true, &pItem);
+
+ if (eState == SfxItemState::SET)
+ {
+ // please note that the language of the numberformat
+ // is implicitly coded into the below value as well
+ nFIndex = static_cast<const SwTableBoxNumFormat*>(pItem)->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))
+ ::rtl::math::setNan(&fTmp);
+ 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::makeAny(getValue()) : uno::makeAny(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),
+ 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(), static_cast<cppu::OWeakObject*>(this));
+ SwTable* pTable = SwTable::FindTable( pFormat );
+ SwTableLine* pLn = SwXTextTableRow::FindLine(pTable, pLine);
+ if(pLn)
+ {
+ // 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: ", static_cast < cppu::OWeakObject * > ( this ) );
+ }
+
+ // Create a 'Table Row Redline' object
+ SwUnoCursorHelper::makeTableRowRedline( *pLn, sRedlineType, tableRowProperties);
+
+ }
+ else
+ {
+ const SfxItemPropertySimpleEntry* pEntry =
+ m_pPropSet->getPropertyMap().getByName(rPropertyName);
+ SwDoc* pDoc = pFormat->GetDoc();
+ if (!pEntry)
+ throw beans::UnknownPropertyException("Unknown property: " + rPropertyName, static_cast < cppu::OWeakObject * > ( this ) );
+ if ( pEntry->nFlags & beans::PropertyAttribute::READONLY)
+ throw beans::PropertyVetoException("Property is read-only: " + rPropertyName, static_cast < cppu::OWeakObject * > ( this ) );
+
+ 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( convertMm100ToTwip(nHeight) );
+ 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, 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(), static_cast<cppu::OWeakObject*>(this));
+ SwTable* pTable = SwTable::FindTable( pFormat );
+ SwTableLine* pLn = SwXTextTableRow::FindLine(pTable, pLine);
+ if(pLn)
+ {
+ const SfxItemPropertySimpleEntry* pEntry =
+ m_pPropSet->getPropertyMap().getByName(rPropertyName);
+ if (!pEntry)
+ throw beans::UnknownPropertyException("Unknown property: " + rPropertyName, static_cast < cppu::OWeakObject * > ( this ) );
+
+ 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, 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", static_cast<cppu::OWeakObject*>(this)); };
+
+void SwXTextTableRow::removePropertyChangeListener(const OUString& /*rPropertyName*/, const uno::Reference< beans::XPropertyChangeListener > & /*xListener*/)
+ { throw uno::RuntimeException("not implemented", static_cast<cppu::OWeakObject*>(this)); };
+
+void SwXTextTableRow::addVetoableChangeListener(const OUString& /*rPropertyName*/, const uno::Reference< beans::XVetoableChangeListener > & /*xListener*/)
+ { throw uno::RuntimeException("not implemented", static_cast<cppu::OWeakObject*>(this)); };
+
+void SwXTextTableRow::removeVetoableChangeListener(const OUString& /*rPropertyName*/, const uno::Reference< beans::XVetoableChangeListener > & /*xListener*/)
+ { throw uno::RuntimeException("not implemented", static_cast<cppu::OWeakObject*>(this)); };
+
+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 == 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::acquire() throw()
+{
+ SwXTextTableCursor_Base::acquire();
+}
+
+void SwXTextTableCursor::release() throw()
+{
+ SolarMutexGuard aGuard;
+ SwXTextTableCursor_Base::release();
+}
+
+css::uno::Any SAL_CALL
+SwXTextTableCursor::queryInterface( const css::uno::Type& _rType )
+{
+ css::uno::Any aReturn = SwXTextTableCursor_Base::queryInterface( _rType );
+ if ( !aReturn.hasValue() )
+ aReturn = OTextCursorHelper::queryInterface( _rType );
+ return aReturn;
+}
+
+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()->nNode.GetNode().FindTableBoxStartNode();
+ const SwTable* pTable = SwTable::FindTable(GetFrameFormat());
+ const SwTableBox* pEndBox = pTable->GetTableBox(pNode->GetIndex());
+ if(pTableCursor->HasMark())
+ {
+ pNode = pTableCursor->GetMark()->nNode.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", static_cast<cppu::OWeakObject*>(this));
+ 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, static_cast<cppu::OWeakObject*>(this));
+ if(pEntry->nFlags & beans::PropertyAttribute::READONLY)
+ throw beans::PropertyVetoException("Property is read-only: " + rPropertyName, static_cast<cppu::OWeakObject*>(this));
+ {
+ auto pSttNode = rUnoCursor.GetNode().StartOfSectionNode();
+ const SwTableNode* pTableNode = pSttNode->FindTableNode();
+ lcl_FormatTable(pTableNode->GetTable().GetFrameFormat());
+ }
+ auto& rTableCursor = dynamic_cast<SwUnoTableCursor&>(rUnoCursor);
+ rTableCursor.MakeBoxSels();
+ SwDoc* pDoc = 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);
+ pDoc->SetBoxAttr(rUnoCursor, *aBrush);
+
+ }
+ break;
+ case RES_BOXATR_FORMAT:
+ {
+ SfxUInt32Item aNumberFormat(RES_BOXATR_FORMAT);
+ aNumberFormat.PutValue(aValue, 0);
+ pDoc->SetBoxAttr(rUnoCursor, aNumberFormat);
+ }
+ break;
+ case FN_UNO_PARA_STYLE:
+ SwUnoCursorHelper::SetTextFormatColl(aValue, rUnoCursor);
+ break;
+ default:
+ {
+ SfxItemSet aItemSet(pDoc->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.GetNode().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, static_cast<cppu::OWeakObject*>(this));
+ 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, static_cast<cppu::OWeakObject*>(this));
+ break;
+ case FN_UNO_PARA_STYLE:
+ {
+ auto pFormat(SwUnoCursorHelper::GetCurTextFormatColl(rUnoCursor, false));
+ if(pFormat)
+ aResult <<= pFormat->GetName();
+ }
+ break;
+ default:
+ {
+ SfxItemSet aSet(rTableCursor.GetDoc()->GetAttrPool(),
+ svl::Items<RES_CHRATR_BEGIN, RES_FRMATR_END-1,
+ RES_UNKNOWNATR_CONTAINER, RES_UNKNOWNATR_CONTAINER>{});
+ 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", static_cast<cppu::OWeakObject*>(this)); };
+
+void SwXTextTableCursor::removePropertyChangeListener(const OUString& /*rPropertyName*/, const uno::Reference< beans::XPropertyChangeListener > & /*xListener*/)
+ { throw uno::RuntimeException("not implemented", static_cast<cppu::OWeakObject*>(this)); };
+
+void SwXTextTableCursor::addVetoableChangeListener(const OUString& /*rPropertyName*/, const uno::Reference< beans::XVetoableChangeListener > & /*xListener*/)
+ { throw uno::RuntimeException("not implemented", static_cast<cppu::OWeakObject*>(this)); };
+
+void SwXTextTableCursor::removeVetoableChangeListener(const OUString& /*rPropertyName*/, const uno::Reference< beans::XVetoableChangeListener > & /*xListener*/)
+ { throw uno::RuntimeException("not implemented", static_cast<cppu::OWeakObject*>(this)); };
+
+void SwXTextTableCursor::Notify( const SfxHint& rHint )
+{
+ if(rHint.GetId() == SfxHintId::Dying)
+ m_pFrameFormat = nullptr;
+}
+
+
+// SwXTextTable ===========================================================
+
+namespace {
+
+class SwTableProperties_Impl
+{
+ SwUnoCursorHelper::SwAnyMapHelper 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)
+ { aAnyMap.SetValue( nWhichId, nMemberId, rVal ); }
+
+bool SwTableProperties_Impl::GetProperty(sal_uInt16 nWhichId, sal_uInt16 nMemberId, const uno::Any*& rpAny )
+ { return 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(*aItem);
+ }
+}
+void SwTableProperties_Impl::ApplyTableAttr(const SwTable& rTable, SwDoc& rDoc)
+{
+ SfxItemSet aSet(
+ rDoc.GetAttrPool(),
+ svl::Items<
+ 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>{});
+ 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;
+ ::osl::Mutex m_Mutex; // just for OInterfaceContainerHelper2
+
+public:
+ uno::WeakReference<uno::XInterface> m_wThis;
+ ::cppu::OMultiTypeInterfaceContainerHelper m_Listeners;
+
+ 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_Listeners(m_Mutex)
+ , 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",
+ static_cast<cppu::OWeakObject*>(&rThis));
+ }
+ return std::make_pair(nRowCount, nColCount);
+ }
+
+ sal_uInt16 GetRowCount();
+ sal_uInt16 GetColumnCount();
+
+ virtual void Notify(const SfxHint&) override;
+
+};
+
+namespace
+{
+ class theSwXTextTableUnoTunnelId : public rtl::Static< UnoTunnelIdInit, theSwXTextTableUnoTunnelId > {};
+}
+
+const uno::Sequence< sal_Int8 > & SwXTextTable::getUnoTunnelId()
+ { return theSwXTextTableUnoTunnelId::get().getSeq(); }
+
+sal_Int64 SAL_CALL SwXTextTable::getSomething( const uno::Sequence< sal_Int8 >& rId )
+{
+ if(isUnoTunnelId<SwXTextTable>(rId))
+ {
+ return sal::static_int_cast<sal_Int64>(reinterpret_cast<sal_IntPtr>(this));
+ }
+ return 0;
+}
+
+
+SwXTextTable::SwXTextTable()
+ : m_pImpl(new Impl(nullptr))
+{
+}
+
+SwXTextTable::SwXTextTable(SwFrameFormat& rFrameFormat)
+ : m_pImpl(new Impl(&rFrameFormat))
+{
+}
+
+SwXTextTable::~SwXTextTable()
+{
+}
+
+uno::Reference<text::XTextTable> SwXTextTable::CreateXTextTable(SwFrameFormat* const pFrameFormat)
+{
+ uno::Reference<text::XTextTable> xTable;
+ if(pFrameFormat)
+ xTable.set(pFrameFormat->GetXObject(), uno::UNO_QUERY); // cached?
+ if(xTable.is())
+ return xTable;
+ SwXTextTable* const pNew( pFrameFormat ? new SwXTextTable(*pFrameFormat) : new SwXTextTable());
+ xTable.set(pNew);
+ if(pFrameFormat)
+ pFrameFormat->SetXObject(xTable);
+ // need a permanent Reference to initialize m_wThis
+ pNew->m_pImpl->m_wThis = xTable;
+ 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 = static_cast<sal_uInt16>(nR);
+ m_pImpl->m_nColumns = static_cast<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(), static_cast<cppu::OWeakObject*>(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(), static_cast<cppu::OWeakObject*>(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.", static_cast<cppu::OWeakObject*>(this));
+
+ uno::Reference<XUnoTunnel> xRangeTunnel(xTextRange, uno::UNO_QUERY);
+ SwXTextRange* pRange(nullptr);
+ OTextCursorHelper* pCursor(nullptr);
+ if(xRangeTunnel.is())
+ {
+ pRange = reinterpret_cast<SwXTextRange*>(
+ sal::static_int_cast<sal_IntPtr>(xRangeTunnel->getSomething(SwXTextRange::getUnoTunnelId())));
+ pCursor = reinterpret_cast<OTextCursorHelper*>(
+ sal::static_int_cast<sal_IntPtr>(xRangeTunnel->getSomething(OTextCursorHelper::getUnoTunnelId())));
+ }
+ 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()->nContent.GetIndex() )
+ {
+ 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();
+ }
+ pTable = pDoc->InsertTable(SwInsertTableOptions( SwInsertTableFlags::Headline | SwInsertTableFlags::DefaultBorder | SwInsertTableFlags::SplitLayout, 0 ),
+ *aPam.GetPoint(),
+ m_pImpl->m_nRows,
+ m_pImpl->m_nColumns,
+ text::HoriOrientation::FULL);
+ 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);
+
+ if (!m_pImpl->m_sTableName.isEmpty())
+ {
+ sal_uInt16 nIndex = 1;
+ OUString sTmpNameIndex(m_pImpl->m_sTableName);
+ while(pDoc->FindTableFormatByName(sTmpNameIndex, true) && nIndex < USHRT_MAX)
+ {
+ sTmpNameIndex = m_pImpl->m_sTableName + OUString::number(nIndex++);
+ }
+ pDoc->SetTableName( *pTableFormat, sTmpNameIndex);
+ }
+
+ const::uno::Any* pName;
+ if (m_pImpl->m_pTableProps->GetProperty(FN_UNO_TABLE_NAME, 0, pName))
+ setName(pName->get<OUString>());
+ m_pImpl->m_pTableProps.reset();
+ }
+ pDoc->GetIDocumentUndoRedo().EndUndo( SwUndoId::END, nullptr );
+ }
+}
+
+uno::Reference<text::XTextRange> SwXTextTable::getAnchor()
+{
+ SolarMutexGuard aGuard;
+ SwFrameFormat* pFormat = lcl_EnsureCoreConnected(GetFrameFormat(), static_cast<cppu::OWeakObject*>(this));
+ return new SwXTextRange(*pFormat);
+}
+
+void SwXTextTable::dispose()
+{
+ SolarMutexGuard aGuard;
+ SwFrameFormat* pFormat = lcl_EnsureCoreConnected(GetFrameFormat(), static_cast<cppu::OWeakObject*>(this));
+ SwTable* pTable = SwTable::FindTable(pFormat);
+ SwSelBoxes aSelBoxes;
+ for(auto& rBox : pTable->GetTabSortBoxes() )
+ aSelBoxes.insert(rBox);
+ pFormat->GetDoc()->DeleteRowCol(aSelBoxes);
+}
+
+void SAL_CALL SwXTextTable::addEventListener(
+ const uno::Reference<lang::XEventListener> & xListener)
+{
+ // no need to lock here as m_pImpl is const and container threadsafe
+ m_pImpl->m_Listeners.addInterface(
+ cppu::UnoType<lang::XEventListener>::get(), 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
+ m_pImpl->m_Listeners.removeInterface(
+ cppu::UnoType<lang::XEventListener>::get(), 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 {
+
+uno::Reference<table::XCellRange> 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()->nNode = *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).get();
+}
+
+} // 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(), static_cast<cppu::OWeakObject*>(this));
+ SwTable* pTable = lcl_EnsureTableNotComplex(SwTable::FindTable(pFormat), static_cast<cppu::OWeakObject*>(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
+ lcl_SendChartEvent(*this, m_pImpl->m_Listeners);
+}
+
+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
+ m_pImpl->m_Listeners.addInterface(
+ cppu::UnoType<chart::XChartDataChangeEventListener>::get(), 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
+ m_pImpl->m_Listeners.removeInterface(
+ cppu::UnoType<chart::XChartDataChangeEventListener>::get(), 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))
+ {
+ 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(), static_cast<cppu::OWeakObject*>(this));
+ SwTable* pTable = lcl_EnsureTableNotComplex(SwTable::FindTable(pFormat), static_cast<cppu::OWeakObject*>(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 SfxItemPropertySimpleEntry* 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, static_cast < cppu::OWeakObject * > ( this ) );
+
+ 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)
+ {
+ lcl_SendChartEvent(*this, m_pImpl->m_Listeners);
+ m_pImpl->m_bFirstRowAsLabel = bTmp;
+ }
+ }
+ break;
+
+ case FN_UNO_RANGE_COL_LABEL:
+ {
+ bool bTmp = *o3tl::doAccess<bool>(aValue);
+ if (m_pImpl->m_bFirstColumnAsLabel != bTmp)
+ {
+ lcl_SendChartEvent(*this, m_pImpl->m_Listeners);
+ 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()->nNode = *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();
+
+ SfxItemSet aSet(pDoc->GetAttrPool(),
+ svl::Items<RES_BOX, RES_BOX,
+ SID_ATTR_BORDER_INNER, SID_ATTR_BORDER_INNER>{});
+
+ 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(static_cast<sal_uInt16>(convertMm100ToTwip(aBorder.Distance)));
+ 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 = convertMm100ToTwip(aTableBorderDistances.LeftDistance);
+ const sal_uInt16 nRightDistance = convertMm100ToTwip(aTableBorderDistances.RightDistance);
+ const sal_uInt16 nTopDistance = convertMm100ToTwip(aTableBorderDistances.TopDistance);
+ const sal_uInt16 nBottomDistance = convertMm100ToTwip(aTableBorderDistances.BottomDistance);
+ 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();
+ pDoc->GetDocShell()->GetFEShell()->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 SfxItemPropertySimpleEntry* pEntry =
+ m_pImpl->m_pPropSet->getPropertyMap().getByName(rPropertyName);
+
+ if (!pEntry)
+ throw beans::UnknownPropertyException("Unknown property: " + rPropertyName, static_cast < cppu::OWeakObject * > ( this ) );
+
+ 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, OUString(), 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()->nNode = *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();
+
+ SfxItemSet aSet(pDoc->GetAttrPool(),
+ svl::Items<RES_BOX, RES_BOX,
+ SID_ATTR_BORDER_INNER, SID_ATTR_BORDER_INNER>{});
+ 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", static_cast<cppu::OWeakObject*>(this)); }
+
+void SwXTextTable::removePropertyChangeListener(const OUString& /*rPropertyName*/, const uno::Reference< beans::XPropertyChangeListener > & /*xListener*/)
+ { throw uno::RuntimeException("Not implemented", static_cast<cppu::OWeakObject*>(this)); }
+
+void SwXTextTable::addVetoableChangeListener(const OUString& /*rPropertyName*/, const uno::Reference< beans::XVetoableChangeListener > & /*xListener*/)
+ { throw uno::RuntimeException("Not implemented", static_cast<cppu::OWeakObject*>(this)); }
+
+void SwXTextTable::removeVetoableChangeListener(const OUString& /*rPropertyName*/, const uno::Reference< beans::XVetoableChangeListener > & /*xListener*/)
+ { throw uno::RuntimeException("Not implemented", static_cast<cppu::OWeakObject*>(this)); }
+
+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 SwFrameFormats* pFrameFormats = pFormat->GetDoc()->GetTableFrameFormats();
+ for (size_t i = pFrameFormats->size(); i;)
+ {
+ const SwFrameFormat* pTmpFormat = (*pFrameFormats)[--i];
+ if( !pTmpFormat->IsDefault() &&
+ pTmpFormat->GetName() == rName &&
+ pFormat->GetDoc()->IsUsed( *pTmpFormat ))
+ {
+ throw uno::RuntimeException();
+ }
+ }
+
+ pFormat->SetName( 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 notfied 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();
+ }
+ 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
+ if(!m_pFrameFormat)
+ {
+ lang::EventObject const ev(xThis);
+ m_Listeners.disposeAndClear(ev);
+ }
+ else
+ {
+ lcl_SendChartEvent(xThis.get(), m_Listeners);
+ }
+ }
+}
+
+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:
+ ::osl::Mutex m_Mutex; // just for OInterfaceContainerHelper2
+ SwFrameFormat* m_pFrameFormat;
+
+public:
+ uno::WeakReference<uno::XInterface> m_wThis;
+ ::comphelper::OInterfaceContainerHelper2 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_ChartListeners(m_Mutex)
+ , 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;
+
+};
+
+namespace
+{
+ class theSwXCellRangeUnoTunnelId : public rtl::Static< UnoTunnelIdInit, theSwXCellRangeUnoTunnelId > {};
+}
+
+const uno::Sequence< sal_Int8 > & SwXCellRange::getUnoTunnelId()
+{
+ return theSwXCellRangeUnoTunnelId::get().getSeq();
+}
+
+sal_Int64 SAL_CALL SwXCellRange::getSomething( const uno::Sequence< sal_Int8 >& rId )
+{
+ if( isUnoTunnelId<SwXCellRange>(rId) )
+ {
+ return sal::static_int_cast< sal_Int64 >( reinterpret_cast< sal_IntPtr >(this) );
+ }
+ return 0;
+}
+
+
+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)
+{
+ SwXCellRange *const pCellRange(new SwXCellRange(pCursor, rFrameFormat, rDesc));
+ uno::Reference<table::XCellRange> xCellRange(pCellRange);
+ // need a permanent Reference to initialize m_wThis
+ pCellRange->m_pImpl->m_wThis = xCellRange;
+ 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 )
+ {
+ 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;
+ uno::Reference< table::XCellRange > 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()->nNode = *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)
+ {
+ const SfxItemPropertySimpleEntry *const pEntry =
+ m_pImpl->m_pPropSet->getPropertyMap().getByName(rPropertyName);
+ if(!pEntry)
+ throw beans::UnknownPropertyException("Unknown property: " + rPropertyName, static_cast < cppu::OWeakObject * > ( this ) );
+
+ if ( pEntry->nFlags & beans::PropertyAttribute::READONLY)
+ throw beans::PropertyVetoException("Property is read-only: " + rPropertyName, static_cast < cppu::OWeakObject * > ( this ) );
+
+ SwDoc *const pDoc = 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);
+ pDoc->SetBoxAttr(*m_pImpl->m_pTableCursor, *aBrush);
+
+ }
+ break;
+ case RES_BOX :
+ {
+ SfxItemSet aSet(pDoc->GetAttrPool(),
+ svl::Items<RES_BOX, RES_BOX,
+ SID_ATTR_BORDER_INNER, SID_ATTR_BORDER_INNER>{});
+ 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);
+ pDoc->SetTabBorders(*m_pImpl->m_pTableCursor, aSet);
+ }
+ break;
+ case RES_BOXATR_FORMAT:
+ {
+ SfxUInt32Item aNumberFormat(RES_BOXATR_FORMAT);
+ static_cast<SfxPoolItem&>(aNumberFormat).PutValue(aValue, 0);
+ pDoc->SetBoxAttr(rCursor, aNumberFormat);
+ }
+ break;
+ case FN_UNO_RANGE_ROW_LABEL:
+ {
+ bool bTmp = *o3tl::doAccess<bool>(aValue);
+ if (m_pImpl->m_bFirstRowAsLabel != bTmp)
+ {
+ lcl_SendChartEvent(*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)
+ {
+ lcl_SendChartEvent(*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)
+ pDoc->SetBoxAlign( rCursor, nAlign );
+ }
+ break;
+ default:
+ {
+ SfxItemSet aItemSet( pDoc->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 SfxItemPropertySimpleEntry *const pEntry =
+ m_pImpl->m_pPropSet->getPropertyMap().getByName(rPropertyName);
+ if(!pEntry)
+ throw beans::UnknownPropertyException("Unknown property: " + rPropertyName, static_cast < cppu::OWeakObject * > ( this ) );
+
+ 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 *const pDoc = m_pImpl->m_pTableCursor->GetDoc();
+ SfxItemSet aSet(pDoc->GetAttrPool(),
+ svl::Items<RES_BOX, RES_BOX,
+ SID_ATTR_BORDER_INNER, SID_ATTR_BORDER_INNER>{});
+ 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:
+ {
+ SfxItemSet aSet(
+ m_pImpl->m_pTableCursor->GetDoc()->GetAttrPool(),
+ svl::Items<
+ RES_CHRATR_BEGIN, RES_FRMATR_END - 1,
+ RES_UNKNOWNATR_CONTAINER,
+ RES_UNKNOWNATR_CONTAINER>{});
+ // first look at the attributes of the cursor
+ SwUnoTableCursor *const pCursor =
+ dynamic_cast<SwUnoTableCursor*>(&(*m_pImpl->m_pTableCursor));
+ SwUnoCursorHelper::GetCursorAttr(pCursor->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", static_cast<cppu::OWeakObject*>(this)); }
+
+void SwXCellRange::removePropertyChangeListener(const OUString& /*PropertyName*/, const uno::Reference< beans::XPropertyChangeListener > & /*aListener*/)
+ { throw uno::RuntimeException("Not implemented", static_cast<cppu::OWeakObject*>(this)); }
+
+void SwXCellRange::addVetoableChangeListener(const OUString& /*PropertyName*/, const uno::Reference< beans::XVetoableChangeListener > & /*aListener*/)
+ { throw uno::RuntimeException("Not implemented", static_cast<cppu::OWeakObject*>(this)); }
+
+void SwXCellRange::removeVetoableChangeListener(const OUString& /*PropertyName*/, const uno::Reference< beans::XVetoableChangeListener > & /*aListener*/)
+ { throw uno::RuntimeException("Not implemented", static_cast<cppu::OWeakObject*>(this)); }
+
+///@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", static_cast<cppu::OWeakObject*>(this));
+ lcl_EnsureCoreConnected(m_pImpl->GetFrameFormat(), static_cast<cppu::OWeakObject*>(this));
+ uno::Sequence< uno::Sequence< uno::Any > > aRowSeq(nRowCount);
+ auto vCells(GetCells());
+ auto pCurrentCell(vCells.begin());
+ for(auto& rRow : aRowSeq)
+ {
+ rRow = uno::Sequence< uno::Any >(nColCount);
+ for(auto& rCellAny : rRow)
+ {
+ auto pCell(static_cast<SwXCell*>(pCurrentCell->get()));
+ if(!pCell)
+ throw uno::RuntimeException("Table too complex", static_cast<cppu::OWeakObject*>(this));
+ 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", static_cast<cppu::OWeakObject*>(this));
+ 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()), static_cast<cppu::OWeakObject*>(this));
+ 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()), static_cast<cppu::OWeakObject*>(this));
+ for(const auto& aValue : rColSeq)
+ {
+ auto pCell(static_cast<SwXCell*>(pCurrentCell->get()));
+ if(!pCell || !pCell->GetTableBox())
+ throw uno::RuntimeException("Box for cell missing", static_cast<cppu::OWeakObject*>(this));
+ 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", static_cast<cppu::OWeakObject*>(this));
+ 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 : vRows)
+ {
+ rRow = uno::Sequence<double>(nColCount);
+ for(auto& rValue : rRow)
+ {
+ if(!(*pCurrentCell))
+ throw uno::RuntimeException("Table too complex", static_cast<cppu::OWeakObject*>(this));
+ 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", static_cast<cppu::OWeakObject*>(this));
+ 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(), static_cast<cppu::OWeakObject*>(this));
+ if(rData.getLength() != nRowCount)
+ throw uno::RuntimeException("Row count mismatch. expected: " + OUString::number(nRowCount) + " got: " + OUString::number(rData.getLength()), static_cast<cppu::OWeakObject*>(this));
+ 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()), static_cast<cppu::OWeakObject*>(this));
+ 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", static_cast<cppu::OWeakObject*>(&rThis));
+ lcl_EnsureCoreConnected(GetFrameFormat(), static_cast<cppu::OWeakObject*>(&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.begin(),
+ [](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(), static_cast<cppu::OWeakObject*>(&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", static_cast<cppu::OWeakObject*>(&rThis));
+ auto xLabelRange(rThis.getCellRangeByPosition(nLeft, nTop, nRight, nBottom));
+ if (!xLabelRange.is())
+ throw uno::RuntimeException("Missing Cell Range", static_cast<cppu::OWeakObject*>(&rThis));
+ 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", static_cast<cppu::OWeakObject*>(&rThis));
+ 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
+ m_pImpl->m_ChartListeners.addInterface(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
+ m_pImpl->m_ChartListeners.removeInterface(xListener);
+}
+
+sal_Bool SwXCellRange::isNotANumber(double /*fNumber*/)
+ { throw uno::RuntimeException("Not implemented", static_cast<cppu::OWeakObject*>(this)); }
+
+double SwXCellRange::getNotANumber()
+ { throw uno::RuntimeException("Not implemented", static_cast<cppu::OWeakObject*>(this)); }
+
+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)
+ lcl_SendChartEvent(xThis.get(), m_ChartListeners);
+ else
+ m_ChartListeners.disposeAndClear(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(), static_cast<cppu::OWeakObject*>(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);
+ return uno::makeAny(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(), static_cast<cppu::OWeakObject*>(this)));
+ SwTable* pTable = lcl_EnsureTableNotComplex(SwTable::FindTable(pFrameFormat), static_cast<cppu::OWeakObject*>(this));
+ const size_t nRowCount = pTable->GetTabLines().size();
+ if (nCount <= 0 || !(0 <= nIndex && o3tl::make_unsigned(nIndex) <= nRowCount))
+ throw uno::RuntimeException("Illegal arguments", static_cast<cppu::OWeakObject*>(this));
+ 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", static_cast<cppu::OWeakObject*>(this));
+ 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, static_cast<sal_uInt16>(nCount), bAppend);
+}
+
+void SwXTableRows::removeByIndex(sal_Int32 nIndex, sal_Int32 nCount)
+{
+ SolarMutexGuard aGuard;
+ if (nCount == 0)
+ return;
+ SwFrameFormat* pFrameFormat(lcl_EnsureCoreConnected(GetFrameFormat(), static_cast<cppu::OWeakObject*>(this)));
+ if(nIndex < 0 || nCount <=0 )
+ throw uno::RuntimeException();
+ SwTable* pTable = lcl_EnsureTableNotComplex(SwTable::FindTable(pFrameFormat), static_cast<cppu::OWeakObject*>(this));
+ OUString sTLName = sw_GetCellName(0, nIndex);
+ const SwTableBox* pTLBox = pTable->GetTableBox(sTLName);
+ if(!pTLBox)
+ throw uno::RuntimeException("Illegal arguments", static_cast<cppu::OWeakObject*>(this));
+ 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", static_cast<cppu::OWeakObject*>(this));
+ pUnoCursor->SetMark();
+ pUnoCursor->GetPoint()->nNode = *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(), static_cast<cppu::OWeakObject*>(this)));
+ SwTable* pTable = SwTable::FindTable( pFrameFormat );
+// if(!pTable->IsTableComplex())
+// throw uno::RuntimeException("Table too complex", static_cast<cppu::OWeakObject*>(this));
+ 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::makeAny(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(), static_cast<cppu::OWeakObject*>(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(), static_cast<cppu::OWeakObject*>(this)));
+ SwTable* pTable = lcl_EnsureTableNotComplex(SwTable::FindTable(pFrameFormat), static_cast<cppu::OWeakObject*>(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", static_cast<cppu::OWeakObject*>(this));
+ 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", static_cast<cppu::OWeakObject*>(this));
+ 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, static_cast<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(), static_cast<cppu::OWeakObject*>(this)));
+ if(nIndex < 0 || nCount <=0 )
+ throw uno::RuntimeException();
+ SwTable* pTable = lcl_EnsureTableNotComplex(SwTable::FindTable(pFrameFormat), static_cast<cppu::OWeakObject*>(this));
+ const OUString sTLName = sw_GetCellName(nIndex, 0);
+ const SwTableBox* pTLBox = pTable->GetTableBox( sTLName );
+ if(!pTLBox)
+ throw uno::RuntimeException("Cell not found", static_cast<cppu::OWeakObject*>(this));
+ 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", static_cast<cppu::OWeakObject*>(this));
+ pUnoCursor->SetMark();
+ pUnoCursor->GetPoint()->nNode = *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 000000000..394e8ae7d
--- /dev/null
+++ b/sw/source/core/unocore/unotext.cxx
@@ -0,0 +1,2717 @@
+/* -*- 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 <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 <IDocumentUndoRedo.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>
+
+using namespace ::com::sun::star;
+
+const char cInvalidObject[] = "this object is invalid";
+
+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
+ uno::Reference< text::XTextRange >
+ 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 >
+SwXText::CreateCursor()
+{
+ uno::Reference< text::XTextCursor > xRet;
+ if(IsValid())
+ {
+ SwNode& rNode = GetDoc()->GetNodes().GetEndOfContent();
+ SwPosition aPos(rNode);
+ xRet = static_cast<text::XWordCursor*>(
+ new SwXTextCursor(*GetDoc(), this, m_pImpl->m_eType, aPos));
+ xRet->gotoStart(false);
+ }
+ return xRet;
+}
+
+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<lang::XUnoTunnel>::get())
+ {
+ aRet <<= uno::Reference< lang::XUnoTunnel >(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();
+ }
+ const uno::Reference<lang::XUnoTunnel> xRangeTunnel(xTextRange,
+ uno::UNO_QUERY);
+ SwXTextRange *const pRange =
+ ::sw::UnoTunnelGetImplementation<SwXTextRange>(xRangeTunnel);
+ OTextCursorHelper *const pCursor =
+ ::sw::UnoTunnelGetImplementation<OTextCursorHelper>(xRangeTunnel);
+ 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->GetNode().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, bForceExpandHints);
+ }
+ else
+ {
+ xTextRange->setString(rString);
+ }
+ }
+ else
+ {
+ pRange->DeleteAndInsert(rString, bForceExpandHints);
+ }
+ }
+ 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()->nNode);
+ m_pImpl->m_pDoc->getIDocumentContentOperations().SplitNode(*aPam.GetPoint(), false);
+ break;
+ case text::ControlCharacter::APPEND_PARAGRAPH:
+ {
+ m_pImpl->m_pDoc->ClearBoxNumAttrs(aPam.GetPoint()->nNode);
+ m_pImpl->m_pDoc->getIDocumentContentOperations().AppendTextNode(*aPam.GetPoint());
+
+ const uno::Reference<lang::XUnoTunnel> xRangeTunnel(
+ xTextRange, uno::UNO_QUERY);
+ SwXTextRange *const pRange =
+ ::sw::UnoTunnelGetImplementation<SwXTextRange>(xRangeTunnel);
+ OTextCursorHelper *const pCursor =
+ ::sw::UnoTunnelGetImplementation<OTextCursorHelper>(
+ xRangeTunnel);
+ 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)
+ {
+ const uno::Reference<lang::XUnoTunnel> xRangeTunnel(
+ xTextRange, uno::UNO_QUERY);
+ SwXTextRange *const pRange =
+ ::sw::UnoTunnelGetImplementation<SwXTextRange>(xRangeTunnel);
+ OTextCursorHelper *const pCursor =
+ ::sw::UnoTunnelGetImplementation<OTextCursorHelper>(xRangeTunnel);
+
+ 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
+ {
+ 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())
+ {
+ lang::IllegalArgumentException aIllegal;
+ aIllegal.Message = "first parameter invalid;";
+ throw aIllegal;
+ }
+ if (!xContent.is())
+ {
+ lang::IllegalArgumentException aIllegal;
+ aIllegal.Message = "second parameter invalid";
+ throw aIllegal;
+ }
+ if(!GetDoc())
+ {
+ uno::RuntimeException aRuntime;
+ aRuntime.Message = cInvalidObject;
+ throw aRuntime;
+ }
+
+ SwUnoInternalPaM aPam(*GetDoc());
+ if (!::sw::XTextRangeToSwPaM(aPam, xRange))
+ {
+ lang::IllegalArgumentException aIllegal;
+ aIllegal.Message = "first parameter invalid";
+ throw aIllegal;
+ }
+
+ // 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.GetNode().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)
+ {
+ uno::RuntimeException aRunException;
+ aRunException.Message = "text interface and cursor not related";
+ throw aRunException;
+ }
+
+ const bool bForceExpandHints(CheckForOwnMemberMeta(aPam, bAbsorb));
+
+ // special treatment for Contents that do not replace the range, but
+ // instead are "overlaid"
+ const uno::Reference<lang::XUnoTunnel> xContentTunnel(xContent,
+ uno::UNO_QUERY);
+ if (!xContentTunnel.is())
+ {
+ lang::IllegalArgumentException aArgException;
+ aArgException.Message = "text content does not support lang::XUnoTunnel";
+ throw aArgException;
+ }
+ SwXDocumentIndexMark *const pDocumentIndexMark =
+ ::sw::UnoTunnelGetImplementation<SwXDocumentIndexMark>(xContentTunnel);
+ SwXTextSection *const pSection =
+ ::sw::UnoTunnelGetImplementation<SwXTextSection>(xContentTunnel);
+ SwXBookmark *const pBookmark =
+ ::sw::UnoTunnelGetImplementation<SwXBookmark>(xContentTunnel);
+ SwXReferenceMark *const pReferenceMark =
+ ::sw::UnoTunnelGetImplementation<SwXReferenceMark>(xContentTunnel);
+ SwXMeta *const pMeta =
+ ::sw::UnoTunnelGetImplementation<SwXMeta>(xContentTunnel);
+ SwXTextField* pTextField =
+ ::sw::UnoTunnelGetImplementation<SwXTextField>(xContentTunnel);
+ if (pTextField && pTextField->GetServiceId() != SwServiceType::FieldTypeAnnotation)
+ pTextField = nullptr;
+
+ const bool bAttribute = pBookmark || pDocumentIndexMark
+ || pSection || pReferenceMark || pMeta || pTextField;
+
+ if (bAbsorb && !bAttribute)
+ {
+ 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())
+ {
+ uno::RuntimeException aRuntime;
+ aRuntime.Message = cInvalidObject;
+ throw aRuntime;
+ }
+
+ SwXParagraph *const pPara =
+ comphelper::getUnoTunnelImplementation<SwXParagraph>(xNewContent);
+ if (!pPara || !pPara->IsDescriptor() || !xSuccessor.is())
+ {
+ throw lang::IllegalArgumentException();
+ }
+
+ bool bRet = false;
+ const uno::Reference<lang::XUnoTunnel> xSuccTunnel(xSuccessor,
+ uno::UNO_QUERY);
+ SwXTextSection *const pXSection =
+ ::sw::UnoTunnelGetImplementation<SwXTextSection>(xSuccTunnel);
+ SwXTextTable *const pXTable =
+ ::sw::UnoTunnelGetImplementation<SwXTextTable>(xSuccTunnel);
+ 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.nNode.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.nNode.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 =
+ comphelper::getUnoTunnelImplementation<SwXParagraph>(xNewContent);
+ if(!pPara || !pPara->IsDescriptor() || !xPredecessor.is())
+ {
+ throw lang::IllegalArgumentException();
+ }
+
+ const uno::Reference<lang::XUnoTunnel> xPredTunnel(xPredecessor,
+ uno::UNO_QUERY);
+ SwXTextSection *const pXSection =
+ ::sw::UnoTunnelGetImplementation<SwXTextSection>(xPredTunnel);
+ SwXTextTable *const pXTable =
+ ::sw::UnoTunnelGetImplementation<SwXTextTable>(xPredTunnel);
+ 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.nNode.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.nNode.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())
+ {
+ uno::RuntimeException aRuntime;
+ aRuntime.Message = cInvalidObject;
+ throw aRuntime;
+ }
+
+ bool bRet = false;
+ const uno::Reference<lang::XUnoTunnel> xSuccTunnel(xSuccessor,
+ uno::UNO_QUERY);
+ SwXTextSection *const pXSection =
+ ::sw::UnoTunnelGetImplementation<SwXTextSection>(xSuccTunnel);
+ SwXTextTable *const pXTable =
+ ::sw::UnoTunnelGetImplementation<SwXTextTable>(xSuccTunnel);
+ 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())
+ {
+ uno::RuntimeException aRuntime;
+ aRuntime.Message = cInvalidObject;
+ throw aRuntime;
+ }
+
+ bool bRet = false;
+ const uno::Reference<lang::XUnoTunnel> xPredTunnel(xPredecessor,
+ uno::UNO_QUERY);
+ SwXTextSection *const pXSection =
+ ::sw::UnoTunnelGetImplementation<SwXTextSection>(xPredTunnel);
+ SwXTextTable *const pXTable =
+ ::sw::UnoTunnelGetImplementation<SwXTextTable>(xPredTunnel);
+ 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())
+ {
+ uno::RuntimeException aRuntime;
+ aRuntime.Message = "first parameter invalid";
+ throw aRuntime;
+ }
+ 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 uno::Reference< text::XTextCursor > xRef = CreateCursor();
+ if(!xRef.is())
+ {
+ uno::RuntimeException aRuntime;
+ aRuntime.Message = cInvalidObject;
+ throw aRuntime;
+ }
+ xRef->gotoStart(false);
+ return xRef;
+}
+
+uno::Reference< text::XTextRange > SAL_CALL
+SwXText::getEnd()
+{
+ SolarMutexGuard aGuard;
+
+ const uno::Reference< text::XTextCursor > xRef = CreateCursor();
+ if(!xRef.is())
+ {
+ uno::RuntimeException aRuntime;
+ aRuntime.Message = cInvalidObject;
+ throw aRuntime;
+ }
+ xRef->gotoEnd(false);
+ return xRef;
+}
+
+OUString SAL_CALL SwXText::getString()
+{
+ SolarMutexGuard aGuard;
+
+ const uno::Reference< text::XTextCursor > xRet = CreateCursor();
+ 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())
+ {
+ uno::RuntimeException aRuntime;
+ aRuntime.Message = cInvalidObject;
+ throw aRuntime;
+ }
+
+ 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 );
+ SwPosition aEndPos(aEndIdx.GetNode());
+ SwPaM aPam(aEndPos);
+ GetDoc()->getIDocumentContentOperations().AppendTextNode( *aPam.Start() );
+ }
+ }
+
+ const uno::Reference< text::XTextCursor > xRet = CreateCursor();
+ if(!xRet.is())
+ {
+ GetDoc()->GetIDocumentUndoRedo().EndUndo(SwUndoId::END, nullptr);
+ uno::RuntimeException aRuntime;
+ aRuntime.Message = cInvalidObject;
+ throw aRuntime;
+ }
+ 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 uno::Reference<text::XTextCursor> xOwnCursor(m_rThis.CreateCursor());
+
+ OTextCursorHelper *const pOwnCursor =
+ comphelper::getUnoTunnelImplementation<OTextCursorHelper>(xOwnCursor);
+ OSL_ENSURE(pOwnCursor, "OTextCursorHelper::getUnoTunnelId() ??? ");
+ const SwStartNode* pOwnStartNode =
+ pOwnCursor->GetPaM()->GetNode().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.GetNode();
+ 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();
+ }
+
+ SfxItemPropertySimpleEntry const*const pEntry =
+ m_pImpl->m_rPropSet.getPropertyMap().getByName(rPropertyName);
+ if (!pEntry)
+ {
+ beans::UnknownPropertyException aExcept;
+ aExcept.Message = "Unknown property: " + rPropertyName;
+ throw aExcept;
+ }
+
+ 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 sal_uLong nOwnIndex = pStartNode->EndOfSectionIndex();
+ for (size_t nRed = 0; nRed < nRedTableCount; ++nRed)
+ {
+ SwRangeRedline const*const pRedline = rRedTable[nRed];
+ SwPosition const*const pRedStart = pRedline->Start();
+ const SwNodeIndex nRedNode = pRedStart->nNode;
+ if (nOwnIndex == nRedNode.GetIndex())
+ {
+ 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
+{
+ class theSwXTextUnoTunnelId : public rtl::Static< UnoTunnelIdInit, theSwXTextUnoTunnelId > {};
+}
+
+const uno::Sequence< sal_Int8 > & SwXText::getUnoTunnelId()
+{
+ return theSwXTextUnoTunnelId::get().getSeq();
+}
+
+sal_Int64 SAL_CALL
+SwXText::getSomething(const uno::Sequence< sal_Int8 >& rId)
+{
+ return ::sw::UnoTunnelImpl<SwXText>(rId, this);
+}
+
+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);
+}
+
+uno::Reference< text::XTextRange >
+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();
+ }
+
+ uno::Reference< text::XTextRange > 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 );
+ SwPosition aInsertPosition(
+ SwNodeIndex( *pStartNode->EndOfSectionNode(), -1 ) );
+ SwPaM aPam(aInsertPosition);
+ // 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()->nNode.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)
+ {
+ lang::IllegalArgumentException aEx;
+ aEx.Message = sMessage;
+ throw aEx;
+ }
+ else
+ {
+ uno::RuntimeException aEx;
+ aEx.Message = sMessage;
+ throw aEx;
+ }
+ }
+ SwTextNode *const pTextNode( aPam.Start()->nNode.GetNode().GetTextNode() );
+ OSL_ENSURE(pTextNode, "no SwTextNode?");
+ if (pTextNode)
+ {
+ xRet.set(SwXParagraph::CreateXParagraph(*m_pDoc, pTextNode, &m_rThis),
+ uno::UNO_QUERY);
+ }
+
+ 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 uno::Reference<text::XTextCursor> xTextCursor = createTextCursorByRange(xInsertPosition);
+
+ const uno::Reference< lang::XUnoTunnel > xRangeTunnel(
+ xTextCursor, uno::UNO_QUERY_THROW );
+ SwXTextCursor *const pTextCursor =
+ ::sw::UnoTunnelGetImplementation<SwXTextCursor>(xRangeTunnel);
+
+ bool bIllegalException = false;
+ bool bRuntimeException = false;
+ OUString sMessage;
+ m_pImpl->m_pDoc->GetIDocumentUndoRedo().StartUndo(SwUndoId::INSERT, nullptr);
+
+ auto& rCursor(pTextCursor->GetCursor());
+ m_pImpl->m_pDoc->DontExpandFormat( *rCursor.Start() );
+
+ if (!rText.isEmpty())
+ {
+ SwNodeIndex const nodeIndex(rCursor.GetPoint()->nNode, -1);
+ const sal_Int32 nContentPos = rCursor.GetPoint()->nContent.GetIndex();
+ SwUnoCursorHelper::DocInsertStringSplitCR(
+ *m_pImpl->m_pDoc, rCursor, rText, false);
+ SwUnoCursorHelper::SelectPam(rCursor, true);
+ rCursor.GetPoint()->nNode.Assign(nodeIndex.GetNode(), +1);
+ rCursor.GetPoint()->nContent = 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)
+ {
+ lang::IllegalArgumentException aEx;
+ aEx.Message = sMessage;
+ throw aEx;
+ }
+ else
+ {
+ uno::RuntimeException aEx;
+ aEx.Message = sMessage;
+ throw aEx;
+ }
+ }
+ 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();
+}
+
+// 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();
+ }
+ uno::Reference< text::XTextContent > xRet;
+ std::unique_ptr<SwUnoInternalPaM> pTempStartPam(new SwUnoInternalPaM(*GetDoc()));
+ std::unique_ptr< SwUnoInternalPaM > pEndPam(new SwUnoInternalPaM(*GetDoc()));
+ if (!::sw::XTextRangeToSwPaM(*pTempStartPam, xStart) ||
+ !::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 =
+ comphelper::getUnoTunnelImplementation<SwXTextRange>(xStart);
+ SwXTextRange *const pEndRange =
+ comphelper::getUnoTunnelImplementation<SwXTextRange>(xEnd);
+ // 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->GetNode().StartOfSectionNode();
+ while (pStartStartNode && pStartStartNode->IsSectionNode())
+ {
+ pStartStartNode = pStartStartNode->StartOfSectionNode();
+ }
+ SwStartNode* pEndStartNode = pEndPam->GetNode().StartOfSectionNode();
+ while (pEndStartNode && pEndStartNode->IsSectionNode())
+ {
+ pEndStartNode = pEndStartNode->StartOfSectionNode();
+ }
+ bool bParaAfterInserted = false;
+ bool bParaBeforeInserted = false;
+ 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->GetNode().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->GetNode().StartOfSectionNode();
+ }
+ // now we should have the positions in the same hierarchy
+ if ((pStartStartNode != pEndStartNode) ||
+ (pStartStartNode != GetStartNode()))
+ {
+ // if not - remove the additional paragraphs and throw
+ 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()->nNode == pEndPam->Start()->nNode
+ && pStartPam->End()->nNode == pEndPam->End()->nNode)
+ {
+ SwPosition aEnd(*pStartPam->End());
+ bParaAfterInserted = GetDoc()->getIDocumentContentOperations().AppendTextNode( aEnd );
+ pEndPam->DeleteMark();
+ *pEndPam->GetPoint() = 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();
+ if ( !isGraphicNode(pFrameFormat) &&
+ (RndStdIds::FLY_AT_PARA == rAnchor.GetAnchorId() || RndStdIds::FLY_AT_CHAR == rAnchor.GetAnchorId()) &&
+ pStartPam->Start()->nNode.GetIndex() <= rAnchor.GetContentAnchor()->nNode.GetIndex() &&
+ pStartPam->End()->nNode.GetIndex() >= rAnchor.GetContentAnchor()->nNode.GetIndex())
+ {
+ if (pFrameFormat->GetName().isEmpty())
+ {
+ aAnchoredObjectsByPtr.insert(pFrameFormat->FindSdrObject());
+ }
+ else
+ {
+ aAnchoredObjectsByName.insert(pFrameFormat->GetName());
+ }
+ }
+ }
+
+ const uno::Reference<text::XTextFrame> xNewFrame(
+ SwXTextFrame::CreateXTextFrame(*m_pImpl->m_pDoc, nullptr));
+ SwXTextFrame& rNewFrame = dynamic_cast<SwXTextFrame&>(*xNewFrame);
+ try
+ {
+ for (const beans::PropertyValue& rValue : rFrameProperties)
+ {
+ rNewFrame.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(rNewFrame.IsDescriptor());
+ rNewFrame.attachToRange(xInsertTextRange, pStartPam.get());
+ rNewFrame.setName(m_pImpl->m_pDoc->GetUniqueFrameName());
+ }
+
+ SwTextNode *const pTextNode(pStartPam->GetNode().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->GetNode() );
+ if (aMovePam.Move( fnMoveForward, GoInContent ))
+ {
+ // move the anchor to the next paragraph
+ SwFormatAnchor aNewAnchor(rNewFrame.GetFrameFormat()->GetAnchor());
+ aNewAnchor.SetAnchor( aMovePam.Start() );
+ m_pImpl->m_pDoc->SetAttr(
+ aNewAnchor, *rNewFrame.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);
+ }
+ }
+ }
+ }
+ 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 = xNewFrame;
+ if (bParaBeforeInserted || bParaAfterInserted)
+ {
+ const uno::Reference<text::XTextCursor> xFrameTextCursor =
+ rNewFrame.createTextCursor();
+ SwXTextCursor *const pFrameCursor =
+ comphelper::getUnoTunnelImplementation<SwXTextCursor>(xFrameTextCursor);
+ if (bParaBeforeInserted)
+ {
+ // todo: remove paragraph before frame
+ m_pImpl->m_pDoc->getIDocumentContentOperations().DelFullPara(*pFrameCursor->GetPaM());
+ }
+ if (bParaAfterInserted)
+ {
+ xFrameTextCursor->gotoEnd(false);
+ if (!bParaBeforeInserted)
+ m_pImpl->m_pDoc->getIDocumentContentOperations().DelFullPara(*pFrameCursor->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(*pFrameCursor->GetPaM()->GetNode().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()->nNode;
+ 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)
+ {
+ lang::IllegalArgumentException aEx;
+ aEx.Message = sMessage;
+ throw aEx;
+ }
+ else
+ {
+ uno::RuntimeException aEx;
+ aEx.Message = sMessage;
+ throw aEx;
+ }
+ }
+ 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()->nNode,
+ aEndCellPam.End()->nNode);
+ std::unique_ptr<SwNodeRange> pCorrectedRange =
+ m_pDoc->GetNodes().ExpandRangeForTableBox(aTmpRange);
+
+ if (pCorrectedRange)
+ {
+ SwPaM aNewStartPaM(pCorrectedRange->aStart, 0);
+ aStartCellPam = aNewStartPaM;
+
+ sal_Int32 nEndLen = 0;
+ SwTextNode * pTextNode = pCorrectedRange->aEnd.GetNode().GetTextNode();
+ if (pTextNode != nullptr)
+ nEndLen = pTextNode->Len();
+
+ SwPaM aNewEndPaM(pCorrectedRange->aEnd, nEndLen);
+ aEndCellPam = aNewEndPaM;
+
+ pCorrectedRange.reset();
+ }
+
+ /** check the nodes between start and end
+ it is allowed to have pairs of StartNode/EndNodes
+ */
+ if (aStartCellPam.Start()->nNode < aEndCellPam.End()->nNode)
+ {
+ // increment on each StartNode and decrement on each EndNode
+ // we must reach zero at the end and must not go below zero
+ long nOpenNodeBlock = 0;
+ SwNodeIndex aCellIndex = aStartCellPam.Start()->nNode;
+ while (aCellIndex < aEndCellPam.End()->nNode.GetIndex())
+ {
+ 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()->nContent.GetIndex())
+ {
+ m_pDoc->getIDocumentContentOperations().SplitNode(*aStartCellPam.Start(), false);
+ }
+ }
+ else
+ {
+ // check the predecessor
+ const sal_uLong nStartCellNodeIndex =
+ aStartCellPam.Start()->nNode.GetIndex();
+ const sal_uLong nLastNodeEndIndex = pLastCell->aEnd.GetIndex();
+ if (nLastNodeEndIndex == nStartCellNodeIndex)
+ {
+ // same node as predecessor then equal nContent?
+ if (0 != aStartCellPam.Start()->nContent.GetIndex())
+ {
+ throw lang::IllegalArgumentException();
+ }
+
+ m_pDoc->getIDocumentContentOperations().SplitNode(*aStartCellPam.Start(), false);
+ sal_uLong const nNewIndex(aStartCellPam.Start()->nNode.GetIndex());
+ 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()->nContent.GetIndex() <
+ aEndCellPam.End()->nNode.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()->nContent = 0;
+ aEndCellPam.DeleteMark();
+ aEndCellPam.Move(fnMoveBackward, GoInNode);
+ aEndCellPam.GetPoint()->nContent =
+ aEndCellPam.GetNode().GetTextNode()->Len();
+ }
+
+ assert(aStartCellPam.Start()->nContent.GetIndex() == 0);
+ assert(aEndCellPam.End()->nContent.GetIndex() == aEndCellPam.End()->nNode.GetNode().GetTextNode()->Len());
+ SwNodeRange aCellRange(aStartCellPam.Start()->nNode,
+ aEndCellPam.End()->nNode);
+ rRowNodes.push_back(aCellRange); // note: invalidates pLastCell!
+}
+
+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
+ {
+ xCellPS->setPropertyValue(rName, rValue);
+ }
+ catch (const uno::Exception& e)
+ {
+ SAL_WARN( "sw.uno", "Exception when getting PropertyState: "
+ + rName + ". Message: " + e.Message );
+ }
+ }
+ }
+}
+
+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::makeAny(nCellCount--));
+ nCellCount*=-1;
+ for(auto pxPSet = aMergedCell.aCells.begin()+1; nCellCount<0; ++pxPSet, ++nCellCount)
+ (*pxPSet)->setPropertyValue(UNO_NAME_ROW_SPAN, uno::makeAny(nCellCount));
+ }
+}
+
+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
+ {
+ xPrSet->setPropertyValue(rTableProperty.Name, rTableProperty.Value);
+ }
+ catch (const uno::Exception& e)
+ {
+ SAL_WARN( "sw.uno", "Exception when setting property: "
+ + rTableProperty.Name + ". Message: " + e.Message );
+ }
+ }
+
+ //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;
+
+ uno::Reference<lang::XUnoTunnel> const xSourceTunnel(xSource,
+ uno::UNO_QUERY);
+ SwXText const*const pSource( xSourceTunnel.is()
+ ? ::sw::UnoTunnelGetImplementation<SwXText>(xSourceTunnel)
+ : nullptr);
+
+ uno::Reference< text::XText > const xText(xSource, uno::UNO_QUERY_THROW);
+ uno::Reference< text::XTextCursor > const xCursor =
+ xText->createTextCursor();
+ xCursor->gotoEnd( true );
+
+ uno::Reference< lang::XUnoTunnel > const xCursorTunnel(xCursor,
+ uno::UNO_QUERY_THROW);
+
+ OTextCursorHelper *const pCursor =
+ ::sw::UnoTunnelGetImplementation<OTextCursorHelper>(xCursorTunnel);
+ if (!pCursor)
+ {
+ throw uno::RuntimeException();
+ }
+
+ SwNodeIndex rNdIndex( *GetStartNode( ), 1 );
+ SwPosition rPos( rNdIndex );
+ // tdf#112202 need SwXText because cursor cannot select table at the start
+ if (pSource)
+ {
+ SwTextNode * pFirstNode;
+ {
+ SwPaM temp(*pSource->GetStartNode(), *pSource->GetStartNode()->EndOfSectionNode(), +1, -1);
+ pFirstNode = temp.GetMark()->nNode.GetNode().GetTextNode();
+ if (pFirstNode)
+ {
+ pFirstNode->MakeStartIndex(&temp.GetMark()->nContent);
+ }
+ if (SwTextNode *const pNode = temp.GetPoint()->nNode.GetNode().GetTextNode())
+ {
+ pNode->MakeEndIndex(&temp.GetPoint()->nContent);
+ }
+ // 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(SwNodeIndex(*GetStartNode(), 1))));
+ m_pImpl->m_pDoc->getIDocumentContentOperations().DelFullPara(*pDelCursor);
+ }
+ }
+ else
+ {
+ m_pImpl->m_pDoc->getIDocumentContentOperations().CopyRange(*pCursor->GetPaM(), rPos, SwCopyFlags::CheckPosInFly);
+ }
+
+}
+
+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::Any SAL_CALL
+SwXBodyText::queryAggregation(const uno::Type& rType)
+{
+ uno::Any aRet;
+ if (rType == cppu::UnoType<container::XEnumerationAccess>::get())
+ {
+ aRet <<= uno::Reference< container::XEnumerationAccess >(this);
+ }
+ else if (rType == cppu::UnoType<container::XElementAccess>::get())
+ {
+ aRet <<= uno::Reference< container::XElementAccess >(this);
+ }
+ else if (rType == cppu::UnoType<lang::XServiceInfo>::get())
+ {
+ aRet <<= uno::Reference< lang::XServiceInfo >(this);
+ }
+ else
+ {
+ aRet = SwXText::queryInterface( rType );
+ }
+ if(aRet.getValueType() == cppu::UnoType<void>::get())
+ {
+ aRet = OWeakAggObject::queryAggregation( rType );
+ }
+ return aRet;
+}
+
+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;
+}
+
+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.GetNode().FindTableNode();
+ SwContentNode * pCont = nullptr;
+ while (pTableNode)
+ {
+ aPam.GetPoint()->nNode = *pTableNode->EndOfSectionNode();
+ pCont = GetDoc()->GetNodes().GoNext(&aPam.GetPoint()->nNode);
+ pTableNode = pCont->FindTableNode();
+ }
+ if (pCont)
+ {
+ aPam.GetPoint()->nContent.Assign(pCont, 0);
+ }
+ }
+ return new SwXTextCursor(*GetDoc(), this, CursorType::Body, *aPam.GetPoint());
+}
+
+uno::Reference< text::XTextCursor > SAL_CALL
+SwXBodyText::createTextCursor()
+{
+ SolarMutexGuard aGuard;
+
+ const uno::Reference< text::XTextCursor > xRef(
+ static_cast<text::XWordCursor*>(CreateTextCursor()) );
+ if (!xRef.is())
+ {
+ uno::RuntimeException aRuntime;
+ aRuntime.Message = cInvalidObject;
+ throw aRuntime;
+ }
+ return xRef;
+}
+
+uno::Reference< text::XTextCursor > SAL_CALL
+SwXBodyText::createTextCursorByRange(
+ const uno::Reference< text::XTextRange > & xTextPosition)
+{
+ SolarMutexGuard aGuard;
+
+ if(!IsValid())
+ {
+ uno::RuntimeException aRuntime;
+ aRuntime.Message = cInvalidObject;
+ throw aRuntime;
+ }
+
+ uno::Reference< text::XTextCursor > aRef;
+ SwUnoInternalPaM aPam(*GetDoc());
+ if (::sw::XTextRangeToSwPaM(aPam, xTextPosition))
+ {
+ if ( !aPam.GetNode().GetTextNode() )
+ throw uno::RuntimeException("Invalid text range" );
+
+ SwNode& rNode = GetDoc()->GetNodes().GetEndOfContent();
+
+ SwStartNode* p1 = aPam.GetNode().StartOfSectionNode();
+ //document starts with a section?
+ while(p1->IsSectionNode())
+ {
+ p1 = p1->StartOfSectionNode();
+ }
+ SwStartNode *const p2 = rNode.StartOfSectionNode();
+
+ if(p1 == p2)
+ {
+ aRef = static_cast<text::XWordCursor*>(
+ 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()
+{
+ SolarMutexGuard aGuard;
+
+ if (!IsValid())
+ {
+ uno::RuntimeException aRuntime;
+ aRuntime.Message = cInvalidObject;
+ throw aRuntime;
+ }
+
+ 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())
+ {
+ uno::RuntimeException aRuntime;
+ aRuntime.Message = cInvalidObject;
+ throw aRuntime;
+ }
+
+ 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;
+ }
+};
+
+uno::Reference<text::XText> SwXHeadFootText::CreateXHeadFootText(
+ SwFrameFormat& rHeadFootFormat,
+ const bool bIsHeader)
+{
+ // re-use existing SwXHeadFootText
+ // #i105557#: do not iterate over the registered clients: race condition
+ uno::Reference<text::XText> xText(rHeadFootFormat.GetXObject(), uno::UNO_QUERY);
+ if(!xText.is())
+ {
+ const auto pXHFT(new SwXHeadFootText(rHeadFootFormat, bIsHeader));
+ xText.set(pXHFT);
+ rHeadFootFormat.SetXObject(xText);
+ }
+ 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::Reference<text::XTextCursor> SwXHeadFootText::CreateCursor()
+{
+ return createTextCursor();
+}
+
+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;
+}
+
+uno::Reference<text::XTextCursor> SAL_CALL
+SwXHeadFootText::createTextCursor()
+{
+ SolarMutexGuard aGuard;
+
+ SwFrameFormat & rHeadFootFormat( m_pImpl->GetHeadFootFormatOrThrow() );
+
+ const SwFormatContent& rFlyContent = rHeadFootFormat.GetContent();
+ const SwNode& rNode = rFlyContent.GetContentIdx()->GetNode();
+ SwPosition aPos(rNode);
+ SwXTextCursor *const 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);
+ // is there a table here?
+ SwTableNode* pTableNode = rUnoCursor.GetNode().FindTableNode();
+ SwContentNode* pCont = nullptr;
+ while (pTableNode)
+ {
+ rUnoCursor.GetPoint()->nNode = *pTableNode->EndOfSectionNode();
+ pCont = GetDoc()->GetNodes().GoNext(&rUnoCursor.GetPoint()->nNode);
+ pTableNode = pCont->FindTableNode();
+ }
+ if (pCont)
+ {
+ rUnoCursor.GetPoint()->nContent.Assign(pCont, 0);
+ }
+ SwStartNode const*const pNewStartNode = rUnoCursor.GetNode().FindSttNodeByType(
+ (m_pImpl->m_bIsHeader) ? SwHeaderStartNode : SwFooterStartNode);
+ if (!pNewStartNode || (pNewStartNode != pOwnStartNode))
+ {
+ uno::RuntimeException aExcept;
+ aExcept.Message = "no text available";
+ throw aExcept;
+ }
+ return static_cast<text::XWordCursor*>(pXCursor);
+}
+
+uno::Reference<text::XTextCursor> SAL_CALL SwXHeadFootText::createTextCursorByRange(
+ const uno::Reference<text::XTextRange>& xTextPosition)
+{
+ SolarMutexGuard aGuard;
+ SwFrameFormat& rHeadFootFormat( m_pImpl->GetHeadFootFormatOrThrow() );
+
+ SwUnoInternalPaM aPam(*GetDoc());
+ if (!sw::XTextRangeToSwPaM(aPam, xTextPosition))
+ {
+ uno::RuntimeException aRuntime;
+ aRuntime.Message = cInvalidObject;
+ throw aRuntime;
+ }
+
+ SwNode& rNode = rHeadFootFormat.GetContent().GetContentIdx()->GetNode();
+ SwPosition aPos(rNode);
+ SwPaM aHFPam(aPos);
+ aHFPam.Move(fnMoveForward, GoInNode);
+ SwStartNode* const pOwnStartNode = aHFPam.GetNode().FindSttNodeByType(
+ (m_pImpl->m_bIsHeader) ? SwHeaderStartNode : SwFooterStartNode);
+ SwStartNode* const p1 = aPam.GetNode().FindSttNodeByType(
+ (m_pImpl->m_bIsHeader) ? SwHeaderStartNode : SwFooterStartNode);
+ if (p1 == pOwnStartNode)
+ {
+ return static_cast<text::XWordCursor*>(
+ 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 000000000..f20b47e15
--- /dev/null
+++ b/sw/source/core/unocore/unotextmarkup.cxx
@@ -0,0 +1,531 @@
+/* -*- 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 <o3tl/safeint.hxx>
+#include <osl/diagnose.h>
+#include <svl/listener.hxx>
+#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 <IGrammarContact.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, const ModelToViewHelper& rMap)
+ : m_pTextNode(pTextNode)
+ , m_ConversionMap(rMap)
+ {
+ 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()
+{
+ SolarMutexGuard aGuard;
+
+ uno::Reference< container::XStringKeyMap > xProp = new SwXStringKeyMap;
+ return xProp;
+}
+
+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;
+
+ uno::Reference<lang::XUnoTunnel> xRangeTunnel( xRange, uno::UNO_QUERY);
+
+ if(!xRangeTunnel.is()) return;
+
+ SwXTextRange* pRange = nullptr;
+ OTextCursorHelper* pCursor = nullptr;
+
+ if(xRangeTunnel.is())
+ {
+ pRange = reinterpret_cast<SwXTextRange*>( sal::static_int_cast< sal_IntPtr >( xRangeTunnel->getSomething(SwXTextRange::getUnoTunnelId())));
+ pCursor = reinterpret_cast<OTextCursorHelper*>( sal::static_int_cast< sal_IntPtr >( xRangeTunnel->getSomething(OTextCursorHelper::getUnoTunnelId())));
+ }
+
+ if (pRange)
+ {
+ SwDoc& rDoc = pRange->GetDoc();
+
+ SwUnoInternalPaM aPam(rDoc);
+
+ ::sw::XTextRangeToSwPaM(aPam, xRange);
+
+ SwPosition* startPos = aPam.Start();
+ SwPosition* endPos = aPam.End();
+
+ commitStringMarkup (nType, aIdentifier, startPos->nContent.GetIndex(), endPos->nContent.GetIndex() - startPos->nContent.GetIndex(), xMarkupInfoContainer);
+ }
+ else if (pCursor)
+ {
+ SwPaM & rPam(*pCursor->GetPaM());
+
+ SwPosition* startPos = rPam.Start();
+ SwPosition* endPos = rPam.End();
+
+ commitStringMarkup (nType, aIdentifier, startPos->nContent.GetIndex(), endPos->nContent.GetIndex() - startPos->nContent.GetIndex(), 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( pWList );
+ }
+ }
+ else if ( nType == text::TextMarkupType::PROOFREADING || nType == text::TextMarkupType::SENTENCE )
+ {
+ IGrammarContact *pGrammarContact = getGrammarContact(*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( new 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( 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 )
+ finishGrammarCheck(*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;
+ IGrammarContact *pGrammarContact = getGrammarContact(*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( new 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 )
+ finishGrammarCheck(*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: */