summaryrefslogtreecommitdiff
path: root/sc/inc
diff options
context:
space:
mode:
authorLuboš Luňák <l.lunak@collabora.com>2019-02-12 13:48:53 +0100
committerChristian Lohmaier <lohmaier+LibreOffice@googlemail.com>2019-03-04 16:50:25 +0100
commitc22ef33f673beb65e24f581ad61ec93807d97085 (patch)
treee5e53c5479ff58e7a04ed4deaf451fd2ec2dfee7 /sc/inc
parentac44b07f7ad305fe73c070ce38913b1578cc211a (diff)
reintroduce ScCaptionPtr
This basically reverts b6b1ded0a0539e7be1b5338de378a3276a6ff445, since it introduces tdf#118707, and I cannot reproduce any of the original problems when reverting. The patch itself is technically correct, but the problem is in the Windows implementation of clipboard handling, which uses delayed processing of setting clipboard contents. This leads to previous clipboard contents being deleted too late, and with shared_ptr instances of SdrCaptionObj may get deleted after the related SdrModel has already been deleted. A proper fix would be to remove the stupid delayed processing from the clipboard code, but that's non-trivial. If that gets fixed, the change removing ScCaptionPtr may most probably be applied again. Change-Id: I29634847486aa955b20483c9eb38bba4fed87187 Reviewed-on: https://gerrit.libreoffice.org/67725 Tested-by: Jenkins Reviewed-by: Michael Meeks <michael.meeks@collabora.com> Reviewed-on: https://gerrit.libreoffice.org/68685 Reviewed-by: Eike Rathke <erack@redhat.com>
Diffstat (limited to 'sc/inc')
-rw-r--r--sc/inc/postit.hxx114
-rw-r--r--sc/inc/scmod.hxx2
2 files changed, 111 insertions, 5 deletions
diff --git a/sc/inc/postit.hxx b/sc/inc/postit.hxx
index ca72c47befca..ae70a65ccb83 100644
--- a/sc/inc/postit.hxx
+++ b/sc/inc/postit.hxx
@@ -36,6 +36,110 @@ 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 <TRUE/> 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
{
@@ -44,7 +148,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.
- std::shared_ptr< SdrCaptionObj > m_pCaption; /// Drawing object representing the cell note.
+ ScCaptionPtr mxCaption; /// Drawing object representing the cell note.
bool mbShown; /// True = note is visible.
explicit ScNoteData( bool bShown = false );
@@ -130,12 +234,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. */
- const std::shared_ptr< SdrCaptionObj>& GetCaption() const { return maNoteData.m_pCaption; }
+ SdrCaptionObj* GetCaption() const { return maNoteData.mxCaption.get();}
/** 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. */
- const std::shared_ptr< SdrCaptionObj>& GetOrCreateCaption( const ScAddress& rPos ) const;
+ SdrCaptionObj* GetOrCreateCaption( const ScAddress& rPos ) const;
/** Forgets the pointer to the note caption object.
@@ -163,7 +267,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 std::shared_ptr< SdrCaptionObj >& pCaption );
+ void CreateCaption( const ScAddress& rPos, const SdrCaptionObj* pCaption = nullptr );
/** Removes the caption object from the drawing layer, if this note is its owner. */
void RemoveCaption();
@@ -178,7 +282,7 @@ class SC_DLLPUBLIC ScNoteUtil
public:
/** Creates and returns a caption object for a temporary caption. */
- static std::shared_ptr< SdrCaptionObj > CreateTempCaption( ScDocument& rDoc, const ScAddress& rPos,
+ static ScCaptionPtr 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 7ba92a747aec..3a389ecc2d45 100644
--- a/sc/inc/scmod.hxx
+++ b/sc/inc/scmod.hxx
@@ -146,6 +146,8 @@ 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 );