diff options
author | Marco Cecchetti <marco.cecchetti@collabora.com> | 2016-10-09 21:50:55 +0200 |
---|---|---|
committer | Marco Cecchetti <mrcekets@gmail.com> | 2016-10-14 15:01:36 +0000 |
commit | 6c9337866d9b4fe4870c3ab2729c6837d07473ff (patch) | |
tree | 5e955cecfe583cb4c8f5595feeb658bdd0436dc2 /sc | |
parent | a6c008b12cd2c2daf95a18eff0d72239588a5321 (diff) |
LOK: Calc: missing invalidate when ending larger-than-cell edit text
- reason: when text content goes further than the cell border the
output area of the edit view is grown (extended to an adjacent cell),
on the contrary the output area of edit views used only for
invalidating windows of other view shells is never updated, so, in
other views, only the tile where the edit cell is placed is
invalidated;
- solution: instead of adding fake edit views for invalidation porpuse
(and having to updated the output area of each of them when required),
the new solution provides each new edit view, created on cell editing,
with a set of `foreign` windows related to other views, they are added
and removed to this collection owned by an edit view still using the
ScExtraEditViewManager, which has been in turn simplified; when
EdiEngine::UpdateViews is invoked not only the window where the edit
view lives is invalidated but also all `foreign` windows in the owned
set;
- note: ScTiledRenderingTest::testTextEditViewInvalidations unit test
has been enhanced in order to test correct invalidation when text
content goes out of the starting tile.
Change-Id: Id223fb1a032d3b18d2cf70df31f704abd245b3ac
Reviewed-on: https://gerrit.libreoffice.org/29625
Reviewed-by: Marco Cecchetti <mrcekets@gmail.com>
Tested-by: Marco Cecchetti <mrcekets@gmail.com>
Reviewed-on: https://gerrit.libreoffice.org/29658
Diffstat (limited to 'sc')
-rw-r--r-- | sc/qa/unit/tiledrendering/tiledrendering.cxx | 17 | ||||
-rw-r--r-- | sc/source/ui/inc/tabview.hxx | 40 | ||||
-rw-r--r-- | sc/source/ui/view/tabview3.cxx | 68 |
3 files changed, 47 insertions, 78 deletions
diff --git a/sc/qa/unit/tiledrendering/tiledrendering.cxx b/sc/qa/unit/tiledrendering/tiledrendering.cxx index dac54bf3852e..83db147f15b3 100644 --- a/sc/qa/unit/tiledrendering/tiledrendering.cxx +++ b/sc/qa/unit/tiledrendering/tiledrendering.cxx @@ -738,6 +738,23 @@ void ScTiledRenderingTest::testTextEditViewInvalidations() CPPUNIT_ASSERT(lcl_hasEditView(*pViewData)); CPPUNIT_ASSERT(aView2.m_bInvalidateTiles); + // text edit a cell in view #1 until + // we can be sure we are out of the initial tile + for (int i = 0; i < 40; ++i) + { + pModelObj->postKeyEvent(LOK_KEYEVENT_KEYINPUT, 'x', 0); + pModelObj->postKeyEvent(LOK_KEYEVENT_KEYUP, 'x', 0); + } + Scheduler::ProcessEventsToIdle(); + + // text edit a cell in view #1 inside the new tile and + // check that view #2 receive a tile invalidate message + aView2.m_bInvalidateTiles = false; + pModelObj->postKeyEvent(LOK_KEYEVENT_KEYINPUT, 'x', 0); + pModelObj->postKeyEvent(LOK_KEYEVENT_KEYUP, 'x', 0); + Scheduler::ProcessEventsToIdle(); + CPPUNIT_ASSERT(aView2.m_bInvalidateTiles); + // view #3 SfxLokHelper::createView(); ViewCallback aView3; diff --git a/sc/source/ui/inc/tabview.hxx b/sc/source/ui/inc/tabview.hxx index f1f9431a2463..c04d027f5a1c 100644 --- a/sc/source/ui/inc/tabview.hxx +++ b/sc/source/ui/inc/tabview.hxx @@ -79,59 +79,41 @@ public: class ScExtraEditViewManager { +private: + enum ModifierTagType { Adder, Remover }; + public: ScExtraEditViewManager(ScTabViewShell* pThisViewShell, VclPtr<ScGridWindow>* pGridWin) : mpThisViewShell(pThisViewShell) , mpGridWin(pGridWin) , mpOtherEditView(nullptr) - , mpOtherEngine(nullptr) - , maSameEditViewChecker() - , nTotalActiveEditViews(0) + , nTotalWindows(0) {} ~ScExtraEditViewManager(); void Add(SfxViewShell* pViewShell, ScSplitPos eWhich) { - Apply(pViewShell, eWhich, &ScExtraEditViewManager::Adder); + Apply<Adder>(pViewShell, eWhich); } void Remove(SfxViewShell* pViewShell, ScSplitPos eWhich) { - Apply(pViewShell, eWhich, &ScExtraEditViewManager::Remover); + Apply<Remover>(pViewShell, eWhich); } private: - class SameEditViewChecker - { - public: - SameEditViewChecker() - : mpOtherEditView(nullptr) - , mpWindow(nullptr) - {} - void SetEditView(EditView* pOtherEditView) { mpOtherEditView = pOtherEditView; } - void SetWindow(ScGridWindow* pWindow) { mpWindow = pWindow; } - bool operator() (const EditView* pView) const; - - private: - EditView* mpOtherEditView; - ScGridWindow* mpWindow; - }; - -private: - typedef void (ScExtraEditViewManager::* FuncType)(ScGridWindow* ); + template<ModifierTagType ModifierTag> + void Apply(SfxViewShell* pViewShell, ScSplitPos eWhich); - void Apply(SfxViewShell* pViewShell, ScSplitPos eWhich, FuncType fHandler); - void Adder(ScGridWindow* pWin); - void Remover(ScGridWindow* pWin); + template<ModifierTagType ModifierTag> + void Modifier(ScGridWindow* pWin); private: ScTabViewShell* mpThisViewShell; VclPtr<ScGridWindow>* mpGridWin; EditView* mpOtherEditView; - EditEngine* mpOtherEngine; - SameEditViewChecker maSameEditViewChecker; - int nTotalActiveEditViews; + int nTotalWindows; }; class ScTabView diff --git a/sc/source/ui/view/tabview3.cxx b/sc/source/ui/view/tabview3.cxx index 68a37a94bd0c..06ef0b9dff9f 100644 --- a/sc/source/ui/view/tabview3.cxx +++ b/sc/source/ui/view/tabview3.cxx @@ -100,10 +100,11 @@ using namespace com::sun::star; ScExtraEditViewManager::~ScExtraEditViewManager() { - assert(nTotalActiveEditViews == 0); + DBG_ASSERT(nTotalWindows == 0, "ScExtraEditViewManager dtor: some out window has not yet been removed!"); } -void ScExtraEditViewManager::Apply(SfxViewShell* pViewShell, ScSplitPos eWhich, FuncType fHandler) +template<ScExtraEditViewManager::ModifierTagType ModifierTag> +void ScExtraEditViewManager::Apply(SfxViewShell* pViewShell, ScSplitPos eWhich) { ScTabViewShell* pOtherViewShell = dynamic_cast<ScTabViewShell*>(pViewShell); if (pOtherViewShell != nullptr && pOtherViewShell != mpThisViewShell) @@ -111,68 +112,37 @@ void ScExtraEditViewManager::Apply(SfxViewShell* pViewShell, ScSplitPos eWhich, mpOtherEditView = pOtherViewShell->GetViewData().GetEditView(eWhich); if (mpOtherEditView != nullptr) { - mpOtherEngine = mpOtherEditView->GetEditEngine(); - if (mpOtherEngine != nullptr) + DBG_ASSERT(mpOtherEditView->GetEditEngine(), "Edit view has no valid engine."); + for (int i = 0; i < 4; ++i) { - maSameEditViewChecker.SetEditView(mpOtherEditView); - for (int i = 0; i < 4; ++i) + ScGridWindow* pWin = mpGridWin[i].get(); + if (pWin != nullptr) { - (this->*fHandler)(mpGridWin[i].get()); + Modifier<ModifierTag>(pWin); } } } } } -void ScExtraEditViewManager::Adder(ScGridWindow* pWin) +template<ScExtraEditViewManager::ModifierTagType ModifierTag> +void ScExtraEditViewManager::Modifier(ScGridWindow* /*pWin*/) { - if (pWin != nullptr) - { - EditEngine::ViewsType& rEditViews = mpOtherEngine->GetEditViews(); - maSameEditViewChecker.SetWindow(pWin); - auto found = std::find_if(rEditViews.begin(), rEditViews.end(), maSameEditViewChecker); - if (found == rEditViews.end()) - { - EditView* pThisEditView = new EditView( mpOtherEngine, pWin ); - if (pThisEditView != nullptr) - { - pThisEditView->SetOutputArea(mpOtherEditView->GetOutputArea()); - pThisEditView->SetVisArea(mpOtherEditView->GetVisArea()); - mpOtherEngine->InsertView(pThisEditView); - ++nTotalActiveEditViews; - } - } - } + SAL_WARN("sc", "ScExtraEditViewManager::Modifier<ModifierTag>: non-specialized version should not be invoked."); } -void ScExtraEditViewManager::Remover(ScGridWindow* pWin) +template<> +void ScExtraEditViewManager::Modifier<ScExtraEditViewManager::Adder>(ScGridWindow* pWin) { - if (pWin != nullptr) - { - EditEngine::ViewsType& rEditViews = mpOtherEngine->GetEditViews(); - maSameEditViewChecker.SetWindow(pWin); - auto found = std::find_if(rEditViews.begin(), rEditViews.end(), maSameEditViewChecker); - if (found != rEditViews.end()) - { - EditView* pView = *found; - if (pView) - { - mpOtherEngine->RemoveView(pView); - delete pView; - pView = nullptr; - --nTotalActiveEditViews; - } - } - } + if (mpOtherEditView->AddOtherViewWindow(pWin)) + ++nTotalWindows; } -bool ScExtraEditViewManager::SameEditViewChecker::operator() (const EditView* pView) const +template<> +void ScExtraEditViewManager::Modifier<ScExtraEditViewManager::Remover>(ScGridWindow* pWin) { - return ( pView != nullptr - && pView->GetWindow() == mpWindow - && pView->GetEditEngine() == mpOtherEditView->GetEditEngine() - && pView->GetOutputArea() == mpOtherEditView->GetOutputArea() - && pView->GetVisArea() == mpOtherEditView->GetVisArea() ); + if (mpOtherEditView->RemoveOtherViewWindow(pWin)) + --nTotalWindows; } // --- public functions |