sc/inc/table.hxx                 |    9 +++
 sc/qa/unit/ucalc.cxx             |    2 
 sc/source/core/data/document.cxx |    9 +++
 sc/source/core/data/table1.cxx   |   19 ++++++--
 sc/source/ui/docshell/docsh.cxx  |    1 
 sc/source/ui/inc/docsh.hxx       |   44 ++++++++++++++----
 sc/source/ui/undo/undoblk3.cxx   |    4 -
 sc/source/ui/undo/undocell.cxx   |   17 +++++--
 sc/source/ui/unoobj/docuno.cxx   |   92 +++++++++++++++++++++++++++++----------
 sc/source/ui/view/viewfun2.cxx   |   10 ++--
 sc/source/ui/view/viewfun3.cxx   |   10 ++--
 sc/source/ui/view/viewfunc.cxx   |   46 +++++++++++++------
 12 files changed, 198 insertions(+), 65 deletions(-)

New commits:
commit ae460d8b75e1c68356d2dca8e5f6cb51067adc27
Author:     Szymon Kłos <szymon.k...@collabora.com>
AuthorDate: Fri Nov 4 15:19:13 2022 +0100
Commit:     Szymon Kłos <szymon.k...@collabora.com>
CommitDate: Thu Nov 10 11:45:40 2022 +0100

    calc: cache GetCellArea results
    
    This will avoid repeated lookup in the ScTable::GetCellArea.
    Which is used for vcl::ITiledRenderable::getDataArea().
    
    Tested in CppunitTest_sc_ucalc
    
    Change-Id: Ied58cfe447e1b924af9b401e95e127c784b80355
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/142279
    Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoff...@gmail.com>
    Reviewed-by: Dennis Francis <dennis.fran...@collabora.com>

diff --git a/sc/inc/table.hxx b/sc/inc/table.hxx
index 6511c3405429..dca46ed44f40 100644
--- a/sc/inc/table.hxx
+++ b/sc/inc/table.hxx
@@ -178,6 +178,12 @@ private:
     SCROW           nRepeatStartY;
     SCROW           nRepeatEndY;
 
+    // last used col and row
+    bool            mbCellAreaDirty;
+    bool            mbCellAreaEmpty;
+    SCCOL           mnEndCol;
+    SCROW           mnEndRow;
+
     std::unique_ptr<ScTableProtection> pTabProtection;
 
     std::unique_ptr<ScCompressedArray<SCCOL, sal_uInt16>> mpColWidth;
@@ -593,7 +599,8 @@ public:
     void        InvalidateTableArea();
     void        InvalidatePageBreaks();
 
-    bool        GetCellArea( SCCOL& rEndCol, SCROW& rEndRow ) const;           
 // FALSE = empty
+    void        InvalidateCellArea() { mbCellAreaDirty = true; }
+    bool        GetCellArea( SCCOL& rEndCol, SCROW& rEndRow );            // 
FALSE = empty
     bool        GetTableArea( SCCOL& rEndCol, SCROW& rEndRow, bool 
bCalcHiddens = false) const;
     bool        GetPrintArea( SCCOL& rEndCol, SCROW& rEndRow, bool bNotes, 
bool bCalcHiddens = false) const;
     bool        GetPrintAreaHor( SCROW nStartRow, SCROW nEndRow,
diff --git a/sc/qa/unit/ucalc.cxx b/sc/qa/unit/ucalc.cxx
index fa58e0f743f5..c718415be069 100644
--- a/sc/qa/unit/ucalc.cxx
+++ b/sc/qa/unit/ucalc.cxx
@@ -64,6 +64,7 @@
 #include <editable.hxx>
 #include <bcaslot.hxx>
 #include <sharedformula.hxx>
+#include <table.hxx>
 #include <tabprotection.hxx>
 #include <scmod.hxx>
 #include <undomanager.hxx>
@@ -5374,6 +5375,7 @@ void Test::testAreasWithNotes()
 
     m_pDoc->SetString(0, 3, 0, "Some Text");
     m_pDoc->SetString(3, 3, 0, "Some Text");
+    m_pDoc->FetchTable(0)->InvalidateCellArea();
 
     dataFound = m_pDoc->GetDataStart(0,col,row);
 
diff --git a/sc/source/core/data/document.cxx b/sc/source/core/data/document.cxx
index a8525fe71085..3622b7fc49da 100644
--- a/sc/source/core/data/document.cxx
+++ b/sc/source/core/data/document.cxx
@@ -41,6 +41,7 @@
 #include <com/sun/star/lang/NotInitializedException.hpp>
 
 #include <document.hxx>
+#include <docsh.hxx>
 #include <docuno.hxx>
 #include <table.hxx>
 #include <column.hxx>
@@ -6723,7 +6724,15 @@ void ScDocument::SetNote(const ScAddress& rPos, 
std::unique_ptr<ScPostIt> pNote)
 void ScDocument::SetNote(SCCOL nCol, SCROW nRow, SCTAB nTab, 
std::unique_ptr<ScPostIt> pNote)
 {
     if (ValidTab(nTab) && nTab < static_cast<SCTAB>(maTabs.size()))
+    {
         maTabs[nTab]->SetNote(nCol, nRow, std::move(pNote));
+
+        if (ScDocShell* pDocSh = dynamic_cast<ScDocShell*>(GetDocumentShell()))
+        {
+            HelperNotifyChanges::NotifyIfChangesListeners(
+                *pDocSh, ScRange(nCol, nRow, nTab), "note");
+        }
+    }
 }
 
 bool ScDocument::HasNote(const ScAddress& rPos) const
diff --git a/sc/source/core/data/table1.cxx b/sc/source/core/data/table1.cxx
index 43dcd6abee20..96025b640856 100644
--- a/sc/source/core/data/table1.cxx
+++ b/sc/source/core/data/table1.cxx
@@ -244,6 +244,10 @@ ScTable::ScTable( ScDocument& rDoc, SCTAB nNewTab, const 
OUString& rNewName,
     nRepeatEndX( SCCOL_REPEAT_NONE ),
     nRepeatStartY( SCROW_REPEAT_NONE ),
     nRepeatEndY( SCROW_REPEAT_NONE ),
+    mbCellAreaDirty( true ),
+    mbCellAreaEmpty( true ),
+    mnEndCol( -1 ),
+    mnEndRow( -1 ),
     mpRowHeights( static_cast<ScFlatUInt16RowSegments*>(nullptr) ),
     mpHiddenCols(new ScFlatBoolColSegments(rDoc.MaxCol())),
     mpHiddenRows(new ScFlatBoolRowSegments(rDoc.MaxRow())),
@@ -510,8 +514,15 @@ void ScTable::SetOptimalHeightOnly(
         delete pProgress;
 }
 
-bool ScTable::GetCellArea( SCCOL& rEndCol, SCROW& rEndRow ) const
+bool ScTable::GetCellArea( SCCOL& rEndCol, SCROW& rEndRow )
 {
+    if (!mbCellAreaDirty)
+    {
+        rEndCol = mnEndCol;
+        rEndRow = mnEndRow;
+        return !mbCellAreaEmpty;
+    }
+
     bool bFound = false;
     SCCOL nMaxX = 0;
     SCROW nMaxY = 0;
@@ -555,8 +566,10 @@ bool ScTable::GetCellArea( SCCOL& rEndCol, SCROW& rEndRow 
) const
             }
     }
 
-    rEndCol = nMaxX;
-    rEndRow = nMaxY;
+    mnEndCol = rEndCol = nMaxX;
+    mnEndRow = rEndRow = nMaxY;
+    mbCellAreaEmpty = !bFound;
+    mbCellAreaDirty = false;
     return bFound;
 }
 
diff --git a/sc/source/ui/docshell/docsh.cxx b/sc/source/ui/docshell/docsh.cxx
index 6089544c768c..867bd443c47a 100644
--- a/sc/source/ui/docshell/docsh.cxx
+++ b/sc/source/ui/docshell/docsh.cxx
@@ -115,6 +115,7 @@
 #include <warnpassword.hxx>
 #include <optsolver.hxx>
 #include <sheetdata.hxx>
+#include <table.hxx>
 #include <tabprotection.hxx>
 #include <docparam.hxx>
 #include "docshimp.hxx"
diff --git a/sc/source/ui/inc/docsh.hxx b/sc/source/ui/inc/docsh.hxx
index 0cbc52750dfe..f35e93a8b232 100644
--- a/sc/source/ui/inc/docsh.hxx
+++ b/sc/source/ui/inc/docsh.hxx
@@ -473,13 +473,34 @@ public:
 //#i97876# Spreadsheet data changes are not notified
 namespace HelperNotifyChanges
 {
-    inline ScModelObj* getMustPropagateChangesModel(const ScDocShell 
&rDocShell)
+    inline bool isDataAreaInvalidateType(std::u16string_view rType)
     {
-        ScModelObj* pModelObj = 
comphelper::getFromUnoTunnel<ScModelObj>(rDocShell.GetModel());
-        const bool isLOK = comphelper::LibreOfficeKit::isActive(); // for 
LOK_CALLBACK_DOCUMENT_SIZE_CHANGED
-        if (pModelObj && (pModelObj->HasChangesListeners() || isLOK))
-            return pModelObj;
-        return nullptr;
+        if (rType == u"delete-content")
+            return true;
+        if (rType == u"delete-rows")
+            return true;
+        if (rType == u"delete-columns")
+            return true;
+        if (rType == u"undo")
+            return true;
+        if (rType == u"redo")
+            return true;
+        if (rType == u"paste")
+            return true;
+        if (rType == u"note")
+            return true;
+
+        return false;
+    }
+
+    inline ScModelObj* getModel(const ScDocShell &rDocShell)
+    {
+        return comphelper::getFromUnoTunnel<ScModelObj>(rDocShell.GetModel());
+    }
+
+    inline bool getMustPropagateChangesModel(ScModelObj* pModelObj)
+    {
+        return pModelObj && pModelObj->HasChangesListeners();
     }
 
     inline void Notify(ScModelObj &rModelObj, const ScRangeList &rChangeRanges,
@@ -493,10 +514,15 @@ namespace HelperNotifyChanges
     inline void NotifyIfChangesListeners(const ScDocShell &rDocShell, const 
ScRange &rRange,
         const OUString &rType = OUString("cell-change"))
     {
-        if (ScModelObj* pModelObj = getMustPropagateChangesModel(rDocShell))
-        {
-            ScRangeList aChangeRanges(rRange);
+        ScModelObj* pModelObj = getModel(rDocShell);
+        ScRangeList aChangeRanges(rRange);
+
+        if (getMustPropagateChangesModel(pModelObj))
             Notify(*pModelObj, aChangeRanges, rType);
+        else if (pModelObj) // possibly need to invalidate getCellArea results
+        {
+            Notify(*pModelObj, aChangeRanges, isDataAreaInvalidateType(rType)
+                ? OUString("data-area-invalidate") : 
OUString("data-area-extend"));
         }
     }
 };
diff --git a/sc/source/ui/undo/undoblk3.cxx b/sc/source/ui/undo/undoblk3.cxx
index 57ce491c6fcb..fe498dfafa1c 100644
--- a/sc/source/ui/undo/undoblk3.cxx
+++ b/sc/source/ui/undo/undoblk3.cxx
@@ -179,7 +179,7 @@ void ScUndoDeleteContents::Undo()
     DoChange( true );
     EndUndo();
 
-    HelperNotifyChanges::NotifyIfChangesListeners(*pDocShell, aRange);
+    HelperNotifyChanges::NotifyIfChangesListeners(*pDocShell, aRange, "undo");
 }
 
 void ScUndoDeleteContents::Redo()
@@ -188,7 +188,7 @@ void ScUndoDeleteContents::Redo()
     DoChange( false );
     EndRedo();
 
-    HelperNotifyChanges::NotifyIfChangesListeners(*pDocShell, aRange);
+    HelperNotifyChanges::NotifyIfChangesListeners(*pDocShell, aRange, "redo");
 }
 
 void ScUndoDeleteContents::Repeat(SfxRepeatTarget& rTarget)
diff --git a/sc/source/ui/undo/undocell.cxx b/sc/source/ui/undo/undocell.cxx
index 8323cd824612..16fad3dde4da 100644
--- a/sc/source/ui/undo/undocell.cxx
+++ b/sc/source/ui/undo/undocell.cxx
@@ -46,9 +46,10 @@
 namespace HelperNotifyChanges
 {
     static void NotifyIfChangesListeners(const ScDocShell& rDocShell, const 
ScAddress &rPos,
-        const ScUndoEnterData::ValuesType &rOldValues)
+        const ScUndoEnterData::ValuesType &rOldValues, const OUString& rType = 
OUString("cell-change"))
     {
-        if (ScModelObj* pModelObj = getMustPropagateChangesModel(rDocShell))
+        ScModelObj* pModelObj = getModel(rDocShell);
+        if (pModelObj)
         {
             ScRangeList aChangeRanges;
 
@@ -57,7 +58,13 @@ namespace HelperNotifyChanges
                 aChangeRanges.push_back( ScRange(rPos.Col(), rPos.Row(), 
rOldValue.mnTab));
             }
 
-            Notify(*pModelObj, aChangeRanges, "cell-change");
+            if (getMustPropagateChangesModel(pModelObj))
+                Notify(*pModelObj, aChangeRanges, rType);
+            if (pModelObj) // possibly need to invalidate getCellArea results
+            {
+                Notify(*pModelObj, aChangeRanges, 
isDataAreaInvalidateType(rType)
+                    ? OUString("data-area-invalidate") : 
OUString("data-area-extend"));
+            }
         }
     }
 }
@@ -258,7 +265,7 @@ void ScUndoEnterData::Undo()
     DoChange();
     EndUndo();
 
-    HelperNotifyChanges::NotifyIfChangesListeners(*pDocShell, maPos, 
maOldValues);
+    HelperNotifyChanges::NotifyIfChangesListeners(*pDocShell, maPos, 
maOldValues, "undo");
 }
 
 void ScUndoEnterData::Redo()
@@ -287,7 +294,7 @@ void ScUndoEnterData::Redo()
     DoChange();
     EndRedo();
 
-    HelperNotifyChanges::NotifyIfChangesListeners(*pDocShell, maPos, 
maOldValues);
+    HelperNotifyChanges::NotifyIfChangesListeners(*pDocShell, maPos, 
maOldValues, "redo");
 }
 
 void ScUndoEnterData::Repeat(SfxRepeatTarget& rTarget)
diff --git a/sc/source/ui/unoobj/docuno.cxx b/sc/source/ui/unoobj/docuno.cxx
index deb0f55fddb4..298b9c951852 100644
--- a/sc/source/ui/unoobj/docuno.cxx
+++ b/sc/source/ui/unoobj/docuno.cxx
@@ -709,9 +709,9 @@ Size ScModelObj::getDataArea(long nPart)
     SCTAB nTab = nPart;
     SCCOL nEndCol = 0;
     SCROW nEndRow = 0;
-    const ScDocument& rDoc = pDocShell->GetDocument();
+    ScDocument& rDoc = pDocShell->GetDocument();
 
-    const ScTable* pTab = rDoc.FetchTable(nTab);
+    ScTable* pTab = rDoc.FetchTable(nTab);
     if (!pTab)
         return aSize;
 
@@ -3203,9 +3203,75 @@ bool ScModelObj::HasChangesListeners() const
     return pDocShell && 
pDocShell->GetDocument().HasAnySheetEventScript(ScSheetEventId::CHANGE);
 }
 
+namespace
+{
+
+void lcl_dataAreaInvalidation(ScDocument& rDocument, ScModelObj* pModel,
+                              const ScRangeList& rRanges,
+                              bool bInvalidateDataArea, bool bExtendDataArea)
+{
+    size_t nRangeCount = rRanges.size();
+
+    for ( size_t nIndex = 0; nIndex < nRangeCount; ++nIndex )
+    {
+        ScRange const & rRange = rRanges[ nIndex ];
+        ScAddress const & rEnd = rRange.aEnd;
+        SCTAB nTab = rEnd.Tab();
+
+        bool bAreaExtended = false;
+
+        if (bExtendDataArea)
+        {
+            const Size aCurrentDataArea = pModel->getDataArea( nTab );
+
+            SCCOL nLastCol = aCurrentDataArea.Width();
+            SCROW nLastRow = aCurrentDataArea.Height();
+
+            bAreaExtended = rEnd.Col() > nLastCol || rEnd.Row() > nLastRow;
+        }
+
+        bool bInvalidate = bAreaExtended || bInvalidateDataArea;
+        if ( bInvalidate )
+        {
+            ScTable* pTab = rDocument.FetchTable( nTab );
+            if ( pTab )
+                pTab->InvalidateCellArea();
+
+            if ( comphelper::LibreOfficeKit::isActive() )
+                SfxLokHelper::notifyPartSizeChangedAllViews( pModel, nTab );
+        }
+    }
+}
+
+};
+
 void ScModelObj::NotifyChanges( const OUString& rOperation, const ScRangeList& 
rRanges,
     const uno::Sequence< beans::PropertyValue >& rProperties )
 {
+    OUString aOperation = rOperation;
+    bool bIsDataAreaInvalidateType = aOperation == "data-area-invalidate";
+    bool bIsDataAreaExtendType = aOperation == "data-area-extend";
+
+    bool bInvalidateDataArea = bIsDataAreaInvalidateType
+        || HelperNotifyChanges::isDataAreaInvalidateType(aOperation);
+    bool bExtendDataArea = bIsDataAreaExtendType || aOperation == 
"cell-change";
+
+    if ( pDocShell )
+    {
+        ScDocument& rDocument = pDocShell->GetDocument();
+        lcl_dataAreaInvalidation(rDocument, this, rRanges, 
bInvalidateDataArea, bExtendDataArea);
+
+        // check if we were called only to update data area
+        if (bIsDataAreaInvalidateType || bIsDataAreaExtendType)
+            return;
+
+        // backward-compatibility Operation conversion
+        // FIXME: make sure it can be passed
+        if (rOperation == "delete-content" || rOperation == "undo"
+            || rOperation == "redo" || rOperation == "paste")
+            aOperation = "cell-change";
+    }
+
     if ( pDocShell && HasChangesListeners() )
     {
         util::ChangesEvent aEvent;
@@ -3230,7 +3296,7 @@ void ScModelObj::NotifyChanges( const OUString& 
rOperation, const ScRangeList& r
             }
 
             util::ElementChange& rChange = pChanges[ static_cast< sal_Int32 >( 
nIndex ) ];
-            rChange.Accessor <<= rOperation;
+            rChange.Accessor <<= aOperation;
             rChange.Element <<= rProperties;
             rChange.ReplacedElement <<= xRangeObj;
         }
@@ -3248,27 +3314,9 @@ void ScModelObj::NotifyChanges( const OUString& 
rOperation, const ScRangeList& r
         }
     }
 
-    if (comphelper::LibreOfficeKit::isActive())
-    {
-        size_t nRangeCount = rRanges.size();
-        for ( size_t nIndex = 0; nIndex < nRangeCount; ++nIndex )
-        {
-            ScRange const & rRange = rRanges[ nIndex ];
-            ScAddress const & rEnd = rRange.aEnd;
-            const Size aCurrentDataArea = getDataArea(rEnd.Tab());
-
-            SCCOL nLastCol = aCurrentDataArea.Width();
-            SCROW nLastRow = aCurrentDataArea.Height();
-
-            // is equal -> probably we just edited last col/row
-            if (rEnd.Col() >= nLastCol || rEnd.Row() >= nLastRow)
-                SfxLokHelper::notifyPartSizeChangedAllViews(this, rEnd.Tab());
-        }
-    }
-
     // handle sheet events
     //! separate method with ScMarkData? Then change HasChangesListeners back.
-    if ( !(rOperation == "cell-change" && pDocShell) )
+    if ( !(aOperation == "cell-change" && pDocShell) )
         return;
 
     ScMarkData aMarkData(pDocShell->GetDocument().GetSheetLimits());
diff --git a/sc/source/ui/view/viewfun2.cxx b/sc/source/ui/view/viewfun2.cxx
index 6dd9cae7d188..451d580f75e0 100644
--- a/sc/source/ui/view/viewfun2.cxx
+++ b/sc/source/ui/view/viewfun2.cxx
@@ -1456,9 +1456,7 @@ void ScViewFunc::FillAuto( FillDir eDir, SCCOL nStartCol, 
SCROW nStartRow,
     if ( bDoAutoSpell )
         CopyAutoSpellData(eDir, nStartCol, nStartRow, nEndCol, nEndRow, 
nCount);
 
-    ScModelObj* pModelObj = 
HelperNotifyChanges::getMustPropagateChangesModel(*pDocSh);
-    if (!pModelObj)
-        return;
+    ScModelObj* pModelObj = HelperNotifyChanges::getModel(*pDocSh);
 
     ScRangeList aChangeRanges;
     ScRange aChangeRange( aRange );
@@ -1480,7 +1478,11 @@ void ScViewFunc::FillAuto( FillDir eDir, SCCOL 
nStartCol, SCROW nStartRow,
             break;
     }
     aChangeRanges.push_back( aChangeRange );
-    HelperNotifyChanges::Notify(*pModelObj, aChangeRanges);
+
+    if (HelperNotifyChanges::getMustPropagateChangesModel(pModelObj))
+        HelperNotifyChanges::Notify(*pModelObj, aChangeRanges);
+    else if (pModelObj)
+        HelperNotifyChanges::Notify(*pModelObj, aChangeRanges, 
"data-area-invalidate");
 }
 
 void ScViewFunc::CopyAutoSpellData( FillDir eDir, SCCOL nStartCol, SCROW 
nStartRow,
diff --git a/sc/source/ui/view/viewfun3.cxx b/sc/source/ui/view/viewfun3.cxx
index 9861a7fdbf15..5d36b74999e2 100644
--- a/sc/source/ui/view/viewfun3.cxx
+++ b/sc/source/ui/view/viewfun3.cxx
@@ -1802,9 +1802,7 @@ void ScViewFunc::PostPasteFromClip(const ScRangeList& 
rPasteRanges, const ScMark
 
     SelectionChanged(true);
 
-    ScModelObj* pModelObj = 
HelperNotifyChanges::getMustPropagateChangesModel(*pDocSh);
-    if (!pModelObj)
-        return;
+    ScModelObj* pModelObj = HelperNotifyChanges::getModel(*pDocSh);
 
     ScRangeList aChangeRanges;
     for (size_t i = 0, n = rPasteRanges.size(); i < n; ++i)
@@ -1818,7 +1816,11 @@ void ScViewFunc::PostPasteFromClip(const ScRangeList& 
rPasteRanges, const ScMark
             aChangeRanges.push_back(aChangeRange);
         }
     }
-    HelperNotifyChanges::Notify(*pModelObj, aChangeRanges);
+
+    if (HelperNotifyChanges::getMustPropagateChangesModel(pModelObj))
+        HelperNotifyChanges::Notify(*pModelObj, aChangeRanges, "paste");
+    else if (pModelObj)
+        HelperNotifyChanges::Notify(*pModelObj, aChangeRanges, 
"data-area-invalidate");
 }
 
 //      D R A G   A N D   D R O P
diff --git a/sc/source/ui/view/viewfunc.cxx b/sc/source/ui/view/viewfunc.cxx
index 0f28e04ca001..1b5ce171c70e 100644
--- a/sc/source/ui/view/viewfunc.cxx
+++ b/sc/source/ui/view/viewfunc.cxx
@@ -325,15 +325,21 @@ static bool lcl_AddFunction( ScAppOptions& rAppOpt, 
sal_uInt16 nOpCode )
 
 namespace HelperNotifyChanges
 {
-    static void NotifyIfChangesListeners(const ScDocShell &rDocShell, 
ScMarkData& rMark, SCCOL nCol, SCROW nRow)
+    static void NotifyIfChangesListeners(const ScDocShell &rDocShell, 
ScMarkData& rMark,
+                                         SCCOL nCol, SCROW nRow, const 
OUString& rType = "cell-change")
     {
-        if (ScModelObj *pModelObj = getMustPropagateChangesModel(rDocShell))
-        {
-            ScRangeList aChangeRanges;
-            for (const auto& rTab : rMark)
-                aChangeRanges.push_back( ScRange( nCol, nRow, rTab ) );
+        ScModelObj* pModelObj = getModel(rDocShell);
+
+        ScRangeList aChangeRanges;
+        for (const auto& rTab : rMark)
+            aChangeRanges.push_back( ScRange( nCol, nRow, rTab ) );
 
-            HelperNotifyChanges::Notify(*pModelObj, aChangeRanges, 
"cell-change");
+        if (getMustPropagateChangesModel(pModelObj))
+            Notify(*pModelObj, aChangeRanges, rType);
+        else
+        {
+            Notify(*pModelObj, aChangeRanges, isDataAreaInvalidateType(rType)
+                    ? OUString("data-area-invalidate") : 
OUString("data-area-extend"));
         }
     }
 }
@@ -613,7 +619,8 @@ void ScViewFunc::EnterData( SCCOL nCol, SCROW nRow, SCTAB 
nTab,
 
     pDocSh->UpdateOle(GetViewData());
 
-    HelperNotifyChanges::NotifyIfChangesListeners(*pDocSh, rMark, nCol, nRow);
+    const OUString aType(rString.isEmpty() ? u"delete-content" : 
u"cell-change");
+    HelperNotifyChanges::NotifyIfChangesListeners(*pDocSh, rMark, nCol, nRow, 
aType);
 
     if ( bRecord )
         rFunc.EndListAction();
@@ -767,7 +774,10 @@ void ScViewFunc::EnterData( SCCOL nCol, SCROW nRow, SCTAB 
nTab,
 
             pDocSh->UpdateOle(GetViewData());
 
-            HelperNotifyChanges::NotifyIfChangesListeners(*pDocSh, rMark, 
nCol, nRow);
+            bool bIsEmpty = rData.GetParagraphCount() == 0
+                || (rData.GetParagraphCount() == 1 && 
rData.GetText(0).isEmpty());
+            const OUString aType(bIsEmpty ? u"delete-content" : 
u"cell-change");
+            HelperNotifyChanges::NotifyIfChangesListeners(*pDocSh, rMark, 
nCol, nRow, aType);
 
             aModificator.SetDocumentModified();
         }
@@ -1273,8 +1283,9 @@ void ScViewFunc::ApplySelectionPattern( const 
ScPatternAttr& rAttr, bool bCursor
         CellContentChanged();
     }
 
-    ScModelObj* pModelObj = 
HelperNotifyChanges::getMustPropagateChangesModel(*pDocSh);
-    if (pModelObj)
+    ScModelObj* pModelObj = HelperNotifyChanges::getModel(*pDocSh);
+
+    if (HelperNotifyChanges::getMustPropagateChangesModel(pModelObj))
     {
         css::uno::Sequence< css::beans::PropertyValue > aProperties;
         sal_Int32 nCount = 0;
@@ -2033,7 +2044,7 @@ void ScViewFunc::DeleteContents( InsertDeleteFlags nFlags 
)
 
     pDocSh->UpdateOle(GetViewData());
 
-    if (ScModelObj *pModelObj = 
HelperNotifyChanges::getMustPropagateChangesModel(*pDocSh))
+    if (ScModelObj* pModelObj = HelperNotifyChanges::getModel(*pDocSh))
     {
         ScRangeList aChangeRanges;
         if ( bSimple )
@@ -2044,7 +2055,11 @@ void ScViewFunc::DeleteContents( InsertDeleteFlags 
nFlags )
         {
             aFuncMark.FillRangeListWithMarks( &aChangeRanges, false );
         }
-        HelperNotifyChanges::Notify(*pModelObj, aChangeRanges);
+
+        if (HelperNotifyChanges::getMustPropagateChangesModel(pModelObj))
+            HelperNotifyChanges::Notify(*pModelObj, aChangeRanges, 
"delete-content");
+        else if (pModelObj)
+            HelperNotifyChanges::Notify(*pModelObj, aChangeRanges, 
"data-area-invalidate");
     }
 
     CellContentChanged();
@@ -2348,8 +2363,9 @@ void ScViewFunc::SetWidthOrHeight(
     if ( !bWidth )
         return;
 
-    ScModelObj* pModelObj = 
HelperNotifyChanges::getMustPropagateChangesModel(*pDocSh);
-    if (!pModelObj)
+    ScModelObj* pModelObj = HelperNotifyChanges::getModel(*pDocSh);
+
+    if (!HelperNotifyChanges::getMustPropagateChangesModel(pModelObj))
         return;
 
     ScRangeList aChangeRanges;

Reply via email to