From b6b1ded0a0539e7be1b5338de378a3276a6ff445 Mon Sep 17 00:00:00 2001 From: Henry Castro Date: Fri, 8 Jun 2018 17:09:55 -0400 Subject: sc: replace ScCaptionPtr with std::shared_ptr, tdf#117997, tdf#117228 Change-Id: I9b6a2c2504c9ce060906ac3bf156721709fef2f3 Reviewed-on: https://gerrit.libreoffice.org/55490 Tested-by: Jenkins Reviewed-by: Eike Rathke --- sc/inc/postit.hxx | 114 +------- sc/inc/scmod.hxx | 2 - sc/qa/unit/ucalc.cxx | 18 +- sc/source/core/data/documen3.cxx | 3 +- sc/source/core/data/document.cxx | 9 +- sc/source/core/data/postit.cxx | 554 +++++++----------------------------- sc/source/core/tool/detfunc.cxx | 2 +- sc/source/filter/excel/xeescher.cxx | 2 +- sc/source/filter/xml/xmlexprt.cxx | 10 +- sc/source/ui/app/scmod.cxx | 28 -- sc/source/ui/docshell/docfunc.cxx | 4 +- sc/source/ui/docshell/docsh.cxx | 33 ++- sc/source/ui/drawfunc/futext3.cxx | 4 +- sc/source/ui/inc/docsh.hxx | 2 + sc/source/ui/inc/notemark.hxx | 2 +- sc/source/ui/inc/undocell.hxx | 45 +++ sc/source/ui/undo/undocell.cxx | 185 +++++++++++- sc/source/ui/unoobj/editsrc.cxx | 2 +- sc/source/ui/unoobj/notesuno.cxx | 2 +- sc/source/ui/view/drawview.cxx | 2 +- sc/source/ui/view/gridwin.cxx | 2 +- sc/source/ui/view/notemark.cxx | 2 +- sc/source/ui/view/tabview5.cxx | 2 +- sc/source/ui/view/viewfun6.cxx | 2 +- 24 files changed, 402 insertions(+), 629 deletions(-) diff --git a/sc/inc/postit.hxx b/sc/inc/postit.hxx index bf29a9693904..de77e208b829 100644 --- a/sc/inc/postit.hxx +++ b/sc/inc/postit.hxx @@ -36,110 +36,6 @@ class ScDocument; namespace tools { class Rectangle; } struct ScCaptionInitData; -/** Some desperate attempt to fight against the caption object ownership mess, - to which none of shared/weak/plain pointer is a cure. - */ -class ScCaptionPtr -{ -public: - ScCaptionPtr(); - explicit ScCaptionPtr( SdrCaptionObj* p ); - ScCaptionPtr( const ScCaptionPtr& r ); - ScCaptionPtr( ScCaptionPtr&& r ); - ~ScCaptionPtr(); - - ScCaptionPtr& operator=( const ScCaptionPtr& r ); - ScCaptionPtr& operator=( ScCaptionPtr&& r ); - explicit operator bool() const { return mpCaption != nullptr; } - const SdrCaptionObj* get() const { return mpCaption; } - SdrCaptionObj* get() { return mpCaption; } - const SdrCaptionObj* operator->() const { return mpCaption; } - SdrCaptionObj* operator->() { return mpCaption; } - const SdrCaptionObj& operator*() const { return *mpCaption; } - SdrCaptionObj& operator*() { return *mpCaption; } - - // Does not default to nullptr to make it visually obvious where such is used. - void reset( SdrCaptionObj* p ); - - /** Insert to draw page. The caption object is owned by the draw page then. - */ - void insertToDrawPage( SdrPage& rDrawPage ); - - /** Remove from draw page. The caption object is not owned anymore by the - draw page then. - */ - void removeFromDrawPage( SdrPage& rDrawPage ); - - /** Remove from draw page and free caption object if no Undo recording. - */ - void removeFromDrawPageAndFree( bool bIgnoreUndo = false ); - - /** Release all management of the SdrCaptionObj* in all instances of this - list and dissolve. The SdrCaptionObj pointer returned is ready to be - managed elsewhere. - */ - SdrCaptionObj* release(); - - /** Forget the SdrCaptionObj pointer in this one instance. - Decrements a use count but does not destroy the object, it's up to the - caller to manage this mess.. - */ - void forget(); - - /** Flag that this instance is in Undo, so drawing layer owns it. */ - void setNotOwner(); - - oslInterlockedCount getRefs() const; - -private: - - struct Head - { - ScCaptionPtr* mpFirst; ///< first in list - oslInterlockedCount mnRefs; ///< use count - - Head() = delete; - explicit Head( ScCaptionPtr* ); - }; - - Head* mpHead; ///< points to the "master" entry - mutable ScCaptionPtr* mpNext; ///< next in list - SdrCaptionObj* mpCaption; ///< the caption object, managed by head master - bool mbNotOwner; ///< whether this caption object is owned by something else, e.g. held in Undo - /* TODO: can that be moved to Head? - * It's unclear when to reset, so - * each instance has its own flag. - * The last reference count - * decrement automatically has the - * then current state available. - * */ - - void newHead(); //< Allocate a new Head and init. - void incRef() const; - bool decRef() const; //< @returns if the last reference was decremented. - void decRefAndDestroy(); //< Destroys caption object if the last reference was decremented. - - /** Remove from current list and close gap. - - Usually there are only very few instances, so maintaining a doubly - linked list isn't worth memory/performance wise and a simple walk does - it. - */ - void removeFromList(); - - /** Replace this instance with pNew in a list, if any. - - Used by move-ctor and move assignment operator. - */ - void replaceInList( ScCaptionPtr* pNew ); - - /** Dissolve list when the caption object is released or gone. */ - void dissolve(); - - /** Just clear everything, while dissolving the list. */ - void clear(); -}; - /** Internal data for a cell annotation. */ struct SC_DLLPUBLIC ScNoteData { @@ -148,7 +44,7 @@ struct SC_DLLPUBLIC ScNoteData OUString maDate; /// Creation date of the note. OUString maAuthor; /// Author of the note. ScCaptionInitDataRef mxInitData; /// Initial data for invisible notes without SdrObject. - ScCaptionPtr mxCaption; /// Drawing object representing the cell note. + std::shared_ptr< SdrCaptionObj > m_pCaption; /// Drawing object representing the cell note. bool mbShown; /// True = note is visible. explicit ScNoteData( bool bShown = false ); @@ -235,12 +131,12 @@ public: contains initial caption data needed to construct a caption object. The SdrCaptionObj* returned is still managed by the underlying ScNoteData::ScCaptionPtr and must not be stored elsewhere. */ - SdrCaptionObj* GetCaption() const { return maNoteData.mxCaption.get();} + const std::shared_ptr< SdrCaptionObj>& GetCaption() const { return maNoteData.m_pCaption; } /** Returns the caption object of this note. Creates the caption object, if the note contains initial caption data instead of the caption. The SdrCaptionObj* returned is still managed by the underlying ScNoteData::ScCaptionPtr and must not be stored elsewhere. */ - SdrCaptionObj* GetOrCreateCaption( const ScAddress& rPos ) const; + const std::shared_ptr< SdrCaptionObj>& GetOrCreateCaption( const ScAddress& rPos ) const; /** Forgets the pointer to the note caption object. @@ -268,7 +164,7 @@ private: /** Creates the caption object from initial caption data if existing. */ void CreateCaptionFromInitData( const ScAddress& rPos ) const; /** Creates a new caption object at the passed cell position, clones passed existing caption. */ - void CreateCaption( const ScAddress& rPos, const SdrCaptionObj* pCaption = nullptr ); + void CreateCaption( const ScAddress& rPos, const std::shared_ptr< SdrCaptionObj >& pCaption ); /** Removes the caption object from the drawing layer, if this note is its owner. */ void RemoveCaption(); @@ -283,7 +179,7 @@ class SC_DLLPUBLIC ScNoteUtil public: /** Creates and returns a caption object for a temporary caption. */ - static ScCaptionPtr CreateTempCaption( ScDocument& rDoc, const ScAddress& rPos, + static std::shared_ptr< SdrCaptionObj > CreateTempCaption( ScDocument& rDoc, const ScAddress& rPos, SdrPage& rDrawPage, const OUString& rUserText, const tools::Rectangle& rVisRect, bool bTailFront ); diff --git a/sc/inc/scmod.hxx b/sc/inc/scmod.hxx index 6d75e15807e6..8349274645a7 100644 --- a/sc/inc/scmod.hxx +++ b/sc/inc/scmod.hxx @@ -147,8 +147,6 @@ public: void SetDragJump( ScDocument* pLocalDoc, const OUString& rTarget, const OUString& rText ); - static ScDocument* GetClipDoc(); // called from document - should be removed later - // X selection: ScSelectionTransferObj* GetSelectionTransfer() const { return m_pSelTransfer; } void SetSelectionTransfer( ScSelectionTransferObj* pNew ); diff --git a/sc/qa/unit/ucalc.cxx b/sc/qa/unit/ucalc.cxx index b836076aab31..6fb52101ed0c 100644 --- a/sc/qa/unit/ucalc.cxx +++ b/sc/qa/unit/ucalc.cxx @@ -5339,7 +5339,7 @@ void Test::testNoteLifeCycle() // Re-insert the note back to the same place. m_pDoc->SetNote(aPos, pNote); - SdrCaptionObj* pCaption = pNote->GetOrCreateCaption(aPos); + SdrCaptionObj* pCaption = pNote->GetOrCreateCaption(aPos).get(); CPPUNIT_ASSERT_MESSAGE("Failed to create a caption object.", pCaption); CPPUNIT_ASSERT_EQUAL_MESSAGE("This caption should belong to the drawing layer of the document.", m_pDoc->GetDrawLayer(), static_cast(&pCaption->getSdrModelFromSdrObject())); @@ -5355,7 +5355,7 @@ void Test::testNoteLifeCycle() ScPostIt* pClipNote = aClipDoc.GetNote(aPos); CPPUNIT_ASSERT_MESSAGE("Failed to copy note to the clipboard.", pClipNote); CPPUNIT_ASSERT_EQUAL_MESSAGE("Note on the clipboard should share the same caption object from the original.", - pCaption, pClipNote->GetCaption()); + pCaption, pClipNote->GetCaption().get()); // Move B2 to B3 with note, which creates an ScUndoDragDrop, and Undo. @@ -5363,7 +5363,7 @@ void Test::testNoteLifeCycle() ScAddress aOrigPos(aPos); ScAddress aMovePos(1,2,0); ScPostIt* pOrigNote = m_pDoc->GetNote(aOrigPos); - const SdrCaptionObj* pOrigCaption = pOrigNote->GetOrCreateCaption(aOrigPos); + const SdrCaptionObj* pOrigCaption = pOrigNote->GetOrCreateCaption(aOrigPos).get(); bool const bCut = true; // like Drag&Drop bool bRecord = true; // record Undo bool const bPaint = false; // don't care about @@ -5381,7 +5381,7 @@ void Test::testNoteLifeCycle() // The caption object should not be identical, it was newly created upon // Drop from clipboard. // pOrigCaption is a dangling pointer. - const SdrCaptionObj* pMoveCaption = pMoveNote->GetOrCreateCaption(aMovePos); + const SdrCaptionObj* pMoveCaption = pMoveNote->GetOrCreateCaption(aMovePos).get(); CPPUNIT_ASSERT_MESSAGE("Captions identical after move.", pOrigCaption != pMoveCaption); SfxUndoManager* pUndoMgr = m_pDoc->GetUndoManager(); @@ -5396,7 +5396,7 @@ void Test::testNoteLifeCycle() // The caption object still should not be identical. // pMoveCaption is a dangling pointer. - pOrigCaption = pOrigNote->GetOrCreateCaption(aOrigPos); + pOrigCaption = pOrigNote->GetOrCreateCaption(aOrigPos).get(); CPPUNIT_ASSERT_MESSAGE("Captions identical after move undo.", pOrigCaption != pMoveCaption); @@ -5405,7 +5405,7 @@ void Test::testNoteLifeCycle() ScAddress aPosB4(1,3,0); ScPostIt* pNoteB4 = m_pDoc->GetOrCreateNote(aPosB4); CPPUNIT_ASSERT_MESSAGE("Failed to insert cell comment at B4.", pNoteB4); - const SdrCaptionObj* pCaptionB4 = pNoteB4->GetOrCreateCaption(aPosB4); + const SdrCaptionObj* pCaptionB4 = pNoteB4->GetOrCreateCaption(aPosB4).get(); ScCellMergeOption aCellMergeOption(1,3,2,3); rDocFunc.MergeCells( aCellMergeOption, true /*bContents*/, bRecord, bApi, false /*bEmptyMergedCells*/ ); @@ -5417,7 +5417,7 @@ void Test::testNoteLifeCycle() // at B4 after the merge and not cloned nor recreated during Undo. ScPostIt* pUndoNoteB4 = m_pDoc->GetNote(aPosB4); CPPUNIT_ASSERT_MESSAGE("No cell comment at B4 after Undo.", pUndoNoteB4); - const SdrCaptionObj* pUndoCaptionB4 = pUndoNoteB4->GetCaption(); + const SdrCaptionObj* pUndoCaptionB4 = pUndoNoteB4->GetCaption().get(); CPPUNIT_ASSERT_EQUAL_MESSAGE("Captions not identical after Merge Undo.", pCaptionB4, pUndoCaptionB4); @@ -5433,7 +5433,7 @@ void Test::testNoteLifeCycle() ScAddress aPosB5(1,4,0); ScPostIt* pOtherNoteB5 = pDoc2->GetOrCreateNote(aPosB5); CPPUNIT_ASSERT_MESSAGE("Failed to insert cell comment at B5.", pOtherNoteB5); - const SdrCaptionObj* pOtherCaptionB5 = pOtherNoteB5->GetOrCreateCaption(aPosB5); + const SdrCaptionObj* pOtherCaptionB5 = pOtherNoteB5->GetOrCreateCaption(aPosB5).get(); CPPUNIT_ASSERT_MESSAGE("No caption at B5.", pOtherCaptionB5); ScDocument aClipDoc2(SCDOCMODE_CLIP); @@ -5451,7 +5451,7 @@ void Test::testNoteLifeCycle() pasteFromClip( m_pDoc, aPosB5, &aClipDoc2); // should not crash... tdf#104967 ScPostIt* pNoteB5 = m_pDoc->GetNote(aPosB5); CPPUNIT_ASSERT_MESSAGE("Failed to paste cell comment at B5.", pNoteB5); - const SdrCaptionObj* pCaptionB5 = pNoteB5->GetOrCreateCaption(aPosB5); + const SdrCaptionObj* pCaptionB5 = pNoteB5->GetOrCreateCaption(aPosB5).get(); CPPUNIT_ASSERT_MESSAGE("No caption at pasted B5.", pCaptionB5); // Do not test if pCaptionB5 != pOtherCaptionB5 because since pDoc2 // has been closed and the caption been deleted objects *may* be diff --git a/sc/source/core/data/documen3.cxx b/sc/source/core/data/documen3.cxx index bb68d1c849ef..1b9629c34a9d 100644 --- a/sc/source/core/data/documen3.cxx +++ b/sc/source/core/data/documen3.cxx @@ -76,6 +76,7 @@ #include #include #include +#include #include #include @@ -1093,7 +1094,7 @@ void ScDocument::UpdateReference( // After moving, no clipboard move ref-updates are possible if (rCxt.meMode != URM_COPY && IsClipboardSource()) { - ScDocument* pClipDoc = ScModule::GetClipDoc(); + ScDocument* pClipDoc = static_cast(mpShell)->GetClipDoc(); if (pClipDoc) pClipDoc->GetClipParam().mbCutMode = false; } diff --git a/sc/source/core/data/document.cxx b/sc/source/core/data/document.cxx index 32f1669e97d1..3f0886805fdc 100644 --- a/sc/source/core/data/document.cxx +++ b/sc/source/core/data/document.cxx @@ -99,6 +99,7 @@ #include #include #include +#include #include @@ -2183,7 +2184,7 @@ void ScDocument::CopyToClip(const ScClipParam& rClipParam, if (!pClipDoc) { SAL_WARN("sc", "CopyToClip: no ClipDoc"); - pClipDoc = ScModule::GetClipDoc(); + pClipDoc = static_cast(mpShell)->GetClipDoc(); } if (mpShell->GetMedium()) @@ -2283,7 +2284,7 @@ void ScDocument::CopyTabToClip(SCCOL nCol1, SCROW nRow1, if (!pClipDoc) { SAL_WARN("sc", "CopyTabToClip: no ClipDoc"); - pClipDoc = ScModule::GetClipDoc(); + pClipDoc = static_cast(mpShell)->GetClipDoc(); } if (mpShell->GetMedium()) @@ -2570,7 +2571,7 @@ bool ScDocument::IsClipboardSource() const if (bIsClip) return false; - ScDocument* pClipDoc = ScModule::GetClipDoc(); + ScDocument* pClipDoc = static_cast(mpShell)->GetClipDoc(); return pClipDoc && pClipDoc->bIsClip && pClipDoc->mxPoolHelper.is() && mxPoolHelper.is() && mxPoolHelper->GetDocPool() == pClipDoc->mxPoolHelper->GetDocPool(); } @@ -2807,7 +2808,7 @@ void ScDocument::CopyFromClip( const ScRange& rDestRange, const ScMarkData& rMar if (!pClipDoc) { OSL_FAIL("CopyFromClip: no ClipDoc"); - pClipDoc = ScModule::GetClipDoc(); + pClipDoc = static_cast(mpShell)->GetClipDoc(); } if (!pClipDoc->bIsClip || !pClipDoc->GetTableCount()) diff --git a/sc/source/core/data/postit.cxx b/sc/source/core/data/postit.cxx index c943d0350d8b..4629bbdc052b 100644 --- a/sc/source/core/data/postit.cxx +++ b/sc/source/core/data/postit.cxx @@ -44,6 +44,7 @@ #include #include #include +#include #include #include #include @@ -162,12 +163,12 @@ public: /** Create a new caption. The caption will not be inserted into the document. */ explicit ScCaptionCreator( ScDocument& rDoc, const ScAddress& rPos, bool bTailFront ); /** Manipulate an existing caption. */ - explicit ScCaptionCreator( ScDocument& rDoc, const ScAddress& rPos, const ScCaptionPtr& xCaption ); + explicit ScCaptionCreator( ScDocument& rDoc, const ScAddress& rPos, const std::shared_ptr< SdrCaptionObj >& pCaption ); /** Returns the drawing layer page of the sheet contained in maPos. */ SdrPage* GetDrawPage(); /** Returns the caption drawing object. */ - ScCaptionPtr & GetCaption() { return mxCaption; } + const std::shared_ptr< SdrCaptionObj >& GetCaption() { return m_pCaption; } /** Moves the caption inside the passed rectangle. Uses page area if 0 is passed. */ void FitCaptionToRect( const tools::Rectangle* pVisRect = nullptr ); @@ -194,7 +195,7 @@ private: private: ScDocument& mrDoc; ScAddress maPos; - ScCaptionPtr mxCaption; + std::shared_ptr< SdrCaptionObj > m_pCaption; tools::Rectangle maPageRect; tools::Rectangle maCellRect; bool mbNegPage; @@ -208,10 +209,10 @@ ScCaptionCreator::ScCaptionCreator( ScDocument& rDoc, const ScAddress& rPos, boo CreateCaption( true/*bShown*/, bTailFront ); } -ScCaptionCreator::ScCaptionCreator( ScDocument& rDoc, const ScAddress& rPos, const ScCaptionPtr& xCaption ) : +ScCaptionCreator::ScCaptionCreator( ScDocument& rDoc, const ScAddress& rPos, const std::shared_ptr< SdrCaptionObj >& pCaption ) : mrDoc( rDoc ), maPos( rPos ), - mxCaption( xCaption ) + m_pCaption( pCaption ) { Initialize(); } @@ -234,13 +235,13 @@ void ScCaptionCreator::FitCaptionToRect( const tools::Rectangle* pVisRect ) const tools::Rectangle& rVisRect = GetVisRect( pVisRect ); // tail position - Point aTailPos = mxCaption->GetTailPos(); + Point aTailPos = m_pCaption->GetTailPos(); aTailPos.setX( ::std::max( ::std::min( aTailPos.X(), rVisRect.Right() ), rVisRect.Left() ) ); aTailPos.setY( ::std::max( ::std::min( aTailPos.Y(), rVisRect.Bottom() ), rVisRect.Top() ) ); - mxCaption->SetTailPos( aTailPos ); + m_pCaption->SetTailPos( aTailPos ); // caption rectangle - tools::Rectangle aCaptRect = mxCaption->GetLogicRect(); + tools::Rectangle aCaptRect = m_pCaption->GetLogicRect(); Point aCaptPos = aCaptRect.TopLeft(); // move textbox inside right border of visible area aCaptPos.setX( ::std::min< long >( aCaptPos.X(), rVisRect.Right() - aCaptRect.GetWidth() ) ); @@ -252,7 +253,7 @@ void ScCaptionCreator::FitCaptionToRect( const tools::Rectangle* pVisRect ) aCaptPos.setY( ::std::max< long >( aCaptPos.Y(), rVisRect.Top() ) ); // update caption aCaptRect.SetPos( aCaptPos ); - mxCaption->SetLogicRect( aCaptRect ); + m_pCaption->SetLogicRect( aCaptRect ); } void ScCaptionCreator::AutoPlaceCaption( const tools::Rectangle* pVisRect ) @@ -260,7 +261,7 @@ void ScCaptionCreator::AutoPlaceCaption( const tools::Rectangle* pVisRect ) const tools::Rectangle& rVisRect = GetVisRect( pVisRect ); // caption rectangle - tools::Rectangle aCaptRect = mxCaption->GetLogicRect(); + tools::Rectangle aCaptRect = m_pCaption->GetLogicRect(); long nWidth = aCaptRect.GetWidth(); long nHeight = aCaptRect.GetHeight(); @@ -318,7 +319,7 @@ void ScCaptionCreator::AutoPlaceCaption( const tools::Rectangle* pVisRect ) // update textbox position in note caption object aCaptRect.SetPos( aCaptPos ); - mxCaption->SetLogicRect( aCaptRect ); + m_pCaption->SetLogicRect( aCaptRect ); FitCaptionToRect( pVisRect ); } @@ -327,33 +328,33 @@ void ScCaptionCreator::UpdateCaptionPos() ScDrawLayer* pDrawLayer = mrDoc.GetDrawLayer(); // update caption position - const Point& rOldTailPos = mxCaption->GetTailPos(); + const Point& rOldTailPos = m_pCaption->GetTailPos(); Point aTailPos = CalcTailPos( false ); if( rOldTailPos != aTailPos ) { // create drawing undo action if( pDrawLayer && pDrawLayer->IsRecording() ) - pDrawLayer->AddCalcUndo( new SdrUndoGeoObj( *mxCaption ) ); + pDrawLayer->AddCalcUndo( new SdrUndoGeoObj( *m_pCaption ) ); // calculate new caption rectangle (#i98141# handle LTR<->RTL switch correctly) - tools::Rectangle aCaptRect = mxCaption->GetLogicRect(); + tools::Rectangle aCaptRect = m_pCaption->GetLogicRect(); long nDiffX = (rOldTailPos.X() >= 0) ? (aCaptRect.Left() - rOldTailPos.X()) : (rOldTailPos.X() - aCaptRect.Right()); if( mbNegPage ) nDiffX = -nDiffX - aCaptRect.GetWidth(); long nDiffY = aCaptRect.Top() - rOldTailPos.Y(); aCaptRect.SetPos( aTailPos + Point( nDiffX, nDiffY ) ); // set new tail position and caption rectangle - mxCaption->SetTailPos( aTailPos ); - mxCaption->SetLogicRect( aCaptRect ); + m_pCaption->SetTailPos( aTailPos ); + m_pCaption->SetLogicRect( aCaptRect ); // fit caption into draw page FitCaptionToRect(); } // update cell position in caption user data - ScDrawObjData* pCaptData = ScDrawLayer::GetNoteCaptionData( mxCaption.get(), maPos.Tab() ); + ScDrawObjData* pCaptData = ScDrawLayer::GetNoteCaptionData( m_pCaption.get(), maPos.Tab() ); if( pCaptData && (maPos != pCaptData->maStart) ) { // create drawing undo action if( pDrawLayer && pDrawLayer->IsRecording() ) - pDrawLayer->AddCalcUndo( new ScUndoObjData( mxCaption.get(), pCaptData->maStart, pCaptData->maEnd, maPos, pCaptData->maEnd ) ); + pDrawLayer->AddCalcUndo( new ScUndoObjData( m_pCaption.get(), pCaptData->maStart, pCaptData->maEnd, maPos, pCaptData->maEnd ) ); // set new position pCaptData->maStart = maPos; } @@ -375,13 +376,22 @@ void ScCaptionCreator::CreateCaption( bool bShown, bool bTailFront ) // create the caption drawing object tools::Rectangle aTextRect( Point( 0 , 0 ), Size( SC_NOTECAPTION_WIDTH, SC_NOTECAPTION_HEIGHT ) ); Point aTailPos = CalcTailPos( bTailFront ); - mxCaption.reset( + m_pCaption.reset( new SdrCaptionObj( *mrDoc.GetDrawLayer(), // TTTT should ret a ref? aTextRect, - aTailPos)); + aTailPos), + [](SdrCaptionObj* pCaptionObj){ + SdrPage* pDrawPage(pCaptionObj->getSdrPageFromSdrObject()); + if (pDrawPage) + { + pDrawPage->RemoveObject(pCaptionObj->GetOrdNum()); + } + SdrObject* pObj = pCaptionObj; + SdrObject::Free(pObj); + }); // basic caption settings - ScCaptionUtil::SetBasicCaptionSettings( *mxCaption, bShown ); + ScCaptionUtil::SetBasicCaptionSettings( *m_pCaption, bShown ); } void ScCaptionCreator::Initialize() @@ -405,7 +415,7 @@ public: /** Create a new caption object and inserts it into the document. */ explicit ScNoteCaptionCreator( ScDocument& rDoc, const ScAddress& rPos, ScNoteData& rNoteData ); /** Manipulate an existing caption. */ - explicit ScNoteCaptionCreator( ScDocument& rDoc, const ScAddress& rPos, ScCaptionPtr& xCaption, bool bShown ); + explicit ScNoteCaptionCreator( ScDocument& rDoc, const ScAddress& rPos, const std::shared_ptr< SdrCaptionObj >& xCaption, bool bShown ); }; ScNoteCaptionCreator::ScNoteCaptionCreator( ScDocument& rDoc, const ScAddress& rPos, ScNoteData& rNoteData ) : @@ -417,340 +427,38 @@ ScNoteCaptionCreator::ScNoteCaptionCreator( ScDocument& rDoc, const ScAddress& r { // create the caption drawing object CreateCaption( rNoteData.mbShown, false ); - rNoteData.mxCaption = GetCaption(); - OSL_ENSURE( rNoteData.mxCaption, "ScNoteCaptionCreator::ScNoteCaptionCreator - missing caption object" ); - if( rNoteData.mxCaption ) + rNoteData.m_pCaption = GetCaption(); + OSL_ENSURE( rNoteData.m_pCaption, "ScNoteCaptionCreator::ScNoteCaptionCreator - missing caption object" ); + if( rNoteData.m_pCaption ) { // store note position in user data of caption object - ScCaptionUtil::SetCaptionUserData( *rNoteData.mxCaption, rPos ); + ScCaptionUtil::SetCaptionUserData( *rNoteData.m_pCaption, rPos ); // insert object into draw page - rNoteData.mxCaption.insertToDrawPage( *pDrawPage ); + pDrawPage->InsertObject( rNoteData.m_pCaption.get() ); } } } -ScNoteCaptionCreator::ScNoteCaptionCreator( ScDocument& rDoc, const ScAddress& rPos, ScCaptionPtr& xCaption, bool bShown ) : - ScCaptionCreator( rDoc, rPos, xCaption ) +ScNoteCaptionCreator::ScNoteCaptionCreator( ScDocument& rDoc, const ScAddress& rPos, const std::shared_ptr< SdrCaptionObj >& pCaption, bool bShown ) : + ScCaptionCreator( rDoc, rPos, pCaption ) { SdrPage* pDrawPage = GetDrawPage(); OSL_ENSURE( pDrawPage, "ScNoteCaptionCreator::ScNoteCaptionCreator - no drawing page" ); - OSL_ENSURE( xCaption->getSdrPageFromSdrObject() == pDrawPage, "ScNoteCaptionCreator::ScNoteCaptionCreator - wrong drawing page in caption" ); - if( pDrawPage && (xCaption->getSdrPageFromSdrObject() == pDrawPage) ) + OSL_ENSURE( pCaption->getSdrPageFromSdrObject() == pDrawPage, "ScNoteCaptionCreator::ScNoteCaptionCreator - wrong drawing page in caption" ); + if( pDrawPage && (pCaption->getSdrPageFromSdrObject() == pDrawPage) ) { // store note position in user data of caption object - ScCaptionUtil::SetCaptionUserData( *xCaption, rPos ); + ScCaptionUtil::SetCaptionUserData( *pCaption, rPos ); // basic caption settings - ScCaptionUtil::SetBasicCaptionSettings( *xCaption, bShown ); + ScCaptionUtil::SetBasicCaptionSettings( *pCaption, bShown ); // set correct tail position - xCaption->SetTailPos( CalcTailPos( false ) ); - } -} - -} // namespace - - -ScCaptionPtr::ScCaptionPtr() : - mpHead(nullptr), mpNext(nullptr), mpCaption(nullptr), mbNotOwner(false) -{ -} - -ScCaptionPtr::ScCaptionPtr( SdrCaptionObj* p ) : - mpHead(nullptr), mpNext(nullptr), mpCaption(p), mbNotOwner(false) -{ - if (p) - { - newHead(); + pCaption->SetTailPos( CalcTailPos( false ) ); } } -ScCaptionPtr::ScCaptionPtr( const ScCaptionPtr& r ) : - mpHead(r.mpHead), mpCaption(r.mpCaption), mbNotOwner(false) +void removeFromDrawPageAndFree( const std::shared_ptr< SdrCaptionObj >& pCaption, bool bIgnoreUndo = false ) { - if (r.mpCaption) - { - assert(r.mpHead); - r.incRef(); - // Insert into list. - mpNext = r.mpNext; - r.mpNext = this; - } - else - { - assert(!r.mpHead); - mpNext = nullptr; - } -} - -ScCaptionPtr::ScCaptionPtr( ScCaptionPtr&& r ) : - mpHead(r.mpHead), mpNext(r.mpNext), mpCaption(r.mpCaption), mbNotOwner(false) -{ - r.replaceInList( this ); - r.mpCaption = nullptr; - r.mbNotOwner = false; -} - -ScCaptionPtr& ScCaptionPtr::operator=( ScCaptionPtr&& r ) -{ - assert(this != &r); - - mpHead = r.mpHead; - mpNext = r.mpNext; - mpCaption = r.mpCaption; - mbNotOwner = r.mbNotOwner; - - r.replaceInList( this ); - r.mpCaption = nullptr; - r.mbNotOwner = false; - - return *this; -} - -ScCaptionPtr& ScCaptionPtr::operator=( const ScCaptionPtr& r ) -{ - if (this == &r) - return *this; - - if (mpCaption == r.mpCaption) - { - // Two lists for the same caption is bad. - assert(!mpCaption || mpHead == r.mpHead); - assert(!mpCaption); // assigning same caption pointer within same list is weird - // Nullptr captions are not inserted to the list, so nothing to do here - // if both are. - return *this; - } - - // Let's find some weird usage. - // Assigning without head doesn't make sense unless it is a nullptr caption. - assert(r.mpHead || !r.mpCaption); - // A nullptr caption must not be in a list and thus not have a head. - assert(!r.mpHead || r.mpCaption); - // Same captions were caught above, so here different heads must be present. - assert(r.mpHead != mpHead); - - r.incRef(); - decRefAndDestroy(); - removeFromList(); - - mpCaption = r.mpCaption; - mbNotOwner = r.mbNotOwner; - // That head is this' master. - mpHead = r.mpHead; - // Insert into list. - mpNext = r.mpNext; - r.mpNext = this; - - return *this; -} - -void ScCaptionPtr::setNotOwner() -{ - mbNotOwner = true; -} - -ScCaptionPtr::Head::Head( ScCaptionPtr* p ) : - mpFirst(p), mnRefs(1) -{ -} - -void ScCaptionPtr::newHead() -{ - assert(!mpHead); - mpHead = new Head(this); -} - -void ScCaptionPtr::replaceInList( ScCaptionPtr* pNew ) -{ - if (!mpHead && !mpNext) - return; - - assert(mpHead); - assert(mpCaption == pNew->mpCaption); - - ScCaptionPtr* pThat = mpHead->mpFirst; - while (pThat && pThat != this && pThat->mpNext != this) - { - pThat = pThat->mpNext; - } - if (pThat && pThat != this) - { - assert(pThat->mpNext == this); - pThat->mpNext = pNew; - } - pNew->mpNext = mpNext; - if (mpHead->mpFirst == this) - mpHead->mpFirst = pNew; - - mpHead = nullptr; - mpNext = nullptr; -} - -void ScCaptionPtr::removeFromList() -{ - if (!mpHead && !mpNext && !mpCaption) - return; - -#if OSL_DEBUG_LEVEL > 0 - oslInterlockedCount nCount = 0; -#endif - ScCaptionPtr* pThat = (mpHead ? mpHead->mpFirst : nullptr); - while (pThat && pThat != this && pThat->mpNext != this) - { - // Use the walk to check consistency on the fly. - assert(pThat->mpHead == mpHead); // all belong to the same - assert(pThat->mpHead || !pThat->mpNext); // next without head is bad - assert(pThat->mpCaption == mpCaption); - pThat = pThat->mpNext; -#if OSL_DEBUG_LEVEL > 0 - ++nCount; -#endif - } - assert(pThat || !mpHead); // not found only if this was standalone - if (pThat) - { - if (pThat != this) - { -#if OSL_DEBUG_LEVEL > 0 - // The while loop above was not executed, and for this - // (pThat->mpNext) the loop below won't either. - ++nCount; -#endif - pThat->mpNext = mpNext; - } -#if OSL_DEBUG_LEVEL > 0 - do - { - assert(pThat->mpHead == mpHead); // all belong to the same - assert(pThat->mpHead || !pThat->mpNext); // next without head is bad - assert(pThat->mpCaption == mpCaption); - ++nCount; - } - while ((pThat = pThat->mpNext) != nullptr); -#endif - } -#if OSL_DEBUG_LEVEL > 0 - // If part of a list then refs were already decremented. - assert(nCount == (mpHead ? mpHead->mnRefs + 1 : 0)); -#endif - if (mpHead && mpHead->mpFirst == this) - { - if (mpNext) - mpHead->mpFirst = mpNext; - else - { - // The only one destroys also head. - assert(mpHead->mnRefs == 0); // cough - delete mpHead; // DEAD now - } - } - mpHead = nullptr; - mpNext = nullptr; -} - -void ScCaptionPtr::reset( SdrCaptionObj* p ) -{ - assert(!p || p != mpCaption); -#if OSL_DEBUG_LEVEL > 0 - if (p) - { - // Check if we end up with a duplicated management in this list. - ScCaptionPtr* pThat = (mpHead ? mpHead->mpFirst : nullptr); - while (pThat) - { - assert(pThat->mpCaption != p); - pThat = pThat->mpNext; - } - } -#endif - decRefAndDestroy(); - removeFromList(); - mpCaption = p; - mbNotOwner = false; - if (p) - { - newHead(); - } -} - -ScCaptionPtr::~ScCaptionPtr() -{ - decRefAndDestroy(); - removeFromList(); -} - -oslInterlockedCount ScCaptionPtr::getRefs() const -{ - return mpHead ? mpHead->mnRefs : 0; -} - -void ScCaptionPtr::incRef() const -{ - if (mpHead) - osl_atomic_increment(&mpHead->mnRefs); -} - -bool ScCaptionPtr::decRef() const -{ - return mpHead && mpHead->mnRefs > 0 && !osl_atomic_decrement(&mpHead->mnRefs); -} - -void ScCaptionPtr::decRefAndDestroy() -{ - if (decRef()) - { - assert(mpHead->mpFirst == this); // this must be one and only one - assert(!mpNext); // this must be one and only one - assert(mpCaption); - -#if 0 - // Quick workaround for when there are still cases where the caption - // pointer is dangling - mpCaption = nullptr; - mbNotOwner = false; -#else - // Destroying Draw Undo and some other delete the SdrObject, don't - // attempt that twice. - if (mbNotOwner) - { - mpCaption = nullptr; - mbNotOwner = false; - } - else - { - removeFromDrawPageAndFree( true ); // ignoring Undo - if (mpCaption) - { - // There's no draw page associated so removeFromDrawPageAndFree() - // didn't do anything, but still we want to delete the caption - // object. release()/dissolve() also resets mpCaption. - SdrObject* pObj = release(); - SdrObject::Free( pObj ); - } - } -#endif - delete mpHead; - mpHead = nullptr; - } -} - -void ScCaptionPtr::insertToDrawPage( SdrPage& rDrawPage ) -{ - assert(mpHead && mpCaption); - - rDrawPage.InsertObject( mpCaption ); -} - -void ScCaptionPtr::removeFromDrawPage( SdrPage& rDrawPage ) -{ - assert(mpHead && mpCaption); - SdrObject* pObj = rDrawPage.RemoveObject( mpCaption->GetOrdNum() ); - assert(pObj == mpCaption); (void)pObj; -} - -void ScCaptionPtr::removeFromDrawPageAndFree( bool bIgnoreUndo ) -{ - assert(mpHead && mpCaption); - SdrPage* pDrawPage(mpCaption->getSdrPageFromSdrObject()); + SdrPage* pDrawPage(pCaption->getSdrPageFromSdrObject()); SAL_WARN_IF( !pDrawPage, "sc.core", "ScCaptionPtr::removeFromDrawPageAndFree - object without drawing page"); if (pDrawPage) { @@ -758,64 +466,19 @@ void ScCaptionPtr::removeFromDrawPageAndFree( bool bIgnoreUndo ) bool bRecording = false; if (!bIgnoreUndo) { - ScDrawLayer* pDrawLayer(dynamic_cast< ScDrawLayer* >(&mpCaption->getSdrModelFromSdrObject())); + ScDrawLayer* pDrawLayer(dynamic_cast< ScDrawLayer* >(&pCaption->getSdrModelFromSdrObject())); SAL_WARN_IF( !pDrawLayer, "sc.core", "ScCaptionPtr::removeFromDrawPageAndFree - object without drawing layer"); // create drawing undo action (before removing the object to have valid draw page in undo action) bRecording = (pDrawLayer && pDrawLayer->IsRecording()); if (bRecording) - pDrawLayer->AddCalcUndo( new SdrUndoDelObj( *mpCaption )); + pDrawLayer->AddCalcUndo( new ScUndoDelSdrCaptionObj( pCaption )); } // remove the object from the drawing page, delete if undo is disabled - removeFromDrawPage( *pDrawPage ); - // If called from outside mnRefs must be 1 to delete. If called from - // decRefAndDestroy() mnRefs is already 0. - if (!bRecording && getRefs() <= 1) - { - SdrObject* pObj = release(); - SdrObject::Free( pObj ); - } - } -} - -SdrCaptionObj* ScCaptionPtr::release() -{ - SdrCaptionObj* pTmp = mpCaption; - dissolve(); - return pTmp; -} - -void ScCaptionPtr::forget() -{ - decRef(); - removeFromList(); - mpCaption = nullptr; - mbNotOwner = false; -} - -void ScCaptionPtr::dissolve() -{ - ScCaptionPtr::Head* pHead = mpHead; - ScCaptionPtr* pThat = (mpHead ? mpHead->mpFirst : this); - while (pThat) - { - assert(!pThat->mpNext || pThat->mpHead); // next without head is bad - assert(pThat->mpHead == pHead); // same head required within one list - ScCaptionPtr* p = pThat->mpNext; - pThat->clear(); - pThat = p; + pDrawPage->RemoveObject( pCaption->GetOrdNum() ); } - assert(!mpHead && !mpNext && !mpCaption); // should had been cleared during list walk - delete pHead; -} - -void ScCaptionPtr::clear() -{ - mpHead = nullptr; - mpNext = nullptr; - mpCaption = nullptr; - mbNotOwner = false; } +} // namespace struct ScCaptionInitData { @@ -851,7 +514,7 @@ ScPostIt::ScPostIt( ScDocument& rDoc, const ScAddress& rPos, sal_uInt32 nPostItI { mnPostItId = nPostItId == 0 ? mnLastPostItId++ : nPostItId; AutoStamp(); - CreateCaption( rPos ); + CreateCaption( rPos, nullptr ); } ScPostIt::ScPostIt( ScDocument& rDoc, const ScAddress& rPos, const ScPostIt& rNote, sal_uInt32 nPostItId ) : @@ -859,8 +522,8 @@ ScPostIt::ScPostIt( ScDocument& rDoc, const ScAddress& rPos, const ScPostIt& rNo maNoteData( rNote.maNoteData ) { mnPostItId = nPostItId == 0 ? mnLastPostItId++ : nPostItId; - maNoteData.mxCaption.reset(nullptr); - CreateCaption( rPos, rNote.maNoteData.mxCaption.get() ); + maNoteData.m_pCaption.reset(); + CreateCaption( rPos, rNote.maNoteData.m_pCaption ); } ScPostIt::ScPostIt( ScDocument& rDoc, const ScAddress& rPos, const ScNoteData& rNoteData, bool bAlwaysCreateCaption, sal_uInt32 nPostItId ) : @@ -901,8 +564,8 @@ void ScPostIt::AutoStamp() const OutlinerParaObject* ScPostIt::GetOutlinerObject() const { - if( maNoteData.mxCaption ) - return maNoteData.mxCaption->GetOutlinerParaObject(); + if( maNoteData.m_pCaption ) + return maNoteData.m_pCaption->GetOutlinerParaObject(); if( maNoteData.mxInitData.get() ) return maNoteData.mxInitData->mxOutlinerObj.get(); return nullptr; @@ -947,14 +610,14 @@ bool ScPostIt::HasMultiLineText() const void ScPostIt::SetText( const ScAddress& rPos, const OUString& rText ) { CreateCaptionFromInitData( rPos ); - if( maNoteData.mxCaption ) - maNoteData.mxCaption->SetText( rText ); + if( maNoteData.m_pCaption ) + maNoteData.m_pCaption->SetText( rText ); } -SdrCaptionObj* ScPostIt::GetOrCreateCaption( const ScAddress& rPos ) const +const std::shared_ptr< SdrCaptionObj>& ScPostIt::GetOrCreateCaption( const ScAddress& rPos ) const { CreateCaptionFromInitData( rPos ); - return maNoteData.mxCaption.get(); + return maNoteData.m_pCaption; } void ScPostIt::ForgetCaption( bool bPreserveData ) @@ -974,13 +637,13 @@ void ScPostIt::ForgetCaption( bool bPreserveData ) pInitData->maSimpleText = GetText(); maNoteData.mxInitData.reset(pInitData); - maNoteData.mxCaption.forget(); + maNoteData.m_pCaption.reset(); } else { /* This function is used in undo actions to give up the responsibility for the caption object which is handled by separate drawing undo actions. */ - maNoteData.mxCaption.forget(); + maNoteData.m_pCaption.reset(); maNoteData.mxInitData.reset(); } } @@ -990,23 +653,23 @@ void ScPostIt::ShowCaption( const ScAddress& rPos, bool bShow ) CreateCaptionFromInitData( rPos ); // no separate drawing undo needed, handled completely inside ScUndoShowHideNote maNoteData.mbShown = bShow; - if( maNoteData.mxCaption ) - ScCaptionUtil::SetCaptionLayer( *maNoteData.mxCaption, bShow ); + if( maNoteData.m_pCaption ) + ScCaptionUtil::SetCaptionLayer( *maNoteData.m_pCaption, bShow ); } void ScPostIt::ShowCaptionTemp( const ScAddress& rPos, bool bShow ) { CreateCaptionFromInitData( rPos ); - if( maNoteData.mxCaption ) - ScCaptionUtil::SetCaptionLayer( *maNoteData.mxCaption, maNoteData.mbShown || bShow ); + if( maNoteData.m_pCaption ) + ScCaptionUtil::SetCaptionLayer( *maNoteData.m_pCaption, maNoteData.mbShown || bShow ); } void ScPostIt::UpdateCaptionPos( const ScAddress& rPos ) { CreateCaptionFromInitData( rPos ); - if( maNoteData.mxCaption ) + if( maNoteData.m_pCaption ) { - ScCaptionCreator aCreator( mrDoc, rPos, maNoteData.mxCaption ); + ScCaptionCreator aCreator( mrDoc, rPos, maNoteData.m_pCaption ); aCreator.UpdateCaptionPos(); } } @@ -1017,7 +680,7 @@ void ScPostIt::CreateCaptionFromInitData( const ScAddress& rPos ) const { // Captions are not created in Undo documents and only rarely in Clipboard, // but otherwise we need caption or initial data. - assert((maNoteData.mxCaption || maNoteData.mxInitData.get()) || mrDoc.IsUndo() || mrDoc.IsClipboard()); + assert((maNoteData.m_pCaption || maNoteData.mxInitData.get()) || mrDoc.IsUndo() || mrDoc.IsClipboard()); if( maNoteData.mxInitData.get() ) { /* This function is called from ScPostIt::Clone() when copying cells @@ -1027,22 +690,22 @@ void ScPostIt::CreateCaptionFromInitData( const ScAddress& rPos ) const been created already. However, for clipboard in case the originating document was destructed a new caption has to be created. */ - OSL_ENSURE( !mrDoc.IsUndo() && (!mrDoc.IsClipboard() || !maNoteData.mxCaption), + OSL_ENSURE( !mrDoc.IsUndo() && (!mrDoc.IsClipboard() || !maNoteData.m_pCaption), "ScPostIt::CreateCaptionFromInitData - note caption should not be created in undo/clip documents" ); /* #i104915# Never try to create notes in Undo document, leads to crash due to missing document members (e.g. row height array). */ - if( !maNoteData.mxCaption && !mrDoc.IsUndo() ) + if( !maNoteData.m_pCaption && !mrDoc.IsUndo() ) { if (mrDoc.IsClipboard()) mrDoc.InitDrawLayer(); // ensure there is a drawing layer // ScNoteCaptionCreator c'tor creates the caption and inserts it into the document and maNoteData ScNoteCaptionCreator aCreator( mrDoc, rPos, maNoteData ); - if( maNoteData.mxCaption ) + if( maNoteData.m_pCaption ) { // Prevent triple change broadcasts of the same object. - SdrDelayBroadcastObjectChange aDelayChange( *maNoteData.mxCaption); + SdrDelayBroadcastObjectChange aDelayChange( *maNoteData.m_pCaption); ScCaptionInitData& rInitData = *maNoteData.mxInitData; @@ -1050,22 +713,22 @@ void ScPostIt::CreateCaptionFromInitData( const ScAddress& rPos ) const OSL_ENSURE( rInitData.mxOutlinerObj.get() || !rInitData.maSimpleText.isEmpty(), "ScPostIt::CreateCaptionFromInitData - need either outliner para object or simple text" ); if( rInitData.mxOutlinerObj.get() ) - maNoteData.mxCaption->SetOutlinerParaObject( rInitData.mxOutlinerObj.release() ); + maNoteData.m_pCaption->SetOutlinerParaObject( rInitData.mxOutlinerObj.release() ); else - maNoteData.mxCaption->SetText( rInitData.maSimpleText ); + maNoteData.m_pCaption->SetText( rInitData.maSimpleText ); // copy all items or set default items; reset shadow items - ScCaptionUtil::SetDefaultItems( *maNoteData.mxCaption, mrDoc ); + ScCaptionUtil::SetDefaultItems( *maNoteData.m_pCaption, mrDoc ); if( rInitData.mxItemSet.get() ) - ScCaptionUtil::SetCaptionItems( *maNoteData.mxCaption, *rInitData.mxItemSet ); + ScCaptionUtil::SetCaptionItems( *maNoteData.m_pCaption, *rInitData.mxItemSet ); // set position and size of the caption object if( rInitData.mbDefaultPosSize ) { // set other items and fit caption size to text - maNoteData.mxCaption->SetMergedItem( makeSdrTextMinFrameWidthItem( SC_NOTECAPTION_WIDTH ) ); - maNoteData.mxCaption->SetMergedItem( makeSdrTextMaxFrameWidthItem( SC_NOTECAPTION_MAXWIDTH_TEMP ) ); - maNoteData.mxCaption->AdjustTextFrameWidthAndHeight(); + maNoteData.m_pCaption->SetMergedItem( makeSdrTextMinFrameWidthItem( SC_NOTECAPTION_WIDTH ) ); + maNoteData.m_pCaption->SetMergedItem( makeSdrTextMaxFrameWidthItem( SC_NOTECAPTION_MAXWIDTH_TEMP ) ); + maNoteData.m_pCaption->AdjustTextFrameWidthAndHeight(); aCreator.AutoPlaceCaption(); } else @@ -1075,7 +738,7 @@ void ScPostIt::CreateCaptionFromInitData( const ScAddress& rPos ) const long nPosX = bNegPage ? (aCellRect.Left() - rInitData.maCaptionOffset.X()) : (aCellRect.Right() + rInitData.maCaptionOffset.X()); long nPosY = aCellRect.Top() + rInitData.maCaptionOffset.Y(); tools::Rectangle aCaptRect( Point( nPosX, nPosY ), rInitData.maCaptionSize ); - maNoteData.mxCaption->SetLogicRect( aCaptRect ); + maNoteData.m_pCaption->SetLogicRect( aCaptRect ); aCreator.FitCaptionToRect(); } } @@ -1085,10 +748,10 @@ void ScPostIt::CreateCaptionFromInitData( const ScAddress& rPos ) const } } -void ScPostIt::CreateCaption( const ScAddress& rPos, const SdrCaptionObj* pCaption ) +void ScPostIt::CreateCaption( const ScAddress& rPos, const std::shared_ptr< SdrCaptionObj >& pCaption ) { - OSL_ENSURE( !maNoteData.mxCaption, "ScPostIt::CreateCaption - unexpected caption object found" ); - maNoteData.mxCaption.reset(nullptr); + OSL_ENSURE( !maNoteData.m_pCaption, "ScPostIt::CreateCaption - unexpected caption object found" ); + maNoteData.m_pCaption.reset(); /* #i104915# Never try to create notes in Undo document, leads to crash due to missing document members (e.g. row height array). */ @@ -1102,40 +765,40 @@ void ScPostIt::CreateCaption( const ScAddress& rPos, const SdrCaptionObj* pCapti // ScNoteCaptionCreator c'tor creates the caption and inserts it into the document and maNoteData ScNoteCaptionCreator aCreator( mrDoc, rPos, maNoteData ); - if( maNoteData.mxCaption ) + if( maNoteData.m_pCaption ) { // clone settings of passed caption if( pCaption ) { // copy edit text object (object must be inserted into page already) if( OutlinerParaObject* pOPO = pCaption->GetOutlinerParaObject() ) - maNoteData.mxCaption->SetOutlinerParaObject( new OutlinerParaObject( *pOPO ) ); + maNoteData.m_pCaption->SetOutlinerParaObject( new OutlinerParaObject( *pOPO ) ); // copy formatting items (after text has been copied to apply font formatting) - maNoteData.mxCaption->SetMergedItemSetAndBroadcast( pCaption->GetMergedItemSet() ); + maNoteData.m_pCaption->SetMergedItemSetAndBroadcast( pCaption->GetMergedItemSet() ); // move textbox position relative to new cell, copy textbox size tools::Rectangle aCaptRect = pCaption->GetLogicRect(); - Point aDist = maNoteData.mxCaption->GetTailPos() - pCaption->GetTailPos(); + Point aDist = maNoteData.m_pCaption->GetTailPos() - pCaption->GetTailPos(); aCaptRect.Move( aDist.X(), aDist.Y() ); - maNoteData.mxCaption->SetLogicRect( aCaptRect ); + maNoteData.m_pCaption->SetLogicRect( aCaptRect ); aCreator.FitCaptionToRect(); } else { // set default formatting and default position - ScCaptionUtil::SetDefaultItems( *maNoteData.mxCaption, mrDoc ); + ScCaptionUtil::SetDefaultItems( *maNoteData.m_pCaption, mrDoc ); aCreator.AutoPlaceCaption(); } // create undo action if( ScDrawLayer* pDrawLayer = mrDoc.GetDrawLayer() ) if( pDrawLayer->IsRecording() ) - pDrawLayer->AddCalcUndo( new SdrUndoNewObj( *maNoteData.mxCaption ) ); + pDrawLayer->AddCalcUndo( new ScUndoNewSdrCaptionObj( maNoteData.m_pCaption ) ); } } void ScPostIt::RemoveCaption() { - if (!maNoteData.mxCaption) + if (!maNoteData.m_pCaption) return; /* Remove caption object only, if this note is its owner (e.g. notes in @@ -1143,28 +806,19 @@ void ScPostIt::RemoveCaption() them from drawing layer here). */ // TTTT maybe no longer needed - can that still happen? ScDrawLayer* pDrawLayer = mrDoc.GetDrawLayer(); - if (pDrawLayer == &maNoteData.mxCaption->getSdrModelFromSdrObject()) - maNoteData.mxCaption.removeFromDrawPageAndFree(); - - SAL_INFO("sc.core","ScPostIt::RemoveCaption - refs: " << maNoteData.mxCaption.getRefs() << - " IsUndo: " << mrDoc.IsUndo() << " IsClip: " << mrDoc.IsClipboard() << - " Dtor: " << mrDoc.IsInDtorClear()); + if (pDrawLayer == &maNoteData.m_pCaption->getSdrModelFromSdrObject()) + removeFromDrawPageAndFree(maNoteData.m_pCaption); - // Forget the caption object if removeFromDrawPageAndFree() did not free it. - if (maNoteData.mxCaption) - { - SAL_INFO("sc.core","ScPostIt::RemoveCaption - forgetting one ref"); - maNoteData.mxCaption.forget(); - } + maNoteData.m_pCaption.reset(); } -ScCaptionPtr ScNoteUtil::CreateTempCaption( +std::shared_ptr< SdrCaptionObj > ScNoteUtil::CreateTempCaption( ScDocument& rDoc, const ScAddress& rPos, SdrPage& rDrawPage, const OUString& rUserText, const tools::Rectangle& rVisRect, bool bTailFront ) { OUStringBuffer aBuffer( rUserText ); // add plain text of invisible (!) cell note (no formatting etc.) - SdrCaptionObj* pNoteCaption = nullptr; + std::shared_ptr< SdrCaptionObj > pNoteCaption = nullptr; const ScPostIt* pNote = rDoc.GetNote( rPos ); if( pNote && !pNote->IsCaptionShown() ) { @@ -1175,7 +829,7 @@ ScCaptionPtr ScNoteUtil::CreateTempCaption( // create a caption if any text exists if( !pNoteCaption && aBuffer.isEmpty() ) - return ScCaptionPtr(); + return std::shared_ptr< SdrCaptionObj >(); // prepare visible rectangle (add default distance to all borders) tools::Rectangle aVisRect( @@ -1188,7 +842,7 @@ ScCaptionPtr ScNoteUtil::CreateTempCaption( ScCaptionCreator aCreator( rDoc, rPos, bTailFront ); // insert caption into page (needed to set caption text) - aCreator.GetCaption().insertToDrawPage( rDrawPage ); + rDrawPage.InsertObject( aCreator.GetCaption().get() ); SdrCaptionObj* pCaption = aCreator.GetCaption().get(); // just for ease of use @@ -1227,14 +881,22 @@ ScPostIt* ScNoteUtil::CreateNoteFromCaption( ScDocument& rDoc, const ScAddress& rPos, SdrCaptionObj* pCaption ) { ScNoteData aNoteData( true/*bShown*/ ); - aNoteData.mxCaption.reset( pCaption ); + aNoteData.m_pCaption.reset(pCaption, [](SdrCaptionObj* pCaptionObj) { + SdrPage* pDrawPage(pCaptionObj->getSdrPageFromSdrObject()); + if (pDrawPage) + { + pDrawPage->RemoveObject(pCaptionObj->GetOrdNum()); + } + SdrObject* pObj = pCaptionObj; + SdrObject::Free(pObj); + }); ScPostIt* pNote = new ScPostIt( rDoc, rPos, aNoteData, false ); pNote->AutoStamp(); rDoc.SetNote(rPos, pNote); // ScNoteCaptionCreator c'tor updates the caption object to be part of a note - ScNoteCaptionCreator aCreator( rDoc, rPos, aNoteData.mxCaption, true/*bShown*/ ); + ScNoteCaptionCreator aCreator( rDoc, rPos, aNoteData.m_pCaption, true/*bShown*/ ); return pNote; } diff --git a/sc/source/core/tool/detfunc.cxx b/sc/source/core/tool/detfunc.cxx index 0703baa363a3..a356ee396c09 100644 --- a/sc/source/core/tool/detfunc.cxx +++ b/sc/source/core/tool/detfunc.cxx @@ -1425,7 +1425,7 @@ void ScDetectiveFunc::UpdateAllComments( ScDocument& rDoc ) { ScPostIt* pNote = rDoc.GetNote( pData->maStart ); // caption should exist, we iterate over drawing objects... - OSL_ENSURE( pNote && (pNote->GetCaption() == pObject), "ScDetectiveFunc::UpdateAllComments - invalid cell note" ); + OSL_ENSURE( pNote && (pNote->GetCaption().get() == pObject), "ScDetectiveFunc::UpdateAllComments - invalid cell note" ); if( pNote ) { ScCommentData aData( rDoc, pModel ); diff --git a/sc/source/filter/excel/xeescher.cxx b/sc/source/filter/excel/xeescher.cxx index 4c3728691c98..c2e9aba3b175 100644 --- a/sc/source/filter/excel/xeescher.cxx +++ b/sc/source/filter/excel/xeescher.cxx @@ -1196,7 +1196,7 @@ XclExpNote::XclExpNote(const XclExpRoot& rRoot, const ScAddress& rScPos, // TODO: additional text if( pScNote ) { - if( SdrCaptionObj* pCaption = pScNote->GetOrCreateCaption( maScPos ) ) + if( SdrCaptionObj* pCaption = pScNote->GetOrCreateCaption( maScPos ).get() ) { lcl_GetFromTo( rRoot, pCaption->GetLogicRect(), maScPos.Tab(), maCommentFrom, maCommentTo ); if( const OutlinerParaObject* pOPO = pCaption->GetOutlinerParaObject() ) diff --git a/sc/source/filter/xml/xmlexprt.cxx b/sc/source/filter/xml/xmlexprt.cxx index 6e5c2b49bbe7..bcfe73fe22d8 100644 --- a/sc/source/filter/xml/xmlexprt.cxx +++ b/sc/source/filter/xml/xmlexprt.cxx @@ -2406,7 +2406,7 @@ void ScXMLExport::ExportAutoStyles_() OSL_ENSURE( pNote, "note not found" ); if (pNote) { - SdrCaptionObj* pDrawObj = pNote->GetOrCreateCaption( aPos ); + std::shared_ptr< SdrCaptionObj > pDrawObj = pNote->GetOrCreateCaption( aPos ); // all uno shapes are created anyway in CollectSharedData uno::Reference xShapeProperties( pDrawObj->getUnoShape(), uno::UNO_QUERY ); if (xShapeProperties.is()) @@ -2450,7 +2450,7 @@ void ScXMLExport::ExportAutoStyles_() OSL_ENSURE( pNote, "note not found" ); if (pNote) { - SdrCaptionObj* pDrawObj = pNote->GetOrCreateCaption( aPos ); + std::shared_ptr< SdrCaptionObj > pDrawObj = pNote->GetOrCreateCaption( aPos ); uno::Reference xCellText(pDrawObj->getUnoShape(), uno::UNO_QUERY); uno::Reference xParaProp( lcl_GetEnumerated( xCellText, aNoteParaIter->maSelection.nStartPara ), uno::UNO_QUERY ); @@ -2484,7 +2484,7 @@ void ScXMLExport::ExportAutoStyles_() OSL_ENSURE( pNote, "note not found" ); if (pNote) { - SdrCaptionObj* pDrawObj = pNote->GetOrCreateCaption( aPos ); + std::shared_ptr< SdrCaptionObj > pDrawObj = pNote->GetOrCreateCaption( aPos ); uno::Reference xCellText(pDrawObj->getUnoShape(), uno::UNO_QUERY); uno::Reference xCursorProp(xCellText->createTextCursor(), uno::UNO_QUERY); ScDrawTextCursor* pCursor = ScDrawTextCursor::getImplementation( xCursorProp ); @@ -3617,7 +3617,7 @@ void ScXMLExport::exportAnnotationMeta( const uno::Reference < drawing::XShape > // TODO : notes //is it still useful, as this call back is only called from ScXMLExport::WriteAnnotation // and should be in sync with pCurrentCell - SdrCaptionObj* pNoteCaption = pNote->GetOrCreateCaption(pCurrentCell->maCellAddress); + std::shared_ptr< SdrCaptionObj > pNoteCaption = pNote->GetOrCreateCaption(pCurrentCell->maCellAddress); uno::Reference xCurrentShape( pNoteCaption->getUnoShape(), uno::UNO_QUERY ); if (xCurrentShape.get()!=xShape.get()) return; @@ -3674,7 +3674,7 @@ void ScXMLExport::WriteAnnotation(ScMyCell& rMyCell) pCurrentCell = &rMyCell; - SdrCaptionObj* pNoteCaption = pNote->GetOrCreateCaption(rMyCell.maCellAddress); + std::shared_ptr< SdrCaptionObj > pNoteCaption = pNote->GetOrCreateCaption(rMyCell.maCellAddress); if (pNoteCaption) { uno::Reference xShape( pNoteCaption->getUnoShape(), uno::UNO_QUERY ); diff --git a/sc/source/ui/app/scmod.cxx b/sc/source/ui/app/scmod.cxx index c0f8a33b8367..687ced15ef33 100644 --- a/sc/source/ui/app/scmod.cxx +++ b/sc/source/ui/app/scmod.cxx @@ -659,34 +659,6 @@ void ScModule::SetDragJump( m_pDragData->aJumpText = rText; } -ScDocument* ScModule::GetClipDoc() -{ - // called from document - SfxViewFrame* pViewFrame = nullptr; - ScTabViewShell* pViewShell = nullptr; - css::uno::Reference xTransferable; - - if ((pViewShell = dynamic_cast(SfxViewShell::Current()))) - xTransferable.set(pViewShell->GetClipData()); - else if ((pViewShell = dynamic_cast(SfxViewShell::GetFirst()))) - xTransferable.set(pViewShell->GetClipData()); - else if ((pViewFrame = SfxViewFrame::GetFirst())) - { - css::uno::Reference xClipboard = - pViewFrame->GetWindow().GetClipboard(); - xTransferable.set(xClipboard.is() ? xClipboard->getContents() : nullptr, css::uno::UNO_QUERY); - } - - const ScTransferObj* pObj = ScTransferObj::GetOwnClipboard(xTransferable); - if (pObj) - { - ScDocument* pDoc = pObj->GetDocument(); - assert((!pDoc || pDoc->IsClipboard()) && "Document is not clipboard, how can that be?"); - return pDoc; - } - - return nullptr; -} void ScModule::SetSelectionTransfer( ScSelectionTransferObj* pNew ) { diff --git a/sc/source/ui/docshell/docfunc.cxx b/sc/source/ui/docshell/docfunc.cxx index 3908a1a35279..518410f25f47 100644 --- a/sc/source/ui/docshell/docfunc.cxx +++ b/sc/source/ui/docshell/docfunc.cxx @@ -1206,7 +1206,7 @@ bool ScDocFunc::ShowNote( const ScAddress& rPos, bool bShow ) if (ScViewData* pViewData = ScDocShell::GetViewData()) { if (ScDrawView* pDrawView = pViewData->GetScDrawView()) - pDrawView->SyncForGrid( pNote->GetCaption()); + pDrawView->SyncForGrid( pNote->GetCaption().get() ); } rDocShell.SetDocumentModified(); @@ -1282,7 +1282,7 @@ void ScDocFunc::ReplaceNote( const ScAddress& rPos, const OUString& rNoteText, c } // create the undo action - if( pUndoMgr && (aOldData.mxCaption || aNewData.mxCaption) ) + if( pUndoMgr && (aOldData.m_pCaption || aNewData.m_pCaption) ) pUndoMgr->AddUndoAction( new ScUndoReplaceNote( rDocShell, rPos, aOldData, aNewData, pDrawLayer->GetCalcUndo().release() ) ); // repaint cell (to make note marker visible) diff --git a/sc/source/ui/docshell/docsh.cxx b/sc/source/ui/docshell/docsh.cxx index b0c10dd0989b..40d6107accb5 100644 --- a/sc/source/ui/docshell/docsh.cxx +++ b/sc/source/ui/docshell/docsh.cxx @@ -114,6 +114,7 @@ #include #include #include +#include #include #include "docshimp.hxx" #include @@ -1076,7 +1077,7 @@ void ScDocShell::Notify( SfxBroadcaster&, const SfxHint& rHint ) // document's drawing layer pages and what not, which otherwise when // pasting to another document after this document was destructed would // attempt to access non-existing data. Preserve the text data though. - ScDocument* pClipDoc = ScModule::GetClipDoc(); + ScDocument* pClipDoc = GetClipDoc(); if (pClipDoc) pClipDoc->ClosingClipboardSource(); } @@ -2783,6 +2784,36 @@ ScDocFunc *ScDocShell::CreateDocFunc() return new ScDocFuncDirect( *this ); } +ScDocument* ScDocShell::GetClipDoc() +{ + css::uno::Reference xTransferable; + + if (ScTabViewShell* pViewShell = GetBestViewShell()) + xTransferable.set(pViewShell->GetClipData()); + else + { + SfxViewFrame* pViewFrame = nullptr; + css::uno::Reference xClipboard; + + if ((pViewFrame = SfxViewFrame::GetFirst(this, false))) + xClipboard = pViewFrame->GetWindow().GetClipboard(); + else if ((pViewFrame = SfxViewFrame::GetFirst())) + xClipboard = pViewFrame->GetWindow().GetClipboard(); + + xTransferable.set(xClipboard.is() ? xClipboard->getContents() : nullptr, css::uno::UNO_QUERY); + } + + const ScTransferObj* pObj = ScTransferObj::GetOwnClipboard(xTransferable); + if (pObj) + { + ScDocument* pDoc = pObj->GetDocument(); + assert((!pDoc || pDoc->IsClipboard()) && "Document is not clipboard, how can that be?"); + return pDoc; + } + + return nullptr; +} + ScDocShell::ScDocShell( const ScDocShell& rShell ) : SvRefBase(), SotObject(), diff --git a/sc/source/ui/drawfunc/futext3.cxx b/sc/source/ui/drawfunc/futext3.cxx index a9e243fb3583..4a003558c88d 100644 --- a/sc/source/ui/drawfunc/futext3.cxx +++ b/sc/source/ui/drawfunc/futext3.cxx @@ -68,7 +68,7 @@ void FuText::StopEditMode() { aNotePos = pCaptData->maStart; pNote = rDoc.GetNote( aNotePos ); - OSL_ENSURE( pNote && (pNote->GetCaption() == pObject), "FuText::StopEditMode - missing or invalid cell note" ); + OSL_ENSURE( pNote && (pNote->GetCaption().get() == pObject), "FuText::StopEditMode - missing or invalid cell note" ); } ScDocShell* pDocShell = rViewData.GetDocShell(); @@ -88,7 +88,7 @@ void FuText::StopEditMode() /* Note has been created before editing, if first undo action is an insert action. Needed below to decide whether to drop the undo if editing a new note has been cancelled. */ - bNewNote = (pCalcUndo->GetActionCount() > 0) && dynamic_cast< SdrUndoNewObj* >(pCalcUndo->GetAction( 0 )); + bNewNote = (pCalcUndo->GetActionCount() > 0) && dynamic_cast< ScUndoNewSdrCaptionObj* >(pCalcUndo->GetAction( 0 )); // create a "insert note" undo action if needed if( bNewNote ) diff --git a/sc/source/ui/inc/docsh.hxx b/sc/source/ui/inc/docsh.hxx index d65b09772a75..6082dee5bc6f 100644 --- a/sc/source/ui/inc/docsh.hxx +++ b/sc/source/ui/inc/docsh.hxx @@ -379,6 +379,8 @@ public: ScTabViewShell* GetBestViewShell( bool bOnlyVisible = true ); + ScDocument* GetClipDoc(); + void SetDocumentModifiedPending( bool bVal ) { m_bDocumentModifiedPending = bVal; } bool IsDocumentModifiedPending() const diff --git a/sc/source/ui/inc/notemark.hxx b/sc/source/ui/inc/notemark.hxx index e0e723c624c3..a8305316e2d4 100644 --- a/sc/source/ui/inc/notemark.hxx +++ b/sc/source/ui/inc/notemark.hxx @@ -48,7 +48,7 @@ private: tools::Rectangle m_aRect; ScDrawView* m_pDrawView; SdrModel* m_pModel; - ScCaptionPtr m_xObject; + std::shared_ptr< SdrCaptionObj > m_xObject; bool m_bVisible; DECL_LINK( TimeHdl, Timer*, void ); diff --git a/sc/source/ui/inc/undocell.hxx b/sc/source/ui/inc/undocell.hxx index 67306e5d6e71..695c36f609d0 100644 --- a/sc/source/ui/inc/undocell.hxx +++ b/sc/source/ui/inc/undocell.hxx @@ -42,6 +42,51 @@ class CellValues; } +class ScUndoSdrCaptionObj: public SdrUndoAction +{ +protected: + SdrObjList* m_pObjList; + sal_uInt32 m_nOrdNum; + std::shared_ptr< SdrCaptionObj > m_pCaptionObj; + + void UnmarkObject(); + void BroadcastSwitchToPage(); + OUString GetDescriptionString( const char* pStrCacheID, bool bRepeat = false ) const; + +public: + ScUndoSdrCaptionObj(const std::shared_ptr< SdrCaptionObj >&); + virtual ~ScUndoSdrCaptionObj() override; +}; + +class ScUndoDelSdrCaptionObj: public ScUndoSdrCaptionObj +{ +public: + ScUndoDelSdrCaptionObj(const std::shared_ptr< SdrCaptionObj >& pCaptionObj); + virtual ~ScUndoDelSdrCaptionObj() override; + + virtual void Undo() override; + virtual void Redo() override; + + virtual OUString GetComment() const override; + virtual OUString GetSdrRepeatComment(SdrView& rView) const override; + + virtual void SdrRepeat(SdrView& rView) override; + virtual bool CanSdrRepeat(SdrView& rView) const override; +}; + + +class ScUndoNewSdrCaptionObj: public ScUndoSdrCaptionObj +{ +public: + ScUndoNewSdrCaptionObj(const std::shared_ptr< SdrCaptionObj >& pCaptionObj); + virtual ~ScUndoNewSdrCaptionObj() override; + + virtual void Undo() override; + virtual void Redo() override; + + virtual OUString GetComment() const override; +}; + class ScUndoCursorAttr: public ScSimpleUndo { public: diff --git a/sc/source/ui/undo/undocell.cxx b/sc/source/ui/undo/undocell.cxx index fc9015daff20..04048d8ef96e 100644 --- a/sc/source/ui/undo/undocell.cxx +++ b/sc/source/ui/undo/undocell.cxx @@ -25,6 +25,12 @@ #include #include #include +#include +#include +#include +#include +#include +#include #include #include @@ -715,22 +721,183 @@ bool ScUndoThesaurus::CanRepeat(SfxRepeatTarget& rTarget) const return dynamic_cast( &rTarget) != nullptr; } + +ScUndoSdrCaptionObj::ScUndoSdrCaptionObj(const std::shared_ptr< SdrCaptionObj >& pCaptionObj) + : SdrUndoAction(pCaptionObj->getSdrModelFromSdrObject()) + , m_pObjList(pCaptionObj->getParentSdrObjListFromSdrObject()) + , m_nOrdNum(pCaptionObj->GetOrdNum()) + , m_pCaptionObj(pCaptionObj) +{ +} + +ScUndoSdrCaptionObj::~ScUndoSdrCaptionObj() +{ +} + +void ScUndoSdrCaptionObj::BroadcastSwitchToPage() +{ + if (m_pCaptionObj && m_pCaptionObj->IsInserted() && m_pCaptionObj->getSdrPageFromSdrObject()) + { + SdrHint aHint(SdrHintKind::SwitchToPage, *m_pCaptionObj, m_pCaptionObj->getSdrPageFromSdrObject()); + rMod.Broadcast(aHint); + } +} + +void ScUndoSdrCaptionObj::UnmarkObject() +{ + SdrViewIter aIter( m_pCaptionObj.get() ); + for ( SdrView* pView = aIter.FirstView(); pView; pView = aIter.NextView() ) + { + pView->MarkObj( m_pCaptionObj.get(), pView->GetSdrPageView(), true ); + } +} + +OUString ScUndoSdrCaptionObj::GetDescriptionString(const char* pStrCacheID, bool bRepeat ) const +{ + const OUString rStr {SvxResId(pStrCacheID)}; + + const sal_Int32 nPos = rStr.indexOf("%1"); + if (nPos < 0) + return rStr; + + if (bRepeat) + return rStr.replaceAt(nPos, 2, SvxResId(STR_ObjNameSingulPlural)); + + return rStr.replaceAt(nPos, 2, m_pCaptionObj->TakeObjNameSingul()); +} + +ScUndoDelSdrCaptionObj::ScUndoDelSdrCaptionObj(const std::shared_ptr< SdrCaptionObj >& pCaptionObj) + : ScUndoSdrCaptionObj(pCaptionObj) +{ +} + +ScUndoDelSdrCaptionObj::~ScUndoDelSdrCaptionObj() +{ + +} + +void ScUndoDelSdrCaptionObj::Undo() +{ + // Trigger PageChangeCall + BroadcastSwitchToPage(); + + if (!m_pCaptionObj->IsInserted()) + { + Point aOwnerAnchorPos(0, 0); + + if (dynamic_cast< const SdrObjGroup* >(m_pObjList->getSdrObjectFromSdrObjList()) != nullptr) + { + aOwnerAnchorPos = m_pObjList->getSdrObjectFromSdrObjList()->GetAnchorPos(); + } + + E3DModifySceneSnapRectUpdater aUpdater(m_pObjList->getSdrObjectFromSdrObjList()); + m_pObjList->InsertObject(m_pCaptionObj.get(), m_nOrdNum); + + if(aOwnerAnchorPos.X() || aOwnerAnchorPos.Y()) + { + m_pCaptionObj->NbcSetAnchorPos(aOwnerAnchorPos); + } + } + +} + +void ScUndoDelSdrCaptionObj::Redo() +{ + if (m_pCaptionObj->IsInserted()) + { + UnmarkObject(); + E3DModifySceneSnapRectUpdater aUpdater(m_pCaptionObj.get()); + m_pObjList->RemoveObject(m_nOrdNum); + } + + // Trigger PageChangeCall + BroadcastSwitchToPage(); +} + +OUString ScUndoDelSdrCaptionObj::GetComment() const +{ + return GetDescriptionString(STR_EditDelete); +} + +void ScUndoDelSdrCaptionObj::SdrRepeat(SdrView& rView) +{ + rView.DeleteMarked(); +} + +bool ScUndoDelSdrCaptionObj::CanSdrRepeat(SdrView& rView) const +{ + return rView.AreObjectsMarked(); +} + +OUString ScUndoDelSdrCaptionObj::GetSdrRepeatComment(SdrView& /*rView*/) const +{ + return GetDescriptionString(STR_EditDelete, true); +} + +ScUndoNewSdrCaptionObj::ScUndoNewSdrCaptionObj(const std::shared_ptr< SdrCaptionObj >& pCaptionObj) + : ScUndoSdrCaptionObj(pCaptionObj) +{ +} + +ScUndoNewSdrCaptionObj::~ScUndoNewSdrCaptionObj() +{ +} + +void ScUndoNewSdrCaptionObj::Undo() +{ + // Trigger PageChangeCall + BroadcastSwitchToPage(); + + if (m_pCaptionObj->IsInserted()) + { + UnmarkObject(); + m_pObjList->RemoveObject(m_nOrdNum); + } +} + +void ScUndoNewSdrCaptionObj::Redo() +{ + if (!m_pCaptionObj->IsInserted()) + { + Point aAnchorPos( 0, 0 ); + + if (dynamic_cast(m_pObjList->getSdrObjectFromSdrObjList()) != nullptr) + { + aAnchorPos = m_pCaptionObj->GetAnchorPos(); + } + + m_pObjList->InsertObject(m_pCaptionObj.get(), m_nOrdNum); + + // Arcs lose position when grouped (#i45952#) + if ( aAnchorPos.X() || aAnchorPos.Y() ) + { + m_pCaptionObj->NbcSetAnchorPos( aAnchorPos ); + } + } + + // Trigger PageChangeCall + BroadcastSwitchToPage(); +} + +OUString ScUndoNewSdrCaptionObj::GetComment() const +{ + return GetDescriptionString(STR_UndoInsertObj); +} + ScUndoReplaceNote::ScUndoReplaceNote( ScDocShell& rDocShell, const ScAddress& rPos, const ScNoteData& rNoteData, bool bInsert, SdrUndoAction* pDrawUndo ) : ScSimpleUndo( &rDocShell ), maPos( rPos ), mpDrawUndo( pDrawUndo ) { - OSL_ENSURE( rNoteData.mxCaption, "ScUndoReplaceNote::ScUndoReplaceNote - missing note caption" ); + OSL_ENSURE( rNoteData.m_pCaption, "ScUndoReplaceNote::ScUndoReplaceNote - missing note caption" ); if (bInsert) { maNewData = rNoteData; - maNewData.mxCaption.setNotOwner(); } else { maOldData = rNoteData; - maOldData.mxCaption.setNotOwner(); } } @@ -742,10 +909,8 @@ ScUndoReplaceNote::ScUndoReplaceNote( ScDocShell& rDocShell, const ScAddress& rP maNewData( rNewData ), mpDrawUndo( pDrawUndo ) { - OSL_ENSURE( maOldData.mxCaption || maNewData.mxCaption, "ScUndoReplaceNote::ScUndoReplaceNote - missing note captions" ); + OSL_ENSURE( maOldData.m_pCaption || maNewData.m_pCaption, "ScUndoReplaceNote::ScUndoReplaceNote - missing note captions" ); OSL_ENSURE( !maOldData.mxInitData.get() && !maNewData.mxInitData.get(), "ScUndoReplaceNote::ScUndoReplaceNote - unexpected uninitialized note" ); - maOldData.mxCaption.setNotOwner(); - maNewData.mxCaption.setNotOwner(); } ScUndoReplaceNote::~ScUndoReplaceNote() @@ -790,13 +955,13 @@ bool ScUndoReplaceNote::CanRepeat( SfxRepeatTarget& /*rTarget*/ ) const OUString ScUndoReplaceNote::GetComment() const { - return ScResId( maNewData.mxCaption ? - (maOldData.mxCaption ? STR_UNDO_EDITNOTE : STR_UNDO_INSERTNOTE) : STR_UNDO_DELETENOTE ); + return ScResId( maNewData.m_pCaption ? + (maOldData.m_pCaption ? STR_UNDO_EDITNOTE : STR_UNDO_INSERTNOTE) : STR_UNDO_DELETENOTE ); } void ScUndoReplaceNote::DoInsertNote( const ScNoteData& rNoteData ) { - if( rNoteData.mxCaption ) + if( rNoteData.m_pCaption ) { ScDocument& rDoc = pDocShell->GetDocument(); OSL_ENSURE( !rDoc.GetNote(maPos), "ScUndoReplaceNote::DoInsertNote - unexpected cell note" ); @@ -808,7 +973,7 @@ void ScUndoReplaceNote::DoInsertNote( const ScNoteData& rNoteData ) void ScUndoReplaceNote::DoRemoveNote( const ScNoteData& rNoteData ) { - if( rNoteData.mxCaption ) + if( rNoteData.m_pCaption ) { ScDocument& rDoc = pDocShell->GetDocument(); OSL_ENSURE( rDoc.GetNote(maPos), "ScUndoReplaceNote::DoRemoveNote - missing cell note" ); diff --git a/sc/source/ui/unoobj/editsrc.cxx b/sc/source/ui/unoobj/editsrc.cxx index fb59b24b328e..2989c6aed34a 100644 --- a/sc/source/ui/unoobj/editsrc.cxx +++ b/sc/source/ui/unoobj/editsrc.cxx @@ -137,7 +137,7 @@ std::unique_ptr ScAnnotationEditSource::Clone() const SdrObject* ScAnnotationEditSource::GetCaptionObj() { ScPostIt* pNote = pDocShell->GetDocument().GetNote(aCellPos); - return pNote ? pNote->GetOrCreateCaption( aCellPos ) : nullptr; + return pNote ? pNote->GetOrCreateCaption( aCellPos ).get() : nullptr; } SvxTextForwarder* ScAnnotationEditSource::GetTextForwarder() diff --git a/sc/source/ui/unoobj/notesuno.cxx b/sc/source/ui/unoobj/notesuno.cxx index 12e44a040e85..796ed043e3e6 100644 --- a/sc/source/ui/unoobj/notesuno.cxx +++ b/sc/source/ui/unoobj/notesuno.cxx @@ -216,7 +216,7 @@ uno::Reference < drawing::XShape > SAL_CALL ScAnnotationObj::getAnnotationShape( SolarMutexGuard aGuard; uno::Reference < drawing::XShape > xShape; if( const ScPostIt* pNote = ImplGetNote() ) - if( SdrObject* pCaption = pNote->GetOrCreateCaption( aCellPos ) ) + if( SdrObject* pCaption = pNote->GetOrCreateCaption( aCellPos ).get() ) xShape.set( pCaption->getUnoShape(), uno::UNO_QUERY ); return xShape; } diff --git a/sc/source/ui/view/drawview.cxx b/sc/source/ui/view/drawview.cxx index 9069aede14ad..51b281c91b3f 100644 --- a/sc/source/ui/view/drawview.cxx +++ b/sc/source/ui/view/drawview.cxx @@ -867,7 +867,7 @@ void ScDrawView::DeleteMarked() { // rescue note data for undo (with pointer to caption object) ScNoteData aNoteData = pNote->GetNoteData(); - OSL_ENSURE( aNoteData.mxCaption.get() == pCaptObj, "ScDrawView::DeleteMarked - caption object does not match" ); + OSL_ENSURE( aNoteData.m_pCaption.get() == pCaptObj, "ScDrawView::DeleteMarked - caption object does not match" ); // collect the drawing undo action created while deleting the note if( bUndo ) pDrawLayer->BeginCalcUndo(false); diff --git a/sc/source/ui/view/gridwin.cxx b/sc/source/ui/view/gridwin.cxx index a159d448b726..a1598a203b0a 100644 --- a/sc/source/ui/view/gridwin.cxx +++ b/sc/source/ui/view/gridwin.cxx @@ -360,7 +360,7 @@ static void lcl_UnLockComment( ScDrawView* pView, const Point& rPos, const ScVie ScDocument& rDoc = *pViewData->GetDocument(); ScAddress aCellPos( pViewData->GetCurX(), pViewData->GetCurY(), pViewData->GetTabNo() ); ScPostIt* pNote = rDoc.GetNote( aCellPos ); - SdrObject* pObj = pNote ? pNote->GetCaption() : nullptr; + SdrObject* pObj = pNote ? pNote->GetCaption().get() : nullptr; if( pObj && pObj->GetLogicRect().IsInside( rPos ) && ScDrawLayer::IsNoteCaption( pObj ) ) { const ScProtectionAttr* pProtAttr = rDoc.GetAttr( aCellPos, ATTR_PROTECTION ); diff --git a/sc/source/ui/view/notemark.cxx b/sc/source/ui/view/notemark.cxx index af3a404401fb..3df9dc44e2ff 100644 --- a/sc/source/ui/view/notemark.cxx +++ b/sc/source/ui/view/notemark.cxx @@ -67,7 +67,7 @@ ScNoteMarker::ScNoteMarker( vcl::Window* pWin, vcl::Window* pRight, vcl::Window* ScNoteMarker::~ScNoteMarker() { if (m_pModel) - m_xObject.release(); // deleting pModel also deletes the SdrCaptionObj + m_xObject.reset(); // deleting pModel also deletes the SdrCaptionObj InvalidateWin(); diff --git a/sc/source/ui/view/tabview5.cxx b/sc/source/ui/view/tabview5.cxx index 8f95f23078db..058bedd5b1d0 100644 --- a/sc/source/ui/view/tabview5.cxx +++ b/sc/source/ui/view/tabview5.cxx @@ -653,7 +653,7 @@ void ScTabView::OnLOKNoteStateChanged(const ScPostIt* pNote) if (!comphelper::LibreOfficeKit::isActive()) return; - const SdrCaptionObj* pCaption = pNote->GetCaption(); + const SdrCaptionObj* pCaption = pNote->GetCaption().get(); if (!pCaption) return; tools::Rectangle aRect = pCaption->GetLogicRect(); diff --git a/sc/source/ui/view/viewfun6.cxx b/sc/source/ui/view/viewfun6.cxx index f37d0d1241fc..28c0340986ba 100644 --- a/sc/source/ui/view/viewfun6.cxx +++ b/sc/source/ui/view/viewfun6.cxx @@ -495,7 +495,7 @@ void ScViewFunc::EditNote() /* Drawing object has been created in ScDocument::GetOrCreateNote() or in ScPostIt::ShowCaptionTemp(), so ScPostIt::GetCaption() should return a caption object. */ - if( SdrCaptionObj* pCaption = pNote->GetCaption() ) + if( SdrCaptionObj* pCaption = pNote->GetCaption().get() ) { if ( ScDrawView* pScDrawView = GetScDrawView() ) pScDrawView->SyncForGrid( pCaption ); -- cgit v1.2.3