diff options
author | Miklos Vajna <vmiklos@collabora.co.uk> | 2016-07-27 17:07:47 +0200 |
---|---|---|
committer | Miklos Vajna <vmiklos@collabora.co.uk> | 2016-07-28 09:04:51 +0200 |
commit | 9931331e5e9cdd4e581962e332024af572f7f90e (patch) | |
tree | 3561f8735f2389a115276ad55a92a70e12a143e3 /svx | |
parent | 0f83ff712a6253066b758d39d92ac528bdb2f5d3 (diff) |
svx lok: fix handling of text edit drawing when view/page changes
This is a follow-up to commit 9d91d371e92548c7f75a7d0155eecaf3769fdee6
(svx lok: draw text edits in all views, 2016-07-26). Two corner-cases
are now handled:
1) When the SfxViewShell is created after begin text edit and
2) When the other draw view is already created, but at the time begin
text edit happens, the other draw view shows a different page.
And the opposite of these: switching away from a page were we observe a
text edit done in an other view or destroying a view that observes a
text edit.
When the complete view goes away, then SdrObjEditView::HideSdrPage() is
not called, so also try to destroy the outliner view of the text edit
from SdrObjEditView::DeleteWindowFromPaintView(). The GetSfxViewShell()
call in SdrObjEditView::ShowSdrPage() is important, because we let the
other draw view create the outliner view, but the outliner view should
invoke our view shell, not the view shell of the other draw view.
Also improve the SdTiledRenderingTest::testCursorViews() testcase, so
that it asserts it managed to begin text edit and use a test document
that still has a single slide and shape, but the shape is not
auto-sized; otherwise invalidations happen even if outliner views are
not created in all draw views, so the test would pass even without the
fixes.
Change-Id: I2c3bb27826c6887115366db818599fc8adabc5a5
Reviewed-on: https://gerrit.libreoffice.org/27583
Reviewed-by: Miklos Vajna <vmiklos@collabora.co.uk>
Tested-by: Jenkins <ci@libreoffice.org>
(cherry picked from commit 5f65ca15a2297f298536d07cfa8564a1f7c67abb)
Diffstat (limited to 'svx')
-rw-r--r-- | svx/source/svdraw/svdedxv.cxx | 76 |
1 files changed, 74 insertions, 2 deletions
diff --git a/svx/source/svdraw/svdedxv.cxx b/svx/source/svdraw/svdedxv.cxx index cd315afee569..0731dfd14250 100644 --- a/svx/source/svdraw/svdedxv.cxx +++ b/svx/source/svdraw/svdedxv.cxx @@ -134,6 +134,76 @@ void SdrObjEditView::BrkAction() SdrGlueEditView::BrkAction(); } +SdrPageView* SdrObjEditView::ShowSdrPage(SdrPage* pPage) +{ + SdrPageView* pPageView = SdrGlueEditView::ShowSdrPage(pPage); + + if (comphelper::LibreOfficeKit::isActive() && pPageView) + { + // Check if other views have an active text edit on the same page as + // this one. + SdrViewIter aIter(pPageView->GetPage()); + for (SdrView* pView = aIter.FirstView(); pView; pView = aIter.NextView()) + { + if (pView == this || !pView->IsTextEdit()) + continue; + + OutputDevice* pOutDev = GetFirstOutputDevice(); + if (!pOutDev || pOutDev->GetOutDevType() != OUTDEV_WINDOW) + continue; + + // Found one, so create an outliner view, to get invalidations when + // the text edit changes. + bool bEmpty = pView->GetTextEditObject()->GetOutlinerParaObject() == nullptr; + // Call GetSfxViewShell() to make sure ImpMakeOutlinerView() + // registers the view shell of this draw view, and not the view + // shell of pView. + OutlinerView* pOutlinerView = pView->ImpMakeOutlinerView(static_cast<vcl::Window*>(pOutDev), !bEmpty, nullptr, GetSfxViewShell()); + pView->GetTextEditOutliner()->InsertView(pOutlinerView); + } + } + + return pPageView; +} + +/// Removes outliner views registered in other draw views that use pOutputDevice. +void lcl_RemoveTextEditOutlinerViews(SdrObjEditView* pThis, SdrPageView* pPageView, OutputDevice* pOutputDevice) +{ + if (!comphelper::LibreOfficeKit::isActive()) + return; + + if (!pPageView) + return; + + if (!pOutputDevice || pOutputDevice->GetOutDevType() != OUTDEV_WINDOW) + return; + + SdrViewIter aIter(pPageView->GetPage()); + for (SdrView* pView = aIter.FirstView(); pView; pView = aIter.NextView()) + { + if (pView == pThis || !pView->IsTextEdit()) + continue; + + SdrOutliner* pOutliner = pView->GetTextEditOutliner(); + for (size_t nView = 0; nView < pOutliner->GetViewCount(); ++nView) + { + OutlinerView* pOutlinerView = pOutliner->GetView(nView); + if (pOutlinerView->GetWindow() != pOutputDevice) + continue; + + pOutliner->RemoveView(pOutlinerView); + delete pOutlinerView; + } + } +} + +void SdrObjEditView::HideSdrPage() +{ + lcl_RemoveTextEditOutlinerViews(this, GetSdrPageView(), GetFirstOutputDevice()); + + SdrGlueEditView::HideSdrPage(); +} + void SdrObjEditView::TakeActionRect(Rectangle& rRect) const { if (IsMacroObj()) { @@ -443,7 +513,7 @@ void SdrObjEditView::ImpInvalidateOutlinerView(OutlinerView& rOutlView) const } } -OutlinerView* SdrObjEditView::ImpMakeOutlinerView(vcl::Window* pWin, bool /*bNoPaint*/, OutlinerView* pGivenView) const +OutlinerView* SdrObjEditView::ImpMakeOutlinerView(vcl::Window* pWin, bool /*bNoPaint*/, OutlinerView* pGivenView, SfxViewShell* pViewShell) const { // background Color aBackground(GetTextEditBackgroundColor(*this)); @@ -472,7 +542,7 @@ OutlinerView* SdrObjEditView::ImpMakeOutlinerView(vcl::Window* pWin, bool /*bNoP // SfxViewShell::Current() may still point to the old one. So if possible, // depend on the application owning this draw view to provide the view // shell. - SfxViewShell* pSfxViewShell = GetSfxViewShell(); + SfxViewShell* pSfxViewShell = pViewShell ? pViewShell : GetSfxViewShell(); pOutlView->registerLibreOfficeKitViewCallback(pSfxViewShell ? pSfxViewShell : SfxViewShell::Current()); if (pText!=nullptr) @@ -1854,6 +1924,8 @@ void SdrObjEditView::DeleteWindowFromPaintView(OutputDevice* pOldWin) } } } + + lcl_RemoveTextEditOutlinerViews(this, GetSdrPageView(), pOldWin); } bool SdrObjEditView::IsTextEditInSelectionMode() const |