From b0da52d19ed40dd0871f208eb7387ec1d8252de4 Mon Sep 17 00:00:00 2001 From: Tor Lillqvist Date: Tue, 2 Jun 2020 12:46:51 +0300 Subject: tdf#128502: Try to support multiple documents in LibreOfficeKit-using process The LibreOfficeKit-specific code typically has assumed that all the "views" (SfxViewShell instances) are for the same document, because all LibreOfficeKit-based application processes (including the "kit" processes in Online and the iOS app) so far have only had one document open at a time. It is now possible to pass several document file names on the command line to gtktiledviewer and that is an easy way to demonstrate how badly it still works even with this patch. Introduce a unique numeric document id that is increased in the LibLODocument_Impl constructor. Add APIs to access that. When iterating over views, try to skip views that are not of the document visible in the "current" view, if we know what the "current" view is. Also add a couple of FIXMEs at places where it is a bit unclear (to me) whether it is correct to iterate over all views, or whether only views for the "current" document are what we would want. Change-Id: I6e2d85e61a6743ca110500bf48b3d80b2027dfb1 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/97085 Tested-by: Jenkins CollaboraOffice Reviewed-by: Tor Lillqvist --- sfx2/source/view/lokhelper.cxx | 75 +++++++++++++++++++++++++++++++++++------- 1 file changed, 63 insertions(+), 12 deletions(-) (limited to 'sfx2/source/view/lokhelper.cxx') diff --git a/sfx2/source/view/lokhelper.cxx b/sfx2/source/view/lokhelper.cxx index 4fb7761cec95..2f78bfc1eaa5 100644 --- a/sfx2/source/view/lokhelper.cxx +++ b/sfx2/source/view/lokhelper.cxx @@ -69,11 +69,17 @@ int SfxLokHelper::createView() SfxViewFrame* pViewFrame = SfxViewFrame::GetFirst(); if (!pViewFrame) return -1; + SfxViewShell* pPrevViewShell = SfxViewShell::Current(); + ViewShellDocId nId; + if (pPrevViewShell) + nId = pPrevViewShell->GetDocId(); SfxRequest aRequest(pViewFrame, SID_NEWWINDOW); pViewFrame->ExecView_Impl(aRequest); SfxViewShell* pViewShell = SfxViewShell::Current(); if (!pViewShell) return -1; + if (pPrevViewShell) + pViewShell->SetDocId(nId); return static_cast(pViewShell->GetViewShellId()); } @@ -147,7 +153,20 @@ int SfxLokHelper::getView(SfxViewShell* pViewShell) std::size_t SfxLokHelper::getViewsCount() { SfxApplication* pApp = SfxApplication::Get(); - return !pApp ? 0 : pApp->GetViewShells_Impl().size(); + if (!pApp) + return 0; + + const SfxViewShell* const pCurrentViewShell = SfxViewShell::Current(); + const ViewShellDocId nCurrentDocId = pCurrentViewShell ? pCurrentViewShell->GetDocId() : ViewShellDocId(-1); + std::size_t n = 0; + SfxViewShell* pViewShell = SfxViewShell::GetFirst(); + while (pViewShell) + { + if (pViewShell->GetDocId() == nCurrentDocId) + n++; + pViewShell = SfxViewShell::GetNext(*pViewShell); + } + return n; } bool SfxLokHelper::getViewIds(int* pArray, size_t nSize) @@ -156,18 +175,45 @@ bool SfxLokHelper::getViewIds(int* pArray, size_t nSize) if (!pApp) return false; - SfxViewShellArr_Impl& rViewArr = pApp->GetViewShells_Impl(); - if (rViewArr.size() > nSize) - return false; - - for (std::size_t i = 0; i < rViewArr.size(); ++i) + const SfxViewShell* const pCurrentViewShell = SfxViewShell::Current(); + const ViewShellDocId nCurrentDocId = pCurrentViewShell ? pCurrentViewShell->GetDocId() : ViewShellDocId(-1); + std::size_t n = 0; + SfxViewShell* pViewShell = SfxViewShell::GetFirst(); + while (pViewShell) { - SfxViewShell* pViewShell = rViewArr[i]; - pArray[i] = static_cast(pViewShell->GetViewShellId()); + if (n == nSize) + return false; + if (pViewShell->GetDocId() == nCurrentDocId) + { + pArray[n] = static_cast(pViewShell->GetViewShellId()); + n++; + } + pViewShell = SfxViewShell::GetNext(*pViewShell); } return true; } +void SfxLokHelper::setDocumentIdOfView(int nId) +{ + SfxViewShell* pViewShell = SfxViewShell::Current(); + assert(pViewShell); + if (!pViewShell) + return; + pViewShell->SetDocId(ViewShellDocId(nId)); +} + +int SfxLokHelper::getDocumentIdOfView(int nViewId) +{ + SfxViewShell* pViewShell = SfxViewShell::GetFirst(); + while (pViewShell) + { + if (pViewShell->GetViewShellId() == ViewShellId(nViewId)) + return static_cast(pViewShell->GetDocId()); + pViewShell = SfxViewShell::GetNext(*pViewShell); + } + return -1; +} + LanguageTag SfxLokHelper::getDefaultLanguage() { return g_defaultLanguageTag; @@ -252,13 +298,13 @@ void SfxLokHelper::notifyOtherView(SfxViewShell* pThisView, SfxViewShell const* void SfxLokHelper::notifyOtherViews(SfxViewShell* pThisView, int nType, const OString& rKey, const OString& rPayload) { - if (SfxLokHelper::getViewsCount() <= 1 || DisableCallbacks::disabled()) + if (DisableCallbacks::disabled()) return; SfxViewShell* pViewShell = SfxViewShell::GetFirst(); while (pViewShell) { - if (pViewShell != pThisView) + if (pViewShell != pThisView && pViewShell->GetDocId() == pThisView-> GetDocId()) notifyOtherView(pThisView, pViewShell, nType, rKey, rPayload); pViewShell = SfxViewShell::GetNext(*pViewShell); @@ -371,10 +417,13 @@ void SfxLokHelper::notifyDocumentSizeChangedAllViews(vcl::ITiledRenderable* pDoc if (!comphelper::LibreOfficeKit::isActive() || DisableCallbacks::disabled()) return; + // FIXME: Do we know whether it is the views for the document that is in the "current" view that has changed? + const SfxViewShell* const pCurrentViewShell = SfxViewShell::Current(); SfxViewShell* pViewShell = SfxViewShell::GetFirst(); while (pViewShell) { - SfxLokHelper::notifyDocumentSizeChanged(pViewShell, "", pDoc, bInvalidateAll); + if (pViewShell->GetDocId() == pCurrentViewShell-> GetDocId()) + SfxLokHelper::notifyDocumentSizeChanged(pViewShell, "", pDoc, bInvalidateAll); pViewShell = SfxViewShell::GetNext(*pViewShell); } } @@ -406,10 +455,12 @@ void SfxLokHelper::notifyAllViews(int nType, const OString& rPayload) return; const auto payload = rPayload.getStr(); + const SfxViewShell* const pCurrentViewShell = SfxViewShell::Current(); SfxViewShell* pViewShell = SfxViewShell::GetFirst(); while (pViewShell) { - pViewShell->libreOfficeKitViewCallback(nType, payload); + if (pViewShell->GetDocId() == pCurrentViewShell->GetDocId()) + pViewShell->libreOfficeKitViewCallback(nType, payload); pViewShell = SfxViewShell::GetNext(*pViewShell); } } -- cgit