libreofficekit/source/gtk/lokdocview.cxx | 9 ++++ sc/source/ui/view/tabvwsh4.cxx | 8 +++ sd/source/ui/view/ViewShellBase.cxx | 7 +++ sfx2/source/view/lokhelper.cxx | 17 -------- sw/qa/extras/tiledrendering/tiledrendering.cxx | 51 ++++++++++++++++++++++++- sw/source/uibase/uiview/view.cxx | 7 +++ 6 files changed, 83 insertions(+), 16 deletions(-)
New commits: commit bc9b4fd4c83af3532204237157821d4884c42d8e Author: Miklos Vajna <[email protected]> Date: Fri Jul 15 17:26:34 2016 +0200 lok::Document::destroyView: clean up view cursors/selections Change-Id: Icd3f96a922e7d1aec0d52e90df87ec45790c9807 diff --git a/sc/source/ui/view/tabvwsh4.cxx b/sc/source/ui/view/tabvwsh4.cxx index 51837a3..b2fdbde 100644 --- a/sc/source/ui/view/tabvwsh4.cxx +++ b/sc/source/ui/view/tabvwsh4.cxx @@ -97,6 +97,8 @@ #include <com/sun/star/chart2/XCoordinateSystem.hpp> #include <com/sun/star/chart2/XChartTypeContainer.hpp> #include <com/sun/star/chart2/XChartType.hpp> +#include <sfx2/lokhelper.hxx> +#include <LibreOfficeKit/LibreOfficeKitEnums.h> extern SfxViewShell* pScActiveViewShell; // global.cxx @@ -1735,6 +1737,12 @@ ScTabViewShell::ScTabViewShell( SfxViewFrame* pViewFrame, ScTabViewShell::~ScTabViewShell() { + // Notify other LOK views that we are going away. + SfxLokHelper::notifyOtherViews(this, LOK_CALLBACK_VIEW_CURSOR_VISIBLE, "visible", "false"); + SfxLokHelper::notifyOtherViews(this, LOK_CALLBACK_TEXT_VIEW_SELECTION, "selection", ""); + SfxLokHelper::notifyOtherViews(this, LOK_CALLBACK_GRAPHIC_VIEW_SELECTION, "selection", "EMPTY"); + SfxLokHelper::notifyOtherViews(this, LOK_CALLBACK_CELL_VIEW_CURSOR, "rectangle", "EMPTY"); + ScDocShell* pDocSh = GetViewData().GetDocShell(); EndListening(*pDocSh); EndListening(*GetViewFrame()); diff --git a/sd/source/ui/view/ViewShellBase.cxx b/sd/source/ui/view/ViewShellBase.cxx index 668974e..3da4489 100644 --- a/sd/source/ui/view/ViewShellBase.cxx +++ b/sd/source/ui/view/ViewShellBase.cxx @@ -86,6 +86,8 @@ #include <sfx2/notebookbar/SfxNotebookBar.hxx> #include <tools/diagnose_ex.h> +#include <sfx2/lokhelper.hxx> +#include <LibreOfficeKit/LibreOfficeKitEnums.h> #include "fubullet.hxx" @@ -270,6 +272,11 @@ ViewShellBase::ViewShellBase ( */ ViewShellBase::~ViewShellBase() { + // Notify other LOK views that we are going away. + SfxLokHelper::notifyOtherViews(this, LOK_CALLBACK_VIEW_CURSOR_VISIBLE, "visible", "false"); + SfxLokHelper::notifyOtherViews(this, LOK_CALLBACK_TEXT_VIEW_SELECTION, "selection", ""); + SfxLokHelper::notifyOtherViews(this, LOK_CALLBACK_GRAPHIC_VIEW_SELECTION, "selection", "EMPTY"); + sfx2::SfxNotebookBar::CloseMethod(GetFrame()->GetBindings()); rtl::Reference<SlideShow> xSlideShow(SlideShow::GetSlideShow(*this)); diff --git a/sw/qa/extras/tiledrendering/tiledrendering.cxx b/sw/qa/extras/tiledrendering/tiledrendering.cxx index 476b6d6..8c56355 100644 --- a/sw/qa/extras/tiledrendering/tiledrendering.cxx +++ b/sw/qa/extras/tiledrendering/tiledrendering.cxx @@ -54,6 +54,7 @@ public: void testViewCursors(); void testMissingInvalidation(); void testViewCursorVisibility(); + void testViewCursorCleanup(); CPPUNIT_TEST_SUITE(SwTiledRenderingTest); CPPUNIT_TEST(testRegisterCallback); @@ -75,6 +76,7 @@ public: CPPUNIT_TEST(testViewCursors); CPPUNIT_TEST(testMissingInvalidation); CPPUNIT_TEST(testViewCursorVisibility); + CPPUNIT_TEST(testViewCursorCleanup); CPPUNIT_TEST_SUITE_END(); private: @@ -556,6 +558,7 @@ public: bool m_bViewSelectionSet; bool m_bTilesInvalidated; bool m_bViewCursorVisible; + bool m_bGraphicViewSelection; ViewCallback() : m_bOwnCursorInvalidated(false), @@ -563,7 +566,8 @@ public: m_bOwnSelectionSet(false), m_bViewSelectionSet(false), m_bTilesInvalidated(false), - m_bViewCursorVisible(false) + m_bViewCursorVisible(false), + m_bGraphicViewSelection(false) { } @@ -606,6 +610,14 @@ public: m_bViewCursorVisible = OString("true") == pPayload; } break; + case LOK_CALLBACK_GRAPHIC_VIEW_SELECTION: + { + std::stringstream aStream(pPayload); + boost::property_tree::ptree aTree; + boost::property_tree::read_json(aStream, aTree); + m_bGraphicViewSelection = aTree.get_child("selection").get_value<std::string>() != "EMPTY"; + } + break; } } }; @@ -719,6 +731,43 @@ void SwTiledRenderingTest::testViewCursorVisibility() comphelper::LibreOfficeKit::setActive(false); } +void SwTiledRenderingTest::testViewCursorCleanup() +{ + comphelper::LibreOfficeKit::setActive(); + + // Load a document that has a shape and create two views. + SwXTextDocument* pXTextDocument = createDoc("shape.fodt"); + ViewCallback aView1; + SfxViewShell::Current()->registerLibreOfficeKitViewCallback(&ViewCallback::callback, &aView1); + int nView2 = SfxLokHelper::createView(); + pXTextDocument->initializeForTiledRendering(uno::Sequence<beans::PropertyValue>()); + ViewCallback aView2; + SfxViewShell::Current()->registerLibreOfficeKitViewCallback(&ViewCallback::callback, &aView2); + + // Click on the shape in the second view. + SwWrtShell* pWrtShell = pXTextDocument->GetDocShell()->GetWrtShell(); + SdrPage* pPage = pWrtShell->GetDoc()->getIDocumentDrawModelAccess().GetDrawModel()->GetPage(0); + SdrObject* pObject = pPage->GetObj(0); + Point aCenter = pObject->GetSnapRect().Center(); + aView1.m_bGraphicViewSelection = false; + pXTextDocument->postMouseEvent(LOK_MOUSEEVENT_MOUSEBUTTONDOWN, aCenter.getX(), aCenter.getY(), 1); + pXTextDocument->postMouseEvent(LOK_MOUSEEVENT_MOUSEBUTTONUP, aCenter.getX(), aCenter.getY(), 1); + Scheduler::ProcessEventsToIdle(); + // Make sure there is a graphic view selection on the first view. + CPPUNIT_ASSERT(aView1.m_bGraphicViewSelection); + + // Now destroy the second view. + SfxLokHelper::destroyView(nView2); + Scheduler::ProcessEventsToIdle(); + CPPUNIT_ASSERT_EQUAL(static_cast<std::size_t>(1), SfxLokHelper::getViews()); + // Make sure that the graphic view selection on the first view is cleaned up. + CPPUNIT_ASSERT(!aView1.m_bGraphicViewSelection); + mxComponent->dispose(); + mxComponent.clear(); + + comphelper::LibreOfficeKit::setActive(false); +} + CPPUNIT_TEST_SUITE_REGISTRATION(SwTiledRenderingTest); CPPUNIT_PLUGIN_IMPLEMENT(); diff --git a/sw/source/uibase/uiview/view.cxx b/sw/source/uibase/uiview/view.cxx index 7821da5..09d2e83 100644 --- a/sw/source/uibase/uiview/view.cxx +++ b/sw/source/uibase/uiview/view.cxx @@ -114,6 +114,8 @@ #include <svl/cjkoptions.hxx> #include <comphelper/propertyvalue.hxx> +#include <sfx2/lokhelper.hxx> +#include <LibreOfficeKit/LibreOfficeKitEnums.h> using namespace ::com::sun::star; using namespace ::com::sun::star::uno; @@ -1017,6 +1019,11 @@ SwView::SwView( SfxViewFrame *_pFrame, SfxViewShell* pOldSh ) SwView::~SwView() { + // Notify other LOK views that we are going away. + SfxLokHelper::notifyOtherViews(this, LOK_CALLBACK_VIEW_CURSOR_VISIBLE, "visible", "false"); + SfxLokHelper::notifyOtherViews(this, LOK_CALLBACK_TEXT_VIEW_SELECTION, "selection", ""); + SfxLokHelper::notifyOtherViews(this, LOK_CALLBACK_GRAPHIC_VIEW_SELECTION, "selection", "EMPTY"); + GetViewFrame()->GetWindow().RemoveChildEventListener( LINK( this, SwView, WindowChildEventListener ) ); delete m_pPostItMgr; m_pPostItMgr = nullptr; commit 85c5a172953ac29d1fcab3f4c2f19fa897074e52 Author: Miklos Vajna <[email protected]> Date: Fri Jul 15 17:12:20 2016 +0200 sfx2 lok: handle when SfxViewFrame::Current() returns nullptr In these two cases no need to call it and dereference the result unconditionally, there are other ways to get the info. Change-Id: Idb5969e909dc2faed97a5a4ac79dfcc1aec8ddcd diff --git a/sfx2/source/view/lokhelper.cxx b/sfx2/source/view/lokhelper.cxx index 653dd7f..d027bad 100644 --- a/sfx2/source/view/lokhelper.cxx +++ b/sfx2/source/view/lokhelper.cxx @@ -38,7 +38,7 @@ int shellToView(SfxViewShell* pViewShell) int SfxLokHelper::createView() { - SfxViewFrame* pViewFrame = SfxViewFrame::Current(); + SfxViewFrame* pViewFrame = SfxViewFrame::GetFirst(); SfxRequest aRequest(pViewFrame, SID_NEWWINDOW); pViewFrame->ExecView_Impl(aRequest); @@ -91,21 +91,8 @@ int SfxLokHelper::getView(SfxViewShell* pViewShell) std::size_t SfxLokHelper::getViews() { - std::size_t nRet = 0; - - SfxViewFrame* pViewFrame = SfxViewFrame::Current(); - if (!pViewFrame) - return nRet; - - SfxObjectShell* pObjectShell = pViewFrame->GetObjectShell(); SfxViewShellArr_Impl& rViewArr = SfxGetpApp()->GetViewShells_Impl(); - for (SfxViewShell* i : rViewArr) - { - if (i->GetObjectShell() == pObjectShell) - ++nRet; - } - - return nRet; + return rViewArr.size(); } void SfxLokHelper::notifyOtherViews(SfxViewShell* pThisView, int nType, const OString& rKey, const OString& rPayload) commit 8090b53e0e16e9aef95f2f5557985f7c2e7c69f3 Author: Miklos Vajna <[email protected]> Date: Fri Jul 15 17:10:47 2016 +0200 lokdocview: ignore notifications on view shutdown Callbacks are processed on idle on the main thread, so by the time we parse them, possibly the widget is already gone, avoid that problem. Change-Id: Ie8e16423d1ffe087e0dd21425026f7a5d644c27b diff --git a/libreofficekit/source/gtk/lokdocview.cxx b/libreofficekit/source/gtk/lokdocview.cxx index 0c9d135..198dfd8 100644 --- a/libreofficekit/source/gtk/lokdocview.cxx +++ b/libreofficekit/source/gtk/lokdocview.cxx @@ -2394,6 +2394,15 @@ static void lok_doc_view_finalize (GObject* object) LOKDocView* pDocView = LOK_DOC_VIEW (object); LOKDocViewPrivate& priv = getPrivate(pDocView); + // Ignore notifications sent to this view on shutdown. + std::unique_lock<std::mutex> aGuard(g_aLOKMutex); + std::stringstream ss; + ss << "lok::Document::setView(" << priv->m_nViewId << ")"; + g_info("%s", ss.str().c_str()); + priv->m_pDocument->pClass->setView(priv->m_pDocument, priv->m_nViewId); + priv->m_pDocument->pClass->registerCallback(priv->m_pDocument, nullptr, nullptr); + aGuard.unlock(); + if (priv->m_pDocument && priv->m_pDocument->pClass->getViews(priv->m_pDocument) > 1) { priv->m_pDocument->pClass->destroyView(priv->m_pDocument, priv->m_nViewId); _______________________________________________ Libreoffice-commits mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits
