diff options
Diffstat (limited to 'sw/source/core/unocore/unoobj.cxx')
-rw-r--r-- | sw/source/core/unocore/unoobj.cxx | 1010 |
1 files changed, 601 insertions, 409 deletions
diff --git a/sw/source/core/unocore/unoobj.cxx b/sw/source/core/unocore/unoobj.cxx index 079e69ba2abc..ee8645aab566 100644 --- a/sw/source/core/unocore/unoobj.cxx +++ b/sw/source/core/unocore/unoobj.cxx @@ -25,6 +25,8 @@ #include <o3tl/safeint.hxx> #include <osl/endian.h> #include <unotools/collatorwrapper.hxx> + +#include <autostyle_helper.hxx> #include <swtypes.hxx> #include <hintids.hxx> #include <cmdid.h> @@ -36,11 +38,13 @@ #include <ndtxt.hxx> #include <unocrsr.hxx> #include <unocrsrhelper.hxx> +#include <unoport.hxx> #include <swundo.hxx> #include <rootfrm.hxx> #include <paratr.hxx> #include <pam.hxx> #include <shellio.hxx> +#include <unotbl.hxx> #include <fmtruby.hxx> #include <docsh.hxx> #include <docstyle.hxx> @@ -54,8 +58,10 @@ #include <unomap.hxx> #include <unoprnms.hxx> #include <unometa.hxx> +#include <unocontentcontrol.hxx> #include <unotext.hxx> #include <com/sun/star/text/TextMarkupType.hpp> +#include <utility> #include <vcl/svapp.hxx> #include <unotools/syslocale.hxx> #include <i18nlangtag/languagetag.hxx> @@ -68,8 +74,11 @@ #include <unoparaframeenum.hxx> #include <unoparagraph.hxx> #include <iodetect.hxx> +#include <comphelper/propertyvalue.hxx> #include <comphelper/servicehelper.hxx> #include <comphelper/profilezone.hxx> +#include <comphelper/flagguard.hxx> +#include <swmodule.hxx> using namespace ::com::sun::star; @@ -83,6 +92,7 @@ SwUnoInternalPaM::~SwUnoInternalPaM() { while( GetNext() != this) { + // coverity[deref_arg] - the delete moves a new entry into GetNext() delete GetNext(); } } @@ -153,6 +163,11 @@ void SwUnoCursorHelper::GetTextFromPam(SwPaM & rPam, OUString & rBuffer, const bool bOldShowProgress = xWrt->m_bShowProgress; xWrt->m_bShowProgress = false; xWrt->m_bHideDeleteRedlines = pLayout && pLayout->IsHideRedlines(); + // tdf#155951 SwWriter::Write calls EndAllAction, and that + // called SelectShell(), triggering selection change event, which + // resulted infinite recursion, if selectionChanged() calls + // XTextRange::getString() e.g. on the selected range. + ::comphelper::FlagRestorationGuard g(g_bNoInterrupt, true); if( ! aWriter.Write( xWrt ).IsError() ) { @@ -265,11 +280,9 @@ SwUnoCursorHelper::SetPageDesc( return false; } std::unique_ptr<SwFormatPageDesc> pNewDesc; - const SfxPoolItem* pItem; - if(SfxItemState::SET == rSet.GetItemState( RES_PAGEDESC, true, &pItem ) ) + if(const SwFormatPageDesc* pItem = rSet.GetItemIfSet( RES_PAGEDESC )) { - pNewDesc.reset(new SwFormatPageDesc( - *static_cast<const SwFormatPageDesc*>(pItem))); + pNewDesc.reset(new SwFormatPageDesc(*pItem)); } if (!pNewDesc) { @@ -299,7 +312,7 @@ SwUnoCursorHelper::SetPageDesc( } else { - rSet.Put(*pNewDesc); + rSet.Put(std::move(pNewDesc)); } } return true; @@ -310,7 +323,7 @@ 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)); + sal_uInt16 nStt = (nTmp < 0 ? USHRT_MAX : o3tl::narrowing<sal_uInt16>(nTmp)); SwDoc& rDoc = rCursor.GetDoc(); UnoActionContext aAction(&rDoc); @@ -349,8 +362,7 @@ lcl_setCharFormatSequence(SwPaM & rPam, uno::Any const& rValue) 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>{}); + SfxItemSetFixed<RES_TXTATR_CHARFMT, RES_TXTATR_CHARFMT> aSet(rPam.GetDoc().GetAttrPool()); lcl_setCharStyle(rPam.GetDoc(), aStyle, aSet); // the first style should replace the current attributes, // all other have to be added @@ -384,11 +396,9 @@ lcl_setDropcapCharStyle(SwPaM const & rPam, SfxItemSet & rItemSet, throw lang::IllegalArgumentException(); } std::unique_ptr<SwFormatDrop> pDrop; - SfxPoolItem const* pItem(nullptr); - if (SfxItemState::SET == - rItemSet.GetItemState(RES_PARATR_DROP, true, &pItem)) + if (const SwFormatDrop* pItem = rItemSet.GetItemIfSet(RES_PARATR_DROP)) { - pDrop.reset(new SwFormatDrop(*static_cast<const SwFormatDrop*>(pItem))); + pDrop.reset(new SwFormatDrop(*pItem)); } if (!pDrop) { @@ -396,7 +406,7 @@ lcl_setDropcapCharStyle(SwPaM const & rPam, SfxItemSet & rItemSet, } const rtl::Reference<SwDocStyleSheet> xStyle(new SwDocStyleSheet(*pStyle)); pDrop->SetCharFormat(xStyle->GetCharFormat()); - rItemSet.Put(*pDrop); + rItemSet.Put(std::move(pDrop)); } static void @@ -409,11 +419,9 @@ lcl_setRubyCharstyle(SfxItemSet & rItemSet, uno::Any const& rValue) } std::unique_ptr<SwFormatRuby> pRuby; - const SfxPoolItem* pItem; - if (SfxItemState::SET == - rItemSet.GetItemState(RES_TXTATR_CJK_RUBY, true, &pItem)) + if (const SwFormatRuby* pItem = rItemSet.GetItemIfSet(RES_TXTATR_CJK_RUBY)) { - pRuby.reset(new SwFormatRuby(*static_cast<const SwFormatRuby*>(pItem))); + pRuby.reset(new SwFormatRuby(*pItem)); } if (!pRuby) { @@ -430,7 +438,7 @@ lcl_setRubyCharstyle(SfxItemSet & rItemSet, uno::Any const& rValue) sStyle, SwGetPoolIdFromName::ChrFmt); pRuby->SetCharFormatId(nId); } - rItemSet.Put(*pRuby); + rItemSet.Put(std::move(pRuby)); } bool @@ -476,7 +484,7 @@ SwUnoCursorHelper::SetCursorPropertyValue( case FN_UNO_PARA_NUM_AUTO_FORMAT: { // multi selection is not considered - SwTextNode *const pTextNd = rPam.GetNode().GetTextNode(); + SwTextNode *const pTextNd = rPam.GetPointNode().GetTextNode(); if (!pTextNd) { throw lang::IllegalArgumentException(); @@ -513,28 +521,24 @@ SwUnoCursorHelper::SetCursorPropertyValue( } else if (FN_UNO_PARA_NUM_AUTO_FORMAT == rEntry.nWID) { - uno::Sequence<beans::NamedValue> props; - if (rValue >>= props) + std::shared_ptr<SfxItemSet> pAutoStyle; + if (uno::Sequence<beans::NamedValue> props; rValue >>= props) { // TODO create own map for this, it contains UNO_NAME_DISPLAY_NAME? or make property readable so ODF export can map it to a automatic style? SfxItemPropertySet const& rPropSet(*aSwMapProvider.GetPropertySet(PROPERTY_MAP_CHAR_AUTO_STYLE)); SfxItemPropertyMap const& rMap(rPropSet.getPropertyMap()); - SfxItemSet items( rPam.GetDoc().GetAttrPool(), - svl::Items<RES_CHRATR_BEGIN, RES_CHRATR_END-1, + SfxItemSetFixed + <RES_CHRATR_BEGIN, RES_CHRATR_END-1, RES_TXTATR_CHARFMT, RES_TXTATR_CHARFMT, - RES_UNKNOWNATR_BEGIN, RES_UNKNOWNATR_END-1>{} ); + RES_UNKNOWNATR_BEGIN, RES_UNKNOWNATR_END-1> + items( rPam.GetDoc().GetAttrPool() ); - for (beans::NamedValue const & prop : std::as_const(props)) + for (beans::NamedValue const& prop : props) { SfxItemPropertyMapEntry const*const pEntry = rMap.getByName(prop.Name); if (!pEntry) { - if (prop.Name == "CharStyleName") - { - lcl_setCharStyle(rPam.GetDoc(), prop.Value, items); - continue; - } throw beans::UnknownPropertyException( "Unknown property: " + prop.Name); } @@ -543,13 +547,30 @@ SwUnoCursorHelper::SetCursorPropertyValue( throw beans::PropertyVetoException( "Property is read-only: " + prop.Name); } - rPropSet.setPropertyValue(*pEntry, prop.Value, items); + if (prop.Name == "CharStyleName") + { + lcl_setCharStyle(rPam.GetDoc(), prop.Value, items); + } + else + { + SfxItemPropertySet::setPropertyValue(*pEntry, prop.Value, items); + } } + IStyleAccess& rStyleAccess = rPam.GetDoc().GetIStyleAccess(); + // Add it to the autostyle pool, needed by the ODT export. + pAutoStyle = rStyleAccess.getAutomaticStyle(items, IStyleAccess::AUTO_STYLE_CHAR); + } + else if (OUString styleName; rValue >>= styleName) + { + IStyleAccess& rStyleAccess = rPam.GetDoc().GetIStyleAccess(); + pAutoStyle = rStyleAccess.getByName(styleName, IStyleAccess::AUTO_STYLE_CHAR); + } + if (pAutoStyle) + { SwFormatAutoFormat item(RES_PARATR_LIST_AUTOFMT); - // 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)); + item.SetStyleHandle(pAutoStyle); pTextNd->SetAttr(item); } } @@ -621,17 +642,17 @@ SwUnoCursorHelper::GetCurTextFormatColl(SwPaM & rPaM, const bool bConditional) SwPaM *pTmpCursor = &rPaM; do { - const sal_uLong nSttNd = pTmpCursor->Start()->nNode.GetIndex(); - const sal_uLong nEndNd = pTmpCursor->End()->nNode.GetIndex(); + const SwNodeOffset nSttNd = pTmpCursor->Start()->GetNodeIndex(); + const SwNodeOffset nEndNd = pTmpCursor->End()->GetNodeIndex(); - if( nEndNd - nSttNd >= nMaxLookup ) + if( nEndNd - nSttNd >= SwNodeOffset(nMaxLookup) ) { pFormat = nullptr; break; } const SwNodes& rNds = rPaM.GetDoc().GetNodes(); - for( sal_uLong n = nSttNd; n <= nEndNd; ++n ) + for( SwNodeOffset n = nSttNd; n <= nEndNd; ++n ) { SwTextNode const*const pNd = rNds[ n ]->GetTextNode(); if( pNd ) @@ -655,103 +676,95 @@ SwUnoCursorHelper::GetCurTextFormatColl(SwPaM & rPaM, const bool bConditional) 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; } + { return *m_pUnoCursor; } SwPaM const* SwXTextCursor::GetPaM() const - { return m_pImpl->m_pUnoCursor.get(); } + { return m_pUnoCursor.get(); } SwPaM* SwXTextCursor::GetPaM() - { return m_pImpl->m_pUnoCursor.get(); } + { return m_pUnoCursor.get(); } SwDoc const* SwXTextCursor::GetDoc() const - { return m_pImpl->m_pUnoCursor ? &m_pImpl->m_pUnoCursor->GetDoc() : nullptr; } + { return m_pUnoCursor ? &m_pUnoCursor->GetDoc() : nullptr; } SwDoc* SwXTextCursor::GetDoc() - { return m_pImpl->m_pUnoCursor ? &m_pImpl->m_pUnoCursor->GetDoc() : nullptr; } + { return m_pUnoCursor ? &m_pUnoCursor->GetDoc() : nullptr; } SwXTextCursor::SwXTextCursor( SwDoc & rDoc, - uno::Reference< text::XText > const& xParent, + uno::Reference< text::XText > xParent, const CursorType eType, const SwPosition& rPos, SwPosition const*const pMark) - : m_pImpl( new Impl(rDoc, eType, xParent, rPos, pMark) ) + : m_rPropSet(*aSwMapProvider.GetPropertySet(PROPERTY_MAP_TEXT_CURSOR)) + , m_eType(eType) + , m_xParentText(std::move(xParent)) + , m_pUnoCursor(rDoc.CreateUnoCursor(rPos)) { + if (pMark) + { + m_pUnoCursor->SetMark(); + *m_pUnoCursor->GetMark() = *pMark; + } } -SwXTextCursor::SwXTextCursor(uno::Reference< text::XText > const& xParent, +SwXTextCursor::SwXTextCursor(uno::Reference< text::XText > xParent, SwPaM const& rSourceCursor, const CursorType eType) - : m_pImpl( new Impl(rSourceCursor.GetDoc(), eType, - xParent, *rSourceCursor.GetPoint(), - rSourceCursor.HasMark() ? rSourceCursor.GetMark() : nullptr) ) + : m_rPropSet(*aSwMapProvider.GetPropertySet(PROPERTY_MAP_TEXT_CURSOR)) + , m_eType(eType) + , m_xParentText(std::move(xParent)) + , m_pUnoCursor(rSourceCursor.GetDoc().CreateUnoCursor(*rSourceCursor.GetPoint())) { + if (rSourceCursor.HasMark()) + { + m_pUnoCursor->SetMark(); + *m_pUnoCursor->GetMark() = *rSourceCursor.GetMark(); + } } SwXTextCursor::~SwXTextCursor() { + SolarMutexGuard g; // #i105557#: call dtor with locked solar mutex + m_pUnoCursor.reset(nullptr); // need to delete this with SolarMutex held } -void SwXTextCursor::DeleteAndInsert(const OUString& rText, - const bool bForceExpandHints) +void SwXTextCursor::DeleteAndInsert(std::u16string_view aText, + ::sw::DeleteAndInsertMode const eMode) { - auto pUnoCursor = static_cast<SwCursor*>(m_pImpl->m_pUnoCursor.get()); + auto pUnoCursor = static_cast<SwCursor*>(m_pUnoCursor.get()); if (!pUnoCursor) return; // Start/EndAction SwDoc& rDoc = pUnoCursor->GetDoc(); UnoActionContext aAction(&rDoc); - const sal_Int32 nTextLen = rText.getLength(); + const sal_Int32 nTextLen = aText.size(); rDoc.GetIDocumentUndoRedo().StartUndo(SwUndoId::INSERT, nullptr); auto pCurrent = pUnoCursor; do { if (pCurrent->HasMark()) { - rDoc.getIDocumentContentOperations().DeleteAndJoin(*pCurrent); + rDoc.getIDocumentContentOperations().DeleteAndJoin(*pCurrent, + // is it "delete" or "replace"? + (nTextLen != 0 || eMode & ::sw::DeleteAndInsertMode::ForceReplace) ? SwDeleteFlags::ArtificialSelection : SwDeleteFlags::Default); } if(nTextLen) { + // Store node and content indexes prior to insertion: to select the inserted text, + // we need to account for possible surrogate pairs, combining characters, etc.; it + // is easier to just restore the correct position from the indexes. + const auto start = pCurrent->Start(); + const auto nodeIndex = start->GetNodeIndex(); + const auto contentIndex = start->GetContentIndex(); const bool bSuccess( SwUnoCursorHelper::DocInsertStringSplitCR( - rDoc, *pCurrent, rText, bForceExpandHints ) ); + rDoc, SwPaM(*start, pCurrent), aText, bool(eMode & ::sw::DeleteAndInsertMode::ForceExpandHints))); OSL_ENSURE( bSuccess, "Doc->Insert(Str) failed." ); - SwUnoCursorHelper::SelectPam(*pUnoCursor, true); - pCurrent->Left(rText.getLength()); + pCurrent->SetMark(); + pCurrent->GetPoint()->Assign(nodeIndex, contentIndex); } pCurrent = pCurrent->GetNext(); } while (pCurrent != pUnoCursor); @@ -762,6 +775,12 @@ namespace { enum ForceIntoMetaMode { META_CHECK_BOTH, META_INIT_START, META_INIT_END }; +enum ForceIntoContentControlMode +{ + CONTENT_CONTROL_CHECK_BOTH, + CONTENT_CONTROL_INIT_START, + CONTENT_CONTROL_INIT_END +}; } static bool @@ -808,13 +827,68 @@ lcl_ForceIntoMeta(SwPaM & rCursor, return bRet; } +namespace +{ +bool lcl_ForceIntoContentControl(SwPaM& rCursor, const uno::Reference<text::XText>& xParentText, + ForceIntoContentControlMode eMode) +{ + bool bRet = true; // means not forced in CONTENT_CONTROL_CHECK_BOTH + auto pXContentControl = dynamic_cast<SwXContentControl*>(xParentText.get()); + if (!pXContentControl) + { + SAL_WARN("sw.core", "lcl_ForceIntoContentControl: no parent text"); + throw uno::RuntimeException(); + } + + SwTextNode* pTextNode; + sal_Int32 nStart; + sal_Int32 nEnd; + bool bSuccess = pXContentControl->SetContentRange(pTextNode, nStart, nEnd); + if (!bSuccess) + { + SAL_WARN("sw.core", "lcl_ForceIntoContentControl: SetContentRange() failed"); + throw uno::RuntimeException(); + } + + // Force the cursor back into the content control if it has moved outside. + SwPosition aStart(*pTextNode, nStart); + SwPosition aEnd(*pTextNode, nEnd); + switch (eMode) + { + case CONTENT_CONTROL_INIT_START: + *rCursor.GetPoint() = aStart; + break; + + case CONTENT_CONTROL_INIT_END: + *rCursor.GetPoint() = aEnd; + break; + + case CONTENT_CONTROL_CHECK_BOTH: + if (*rCursor.Start() < aStart) + { + *rCursor.Start() = aStart; + bRet = false; + } + + if (*rCursor.End() > aEnd) + { + *rCursor.End() = aEnd; + bRet = false; + } + break; + } + + return bRet; +} +} + bool SwXTextCursor::IsAtEndOfMeta() const { - if (CursorType::Meta == m_pImpl->m_eType) + if (CursorType::Meta == m_eType) { - auto pCursor( m_pImpl->m_pUnoCursor ); + auto pCursor( m_pUnoCursor ); SwXMeta const*const pXMeta( - dynamic_cast<SwXMeta*>(m_pImpl->m_xParentText.get()) ); + dynamic_cast<SwXMeta*>(m_xParentText.get()) ); OSL_ENSURE(pXMeta, "no meta?"); if (pCursor && pXMeta) { @@ -838,6 +912,42 @@ bool SwXTextCursor::IsAtEndOfMeta() const return false; } +bool SwXTextCursor::IsAtEndOfContentControl() const +{ + if (CursorType::ContentControl == m_eType) + { + auto pCursor( m_pUnoCursor ); + auto pXContentControl( + dynamic_cast<SwXContentControl*>(m_xParentText.get()) ); + if (!pXContentControl) + { + SAL_WARN("sw.core", "SwXTextCursor::IsAtEndOfContentControl: no content control"); + } + if (pCursor && pXContentControl) + { + SwTextNode * pTextNode; + sal_Int32 nStart; + sal_Int32 nEnd; + const bool bSuccess( + pXContentControl->SetContentRange(pTextNode, nStart, nEnd) ); + if (!bSuccess) + { + SAL_WARN("sw.core", "SwXTextCursor::IsAtEndOfContentControl: no pam"); + } + else + { + const SwPosition end(*pTextNode, nEnd); + if ( (*pCursor->GetPoint() == end) + || (*pCursor->GetMark() == end)) + { + return true; + } + } + } + } + return false; +} + OUString SwXTextCursor::getImplementationName() { return "SwXTextCursor"; @@ -863,24 +973,11 @@ SwXTextCursor::getSupportedServiceNames() }; } -const uno::Sequence< sal_Int8 > & SwXTextCursor::getUnoTunnelId() -{ - static const UnoTunnelIdInit theSwXTextCursorUnoTunnelId; - return theSwXTextCursorUnoTunnelId.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() ); + SwUnoCursor & rUnoCursor( GetCursorOrThrow() ); if (rUnoCursor.HasMark()) { @@ -896,7 +993,7 @@ void SAL_CALL SwXTextCursor::collapseToEnd() { SolarMutexGuard aGuard; - SwUnoCursor & rUnoCursor( m_pImpl->GetCursorOrThrow() ); + SwUnoCursor & rUnoCursor( GetCursorOrThrow() ); if (rUnoCursor.HasMark()) { @@ -913,7 +1010,7 @@ sal_Bool SAL_CALL SwXTextCursor::isCollapsed() SolarMutexGuard aGuard; bool bRet = true; - auto pUnoCursor(m_pImpl->m_pUnoCursor); + auto pUnoCursor(m_pUnoCursor); if(pUnoCursor && pUnoCursor->GetMark()) { bRet = (*pUnoCursor->GetPoint() == *pUnoCursor->GetMark()); @@ -926,16 +1023,21 @@ SwXTextCursor::goLeft(sal_Int16 nCount, sal_Bool Expand) { SolarMutexGuard aGuard; - SwUnoCursor & rUnoCursor( m_pImpl->GetCursorOrThrow() ); + SwUnoCursor & rUnoCursor( GetCursorOrThrow() ); SwUnoCursorHelper::SelectPam(rUnoCursor, Expand); bool bRet = rUnoCursor.Left( nCount); - if (CursorType::Meta == m_pImpl->m_eType) + if (CursorType::Meta == m_eType) { - bRet = lcl_ForceIntoMeta(rUnoCursor, m_pImpl->m_xParentText, + bRet = lcl_ForceIntoMeta(rUnoCursor, m_xParentText, META_CHECK_BOTH) && bRet; } + else if (m_eType == CursorType::ContentControl) + { + bRet = lcl_ForceIntoContentControl(rUnoCursor, m_xParentText, CONTENT_CONTROL_CHECK_BOTH) + && bRet; + } return bRet; } @@ -944,16 +1046,21 @@ SwXTextCursor::goRight(sal_Int16 nCount, sal_Bool Expand) { SolarMutexGuard aGuard; - SwUnoCursor & rUnoCursor( m_pImpl->GetCursorOrThrow() ); + SwUnoCursor & rUnoCursor( GetCursorOrThrow() ); SwUnoCursorHelper::SelectPam(rUnoCursor, Expand); bool bRet = rUnoCursor.Right(nCount); - if (CursorType::Meta == m_pImpl->m_eType) + if (CursorType::Meta == m_eType) { - bRet = lcl_ForceIntoMeta(rUnoCursor, m_pImpl->m_xParentText, + bRet = lcl_ForceIntoMeta(rUnoCursor, m_xParentText, META_CHECK_BOTH) && bRet; } + else if (m_eType == CursorType::ContentControl) + { + bRet = lcl_ForceIntoContentControl(rUnoCursor, m_xParentText, CONTENT_CONTROL_CHECK_BOTH) + && bRet; + } return bRet; } @@ -963,54 +1070,49 @@ SwXTextCursor::gotoStart(sal_Bool Expand) SolarMutexGuard aGuard; comphelper::ProfileZone aZone("gotoStart"); - SwUnoCursor & rUnoCursor( m_pImpl->GetCursorOrThrow() ); + SwUnoCursor & rUnoCursor( GetCursorOrThrow() ); SwUnoCursorHelper::SelectPam(rUnoCursor, Expand); - if (CursorType::Body == m_pImpl->m_eType) + if (CursorType::Body == m_eType) { rUnoCursor.Move( fnMoveBackward, GoInDoc ); //check, that the cursor is not in a table - SwTableNode * pTableNode = rUnoCursor.GetNode().FindTableNode(); - SwContentNode * pCNode = nullptr; + SwTableNode * pTableNode = rUnoCursor.GetPointNode().FindTableNode(); while (pTableNode) { - rUnoCursor.GetPoint()->nNode = *pTableNode->EndOfSectionNode(); - pCNode = GetDoc()->GetNodes().GoNext(&rUnoCursor.GetPoint()->nNode); + rUnoCursor.GetPoint()->Assign( *pTableNode->EndOfSectionNode() ); + SwContentNode* pCNode = SwNodes::GoNext(rUnoCursor.GetPoint()); pTableNode = pCNode ? pCNode->FindTableNode() : nullptr; } - if (pCNode) - { - rUnoCursor.GetPoint()->nContent.Assign(pCNode, 0); - } SwStartNode const*const pTmp = - rUnoCursor.GetNode().StartOfSectionNode(); + rUnoCursor.GetPointNode().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); - } + SwNodes::GoNextSection( + rUnoCursor.GetPoint(), true, false); } } } - 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)) + else if ( (CursorType::Frame == m_eType) + || (CursorType::TableText == m_eType) + || (CursorType::Header == m_eType) + || (CursorType::Footer == m_eType) + || (CursorType::Footnote== m_eType) + || (CursorType::Redline == m_eType)) { rUnoCursor.MoveSection(GoCurrSection, fnSectionStart); } - else if (CursorType::Meta == m_pImpl->m_eType) + else if (CursorType::Meta == m_eType) + { + lcl_ForceIntoMeta(rUnoCursor, m_xParentText, META_INIT_START); + } + else if (m_eType == CursorType::ContentControl) { - lcl_ForceIntoMeta(rUnoCursor, m_pImpl->m_xParentText, META_INIT_START); + lcl_ForceIntoContentControl(rUnoCursor, m_xParentText, CONTENT_CONTROL_INIT_START); } } @@ -1020,25 +1122,29 @@ SwXTextCursor::gotoEnd(sal_Bool Expand) SolarMutexGuard aGuard; comphelper::ProfileZone aZone("gotoEnd"); - SwUnoCursor & rUnoCursor( m_pImpl->GetCursorOrThrow() ); + SwUnoCursor & rUnoCursor( GetCursorOrThrow() ); SwUnoCursorHelper::SelectPam(rUnoCursor, Expand); - if (CursorType::Body == m_pImpl->m_eType) + if (CursorType::Body == 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)) + else if ( (CursorType::Frame == m_eType) + || (CursorType::TableText == m_eType) + || (CursorType::Header == m_eType) + || (CursorType::Footer == m_eType) + || (CursorType::Footnote== m_eType) + || (CursorType::Redline == m_eType)) { rUnoCursor.MoveSection( GoCurrSection, fnSectionEnd); } - else if (CursorType::Meta == m_pImpl->m_eType) + else if (CursorType::Meta == m_eType) + { + lcl_ForceIntoMeta(rUnoCursor, m_xParentText, META_INIT_END); + } + else if (m_eType == CursorType::ContentControl) { - lcl_ForceIntoMeta(rUnoCursor, m_pImpl->m_xParentText, META_INIT_END); + lcl_ForceIntoContentControl(rUnoCursor, m_xParentText, CONTENT_CONTROL_INIT_END); } } @@ -1053,17 +1159,10 @@ SwXTextCursor::gotoRange( throw uno::RuntimeException(); } - SwUnoCursor & rOwnCursor( m_pImpl->GetCursorOrThrow() ); + SwUnoCursor & rOwnCursor( 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); - } + SwXTextRange* pRange = dynamic_cast<SwXTextRange*>(xRange.get()); + OTextCursorHelper* pCursor = dynamic_cast<OTextCursorHelper*>(xRange.get()); if (!pRange && !pCursor) { @@ -1091,7 +1190,7 @@ SwXTextCursor::gotoRange( { SwStartNodeType eSearchNodeType = SwNormalStartNode; - switch (m_pImpl->m_eType) + switch (m_eType) { case CursorType::Frame: eSearchNodeType = SwFlyStartNode; break; case CursorType::TableText: eSearchNodeType = SwTableBoxStartNode; break; @@ -1104,7 +1203,7 @@ SwXTextCursor::gotoRange( ; } - const SwStartNode* pOwnStartNode = rOwnCursor.GetNode().FindSttNodeByType(eSearchNodeType); + const SwStartNode* pOwnStartNode = rOwnCursor.GetPointNode().FindSttNodeByType(eSearchNodeType); while ( pOwnStartNode != nullptr && pOwnStartNode->IsSectionNode()) { @@ -1112,7 +1211,7 @@ SwXTextCursor::gotoRange( } const SwStartNode* pTmp = - pPam->GetNode().FindSttNodeByType(eSearchNodeType); + pPam->GetPointNode().FindSttNodeByType(eSearchNodeType); while ( pTmp != nullptr && pTmp->IsSectionNode() ) { @@ -1140,11 +1239,11 @@ SwXTextCursor::gotoRange( } } - if (CursorType::Meta == m_pImpl->m_eType) + if (CursorType::Meta == m_eType) { SwPaM CopyPam(*pPam->GetMark(), *pPam->GetPoint()); const bool bNotForced( lcl_ForceIntoMeta( - CopyPam, m_pImpl->m_xParentText, META_CHECK_BOTH) ); + CopyPam, m_xParentText, META_CHECK_BOTH) ); if (!bNotForced) { throw uno::RuntimeException( @@ -1153,6 +1252,15 @@ SwXTextCursor::gotoRange( static_cast<text::XWordCursor*>(this)); } } + else if (m_eType == CursorType::ContentControl) + { + SwPaM aPaM(*pPam->GetMark(), *pPam->GetPoint()); + if (!lcl_ForceIntoContentControl(aPaM, m_xParentText, CONTENT_CONTROL_CHECK_BOTH)) + { + throw uno::RuntimeException("gotoRange: xRange is out of bounds of the content control", + static_cast<text::XWordCursor*>(this)); + } + } // selection has to be expanded here if(bExpand) @@ -1195,7 +1303,7 @@ sal_Bool SAL_CALL SwXTextCursor::isStartOfWord() { SolarMutexGuard aGuard; - SwUnoCursor & rUnoCursor( m_pImpl->GetCursorOrThrow() ); + SwUnoCursor & rUnoCursor( GetCursorOrThrow() ); const bool bRet = rUnoCursor.IsStartWordWT( i18n::WordType::DICTIONARY_WORD ); @@ -1206,7 +1314,7 @@ sal_Bool SAL_CALL SwXTextCursor::isEndOfWord() { SolarMutexGuard aGuard; - SwUnoCursor & rUnoCursor( m_pImpl->GetCursorOrThrow() ); + SwUnoCursor & rUnoCursor( GetCursorOrThrow() ); const bool bRet = rUnoCursor.IsEndWordWT( i18n::WordType::DICTIONARY_WORD ); @@ -1218,7 +1326,7 @@ SwXTextCursor::gotoNextWord(sal_Bool Expand) { SolarMutexGuard aGuard; - SwUnoCursor & rUnoCursor( m_pImpl->GetCursorOrThrow() ); + SwUnoCursor & rUnoCursor( GetCursorOrThrow() ); // problems arise when a paragraph starts with something other than a word bool bRet = false; @@ -1226,13 +1334,13 @@ SwXTextCursor::gotoNextWord(sal_Bool Expand) // 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(); + SwNode *const pOldNode = &pPoint->GetNode(); + sal_Int32 const nOldIndex = pPoint->GetContentIndex(); SwUnoCursorHelper::SelectPam(rUnoCursor, Expand); // end of paragraph - if (rUnoCursor.GetContentNode() && - (pPoint->nContent == rUnoCursor.GetContentNode()->Len())) + if (rUnoCursor.GetPointContentNode() && + (pPoint->GetContentIndex() == rUnoCursor.GetPointContentNode()->Len())) { rUnoCursor.Right(1); } @@ -1249,13 +1357,17 @@ SwXTextCursor::gotoNextWord(sal_Bool Expand) } // return true if cursor has moved - bRet = (&pPoint->nNode.GetNode() != pOldNode) || - (pPoint->nContent.GetIndex() != nOldIndex); - if (bRet && (CursorType::Meta == m_pImpl->m_eType)) + bRet = (&pPoint->GetNode() != pOldNode) || + (pPoint->GetContentIndex() != nOldIndex); + if (bRet && (CursorType::Meta == m_eType)) { - bRet = lcl_ForceIntoMeta(rUnoCursor, m_pImpl->m_xParentText, + bRet = lcl_ForceIntoMeta(rUnoCursor, m_xParentText, META_CHECK_BOTH); } + else if (bRet && m_eType == CursorType::ContentControl) + { + bRet = lcl_ForceIntoContentControl(rUnoCursor, m_xParentText, CONTENT_CONTROL_CHECK_BOTH); + } return bRet; } @@ -1265,37 +1377,41 @@ SwXTextCursor::gotoPreviousWord(sal_Bool Expand) { SolarMutexGuard aGuard; - SwUnoCursor & rUnoCursor( m_pImpl->GetCursorOrThrow() ); + SwUnoCursor & rUnoCursor( 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(); + SwNode *const pOldNode = &pPoint->GetNode(); + sal_Int32 const nOldIndex = pPoint->GetContentIndex(); SwUnoCursorHelper::SelectPam(rUnoCursor, Expand); // start of paragraph? - if (pPoint->nContent == 0) + if (pPoint->GetContentIndex() == 0) { rUnoCursor.Left(1); } else { rUnoCursor.GoPrevWordWT( i18n::WordType::DICTIONARY_WORD ); - if (pPoint->nContent == 0) + if (pPoint->GetContentIndex() == 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 = (&pPoint->GetNode() != pOldNode) || + (pPoint->GetContentIndex() != nOldIndex); + if (bRet && (CursorType::Meta == m_eType)) { - bRet = lcl_ForceIntoMeta(rUnoCursor, m_pImpl->m_xParentText, + bRet = lcl_ForceIntoMeta(rUnoCursor, m_xParentText, META_CHECK_BOTH); } + else if (bRet && m_eType == CursorType::ContentControl) + { + bRet = lcl_ForceIntoContentControl(rUnoCursor, m_xParentText, CONTENT_CONTROL_CHECK_BOTH); + } return bRet; } @@ -1305,12 +1421,12 @@ SwXTextCursor::gotoEndOfWord(sal_Bool Expand) { SolarMutexGuard aGuard; - SwUnoCursor & rUnoCursor( m_pImpl->GetCursorOrThrow() ); + SwUnoCursor & rUnoCursor( GetCursorOrThrow() ); bool bRet = false; SwPosition *const pPoint = rUnoCursor.GetPoint(); - SwNode & rOldNode = pPoint->nNode.GetNode(); - sal_Int32 const nOldIndex = pPoint->nContent.GetIndex(); + SwNode & rOldNode = pPoint->GetNode(); + sal_Int32 const nOldIndex = pPoint->GetContentIndex(); const sal_Int16 nWordType = i18n::WordType::DICTIONARY_WORD; SwUnoCursorHelper::SelectPam(rUnoCursor, Expand); @@ -1324,14 +1440,17 @@ SwXTextCursor::gotoEndOfWord(sal_Bool Expand) bRet = rUnoCursor.IsEndWordWT( nWordType ); if (!bRet) { - pPoint->nNode = rOldNode; - pPoint->nContent = nOldIndex; + pPoint->Assign(rOldNode, nOldIndex); } - else if (CursorType::Meta == m_pImpl->m_eType) + else if (CursorType::Meta == m_eType) { - bRet = lcl_ForceIntoMeta(rUnoCursor, m_pImpl->m_xParentText, + bRet = lcl_ForceIntoMeta(rUnoCursor, m_xParentText, META_CHECK_BOTH); } + else if (m_eType == CursorType::ContentControl) + { + bRet = lcl_ForceIntoContentControl(rUnoCursor, m_xParentText, CONTENT_CONTROL_CHECK_BOTH); + } return bRet; } @@ -1341,12 +1460,12 @@ SwXTextCursor::gotoStartOfWord(sal_Bool Expand) { SolarMutexGuard aGuard; - SwUnoCursor & rUnoCursor( m_pImpl->GetCursorOrThrow() ); + SwUnoCursor & rUnoCursor( GetCursorOrThrow() ); bool bRet = false; SwPosition *const pPoint = rUnoCursor.GetPoint(); - SwNode & rOldNode = pPoint->nNode.GetNode(); - sal_Int32 const nOldIndex = pPoint->nContent.GetIndex(); + SwNode & rOldNode = pPoint->GetNode(); + sal_Int32 const nOldIndex = pPoint->GetContentIndex(); const sal_Int16 nWordType = i18n::WordType::DICTIONARY_WORD; SwUnoCursorHelper::SelectPam(rUnoCursor, Expand); @@ -1360,14 +1479,17 @@ SwXTextCursor::gotoStartOfWord(sal_Bool Expand) bRet = rUnoCursor.IsStartWordWT( nWordType ); if (!bRet) { - pPoint->nNode = rOldNode; - pPoint->nContent = nOldIndex; + pPoint->Assign(rOldNode, nOldIndex); } - else if (CursorType::Meta == m_pImpl->m_eType) + else if (CursorType::Meta == m_eType) { - bRet = lcl_ForceIntoMeta(rUnoCursor, m_pImpl->m_xParentText, + bRet = lcl_ForceIntoMeta(rUnoCursor, m_xParentText, META_CHECK_BOTH); } + else if (m_eType == CursorType::ContentControl) + { + bRet = lcl_ForceIntoContentControl(rUnoCursor, m_xParentText, CONTENT_CONTROL_CHECK_BOTH); + } return bRet; } @@ -1377,10 +1499,10 @@ SwXTextCursor::isStartOfSentence() { SolarMutexGuard aGuard; - SwUnoCursor & rUnoCursor( m_pImpl->GetCursorOrThrow() ); + SwUnoCursor & rUnoCursor( GetCursorOrThrow() ); // start of paragraph? - bool bRet = rUnoCursor.GetPoint()->nContent == 0; + bool bRet = rUnoCursor.GetPoint()->GetContentIndex() == 0; // with mark ->no sentence start // (check if cursor is no selection, i.e. it does not have // a mark or else point and mark are identical) @@ -1400,11 +1522,11 @@ SwXTextCursor::isEndOfSentence() { SolarMutexGuard aGuard; - SwUnoCursor & rUnoCursor( m_pImpl->GetCursorOrThrow() ); + SwUnoCursor & rUnoCursor( GetCursorOrThrow() ); // end of paragraph? - bool bRet = rUnoCursor.GetContentNode() && - (rUnoCursor.GetPoint()->nContent == rUnoCursor.GetContentNode()->Len()); + bool bRet = rUnoCursor.GetPointContentNode() && + (rUnoCursor.GetPoint()->GetContentIndex() == rUnoCursor.GetPointContentNode()->Len()); // with mark->no sentence end // (check if cursor is no selection, i.e. it does not have // a mark or else point and mark are identical) @@ -1424,7 +1546,7 @@ SwXTextCursor::gotoNextSentence(sal_Bool Expand) { SolarMutexGuard aGuard; - SwUnoCursor & rUnoCursor( m_pImpl->GetCursorOrThrow() ); + SwUnoCursor & rUnoCursor( GetCursorOrThrow() ); const bool bWasEOS = isEndOfSentence(); SwUnoCursorHelper::SelectPam(rUnoCursor, Expand); @@ -1445,12 +1567,17 @@ SwXTextCursor::gotoNextSentence(sal_Bool Expand) bRet = false; } } - if (CursorType::Meta == m_pImpl->m_eType) + if (CursorType::Meta == m_eType) { - bRet = lcl_ForceIntoMeta(rUnoCursor, m_pImpl->m_xParentText, + bRet = lcl_ForceIntoMeta(rUnoCursor, m_xParentText, META_CHECK_BOTH) && bRet; } + else if (m_eType == CursorType::ContentControl) + { + bRet = lcl_ForceIntoContentControl(rUnoCursor, m_xParentText, CONTENT_CONTROL_CHECK_BOTH) + && bRet; + } return bRet; } @@ -1459,7 +1586,7 @@ SwXTextCursor::gotoPreviousSentence(sal_Bool Expand) { SolarMutexGuard aGuard; - SwUnoCursor & rUnoCursor( m_pImpl->GetCursorOrThrow() ); + SwUnoCursor & rUnoCursor( GetCursorOrThrow() ); SwUnoCursorHelper::SelectPam(rUnoCursor, Expand); bool bRet = rUnoCursor.GoSentence(SwCursor::PREV_SENT); @@ -1473,12 +1600,17 @@ SwXTextCursor::gotoPreviousSentence(sal_Bool Expand) rUnoCursor.GoSentence(SwCursor::PREV_SENT); } } - if (CursorType::Meta == m_pImpl->m_eType) + if (CursorType::Meta == m_eType) { - bRet = lcl_ForceIntoMeta(rUnoCursor, m_pImpl->m_xParentText, + bRet = lcl_ForceIntoMeta(rUnoCursor, m_xParentText, META_CHECK_BOTH) && bRet; } + else if (m_eType == CursorType::ContentControl) + { + bRet = lcl_ForceIntoContentControl(rUnoCursor, m_xParentText, CONTENT_CONTROL_CHECK_BOTH) + && bRet; + } return bRet; } @@ -1487,7 +1619,7 @@ SwXTextCursor::gotoStartOfSentence(sal_Bool Expand) { SolarMutexGuard aGuard; - SwUnoCursor & rUnoCursor( m_pImpl->GetCursorOrThrow() ); + SwUnoCursor & rUnoCursor( GetCursorOrThrow() ); SwUnoCursorHelper::SelectPam(rUnoCursor, Expand); // if we're at the para start then we won't move @@ -1496,12 +1628,17 @@ SwXTextCursor::gotoStartOfSentence(sal_Bool Expand) bool bRet = SwUnoCursorHelper::IsStartOfPara(rUnoCursor) || rUnoCursor.GoSentence(SwCursor::START_SENT) || SwUnoCursorHelper::IsStartOfPara(rUnoCursor); - if (CursorType::Meta == m_pImpl->m_eType) + if (CursorType::Meta == m_eType) { - bRet = lcl_ForceIntoMeta(rUnoCursor, m_pImpl->m_xParentText, + bRet = lcl_ForceIntoMeta(rUnoCursor, m_xParentText, META_CHECK_BOTH) && bRet; } + else if (m_eType == CursorType::ContentControl) + { + bRet = lcl_ForceIntoContentControl(rUnoCursor, m_xParentText, CONTENT_CONTROL_CHECK_BOTH) + && bRet; + } return bRet; } @@ -1510,7 +1647,7 @@ SwXTextCursor::gotoEndOfSentence(sal_Bool Expand) { SolarMutexGuard aGuard; - SwUnoCursor & rUnoCursor( m_pImpl->GetCursorOrThrow() ); + SwUnoCursor & rUnoCursor( GetCursorOrThrow() ); SwUnoCursorHelper::SelectPam(rUnoCursor, Expand); // bRet is true if GoSentence() succeeded or if the @@ -1520,12 +1657,17 @@ SwXTextCursor::gotoEndOfSentence(sal_Bool Expand) bool bRet = !bAlreadyParaEnd && (rUnoCursor.GoSentence(SwCursor::END_SENT) || rUnoCursor.MovePara(GoCurrPara, fnParaEnd)); - if (CursorType::Meta == m_pImpl->m_eType) + if (CursorType::Meta == m_eType) { - bRet = lcl_ForceIntoMeta(rUnoCursor, m_pImpl->m_xParentText, + bRet = lcl_ForceIntoMeta(rUnoCursor, m_xParentText, META_CHECK_BOTH) && bRet; } + else if (m_eType == CursorType::ContentControl) + { + bRet = lcl_ForceIntoContentControl(rUnoCursor, m_xParentText, CONTENT_CONTROL_CHECK_BOTH) + && bRet; + } return bRet; } @@ -1534,7 +1676,7 @@ SwXTextCursor::isStartOfParagraph() { SolarMutexGuard aGuard; - SwUnoCursor & rUnoCursor( m_pImpl->GetCursorOrThrow() ); + SwUnoCursor & rUnoCursor( GetCursorOrThrow() ); const bool bRet = SwUnoCursorHelper::IsStartOfPara(rUnoCursor); return bRet; @@ -1545,7 +1687,7 @@ SwXTextCursor::isEndOfParagraph() { SolarMutexGuard aGuard; - SwUnoCursor & rUnoCursor( m_pImpl->GetCursorOrThrow() ); + SwUnoCursor & rUnoCursor( GetCursorOrThrow() ); const bool bRet = SwUnoCursorHelper::IsEndOfPara(rUnoCursor); return bRet; @@ -1556,9 +1698,9 @@ SwXTextCursor::gotoStartOfParagraph(sal_Bool Expand) { SolarMutexGuard aGuard; - SwUnoCursor & rUnoCursor( m_pImpl->GetCursorOrThrow() ); + SwUnoCursor & rUnoCursor( GetCursorOrThrow() ); - if (CursorType::Meta == m_pImpl->m_eType) + if (CursorType::Meta == m_eType) { return false; } @@ -1581,9 +1723,9 @@ SwXTextCursor::gotoEndOfParagraph(sal_Bool Expand) { SolarMutexGuard aGuard; - SwUnoCursor & rUnoCursor( m_pImpl->GetCursorOrThrow() ); + SwUnoCursor & rUnoCursor( GetCursorOrThrow() ); - if (CursorType::Meta == m_pImpl->m_eType) + if (CursorType::Meta == m_eType) { return false; } @@ -1606,9 +1748,9 @@ SwXTextCursor::gotoNextParagraph(sal_Bool Expand) { SolarMutexGuard aGuard; - SwUnoCursor & rUnoCursor( m_pImpl->GetCursorOrThrow() ); + SwUnoCursor & rUnoCursor( GetCursorOrThrow() ); - if (CursorType::Meta == m_pImpl->m_eType) + if (CursorType::Meta == m_eType) { return false; } @@ -1622,9 +1764,9 @@ SwXTextCursor::gotoPreviousParagraph(sal_Bool Expand) { SolarMutexGuard aGuard; - SwUnoCursor & rUnoCursor( m_pImpl->GetCursorOrThrow() ); + SwUnoCursor & rUnoCursor( GetCursorOrThrow() ); - if (CursorType::Meta == m_pImpl->m_eType) + if (CursorType::Meta == m_eType) { return false; } @@ -1638,7 +1780,7 @@ SwXTextCursor::getText() { SolarMutexGuard g; - return m_pImpl->m_xParentText; + return m_xParentText; } uno::Reference< text::XTextRange > SAL_CALL @@ -1646,12 +1788,12 @@ SwXTextCursor::getStart() { SolarMutexGuard aGuard; - SwUnoCursor & rUnoCursor( m_pImpl->GetCursorOrThrow() ); + SwUnoCursor & rUnoCursor( GetCursorOrThrow() ); uno::Reference< text::XTextRange > xRet; SwPaM aPam(*rUnoCursor.Start()); const uno::Reference< text::XText > xParent = getText(); - if (CursorType::Meta == m_pImpl->m_eType) + if (CursorType::Meta == m_eType) { // return cursor to prevent modifying SwXTextRange for META rtl::Reference<SwXTextCursor> pXCursor( @@ -1672,12 +1814,12 @@ SwXTextCursor::getEnd() { SolarMutexGuard aGuard; - SwUnoCursor & rUnoCursor( m_pImpl->GetCursorOrThrow() ); + SwUnoCursor & rUnoCursor( GetCursorOrThrow() ); uno::Reference< text::XTextRange > xRet; SwPaM aPam(*rUnoCursor.End()); const uno::Reference< text::XText > xParent = getText(); - if (CursorType::Meta == m_pImpl->m_eType) + if (CursorType::Meta == m_eType) { // return cursor to prevent modifying SwXTextRange for META rtl::Reference<SwXTextCursor> pXCursor( @@ -1697,7 +1839,7 @@ OUString SAL_CALL SwXTextCursor::getString() { SolarMutexGuard aGuard; - SwUnoCursor & rUnoCursor( m_pImpl->GetCursorOrThrow() ); + SwUnoCursor & rUnoCursor( GetCursorOrThrow() ); OUString aText; SwUnoCursorHelper::GetTextFromPam(rUnoCursor, aText); @@ -1709,12 +1851,12 @@ SwXTextCursor::setString(const OUString& aString) { SolarMutexGuard aGuard; - m_pImpl->GetCursorOrThrow(); // just to check if valid + GetCursorOrThrow(); // just to check if valid - const bool bForceExpandHints( (CursorType::Meta == m_pImpl->m_eType) - && dynamic_cast<SwXMeta&>(*m_pImpl->m_xParentText) + const bool bForceExpandHints( (CursorType::Meta == m_eType) + && dynamic_cast<SwXMeta&>(*m_xParentText) .CheckForOwnMemberMeta(*GetPaM(), true) ); - DeleteAndInsert(aString, bForceExpandHints); + DeleteAndInsert(aString, bForceExpandHints ? ::sw::DeleteAndInsertMode::ForceExpandHints : ::sw::DeleteAndInsertMode::Default); } uno::Any SwUnoCursorHelper::GetPropertyValue( @@ -1728,8 +1870,7 @@ uno::Any SwUnoCursorHelper::GetPropertyValue( if (!pEntry) { throw beans::UnknownPropertyException( - OUString::Concat("Unknown property: ") + rPropertyName, - static_cast<cppu::OWeakObject *>(nullptr)); + OUString::Concat("Unknown property: ") + rPropertyName); } beans::PropertyState eTemp; @@ -1738,14 +1879,14 @@ uno::Any SwUnoCursorHelper::GetPropertyValue( if (!bDone) { - SfxItemSet aSet( - rPaM.GetDoc().GetAttrPool(), - svl::Items< + SfxItemSetFixed< RES_CHRATR_BEGIN, RES_FRMATR_END - 1, - RES_UNKNOWNATR_CONTAINER, RES_UNKNOWNATR_CONTAINER>{}); + RES_UNKNOWNATR_CONTAINER, RES_UNKNOWNATR_CONTAINER> + aSet(rPaM.GetDoc().GetAttrPool()); + SwUnoCursorHelper::GetCursorAttr(rPaM, aSet); - rPropSet.getPropertyValue(*pEntry, aSet, aAny); + SfxItemPropertySet::getPropertyValue(*pEntry, aSet, aAny); } return aAny; @@ -1757,10 +1898,8 @@ void SwUnoCursorHelper::SetPropertyValue( 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); + beans::PropertyValue aVal { comphelper::makePropertyValue(rPropertyName, rValue) }; + SetPropertyValues(rPaM, rPropSet, std::span<beans::PropertyValue>(&aVal, 1), nAttrMode); } // FN_UNO_PARA_STYLE is known to set attributes for nodes, inside @@ -1780,18 +1919,28 @@ void SwUnoCursorHelper::SetPropertyValues( const uno::Sequence< beans::PropertyValue > &rPropertyValues, const SetAttrMode nAttrMode) { - if (!rPropertyValues.hasElements()) + SetPropertyValues(rPaM, rPropSet, + std::span<const beans::PropertyValue>(rPropertyValues.getConstArray(), rPropertyValues.getLength()), + nAttrMode); +} + +void SwUnoCursorHelper::SetPropertyValues( + SwPaM& rPaM, const SfxItemPropertySet& rPropSet, + std::span< const beans::PropertyValue > aPropertyValues, + const SetAttrMode nAttrMode) +{ + if (aPropertyValues.empty()) return; SwDoc& rDoc = rPaM.GetDoc(); OUString aUnknownExMsg, aPropertyVetoExMsg; // Build set of attributes we want to fetch - const sal_uInt16 zero = 0; - SfxItemSet aItemSet(rDoc.GetAttrPool(), &zero); + WhichRangesContainer aRanges; + std::vector<std::pair<const SfxItemPropertyMapEntry*, const uno::Any&>> aSideEffectsEntries; std::vector<std::pair<const SfxItemPropertyMapEntry*, const uno::Any&>> aEntries; - aEntries.reserve(rPropertyValues.getLength()); - for (const auto& rPropVal : rPropertyValues) + aEntries.reserve(aPropertyValues.size()); + for (const auto& rPropVal : aPropertyValues) { const OUString &rPropertyName = rPropVal.Name; @@ -1809,44 +1958,50 @@ void SwUnoCursorHelper::SetPropertyValues( aPropertyVetoExMsg += "Property is read-only: '" + rPropertyName + "' "; continue; } - aItemSet.MergeRange(pEntry->nWID, pEntry->nWID); - aEntries.emplace_back(pEntry, rPropVal.Value); + if (propertyCausesSideEffectsInNodes(pEntry->nWID)) + { + aSideEffectsEntries.emplace_back(pEntry, rPropVal.Value); + } + else + { + aRanges = aRanges.MergeRange(pEntry->nWID, pEntry->nWID); + aEntries.emplace_back(pEntry, rPropVal.Value); + } + } + + // Entries with side effects first, using dedicated one-element SfxItemSet for each + for (const auto& [pEntry, rValue] : aSideEffectsEntries) + { + SfxItemSet aItemSet(rDoc.GetAttrPool(), pEntry->nWID, pEntry->nWID); + // we need to get up-to-date item set from nodes + SwUnoCursorHelper::GetCursorAttr(rPaM, aItemSet); + // this can set some attributes in nodes' mpAttrSet + if (!SwUnoCursorHelper::SetCursorPropertyValue(*pEntry, rValue, rPaM, aItemSet)) + SfxItemPropertySet::setPropertyValue(*pEntry, rValue, aItemSet); + SwUnoCursorHelper::SetCursorAttr(rPaM, aItemSet, nAttrMode, false /*bTableMode*/); } if (!aEntries.empty()) { // Fetch, overwrite, and re-set the attributes from the core + SfxItemSet aItemSet(rDoc.GetAttrPool(), std::move(aRanges)); + // we need to get up-to-date item set from nodes + SwUnoCursorHelper::GetCursorAttr(rPaM, aItemSet); - bool bPreviousPropertyCausesSideEffectsInNodes = false; - for (size_t i = 0; i < aEntries.size(); ++i) + for (const auto& [pEntry, rValue] : aEntries) { - SfxItemPropertyMapEntry 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; + SfxItemPropertySet::setPropertyValue(*pEntry, rValue, aItemSet); } + + SwUnoCursorHelper::SetCursorAttr(rPaM, aItemSet, nAttrMode, false /*bTableMode*/); } if (!aUnknownExMsg.isEmpty()) - throw beans::UnknownPropertyException(aUnknownExMsg, static_cast<cppu::OWeakObject *>(nullptr)); + throw beans::UnknownPropertyException(aUnknownExMsg); if (!aPropertyVetoExMsg.isEmpty()) - throw beans::PropertyVetoException(aPropertyVetoExMsg, static_cast<cppu::OWeakObject *>(nullptr)); + throw beans::PropertyVetoException(aPropertyVetoExMsg); } namespace @@ -1867,8 +2022,8 @@ SwUnoCursorHelper::GetPropertyStates( 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; + std::optional<SfxItemSet> oSet; + std::optional<SfxItemSet> oSetParent; for (sal_Int32 i = 0, nEnd = rPropertyNames.getLength(); i < nEnd; i++) { @@ -1877,7 +2032,8 @@ SwUnoCursorHelper::GetPropertyStates( if(!pEntry) { if (pNames[i] == UNO_NAME_IS_SKIP_HIDDEN_TEXT || - pNames[i] == UNO_NAME_IS_SKIP_PROTECTED_TEXT) + pNames[i] == UNO_NAME_IS_SKIP_PROTECTED_TEXT || + pNames[i] == UNO_NAME_NO_FORMAT_ATTR) { pStates[i] = beans::PropertyState_DEFAULT_VALUE; continue; @@ -1892,8 +2048,7 @@ SwUnoCursorHelper::GetPropertyStates( else { throw beans::UnknownPropertyException( - "Unknown property: " + pNames[i], - static_cast<cppu::OWeakObject *>(nullptr)); + "Unknown property: " + pNames[i]); } } if (((SW_PROPERTY_STATE_CALLER_SWX_TEXT_PORTION == eCaller) || @@ -1913,50 +2068,48 @@ SwUnoCursorHelper::GetPropertyStates( } else { - if (!pSet) + if (!oSet) { 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>{} )); + oSet.emplace( 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}} )); + oSet.emplace( rPaM.GetDoc().GetAttrPool(), + pEntry->nWID, pEntry->nWID ); break; default: - pSet.reset( new SfxItemSet( + oSet.emplace( rPaM.GetDoc().GetAttrPool(), svl::Items< RES_CHRATR_BEGIN, RES_FRMATR_END - 1, RES_UNKNOWNATR_CONTAINER, - RES_UNKNOWNATR_CONTAINER>{})); + RES_UNKNOWNATR_CONTAINER>); } // #i63870# - SwUnoCursorHelper::GetCursorAttr( rPaM, *pSet ); + SwUnoCursorHelper::GetCursorAttr( rPaM, *oSet ); } - pStates[i] = ( pSet->Count() ) - ? rPropSet.getPropertyState( *pEntry, *pSet ) + pStates[i] = ( oSet->Count() ) + ? SfxItemPropertySet::getPropertyState( *pEntry, *oSet ) : beans::PropertyState_DEFAULT_VALUE; //try again to find out if a value has been inherited if( beans::PropertyState_DIRECT_VALUE == pStates[i] ) { - if (!pSetParent) + if (!oSetParent) { - pSetParent = pSet->Clone( false ); + oSetParent.emplace(oSet->CloneAsValue( false )); // #i63870# SwUnoCursorHelper::GetCursorAttr( - rPaM, *pSetParent, true, false ); + rPaM, *oSetParent, true, false ); } - pStates[i] = ( pSetParent->Count() ) - ? rPropSet.getPropertyState( *pEntry, *pSetParent ) + pStates[i] = ( oSetParent->Count() ) + ? SfxItemPropertySet::getPropertyState( *pEntry, *oSetParent ) : beans::PropertyState_DEFAULT_VALUE; } } @@ -1989,7 +2142,7 @@ lcl_SelectParaAndReset( SwPaM &rPaM, SwDoc & rDoc, pTemp->MovePara(GoCurrPara, fnParaStart); } pTemp->SetMark(); - *pTemp->GetPoint() = aEnd; + *pTemp->GetPoint() = std::move(aEnd); SwUnoCursorHelper::SelectPam(*pTemp, true); if(!SwUnoCursorHelper::IsEndOfPara(*pTemp)) { @@ -2008,8 +2161,7 @@ void SwUnoCursorHelper::SetPropertyToDefault( if (!pEntry) { throw beans::UnknownPropertyException( - OUString::Concat("Unknown property: ") + rPropertyName, - static_cast<cppu::OWeakObject *>(nullptr)); + OUString::Concat("Unknown property: ") + rPropertyName); } if (pEntry->nFlags & beans::PropertyAttribute::READONLY) @@ -2046,8 +2198,7 @@ uno::Any SwUnoCursorHelper::GetPropertyDefault( if (!pEntry) { throw beans::UnknownPropertyException( - OUString::Concat("Unknown property: ") + rPropertyName, - static_cast<cppu::OWeakObject *>(nullptr)); + OUString::Concat("Unknown property: ") + rPropertyName); } uno::Any aRet; @@ -2055,7 +2206,7 @@ uno::Any SwUnoCursorHelper::GetPropertyDefault( { SwDoc& rDoc = rPaM.GetDoc(); const SfxPoolItem& rDefItem = - rDoc.GetAttrPool().GetDefaultItem(pEntry->nWID); + rDoc.GetAttrPool().GetUserOrPoolDefaultItem(pEntry->nWID); rDefItem.QueryValue(aRet, pEntry->nMemberId); } return aRet; @@ -2070,12 +2221,12 @@ SwXTextCursor::getPropertySetInfo() { static SfxItemPropertyMapEntry const aCursorExtMap_Impl[] = { - { u"" UNO_NAME_IS_SKIP_HIDDEN_TEXT, FN_SKIP_HIDDEN_TEXT, cppu::UnoType<bool>::get(), PROPERTY_NONE, 0}, - { u"" UNO_NAME_IS_SKIP_PROTECTED_TEXT, FN_SKIP_PROTECTED_TEXT, cppu::UnoType<bool>::get(), PROPERTY_NONE, 0}, - { u"", 0, css::uno::Type(), 0, 0 } + { UNO_NAME_IS_SKIP_HIDDEN_TEXT, FN_SKIP_HIDDEN_TEXT, cppu::UnoType<bool>::get(), PROPERTY_NONE, 0}, + { UNO_NAME_IS_SKIP_PROTECTED_TEXT, FN_SKIP_PROTECTED_TEXT, cppu::UnoType<bool>::get(), PROPERTY_NONE, 0}, + { UNO_NAME_NO_FORMAT_ATTR, 0, cppu::UnoType<bool>::get(), PROPERTY_NONE, 0}, }; const uno::Reference< beans::XPropertySetInfo > xInfo = - m_pImpl->m_rPropSet.getPropertySetInfo(); + m_rPropSet.getPropertySetInfo(); // extend PropertySetInfo! const uno::Sequence<beans::Property> aPropSeq = xInfo->getProperties(); return rtl::Reference<SfxExtItemPropertySetInfo>(new SfxExtItemPropertySetInfo( @@ -2091,7 +2242,7 @@ SwXTextCursor::setPropertyValue( { SolarMutexGuard aGuard; - SwUnoCursor & rUnoCursor( m_pImpl->GetCursorOrThrow() ); + SwUnoCursor & rUnoCursor( GetCursorOrThrow() ); if (rPropertyName == UNO_NAME_IS_SKIP_HIDDEN_TEXT) { @@ -2111,10 +2262,76 @@ SwXTextCursor::setPropertyValue( } rUnoCursor.SetSkipOverProtectSections(bSet); } + else if (rPropertyName == UNO_NAME_NO_FORMAT_ATTR) + { + bool bSet(false); + if (!(rValue >>= bSet)) + { + throw lang::IllegalArgumentException(); + } + if (bSet) + { + m_nAttrMode = SetAttrMode::NOFORMATATTR; + } + else + { + m_nAttrMode = SetAttrMode::DEFAULT; + } + } + else if (rPropertyName == "ParaAutoStyleDef") + { + // Create an autostyle from passed definition (sequence of PropertyValue, same + // as in XAutoStyleFamily::insertStyle), using the currently applied properties + // from the paragraph to not lose their values when creating complex properties + // like SvxULSpaceItem, when only part of the properties stored there is passed; + // and apply it to the paragraph. + uno::Sequence<beans::PropertyValue> def; + if (!(rValue >>= def)) + throw lang::IllegalArgumentException(); + + // See SwUnoCursorHelper::SetPropertyValues + + auto pPropSet = aSwMapProvider.GetPropertySet(PROPERTY_MAP_PARA_AUTO_STYLE); + + // Build set of attributes we want to fetch + WhichRangesContainer aRanges; + for (auto& rPropVal : def) + { + SfxItemPropertyMapEntry const* pEntry = + pPropSet->getPropertyMap().getByName(rPropVal.Name); + if (!pEntry) + continue; // PropValuesToAutoStyleItemSet ignores invalid names + + aRanges = aRanges.MergeRange(pEntry->nWID, pEntry->nWID); + } + + if (!aRanges.empty()) + { + SwAttrSet aAutoStyleItemSet(rUnoCursor.GetDoc().GetAttrPool(), std::move(aRanges)); + // we need to get up-to-date item set: this makes sure that the complex properties, + // that are only partially defined by passed definition, do not lose the rest of + // their already present data (which will become part of the autostyle, too). + SwUnoCursorHelper::GetCursorAttr(rUnoCursor, aAutoStyleItemSet); + // Set normal set ranges before putting into autostyle, to the same ranges + // that are used for paragraph autostyle in SwXAutoStyleFamily::insertStyle + aAutoStyleItemSet.SetRanges(aTextNodeSetRange); + + // Fill the prepared item set, containing current paragraph property values, + // with the passed definition, and create the autostyle. + auto pStyle = PropValuesToAutoStyleItemSet( + rUnoCursor.GetDoc(), IStyleAccess::AUTO_STYLE_PARA, def, aAutoStyleItemSet); + + SwFormatAutoFormat aFormat(RES_AUTO_STYLE); + aFormat.SetStyleHandle(pStyle); + SfxItemSet rSet(rUnoCursor.GetDoc().GetAttrPool(), RES_AUTO_STYLE, RES_AUTO_STYLE); + rSet.Put(aFormat); + SwUnoCursorHelper::SetCursorAttr(rUnoCursor, rSet, m_nAttrMode); + } + } else { SwUnoCursorHelper::SetPropertyValue(rUnoCursor, - m_pImpl->m_rPropSet, rPropertyName, rValue); + m_rPropSet, rPropertyName, rValue, m_nAttrMode); } } @@ -2123,7 +2340,7 @@ SwXTextCursor::getPropertyValue(const OUString& rPropertyName) { SolarMutexGuard aGuard; - SwUnoCursor & rUnoCursor( m_pImpl->GetCursorOrThrow() ); + SwUnoCursor & rUnoCursor( GetCursorOrThrow() ); uno::Any aAny; if (rPropertyName == UNO_NAME_IS_SKIP_HIDDEN_TEXT) @@ -2139,7 +2356,7 @@ SwXTextCursor::getPropertyValue(const OUString& rPropertyName) else { aAny = SwUnoCursorHelper::GetPropertyValue(rUnoCursor, - m_pImpl->m_rPropSet, rPropertyName); + m_rPropSet, rPropertyName); } return aAny; } @@ -2181,10 +2398,10 @@ SwXTextCursor::getPropertyState(const OUString& rPropertyName) { SolarMutexGuard aGuard; - SwUnoCursor & rUnoCursor( m_pImpl->GetCursorOrThrow() ); + SwUnoCursor & rUnoCursor( GetCursorOrThrow() ); const beans::PropertyState eRet = SwUnoCursorHelper::GetPropertyState( - rUnoCursor, m_pImpl->m_rPropSet, rPropertyName); + rUnoCursor, m_rPropSet, rPropertyName); return eRet; } @@ -2194,10 +2411,10 @@ SwXTextCursor::getPropertyStates( { SolarMutexGuard aGuard; - SwUnoCursor & rUnoCursor( m_pImpl->GetCursorOrThrow() ); + SwUnoCursor & rUnoCursor( GetCursorOrThrow() ); return SwUnoCursorHelper::GetPropertyStates( - rUnoCursor, m_pImpl->m_rPropSet, rPropertyNames); + rUnoCursor, m_rPropSet, rPropertyNames); } void SAL_CALL @@ -2228,10 +2445,11 @@ void SAL_CALL SwXTextCursor::setPropertyValues( SolarMutexGuard aGuard; - SwUnoCursor & rUnoCursor( m_pImpl->GetCursorOrThrow() ); + SwUnoCursor & rUnoCursor( GetCursorOrThrow() ); // a little lame to have to copy into this. uno::Sequence< beans::PropertyValue > aPropertyValues( aValues.getLength() ); + auto aPropertyValuesRange = asNonConstRange(aPropertyValues); for ( sal_Int32 i = 0; i < aPropertyNames.getLength(); i++ ) { if ( aPropertyNames[ i ] == UNO_NAME_IS_SKIP_HIDDEN_TEXT || @@ -2241,12 +2459,12 @@ void SAL_CALL SwXTextCursor::setPropertyValues( OSL_FAIL("invalid property name for batch setting"); throw lang::IllegalArgumentException(); } - aPropertyValues[ i ].Name = aPropertyNames[ i ]; - aPropertyValues[ i ].Value = aValues[ i ]; + aPropertyValuesRange[ i ].Name = aPropertyNames[ i ]; + aPropertyValuesRange[ i ].Value = aValues[ i ]; } try { - SwUnoCursorHelper::SetPropertyValues( rUnoCursor, m_pImpl->m_rPropSet, aPropertyValues ); + SwUnoCursorHelper::SetPropertyValues( rUnoCursor, m_rPropSet, aPropertyValues ); } catch (const css::beans::UnknownPropertyException& e) { @@ -2262,7 +2480,7 @@ SwXTextCursor::getPropertyValues( const uno::Sequence< OUString >& aPropertyName { // a banal implementation for now uno::Sequence< uno::Any > aValues( aPropertyNames.getLength() ); - std::transform(aPropertyNames.begin(), aPropertyNames.end(), aValues.begin(), + std::transform(aPropertyNames.begin(), aPropertyNames.end(), aValues.getArray(), [this](const OUString& rName) -> uno::Any { return getPropertyValue( rName ); }); return aValues; } @@ -2324,7 +2542,7 @@ SwXTextCursor::setAllPropertiesToDefault() { SolarMutexGuard aGuard; - SwUnoCursor & rUnoCursor( m_pImpl->GetCursorOrThrow() ); + SwUnoCursor & rUnoCursor( GetCursorOrThrow() ); o3tl::sorted_vector<sal_uInt16> aParaWhichIds; o3tl::sorted_vector<sal_uInt16> aWhichIds; @@ -2347,7 +2565,7 @@ SwXTextCursor::setPropertiesToDefault( { SolarMutexGuard aGuard; - SwUnoCursor & rUnoCursor( m_pImpl->GetCursorOrThrow() ); + SwUnoCursor & rUnoCursor( GetCursorOrThrow() ); if ( !rPropertyNames.hasElements() ) return; @@ -2358,7 +2576,7 @@ SwXTextCursor::setPropertiesToDefault( for (const OUString& rName : rPropertyNames) { SfxItemPropertyMapEntry const*const pEntry = - m_pImpl->m_rPropSet.getPropertyMap().getByName( rName ); + m_rPropSet.getPropertyMap().getByName( rName ); if (!pEntry) { if (rName == UNO_NAME_IS_SKIP_HIDDEN_TEXT || @@ -2368,13 +2586,13 @@ SwXTextCursor::setPropertiesToDefault( } throw beans::UnknownPropertyException( "Unknown property: " + rName, - static_cast<cppu::OWeakObject *>(this)); + getXWeak()); } if (pEntry->nFlags & beans::PropertyAttribute::READONLY) { throw uno::RuntimeException( "setPropertiesToDefault: property is read-only: " + rName, - static_cast<cppu::OWeakObject *>(this)); + getXWeak()); } if (pEntry->nWID < RES_FRMATR_END) @@ -2410,7 +2628,7 @@ SwXTextCursor::getPropertyDefaults( { SolarMutexGuard aGuard; - SwUnoCursor & rUnoCursor( m_pImpl->GetCursorOrThrow() ); + SwUnoCursor & rUnoCursor( GetCursorOrThrow() ); const sal_Int32 nCount = rPropertyNames.getLength(); uno::Sequence< uno::Any > aRet(nCount); @@ -2422,22 +2640,22 @@ SwXTextCursor::getPropertyDefaults( for (sal_Int32 i = 0; i < nCount; i++) { SfxItemPropertyMapEntry const*const pEntry = - m_pImpl->m_rPropSet.getPropertyMap().getByName( pNames[i] ); + m_rPropSet.getPropertyMap().getByName( pNames[i] ); if (!pEntry) { if (pNames[i] == UNO_NAME_IS_SKIP_HIDDEN_TEXT || - pNames[i] == UNO_NAME_IS_SKIP_PROTECTED_TEXT) + pNames[i] == UNO_NAME_IS_SKIP_PROTECTED_TEXT || + pNames[i] == UNO_NAME_NO_FORMAT_ATTR) { continue; } throw beans::UnknownPropertyException( - "Unknown property: " + pNames[i], - static_cast<cppu::OWeakObject *>(nullptr)); + "Unknown property: " + pNames[i]); } if (pEntry->nWID < RES_FRMATR_END) { const SfxPoolItem& rDefItem = - rDoc.GetAttrPool().GetDefaultItem(pEntry->nWID); + rDoc.GetAttrPool().GetUserOrPoolDefaultItem(pEntry->nWID); rDefItem.QueryValue(pAny[i], pEntry->nMemberId); } } @@ -2449,9 +2667,9 @@ void SAL_CALL SwXTextCursor::invalidateMarkings(::sal_Int32 nType) { SolarMutexGuard aGuard; - SwUnoCursor & rUnoCursor( m_pImpl->GetCursorOrThrow() ); + SwUnoCursor & rUnoCursor( GetCursorOrThrow() ); - SwNode& node = rUnoCursor.GetNode(); + SwNode& node = rUnoCursor.GetPointNode(); SwTextNode* txtNode = node.GetTextNode(); @@ -2459,18 +2677,18 @@ void SAL_CALL SwXTextCursor::invalidateMarkings(::sal_Int32 nType) if ( text::TextMarkupType::SPELLCHECK == nType ) { - txtNode->SetWrongDirty(SwTextNode::WrongState::TODO); - txtNode->SetWrong(nullptr); + txtNode->SetWrongDirty(sw::WrongState::TODO); + txtNode->ClearWrong(); } else if( text::TextMarkupType::PROOFREADING == nType ) { txtNode->SetGrammarCheckDirty(true); - txtNode->SetGrammarCheck(nullptr); + txtNode->ClearGrammarCheck(); } else if ( text::TextMarkupType::SMARTTAG == nType ) { txtNode->SetSmartTagDirty(true); - txtNode->SetSmartTags(nullptr); + txtNode->ClearSmartTags(); } else return; @@ -2489,7 +2707,7 @@ SwXTextCursor::makeRedline( { SolarMutexGuard aGuard; - SwUnoCursor & rUnoCursor( m_pImpl->GetCursorOrThrow() ); + SwUnoCursor & rUnoCursor( GetCursorOrThrow() ); SwUnoCursorHelper::makeRedline(rUnoCursor, rRedlineType, rRedlineProperties); } @@ -2499,7 +2717,7 @@ void SAL_CALL SwXTextCursor::insertDocumentFromURL(const OUString& rURL, { SolarMutexGuard aGuard; - SwUnoCursor & rUnoCursor( m_pImpl->GetCursorOrThrow() ); + SwUnoCursor & rUnoCursor( GetCursorOrThrow() ); SwUnoCursorHelper::InsertFile(&rUnoCursor, rURL, rOptions); } @@ -2527,9 +2745,6 @@ SwUnoCursorHelper::CreateSortDescriptor(const bool bFromTable) 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( @@ -2542,26 +2757,13 @@ SwUnoCursorHelper::CreateSortDescriptor(const bool bFromTable) 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; + uno::Sequence< table::TableSortField > aFields + { + // Field, IsAscending, IsCaseSensitive, FieldType, CollatorLocale, CollatorAlgorithm + { 1, true, false, table::TableSortFieldType_ALPHANUMERIC, aLang, aCollAlg }, + { 1, true, false, table::TableSortFieldType_ALPHANUMERIC, aLang, aCollAlg }, + { 1, true, false, table::TableSortFieldType_ALPHANUMERIC, aLang, aCollAlg } + }; aVal <<= aFields; pArray[4] = beans::PropertyValue("SortFields", -1, aVal, @@ -2588,21 +2790,21 @@ bool SwUnoCursorHelper::ConvertSortProperties( 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; + SwSortKey aKey1; + aKey1.nColumnId = USHRT_MAX; + aKey1.bIsNumeric = true; + aKey1.eSortOrder = SwSortOrder::Ascending; - std::unique_ptr<SwSortKey> pKey2(new SwSortKey); - pKey2->nColumnId = USHRT_MAX; - pKey2->bIsNumeric = true; - pKey2->eSortOrder = SwSortOrder::Ascending; + SwSortKey aKey2; + aKey2.nColumnId = USHRT_MAX; + aKey2.bIsNumeric = true; + aKey2.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()}; + SwSortKey aKey3; + aKey3.nColumnId = USHRT_MAX; + aKey3.bIsNumeric = true; + aKey3.eSortOrder = SwSortOrder::Ascending; + SwSortKey* aKeys[3] = {&aKey1, &aKey2, &aKey3}; bool bOldSortdescriptor(false); bool bNewSortdescriptor(false); @@ -2729,8 +2931,8 @@ bool SwUnoCursorHelper::ConvertSortProperties( bOldSortdescriptor = true; sal_uInt16 nIndex = rPropName[13]; nIndex = nIndex - '0'; - auto bTemp = o3tl::tryAccess<bool>(aValue); - if (bTemp && nIndex < 3) + std::optional<const bool> bTemp = o3tl::tryAccess<bool>(aValue); + if (bTemp.has_value() && nIndex < 3) { aKeys[nIndex]->bIsNumeric = *bTemp; } @@ -2746,8 +2948,8 @@ bool SwUnoCursorHelper::ConvertSortProperties( bOldSortdescriptor = true; sal_uInt16 nIndex = rPropName[15]; nIndex -= '0'; - auto bTemp = o3tl::tryAccess<bool>(aValue); - if (bTemp && nIndex < 3) + std::optional<const bool> bTemp = o3tl::tryAccess<bool>(aValue); + if (bTemp.has_value() && nIndex < 3) { aKeys[nIndex]->eSortOrder = (*bTemp) ? SwSortOrder::Ascending : SwSortOrder::Descending; @@ -2787,7 +2989,7 @@ bool SwUnoCursorHelper::ConvertSortProperties( LanguageTag::convertToLanguageType( pFields[i].CollatorLocale ); aKeys[i]->sSortType = pFields[i].CollatorAlgorithm; aKeys[i]->nColumnId = - static_cast<sal_uInt16>(pFields[i].Field); + o3tl::narrowing<sal_uInt16>(pFields[i].Field); aKeys[i]->bIsNumeric = (pFields[i].FieldType == table::TableSortFieldType_NUMERIC); aKeys[i]->eSortOrder = (pFields[i].IsAscending) @@ -2813,17 +3015,17 @@ bool SwUnoCursorHelper::ConvertSortProperties( bRet = false; } - if (pKey1->nColumnId != USHRT_MAX) + if (aKey1.nColumnId != USHRT_MAX) { - rSortOpt.aKeys.push_back(std::move(pKey1)); + rSortOpt.aKeys.push_back(aKey1); } - if (pKey2->nColumnId != USHRT_MAX) + if (aKey2.nColumnId != USHRT_MAX) { - rSortOpt.aKeys.push_back(std::move(pKey2)); + rSortOpt.aKeys.push_back(aKey2); } - if (pKey3->nColumnId != USHRT_MAX) + if (aKey3.nColumnId != USHRT_MAX) { - rSortOpt.aKeys.push_back(std::move(pKey3)); + rSortOpt.aKeys.push_back(aKey3); } return bRet && !rSortOpt.aKeys.empty(); @@ -2834,7 +3036,7 @@ SwXTextCursor::sort(const uno::Sequence< beans::PropertyValue >& rDescriptor) { SolarMutexGuard aGuard; - SwUnoCursor & rUnoCursor( m_pImpl->GetCursorOrThrow() ); + SwUnoCursor & rUnoCursor( GetCursorOrThrow() ); if (!rUnoCursor.HasMark()) return; @@ -2849,27 +3051,27 @@ SwXTextCursor::sort(const uno::Sequence< beans::PropertyValue >& rDescriptor) 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(); + SwNodeIndex aPrevIdx( rStart.GetNode(), -1 ); + const SwNodeOffset nOffset = rEnd.GetNodeIndex() - rStart.GetNodeIndex(); + const sal_Int32 nCntStt = rStart.GetContentIndex(); rUnoCursor.GetDoc().SortText(rUnoCursor, aSortOpt); // update selection rUnoCursor.DeleteMark(); - rUnoCursor.GetPoint()->nNode.Assign( aPrevIdx.GetNode(), +1 ); - SwContentNode *const pCNd = rUnoCursor.GetContentNode(); + rUnoCursor.GetPoint()->Assign( aPrevIdx.GetNode(), SwNodeOffset(1) ); + SwContentNode *const pCNd = rUnoCursor.GetPointContentNode(); sal_Int32 nLen = pCNd->Len(); if (nLen > nCntStt) { nLen = nCntStt; } - rUnoCursor.GetPoint()->nContent.Assign(pCNd, nLen ); + rUnoCursor.GetPoint()->SetContent( nLen ); rUnoCursor.SetMark(); - rUnoCursor.GetPoint()->nNode += nOffset; - SwContentNode *const pCNd2 = rUnoCursor.GetContentNode(); - rUnoCursor.GetPoint()->nContent.Assign( pCNd2, pCNd2->Len() ); + rUnoCursor.GetPoint()->Adjust(nOffset); + SwContentNode *const pCNd2 = rUnoCursor.GetPointContentNode(); + rUnoCursor.GetPoint()->SetContent( pCNd2->Len() ); } @@ -2879,7 +3081,7 @@ SwXTextCursor::createContentEnumeration(const OUString& rServiceName) SolarMutexGuard g; if (rServiceName != "com.sun.star.text.TextContent") throw uno::RuntimeException(); - SwUnoCursor& rUnoCursor( m_pImpl->GetCursorOrThrow() ); + SwUnoCursor& rUnoCursor( GetCursorOrThrow() ); return SwXParaFrameEnumeration::Create(rUnoCursor, PARAFRAME_PORTION_TEXTRANGE); } @@ -2888,9 +3090,9 @@ SwXTextCursor::createEnumeration() { SolarMutexGuard g; - SwUnoCursor & rUnoCursor( m_pImpl->GetCursorOrThrow() ); + SwUnoCursor & rUnoCursor( GetCursorOrThrow() ); - SwXText* pParentText = comphelper::getUnoTunnelImplementation<SwXText>(m_pImpl->m_xParentText); + SwXText* pParentText = dynamic_cast<SwXText*>(m_xParentText.get()); OSL_ENSURE(pParentText, "parent is not a SwXText"); if (!pParentText) { @@ -2903,7 +3105,7 @@ SwXTextCursor::createEnumeration() pNewCursor->SetMark(); *pNewCursor->GetMark() = *rUnoCursor.GetMark(); } - const CursorType eSetType = (CursorType::TableText == m_pImpl->m_eType) + const CursorType eSetType = (CursorType::TableText == m_eType) ? CursorType::SelectionInTable : CursorType::Selection; return SwXParagraphEnumeration::Create(pParentText, pNewCursor, eSetType); } @@ -2926,14 +3128,4 @@ SwXTextCursor::getAvailableServiceNames() 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: */ |