summaryrefslogtreecommitdiff
path: root/sc/source/ui
diff options
context:
space:
mode:
Diffstat (limited to 'sc/source/ui')
-rw-r--r--sc/source/ui/docshell/docsh.cxx1
-rw-r--r--sc/source/ui/inc/docsh.hxx44
-rw-r--r--sc/source/ui/undo/undoblk3.cxx4
-rw-r--r--sc/source/ui/undo/undocell.cxx17
-rw-r--r--sc/source/ui/unoobj/docuno.cxx92
-rw-r--r--sc/source/ui/view/viewfun2.cxx10
-rw-r--r--sc/source/ui/view/viewfun3.cxx10
-rw-r--r--sc/source/ui/view/viewfunc.cxx46
8 files changed, 163 insertions, 61 deletions
diff --git a/sc/source/ui/docshell/docsh.cxx b/sc/source/ui/docshell/docsh.cxx
index 40a8311b7bf7..2f2f3521ae4e 100644
--- a/sc/source/ui/docshell/docsh.cxx
+++ b/sc/source/ui/docshell/docsh.cxx
@@ -116,6 +116,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 660f17aee3f4..8fac5cf6ed5a 100644
--- a/sc/source/ui/inc/docsh.hxx
+++ b/sc/source/ui/inc/docsh.hxx
@@ -470,13 +470,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,
@@ -490,10 +511,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 da7fa26ff9c1..8e6978659331 100644
--- a/sc/source/ui/undo/undoblk3.cxx
+++ b/sc/source/ui/undo/undoblk3.cxx
@@ -180,7 +180,7 @@ void ScUndoDeleteContents::Undo()
DoChange( true );
EndUndo();
- HelperNotifyChanges::NotifyIfChangesListeners(*pDocShell, aRange);
+ HelperNotifyChanges::NotifyIfChangesListeners(*pDocShell, aRange, "undo");
}
void ScUndoDeleteContents::Redo()
@@ -189,7 +189,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 5d15ac26a677..c51110402b1e 100644
--- a/sc/source/ui/undo/undocell.cxx
+++ b/sc/source/ui/undo/undocell.cxx
@@ -48,9 +48,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;
@@ -59,7 +60,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"));
+ }
}
}
}
@@ -260,7 +267,7 @@ void ScUndoEnterData::Undo()
DoChange();
EndUndo();
- HelperNotifyChanges::NotifyIfChangesListeners(*pDocShell, maPos, maOldValues);
+ HelperNotifyChanges::NotifyIfChangesListeners(*pDocShell, maPos, maOldValues, "undo");
}
void ScUndoEnterData::Redo()
@@ -289,7 +296,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 0701cae0d9ca..d6d8f1ae0583 100644
--- a/sc/source/ui/unoobj/docuno.cxx
+++ b/sc/source/ui/unoobj/docuno.cxx
@@ -695,9 +695,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;
@@ -3173,9 +3173,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;
@@ -3200,7 +3266,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;
}
@@ -3218,27 +3284,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 44c84b8ebcd7..884722204f0a 100644
--- a/sc/source/ui/view/viewfun2.cxx
+++ b/sc/source/ui/view/viewfun2.cxx
@@ -1487,9 +1487,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 );
@@ -1511,7 +1509,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 215fde010694..9dd9b810273a 100644
--- a/sc/source/ui/view/viewfun3.cxx
+++ b/sc/source/ui/view/viewfun3.cxx
@@ -1803,9 +1803,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)
@@ -1819,7 +1817,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 8b7adf0c0f19..6e15f9b3e0f8 100644
--- a/sc/source/ui/view/viewfunc.cxx
+++ b/sc/source/ui/view/viewfunc.cxx
@@ -337,15 +337,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"));
}
}
}
@@ -648,7 +654,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();
@@ -802,7 +809,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();
}
@@ -1337,8 +1347,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;
@@ -2097,7 +2108,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 )
@@ -2108,7 +2119,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();
@@ -2428,8 +2443,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;