[Libreoffice-commits] .: sc/inc sc/source

Kevin Hunter hunteke at kemper.freedesktop.org
Mon Oct 31 10:24:01 PDT 2011


 sc/inc/cell.hxx                                        |   64 ++---
 sc/inc/column.hxx                                      |    9 
 sc/inc/dociter.hxx                                     |    2 
 sc/inc/document.hxx                                    |   19 -
 sc/inc/global.hxx                                      |    2 
 sc/inc/table.hxx                                       |    8 
 sc/source/core/data/autonamecache.cxx                  |    2 
 sc/source/core/data/cell.cxx                           |   86 ++-----
 sc/source/core/data/cell2.cxx                          |    2 
 sc/source/core/data/column.cxx                         |   66 +++--
 sc/source/core/data/column2.cxx                        |  112 +++++++--
 sc/source/core/data/column3.cxx                        |  195 ++++++++---------
 sc/source/core/data/dociter.cxx                        |   18 +
 sc/source/core/data/documen2.cxx                       |    1 
 sc/source/core/data/documen4.cxx                       |   16 -
 sc/source/core/data/document.cxx                       |  188 ++++++++++++++--
 sc/source/core/data/fillinfo.cxx                       |    2 
 sc/source/core/data/postit.cxx                         |   22 +
 sc/source/core/data/table1.cxx                         |    4 
 sc/source/core/data/table2.cxx                         |   57 +---
 sc/source/core/data/table3.cxx                         |   11 
 sc/source/core/data/table4.cxx                         |    6 
 sc/source/core/data/table6.cxx                         |   30 +-
 sc/source/core/tool/chartlis.cxx                       |    2 
 sc/source/core/tool/chgtrack.cxx                       |   10 
 sc/source/core/tool/compiler.cxx                       |    4 
 sc/source/core/tool/interpr1.cxx                       |   14 -
 sc/source/core/tool/interpr2.cxx                       |   13 -
 sc/source/core/tool/interpr4.cxx                       |    4 
 sc/source/filter/dif/difexp.cxx                        |    2 
 sc/source/filter/excel/xetable.cxx                     |    4 
 sc/source/filter/html/htmlexp.cxx                      |    2 
 sc/source/filter/lotus/expop.cxx                       |    2 
 sc/source/filter/rtf/rtfexp.cxx                        |    2 
 sc/source/filter/xml/XMLChangeTrackingImportHelper.cxx |    6 
 sc/source/filter/xml/xmlcelli.cxx                      |    2 
 sc/source/ui/docshell/dbdocfun.cxx                     |    5 
 sc/source/ui/docshell/docfunc.cxx                      |    6 
 sc/source/ui/docshell/docsh.cxx                        |    4 
 sc/source/ui/docshell/docsh8.cxx                       |    4 
 sc/source/ui/docshell/impex.cxx                        |    4 
 sc/source/ui/navipi/content.cxx                        |    8 
 sc/source/ui/undo/undocell.cxx                         |   11 
 sc/source/ui/unoobj/cellsuno.cxx                       |   18 -
 sc/source/ui/unoobj/chart2uno.cxx                      |    2 
 sc/source/ui/unoobj/docuno.cxx                         |    9 
 sc/source/ui/unoobj/funcuno.cxx                        |    2 
 sc/source/ui/view/cellsh.cxx                           |    2 
 sc/source/ui/view/gridwin.cxx                          |    2 
 sc/source/ui/view/output.cxx                           |   27 +-
 sc/source/ui/view/output2.cxx                          |    2 
 sc/source/ui/view/printfun.cxx                         |    8 
 sc/source/ui/view/spelleng.cxx                         |    4 
 sc/source/ui/view/viewfunc.cxx                         |    6 
 54 files changed, 633 insertions(+), 480 deletions(-)

New commits:
commit 249faa5cb64a7270e852862a26b4a5e3a69a9895
Author: Kevin Hunter <hunteke at earlham.edu>
Date:   Mon Oct 31 13:23:06 2011 -0400

    Move ScPostIt storage from ScBaseCell->ScDocument
    
    ScPostIt is the behind-the-scenes name for Notes.  This move removes a
    usually empty pointer for each ScBaseCell to list of pointers within
    ScDocument.  The advantage is basically a reduction in size of 8 bytes
    per cell.  The current sizeof(ScBaseCell) is 16.  Here are the
    highlights:
    
    * Remove mpNote from ScBaseCell, and add a std::map (data structure) to
      ScDocument to store notes and associate with addresses.
    
    * Remove ScPostIt accessors and mutators from ScTable, ScColumn, and
      ScBaseCell
    
    * Replace ScPostIt accessors and mutators in ScDocument with ones to
      handle move of data structure from ScBaseCell to ScDocument
    
    * Rename ScPostIt.CloneWithoutNote to ScPostIt.Clone, while completely
      removing ScPostIt.CloneWithNote.  Any cloning of cell notes must now
      be handled outside external to the ScPostIt class, through
      ScDocument.*Note() functions.
    
    * Rename ScNoteCell to a more ScEmptyCell.  I expect this can be
      completely removed at some point the future, if we can handle
      broadcasters external to the cell logic.
    
    * Add ScDocument and ScTable to ScUsedAreaIterator data structure to
      accomodate for new placement of ScPostIt objects in ScDocument.
    
    * Convert CELLTYPE_NOTE to CELLTYPE_EMPTY (and all ensuing uses).
    
    * Wherever possible, respect 80-columns.
    
    * New ScDocument based API (individually block-comment documented before
      their definitions):
    
    SC_DLLPUBLIC ScPostIt* GetNote( ScAddress const & );
    SC_DLLPUBLIC ScPostIt* GetOrCreateNote( const ScAddress& rPos );
    bool                   SetNote( ScAddress const &, ScPostIt* );
    bool                   MoveNote( ScAddress const & from, ScAddress const & to );
    bool                   SwapNotes( ScAddress const &, ScAddress const & );
    ScPostIt*              ReleaseNote( ScAddress const & );
    void                   DeleteNote( ScAddress const & );
    
    Of note, TakeNote has been replaced with SetNote, which returns true on
    success, and false on failure.  TakeNote indicated failure by removing
    the passed note.  The SetNote approach leaves room for the caller to
    attempt to fix the issue, but also means the caller is now on the hook
    to cleanup the memory.  For now, the Calc-internal API is lazy and does
    not take advantage of this, but merely says "You failed?  Oh well,
    delete the note." ... which is exactly what TakeNote did.  This means, the
    lazy-programmer's idiom for SetNote use is:
    
       if ( ! pDoc->SetNote( aAddress, pNotePointer ) )
          DELETEZ( pNotePointer );

diff --git a/sc/inc/cell.hxx b/sc/inc/cell.hxx
index 7551ba6..c1d5cf2 100644
--- a/sc/inc/cell.hxx
+++ b/sc/inc/cell.hxx
@@ -65,7 +65,7 @@ class ScPatternAttr;
 // ============================================================================
 
 /** Default cell clone flags: do not start listening, do not adjust 3D refs to
-    old position, clone note captions of cell notes. */
+    old position. Note: Notes must be cloned separately, through ScDocument.*/
 const int SC_CLONECELL_DEFAULT          = 0x0000;
 
 /** If set, cloned formula cells will start to listen to the document. */
@@ -92,27 +92,29 @@ public:
     /** Base copy constructor. Does NOT clone cell note or broadcaster! */
                     ScBaseCell( const ScBaseCell& rCell );
 
-    /** Returns a clone of this cell at the same position, cell note and
-        broadcaster will not be cloned. */
-    ScBaseCell*     CloneWithoutNote( ScDocument& rDestDoc, int nCloneFlags = SC_CLONECELL_DEFAULT ) const;
+    /** Returns a clone of this cell at the same position; cell broadcaster
+        will not be cloned. */
+    ScBaseCell*     Clone( ScDocument& rDestDoc,
+                          int nCloneFlags = SC_CLONECELL_DEFAULT ) const;
 
     /** Returns a clone of this cell for the passed document position, cell
-        note and broadcaster will not be cloned. */
-    ScBaseCell*     CloneWithoutNote( ScDocument& rDestDoc, const ScAddress& rDestPos, int nCloneFlags = SC_CLONECELL_DEFAULT ) const;
-
-    /** Returns a clone of this cell, clones cell note and caption object too
-        (unless SC_CLONECELL_NOCAPTION flag is set). Broadcaster will not be cloned. */
-    ScBaseCell*     CloneWithNote( const ScAddress& rOwnPos, ScDocument& rDestDoc, const ScAddress& rDestPos, int nCloneFlags = SC_CLONECELL_DEFAULT ) const;
+        broadcaster will not be cloned. */
+    ScBaseCell*     Clone( ScDocument& rDestDoc, const ScAddress& rDestPos,
+                          int nCloneFlags = SC_CLONECELL_DEFAULT ) const;
 
     /** Due to the fact that ScBaseCell does not have a vtable, this function
-        deletes the cell by calling the appropriate d'tor of the derived class. */
+        deletes the cell by calling the appropriate d'tor of the derived class.
+    */
     void            Delete();
 
     inline CellType GetCellType() const { return (CellType)eCellType; }
 
-    /** Returns true, if the cell is empty (neither value nor formula nor cell note).
-        Returns false for formula cells returning nothing, use HasEmptyData() for that. */
-    bool            IsBlank( bool bIgnoreNotes = false ) const;
+    /** Returns true, if the cell is empty (neither value nor formula).
+        Returns false for formula cells returning nothing; use HasEmptyData()
+          for that.
+        Does *not* check for notes; use ScDocument.GetNote() for that.
+    */
+    bool            IsBlank( ) const;
 
 // for idle-calculations
     inline sal_uInt16   GetTextWidth() const { return nTextWidth; }
@@ -121,18 +123,6 @@ public:
     inline sal_uInt8     GetScriptType() const { return nScriptType; }
     inline void     SetScriptType( sal_uInt8 nNew ) { nScriptType = nNew; }
 
-    /** Returns true, if the cell contains a note. */
-    inline bool     HasNote() const { return mpNote != 0; }
-    /** Returns the pointer to a cell note object (read-only). */
-    inline const ScPostIt* GetNote() const { return mpNote; }
-    /** Returns the pointer to a cell note object. */
-    inline ScPostIt* GetNote() { return mpNote; }
-    /** Takes ownership of the passed cell note object. */
-    void            TakeNote( ScPostIt* pNote );
-    /** Returns and forgets the own cell note object. Caller takes ownership! */
-    ScPostIt*       ReleaseNote();
-    /** Deletes the own cell note object. */
-    void            DeleteNote();
 
     /** Returns true, if the cell contains a broadcaster. */
     inline bool     HasBroadcaster() const { return mpBroadcaster != 0; }
@@ -156,20 +146,20 @@ public:
 
     /** Error code if ScFormulaCell, else 0. */
     sal_uInt16          GetErrorCode() const;
-    /** ScFormulaCell with formula::svEmptyCell result, or ScNoteCell (may have been
-        created due to reference to empty cell). */
+
+    /** ScFormulaCell with formula::svEmptyCell result, or ScEmptyCell */
     bool            HasEmptyData() const;
     bool            HasValueData() const;
     bool            HasStringData() const;
     String          GetStringData() const;          // only real strings
 
+
     static bool     CellEqual( const ScBaseCell* pCell1, const ScBaseCell* pCell2 );
 
 private:
     ScBaseCell&     operator=( const ScBaseCell& );
 
 private:
-    ScPostIt*       mpNote;         /// The cell note. Cell takes ownership!
     SvtBroadcaster* mpBroadcaster;  /// Broadcaster for changed values. Cell takes ownership!
 
 protected:
@@ -180,26 +170,24 @@ protected:
 
 // ============================================================================
 
-class SC_DLLPUBLIC ScNoteCell : public ScBaseCell
+
+// Empty cell to take broadcaster
+class SC_DLLPUBLIC ScEmptyCell : public ScBaseCell
 {
 public:
 #ifdef USE_MEMPOOL
-    DECL_FIXEDMEMPOOL_NEWDEL( ScNoteCell )
+    DECL_FIXEDMEMPOOL_NEWDEL( ScEmptyCell )
 #endif
 
     /** Cell takes ownership of the passed broadcaster. */
-    explicit        ScNoteCell( SvtBroadcaster* pBC = 0 );
-    /** Cell takes ownership of the passed note and broadcaster. */
-    explicit        ScNoteCell( ScPostIt* pNote, SvtBroadcaster* pBC = 0 );
+    explicit        ScEmptyCell( SvtBroadcaster* pBC = 0 );
 
 #if OSL_DEBUG_LEVEL > 0
-                    ~ScNoteCell();
+                    ~ScEmptyCell();
 #endif
-
-private:
-                    ScNoteCell( const ScNoteCell& );
 };
 
+
 class SC_DLLPUBLIC ScValueCell : public ScBaseCell
 {
 public:
diff --git a/sc/inc/column.hxx b/sc/inc/column.hxx
index 7e21ba8..b665e39 100644
--- a/sc/inc/column.hxx
+++ b/sc/inc/column.hxx
@@ -265,15 +265,6 @@ public:
     bool    HasValueData( SCROW nRow ) const;
     bool    HasStringCells( SCROW nStartRow, SCROW nEndRow ) const;
 
-    /** Returns the pointer to a cell note object at the passed row. */
-    ScPostIt*   GetNote( SCROW nRow );
-    /** Sets the passed cell note object at the passed row. Takes ownership! */
-    void        TakeNote( SCROW nRow, ScPostIt* pNote );
-    /** Returns and forgets a cell note object at the passed row. */
-    ScPostIt*   ReleaseNote( SCROW nRow );
-    /** Deletes the note at the passed row. */
-    void        DeleteNote( SCROW nRow );
-
     void        SetDirty();
     void        SetDirty( const ScRange& );
     void        SetDirtyVar();
diff --git a/sc/inc/dociter.hxx b/sc/inc/dociter.hxx
index c06b993..43e13bf 100644
--- a/sc/inc/dociter.hxx
+++ b/sc/inc/dociter.hxx
@@ -479,6 +479,8 @@ private:
     ScHorizontalCellIterator    aCellIter;
     ScHorizontalAttrIterator    aAttrIter;
 
+    ScDocument *            pDoc;
+    const SCTAB             nTable;
     SCCOL                   nNextCol;
     SCROW                   nNextRow;
 
diff --git a/sc/inc/document.hxx b/sc/inc/document.hxx
index a7ae1c3..cbcc3b1 100644
--- a/sc/inc/document.hxx
+++ b/sc/inc/document.hxx
@@ -273,6 +273,7 @@ private:
     ::std::auto_ptr<ScExternalRefManager> pExternalRefMgr;
     ::std::auto_ptr<ScMacroManager> mpMacroMgr;
 
+    std::map< const ScAddress, ScPostIt* > pNotes;
 
     // mutable for lazy construction
     mutable ::std::auto_ptr< ScFormulaParserPool >
@@ -802,16 +803,16 @@ public:
     /** Returns true, if there is any data to create a selection list for rPos. */
     sal_Bool            HasSelectionData( SCCOL nCol, SCROW nRow, SCTAB nTab ) const;
 
-    /** Returns the pointer to a cell note object at the passed cell address. */
-    SC_DLLPUBLIC ScPostIt*       GetNote( const ScAddress& rPos );
-    /** Sets the passed note at the cell with the passed cell address. */
-    void            TakeNote( const ScAddress& rPos, ScPostIt*& rpNote );
-    /** Returns and forgets the cell note object at the passed cell address. */
-    ScPostIt*       ReleaseNote( const ScAddress& rPos );
-    /** Returns the pointer to an existing or created cell note object at the passed cell address. */
+    /* Note management API
+    */
+    SC_DLLPUBLIC ScPostIt* GetNote( ScAddress const & );
     SC_DLLPUBLIC ScPostIt* GetOrCreateNote( const ScAddress& rPos );
-    /** Deletes the note at the passed cell address. */
-    void            DeleteNote( const ScAddress& rPos );
+    bool                   SetNote( ScAddress const &, ScPostIt* );
+    bool                   MoveNote( ScAddress const & from, ScAddress const & to );
+    bool                   SwapNotes( ScAddress const &, ScAddress const & );
+    ScPostIt*              ReleaseNote( ScAddress const & );
+    void                   DeleteNote( ScAddress const & );
+
     /** Creates the captions of all uninitialized cell notes in the specified sheet.
         @param bForced  True = always create all captions, false = skip when Undo is disabled. */
     void            InitializeNoteCaptions( SCTAB nTab, bool bForced = false );
diff --git a/sc/inc/global.hxx b/sc/inc/global.hxx
index e8f7da1..7d72340 100644
--- a/sc/inc/global.hxx
+++ b/sc/inc/global.hxx
@@ -273,7 +273,7 @@ enum CellType
         CELLTYPE_VALUE,
         CELLTYPE_STRING,
         CELLTYPE_FORMULA,
-        CELLTYPE_NOTE,
+        CELLTYPE_EMPTY,
         CELLTYPE_EDIT,
         CELLTYPE_SYMBOLS        // for load/save
 #if OSL_DEBUG_LEVEL > 0
diff --git a/sc/inc/table.hxx b/sc/inc/table.hxx
index 9cd3c57..2859dd0 100644
--- a/sc/inc/table.hxx
+++ b/sc/inc/table.hxx
@@ -340,14 +340,6 @@ public:
     void        GetFirstDataPos(SCCOL& rCol, SCROW& rRow) const;
     void        GetLastDataPos(SCCOL& rCol, SCROW& rRow) const;
 
-    /** Returns the pointer to a cell note object at the passed cell address. */
-    ScPostIt*   GetNote( SCCOL nCol, SCROW nRow );
-    /** Sets the passed cell note object at the passed cell address. Takes ownership! */
-    void        TakeNote( SCCOL nCol, SCROW nRow, ScPostIt*& rpNote );
-    /** Returns and forgets the cell note object at the passed cell address. */
-    ScPostIt*   ReleaseNote( SCCOL nCol, SCROW nRow );
-    /** Deletes the note at the passed cell address. */
-    void        DeleteNote( SCCOL nCol, SCROW nRow );
     /** Creates the captions of all uninitialized cell notes.
         @param bForced  True = always create all captions, false = skip when Undo is disabled. */
     void        InitializeNoteCaptions( bool bForced = false );
diff --git a/sc/source/core/data/autonamecache.cxx b/sc/source/core/data/autonamecache.cxx
index 44f5cd5..df8462c 100644
--- a/sc/source/core/data/autonamecache.cxx
+++ b/sc/source/core/data/autonamecache.cxx
@@ -90,7 +90,7 @@ const ScAutoNameAddresses& ScAutoNameCache::GetNameOccurrences( const String& rN
                 break;
                 case CELLTYPE_NONE:
                 case CELLTYPE_VALUE:
-                case CELLTYPE_NOTE:
+                case CELLTYPE_EMPTY:
                 case CELLTYPE_SYMBOLS:
 #if OSL_DEBUG_LEVEL > 0
                 case CELLTYPE_DESTROYED:
diff --git a/sc/source/core/data/cell.cxx b/sc/source/core/data/cell.cxx
index 49c94a5..c56cb23 100644
--- a/sc/source/core/data/cell.cxx
+++ b/sc/source/core/data/cell.cxx
@@ -72,20 +72,20 @@ const sal_uInt16 MAXRECURSION = 400;
 
 #ifdef USE_MEMPOOL
 // MemPools auf 4k Boundaries  - 64 Bytes ausrichten
-const sal_uInt16 nMemPoolValueCell = (0x8000 - 64) / sizeof(ScValueCell);
+const sal_uInt16 nMemPoolEmptyCell   = (0x8000 - 64) / sizeof(ScEmptyCell);
+const sal_uInt16 nMemPoolValueCell   = (0x8000 - 64) / sizeof(ScValueCell);
 const sal_uInt16 nMemPoolFormulaCell = (0x8000 - 64) / sizeof(ScFormulaCell);
-const sal_uInt16 nMemPoolStringCell = (0x4000 - 64) / sizeof(ScStringCell);
-const sal_uInt16 nMemPoolNoteCell = (0x1000 - 64) / sizeof(ScNoteCell);
-IMPL_FIXEDMEMPOOL_NEWDEL( ScValueCell,   nMemPoolValueCell, nMemPoolValueCell )
+const sal_uInt16 nMemPoolStringCell  = (0x4000 - 64) / sizeof(ScStringCell);
+
+IMPL_FIXEDMEMPOOL_NEWDEL( ScEmptyCell,   nMemPoolEmptyCell,   nMemPoolEmptyCell )
+IMPL_FIXEDMEMPOOL_NEWDEL( ScValueCell,   nMemPoolValueCell,   nMemPoolValueCell )
 IMPL_FIXEDMEMPOOL_NEWDEL( ScFormulaCell, nMemPoolFormulaCell, nMemPoolFormulaCell )
-IMPL_FIXEDMEMPOOL_NEWDEL( ScStringCell,  nMemPoolStringCell, nMemPoolStringCell )
-IMPL_FIXEDMEMPOOL_NEWDEL( ScNoteCell,    nMemPoolNoteCell, nMemPoolNoteCell )
+IMPL_FIXEDMEMPOOL_NEWDEL( ScStringCell,  nMemPoolStringCell,  nMemPoolStringCell )
 #endif
 
 // ============================================================================
 
 ScBaseCell::ScBaseCell( CellType eNewType ) :
-    mpNote( 0 ),
     mpBroadcaster( 0 ),
     nTextWidth( TEXTWIDTH_DIRTY ),
     eCellType( sal::static_int_cast<sal_uInt8>(eNewType) ),
@@ -94,7 +94,6 @@ ScBaseCell::ScBaseCell( CellType eNewType ) :
 }
 
 ScBaseCell::ScBaseCell( const ScBaseCell& rCell ) :
-    mpNote( 0 ),
     mpBroadcaster( 0 ),
     nTextWidth( rCell.nTextWidth ),
     eCellType( rCell.eCellType ),
@@ -104,7 +103,6 @@ ScBaseCell::ScBaseCell( const ScBaseCell& rCell ) :
 
 ScBaseCell::~ScBaseCell()
 {
-    delete mpNote;
     delete mpBroadcaster;
     OSL_ENSURE( eCellType == CELLTYPE_DESTROYED, "BaseCell Destructor" );
 }
@@ -123,9 +121,9 @@ ScBaseCell* lclCloneCell( const ScBaseCell& rSrcCell, ScDocument& rDestDoc, cons
             return new ScEditCell( static_cast< const ScEditCell& >( rSrcCell ), rDestDoc );
         case CELLTYPE_FORMULA:
             return new ScFormulaCell( static_cast< const ScFormulaCell& >( rSrcCell ), rDestDoc, rDestPos, nCloneFlags );
-        case CELLTYPE_NOTE:
-            return new ScNoteCell;
-        default:;
+        case CELLTYPE_EMPTY:
+            return new ScEmptyCell;
+         default:;
     }
     OSL_FAIL( "lclCloneCell - unknown cell type" );
     return 0;
@@ -227,7 +225,7 @@ void adjustDBRange(ScToken* pToken, ScDocument& rNewDoc, const ScDocument* pOldD
 
 } // namespace
 
-ScBaseCell* ScBaseCell::CloneWithoutNote( ScDocument& rDestDoc, int nCloneFlags ) const
+ScBaseCell* ScBaseCell::Clone( ScDocument& rDestDoc, int nCloneFlags ) const
 {
     // notes will not be cloned -> cell address only needed for formula cells
     ScAddress aDestPos;
@@ -236,27 +234,14 @@ ScBaseCell* ScBaseCell::CloneWithoutNote( ScDocument& rDestDoc, int nCloneFlags
     return lclCloneCell( *this, rDestDoc, aDestPos, nCloneFlags );
 }
 
-ScBaseCell* ScBaseCell::CloneWithoutNote( ScDocument& rDestDoc, const ScAddress& rDestPos, int nCloneFlags ) const
+ScBaseCell* ScBaseCell::Clone( ScDocument& rDestDoc, const ScAddress& rDestPos, int nCloneFlags ) const
 {
     return lclCloneCell( *this, rDestDoc, rDestPos, nCloneFlags );
 }
 
-ScBaseCell* ScBaseCell::CloneWithNote( const ScAddress& rOwnPos, ScDocument& rDestDoc, const ScAddress& rDestPos, int nCloneFlags ) const
-{
-    ScBaseCell* pNewCell = lclCloneCell( *this, rDestDoc, rDestPos, nCloneFlags );
-    if( mpNote )
-    {
-        if( !pNewCell )
-            pNewCell = new ScNoteCell;
-        bool bCloneCaption = (nCloneFlags & SC_CLONECELL_NOCAPTION) == 0;
-        pNewCell->TakeNote( mpNote->Clone( rOwnPos, rDestDoc, rDestPos, bCloneCaption ) );
-    }
-    return pNewCell;
-}
 
 void ScBaseCell::Delete()
 {
-    DeleteNote();
     switch (eCellType)
     {
         case CELLTYPE_VALUE:
@@ -271,8 +256,8 @@ void ScBaseCell::Delete()
         case CELLTYPE_FORMULA:
             delete (ScFormulaCell*) this;
             break;
-        case CELLTYPE_NOTE:
-            delete (ScNoteCell*) this;
+        case CELLTYPE_EMPTY:
+            delete (ScEmptyCell*) this;
             break;
         default:
             OSL_FAIL("Attempt to Delete() an unknown CELLTYPE");
@@ -280,28 +265,12 @@ void ScBaseCell::Delete()
     }
 }
 
-bool ScBaseCell::IsBlank( bool bIgnoreNotes ) const
-{
-    return (eCellType == CELLTYPE_NOTE) && (bIgnoreNotes || !mpNote);
-}
-
-void ScBaseCell::TakeNote( ScPostIt* pNote )
-{
-    delete mpNote;
-    mpNote = pNote;
-}
 
-ScPostIt* ScBaseCell::ReleaseNote()
+bool ScBaseCell::IsBlank( ) const
 {
-    ScPostIt* pNote = mpNote;
-    mpNote = 0;
-    return pNote;
+    return (CELLTYPE_EMPTY == eCellType);
 }
 
-void ScBaseCell::DeleteNote()
-{
-    DELETEZ( mpNote );
-}
 
 void ScBaseCell::TakeBroadcaster( SvtBroadcaster* pBroadcaster )
 {
@@ -518,7 +487,7 @@ bool ScBaseCell::HasEmptyData() const
 {
     switch ( eCellType )
     {
-        case CELLTYPE_NOTE :
+        case CELLTYPE_EMPTY :
             return true;
         case CELLTYPE_FORMULA :
             return ((ScFormulaCell*)this)->IsEmpty();
@@ -581,17 +550,17 @@ bool ScBaseCell::CellEqual( const ScBaseCell* pCell1, const ScBaseCell* pCell2 )
     if ( pCell1 )
     {
         eType1 = pCell1->GetCellType();
-        if (eType1 == CELLTYPE_EDIT)
+        if (CELLTYPE_EDIT == eType1)
             eType1 = CELLTYPE_STRING;
-        else if (eType1 == CELLTYPE_NOTE)
+        else if (CELLTYPE_EMPTY == eType1)
             eType1 = CELLTYPE_NONE;
     }
     if ( pCell2 )
     {
         eType2 = pCell2->GetCellType();
-        if (eType2 == CELLTYPE_EDIT)
+        if (CELLTYPE_EDIT == eType2)
             eType2 = CELLTYPE_STRING;
-        else if (eType2 == CELLTYPE_NOTE)
+        else if (CELLTYPE_EMPTY == eType2)
             eType2 = CELLTYPE_NONE;
     }
     if ( eType1 != eType2 )
@@ -654,26 +623,21 @@ bool ScBaseCell::CellEqual( const ScBaseCell* pCell1, const ScBaseCell* pCell2 )
 
 // ============================================================================
 
-ScNoteCell::ScNoteCell( SvtBroadcaster* pBC ) :
-    ScBaseCell( CELLTYPE_NOTE )
+ScEmptyCell::ScEmptyCell( SvtBroadcaster* pBC ) :
+    ScBaseCell( CELLTYPE_EMPTY )
 {
     TakeBroadcaster( pBC );
 }
 
-ScNoteCell::ScNoteCell( ScPostIt* pNote, SvtBroadcaster* pBC ) :
-    ScBaseCell( CELLTYPE_NOTE )
-{
-    TakeNote( pNote );
-    TakeBroadcaster( pBC );
-}
 
 #if OSL_DEBUG_LEVEL > 0
-ScNoteCell::~ScNoteCell()
+ScEmptyCell::~ScEmptyCell()
 {
     eCellType = CELLTYPE_DESTROYED;
 }
 #endif
 
+
 // ============================================================================
 
 ScValueCell::ScValueCell() :
diff --git a/sc/source/core/data/cell2.cxx b/sc/source/core/data/cell2.cxx
index 28fb634..2c8d341 100644
--- a/sc/source/core/data/cell2.cxx
+++ b/sc/source/core/data/cell2.cxx
@@ -61,7 +61,7 @@ using namespace formula;
 // STATIC DATA -----------------------------------------------------------
 
 #ifdef USE_MEMPOOL
-const sal_uInt16 nMemPoolEditCell = (0x1000 - 64) / sizeof(ScNoteCell);
+const sal_uInt16 nMemPoolEditCell = (0x1000 - 64) / sizeof(ScEmptyCell);
 IMPL_FIXEDMEMPOOL_NEWDEL( ScEditCell, nMemPoolEditCell, nMemPoolEditCell )
 #endif
 
diff --git a/sc/source/core/data/column.cxx b/sc/source/core/data/column.cxx
index fc1178f..89e6354 100644
--- a/sc/source/core/data/column.cxx
+++ b/sc/source/core/data/column.cxx
@@ -840,7 +840,7 @@ void lclTakeBroadcaster( ScBaseCell*& rpCell, SvtBroadcaster* pBC )
         if( rpCell )
             rpCell->TakeBroadcaster( pBC );
         else
-            rpCell = new ScNoteCell( pBC );
+            rpCell = new ScEmptyCell( pBC );
     }
 }
 
@@ -908,11 +908,10 @@ void ScColumn::SwapRow(SCROW nRow1, SCROW nRow2)
         }
         else
         {
-            ScNoteCell* pDummyCell = pBC1 ? new ScNoteCell( pBC1 ) : 0;
-            if ( pDummyCell )
+            if ( pBC1 )
             {
                 // insert dummy note cell (without note) containing old broadcaster
-                pItems[nIndex1].pCell = pDummyCell;
+                pItems[nIndex1].pCell = new ScEmptyCell( pBC1 );
             }
             else
             {
@@ -962,9 +961,8 @@ void ScColumn::SwapRow(SCROW nRow1, SCROW nRow2)
             // do not swap formula cells with equal formulas, but swap notes
             if (bEqual)
             {
-                ScPostIt* pNote1 = pCell1->ReleaseNote();
-                pCell1->TakeNote( pCell2->ReleaseNote() );
-                pCell2->TakeNote( pNote1 );
+                pDocument->SwapNotes( aPos1, aPos2 );
+
                 return;
             }
         }
@@ -973,17 +971,14 @@ void ScColumn::SwapRow(SCROW nRow1, SCROW nRow2)
     /*  Create clone of pCell1 at position of pCell2 (pCell1 exists always, see
         variable swapping above). Do not clone the note, but move pointer of
         old note to new cell. */
-    ScBaseCell* pNew2 = pCell1->CloneWithoutNote( *pDocument, aPos2, SC_CLONECELL_ADJUST3DREL );
-    pNew2->TakeNote( pCell1->ReleaseNote() );
+    ScBaseCell* pNew2 = pCell1->Clone( *pDocument, aPos2, SC_CLONECELL_ADJUST3DREL );
 
-    /*  Create clone of pCell2 at position of pCell1. Do not clone the note,
-        but move pointer of old note to new cell. */
     ScBaseCell* pNew1 = 0;
     if ( pCell2 )
     {
-        pNew1 = pCell2->CloneWithoutNote( *pDocument, aPos1, SC_CLONECELL_ADJUST3DREL );
-        pNew1->TakeNote( pCell2->ReleaseNote() );
+        pNew1 = pCell2->Clone( *pDocument, aPos1, SC_CLONECELL_ADJUST3DREL );
     }
+    pDocument->SwapNotes( aPos1, aPos2 );
 
     // move old broadcasters new cells at the same old position
     SvtBroadcaster* pBC1 = pCell1->ReleaseBroadcaster();
@@ -1079,10 +1074,17 @@ bool ScColumn::TestInsertCol( SCROW nStartRow, SCROW nEndRow) const
     if (!IsEmpty())
     {
         bool bTest = true;
-        if (pItems)
-            for (SCSIZE i=0; (i<nCount) && bTest; i++)
-                bTest = (pItems[i].nRow < nStartRow) || (pItems[i].nRow > nEndRow)
-                        || pItems[i].pCell->IsBlank();
+        if (pItems) {
+            ScAddress pos( nCol, 0, nTab );
+            for (SCSIZE i=0; (i<nCount) && bTest; i++) {
+                pos.SetRow( pItems[i].nRow );
+                bTest = (
+                    ((nStartRow < pItems[i].nRow) && (pItems[i].nRow < nEndRow))
+                 || (pItems[i].pCell->IsBlank())
+                 || (0 == pDocument->GetNote( pos ))
+                );
+            }
+        }
 
         //  AttrArray testet nur zusammengefasste
 
@@ -1199,6 +1201,9 @@ void ScColumn::InsertRow( SCROW nStartRow, SCSIZE nSize )
         for (i = 0; i < nDelCount; i++)
         {
             ScBaseCell* pCell = ppDelCells[i];
+            // Oct, 2011: Perhaps need to update IsBlank call in ENSURE to check
+            // for notes (via ScDocument.GetNote), but I'm not sure the current
+            // code (above and below this comment) is even correct.
             OSL_ENSURE( pCell->IsBlank(), "sichtbare Zelle weggeschoben" );
             SvtBroadcaster* pBC = pCell->GetBroadcaster();
             if (pBC)
@@ -1247,6 +1252,8 @@ void ScColumn::CopyToClip(SCROW nRow1, SCROW nRow2, ScColumn& rColumn, bool bKee
     if (nBlockCount)
     {
         int nCloneFlags = bCloneNoteCaptions ? SC_CLONECELL_DEFAULT : SC_CLONECELL_NOCAPTION;
+        ScDocument * rDestDoc = rColumn.pDocument;
+
         rColumn.Resize( rColumn.GetCellCount() + nBlockCount );
         ScAddress aOwnPos( nCol, 0, nTab );
         ScAddress aDestPos( rColumn.nCol, 0, rColumn.nTab );
@@ -1254,7 +1261,15 @@ void ScColumn::CopyToClip(SCROW nRow1, SCROW nRow2, ScColumn& rColumn, bool bKee
         {
             aOwnPos.SetRow( pItems[i].nRow );
             aDestPos.SetRow( pItems[i].nRow );
-            ScBaseCell* pNewCell = pItems[i].pCell->CloneWithNote( aOwnPos, *rColumn.pDocument, aDestPos, nCloneFlags );
+            ScBaseCell* pNewCell = pItems[i].pCell->Clone(
+               *rDestDoc, aDestPos, nCloneFlags
+            );
+            ScPostIt* pNewNote = pDocument->GetNote( aOwnPos );
+            if (pNewNote)
+                pNewNote = new ScPostIt( *rDestDoc, aDestPos, *pNewNote );
+            if ( ! rDestDoc->SetNote( aDestPos, pNewNote ) )
+                DELETEZ( pNewNote ); // apparently unsuccessful; don't leak
+
             rColumn.Append( aDestPos.Row(), pNewCell );
         }
     }
@@ -1383,7 +1398,12 @@ void ScColumn::CopyUpdated( const ScColumn& rPosCol, ScColumn& rDestCol ) const
         SCSIZE nThisIndex;
         if ( Search( aDestPos.Row(), nThisIndex ) )
         {
-            ScBaseCell* pNew = pItems[nThisIndex].pCell->CloneWithNote( aOwnPos, rDestDoc, aDestPos );
+            ScBaseCell* pNew = pItems[nThisIndex].pCell->Clone( rDestDoc, aDestPos );
+            ScPostIt* pNewNote = pDocument->GetNote( aOwnPos );
+            pNewNote = new ScPostIt( rDestDoc, aDestPos, pNewNote );
+            if ( ! rDestDoc.SetNote( aDestPos, pNewNote ) )
+                DELETEZ( pNewNote ); // apparently unsuccessful; don't leak
+
             rDestCol.Insert( aDestPos.Row(), pNew );
         }
     }
@@ -1591,7 +1611,7 @@ void ScColumn::MoveTo(SCROW nStartRow, SCROW nEndRow, ScColumn& rCol)
             ScAddress aAdr( nCol, 0, nTab );
             ScHint aHint( SC_HINT_DYING, aAdr, NULL );  // areas only
             ScAddress& rAddress = aHint.GetAddress();
-            ScNoteCell* pNoteCell = new ScNoteCell;     // Dummy like in DeleteRange
+            ScEmptyCell* pEmptyCell = new ScEmptyCell;  // Dummy like in DeleteRange
 
             // must iterate backwards, because indexes of following cells become invalid
             for (EntryPosPairs::reverse_iterator it( aEntries.rbegin());
@@ -1600,7 +1620,7 @@ void ScColumn::MoveTo(SCROW nStartRow, SCROW nEndRow, ScColumn& rCol)
                 nStartPos = (*it).first;
                 nStopPos = (*it).second;
                 for (i=nStartPos; i<nStopPos; ++i)
-                    pItems[i].pCell = pNoteCell;
+                    pItems[i].pCell = pEmptyCell;
                 for (i=nStartPos; i<nStopPos; ++i)
                 {
                     rAddress.SetRow( pItems[i].nRow );
@@ -1610,7 +1630,7 @@ void ScColumn::MoveTo(SCROW nStartRow, SCROW nEndRow, ScColumn& rCol)
                 memmove( &pItems[nStartPos], &pItems[nStopPos],
                         (nCount - nStartPos) * sizeof(ColEntry) );
             }
-            pNoteCell->Delete();
+            pEmptyCell->Delete();
             pItems[nCount].nRow = 0;
             pItems[nCount].pCell = NULL;
         }
@@ -1786,7 +1806,7 @@ void ScColumn::UpdateDeleteTab( SCTAB nTable, bool bIsMove, ScColumn* pRefUndo,
 
                 /*  Do not copy cell note to the undo document. Undo will copy
                     back the formula cell while keeping the original note. */
-                ScBaseCell* pSave = pRefUndo ? pOld->CloneWithoutNote( *pDocument ) : 0;
+                ScBaseCell* pSave = pRefUndo ? pOld->Clone( *pDocument ) : 0;
 
                 bool bChanged = pOld->UpdateDeleteTab(nTable, bIsMove, nSheets);
                 if ( nRow != pItems[i].nRow )
diff --git a/sc/source/core/data/column2.cxx b/sc/source/core/data/column2.cxx
index 83ecd3c..547e833 100644
--- a/sc/source/core/data/column2.cxx
+++ b/sc/source/core/data/column2.cxx
@@ -946,7 +946,7 @@ void ScColumn::RemoveAutoSpellObj()
                 String aText = ScEditUtil::GetSpaceDelimitedString( *pEngine );
                 ScBaseCell* pNewCell = new ScStringCell( aText );
                 pNewCell->TakeBroadcaster( pOldCell->ReleaseBroadcaster() );
-                pNewCell->TakeNote( pOldCell->ReleaseNote() );
+
                 pItems[i].pCell = pNewCell;
                 delete pOldCell;
             }
@@ -1018,7 +1018,7 @@ void ScColumn::RemoveEditAttribs( SCROW nStartRow, SCROW nEndRow )
                 String aText = ScEditUtil::GetSpaceDelimitedString( *pEngine );
                 ScBaseCell* pNewCell = new ScStringCell( aText );
                 pNewCell->TakeBroadcaster( pOldCell->ReleaseBroadcaster() );
-                pNewCell->TakeNote( pOldCell->ReleaseNote() );
+
                 pItems[i].pCell = pNewCell;
                 delete pOldCell;
             }
@@ -1150,7 +1150,11 @@ bool ScColumn::IsEmptyVisData(bool bNotes) const
         for (i=0; i<nCount && !bVisData; i++)
         {
             ScBaseCell* pCell = pItems[i].pCell;
-            if ( pCell->GetCellType() != CELLTYPE_NOTE || (bNotes && pCell->HasNote()) )
+            ScPostIt *note = pDocument->GetNote(
+              ScAddress( nCol, pItems[i].nRow, nTab )
+            );
+
+            if (pCell->GetCellType() != CELLTYPE_EMPTY || (bNotes && 0 != note))
                 bVisData = true;
         }
         return !bVisData;
@@ -1167,7 +1171,7 @@ SCSIZE ScColumn::VisibleCount( SCROW nStartRow, SCROW nEndRow ) const
     while ( nIndex < nCount && pItems[nIndex].nRow <= nEndRow )
     {
         if ( pItems[nIndex].nRow >= nStartRow &&
-             pItems[nIndex].pCell->GetCellType() != CELLTYPE_NOTE )
+             pItems[nIndex].pCell->GetCellType() != CELLTYPE_EMPTY )
         {
             ++nVisCount;
         }
@@ -1187,7 +1191,9 @@ SCROW ScColumn::GetLastVisDataPos(bool bNotes) const
         {
             --i;
             ScBaseCell* pCell = pItems[i].pCell;
-            if ( pCell->GetCellType() != CELLTYPE_NOTE || (bNotes && pCell->HasNote()) )
+            ScPostIt *note = pDocument->GetNote( ScAddress(nCol, pItems[i].nRow, nTab) );
+
+            if (pCell->GetCellType() != CELLTYPE_EMPTY || (bNotes && 0 != note))
             {
                 bFound = true;
                 nRet = pItems[i].nRow;
@@ -1207,7 +1213,9 @@ SCROW ScColumn::GetFirstVisDataPos(bool bNotes) const
         for (i=0; i<nCount && !bFound; i++)
         {
             ScBaseCell* pCell = pItems[i].pCell;
-            if ( pCell->GetCellType() != CELLTYPE_NOTE || (bNotes && pCell->HasNote()) )
+            ScPostIt *note = pDocument->GetNote( ScAddress(nCol, pItems[i].nRow, nTab) );
+
+            if (pCell->GetCellType() != CELLTYPE_EMPTY || (bNotes && 0 != note))
             {
                 bFound = true;
                 nRet = pItems[i].nRow;
@@ -1220,9 +1228,11 @@ SCROW ScColumn::GetFirstVisDataPos(bool bNotes) const
 bool ScColumn::HasVisibleDataAt(SCROW nRow) const
 {
     SCSIZE nIndex;
-    if (Search(nRow, nIndex))
-        if (!pItems[nIndex].pCell->IsBlank())
+    if (Search(nRow, nIndex)) {
+        ScAddress aPos( nCol, nRow, nTab );
+        if (!pItems[nIndex].pCell->IsBlank() || pDocument->GetNote(aPos))
             return true;
+    }
 
     return false;
 }
@@ -1249,8 +1259,10 @@ bool ScColumn::IsEmptyBlock(SCROW nStartRow, SCROW nEndRow, bool bIgnoreNotes) c
     Search( nStartRow, nIndex );
     while ( nIndex < nCount && pItems[nIndex].nRow <= nEndRow )
     {
-        if ( !pItems[nIndex].pCell->IsBlank( bIgnoreNotes ) )   // found a cell
-            return false;                           // not empty
+        if (   ( ! pItems[nIndex].pCell->IsBlank() )
+            || ( ! bIgnoreNotes && pDocument->GetNote( ScAddress( nCol, pItems[nIndex].nRow, nTab )))
+           )
+            return false;  // not empty if even one cell is not blank or has a note
         ++nIndex;
     }
     return true;                                    // no cell found
@@ -1263,6 +1275,7 @@ SCSIZE ScColumn::GetEmptyLinesInBlock( SCROW nStartRow, SCROW nEndRow, ScDirecti
     SCSIZE i;
     if (pItems && (nCount > 0))
     {
+        ScAddress aPos( nCol, 0, nTab );
         if (eDir == DIR_BOTTOM)
         {
             i = nCount;
@@ -1271,7 +1284,9 @@ SCSIZE ScColumn::GetEmptyLinesInBlock( SCROW nStartRow, SCROW nEndRow, ScDirecti
                 i--;
                 if ( pItems[i].nRow < nStartRow )
                     break;
-                bFound = pItems[i].nRow <= nEndRow && !pItems[i].pCell->IsBlank();
+                aPos.SetRow( pItems[i].nRow );
+                ScPostIt* aNote = pDocument->GetNote( aPos );
+                bFound = pItems[i].nRow <= nEndRow && (!pItems[i].pCell->IsBlank() || aNote );
             }
             if (bFound)
                 nLines = static_cast<SCSIZE>(nEndRow - pItems[i].nRow);
@@ -1285,7 +1300,9 @@ SCSIZE ScColumn::GetEmptyLinesInBlock( SCROW nStartRow, SCROW nEndRow, ScDirecti
             {
                 if ( pItems[i].nRow > nEndRow )
                     break;
-                bFound = pItems[i].nRow >= nStartRow && !pItems[i].pCell->IsBlank();
+                aPos.SetRow( pItems[i].nRow );
+                ScPostIt* aNote = pDocument->GetNote( aPos );
+                bFound = pItems[i].nRow >= nStartRow && (!pItems[i].pCell->IsBlank() || aNote );
                 i++;
             }
             if (bFound)
@@ -1348,8 +1365,14 @@ void ScColumn::FindDataAreaPos(SCROW& rRow, long nMovY) const
 
     SCSIZE nIndex;
     bool bThere = Search(rRow, nIndex);
-    if (bThere && pItems[nIndex].pCell->IsBlank())
-        bThere = false;
+    ScAddress aPos( nCol, 0, nTab );
+    if (bThere) {
+        aPos.SetRow(pItems[nIndex].nRow);
+        if (    pItems[nIndex].pCell->IsBlank()
+            && (0 == pDocument->GetNote( aPos ) )
+           )
+            bThere = false;
+    }
 
     if (bThere)
     {
@@ -1360,14 +1383,22 @@ void ScColumn::FindDataAreaPos(SCROW& rRow, long nMovY) const
             if (nIndex<nCount-1)
             {
                 ++nIndex;
-                while (nIndex<nCount-1 && pItems[nIndex].nRow==nLast+1
-                                        && !pItems[nIndex].pCell->IsBlank())
+                aPos.SetRow( pItems[nIndex].nRow );
+                while (   nIndex < nCount -1
+                       && pItems[nIndex].nRow == nLast +1
+                       && (   ! pItems[nIndex].pCell->IsBlank()
+                           || pDocument->GetNote( aPos ) )
+                      )
                 {
                     ++nIndex;
                     ++nLast;
+                    aPos.SetRow( pItems[nIndex].nRow );
                 }
-                if (nIndex==nCount-1)
-                    if (pItems[nIndex].nRow==nLast+1 && !pItems[nIndex].pCell->IsBlank())
+                if ( nIndex == nCount -1 )
+                    if (    pItems[nIndex].nRow == nLast +1
+                        && (   ! pItems[nIndex].pCell->IsBlank()
+                            || pDocument->GetNote( aPos ) )
+                       )
                         ++nLast;
             }
         }
@@ -1376,14 +1407,22 @@ void ScColumn::FindDataAreaPos(SCROW& rRow, long nMovY) const
             if (nIndex>0)
             {
                 --nIndex;
-                while (nIndex>0 && pItems[nIndex].nRow+1==nLast
-                                        && !pItems[nIndex].pCell->IsBlank())
+                aPos.SetRow( pItems[nIndex].nRow );
+                while (   nIndex > 0
+                       && pItems[nIndex].nRow +1 == nLast
+                       && (   ! pItems[nIndex].pCell->IsBlank()
+                           || pDocument->GetNote( aPos ) )
+                      )
                 {
                     --nIndex;
                     --nLast;
+                    aPos.SetRow( pItems[nIndex].nRow );
                 }
-                if (nIndex==0)
-                    if (pItems[nIndex].nRow+1==nLast && !pItems[nIndex].pCell->IsBlank())
+                if ( 0 == nIndex )
+                    if (   pItems[nIndex].nRow +1 == nLast
+                        && (   ! pItems[nIndex].pCell->IsBlank()
+                            || pDocument->GetNote( aPos ) )
+                       )
                         --nLast;
             }
         }
@@ -1398,10 +1437,17 @@ void ScColumn::FindDataAreaPos(SCROW& rRow, long nMovY) const
 
     if (!bThere)
     {
+        aPos.SetRow( pItems[nIndex].nRow );
         if (bForward)
         {
-            while (nIndex<nCount && pItems[nIndex].pCell->IsBlank())
+            while (   nIndex < nCount
+                   && (  pItems[nIndex].pCell->IsBlank()
+                       && (0 == pDocument->GetNote( aPos )) )
+                  )
+            {
                 ++nIndex;
+                aPos.SetRow( pItems[nIndex].nRow );
+            }
             if (nIndex<nCount)
                 rRow = pItems[nIndex].nRow;
             else
@@ -1409,8 +1455,14 @@ void ScColumn::FindDataAreaPos(SCROW& rRow, long nMovY) const
         }
         else
         {
-            while (nIndex>0 && pItems[nIndex-1].pCell->IsBlank())
+            while (   nIndex > 0
+                   && (   pItems[nIndex-1].pCell->IsBlank()
+                       && (0 == pDocument->GetNote( aPos )) )
+                  )
+            {
                 --nIndex;
+                aPos.SetRow( pItems[nIndex].nRow );
+            }
             if (nIndex>0)
                 rRow = pItems[nIndex-1].nRow;
             else
@@ -1426,7 +1478,9 @@ bool ScColumn::HasDataAt(SCROW nRow) const
 
     SCSIZE nIndex;
     if (Search(nRow, nIndex))
-        if (!pItems[nIndex].pCell->IsBlank())
+        if (   ! pItems[nIndex].pCell->IsBlank()
+            || pDocument->GetNote( ScAddress( nCol, nRow, nTab ))
+           )
             return true;
 
     return false;
@@ -1503,7 +1557,7 @@ void ScColumn::StartListening( SvtListener& rLst, SCROW nRow )
     }
     else
     {
-        pCell = new ScNoteCell;
+        pCell = new ScEmptyCell;
         Insert(nRow, pCell);
     }
 
@@ -1528,7 +1582,7 @@ void ScColumn::MoveListeners( SvtBroadcaster& rSource, SCROW nDestRow )
     }
     else
     {
-        pCell = new ScNoteCell;
+        pCell = new ScEmptyCell;
         Insert(nDestRow, pCell);
     }
 
@@ -1562,7 +1616,7 @@ void ScColumn::EndListening( SvtListener& rLst, SCROW nRow )
 
             if (!pBC->HasListeners())
             {
-                if (pCell->IsBlank())
+                if (pCell->IsBlank() && (0 == pDocument->GetNote(ScAddress(nCol, nRow, nTab))) )
                     DeleteAtIndex(nIndex);
                 else
                     pCell->DeleteBroadcaster();
@@ -1645,7 +1699,7 @@ void lcl_UpdateSubTotal( ScFunctionData& rData, ScBaseCell* pCell )
                 }
             }
             break;
-        case CELLTYPE_NOTE:
+        case CELLTYPE_EMPTY:
             bCell = false;
             break;
         // bei Strings nichts
diff --git a/sc/source/core/data/column3.cxx b/sc/source/core/data/column3.cxx
index baa0518..e39cbe1 100644
--- a/sc/source/core/data/column3.cxx
+++ b/sc/source/core/data/column3.cxx
@@ -88,12 +88,17 @@ void ScColumn::Insert( SCROW nRow, ScBaseCell* pNewCell )
         if (Search(nRow, nIndex))
         {
             ScBaseCell* pOldCell = pItems[nIndex].pCell;
+            ScAddress oldAddy( nCol, pItems[nIndex].nRow, nTab );
+            ScAddress newAddy( nCol, nRow, nTab );
+            ScPostIt* oldNote = pDocument->GetNote( oldAddy );
+            ScPostIt* newNote = pDocument->GetNote( newAddy );
 
             // move broadcaster and note to new cell, if not existing in new cell
             if (pOldCell->HasBroadcaster() && !pNewCell->HasBroadcaster())
                 pNewCell->TakeBroadcaster( pOldCell->ReleaseBroadcaster() );
-            if (pOldCell->HasNote() && !pNewCell->HasNote())
-                pNewCell->TakeNote( pOldCell->ReleaseNote() );
+
+            if ( oldNote && !newNote )
+                pDocument->MoveNote( oldAddy, newAddy );
 
             if ( pOldCell->GetCellType() == CELLTYPE_FORMULA && !pDocument->IsClipOrUndo() )
             {
@@ -148,7 +153,7 @@ void ScColumn::Insert( SCROW nRow, ScBaseCell* pNewCell )
         CellType eCellType = pNewCell->GetCellType();
         // Notizzelle entsteht beim Laden nur durch StartListeningCell,
         // ausloesende Formelzelle muss sowieso dirty sein.
-        if ( !(pDocument->IsCalcingAfterLoad() && eCellType == CELLTYPE_NOTE) )
+        if ( !(pDocument->IsCalcingAfterLoad() && eCellType == CELLTYPE_EMPTY) )
         {
             if ( eCellType == CELLTYPE_FORMULA )
                 ((ScFormulaCell*)pNewCell)->SetDirty();
@@ -212,17 +217,17 @@ void ScColumn::Delete( SCROW nRow )
     if (Search(nRow, nIndex))
     {
         ScBaseCell* pCell = pItems[nIndex].pCell;
-        ScNoteCell* pNoteCell = new ScNoteCell;
-        pItems[nIndex].pCell = pNoteCell;       // Dummy fuer Interpret
+        ScEmptyCell* pEmptyCell = new ScEmptyCell;
+        pItems[nIndex].pCell = pEmptyCell;      // Dummy, for Interpret
         pDocument->Broadcast( ScHint( SC_HINT_DYING,
             ScAddress( nCol, nRow, nTab ), pCell ) );
         if ( SvtBroadcaster* pBC = pCell->ReleaseBroadcaster() )
         {
-            pNoteCell->TakeBroadcaster( pBC );
+            pEmptyCell->TakeBroadcaster( pBC );
         }
         else
         {
-            pNoteCell->Delete();
+            pEmptyCell->Delete();
             --nCount;
             memmove( &pItems[nIndex], &pItems[nIndex + 1], (nCount - nIndex) * sizeof(ColEntry) );
             pItems[nCount].nRow = 0;
@@ -238,11 +243,11 @@ void ScColumn::Delete( SCROW nRow )
 void ScColumn::DeleteAtIndex( SCSIZE nIndex )
 {
     ScBaseCell* pCell = pItems[nIndex].pCell;
-    ScNoteCell* pNoteCell = new ScNoteCell;
-    pItems[nIndex].pCell = pNoteCell;       // Dummy fuer Interpret
+    ScEmptyCell* pEmptyCell = new ScEmptyCell;
+    pItems[nIndex].pCell = pEmptyCell;      // Dummy, for Interpret
     pDocument->Broadcast( ScHint( SC_HINT_DYING,
         ScAddress( nCol, pItems[nIndex].nRow, nTab ), pCell ) );
-    pNoteCell->Delete();
+    pEmptyCell->Delete();
     --nCount;
     memmove( &pItems[nIndex], &pItems[nIndex + 1], (nCount - nIndex) * sizeof(ColEntry) );
     pItems[nCount].nRow = 0;
@@ -374,13 +379,20 @@ void ScColumn::DeleteRange( SCSIZE nStartIndex, SCSIZE nEndIndex, sal_uInt16 nDe
         drawing undo. */
     bool bDeleteNote = (nDelFlag & IDF_NOTE) != 0;
     bool bNoCaptions = (nDelFlag & IDF_NOCAPTIONS) != 0;
-    if (bDeleteNote && bNoCaptions)
-        for ( SCSIZE nIdx = nStartIndex; nIdx <= nEndIndex; ++nIdx )
-            if ( ScPostIt* pNote = pItems[ nIdx ].pCell->GetNote() )
+
+    if (bDeleteNote && bNoCaptions) {
+        for ( SCSIZE nIdx = nStartIndex; nIdx <= nEndIndex; ++nIdx ) {
+            ScPostIt* pNote = pDocument->GetNote(
+              ScAddress( nCol, pItems[ nIdx ].nRow, nTab )
+            );
+            if ( pNote )
                 pNote->ForgetCaption();
+        }
+    }
 
     ScHint aHint( SC_HINT_DYING, ScAddress( nCol, 0, nTab ), 0 );
 
+
     // cache all formula cells, they will be deleted at end of this function
     typedef ::std::vector< ScFormulaCell* > FormulaCellVector;
     FormulaCellVector aDelCells;
@@ -391,7 +403,7 @@ void ScColumn::DeleteRange( SCSIZE nStartIndex, SCSIZE nEndIndex, sal_uInt16 nDe
     SCSIZE nFirst(nStartIndex);
 
     // dummy replacement for old cells, to prevent that interpreter uses old cell
-    boost::scoped_ptr<ScNoteCell> pDummyCell(new ScNoteCell);
+    boost::scoped_ptr<ScEmptyCell> pDummyCell(new ScEmptyCell);
 
     for ( SCSIZE nIdx = nStartIndex; nIdx <= nEndIndex; ++nIdx )
     {
@@ -424,7 +436,7 @@ void ScColumn::DeleteRange( SCSIZE nStartIndex, SCSIZE nEndIndex, sal_uInt16 nDe
                 bDelete = true;
             else
             {
-                // decide whether to delete the cell object according to passed 
+                // decide whether to delete the cell object according to passed
                 // flags
                 switch ( eCellType )
                 {
@@ -455,7 +467,7 @@ void ScColumn::DeleteRange( SCSIZE nStartIndex, SCSIZE nEndIndex, sal_uInt16 nDe
                         bDelete = (nDelFlag & IDF_FORMULA) != 0;
                         break;
 
-                    case CELLTYPE_NOTE:
+                    case CELLTYPE_EMPTY:
                         // do note delete note cell with broadcaster
                         bDelete = bDeleteNote && !pOldCell->GetBroadcaster();
                         break;
@@ -467,23 +479,28 @@ void ScColumn::DeleteRange( SCSIZE nStartIndex, SCSIZE nEndIndex, sal_uInt16 nDe
             if (bDelete)
             {
                 // try to create a replacement note cell, if note or broadcaster exists
-                ScNoteCell* pNoteCell = 0;
-                if (eCellType != CELLTYPE_NOTE)
+                ScEmptyCell* pEmptyCell = 0;
+                if (eCellType != CELLTYPE_EMPTY)
                 {
-                    // do not rescue note if it has to be deleted according to passed flags
-                    ScPostIt* pNote = bDeleteNote ? 0 : pOldCell->ReleaseNote();
-                    // #i99844# do not release broadcaster from old cell, it still has to notify deleted content
+                    // do not rescue note if it has to be deleted according to
+                    // passed flags
+                    // #i99844# do not release broadcaster from old cell, it
+                    // still has to notify deleted content
                     SvtBroadcaster* pBC = pOldCell->GetBroadcaster();
-                    if( pNote || pBC )
-                        pNoteCell = new ScNoteCell( pNote, pBC );
+                    if ( ! bDeleteNote || pBC )
+                        pEmptyCell = new ScEmptyCell( pBC );
+                    else
+                        pDocument->DeleteNote(
+                          ScAddress(nCol, pItems[nIdx].nRow, nTab)
+                        );
                 }
 
                 // remove cell entry in cell item list
                 SCROW nOldRow = pItems[nIdx].nRow;
-                if (pNoteCell)
+                if (pEmptyCell)
                 {
                     // replace old cell with the replacement note cell
-                    pItems[nIdx].pCell = pNoteCell;
+                    pItems[nIdx].pCell = pEmptyCell;
                     // ... so it's not really deleted
                     bDelete = false;
                 }
@@ -500,16 +517,15 @@ void ScColumn::DeleteRange( SCSIZE nStartIndex, SCSIZE nEndIndex, sal_uInt16 nDe
                     aHint.GetAddress().SetRow( nOldRow );
                     aHint.SetCell( pOldCell );
                     pDocument->Broadcast( aHint );
-                    // #i99844# after broadcasting, old cell has to forget the broadcaster (owned by pNoteCell)
+                    // #i99844# after broadcasting, old cell has to forget the broadcaster (owned by pEmptyCell)
                     pOldCell->ReleaseBroadcaster();
                     pOldCell->Delete();
                 }
             }
             else
             {
-                // delete cell note
                 if (bDeleteNote)
-                    pItems[nIdx].pCell->DeleteNote();
+                    pDocument->DeleteNote( ScAddress(nCol, pItems[nIdx].nRow, nTab) );
             }
 
             if (!bDelete)
@@ -543,7 +559,7 @@ void ScColumn::DeleteRange( SCSIZE nStartIndex, SCSIZE nEndIndex, sal_uInt16 nDe
             { // this segment removed
                 if (!bRemoved)
                     nStartSegment = aIt->first;
-                    // The first of removes in a row sets start (they should be 
+                    // The first of removes in a row sets start (they should be
                     // alternating removed/notremoved anyway).
                 bRemoved = true;
             }
@@ -562,7 +578,7 @@ void ScColumn::DeleteRange( SCSIZE nStartIndex, SCSIZE nEndIndex, sal_uInt16 nDe
             }
             ++aIt;
         }
-        // The last removed segment up to nCount is discarded, there's nothing 
+        // The last removed segment up to nCount is discarded, there's nothing
         // following to be moved.
         if (bRemoved)
             nShift += nCount - nStartSegment;
@@ -730,7 +746,7 @@ void ScColumn::CopyFromClip(SCROW nRow1, SCROW nRow2, long nDy,
             while ( nStartIndex < rColumn.nCount && rColumn.pItems[nStartIndex].nRow <= nRow2-nDy )
             {
                 SCSIZE nEndIndex = nStartIndex;
-                if ( rColumn.pItems[nStartIndex].pCell->GetCellType() != CELLTYPE_NOTE )
+                if ( rColumn.pItems[nStartIndex].pCell->GetCellType() != CELLTYPE_EMPTY )
                 {
                     SCROW nStartRow = rColumn.pItems[nStartIndex].nRow;
                     SCROW nEndRow = nStartRow;
@@ -740,7 +756,7 @@ void ScColumn::CopyFromClip(SCROW nRow1, SCROW nRow2, long nDy,
                     while ( nEndRow < nRow2-nDy &&
                             nEndIndex+1 < rColumn.nCount &&
                             rColumn.pItems[nEndIndex+1].nRow == nEndRow+1 &&
-                            rColumn.pItems[nEndIndex+1].pCell->GetCellType() != CELLTYPE_NOTE )
+                            rColumn.pItems[nEndIndex+1].pCell->GetCellType() != CELLTYPE_EMPTY )
                     {
                         ++nEndIndex;
                         ++nEndRow;
@@ -825,25 +841,29 @@ void ScColumn::CopyFromClip(SCROW nRow1, SCROW nRow2, long nDy,
                 passed together with IDF_NOTE in nInsFlag. Of course, there is
                 still the need to create a new cell, if there is no cell at the
                 destination position at all. */
-            ScBaseCell* pAddNoteCell = bAddNotes ? GetCell( aDestPos.Row() ) : 0;
-            if (pAddNoteCell)
+            ScBaseCell* pNewCell = bAddNotes ? GetCell( aDestPos.Row() ) : 0;
+            if (pNewCell)
             {
                 // do nothing if source cell does not contain a note
-                const ScBaseCell* pSourceCell = rColumn.pItems[i].pCell;
-                const ScPostIt* pSourceNote = pSourceCell ? pSourceCell->GetNote() : 0;
-                if (pSourceNote)
+                ScPostIt* pSourceNote = 0;
+                ScAddress aSourcePos( rColumn.nCol, rColumn.pItems[i].nRow, rColumn.nTab );
+                if ( rColumn.pItems[i].pCell )
+                    pSourceNote = pDocument->GetNote( aSourcePos );
+
+                if ( pSourceNote )
                 {
-                    OSL_ENSURE( !pAddNoteCell->HasNote(), "ScColumn::CopyFromClip - unexpected note at destination cell" );
                     bool bCloneCaption = (nInsFlag & IDF_NOCAPTIONS) == 0;
                     // #i52342# if caption is cloned, the note must be constructed with the destination document
-                    ScAddress aSourcePos( rColumn.nCol, rColumn.pItems[i].nRow, rColumn.nTab );
                     ScPostIt* pNewNote = pSourceNote->Clone( aSourcePos, *pDocument, aDestPos, bCloneCaption );
-                    pAddNoteCell->TakeNote( pNewNote );
+                    ScAddress newAddy( nCol, aDestPos.Row(), nTab );
+
+                    if ( ! pDocument->SetNote( newAddy, pNewNote ) )
+                        DELETEZ( pNewNote ); // apparently unsuccessful; no leak
                 }
             }
             else
             {
-                ScBaseCell* pNewCell = bAsLink ?
+                pNewCell = bAsLink ?
                     rColumn.CreateRefCell( pDocument, aDestPos, i, nInsFlag ) :
                     rColumn.CloneCell( i, nInsFlag, *pDocument, aDestPos );
                 if (pNewCell)
@@ -887,7 +907,7 @@ ScBaseCell* ScColumn::CloneCell(SCSIZE nIndex, sal_uInt16 nFlags, ScDocument& rD
     ScBaseCell& rSource = *pItems[nIndex].pCell;
     switch (rSource.GetCellType())
     {
-        case CELLTYPE_NOTE:
+        case CELLTYPE_EMPTY:
             // note will be cloned below
         break;
 
@@ -895,13 +915,13 @@ ScBaseCell* ScColumn::CloneCell(SCSIZE nIndex, sal_uInt16 nFlags, ScDocument& rD
         case CELLTYPE_EDIT:
             // note will be cloned below
             if (bCloneString)
-                pNew = rSource.CloneWithoutNote( rDestDoc, rDestPos );
+                pNew = rSource.Clone( rDestDoc, rDestPos );
         break;
 
         case CELLTYPE_VALUE:
             // note will be cloned below
             if (lclCanCloneValue( *pDocument, *this, pItems[nIndex].nRow, bCloneValue, bCloneDateTime ))
-                pNew = rSource.CloneWithoutNote( rDestDoc, rDestPos );
+                pNew = rSource.Clone( rDestDoc, rDestPos );
         break;
 
         case CELLTYPE_FORMULA:
@@ -919,7 +939,7 @@ ScBaseCell* ScColumn::CloneCell(SCSIZE nIndex, sal_uInt16 nFlags, ScDocument& rD
             if (bForceFormula || bCloneFormula)
             {
                 // note will be cloned below
-                pNew = rSource.CloneWithoutNote( rDestDoc, rDestPos );
+                pNew = rSource.Clone( rDestDoc, rDestPos );
             }
             else if ( (bCloneValue || bCloneDateTime || bCloneString) && !rDestDoc.IsUndo() )
             {
@@ -971,16 +991,20 @@ ScBaseCell* ScColumn::CloneCell(SCSIZE nIndex, sal_uInt16 nFlags, ScDocument& rD
     // clone the cell note
     if (bCloneNote)
     {
-        if (ScPostIt* pNote = rSource.GetNote())
+        ScAddress aOwnPos( nCol, pItems[nIndex].nRow, nTab );
+        ScPostIt* pNote = pDocument->GetNote( aOwnPos );
+
+        if ( pNote )
         {
             bool bCloneCaption = (nFlags & IDF_NOCAPTIONS) == 0;
-            // #i52342# if caption is cloned, the note must be constructed with the destination document
-            ScAddress aOwnPos( nCol, pItems[nIndex].nRow, nTab );
+            // #i52342# if caption is cloned, the note must be constructed
+            // with the destination document
             ScPostIt* pNewNote = pNote->Clone( aOwnPos, rDestDoc, rDestPos, bCloneCaption );
+            if ( ! rDestDoc.SetNote( rDestPos, pNewNote ) )
+                DELETEZ( pNewNote ); // apparently unsuccessful; don't leak
+
             if (!pNew)
-                pNew = new ScNoteCell( pNewNote );
-            else
-                pNew->TakeNote( pNewNote );
+                pNew = new ScEmptyCell();
         }
     }
 
@@ -1086,14 +1110,14 @@ void ScColumn::MixData( SCROW nRow1, SCROW nRow2,
         CellType eSrcType  = pSrc  ? pSrc->GetCellType()  : CELLTYPE_NONE;
         CellType eDestType = pDest ? pDest->GetCellType() : CELLTYPE_NONE;
 
-        sal_Bool bSrcEmpty = ( eSrcType == CELLTYPE_NONE || eSrcType == CELLTYPE_NOTE );
-        sal_Bool bDestEmpty = ( eDestType == CELLTYPE_NONE || eDestType == CELLTYPE_NOTE );
+        sal_Bool bSrcEmpty  = ( eSrcType  == CELLTYPE_NONE || eSrcType  == CELLTYPE_EMPTY );
+        sal_Bool bDestEmpty = ( eDestType == CELLTYPE_NONE || eDestType == CELLTYPE_EMPTY );
 
         if ( bSkipEmpty && bDestEmpty )     // Originalzelle wiederherstellen
         {
             if ( pSrc )                     // war da eine Zelle?
             {
-                pNew = pSrc->CloneWithoutNote( *pDocument );
+                pNew = pSrc->Clone( *pDocument );
             }
         }
         else if ( nFunction )               // wirklich Rechenfunktion angegeben
@@ -1149,7 +1173,7 @@ void ScColumn::MixData( SCROW nRow1, SCROW nRow2,
                 //  mit Texten wird nicht gerechnet - immer "alte" Zelle, also pSrc
 
                 if (pSrc)
-                    pNew = pSrc->CloneWithoutNote( *pDocument );
+                    pNew = pSrc->Clone( *pDocument );
                 else if (pDest)
                     bDelete = sal_True;
             }
@@ -1192,7 +1216,7 @@ void ScColumn::MixData( SCROW nRow1, SCROW nRow2,
             if (pDest && !pNew)                     // alte Zelle da ?
             {
                 if ( pDest->GetBroadcaster() )
-                    pNew = new ScNoteCell;          // Broadcaster uebernehmen
+                    pNew = new ScEmptyCell;         // Broadcaster uebernehmen
                 else
                     Delete(nRow);                   // -> loeschen
             }
@@ -1395,7 +1419,7 @@ bool ScColumn::SetString( SCROW nRow, SCTAB nTabP, const String& rString,
                                 if ( rString == aStr )
                                     bIsText = true;
                             break;
-                            case CELLTYPE_NOTE :    // durch =Formel referenziert
+                            case CELLTYPE_EMPTY :   // durch =Formel referenziert
                             break;
                             default:
                                 if ( i == nCount - 1 )
@@ -1515,14 +1539,17 @@ bool ScColumn::SetString( SCROW nRow, SCTAB nTabP, const String& rString,
         if (Search(nRow, i))
         {
             ScBaseCell* pOldCell = pItems[i].pCell;
-            ScPostIt* pNote = pOldCell->ReleaseNote();
             SvtBroadcaster* pBC = pOldCell->ReleaseBroadcaster();
+
+            ScPostIt* pNote = pDocument->GetNote(
+              ScAddress( nCol, pItems[i].nRow, nTab )
+            );
+
             if (pNewCell || pNote || pBC)
             {
-                if (pNewCell)
-                    pNewCell->TakeNote( pNote );
-                else
-                    pNewCell = new ScNoteCell( pNote );
+                if ( ! pNewCell )
+                    pNewCell = new ScEmptyCell();
+
                 if (pBC)
                 {
                     pNewCell->TakeBroadcaster(pBC);
@@ -1786,7 +1813,7 @@ void ScColumn::GetString( SCROW nRow, String& rString ) const
     if (Search(nRow, nIndex))
     {
         ScBaseCell* pCell = pItems[nIndex].pCell;
-        if (pCell->GetCellType() != CELLTYPE_NOTE)
+        if (pCell->GetCellType() != CELLTYPE_EMPTY)
         {
             sal_uLong nFormat = GetNumberFormat( nRow );
             ScCellFormat::GetString( pCell, nFormat, rString, &pColor, *(pDocument->GetFormatTable()) );
@@ -1805,7 +1832,7 @@ void ScColumn::GetInputString( SCROW nRow, String& rString ) const
     if (Search(nRow, nIndex))
     {
         ScBaseCell* pCell = pItems[nIndex].pCell;
-        if (pCell->GetCellType() != CELLTYPE_NOTE)
+        if (pCell->GetCellType() != CELLTYPE_EMPTY)
         {
             sal_uLong nFormat = GetNumberFormat( nRow );
             ScCellFormat::GetInputString( pCell, nFormat, rString, *(pDocument->GetFormatTable()) );
@@ -1921,44 +1948,6 @@ bool ScColumn::HasStringCells( SCROW nStartRow, SCROW nEndRow ) const
 }
 
 
-ScPostIt* ScColumn::GetNote( SCROW nRow )
-{
-    SCSIZE nIndex;
-    return Search( nRow, nIndex ) ? pItems[ nIndex ].pCell->GetNote() : 0;
-}
-
-
-void ScColumn::TakeNote( SCROW nRow, ScPostIt* pNote )
-{
-    SCSIZE nIndex;
-    if( Search( nRow, nIndex ) )
-        pItems[ nIndex ].pCell->TakeNote( pNote );
-    else
-        Insert( nRow, new ScNoteCell( pNote ) );
-}
-
-
-ScPostIt* ScColumn::ReleaseNote( SCROW nRow )
-{
-    ScPostIt* pNote = 0;
-    SCSIZE nIndex;
-    if( Search( nRow, nIndex ) )
-    {
-        ScBaseCell* pCell = pItems[ nIndex ].pCell;
-        pNote = pCell->ReleaseNote();
-        if( (pCell->GetCellType() == CELLTYPE_NOTE) && !pCell->GetBroadcaster() )
-            DeleteAtIndex( nIndex );
-    }
-    return pNote;
-}
-
-
-void ScColumn::DeleteNote( SCROW nRow )
-{
-    delete ReleaseNote( nRow );
-}
-
-
 sal_Int32 ScColumn::GetMaxStringLen( SCROW nRowStart, SCROW nRowEnd, CharSet eCharSet ) const
 {
     sal_Int32 nStringLen = 0;
@@ -1974,7 +1963,7 @@ sal_Int32 ScColumn::GetMaxStringLen( SCROW nRowStart, SCROW nRowEnd, CharSet eCh
         while ( nIndex < nCount && (nRow = pItems[nIndex].nRow) <= nRowEnd )
         {
             ScBaseCell* pCell = pItems[nIndex].pCell;
-            if ( pCell->GetCellType() != CELLTYPE_NOTE )
+            if ( pCell->GetCellType() != CELLTYPE_EMPTY )
             {
                 Color* pColor;
                 sal_uLong nFormat = (sal_uLong) ((SfxUInt32Item*) GetAttr(
diff --git a/sc/source/core/data/dociter.cxx b/sc/source/core/data/dociter.cxx
index bc9689b..b4e0681 100644
--- a/sc/source/core/data/dociter.cxx
+++ b/sc/source/core/data/dociter.cxx
@@ -1160,7 +1160,7 @@ ScBaseCell* ScQueryCellIterator::GetThis()
                 (nRow = pCol->pItems[nColRow].nRow) <= aParam.nRow2 )
         {
             ScBaseCell* pCell = pCol->pItems[nColRow].pCell;
-            if ( pCell->GetCellType() == CELLTYPE_NOTE )
+            if ( pCell->GetCellType() == CELLTYPE_EMPTY )
                 ++nRow;
             else if (bAllStringIgnore && pCell->HasStringData())
                 ++nRow;
@@ -1472,7 +1472,7 @@ ScBaseCell* ScQueryCellIterator::BinarySearch()
     {
         SCSIZE nMid = (nLo+nHi)/2;
         SCSIZE i = nMid;
-        while (i <= nHi && pItems[i].pCell->GetCellType() == CELLTYPE_NOTE)
+        while (i <= nHi && pItems[i].pCell->GetCellType() == CELLTYPE_EMPTY)
             ++i;
         if (i > nHi)
         {
@@ -1920,10 +1920,12 @@ inline sal_Bool IsGreater( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2 )
     return ( nRow1 > nRow2 ) || ( nRow1 == nRow2 && nCol1 > nCol2 );
 }
 
-ScUsedAreaIterator::ScUsedAreaIterator( ScDocument* pDocument, SCTAB nTable,
+ScUsedAreaIterator::ScUsedAreaIterator( ScDocument* pDocument, SCTAB nTab,
                             SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2 ) :
-    aCellIter( pDocument, nTable, nCol1, nRow1, nCol2, nRow2 ),
-    aAttrIter( pDocument, nTable, nCol1, nRow1, nCol2, nRow2 ),
+    aCellIter( pDocument, nTab, nCol1, nRow1, nCol2, nRow2 ),
+    aAttrIter( pDocument, nTab, nCol1, nRow1, nCol2, nRow2 ),
+    pDoc( pDocument ),
+    nTable( nTab ),
     nNextCol( nCol1 ),
     nNextRow( nRow1 )
 {
@@ -1942,7 +1944,11 @@ sal_Bool ScUsedAreaIterator::GetNext()
     if ( pCell && IsGreater( nNextCol, nNextRow, nCellCol, nCellRow ) )
         pCell = aCellIter.GetNext( nCellCol, nCellRow );
 
-    while ( pCell && pCell->IsBlank() )
+    while (   pCell
+           && (   pCell->IsBlank()
+               && (0 == pDoc->GetNote( ScAddress(nCellCol, nCellRow, nTable)))
+              )
+          )
         pCell = aCellIter.GetNext( nCellCol, nCellRow );
 
     if ( pPattern && IsGreater( nNextCol, nNextRow, nAttrCol2, nAttrRow ) )
diff --git a/sc/source/core/data/documen2.cxx b/sc/source/core/data/documen2.cxx
index 97d8344..e6b4c51 100644
--- a/sc/source/core/data/documen2.cxx
+++ b/sc/source/core/data/documen2.cxx
@@ -124,7 +124,6 @@ private:
 };
 
 // STATIC DATA -----------------------------------------------------------
-
 ScDocument::ScDocument( ScDocumentMode  eMode,
                         SfxObjectShell* pDocShell ) :
         xServiceManager( ::comphelper::getProcessServiceFactory() ),
diff --git a/sc/source/core/data/documen4.cxx b/sc/source/core/data/documen4.cxx
index f821ccf..bb3230d 100644
--- a/sc/source/core/data/documen4.cxx
+++ b/sc/source/core/data/documen4.cxx
@@ -76,12 +76,12 @@ sal_Bool ScDocument::Solver(SCCOL nFCol, SCROW nFRow, SCTAB nFTab,
         CellType eFType, eVType;
         GetCellType(nFCol, nFRow, nFTab, eFType);
         GetCellType(nVCol, nVRow, nVTab, eVType);
-        // CELLTYPE_NOTE: no value, but referenced by formula
+        // CELLTYPE_EMPTY: no value, but referenced by formula
         // #i108005# convert target value to number using default format,
         // as previously done in ScInterpreter::GetDouble
         double nTargetVal = 0.0;
         sal_uInt32 nFIndex = 0;
-        if (eFType == CELLTYPE_FORMULA && (eVType == CELLTYPE_VALUE || eVType == CELLTYPE_NOTE) &&
+        if (CELLTYPE_FORMULA == eFType && (CELLTYPE_VALUE == eVType || CELLTYPE_EMPTY == eVType) &&
             GetFormatTable()->IsNumberFormat(sValStr, nFIndex, nTargetVal))
         {
             ScSingleRefData aRefData;
@@ -172,7 +172,7 @@ void ScDocument::InsertMatrixFormula(SCCOL nCol1, SCROW nRow1,
             if (*itr == nTab1)
                 maTabs[*itr]->PutCell(nCol1, nRow1, pCell);
             else
-                maTabs[*itr]->PutCell(nCol1, nRow1, pCell->CloneWithoutNote(*this, ScAddress( nCol1, nRow1, *itr), SC_CLONECELL_STARTLISTENING));
+                maTabs[*itr]->PutCell(nCol1, nRow1, pCell->Clone(*this, ScAddress( nCol1, nRow1, *itr), SC_CLONECELL_STARTLISTENING));
         }
     }
 
@@ -308,7 +308,7 @@ void ScDocument::InsertTableOp(const ScTabOpParam& rParam,      // Mehrfachopera
                 itr = rMark.begin();
                 for (; itr != itrEnd && *itr < nMax; ++itr)
                 if( maTabs[*itr] )
-                    maTabs[*itr]->PutCell( j, k, aRefCell.CloneWithoutNote( *this, ScAddress( j, k, *itr ), SC_CLONECELL_STARTLISTENING ) );
+                    maTabs[*itr]->PutCell( j, k, aRefCell.Clone( *this, ScAddress( j, k, *itr ), SC_CLONECELL_STARTLISTENING ) );
             }
 }
 
@@ -836,8 +836,8 @@ sal_uInt16 ScDocument::RowDifferences( SCROW nThisRow, SCTAB nThisTab,
                     nDif += 4;      // Inhalt <-> leer zaehlt mehr
             }
 
-            if ( ( pThisCell  && pThisCell->GetCellType()!=CELLTYPE_NOTE ) ||
-                 ( pOtherCell && pOtherCell->GetCellType()!=CELLTYPE_NOTE ) )
+            if ( (pThisCell  && pThisCell->GetCellType()  != CELLTYPE_EMPTY) ||
+                 (pOtherCell && pOtherCell->GetCellType() != CELLTYPE_EMPTY) )
                 ++nUsed;
         }
     }
@@ -877,8 +877,8 @@ sal_uInt16 ScDocument::ColDifferences( SCCOL nThisCol, SCTAB nThisTab,
                     nDif += 4;      // Inhalt <-> leer zaehlt mehr
             }
 
-            if ( ( pThisCell  && pThisCell->GetCellType()!=CELLTYPE_NOTE ) ||
-                 ( pOtherCell && pOtherCell->GetCellType()!=CELLTYPE_NOTE ) )
+            if ( (pThisCell  && pThisCell->GetCellType()  != CELLTYPE_EMPTY) ||
+                 (pOtherCell && pOtherCell->GetCellType() != CELLTYPE_EMPTY) )
                 ++nUsed;
         }
     }
diff --git a/sc/source/core/data/document.cxx b/sc/source/core/data/document.cxx
index b9526d3..2cf366f 100644
--- a/sc/source/core/data/document.cxx
+++ b/sc/source/core/data/document.cxx
@@ -1895,8 +1895,9 @@ void ScDocument::CopyToClip(const ScClipParam& rClipParam,
         i = nTab;
         nEndTab = nTab;
     }
-    else
+    else {
         pClipDoc->ResetClip(this, pMarks);
+    }
 
     if ( bUseRangeForVBA )
         CopyRangeNamesToClip(pClipDoc, aClipRange, nTab );
@@ -3261,45 +3262,192 @@ sal_Bool ScDocument::HasSelectionData( SCCOL nCol, SCROW nRow, SCTAB nTab ) cons
 }
 
 
-ScPostIt* ScDocument::GetNote( const ScAddress& rPos )
+/** ScPostIt* ScDocument::GetNote( ScAddress const & aPos )
+
+Returns the ScPostIt object pointer associated with the document address aPos.
+If the specific cell does not have a note, returns the NULL pointer.
+
+Notes:
+
+- If an ScPostIt* exists for the specified address, but the cell is no
+  longer addressable (e.g. if the sheet was deleted, but the note was not
+  properly removed), this function will remove the note before returning NULL.
+*/
+ScPostIt* ScDocument::GetNote( ScAddress const & aPos )
 {
-    ScTable* pTable = ValidTab( rPos.Tab() ) && rPos.Tab() < static_cast<SCTAB>(maTabs.size()) ? maTabs[ rPos.Tab() ] : 0;
-    return pTable ? pTable->GetNote( rPos.Col(), rPos.Row() ) : 0;
+    std::map< const ScAddress, ScPostIt* >::iterator it;
+    it = pNotes.find( aPos );
+
+    if ( pNotes.end() == it )
+       return( 0 );
+
+    if (! ( ValidTab( aPos.Tab() )
+         && aPos.Tab() < static_cast<SCTAB>(maTabs.size()) )
+       )
+    {
+        DELETEZ( it->second );
+        pNotes.erase(it);
+        return( 0 );
+    }
+
+    return( it->second );
 }
 
 
-void ScDocument::TakeNote( const ScAddress& rPos, ScPostIt*& rpNote )
+/** bool ScDocument::SetNote( ScAddress const & aPos, ScPostIt* pNote )
+
+Set the ScPostIt for the cell at aPos to pNote.
+
+Returns true on success, or false if unable to set pNote for aPos.
+
+Notes:
+- If a note already exists at 'aPos', it will first be deleted, before putting
+  pNote as the new ScPostIt for 'aPos'.
+*/
+bool ScDocument::SetNote( ScAddress const & aPos, ScPostIt* pNote )
 {
-    if( ValidTab( rPos.Tab() ) && rPos.Tab() < static_cast<SCTAB>(maTabs.size()) && maTabs[ rPos.Tab() ] )
-        maTabs[ rPos.Tab() ]->TakeNote( rPos.Col(), rPos.Row(), rpNote );
-    else
-        DELETEZ( rpNote );
+    std::map< const ScAddress, ScPostIt* >::iterator it;
+    it = pNotes.find( aPos );
+
+    if ( pNotes.end() != it ) {
+        // if the note is the same as what's already there, do nothing ...
+        if ( it->second == pNote )
+            return true;
+
+        // ... otherwise, remove old note, before ...
+        DELETEZ( it->second );
+        pNotes.erase( it );
+    }
+
+    if ( ! ( ValidTab( aPos.Tab() )
+         && aPos.Tab() < static_cast<SCTAB>(maTabs.size()) )
+       )
+        return false;
+
+    if ( pNote ) // no sense adding an empty pointer
+        pNotes[ aPos ] = pNote;
+
+    return true;
 }
 
 
-ScPostIt* ScDocument::ReleaseNote( const ScAddress& rPos )
+/** ScPostIt* ScDocument::ReleaseNote( ScAddress const & aPos )
+
+Returns a pointer to the ScPostIt assigned to the document position aPos,
+removing it from cell address aPos.
+
+Notes:
+- When this function completes, the document will have no ScPostIt*
+  assigned to aPos.  Thus, the caller must dispose of, or otherwise deal with,
+  the returned *ScPostIt object.
+*/
+ScPostIt* ScDocument::ReleaseNote( ScAddress const & aPos )
+{
+    ScPostIt* pNote = 0;
+    std::map< const ScAddress, ScPostIt* >::iterator it;
+
+    it = pNotes.find( aPos );
+
+    if ( pNotes.end() != it )
+    {
+        pNote = it->second;
+        pNotes.erase( it );
+    }
+
+    return( pNote );
+}
+
+
+/** void ScDocument::DeleteNote( ScAddress const & aPos )
+
+Removes the ScPostIt object, if any, assigned to the document address aPos.
+*/
+void ScDocument::DeleteNote( ScAddress const & aPos )
 {
-    ScTable* pTable = ValidTab( rPos.Tab() ) && rPos.Tab() < static_cast<SCTAB>(maTabs.size())? maTabs[ rPos.Tab() ] : 0;
-    return pTable ? pTable->ReleaseNote( rPos.Col(), rPos.Row() ) : 0;
+    ScPostIt* pNote = ReleaseNote( aPos );
+    DELETEZ( pNote );
 }
 
 
+/** bool ScDocument::MoveNote( ScAddress const & aFrom, ScAddress const & aTo )
+
+Moves the ScPostIt object associated with aFrom to aTo.
+
+Returns true on success, false on failure.
+
+Notes:
+- Any ScPostIt object that exists at aTo is properly removed before insertion.
+- Not transactional.  If the function fails, there is no guarantee that any
+  ScPostIt at aTo or aFrom will still exist, although they will be properly
+  cleaned up if they don't.
+*/
+bool ScDocument::MoveNote( ScAddress const & aFrom, ScAddress const & aTo )
+{
+    ScPostIt* pFromNote = ReleaseNote( aFrom );
+    if ( SetNote( aTo, pFromNote ) )
+        return true;
+
+    // Doh!  An error occurred.  Attempt to not lose note, or at least
+    // don't leak the memory
+    if ( ! SetNote( aFrom, pFromNote ) )
+        DELETEZ( pFromNote );
+
+    return false;
+}
+
+
+/** bool ScDocument::SwapNotes( ScAddress const & aOne, ScAddress const & aTwo )
+
+Swap the notes assigned to positions aOne and aTwo.
+
+Returns true on success, false on failure.
+
+Notes:
+- Not transactional.  If a failure occurs, the ScPostIt objects at aOne or aTwo
+  may (not) be set.  Any ScPostIt that is not set, however, will be properly
+  cleaned up.
+*/
+bool ScDocument::SwapNotes( ScAddress const & aOne, ScAddress const & aTwo )
+{
+    ScPostIt* pNoteA = ReleaseNote( aOne );
+    ScPostIt* pNoteB = ReleaseNote( aTwo );
+
+    if ( ! SetNote( aTwo, pNoteA ) ) {
+        DELETEZ( pNoteA );
+        if ( ! SetNote( aOne, pNoteB ) )
+            DELETEZ( pNoteB );
+        return false;
+    }
+    else
+    {
+        if ( ! SetNote( aOne, pNoteB ) ) {
+            DELETEZ( pNoteB );
+            return false;
+        }
+    }
+
+    return true;
+}
+
+
+/** ScPostIt* ScDocument::GetOrCreateNote( const ScAddress& rPos )
+
+Returns the pointer to the ScPostIt at rPos.
+
+If no ScPostIt exists at rPos, create a new one for rPos and return pointer
+ to newly created ScPostIt.
+*/
 ScPostIt* ScDocument::GetOrCreateNote( const ScAddress& rPos )
 {
     ScPostIt* pNote = GetNote( rPos );
     if( !pNote )
     {
         pNote = new ScPostIt( *this, rPos, false );
-        TakeNote( rPos, pNote );
+        if ( ! SetNote( rPos, pNote ) )
+            DELETEZ( pNote ); //apparently unsuccessful; don't leak memory
     }
-    return pNote;
-}
-
 
-void ScDocument::DeleteNote( const ScAddress& rPos )
-{
-    if( ValidTab( rPos.Tab() ) && rPos.Tab() < static_cast<SCTAB>(maTabs.size()) && maTabs[ rPos.Tab() ] )
-        maTabs[ rPos.Tab() ]->DeleteNote( rPos.Col(), rPos.Row() );
+    return pNote;
 }
 
 
diff --git a/sc/source/core/data/fillinfo.cxx b/sc/source/core/data/fillinfo.cxx
index 0d70c48..df0ec52 100644
--- a/sc/source/core/data/fillinfo.cxx
+++ b/sc/source/core/data/fillinfo.cxx
@@ -406,7 +406,7 @@ void ScDocument::FillInfo( ScTableInfo& rTabInfo, SCCOL nX1, SCROW nY1, SCCOL nX
                         RowInfo* pThisRowInfo = &pRowInfo[nArrY];
                         CellInfo* pInfo = &pThisRowInfo->pCellInfo[nArrX];
                         pInfo->pCell = pThisCol->pItems[nUIndex].pCell;
-                        if (pInfo->pCell->GetCellType() != CELLTYPE_NOTE)
+                        if (pInfo->pCell->GetCellType() != CELLTYPE_EMPTY)
                         {
                             pThisRowInfo->bEmptyText = false;                   // Zeile nicht leer
                             pInfo->bEmptyCellText = false;                      // Zelle nicht leer
diff --git a/sc/source/core/data/postit.cxx b/sc/source/core/data/postit.cxx
index ddf0941..ad6ee1a 100644
--- a/sc/source/core/data/postit.cxx
+++ b/sc/source/core/data/postit.cxx
@@ -855,13 +855,14 @@ ScPostIt* ScNoteUtil::CreateNoteFromCaption(
     aNoteData.mpCaption = &rCaption;
     ScPostIt* pNote = new ScPostIt( rDoc, rPos, aNoteData, false );
     pNote->AutoStamp();
-    rDoc.TakeNote( rPos, pNote );
-    // if pNote still points to the note after TakeNote(), insertion was successful
-    if( pNote )
-    {
-        // ScNoteCaptionCreator c'tor updates the caption object to be part of a note
+
+    if ( rDoc.SetNote( rPos, pNote ) )
+        // ScNoteCaptionCreator c'tor updates the caption object to be part
+        // of a note
         ScNoteCaptionCreator aCreator( rDoc, rPos, rCaption, bShown );
-    }
+    else
+        DELETEZ( pNote );  // SetNote was apparently not successful.
+
     return pNote;
 }
 
@@ -892,8 +893,9 @@ ScPostIt* ScNoteUtil::CreateNoteFromObjectData(
         visible, the caption object will be created automatically. */
     ScPostIt* pNote = new ScPostIt( rDoc, rPos, aNoteData, bAlwaysCreateCaption );
     pNote->AutoStamp();
-    rDoc.TakeNote( rPos, pNote );
-    // if pNote still points to the note after TakeNote(), insertion was successful
+    if ( ! rDoc.SetNote( rPos, pNote ) )
+        DELETEZ( pNote );  // SetNote was apparently not successful
+
     return pNote;
 }
 
@@ -914,8 +916,8 @@ ScPostIt* ScNoteUtil::CreateNoteFromString(
             visible, the caption object will be created automatically. */
         pNote = new ScPostIt( rDoc, rPos, aNoteData, bAlwaysCreateCaption );
         pNote->AutoStamp();
-        rDoc.TakeNote( rPos, pNote );
-        // if pNote still points to the note after TakeNote(), insertion was successful
+        if ( ! rDoc.SetNote( rPos, pNote ) )
+            DELETEZ( pNote );  // SetNote was apparently not successful
     }
     return pNote;
 }
diff --git a/sc/source/core/data/table1.cxx b/sc/source/core/data/table1.cxx
index 941ca36..7c2edc2 100644
--- a/sc/source/core/data/table1.cxx
+++ b/sc/source/core/data/table1.cxx
@@ -1239,7 +1239,7 @@ bool ScTable::GetNextMarkedCell( SCCOL& rCol, SCROW& rRow, const ScMarkData& rMa
                 ScBaseCell* pCell = NULL;
                 while ( aColIter.Next( nCellRow, pCell ) )
                 {
-                    if ( pCell && pCell->GetCellType() != CELLTYPE_NOTE )
+                    if ( pCell && pCell->GetCellType() != CELLTYPE_EMPTY )
                     {
                         rRow = nCellRow;
                         return true;            // Zelle gefunden
@@ -1655,7 +1655,7 @@ void ScTable::MaybeAddExtraColumn(SCCOL& rCol, SCROW nRow, OutputDevice* pDev, d
     while (nMissing > 0 && nNewCol < MAXCOL)
     {
         ScBaseCell* pNextCell = aCol[nNewCol+1].GetCell(nRow);
-        if (pNextCell && pNextCell->GetCellType() != CELLTYPE_NOTE)
+        if (pNextCell && pNextCell->GetCellType() != CELLTYPE_EMPTY)
             // Cell content in a next column ends display of this string.
             nMissing = 0;
         else
diff --git a/sc/source/core/data/table2.cxx b/sc/source/core/data/table2.cxx
index 6b18359..84fb8f1 100644
--- a/sc/source/core/data/table2.cxx
+++ b/sc/source/core/data/table2.cxx
@@ -630,9 +630,15 @@ void ScTable::TransposeClip( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
                 else                            // kopieren
                 {
                     ScAddress aOwnPos( nCol, nRow, nTab );
+                    ScPostIt* pNewNote = pDocument->GetNote(aOwnPos);
+                    if ( pNewNote )
+                        pNewNote = new ScPostIt( *pDestDoc, aDestPos, *pNewNote);
+                    if ( ! pDestDoc->SetNote( aDestPos, pNewNote ) )
+                        DELETEZ( pNewNote ); // if unsuccessful, don't leak mem
+
                     if (pCell->GetCellType() == CELLTYPE_FORMULA)
                     {
-                        pNew = pCell->CloneWithNote( aOwnPos, *pDestDoc, aDestPos, SC_CLONECELL_STARTLISTENING );
+                        pNew = pCell->Clone( *pDestDoc, aDestPos, SC_CLONECELL_STARTLISTENING );
 
                         //  Referenzen drehen
                         //  bei Cut werden Referenzen spaeter per UpdateTranspose angepasst
@@ -642,7 +648,7 @@ void ScTable::TransposeClip( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
                     }
                     else
                     {
-                        pNew = pCell->CloneWithNote( aOwnPos, *pDestDoc, aDestPos );
+                        pNew = pCell->Clone( *pDestDoc, aDestPos );
                     }
                 }
                 pTransClip->PutCell( static_cast<SCCOL>(nRow-nRow1), static_cast<SCROW>(nCol-nCol1), pNew );
@@ -1092,50 +1098,15 @@ void ScTable::GetFormula( SCCOL nCol, SCROW nRow, String& rFormula )
 }
 
 
-ScPostIt* ScTable::GetNote( SCCOL nCol, SCROW nRow )
-{
-    return ValidColRow( nCol, nRow ) ? aCol[ nCol ].GetNote( nRow ) : 0;
-}
-
-
-void ScTable::TakeNote( SCCOL nCol, SCROW nRow, ScPostIt*& rpNote )
-{
-    if( ValidColRow( nCol, nRow ) )
-    {
-        aCol[ nCol ].TakeNote( nRow, rpNote );
-        if( rpNote && rpNote->GetNoteData().mxInitData.get() )
-        {
-            if( !mxUninitNotes.get() )
-                mxUninitNotes.reset( new ScAddress2DVec );
-            mxUninitNotes->push_back( ScAddress2D( nCol, nRow ) );
-        }
-        InvalidateTableArea();
-    }
-    else
-        DELETEZ( rpNote );
-}
-
-
-ScPostIt* ScTable::ReleaseNote( SCCOL nCol, SCROW nRow )
-{
-    return ValidColRow( nCol, nRow ) ? aCol[ nCol ].ReleaseNote( nRow ) : 0;
-}
-
-
-void ScTable::DeleteNote( SCCOL nCol, SCROW nRow )
-{
-    if( ValidColRow( nCol, nRow ) )
-        aCol[ nCol ].DeleteNote( nRow );
-}
-
-
 void ScTable::InitializeNoteCaptions( bool bForced )
 {
     if( mxUninitNotes.get() && (bForced || pDocument->IsUndoEnabled()) )
     {
-        for( ScAddress2DVec::iterator aIt = mxUninitNotes->begin(), aEnd = mxUninitNotes->end(); aIt != aEnd; ++aIt )
-            if( ScPostIt* pNote = GetNote( aIt->first, aIt->second ) )
-                pNote->GetOrCreateCaption( ScAddress( aIt->first, aIt->second, nTab ) );
+        for( ScAddress2DVec::iterator aIt = mxUninitNotes->begin(), aEnd = mxUninitNotes->end(); aIt != aEnd; ++aIt ) {
+            ScAddress aPos( aIt->first, aIt->second, nTab );
+            if( ScPostIt* pNote = pDocument->GetNote( aPos ) )
+                pNote->GetOrCreateCaption( aPos );
+        }
         mxUninitNotes.reset();
     }
 }
@@ -2970,7 +2941,7 @@ void ScTable::CopyData( SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW n
             ScBaseCell* pCell = GetCell( nCol, nRow );
             if (pCell)
             {
-                pCell = pCell->CloneWithoutNote( *pDocument );
+                pCell = pCell->Clone( *pDocument );
                 if (pCell->GetCellType() == CELLTYPE_FORMULA)
                 {
                     ((ScFormulaCell*)pCell)->UpdateReference( URM_COPY, aRange,
diff --git a/sc/source/core/data/table3.cxx b/sc/source/core/data/table3.cxx
index 047a7f6..2f9f8f0 100644
--- a/sc/source/core/data/table3.cxx
+++ b/sc/source/core/data/table3.cxx
@@ -387,13 +387,13 @@ short ScTable::CompareCell( sal_uInt16 nSort,
     if (pCell1)
     {
         eType1 = pCell1->GetCellType();
-        if (eType1 == CELLTYPE_NOTE)
+        if ( CELLTYPE_EMPTY == eType1)
             pCell1 = NULL;
     }
     if (pCell2)
     {
         eType2 = pCell2->GetCellType();
-        if (eType2 == CELLTYPE_NOTE)
+        if ( CELLTYPE_EMPTY == eType2 )
             pCell2 = NULL;
     }
 
@@ -1202,7 +1202,7 @@ bool ScTable::ValidQuery(SCROW nRow, const ScQueryParam& rParam,
                 bMatchWholeCell = false;
             if ( pCell )
             {
-                if (pCell->GetCellType() != CELLTYPE_NOTE)
+                if (pCell->GetCellType() != CELLTYPE_EMPTY)
                 {
                     sal_uLong nFormat = GetNumberFormat( static_cast<SCCOL>(rEntry.nField), nRow );
                     ScCellFormat::GetInputString( pCell, nFormat, aCellStr, *(pDocument->GetFormatTable()) );
@@ -1451,8 +1451,9 @@ void ScTable::TopTenQuery( ScQueryParam& rParam )
                 ScSortInfo** ppInfo = pArray->GetFirstArray();
                 SCSIZE nValidCount = nCount;
                 // keine Note-/Leerzellen zaehlen, sind ans Ende sortiert
-                while ( nValidCount > 0 && ( ppInfo[nValidCount-1]->pCell == NULL ||
-                                             ppInfo[nValidCount-1]->pCell->GetCellType() == CELLTYPE_NOTE ) )
+                while (   nValidCount > 0
+                       && (   NULL           == ppInfo[nValidCount-1]->pCell
+                           || CELLTYPE_EMPTY == ppInfo[nValidCount-1]->pCell->GetCellType() ) )
                     nValidCount--;
                 // keine Strings zaehlen, sind zwischen Value und Leer
                 while ( nValidCount > 0
diff --git a/sc/source/core/data/table4.cxx b/sc/source/core/data/table4.cxx
index 4854f49..556dd41 100644
--- a/sc/source/core/data/table4.cxx
+++ b/sc/source/core/data/table4.cxx
@@ -808,7 +808,7 @@ void ScTable::FillAuto( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
                                 {
                                     case CELLTYPE_STRING:
                                     case CELLTYPE_EDIT:
-                                        aCol[nCol].Insert( aDestPos.Row(), pSrcCell->CloneWithoutNote( *pDocument ) );
+                                        aCol[nCol].Insert( aDestPos.Row(), pSrcCell->Clone( *pDocument ) );
                                     break;
                                     default:
                                     {
@@ -1357,14 +1357,14 @@ void ScTable::FillSeries( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
                         rProgress.SetStateOnPercent( ++nProgress );
                     }
                 }
-                else if (eCellType != CELLTYPE_NOTE)
+                else if (eCellType != CELLTYPE_EMPTY)
                 {
                     for (rInner = nIMin; rInner <= nIMax; rInner++)
                     {
                         if (pDocument->RowFiltered( rInner, nTab))
                             continue;
                         ScAddress aDestPos( static_cast<SCCOL>(nCol), static_cast<SCROW>(nRow), nTab );
-                        aCol[nCol].Insert( aDestPos.Row(), pSrcCell->CloneWithoutNote( *pDocument ) );
+                        aCol[nCol].Insert( aDestPos.Row(), pSrcCell->Clone( *pDocument ) );
                     }
                     nProgress += nIMax - nIMin + 1;
                     rProgress.SetStateOnPercent( nProgress );
diff --git a/sc/source/core/data/table6.cxx b/sc/source/core/data/table6.cxx
index 4edb697..291f6a6 100644
--- a/sc/source/core/data/table6.cxx
+++ b/sc/source/core/data/table6.cxx
@@ -78,6 +78,7 @@ bool ScTable::SearchCell(const SvxSearchItem& rSearchItem, SCCOL nCol, SCROW nRo
     if ( bDoSearch && ((pCell = aCol[nCol].GetCell( nRow )) != NULL) )
     {
         bool bMultiLine = false;
+        ScAddress cellPos( nCol, nRow, nTab );
         CellType eCellType = pCell->GetCellType();
         switch (rSearchItem.GetCellType())
         {
@@ -102,7 +103,7 @@ bool ScTable::SearchCell(const SvxSearchItem& rSearchItem, SCCOL nCol, SCROW nRo
                 break;
             case SVX_SEARCHIN_NOTE:
                 {
-                    if(const ScPostIt* pNote = pCell->GetNote())
+                    if (const ScPostIt* pNote = pDocument->GetNote( cellPos ))
                     {
                         aString = pNote->GetText();
                         bMultiLine = pNote->HasMultiLineText();
@@ -156,9 +157,8 @@ bool ScTable::SearchCell(const SvxSearchItem& rSearchItem, SCCOL nCol, SCROW nRo
                 rUndoStr = aString;
             else if (pUndoDoc)
             {
-                ScAddress aAdr( nCol, nRow, nTab );
-                ScBaseCell* pUndoCell = pCell->CloneWithoutNote( *pUndoDoc );
-                pUndoDoc->PutCell( aAdr, pUndoCell);
+                ScBaseCell* pUndoCell = pCell->Clone( *pUndoDoc );
+                pUndoDoc->PutCell( cellPos, pUndoCell);
             }
             bool bRepeat = !rSearchItem.GetWordOnly();
             do
@@ -219,8 +219,8 @@ bool ScTable::SearchCell(const SvxSearchItem& rSearchItem, SCCOL nCol, SCROW nRo
             {
                 // NB: rich text format is lost.
                 // This is also true of Cells.
-                if( ScPostIt* pNote = pCell->GetNote() )
-                    pNote->SetText( ScAddress( nCol, nRow, nTab ), aString );
+                if ( ScPostIt* pNote = pDocument->GetNote( cellPos ) )
+                    pNote->SetText( cellPos, aString );
             }
             else if ( cMatrixFlag != MM_NONE )
             {   // Matrix nicht zerreissen
@@ -231,8 +231,7 @@ bool ScTable::SearchCell(const SvxSearchItem& rSearchItem, SCCOL nCol, SCROW nRo
                     if ( aString.GetChar(0) == '{' )
                         aString.Erase( 0, 1 );
                 }
-                ScAddress aAdr( nCol, nRow, nTab );
-                ScFormulaCell* pFCell = new ScFormulaCell( pDocument, aAdr,
+                ScFormulaCell* pFCell = new ScFormulaCell( pDocument, cellPos,
                     aString,formula::FormulaGrammar::GRAM_NATIVE_UI, cMatrixFlag );
                 SCCOL nMatCols;
                 SCROW nMatRows;
@@ -830,7 +829,7 @@ bool lcl_maybeReplaceCellString(
     ScColumn& rColObj, SCCOL& rCol, SCROW& rRow, rtl::OUString& rUndoStr, SCCOL nCol, SCROW nRow, const SvxSearchItem& rSearchItem)
 {
     ScBaseCell* pCell = rColObj.GetCell(nRow);
-    if (!pCell || pCell->GetCellType() == CELLTYPE_NOTE)
+    if (!pCell || CELLTYPE_EMPTY == pCell->GetCellType() )
     {
         // empty cell found.
         rCol = nCol;
@@ -1025,7 +1024,7 @@ bool ScTable::SearchRangeForAllEmptyCells(
                         pUndoDoc->PutCell(nCol, nRow, nTab, new ScStringCell(String()));
                 }
             }
-            else if (pCell->GetCellType() == CELLTYPE_NOTE)
+            else if ( CELLTYPE_EMPTY == pCell->GetCellType() )
             {
                 rMatchedRanges.Join(ScRange(nCol, nRow, nTab));
                 bFound = true;
@@ -1034,8 +1033,15 @@ bool ScTable::SearchRangeForAllEmptyCells(
                 {
                     if (pUndoDoc)
                     {
-                        ScAddress aCellPos(nCol, nRow, nTab);
-                        pUndoDoc->PutCell(nCol, nRow, nTab, pCell->CloneWithNote(aCellPos, *pUndoDoc, aCellPos));
+                        ScAddress aPos(nCol, nRow, nTab);
+                        ScBaseCell* pNewCell = pCell->Clone(*pUndoDoc, aPos);
+
+                        ScPostIt* pNewNote = pDocument->GetNote( aPos );
+                        pNewNote = new ScPostIt( *pUndoDoc, aPos, *pNewNote );
+
+                        pUndoDoc->PutCell(nCol, nRow, nTab, pNewCell);
+                        if ( ! pUndoDoc->SetNote(aPos, pNewNote) )
+                            DELETEZ( pNewNote ); // don't leak mem on failure
                     }
                     aCol[nCol].SetString(nRow, nTab, rSearchItem.GetReplaceString());
                 }
diff --git a/sc/source/core/tool/chartlis.cxx b/sc/source/core/tool/chartlis.cxx
index 6f9129d..f4093df 100644
--- a/sc/source/core/tool/chartlis.cxx
+++ b/sc/source/core/tool/chartlis.cxx
@@ -483,7 +483,7 @@ ScChartListenerCollection::~ScChartListenerCollection()
 {
     //  remove ChartListener objects before aTimer dtor is called, because
     //  ScChartListener::EndListeningTo may cause ScChartListenerCollection::StartTimer
-    //  to be called if an empty ScNoteCell is deleted
+    //  to be called if an empty ScEmptyCell is deleted
 
     if (GetCount())
         FreeAll();
diff --git a/sc/source/core/tool/chgtrack.cxx b/sc/source/core/tool/chgtrack.cxx
index 8a341a6..a3c6133 100644
--- a/sc/source/core/tool/chgtrack.cxx
+++ b/sc/source/core/tool/chgtrack.cxx
@@ -1686,7 +1686,7 @@ void ScChangeActionContent::SetValue( String& rStr, ScBaseCell*& pCell,
         pCell->Delete();
     if ( ScChangeActionContent::GetContentCellType( pOrgCell ) )
     {
-        pCell = pOrgCell->CloneWithoutNote( *pToDoc );
+        pCell = pOrgCell->Clone( *pToDoc );
         switch ( pOrgCell->GetCellType() )
         {
             case CELLTYPE_VALUE :
@@ -1846,7 +1846,7 @@ void ScChangeActionContent::PutValueToDoc( ScBaseCell* pCell,
                             // nothing
                         break;
                         default:
-                            pDoc->PutCell( aPos, pCell->CloneWithoutNote( *pDoc ) );
+                            pDoc->PutCell( aPos, pCell->Clone( *pDoc ) );
                     }
             }
         }
@@ -4399,7 +4399,7 @@ ScChangeTrack* ScChangeTrack::Clone( ScDocument* pDocument ) const
         const ScBaseCell* pNewCell = pContent->GetNewCell();
         if ( pNewCell )
         {
-            ScBaseCell* pClonedNewCell = pNewCell->CloneWithoutNote( *pDocument );
+            ScBaseCell* pClonedNewCell = pNewCell->Clone( *pDocument );
             String aNewValue;
             pContent->GetNewString( aNewValue );
             pClonedTrack->nGeneratedMin = pGenerated->GetActionNumber() + 1;
@@ -4483,7 +4483,7 @@ ScChangeTrack* ScChangeTrack::Clone( ScDocument* pDocument ) const
                     const ScChangeActionContent* pContent = dynamic_cast< const ScChangeActionContent* >( pAction );
                     OSL_ENSURE( pContent, "ScChangeTrack::Clone: pContent is null!" );
                     const ScBaseCell* pOldCell = pContent->GetOldCell();
-                    ScBaseCell* pClonedOldCell = pOldCell ? pOldCell->CloneWithoutNote( *pDocument ) : 0;
+                    ScBaseCell* pClonedOldCell = pOldCell ? pOldCell->Clone( *pDocument ) : 0;
                     String aOldValue;
                     pContent->GetOldString( aOldValue );
 
@@ -4502,7 +4502,7 @@ ScChangeTrack* ScChangeTrack::Clone( ScDocument* pDocument ) const
                     const ScBaseCell* pNewCell = pContent->GetNewCell();
                     if ( pNewCell )
                     {
-                        ScBaseCell* pClonedNewCell = pNewCell->CloneWithoutNote( *pDocument );
+                        ScBaseCell* pClonedNewCell = pNewCell->Clone( *pDocument );
                         pClonedContent->SetNewValue( pClonedNewCell, pDocument );
                     }
 
diff --git a/sc/source/core/tool/compiler.cxx b/sc/source/core/tool/compiler.cxx
index 1a484ef..c43f6f9 100644
--- a/sc/source/core/tool/compiler.cxx
+++ b/sc/source/core/tool/compiler.cxx
@@ -3091,7 +3091,7 @@ bool ScCompiler::IsColRowName( const String& rName )
                             break;
                             case CELLTYPE_NONE:
                             case CELLTYPE_VALUE:
-                            case CELLTYPE_NOTE:
+                            case CELLTYPE_EMPTY:
                             case CELLTYPE_SYMBOLS:
 #if OSL_DEBUG_LEVEL > 0
                             case CELLTYPE_DESTROYED:
@@ -3220,7 +3220,7 @@ bool ScCompiler::IsColRowName( const String& rName )
                         break;
                         case CELLTYPE_NONE:
                         case CELLTYPE_VALUE:
-                        case CELLTYPE_NOTE:
+                        case CELLTYPE_EMPTY:
                         case CELLTYPE_SYMBOLS:
 #if OSL_DEBUG_LEVEL > 0
                         case CELLTYPE_DESTROYED:
diff --git a/sc/source/core/tool/interpr1.cxx b/sc/source/core/tool/interpr1.cxx
index 3fc28bb..c4ec877 100644
--- a/sc/source/core/tool/interpr1.cxx
+++ b/sc/source/core/tool/interpr1.cxx
@@ -1762,7 +1762,7 @@ void ScInterpreter::ScIsEmpty()
             // ScCountEmptyCells().
             // if (HasCellEmptyData( GetCell( aAdr)))
             CellType eCellType = GetCellType( GetCell( aAdr ) );
-            if((eCellType == CELLTYPE_NONE) || (eCellType == CELLTYPE_NOTE))
+            if ( (CELLTYPE_NONE == eCellType) || (CELLTYPE_EMPTY == eCellType) )
                 nRes = 1;
         }
         break;
@@ -1926,7 +1926,7 @@ void ScInterpreter::ScType()
                 switch ( GetCellType( pCell ) )
                 {
                     // NOTE: this is Xcl nonsense!
-                    case CELLTYPE_NOTE :
+                    case CELLTYPE_EMPTY :
                         nType = 1;      // empty cell is value (0)
                         break;
                     case CELLTYPE_STRING :
@@ -3492,7 +3492,7 @@ double ScInterpreter::IterateParameters( ScIterFunc eFunc, bool bTextAsZero )
                     if( eFunc == ifCOUNT2 )
                     {
                         CellType eCellType = pCell->GetCellType();
-                        if (eCellType != CELLTYPE_NONE && eCellType != CELLTYPE_NOTE)
+                        if (eCellType != CELLTYPE_NONE && eCellType != CELLTYPE_EMPTY)
                             nCount++;
                         if ( nGlobalError )
                             nGlobalError = 0;
@@ -3555,7 +3555,7 @@ double ScInterpreter::IterateParameters( ScIterFunc eFunc, bool bTextAsZero )
                         do
                         {
                             CellType eType = pCell->GetCellType();
-                            if( eType != CELLTYPE_NONE && eType != CELLTYPE_NOTE )
+                            if( eType != CELLTYPE_NONE && eType != CELLTYPE_EMPTY )
                                 nCount++;
                         }
                         while ( (pCell = aIter.GetNext()) != NULL );
@@ -4704,7 +4704,7 @@ void ScInterpreter::ScCountEmptyCells()
                 ScAddress aAdr;
                 PopSingleRef( aAdr );
                 eCellType = GetCellType( GetCell( aAdr ) );
-                if (eCellType != CELLTYPE_NONE && eCellType != CELLTYPE_NOTE)
+                if (eCellType != CELLTYPE_NONE && eCellType != CELLTYPE_EMPTY)
                     nCount = 1;
             }
             break;
@@ -4728,7 +4728,7 @@ void ScInterpreter::ScCountEmptyCells()
                         do
                         {
                             if ((eCellType = pCell->GetCellType()) != CELLTYPE_NONE
-                                    && eCellType != CELLTYPE_NOTE)
+                                    && eCellType != CELLTYPE_EMPTY)
                                 nCount++;
                         } while ( (pCell = aDocIter.GetNext()) != NULL );
                     }
@@ -6170,7 +6170,7 @@ bool ScInterpreter::FillEntry(ScQueryEntry& rEntry)
             }
             else
             {
-                if ( GetCellType( pCell ) == CELLTYPE_NOTE )
+                if ( CELLTYPE_EMPTY == GetCellType( pCell ) )
                 {
                     rEntry.bQueryByString = false;
                     rEntry.nVal = 0.0;
diff --git a/sc/source/core/tool/interpr2.cxx b/sc/source/core/tool/interpr2.cxx
index bbde6aa..008a883 100644
--- a/sc/source/core/tool/interpr2.cxx
+++ b/sc/source/core/tool/interpr2.cxx
@@ -1607,8 +1607,8 @@ void ScInterpreter::ScBackSolver()
         if (nGlobalError == 0)
         {
             ScBaseCell* pVCell = GetCell( aValueAdr );
-            // CELLTYPE_NOTE: kein Value aber von Formel referiert
-            bool bTempCell = (!pVCell || pVCell->GetCellType() == CELLTYPE_NOTE);
+            // CELLTYPE_EMPTY: kein Value aber von Formel referiert
+            bool bTempCell = (!pVCell || CELLTYPE_EMPTY == pVCell->GetCellType() );
             ScBaseCell* pFCell = GetCell( aFormulaAdr );
 
             if ( ((pVCell && pVCell->GetCellType() == CELLTYPE_VALUE) || bTempCell)
@@ -1620,7 +1620,7 @@ void ScInterpreter::ScBackSolver()
 
                 if ( bTempCell )
                 {
-                    pNote = pVCell ? pVCell->ReleaseNote() : 0;
+                    pNote = pDok->GetNote( aValueAdr );
                     fSaveVal = 0.0;
                     pVCell = new ScValueCell( fSaveVal );

... etc. - the rest is truncated


More information about the Libreoffice-commits mailing list