diff --git a/desktop/qa/desktop_lib/test_desktop_lib.cxx b/desktop/qa/desktop_lib/test_desktop_lib.cxx index dd84323f6c9b..e7762753775f 100644 --- a/desktop/qa/desktop_lib/test_desktop_lib.cxx +++ b/desktop/qa/desktop_lib/test_desktop_lib.cxx @@ -2275,7 +2275,7 @@ void DesktopLOKTest::testPaintPartTile() // Call paintPartTile() to paint the second part (in whichever view it finds suitable for this). unsigned char pPixels[256 * 256 * 4]; - pDocument->m_pDocumentClass->paintPartTile(pDocument, pPixels, 1, 256, 256, 0, 0, 256, 256); + pDocument->m_pDocumentClass->paintPartTile(pDocument, pPixels, 1, 0, 256, 256, 0, 0, 256, 256); // Type again. Scheduler::ProcessEventsToIdle(); @@ -3624,10 +3624,11 @@ void DesktopLOKTest::testABI() offsetof(struct _LibreOfficeKitDocumentClass, sendContentControlEvent)); CPPUNIT_ASSERT_EQUAL(documentClassOffset(65), offsetof(struct _LibreOfficeKitDocumentClass, getSelectionTypeAndText)); CPPUNIT_ASSERT_EQUAL(documentClassOffset(66), offsetof(struct _LibreOfficeKitDocumentClass, getDataArea)); + CPPUNIT_ASSERT_EQUAL(documentClassOffset(67), offsetof(struct _LibreOfficeKitDocumentClass, getEditMode)); // Extending is fine, update this, and add new assert for the offsetof the // new method - CPPUNIT_ASSERT_EQUAL(documentClassOffset(67), sizeof(struct _LibreOfficeKitDocumentClass)); + CPPUNIT_ASSERT_EQUAL(documentClassOffset(68), sizeof(struct _LibreOfficeKitDocumentClass)); } CPPUNIT_TEST_SUITE_REGISTRATION(DesktopLOKTest); diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx index 1163ef2a638f..766248ef00ef 100644 --- a/desktop/source/lib/init.cxx +++ b/desktop/source/lib/init.cxx @@ -998,6 +998,7 @@ static void doc_selectPart(LibreOfficeKitDocument* pThis, int nPart, int nSelect static void doc_moveSelectedParts(LibreOfficeKitDocument* pThis, int nPosition, bool bDuplicate); static char* doc_getPartName(LibreOfficeKitDocument* pThis, int nPart); static void doc_setPartMode(LibreOfficeKitDocument* pThis, int nPartMode); +static int doc_getEditMode(LibreOfficeKitDocument* pThis); static void doc_paintTile(LibreOfficeKitDocument* pThis, unsigned char* pBuffer, const int nCanvasWidth, const int nCanvasHeight, @@ -1013,6 +1014,7 @@ static void doc_paintTileToCGContext(LibreOfficeKitDocument* pThis, static void doc_paintPartTile(LibreOfficeKitDocument* pThis, unsigned char* pBuffer, const int nPart, + const int nMode, const int nCanvasWidth, const int nCanvasHeight, const int nTilePosX, const int nTilePosY, const int nTileWidth, const int nTileHeight); @@ -1269,6 +1271,7 @@ LibLODocument_Impl::LibLODocument_Impl(uno::Reference xC m_pDocumentClass->moveSelectedParts = doc_moveSelectedParts; m_pDocumentClass->getPartName = doc_getPartName; m_pDocumentClass->setPartMode = doc_setPartMode; + m_pDocumentClass->getEditMode = doc_getEditMode; m_pDocumentClass->paintTile = doc_paintTile; #ifdef IOS m_pDocumentClass->paintTileToCGContext = doc_paintTileToCGContext; @@ -3641,6 +3644,23 @@ static void doc_setPartMode(LibreOfficeKitDocument* pThis, } } +static int doc_getEditMode(LibreOfficeKitDocument* pThis) +{ + comphelper::ProfileZone aZone("doc_getEditMode"); + + SolarMutexGuard aGuard; + SetLastExceptionMsg(); + + ITiledRenderable* pDoc = getTiledRenderable(pThis); + if (!pDoc) + { + SetLastExceptionMsg("Document doesn't support tiled rendering"); + return 0; + } + + return pDoc->getEditMode(); +} + static void doc_paintTile(LibreOfficeKitDocument* pThis, unsigned char* pBuffer, const int nCanvasWidth, const int nCanvasHeight, @@ -3770,6 +3790,7 @@ static void doc_paintTileToCGContext(LibreOfficeKitDocument* pThis, static void doc_paintPartTile(LibreOfficeKitDocument* pThis, unsigned char* pBuffer, const int nPart, + const int nMode, const int nCanvasWidth, const int nCanvasHeight, const int nTilePosX, const int nTilePosY, const int nTileWidth, const int nTileHeight) @@ -3779,7 +3800,7 @@ static void doc_paintPartTile(LibreOfficeKitDocument* pThis, SolarMutexGuard aGuard; SetLastExceptionMsg(); - SAL_INFO( "lok.tiledrendering", "paintPartTile: painting @ " << nPart << " [" + SAL_INFO( "lok.tiledrendering", "paintPartTile: painting @ " << nPart << " : " << nMode << " [" << nTileWidth << "x" << nTileHeight << "]@(" << nTilePosX << ", " << nTilePosY << ") to [" << nCanvasWidth << "x" << nCanvasHeight << "]px" ); @@ -3787,6 +3808,13 @@ static void doc_paintPartTile(LibreOfficeKitDocument* pThis, LibLODocument_Impl* pDocument = static_cast(pThis); int nOrigViewId = doc_getView(pThis); + ITiledRenderable* pDoc = getTiledRenderable(pThis); + if (!pDoc) + { + SetLastExceptionMsg("Document doesn't support tiled rendering"); + return; + } + if (nOrigViewId < 0) { // tile painting always needs a SfxViewShell::Current(), but actually @@ -3819,13 +3847,17 @@ static void doc_paintPartTile(LibreOfficeKitDocument* pThis, int nOrigPart = 0; const int aType = doc_getDocumentType(pThis); const bool isText = (aType == LOK_DOCTYPE_TEXT); + const bool isCalc = (aType == LOK_DOCTYPE_SPREADSHEET); + int nOrigEditMode = 0; + bool bPaintTextEdit = true; int nViewId = nOrigViewId; - int nLastNonEditorView = nViewId; + int nLastNonEditorView = -1; + int nViewMatchingMode = -1; if (!isText) { // Check if just switching to another view is enough, that has // less side-effects. - if (nPart != doc_getPart(pThis)) + if (nPart != doc_getPart(pThis) || nMode != pDoc->getEditMode()) { SfxViewShell* pViewShell = SfxViewShell::GetFirst(); while (pViewShell) @@ -3835,23 +3867,40 @@ static void doc_paintPartTile(LibreOfficeKitDocument* pThis, if (!bIsInEdit) nLastNonEditorView = pViewShell->GetViewShellId().get(); - if (pViewShell->getPart() == nPart && !bIsInEdit) + if (pViewShell->getPart() == nPart && + pViewShell->getEditMode() == nMode && + !bIsInEdit) { nViewId = pViewShell->GetViewShellId().get(); + nViewMatchingMode = nViewId; nLastNonEditorView = nViewId; doc_setView(pThis, nViewId); break; } + else if (pViewShell->getEditMode() == nMode && !bIsInEdit) + { + nViewMatchingMode = pViewShell->GetViewShellId().get(); + } + pViewShell = SfxViewShell::GetNext(*pViewShell); } } - // if not found view with correct part - at least avoid rendering active textbox + // if not found view with correct part + // - at least avoid rendering active textbox, This is for Impress. + // - prefer view with the same mode SfxViewShell* pCurrentViewShell = SfxViewShell::Current(); - if (pCurrentViewShell && pCurrentViewShell->GetDrawView() && + if (nViewMatchingMode >= 0 && nViewMatchingMode != nViewId) + { + nViewId = nViewMatchingMode; + doc_setView(pThis, nViewId); + } + else if (!isCalc && nLastNonEditorView >= 0 && nLastNonEditorView != nViewId && + pCurrentViewShell && pCurrentViewShell->GetDrawView() && pCurrentViewShell->GetDrawView()->GetTextEditOutliner()) { - doc_setView(pThis, nLastNonEditorView); + nViewId = nLastNonEditorView; + doc_setView(pThis, nViewId); } // Disable callbacks while we are painting - after setting the view @@ -3867,36 +3916,44 @@ static void doc_paintPartTile(LibreOfficeKitDocument* pThis, { doc_setPartImpl(pThis, nPart, false); } - } - ITiledRenderable* pDoc = getTiledRenderable(pThis); - if (!pDoc) - { - SetLastExceptionMsg("Document doesn't support tiled rendering"); - return; - } + nOrigEditMode = pDoc->getEditMode(); + if (nOrigEditMode != nMode) + { + SfxLokHelper::setEditMode(nMode, pDoc); + } - bool bPaintTextEdit = nPart == nOrigPart; - pDoc->setPaintTextEdit( bPaintTextEdit ); + bPaintTextEdit = (nPart == nOrigPart && nMode == nOrigEditMode); + pDoc->setPaintTextEdit(bPaintTextEdit); + } doc_paintTile(pThis, pBuffer, nCanvasWidth, nCanvasHeight, nTilePosX, nTilePosY, nTileWidth, nTileHeight); - pDoc->setPaintTextEdit( true ); + if (!isText) + { + pDoc->setPaintTextEdit(true); - if (!isText && nPart != nOrigPart) - { - doc_setPartImpl(pThis, nOrigPart, false); - } - if (!isText && nViewId != nOrigViewId) - { - if (nViewId >= 0) + if (nMode != nOrigEditMode) { - const auto handlerIt = pDocument->mpCallbackFlushHandlers.find(nViewId); - if (handlerIt != pDocument->mpCallbackFlushHandlers.end()) - handlerIt->second->enableCallbacks(); + SfxLokHelper::setEditMode(nOrigEditMode, pDoc); } - doc_setView(pThis, nOrigViewId); + if (nPart != nOrigPart) + { + doc_setPartImpl(pThis, nOrigPart, false); + } + + if (nViewId != nOrigViewId) + { + if (nViewId >= 0) + { + const auto handlerIt = pDocument->mpCallbackFlushHandlers.find(nViewId); + if (handlerIt != pDocument->mpCallbackFlushHandlers.end()) + handlerIt->second->enableCallbacks(); + } + + doc_setView(pThis, nOrigViewId); + } } } catch (const std::exception&) diff --git a/include/LibreOfficeKit/LibreOfficeKit.h b/include/LibreOfficeKit/LibreOfficeKit.h index 2f57f744e1d4..61a68f632209 100644 --- a/include/LibreOfficeKit/LibreOfficeKit.h +++ b/include/LibreOfficeKit/LibreOfficeKit.h @@ -283,6 +283,7 @@ struct _LibreOfficeKitDocumentClass void (*paintPartTile) (LibreOfficeKitDocument* pThis, unsigned char* pBuffer, const int nPart, + const int nMode, const int nCanvasWidth, const int nCanvasHeight, const int nTilePosX, @@ -489,6 +490,9 @@ struct _LibreOfficeKitDocumentClass long* pCol, long* pRow); + /// @see lok::Document::getEditMode(). + int (*getEditMode) (LibreOfficeKitDocument* pThis); + #endif // defined LOK_USE_UNSTABLE_API || defined LIBO_INTERNAL_ONLY }; diff --git a/include/LibreOfficeKit/LibreOfficeKit.hxx b/include/LibreOfficeKit/LibreOfficeKit.hxx index 1adab0d4f066..d70e4eb44d39 100644 --- a/include/LibreOfficeKit/LibreOfficeKit.hxx +++ b/include/LibreOfficeKit/LibreOfficeKit.hxx @@ -126,6 +126,11 @@ public: mpDoc->pClass->setPartMode(mpDoc, nMode); } + int getEditMode() + { + return mpDoc->pClass->getEditMode(mpDoc); + } + /** * Renders a subset of the document to a pre-allocated buffer. * @@ -604,6 +609,7 @@ public: */ void paintPartTile(unsigned char* pBuffer, const int nPart, + const int nMode, const int nCanvasWidth, const int nCanvasHeight, const int nTilePosX, @@ -611,7 +617,7 @@ public: const int nTileWidth, const int nTileHeight) { - return mpDoc->pClass->paintPartTile(mpDoc, pBuffer, nPart, + return mpDoc->pClass->paintPartTile(mpDoc, pBuffer, nPart, nMode, nCanvasWidth, nCanvasHeight, nTilePosX, nTilePosY, nTileWidth, nTileHeight); diff --git a/sfx2/source/view/lokhelper.cxx b/sfx2/source/view/lokhelper.cxx index 7b10b7e6b7ad..5f7bef16a843 100644 --- a/sfx2/source/view/lokhelper.cxx +++ b/sfx2/source/view/lokhelper.cxx @@ -551,8 +551,9 @@ void SfxLokHelper::notifyInvalidation(SfxViewShell const* pThisView, tools::Rect if (DisableCallbacks::disabled()) return; + // -1 means all parts const int nPart = comphelper::LibreOfficeKit::isPartInInvalidation() ? pThisView->getPart() : INT_MIN; - const int nMode = comphelper::LibreOfficeKit::isPartInInvalidation() ? pThisView->getEditMode() : 0; + const int nMode = pThisView->getEditMode(); pThisView->libreOfficeKitViewInvalidateTilesCallback(pRect, nPart, nMode); } @@ -566,7 +567,8 @@ void SfxLokHelper::notifyDocumentSizeChanged(SfxViewShell const* pThisView, cons for (int i = 0; i < pDoc->getParts(); ++i) { tools::Rectangle aRectangle(0, 0, 1000000000, 1000000000); - pThisView->libreOfficeKitViewInvalidateTilesCallback(&aRectangle, i, 0); + const int nMode = pThisView->getEditMode(); + pThisView->libreOfficeKitViewInvalidateTilesCallback(&aRectangle, i, nMode); } } pThisView->libreOfficeKitViewCallback(LOK_CALLBACK_DOCUMENT_SIZE_CHANGED, rPayload.getStr());