diff options
Diffstat (limited to 'desktop/source/lib/init.cxx')
-rw-r--r-- | desktop/source/lib/init.cxx | 356 |
1 files changed, 191 insertions, 165 deletions
diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx index edac3ef9e0b9..b143e8b104b3 100644 --- a/desktop/source/lib/init.cxx +++ b/desktop/source/lib/init.cxx @@ -323,7 +323,7 @@ constexpr ExtensionMap aWriterExtensionMap[] = { { "doc", u"MS Word 97"_ustr }, { "docm", u"MS Word 2007 XML VBA"_ustr }, - { "docx", u"MS Word 2007 XML"_ustr }, + { "docx", u"Office Open XML Text"_ustr }, { "fodt", u"OpenDocument Text Flat XML"_ustr }, { "html", u"HTML (StarWriter)"_ustr }, { "odt", u"writer8"_ustr }, @@ -1352,8 +1352,6 @@ ITiledRenderable* getTiledRenderable(LibreOfficeKitDocument* pThis) return dynamic_cast<ITiledRenderable*>(pDocument->mxComponent.get()); } -#ifndef IOS - /* * Unfortunately clipboard creation using UNO is insanely baroque. * we also need to ensure that this works for the first view which @@ -1375,8 +1373,6 @@ rtl::Reference<LOKClipboard> forceSetClipboardForCurrentView(LibreOfficeKitDocum return xClip; } -#endif - const vcl::Font* FindFont(std::u16string_view rFontName) { SfxObjectShell* pDocSh = SfxObjectShell::Current(); @@ -1554,9 +1550,7 @@ LibLODocument_Impl::LibLODocument_Impl(uno::Reference <css::lang::XComponent> xC } pClass = m_pDocumentClass.get(); -#ifndef IOS forceSetClipboardForCurrentView(this); -#endif } LibLODocument_Impl::~LibLODocument_Impl() @@ -2334,12 +2328,10 @@ bool CallbackFlushHandler::processWindowEvent(int type, CallbackData& aCallbackD return false; } -#ifndef IOS auto xClip = forceSetClipboardForCurrentView(m_pDocument); uno::Reference<datatransfer::clipboard::XClipboard> xClipboard(xClip); pWindow->SetClipboard(xClipboard); -#endif } else if (aAction == "size_changed") { @@ -4464,6 +4456,93 @@ static void doc_paintTile(LibreOfficeKitDocument* pThis, #endif } +inline static ITiledRenderable* getDocumentPointer(LibreOfficeKitDocument* pThis) +{ + ITiledRenderable* pDoc = getTiledRenderable(pThis); + + if (!pDoc) + { + SetLastExceptionMsg(u"Document doesn't support tiled rendering"_ustr); + return nullptr; + } + return pDoc; +} + +inline static void writeInfoLog(const int nPart, const int nMode, + const int nTileWidth, const int nTileHeight, const int nTilePosX, const int nTilePosY, + const int nCanvasWidth, const int nCanvasHeight) +{ + SAL_INFO( "lok.tiledrendering", "paintPartTile: painting @ " << nPart << " : " << nMode << " [" + << nTileWidth << "x" << nTileHeight << "]@(" + << nTilePosX << ", " << nTilePosY << ") to [" + << nCanvasWidth << "x" << nCanvasHeight << "]px" ); +} + +inline static int getFirstViewIdAsFallback(LibreOfficeKitDocument* pThis) +{ + // tile painting always needs a SfxViewShell::Current(), but actually + // it does not really matter which one - all of them should paint the + // same thing. It's important to get a view for the correct document, + // though. + // doc_getViewsCount() returns the count of views for the document in the current view. + int viewCount = doc_getViewsCount(pThis); + + if (viewCount == 0) return -1; + + std::vector<int> viewIds(viewCount); + doc_getViewIds(pThis, viewIds.data(), viewCount); + + int result = viewIds[0]; + doc_setView(pThis, result); + + SAL_WARN("lok.tiledrendering", "Why is this happening? A call to paint without setting a view?"); + + return result; +} + +inline static void disableViewCallbacks(LibLODocument_Impl* pDocument, const int viewId) +{ + const auto handlerIt = pDocument->mpCallbackFlushHandlers.find(viewId); + if (handlerIt != pDocument->mpCallbackFlushHandlers.end()) + handlerIt->second->disableCallbacks(); +} + +inline static void enableViewCallbacks(LibLODocument_Impl* pDocument, const int viewId) +{ + const auto handlerIt = pDocument->mpCallbackFlushHandlers.find(viewId); + if (handlerIt != pDocument->mpCallbackFlushHandlers.end()) + handlerIt->second->enableCallbacks(); +} + +inline static int getAlternativeViewForPaint(LibreOfficeKitDocument* pThis, ITiledRenderable* pDoc, SfxViewShell* pCurrentViewShell, + const std::string_view &sCurrentViewRenderState, const int nPart, const int nMode) +{ + SfxViewShell* pViewShell = SfxViewShell::GetFirst(); + while (pViewShell) + { + bool bIsInEdit = pViewShell->GetDrawView() && pViewShell->GetDrawView()->GetTextEditOutliner(); + + if (!bIsInEdit && pViewShell != pCurrentViewShell) + { + if (pViewShell->getPart() == nPart && pViewShell->getEditMode() == nMode) + { + OString sNewRenderState = pDoc->getViewRenderState(pViewShell); + + if (sCurrentViewRenderState == sNewRenderState) + { + const int nViewId = pViewShell->GetViewShellId().get(); + doc_setView(pThis, nViewId); + return nViewId; + } + } + } + + pViewShell = SfxViewShell::GetNext(*pViewShell); + } + + return -1; +} + static void doc_paintPartTile(LibreOfficeKitDocument* pThis, unsigned char* pBuffer, const int nPart, @@ -4477,46 +4556,26 @@ static void doc_paintPartTile(LibreOfficeKitDocument* pThis, SolarMutexGuard aGuard; SetLastExceptionMsg(); - SAL_INFO( "lok.tiledrendering", "paintPartTile: painting @ " << nPart << " : " << nMode << " [" - << nTileWidth << "x" << nTileHeight << "]@(" - << nTilePosX << ", " << nTilePosY << ") to [" - << nCanvasWidth << "x" << nCanvasHeight << "]px" ); - - LibLODocument_Impl* pDocument = static_cast<LibLODocument_Impl*>(pThis); - int nOrigViewId = doc_getView(pThis); + writeInfoLog(nPart, nMode, nTileWidth, nTileHeight, nTilePosX, nTilePosY, nCanvasWidth, nCanvasHeight); - ITiledRenderable* pDoc = getTiledRenderable(pThis); + ITiledRenderable* pDoc = getDocumentPointer(pThis); if (!pDoc) - { - SetLastExceptionMsg(u"Document doesn't support tiled rendering"_ustr); return; - } + + LibLODocument_Impl* pDocument = static_cast<LibLODocument_Impl*>(pThis); + + int nOrigViewId = doc_getView(pThis); if (nOrigViewId < 0) - { - // tile painting always needs a SfxViewShell::Current(), but actually - // it does not really matter which one - all of them should paint the - // same thing. It's important to get a view for the correct document, - // though. - // doc_getViewsCount() returns the count of views for the document in the current view. - int viewCount = doc_getViewsCount(pThis); - if (viewCount == 0) - return; + nOrigViewId = getFirstViewIdAsFallback(pThis); - std::vector<int> viewIds(viewCount); - doc_getViewIds(pThis, viewIds.data(), viewCount); + if (nOrigViewId == -1) + return; - nOrigViewId = viewIds[0]; - doc_setView(pThis, nOrigViewId); - } + // Data validity checks end here. // Disable callbacks while we are painting. - if (nOrigViewId >= 0) - { - const auto handlerIt = pDocument->mpCallbackFlushHandlers.find(nOrigViewId); - if (handlerIt != pDocument->mpCallbackFlushHandlers.end()) - handlerIt->second->disableCallbacks(); - } + disableViewCallbacks(pDocument, nOrigViewId); try { @@ -4524,86 +4583,38 @@ 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 = -1; - int nViewMatchingMode = -1; SfxViewShell* pCurrentViewShell = SfxViewShell::Current(); + const OString sCurrentViewRenderState = pDoc->getViewRenderState(pCurrentViewShell); if (!isText) { - // Check if just switching to another view is enough, that has - // less side-effects. - if (nPart != doc_getPart(pThis) || nMode != pDoc->getEditMode()) + // Check if just switching to another view is enough, that has less side-effects. + // Render state is sometimes empty, don't risk it. + if ((nPart != doc_getPart(pThis) || nMode != pDoc->getEditMode()) && !sCurrentViewRenderState.isEmpty()) { - SfxViewShell* pViewShell = SfxViewShell::GetFirst(); - while (pViewShell) - { - bool bIsInEdit = pViewShell->GetDrawView() && - pViewShell->GetDrawView()->GetTextEditOutliner(); - - OString sCurrentViewRenderState = pDoc->getViewRenderState(pCurrentViewShell); - OString sNewRenderState = pDoc->getViewRenderState(pViewShell); - - if (sCurrentViewRenderState == sNewRenderState && !bIsInEdit) - nLastNonEditorView = pViewShell->GetViewShellId().get(); - - if (pViewShell->getPart() == nPart && - pViewShell->getEditMode() == nMode && - sCurrentViewRenderState == sNewRenderState && - !bIsInEdit) - { - nViewId = pViewShell->GetViewShellId().get(); - nViewMatchingMode = nViewId; - nLastNonEditorView = nViewId; - doc_setView(pThis, nViewId); - break; - } - else if (pViewShell->getEditMode() == nMode && sCurrentViewRenderState == sNewRenderState && !bIsInEdit) - { - nViewMatchingMode = pViewShell->GetViewShellId().get(); - } + nViewId = getAlternativeViewForPaint(pThis, pDoc, pCurrentViewShell, sCurrentViewRenderState, nPart, nMode); - pViewShell = SfxViewShell::GetNext(*pViewShell); - } - } - - // if not found view with correct part - // - at least avoid rendering active textbox, This is for Impress. - // - prefer view with the same mode - if (nViewMatchingMode >= 0 && nViewMatchingMode != nViewId) - { - nViewId = nViewMatchingMode; - doc_setView(pThis, nViewId); - } - else if (!isCalc && nLastNonEditorView >= 0 && nLastNonEditorView != nViewId && - pCurrentViewShell && pCurrentViewShell->GetDrawView() && - pCurrentViewShell->GetDrawView()->GetTextEditOutliner()) - { - nViewId = nLastNonEditorView; - doc_setView(pThis, nViewId); + if (nViewId == -1) + nViewId = nOrigViewId; // Couldn't find an alternative view. + // else -> We found an alternative view and already switched to that. } // Disable callbacks while we are painting - after setting the view - if (nViewId != nOrigViewId && nViewId >= 0) - { - const auto handlerIt = pDocument->mpCallbackFlushHandlers.find(nViewId); - if (handlerIt != pDocument->mpCallbackFlushHandlers.end()) - handlerIt->second->disableCallbacks(); - } - - nOrigPart = doc_getPart(pThis); - if (nPart != nOrigPart) - { - doc_setPartImpl(pThis, nPart, false); - } - - nOrigEditMode = pDoc->getEditMode(); - if (nOrigEditMode != nMode) + if (nViewId != nOrigViewId) + disableViewCallbacks(pDocument, nViewId); + else { - SfxLokHelper::setEditMode(nMode, pDoc); + // If we are here, we couldn't find an alternative view. We need to check the part and mode. + nOrigPart = doc_getPart(pThis); + if (nPart != nOrigPart) + doc_setPartImpl(pThis, nPart, false); + + nOrigEditMode = pDoc->getEditMode(); + if (nOrigEditMode != nMode) + SfxLokHelper::setEditMode(nMode, pDoc); } bPaintTextEdit = (nPart == nOrigPart && nMode == nOrigEditMode); @@ -4616,25 +4627,19 @@ static void doc_paintPartTile(LibreOfficeKitDocument* pThis, { pDoc->setPaintTextEdit(true); - if (nMode != nOrigEditMode) + if (nViewId == nOrigViewId) { - SfxLokHelper::setEditMode(nOrigEditMode, pDoc); - } + // We didn't find an alternative view, set the part and mode back to their initial values if needed. + if (nMode != nOrigEditMode) + SfxLokHelper::setEditMode(nOrigEditMode, pDoc); - if (nPart != nOrigPart) - { - doc_setPartImpl(pThis, nOrigPart, false); + if (nPart != nOrigPart) + doc_setPartImpl(pThis, nOrigPart, false); } - - if (nViewId != nOrigViewId) + else { - if (nViewId >= 0) - { - const auto handlerIt = pDocument->mpCallbackFlushHandlers.find(nViewId); - if (handlerIt != pDocument->mpCallbackFlushHandlers.end()) - handlerIt->second->enableCallbacks(); - } - + // We found an alternative view and used it. Enable its callbacks again and turn back to our original view. + enableViewCallbacks(pDocument, nViewId); doc_setView(pThis, nOrigViewId); } } @@ -4644,12 +4649,7 @@ static void doc_paintPartTile(LibreOfficeKitDocument* pThis, // Nothing to do but restore the PartTilePainting flag. } - if (nOrigViewId >= 0) - { - const auto handlerIt = pDocument->mpCallbackFlushHandlers.find(nOrigViewId); - if (handlerIt != pDocument->mpCallbackFlushHandlers.end()) - handlerIt->second->enableCallbacks(); - } + enableViewCallbacks(pDocument, nOrigViewId); } static int doc_getTileMode(SAL_UNUSED_PARAMETER LibreOfficeKitDocument* /*pThis*/) @@ -4741,11 +4741,10 @@ static void doc_initializeForRendering(LibreOfficeKitDocument* pThis, } if (!aSignatureCert.empty() && !aSignatureKey.empty()) { - uno::Reference<security::XCertificate> xCertificate = SfxLokHelper::getSigningCertificate(aSignatureCert, aSignatureKey); if (SfxViewShell* pViewShell = SfxViewShell::Current()) { svl::crypto::CertificateOrName aCertificateOrName; - aCertificateOrName.m_xCertificate = xCertificate; + aCertificateOrName.m_xCertificate = SfxLokHelper::getSigningCertificate(aSignatureCert, aSignatureKey); pViewShell->SetSigningCertificate(aCertificateOrName); } } @@ -5272,6 +5271,17 @@ static void updateConfig(const OUString& rConfigPath) auto xUpdate(css::configuration::Update::get(comphelper::getProcessComponentContext())); xUpdate->insertModificationXcuFile(aXcuPath, { u"/"_ustr }, {}); } + else if (sFileName == "wordbook") + { + uno::Reference<css::linguistic2::XSearchableDictionaryList> xDicList + = LinguMgr::GetDictionaryList(); + if (xDicList.is()) + { + uno::Reference<lang::XInitialization> xReInitDictionaryList(xDicList, + uno::UNO_QUERY_THROW); + xReInitDictionaryList->initialize({}); + } + } } } @@ -5392,8 +5402,7 @@ static bool isCommandAllowed(OUString& command) { if (pViewShell && command == u".uno:TransformDialog"_ustr) { // If the just added signature line shape is selected, allow moving it. - SfxObjectShell* pDocShell = pViewShell->GetObjectShell(); - bRet = pDocShell->GetSignPDFCertificate().Is(); + bRet = pViewShell->GetSignPDFCertificate().Is(); } return bRet; } @@ -6109,18 +6118,6 @@ static int doc_getClipboard(LibreOfficeKitDocument* pThis, size_t **pOutSizes, char ***pOutStreams) { -#ifdef IOS - (void) pThis; - (void) pMimeTypes; - (void) pOutCount; - (void) pOutMimeTypes; - (void) pOutSizes; - (void) pOutStreams; - - assert(!"doc_getClipboard should not be called on iOS"); - - return 0; -#else comphelper::ProfileZone aZone("doc_getClipboard"); SolarMutexGuard aGuard; @@ -6200,7 +6197,6 @@ static int doc_getClipboard(LibreOfficeKitDocument* pThis, } return 1; -#endif } static int doc_setClipboard(LibreOfficeKitDocument* pThis, @@ -6209,13 +6205,6 @@ static int doc_setClipboard(LibreOfficeKitDocument* pThis, const size_t *pInSizes, const char **pInStreams) { -#ifdef IOS - (void) pThis; - (void) nInCount; - (void) pInMimeTypes; - (void) pInSizes; - (void) pInStreams; -#else comphelper::ProfileZone aZone("doc_setClipboard"); SolarMutexGuard aGuard; @@ -6240,7 +6229,7 @@ static int doc_setClipboard(LibreOfficeKitDocument* pThis, SetLastExceptionMsg(u"Document doesn't support this mime type"_ustr); return false; } -#endif + return true; } @@ -6649,6 +6638,34 @@ static char* getUndoOrRedo(LibreOfficeKitDocument* pThis, UndoOrRedo eCommand) return pJson; } +/// Returns only the number of the undo or redo elements +static char* getUndoOrRedoCount(LibreOfficeKitDocument* pThis, UndoOrRedo eCommand) +{ + LibLODocument_Impl* pDocument = static_cast<LibLODocument_Impl*>(pThis); + + auto pBaseModel = dynamic_cast<SfxBaseModel*>(pDocument->mxComponent.get()); + if (!pBaseModel) + return nullptr; + + SfxObjectShell* pObjectShell = pBaseModel->GetObjectShell(); + if (!pObjectShell) + return nullptr; + + SfxUndoManager* pUndoManager = pObjectShell->GetUndoManager(); + if (!pUndoManager) + return nullptr; + + size_t nCount; + if (eCommand == UndoOrRedo::UNDO) + nCount = pUndoManager->GetUndoActionCount(); + else + nCount = pUndoManager->GetRedoActionCount(); + + OUString aString = OUString::number(nCount); + char* pCountStr = convertOUString(aString); + return pCountStr; +} + /// Returns the JSON representation of the redline stack. static char* getTrackedChanges(LibreOfficeKitDocument* pThis) { @@ -6763,6 +6780,14 @@ static char* doc_getCommandValues(LibreOfficeKitDocument* pThis, const char* pCo { return getUndoOrRedo(pThis, UndoOrRedo::REDO); } + else if (aCommand == ".uno:UndoCount") + { + return getUndoOrRedoCount(pThis, UndoOrRedo::UNDO); + } + else if (aCommand == ".uno:RedoCount") + { + return getUndoOrRedoCount(pThis, UndoOrRedo::REDO); + } else if (aCommand == ".uno:AcceptTrackedChanges") { return getTrackedChanges(pThis); @@ -7000,11 +7025,7 @@ static int doc_createViewWithOptions(LibreOfficeKitDocument* pThis, vcl::lok::numberOfViewsChanged(SfxLokHelper::getViewsCount(pDocument->mnDocumentId)); -#ifdef IOS - (void) pThis; -#else forceSetClipboardForCurrentView(pThis); -#endif return nId; } @@ -7958,6 +7979,19 @@ static void preloadData() } std::cerr << "\n"; + // preload all available hyphenators + css::uno::Reference<linguistic2::XHyphenator> xHyphenator(xLngSvcMgr->getHyphenator()); + css::uno::Reference<linguistic2::XSupportedLocales> xHyphLocales(xHyphenator, css::uno::UNO_QUERY_THROW); + aLocales = xHyphLocales->getLocales(); + std::cerr << "Preloading local hyphenators: "; + for (auto &it : std::as_const(aLocales)) + { + std::cerr << LanguageTag::convertToBcp47(it) << " "; + css::beans::PropertyValues aNone; + xHyphenator->createPossibleHyphens(u"forcefed"_ustr, it, aNone); + } + std::cerr << "\n"; + std::cerr << "Preloading breakiterator\n"; if (aLocales.getLength()) { @@ -8314,14 +8348,6 @@ static int lo_initialize(LibreOfficeKit* pThis, const char* pAppPath, const char uno::Reference<lang::XInitialization> xReInitSettings(xPathSettings, uno::UNO_QUERY_THROW); xReInitSettings->initialize({}); - uno::Reference<css::linguistic2::XSearchableDictionaryList> xDicList - = LinguMgr::GetDictionaryList(); - if (xDicList.is()) - { - uno::Reference<lang::XInitialization> xReInitDictionaryList(xDicList, - uno::UNO_QUERY_THROW); - xReInitDictionaryList->initialize({}); - } } } |