diff options
Diffstat (limited to 'sc/source/ui')
-rw-r--r-- | sc/source/ui/docshell/docsh.cxx | 1 | ||||
-rw-r--r-- | sc/source/ui/inc/docsh.hxx | 44 | ||||
-rw-r--r-- | sc/source/ui/undo/undoblk3.cxx | 4 | ||||
-rw-r--r-- | sc/source/ui/undo/undocell.cxx | 17 | ||||
-rw-r--r-- | sc/source/ui/unoobj/docuno.cxx | 92 | ||||
-rw-r--r-- | sc/source/ui/view/viewfun2.cxx | 10 | ||||
-rw-r--r-- | sc/source/ui/view/viewfun3.cxx | 10 | ||||
-rw-r--r-- | sc/source/ui/view/viewfunc.cxx | 46 |
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; |