/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* * This file is part of the LibreOffice project. * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include constexpr OUStringLiteral DATA_DIRECTORY = u"/sw/qa/uibase/shells/data/"; /// Covers sw/source/uibase/shells/ fixes. class SwUibaseShellsTest : public SwModelTestBase { }; CPPUNIT_TEST_FIXTURE(SwUibaseShellsTest, testTdf130179) { SwDoc* pDoc = createSwDoc(); IDocumentContentOperations& rIDCO = pDoc->getIDocumentContentOperations(); SwCursorShell* pShell(pDoc->GetEditShell()); SfxItemSet aFrameSet(pDoc->GetAttrPool(), svl::Items); SfxItemSet aGrfSet(pDoc->GetAttrPool(), svl::Items); SwFormatAnchor aAnchor(RndStdIds::FLY_AT_PARA); aFrameSet.Put(aAnchor); GraphicObject aGrf; CPPUNIT_ASSERT(rIDCO.InsertGraphicObject(*pShell->GetCursor(), aGrf, &aFrameSet, &aGrfSet)); CPPUNIT_ASSERT_EQUAL(size_t(1), pDoc->GetFlyCount(FLYCNTTYPE_GRF)); SwView* pView = pDoc->GetDocShell()->GetView(); pView->GetViewFrame()->GetDispatcher()->Execute(FN_CNTNT_TO_NEXT_FRAME, SfxCallMode::SYNCHRON); // Make sure SwTextShell is replaced with SwDrawShell right now, not after 120 ms, as set in the // SwView ctor. pView->StopShellTimer(); std::unique_ptr pItem; pView->GetViewFrame()->GetBindings().QueryState(FN_POSTIT, pItem); // Without the accompanying fix in place, this test would have failed with: // assertion failed // - Expression: !pItem // i.e. comment insertion was enabled for an at-para anchored image. CPPUNIT_ASSERT(!pItem); } CPPUNIT_TEST_FIXTURE(SwUibaseShellsTest, testShapeTextAlignment) { // FIXME find out why this fails on macOS/Windows #if !defined(MACOSX) && !defined(_WIN32) // Create a document with a rectangle in it. SwDoc* pDoc = createSwDoc(); SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell(); Point aStartPos(1000, 1000); pWrtShell->BeginCreate(SdrObjKind::Rectangle, aStartPos); Point aMovePos(2000, 2000); pWrtShell->MoveCreate(aMovePos); pWrtShell->EndCreate(SdrCreateCmd::ForceEnd); // Start shape text edit. SwView* pView = pDoc->GetDocShell()->GetView(); // Select the shape. pView->GetViewFrame()->GetDispatcher()->Execute(FN_CNTNT_TO_NEXT_FRAME, SfxCallMode::SYNCHRON); pView->StopShellTimer(); // Start the actual text edit. SdrPage* pPage = pWrtShell->GetDoc()->getIDocumentDrawModelAccess().GetDrawModel()->GetPage(0); CPPUNIT_ASSERT_EQUAL(static_cast(1), pPage->GetObjCount()); SdrObject* pObject = pPage->GetObj(0); pView->EnterShapeDrawTextMode(pObject); pView->AttrChangedNotify(nullptr); // Change paragraph adjustment to center. pView->GetViewFrame()->GetDispatcher()->Execute(SID_ATTR_PARA_ADJUST_CENTER, SfxCallMode::SYNCHRON); // End shape text edit. pWrtShell->EndTextEdit(); const OutlinerParaObject* pOutliner = pObject->GetOutlinerParaObject(); // Without the accompanying fix in place, this test would have failed, because the shape had no // text or text formatting. In other words the paragraph adjustment command was ignored. CPPUNIT_ASSERT(pOutliner); const SfxItemSet& rParaAttribs = pOutliner->GetTextObject().GetParaAttribs(0); SvxAdjust eAdjust = rParaAttribs.GetItem(EE_PARA_JUST)->GetAdjust(); CPPUNIT_ASSERT_EQUAL(SvxAdjust::Center, eAdjust); #endif } CPPUNIT_TEST_FIXTURE(SwUibaseShellsTest, testOleSavePreviewUpdate) { // Load a document with 2 charts in it. The second is down enough that you have to scroll to // trigger its rendering. Previews are missing for both. load(DATA_DIRECTORY, "ole-save-preview-update.odt"); // Explicitly update OLE previews, etc. dispatchCommand(mxComponent, ".uno:UpdateAll", {}); // Save the document and see if we get the previews. uno::Reference xStorable(mxComponent, uno::UNO_QUERY); xStorable->storeToURL(maTempFile.GetURL(), {}); uno::Reference xNameAccess = packages::zip::ZipFileAccess::createWithURL(comphelper::getComponentContext(m_xSFactory), maTempFile.GetURL()); // Without the accompanying fix in place, this test would have failed, because the object // replacements were not generated, even after UpdateAll. CPPUNIT_ASSERT(xNameAccess->hasByName("ObjectReplacements/Object 1")); CPPUNIT_ASSERT(xNameAccess->hasByName("ObjectReplacements/Object 2")); } CPPUNIT_TEST_FIXTURE(SwUibaseShellsTest, testOlePreviewUpdate) { // Given a document with an embedded Writer object: load(DATA_DIRECTORY, "ole-preview-update.odt"); // When updating "all" (including OLE previews): dispatchCommand(mxComponent, ".uno:UpdateAll", {}); // Then make sure the preview is no longer a 0-sized stream: uno::Reference xStorable(mxComponent, uno::UNO_QUERY); xStorable->storeToURL(maTempFile.GetURL(), {}); uno::Reference xNameAccess = packages::zip::ZipFileAccess::createWithURL(comphelper::getComponentContext(m_xSFactory), maTempFile.GetURL()); uno::Reference xInputStream( xNameAccess->getByName("ObjectReplacements/Object 1"), uno::UNO_QUERY); std::unique_ptr pStream(utl::UcbStreamHelper::CreateStream(xInputStream, true)); // Without the accompanying fix in place, this test would have failed, the stream was still // empty. CPPUNIT_ASSERT_GREATER(static_cast(0), pStream->remainingSize()); } CPPUNIT_TEST_FIXTURE(SwUibaseShellsTest, testBibliographyUrlContextMenu) { // Given a document with a bibliography field: SwDoc* pDoc = createSwDoc(); uno::Reference xFactory(mxComponent, uno::UNO_QUERY); uno::Reference xField( xFactory->createInstance("com.sun.star.text.TextField.Bibliography"), uno::UNO_QUERY); uno::Sequence aFields = { comphelper::makePropertyValue("BibiliographicType", text::BibliographyDataType::WWW), comphelper::makePropertyValue("Identifier", OUString("AT")), comphelper::makePropertyValue("Author", OUString("Author")), comphelper::makePropertyValue("Title", OUString("Title")), comphelper::makePropertyValue("URL", OUString("http://www.example.com/test.pdf#page=1")), }; xField->setPropertyValue("Fields", uno::Any(aFields)); uno::Reference xTextDocument(mxComponent, uno::UNO_QUERY); uno::Reference xText = xTextDocument->getText(); uno::Reference xCursor = xText->createTextCursor(); uno::Reference xContent(xField, uno::UNO_QUERY); xText->insertTextContent(xCursor, xContent, /*bAbsorb=*/false); // When selecting the field and opening the context menu: SwDocShell* pDocShell = pDoc->GetDocShell(); SwWrtShell* pWrtShell = pDocShell->GetWrtShell(); pWrtShell->Left(CRSR_SKIP_CHARS, /*bSelect=*/true, 1, /*bBasicCall=*/false); SfxDispatcher* pDispatcher = pDocShell->GetViewShell()->GetViewFrame()->GetDispatcher(); css::uno::Any aState; SfxItemState eState = pDispatcher->QueryState(SID_OPEN_HYPERLINK, aState); // Then the "open hyperlink" menu item should be visible: // Without the accompanying fix in place, this test would have failed with: // - Expected: 32 (SfxItemState::DEFAULT) // - Actual : 1 (SfxItemState::DISABLED) // i.e. the menu item was not visible for biblio entry fields with an URL. CPPUNIT_ASSERT_EQUAL(SfxItemState::DEFAULT, eState); } CPPUNIT_TEST_FIXTURE(SwUibaseShellsTest, testBibliographyLocalCopyContextMenu) { // Given a document with a bibliography field's local copy: SwDoc* pDoc = createSwDoc(); uno::Reference xFactory(mxComponent, uno::UNO_QUERY); uno::Reference xField( xFactory->createInstance("com.sun.star.text.TextField.Bibliography"), uno::UNO_QUERY); uno::Sequence aFields = { comphelper::makePropertyValue("BibiliographicType", text::BibliographyDataType::WWW), comphelper::makePropertyValue("Identifier", OUString("AT")), comphelper::makePropertyValue("Author", OUString("Author")), comphelper::makePropertyValue("Title", OUString("Title")), comphelper::makePropertyValue("URL", OUString("http://www.example.com/test.pdf#page=1")), comphelper::makePropertyValue("LocalURL", OUString("file:///home/me/test.pdf")), }; xField->setPropertyValue("Fields", uno::Any(aFields)); uno::Reference xTextDocument(mxComponent, uno::UNO_QUERY); uno::Reference xText = xTextDocument->getText(); uno::Reference xCursor = xText->createTextCursor(); uno::Reference xContent(xField, uno::UNO_QUERY); xText->insertTextContent(xCursor, xContent, /*bAbsorb=*/false); // When selecting the field and opening the context menu: SwDocShell* pDocShell = pDoc->GetDocShell(); SwWrtShell* pWrtShell = pDocShell->GetWrtShell(); pWrtShell->Left(CRSR_SKIP_CHARS, /*bSelect=*/true, 1, /*bBasicCall=*/false); SfxDispatcher* pDispatcher = pDocShell->GetViewShell()->GetViewFrame()->GetDispatcher(); css::uno::Any aState; SfxItemState eState = pDispatcher->QueryState(FN_OPEN_LOCAL_URL, aState); // Then the "open local copy" menu item should be visible: // Without the accompanying fix in place, this test would have failed with: // - Expected: 32 (SfxItemState::DEFAULT) // - Actual : 1 (SfxItemState::DISABLED) // i.e. the context menu was disabled all the time, even for biblio fields. CPPUNIT_ASSERT_EQUAL(SfxItemState::DEFAULT, eState); } CPPUNIT_TEST_FIXTURE(SwUibaseShellsTest, testContentControlPageBreak) { // Given a document with a content control and a cursor inside the content control: SwDoc* pDoc = createSwDoc(); uno::Reference xMSF(mxComponent, uno::UNO_QUERY); uno::Reference xTextDocument(mxComponent, uno::UNO_QUERY); uno::Reference xText = xTextDocument->getText(); uno::Reference xCursor = xText->createTextCursor(); xText->insertString(xCursor, "test", /*bAbsorb=*/false); xCursor->gotoStart(/*bExpand=*/false); xCursor->gotoEnd(/*bExpand=*/true); uno::Reference xContentControl( xMSF->createInstance("com.sun.star.text.ContentControl"), uno::UNO_QUERY); xText->insertTextContent(xCursor, xContentControl, /*bAbsorb=*/true); SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell(); pWrtShell->SttEndDoc(/*bStt=*/true); pWrtShell->Right(CRSR_SKIP_CHARS, /*bSelect=*/false, 1, /*bBasicCall=*/false); // When trying to insert a page break: dispatchCommand(mxComponent, ".uno:InsertPagebreak", {}); // Then make sure that the document still has a single page: // Without the accompanying fix in place, this test would have failed with: // - Expected: 1 // - Actual : 2 // i.e. inline content control had its start and end in different text nodes, which is not // allowed. CPPUNIT_ASSERT_EQUAL(1, getPages()); } CPPUNIT_PLUGIN_IMPLEMENT(); /* vim:set shiftwidth=4 softtabstop=4 expandtab: */