save/restore docId in Application::Reschedule

similar to what we do for viewID.

On attemting to load multiple documents StatusIndicator::start calls
Application::Reschedule during load of document #1.

That inner loop ends up loading document #2. The inner loop ends, and
load of document #1 completes in the outer loop.

Unfortunately the inner loop left the current DocumentId as that of the
inner document #2, so the document id set on the view of #1 is
incorrect.

Extend the similar fix for viewId switching during Reschedule to restore
the docId. If this Reschedule happens at any other time except load then
restoring the viewId is sufficient to identify the correct document, but
in the load case there is no viewId yet

Move the mnCurrentDocId out of sfx2 and ViewShell into comphelper so
it's available from vcl without needing to make any adjustments to
LibreOfficeKit.h[xx]

Change-Id: Ied70e0f9ff33f2587cfbcb02b0c9ca3cd4792cfd
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/193814
Tested-by: Jenkins
Reviewed-by: Caolán McNamara <caolan.mcnamara@collabora.com>
This commit is contained in:
Caolán McNamara
2025-11-13 09:37:13 +01:00
parent d6decd5344
commit abdba6ee5b
9 changed files with 43 additions and 23 deletions
+13
View File
@@ -44,6 +44,9 @@ static bool g_bSlideshowRendering(false);
static Compat g_eCompatFlags(Compat::none);
/// Used to set the DocId at ViewShell construction time.
static ViewShellDocId g_nCurrentDocId;
static std::function<bool(void*, int)> g_pAnyInputCallback;
static void* g_pAnyInputCallbackData;
static std::function<int()> g_pMostUrgentPriorityGetter;
@@ -394,6 +397,16 @@ int getView()
return g_pViewGetter();
}
ViewShellDocId getDocId()
{
return g_nCurrentDocId;
}
void setDocId(ViewShellDocId nDocId)
{
g_nCurrentDocId = nDocId;
}
void setInitialClientVisibleArea(const awt::Rectangle& rClientVisibleArea)
{
g_aInitialClientVisibleArea = rClientVisibleArea;
+1 -1
View File
@@ -374,7 +374,7 @@ DesktopLOKTest::loadDocUrlImpl(const OUString& rFileURL, LibreOfficeKitDocumentT
}
static int nDocumentIdCounter = 0;
SfxViewShell::SetCurrentDocId(ViewShellDocId(nDocumentIdCounter));
comphelper::LibreOfficeKit::setDocId(ViewShellDocId(nDocumentIdCounter));
mxComponent = loadFromDesktop(rFileURL, aService);
std::unique_ptr<LibLODocument_Impl> pDocument(new LibLODocument_Impl(mxComponent, nDocumentIdCounter));
+3 -1
View File
@@ -2993,7 +2993,7 @@ static LibreOfficeKitDocument* lo_documentLoadWithOptions(LibreOfficeKit* pThis,
HostFilter::setExemptVerifyHost(OUString(pExemptVerifyHost, strlen(pExemptVerifyHost), RTL_TEXTENCODING_UTF8));
const int nThisDocumentId = nDocumentIdCounter++;
SfxViewShell::SetCurrentDocId(ViewShellDocId(nThisDocumentId));
comphelper::LibreOfficeKit::setDocId(ViewShellDocId(nThisDocumentId));
uno::Reference<lang::XComponent> xComponent = xComponentLoader->loadComponentFromURL(
aURL, u"_blank"_ustr, 0,
aFilterOptions);
@@ -3007,6 +3007,8 @@ static LibreOfficeKitDocument* lo_documentLoadWithOptions(LibreOfficeKit* pThis,
return nullptr;
}
assert(comphelper::LibreOfficeKit::getDocId() == ViewShellDocId(nThisDocumentId) && "incorrect docid set on document");
LibLODocument_Impl* pDocument = new LibLODocument_Impl(xComponent, nThisDocumentId);
// After loading the document, its initial view is the "current" view.
+13
View File
@@ -13,8 +13,11 @@
#include <functional>
#include <comphelper/comphelperdllapi.h>
#include <o3tl/strong_int.hxx>
#include <rtl/ustring.hxx>
typedef o3tl::strong_int<int, struct ViewShellDocIdTag> ViewShellDocId;
class LanguageTag;
namespace com::sun::star::awt
{
@@ -154,6 +157,16 @@ COMPHELPER_DLLPUBLIC void setView(int nView);
COMPHELPER_DLLPUBLIC void setViewGetter(const std::function<int()>& pViewGetter);
COMPHELPER_DLLPUBLIC int getView();
/// Set the current DocId, which is used by Mobile LOKit to
/// load multiple documents and yet identify the views of each.
/// There are events that are fired while creating a new view,
/// and if we don't have a DocId, we can't know which other views
/// within the same document (if any) should get those events.
/// By setting this static value, we are able to set the DocId
/// of each SfxViewShell at construction time.
COMPHELPER_DLLPUBLIC void setDocId(ViewShellDocId nDocId);
COMPHELPER_DLLPUBLIC ViewShellDocId getDocId();
COMPHELPER_DLLPUBLIC void
setInitialClientVisibleArea(const css::awt::Rectangle& rClientVisibleArea);
COMPHELPER_DLLPUBLIC css::awt::Rectangle getInitialClientVisibleArea();
-11
View File
@@ -180,9 +180,6 @@ friend class SfxPrinterController;
bool maLOKIsTimezoneSet;
bool mbLOKColorPreviewEnabled;
/// Used to set the DocId at construction time. See SetCurrentDocId.
static ViewShellDocId mnCurrentDocId;
/// Used for async export
std::shared_ptr<SfxStoringHelper> m_xHelper;
@@ -421,14 +418,6 @@ public:
/// See OutlinerViewShell::GetViewShellId().
ViewShellId GetViewShellId() const override;
/// Set the current DocId, which is used by Mobile LOKit to
/// load multiple documents and yet identify the views of each.
/// There are events that are fired while creating a new view,
/// and if we don't have a DocId, we can't know which other views
/// within the same document (if any) should get those events.
/// By setting this static value, we are able to set the DocId
/// of each SfxViewShell at construction time.
static void SetCurrentDocId(ViewShellDocId nId);
/// Get the DocId used by Mobile LOKit to load multiple documents.
ViewShellDocId GetDocId() const override;
+1 -1
View File
@@ -20,6 +20,7 @@
#define INCLUDED_SVL_UNDO_HXX
#include <svl/svldllapi.h>
#include <comphelper/lok.hxx>
#include <rtl/ustring.hxx>
#include <tools/datetime.hxx>
#include <o3tl/strong_int.hxx>
@@ -29,7 +30,6 @@
#include <vector>
typedef o3tl::strong_int<sal_Int32, struct ViewShellIdTag> ViewShellId;
typedef o3tl::strong_int<int, struct ViewShellDocIdTag> ViewShellDocId;
typedef struct _xmlTextWriter* xmlTextWriterPtr;
+1 -1
View File
@@ -125,7 +125,7 @@ int SfxLokHelper::createView(SfxViewFrame& rViewFrame, ViewShellDocId docId)
// something has likely cleared the original SID_INTERACTIONHANDLER
assert(!isSfxMediumMissingInteractionHandled(rViewFrame) && "original XInteractionHandler missing");
SfxViewShell::SetCurrentDocId(docId);
comphelper::LibreOfficeKit::setDocId(docId);
SfxRequest aRequest(rViewFrame, SID_NEWWINDOW);
rViewFrame.ExecView_Impl(aRequest);
SfxViewShell* pViewShell = SfxViewShell::Current();
+1 -8
View File
@@ -2726,8 +2726,6 @@ void SfxViewShell::SetWindow
//SfxGetpApp()->GrabFocus( pWindow );
}
ViewShellDocId SfxViewShell::mnCurrentDocId(0);
SfxViewShell::SfxViewShell
(
SfxViewFrame& rViewFrame, /* <SfxViewFrame>, which will be
@@ -2736,7 +2734,7 @@ SfxViewShell::SfxViewShell
)
: SfxShell(this)
, pImpl( new SfxViewShell_Impl(nFlags, SfxViewShell::mnCurrentDocId) )
, pImpl( new SfxViewShell_Impl(nFlags, comphelper::LibreOfficeKit::getDocId()) )
, rFrame(rViewFrame)
, pWindow(nullptr)
, bNoNewWindow( nFlags & SfxViewShellFlags::NO_NEWWINDOW )
@@ -3549,11 +3547,6 @@ ViewShellId SfxViewShell::GetViewShellId() const
return pImpl->m_nViewShellId;
}
void SfxViewShell::SetCurrentDocId(ViewShellDocId nId)
{
mnCurrentDocId = nId;
}
ViewShellDocId SfxViewShell::GetDocId() const
{
assert(pImpl->m_nDocId >= ViewShellDocId(0) && "m_nDocId should have been initialized, but it is invalid.");
+10
View File
@@ -406,13 +406,23 @@ bool Application::Reschedule( bool i_bAllEvents )
return false;
}
int nOldView = -1;
ViewShellDocId nOldDocId(-1);
if (comphelper::LibreOfficeKit::isActive())
{
nOldView = comphelper::LibreOfficeKit::getView();
nOldDocId = comphelper::LibreOfficeKit::getDocId();
}
bool bRet = ImplYield(false, i_bAllEvents);
if (comphelper::LibreOfficeKit::isActive())
{
// Yield may have changed the current docId, restore the old value,
// (which is cheap). If there is a view to restore this doesn't matter
// much, but if there isn't yet, as in the case of loading a new
// document, then this ensures that the next view to be created is
// created with the expected document id.
assert(nOldDocId.get() != -1 && "won't be unset");
comphelper::LibreOfficeKit::setDocId(nOldDocId);
int nNewView = comphelper::LibreOfficeKit::getView();
if (nOldView != -1 && nNewView != -1 && nOldView != nNewView)
{