sw/Library_msword.mk | 1 sw/Library_sw.mk | 1 sw/inc/shellio.hxx | 1 sw/qa/extras/uiwriter/data/autotext-empty.dotx |binary sw/qa/extras/uiwriter/data/autotext-multiple.dotx |binary sw/qa/extras/uiwriter/uiwriter.cxx | 61 +++++++ sw/source/filter/basflt/fltini.cxx | 5 sw/source/filter/docx/swdocxreader.cxx | 144 +++++++++++++++++- sw/source/filter/docx/swdocxreader.hxx | 5 sw/source/ui/misc/glossary.cxx | 59 +++++-- sw/source/uibase/inc/glossary.hxx | 9 + writerfilter/inc/dmapper/resourcemodel.hxx | 6 writerfilter/source/dmapper/DomainMapper.cxx | 25 +++ writerfilter/source/dmapper/DomainMapper.hxx | 2 writerfilter/source/dmapper/DomainMapper_Impl.cxx | 5 writerfilter/source/dmapper/DomainMapper_Impl.hxx | 10 + writerfilter/source/dmapper/LoggedResources.cxx | 26 +++ writerfilter/source/dmapper/LoggedResources.hxx | 4 writerfilter/source/ooxml/OOXMLDocumentImpl.cxx | 6 writerfilter/source/ooxml/OOXMLFastContextHandler.cxx | 12 + writerfilter/source/ooxml/OOXMLFastContextHandler.hxx | 2 writerfilter/source/ooxml/model.xml | 12 + 22 files changed, 376 insertions(+), 20 deletions(-)
New commits: commit 020b390bb53c8026ecad8ffd1baf1fd11b3c4ae7 Author: Szymon KÅos <szymon.k...@collabora.com> Date: Tue May 2 18:02:20 2017 +0200 AutoText: first tests & windows fix First tests for AutoText DOCX import: + checking if nothing will be imported when there is no AutoText, only normal content + checking count of loaded entries + checking names of entries + checking first and last paragraph Windows fix: Added swdocxreader to msword library Change-Id: I3cf02572dd85e72b1566ce523e373753a4bd346c Reviewed-on: https://gerrit.libreoffice.org/37176 Tested-by: Jenkins <c...@libreoffice.org> Reviewed-by: Szymon KÅos <szymon.k...@collabora.com> diff --git a/sw/Library_msword.mk b/sw/Library_msword.mk index ca4975049857..ff5c84cadc02 100644 --- a/sw/Library_msword.mk +++ b/sw/Library_msword.mk @@ -71,6 +71,7 @@ $(eval $(call gb_Library_use_externals,msword,\ )) $(eval $(call gb_Library_add_exception_objects,msword,\ + sw/source/filter/docx/swdocxreader \ sw/source/filter/rtf/swparrtf \ sw/source/filter/ww8/docxattributeoutput \ sw/source/filter/ww8/docxexport \ diff --git a/sw/Library_sw.mk b/sw/Library_sw.mk index b49e6f6fe415..811c8c629ef6 100644 --- a/sw/Library_sw.mk +++ b/sw/Library_sw.mk @@ -500,7 +500,6 @@ $(eval $(call gb_Library_add_exception_objects,sw,\ sw/source/filter/basflt/fltshell \ sw/source/filter/basflt/iodetect \ sw/source/filter/basflt/shellio \ - sw/source/filter/docx/swdocxreader \ sw/source/filter/html/SwAppletImpl \ sw/source/filter/html/css1atr \ sw/source/filter/html/css1kywd \ diff --git a/sw/inc/shellio.hxx b/sw/inc/shellio.hxx index ce171924f106..e5dde4214ff4 100644 --- a/sw/inc/shellio.hxx +++ b/sw/inc/shellio.hxx @@ -533,6 +533,7 @@ struct SwReaderWriterEntry namespace SwReaderWriter { SW_DLLPUBLIC Reader* GetRtfReader(); + SW_DLLPUBLIC Reader* GetDOCXReader(); /// Return reader based on the name. Reader* GetReader( const OUString& rFltName ); diff --git a/sw/qa/extras/uiwriter/data/autotext-empty.dotx b/sw/qa/extras/uiwriter/data/autotext-empty.dotx new file mode 100644 index 000000000000..0d9f51dc2a4a Binary files /dev/null and b/sw/qa/extras/uiwriter/data/autotext-empty.dotx differ diff --git a/sw/qa/extras/uiwriter/data/autotext-multiple.dotx b/sw/qa/extras/uiwriter/data/autotext-multiple.dotx new file mode 100644 index 000000000000..83b083992a08 Binary files /dev/null and b/sw/qa/extras/uiwriter/data/autotext-multiple.dotx differ diff --git a/sw/qa/extras/uiwriter/uiwriter.cxx b/sw/qa/extras/uiwriter/uiwriter.cxx index 65e1a0cc1843..69b0a1eabeb3 100644 --- a/sw/qa/extras/uiwriter/uiwriter.cxx +++ b/sw/qa/extras/uiwriter/uiwriter.cxx @@ -116,6 +116,8 @@ public: void testFdo70807(); void testImportRTF(); void testExportRTF(); + void testDOCXAutoTextEmpty(); + void testDOCXAutoTextMultiple(); void testTdf67238(); void testFdo75110(); void testFdo75898(); @@ -233,6 +235,8 @@ public: CPPUNIT_TEST(testFdo70807); CPPUNIT_TEST(testImportRTF); CPPUNIT_TEST(testExportRTF); + CPPUNIT_TEST(testDOCXAutoTextEmpty); + CPPUNIT_TEST(testDOCXAutoTextMultiple); CPPUNIT_TEST(testTdf67238); CPPUNIT_TEST(testFdo75110); CPPUNIT_TEST(testFdo75898); @@ -344,6 +348,7 @@ public: private: SwDoc* createDoc(const char* pName = nullptr); + SwTextBlocks* readDOCXAutotext(const OUString& sFileName, bool bEmpty = false); }; SwDoc* SwUiWriterTest::createDoc(const char* pName) @@ -358,6 +363,23 @@ SwDoc* SwUiWriterTest::createDoc(const char* pName) return pTextDoc->GetDocShell()->GetDoc(); } +SwTextBlocks* SwUiWriterTest::readDOCXAutotext(const OUString& sFileName, bool bEmpty) +{ + OUString rURL = m_directories.getURLFromSrc(DATA_DIRECTORY) + sFileName; + + SfxMedium* pSrcMed = new SfxMedium(rURL, StreamMode::STD_READ); + SwDoc* pDoc = createDoc(); + + SwReader aReader(*pSrcMed, rURL, pDoc); + Reader* pDOCXReader = SwReaderWriter::GetDOCXReader(); + SwTextBlocks* pGlossary = new SwTextBlocks(rURL); + + CPPUNIT_ASSERT(pDOCXReader != nullptr); + CPPUNIT_ASSERT_EQUAL(!bEmpty, aReader.ReadGlossaries(*pDOCXReader, *pGlossary, false)); + + return pGlossary; +} + //Replacement tests static void lcl_selectCharacters(SwPaM& rPaM, sal_Int32 first, sal_Int32 end) @@ -719,6 +741,45 @@ void SwUiWriterTest::testExportRTF() CPPUNIT_ASSERT(aData.endsWith("bbb}" SAL_NEWLINE_STRING "}")); } +void SwUiWriterTest::testDOCXAutoTextEmpty() +{ + // file contains normal content but no AutoText + SwTextBlocks* pGlossary = readDOCXAutotext("autotext-empty.dotx", true); + CPPUNIT_ASSERT(pGlossary != nullptr); +} + +void SwUiWriterTest::testDOCXAutoTextMultiple() +{ + // file contains three AutoText entries + SwTextBlocks* pGlossary = readDOCXAutotext("autotext-multiple.dotx"); + + // check entries count + CPPUNIT_ASSERT_EQUAL((sal_uInt16)3, pGlossary->GetCount()); + + // check names of entries, sorted order + CPPUNIT_ASSERT_EQUAL(OUString("Anothercomplex"), pGlossary->GetLongName(0)); + CPPUNIT_ASSERT_EQUAL(OUString("Multiple"), pGlossary->GetLongName(1)); + CPPUNIT_ASSERT_EQUAL(OUString("Second Autotext"), pGlossary->GetLongName(2)); + + // check if previously loaded content is correct (eg. doesn't contain title) + SwDoc* pDoc = pGlossary->GetDoc(); + CPPUNIT_ASSERT(pDoc != nullptr); + + SwNodeIndex aDocEnd(pDoc->GetNodes().GetEndOfContent()); + SwNodeIndex aStart(*aDocEnd.GetNode().StartOfSectionNode(), 1); + + CPPUNIT_ASSERT(aStart < aDocEnd); + + // first line + SwNode& rNode = aStart.GetNode(); + CPPUNIT_ASSERT_EQUAL(OUString("Another "), rNode.GetTextNode()->GetText()); + + // last line + SwNodeIndex aLast(*aDocEnd.GetNode().EndOfSectionNode(), -1); + SwNode& rLastNode = aLast.GetNode(); + CPPUNIT_ASSERT_EQUAL(OUString("complex"), rLastNode.GetTextNode()->GetText()); +} + void SwUiWriterTest::testFdo74981() { // create a document with an input field diff --git a/sw/source/filter/basflt/fltini.cxx b/sw/source/filter/basflt/fltini.cxx index af368df364a0..46e81083ef4d 100644 --- a/sw/source/filter/basflt/fltini.cxx +++ b/sw/source/filter/basflt/fltini.cxx @@ -166,6 +166,11 @@ Reader* GetRtfReader() return aReaderWriter[READER_WRITER_RTF].GetReader(); } +Reader* GetDOCXReader() +{ + return aReaderWriter[READER_WRITER_DOCX].GetReader(); +} + void GetWriter( const OUString& rFltName, const OUString& rBaseURL, WriterRef& xRet ) { for( int n = 0; n < MAXFILTER; ++n ) commit d543b1e92d7e8f6e6a1d55c5f3c904fe1ecc0e6e Author: Szymon KÅos <szymon.k...@collabora.com> Date: Wed May 3 13:51:47 2017 +0200 AutoText: don't add empty paragraph at the end Change-Id: Idf255ea87982a2c95c129ac34864779700861e69 diff --git a/sw/source/filter/docx/swdocxreader.cxx b/sw/source/filter/docx/swdocxreader.cxx index 8a20cf0d2a8a..7558b4dfba10 100644 --- a/sw/source/filter/docx/swdocxreader.cxx +++ b/sw/source/filter/docx/swdocxreader.cxx @@ -139,7 +139,7 @@ bool SwDOCXReader::MakeEntries( SwDoc *pD, SwTextBlocks &rBlocks ) aPam.SetMark(); { SwNodeIndex& rIdx = aPam.GetPoint()->nNode; - rIdx = aStart.GetNode().EndOfSectionIndex() - 1; + rIdx = aStart.GetNode().EndOfSectionIndex() - 2; if( ( nullptr == ( pCNd = rIdx.GetNode().GetContentNode() ) ) ) { ++rIdx; commit 683ba8bdbdbf718d1e26ddc0fd7e45b4aa7771a1 Author: Szymon KÅos <szymon.k...@collabora.com> Date: Mon May 1 19:05:48 2017 +0200 AutoText: read names of entries + extended model to parse <docPartPr> and <name> marks + names are inserted to the document before content of each entry + SwDOCXReader interprets first paragraph of each section as a name Change-Id: Ib7de152ba1c6bea4f4665f98d321019c3f68863e Reviewed-on: https://gerrit.libreoffice.org/37124 Tested-by: Jenkins <c...@libreoffice.org> Reviewed-by: Miklos Vajna <vmik...@collabora.co.uk> diff --git a/sw/source/filter/docx/swdocxreader.cxx b/sw/source/filter/docx/swdocxreader.cxx index 7a3cc9425bd5..8a20cf0d2a8a 100644 --- a/sw/source/filter/docx/swdocxreader.cxx +++ b/sw/source/filter/docx/swdocxreader.cxx @@ -111,6 +111,19 @@ bool SwDOCXReader::MakeEntries( SwDoc *pD, SwTextBlocks &rBlocks ) sal_uInt16 nGlosEntry = 0; SwContentNode* pCNd = nullptr; do { + // Get name - first paragraph + OUString aLNm; + { + SwPaM aPam( aStart ); + SwNodeIndex& rIdx = aPam.GetPoint()->nNode; + ++rIdx; + aLNm = aPam.GetNode().GetTextNode()->GetText(); + } + + // Do not copy name + aStart++; + + // Get content SwPaM aPam( aStart ); { SwNodeIndex& rIdx = aPam.GetPoint()->nNode; @@ -139,10 +152,7 @@ bool SwDOCXReader::MakeEntries( SwDoc *pD, SwTextBlocks &rBlocks ) // Now we have the right selection for one entry rBlocks.ClearDoc(); - // TODO: correct entry name - const OUString rLNm = "ImportedAutoText"; - - OUString sShortcut = rLNm; + OUString sShortcut = aLNm; // Need to check make sure the shortcut is not already being used sal_Int32 nStart = 0; diff --git a/writerfilter/source/dmapper/DomainMapper.cxx b/writerfilter/source/dmapper/DomainMapper.cxx index 94116020c8c6..003983b6e54c 100644 --- a/writerfilter/source/dmapper/DomainMapper.cxx +++ b/writerfilter/source/dmapper/DomainMapper.cxx @@ -1080,6 +1080,13 @@ void DomainMapper::lcl_attribute(Id nName, Value & val) case NS_ooxml::LN_CT_Cnf_val: m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, "val", sStringValue); break; + case NS_ooxml::LN_CT_DocPartName_val: + { + // Add glossary entry name as a first paragraph in section + PropertyMapPtr pContext = m_pImpl->GetTopContext(); + m_pImpl->appendTextPortion(sStringValue, pContext); + break; + } default: SAL_WARN("writerfilter", "DomainMapper::lcl_attribute: unhandled token: " << nName); } @@ -2753,6 +2760,13 @@ void DomainMapper::sprmWithProps( Sprm& rSprm, const PropertyMapPtr& rContext ) pProperties->resolve(m_pImpl->getSmartTagHandler()); } break; + case NS_ooxml::LN_CT_DocPartPr_name: + { + writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps(); + if (pProperties.get() != nullptr) + pProperties->resolve(*this); + } + break; default: { #ifdef DEBUG_WRITERFILTER diff --git a/writerfilter/source/ooxml/model.xml b/writerfilter/source/ooxml/model.xml index 1b9b0933611d..bb1917307ff1 100644 --- a/writerfilter/source/ooxml/model.xml +++ b/writerfilter/source/ooxml/model.xml @@ -19062,6 +19062,13 @@ <action name="start" action="startGlossaryEntry"/> <action name="end" action="endGlossaryEntry"/> </resource> + <resource name="CT_DocPartPr" resource="Properties"> + <action name="start" action="startSectionGroup"/> + <element name="name" tokenid="ooxml:CT_DocPartPr_name"/> + </resource> + <resource name="CT_DocPartName" resource="Properties"> + <attribute name="val" tokenid="ooxml:CT_DocPartName_val"/> + </resource> <resource name="document" resource="Stream"/> <resource name="glossaryDocument" resource="Stream"/> <resource name="CT_TxbxContent" resource="Stream"> commit d294c6d749c1f3281df0b384a3793a2ed681e4b4 Author: Szymon KÅos <szymon.k...@collabora.com> Date: Fri Apr 28 21:00:23 2017 +0200 AutoText: Reading multiple entries + each entry is placed in a separate section + extended model and dmapper to react on docPart mark Change-Id: I7e5213a09ae7352d1d09369bd0a209b6d4e18e82 Reviewed-on: https://gerrit.libreoffice.org/37107 Tested-by: Jenkins <c...@libreoffice.org> Reviewed-by: Szymon KÅos <szymon.k...@collabora.com> diff --git a/sw/source/filter/docx/swdocxreader.cxx b/sw/source/filter/docx/swdocxreader.cxx index 419d0bc142fb..7a3cc9425bd5 100644 --- a/sw/source/filter/docx/swdocxreader.cxx +++ b/sw/source/filter/docx/swdocxreader.cxx @@ -87,16 +87,8 @@ bool SwDOCXReader::ReadGlossaries( SwTextBlocks& rBlocks, bool /* bSaveRelFiles aDescriptor[1].Name = "ReadGlossaries"; aDescriptor[1].Value <<= true; - try - { - xFilter->filter( aDescriptor ); - } - catch( uno::Exception const& e ) - { - SAL_WARN("sw.docx", "SwDOCXReader::ReadGlossaries(): exception: " << e.Message); - } - - return MakeEntries( static_cast<SwDocShell*>( &xDocSh )->GetDoc(), rBlocks ); + if( xFilter->filter( aDescriptor ) ) + return MakeEntries( static_cast<SwDocShell*>( &xDocSh )->GetDoc(), rBlocks ); } return false; @@ -110,7 +102,7 @@ bool SwDOCXReader::MakeEntries( SwDoc *pD, SwTextBlocks &rBlocks ) bool bRet = false; SwNodeIndex aDocEnd( pD->GetNodes().GetEndOfContent() ); - SwNodeIndex aStart( *aDocEnd.GetNode().StartOfSectionNode() ); + SwNodeIndex aStart( *aDocEnd.GetNode().StartOfSectionNode(), 1 ); if( aStart < aDocEnd && ( aDocEnd.GetIndex() - aStart.GetIndex() > 2 ) ) { @@ -144,6 +136,7 @@ bool SwDOCXReader::MakeEntries( SwDoc *pD, SwTextBlocks &rBlocks ) } aPam.GetPoint()->nContent.Assign( pCNd, pCNd->Len() ); + // Now we have the right selection for one entry rBlocks.ClearDoc(); // TODO: correct entry name @@ -174,15 +167,9 @@ bool SwDOCXReader::MakeEntries( SwDoc *pD, SwTextBlocks &rBlocks ) rBlocks.PutDoc(); } - if( aStart.GetNodes().Count() <= aStart.GetNode().GetIndex() ) - aStart = aStart.GetNode().EndOfSectionIndex() + 1; - else - break; - + aStart = aStart.GetNode().EndOfSectionIndex() + 1; ++nGlosEntry; - - } while( aStart < aDocEnd ); - + } while( aStart < aDocEnd && aStart.GetNode().IsStartNode() ); bRet = true; } diff --git a/writerfilter/inc/dmapper/resourcemodel.hxx b/writerfilter/inc/dmapper/resourcemodel.hxx index 252d83375c69..71b967d2db98 100644 --- a/writerfilter/inc/dmapper/resourcemodel.hxx +++ b/writerfilter/inc/dmapper/resourcemodel.hxx @@ -292,6 +292,12 @@ public: */ virtual void info(const std::string & info) = 0; + /// Receives start mark for glossary document entry. + virtual void startGlossaryEntry() = 0; + + /// Receives end mark for glossary document entry. + virtual void endGlossaryEntry() = 0; + protected: ~Stream() {} }; diff --git a/writerfilter/source/dmapper/DomainMapper.cxx b/writerfilter/source/dmapper/DomainMapper.cxx index f2dfd37e727c..94116020c8c6 100644 --- a/writerfilter/source/dmapper/DomainMapper.cxx +++ b/writerfilter/source/dmapper/DomainMapper.cxx @@ -3427,6 +3427,17 @@ void DomainMapper::lcl_info(const std::string & /*info_*/) { } +void DomainMapper::lcl_startGlossaryEntry() +{ + uno::Reference< text::XTextRange > xTextRange = GetCurrentTextRange(); + m_pImpl->setGlossaryEntryStart(xTextRange); +} + +void DomainMapper::lcl_endGlossaryEntry() +{ + m_pImpl->appendGlossaryEntry(); +} + void DomainMapper::handleUnderlineType(const Id nId, const ::std::shared_ptr<PropertyMap>& rContext) { sal_Int16 nUnderline = awt::FontUnderline::NONE; diff --git a/writerfilter/source/dmapper/DomainMapper.hxx b/writerfilter/source/dmapper/DomainMapper.hxx index 4f05118b1190..7a346884d642 100644 --- a/writerfilter/source/dmapper/DomainMapper.hxx +++ b/writerfilter/source/dmapper/DomainMapper.hxx @@ -146,6 +146,8 @@ private: virtual void lcl_substream(Id name, ::writerfilter::Reference<Stream>::Pointer_t ref) override; virtual void lcl_info(const std::string & info) override; + virtual void lcl_startGlossaryEntry() override; + virtual void lcl_endGlossaryEntry() override; // Properties virtual void lcl_attribute(Id Name, Value & val) override; diff --git a/writerfilter/source/dmapper/DomainMapper_Impl.cxx b/writerfilter/source/dmapper/DomainMapper_Impl.cxx index a9473ef74c68..8e261740a400 100644 --- a/writerfilter/source/dmapper/DomainMapper_Impl.cxx +++ b/writerfilter/source/dmapper/DomainMapper_Impl.cxx @@ -1536,6 +1536,11 @@ uno::Reference< beans::XPropertySet > DomainMapper_Impl::appendTextSectionAfter( return xRet; } +uno::Reference< beans::XPropertySet > DomainMapper_Impl::appendGlossaryEntry() +{ + return appendTextSectionAfter(m_xGlossaryEntryStart); +} + void DomainMapper_Impl::PushPageHeaderFooter(bool bHeader, SectionPropertyMap::PageType eType) { m_aHeaderFooterStack.push(HeaderFooterContext(m_bTextInserted)); diff --git a/writerfilter/source/dmapper/DomainMapper_Impl.hxx b/writerfilter/source/dmapper/DomainMapper_Impl.hxx index 7ec425151ee9..b86938df337f 100644 --- a/writerfilter/source/dmapper/DomainMapper_Impl.hxx +++ b/writerfilter/source/dmapper/DomainMapper_Impl.hxx @@ -464,6 +464,8 @@ private: std::map<sal_Int32, css::uno::Any> deferredCharacterProperties; SmartTagHandler m_aSmartTagHandler; + css::uno::Reference<css::text::XTextRange> m_xGlossaryEntryStart; + public: css::uno::Reference<css::text::XTextRange> m_xInsertTextRange; private: @@ -557,6 +559,14 @@ public: void appendStarMath( const Value& v ); css::uno::Reference<css::beans::XPropertySet> appendTextSectionAfter(css::uno::Reference<css::text::XTextRange>& xBefore); + /// AutoText import: each entry is placed in the separate section + css::uno::Reference<css::beans::XPropertySet> appendGlossaryEntry(); + /// Remember where entry was started + void setGlossaryEntryStart( css::uno::Reference<css::text::XTextRange>& xStart ) + { + m_xGlossaryEntryStart = xStart; + } + // push the new properties onto the stack and make it the 'current' property map void PushProperties(ContextType eId); void PushStyleProperties(const PropertyMapPtr& pStyleProperties); diff --git a/writerfilter/source/dmapper/LoggedResources.cxx b/writerfilter/source/dmapper/LoggedResources.cxx index 55ade5a41138..33744b9765e7 100644 --- a/writerfilter/source/dmapper/LoggedResources.cxx +++ b/writerfilter/source/dmapper/LoggedResources.cxx @@ -301,6 +301,32 @@ void LoggedStream::info(const std::string & _info) #endif } +void LoggedStream::startGlossaryEntry() +{ +#ifdef DEBUG_WRITERFILTER + mHelper.startElement("startGlossaryEntry"); +#endif + + lcl_startGlossaryEntry(); + +#ifdef DEBUG_WRITERFILTER + LoggedResourcesHelper::endElement("startGlossaryEntry"); +#endif +} + +void LoggedStream::endGlossaryEntry() +{ +#ifdef DEBUG_WRITERFILTER + mHelper.startElement("endGlossaryEntry"); +#endif + + lcl_endGlossaryEntry(); + +#ifdef DEBUG_WRITERFILTER + LoggedResourcesHelper::endElement("endGlossaryEntry"); +#endif +} + // class LoggedProperties LoggedProperties::LoggedProperties( #ifdef DEBUG_WRITERFILTER diff --git a/writerfilter/source/dmapper/LoggedResources.hxx b/writerfilter/source/dmapper/LoggedResources.hxx index 0c466448a85b..c5d59a68a9ec 100644 --- a/writerfilter/source/dmapper/LoggedResources.hxx +++ b/writerfilter/source/dmapper/LoggedResources.hxx @@ -69,6 +69,8 @@ public: void table(Id name, writerfilter::Reference<Table>::Pointer_t ref) override; void substream(Id name, writerfilter::Reference<Stream>::Pointer_t ref) override; void info(const std::string & info) override; + void startGlossaryEntry() override; + void endGlossaryEntry() override; protected: virtual void lcl_startSectionGroup() = 0; @@ -89,6 +91,8 @@ protected: virtual void lcl_table(Id name, writerfilter::Reference<Table>::Pointer_t ref) = 0; virtual void lcl_substream(Id name, writerfilter::Reference<Stream>::Pointer_t ref) = 0; virtual void lcl_info(const std::string & info) = 0; + virtual void lcl_startGlossaryEntry() { } + virtual void lcl_endGlossaryEntry() { } #ifdef DEBUG_WRITERFILTER LoggedResourcesHelper mHelper; diff --git a/writerfilter/source/ooxml/OOXMLFastContextHandler.cxx b/writerfilter/source/ooxml/OOXMLFastContextHandler.cxx index 0715e0ed828f..bb5ff5fa98fb 100644 --- a/writerfilter/source/ooxml/OOXMLFastContextHandler.cxx +++ b/writerfilter/source/ooxml/OOXMLFastContextHandler.cxx @@ -652,6 +652,18 @@ void OOXMLFastContextHandler::positivePercentage(const OUString& rText) mpStream->positivePercentage(rText); } +void OOXMLFastContextHandler::startGlossaryEntry() +{ + if (isForwardEvents()) + mpStream->startGlossaryEntry(); +} + +void OOXMLFastContextHandler::endGlossaryEntry() +{ + if (isForwardEvents()) + mpStream->endGlossaryEntry(); +} + void OOXMLFastContextHandler::propagateCharacterProperties() { mpParserState->setCharacterProperties(getPropertySet()); diff --git a/writerfilter/source/ooxml/OOXMLFastContextHandler.hxx b/writerfilter/source/ooxml/OOXMLFastContextHandler.hxx index d0df17fcb30d..f986c76029ae 100644 --- a/writerfilter/source/ooxml/OOXMLFastContextHandler.hxx +++ b/writerfilter/source/ooxml/OOXMLFastContextHandler.hxx @@ -168,6 +168,8 @@ public: void alignH(const OUString & sText); void alignV(const OUString & sText); void positivePercentage(const OUString& rText); + void startGlossaryEntry(); + void endGlossaryEntry(); void startTxbxContent(); void endTxbxContent(); void propagateCharacterProperties(); diff --git a/writerfilter/source/ooxml/model.xml b/writerfilter/source/ooxml/model.xml index cfd6d527d4bc..1b9b0933611d 100644 --- a/writerfilter/source/ooxml/model.xml +++ b/writerfilter/source/ooxml/model.xml @@ -19058,7 +19058,10 @@ <resource name="CT_Document" resource="Stream"/> <resource name="CT_GlossaryDocument" resource="Stream"/> <resource name="CT_DocParts" resource="Stream"/> - <resource name="CT_DocPart" resource="Stream"/> + <resource name="CT_DocPart" resource="Stream"> + <action name="start" action="startGlossaryEntry"/> + <action name="end" action="endGlossaryEntry"/> + </resource> <resource name="document" resource="Stream"/> <resource name="glossaryDocument" resource="Stream"/> <resource name="CT_TxbxContent" resource="Stream"> commit 463d408f3555b57c4af8cbd006812f269944b092 Author: Szymon KÅos <szymon.k...@collabora.com> Date: Mon May 1 13:59:51 2017 +0200 AutoText: handle Delete key in the dialog Change-Id: Ifbd0026b097ff9fbf077dda57f874cfc59da3e45 Reviewed-on: https://gerrit.libreoffice.org/37119 Tested-by: Jenkins <c...@libreoffice.org> Reviewed-by: Szymon KÅos <szymon.k...@collabora.com> diff --git a/sw/source/ui/misc/glossary.cxx b/sw/source/ui/misc/glossary.cxx index 29d482ac7dea..9d6f208bb25a 100644 --- a/sw/source/ui/misc/glossary.cxx +++ b/sw/source/ui/misc/glossary.cxx @@ -230,6 +230,7 @@ SwGlossaryDlg::SwGlossaryDlg(SfxViewFrame* pViewFrame, m_pCategoryBox->SetDoubleClickHdl(LINK(this,SwGlossaryDlg, NameDoubleClick)); m_pCategoryBox->SetSelectHdl(LINK(this,SwGlossaryDlg,GrpSelect)); + m_pCategoryBox->SetDeleteHdl(LINK(this,SwGlossaryDlg,DeleteHdl)); m_pBibBtn->SetClickHdl(LINK(this,SwGlossaryDlg,BibHdl)); m_pInsertBtn->SetClickHdl(LINK(this,SwGlossaryDlg,InsertHdl)); @@ -522,23 +523,7 @@ IMPL_LINK( SwGlossaryDlg, MenuHdl, Menu *, pMn, bool ) } else if (sItemIdent == "delete") { - ScopedVclPtrInstance< MessageDialog > aQuery(this, SW_RES(STR_QUERY_DELETE), VclMessageType::Question, VCL_BUTTONS_YES_NO); - if (RET_YES == aQuery->Execute()) - { - const OUString aShortName(m_pShortNameEdit->GetText()); - const OUString aTitle(m_pNameED->GetText()); - if (!aTitle.isEmpty() && pGlossaryHdl->DelGlossary(aShortName)) - { - SvTreeListEntry* pChild = DoesBlockExist(aTitle, aShortName); - OSL_ENSURE(pChild, "entry not found!"); - SvTreeListEntry* pParent = m_pCategoryBox->GetParent(pChild); - m_pCategoryBox->Select(pParent); - - m_pCategoryBox->GetModel()->Remove(pChild); - m_pNameED->SetText(OUString()); - NameModify(*m_pNameED); - } - } + DeleteEntry(); } else if (sItemIdent == "macro") { @@ -1028,6 +1013,16 @@ void SwGlTreeListBox::ExpandedHdl() SvTreeListBox::ExpandedHdl(); } +void SwGlTreeListBox::KeyInput( const KeyEvent& rKEvt ) +{ + if(m_aDeleteHdl.IsSet() && rKEvt.GetKeyCode().GetCode() == KEY_DELETE) + { + m_aDeleteHdl.Call(nullptr); + return; + } + SvTreeListBox::KeyInput( rKEvt ); +} + OUString SwGlossaryDlg::GetCurrGrpName() const { SvTreeListEntry* pEntry = m_pCategoryBox->FirstSelected(); @@ -1069,6 +1064,11 @@ IMPL_LINK_NOARG(SwGlossaryDlg, InsertHdl, Button*, void) EndDialog(RET_OK); } +IMPL_LINK_NOARG(SwGlossaryDlg, DeleteHdl, SwGlTreeListBox*, void) +{ + DeleteEntry(); +} + void SwGlossaryDlg::ShowPreview() { //create example @@ -1130,4 +1130,29 @@ void SwGlossaryDlg::ResumeShowAutoText() bResume = false; } +void SwGlossaryDlg::DeleteEntry() +{ + SvTreeListEntry* pEntry = m_pCategoryBox->FirstSelected(); + + const OUString aTitle(m_pNameED->GetText()); + const OUString aShortName(m_pShortNameEdit->GetText()); + SvTreeListEntry* pChild = DoesBlockExist(aTitle, aShortName); + SvTreeListEntry* pParent = pChild ? m_pCategoryBox->GetParent(pChild) : nullptr; + const bool bExists = nullptr != pChild; + const bool bIsGroup = pEntry && !pParent; + + ScopedVclPtrInstance< MessageDialog > aQuery(this, SW_RES(STR_QUERY_DELETE), VclMessageType::Question, VCL_BUTTONS_YES_NO); + if (bExists && !bIsGroup && RET_YES == aQuery->Execute()) + { + if (!aTitle.isEmpty() && pGlossaryHdl->DelGlossary(aShortName)) + { + OSL_ENSURE(pChild, "entry not found!"); + m_pCategoryBox->Select(pParent); + m_pCategoryBox->GetModel()->Remove(pChild); + m_pNameED->SetText(OUString()); + NameModify(*m_pNameED); + } + } +} + /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/uibase/inc/glossary.hxx b/sw/source/uibase/inc/glossary.hxx index 72075b5737a2..7a341336e235 100644 --- a/sw/source/uibase/inc/glossary.hxx +++ b/sw/source/uibase/inc/glossary.hxx @@ -57,6 +57,8 @@ class SwGlTreeListBox : public SvTreeListBox SvTreeListEntry* pDragEntry; + Link<SwGlTreeListBox*,void> m_aDeleteHdl; + virtual DragDropMode NotifyStartDrag( TransferDataContainer& rContainer, SvTreeListEntry* ) override; virtual bool NotifyAcceptDrop( SvTreeListEntry* ) override; @@ -82,6 +84,10 @@ public: void Clear(); virtual void ExpandedHdl() override; + + virtual void KeyInput( const KeyEvent& rKEvt ) override; + + void SetDeleteHdl( const Link<SwGlTreeListBox*,void>& rLink ) { m_aDeleteHdl = rLink; } }; class SwOneExampleFrame; @@ -136,6 +142,7 @@ class SwGlossaryDlg : public SvxStandardDialog DECL_LINK( PathHdl, Button *, void ); DECL_LINK( CheckBoxHdl, Button*, void ); DECL_LINK( PreviewLoadedHdl, SwOneExampleFrame&, void ); + DECL_LINK( DeleteHdl, SwGlTreeListBox*, void ); virtual void Apply() override; void Init(); @@ -147,6 +154,8 @@ class SwGlossaryDlg : public SvxStandardDialog {rGroup = sResumeGroup; rShortName = sResumeShortName; return bResume;} void SetResumeData(const OUString& rGroup, const OUString& rShortName) {sResumeGroup = rGroup; sResumeShortName = rShortName; bResume = true;} + + void DeleteEntry(); public: SwGlossaryDlg(SfxViewFrame* pViewFrame, SwGlossaryHdl* pGlosHdl, SwWrtShell *pWrtShell); virtual ~SwGlossaryDlg() override; commit 2d4730053dc13bade249579475b5170771ff58d3 Author: Szymon KÅos <szymon.k...@collabora.com> Date: Thu Apr 20 18:42:56 2017 +0200 AutoText: importing docx content - passing "ReadGlossaries" flag to the WriterFilter - if set - WriterFilter reads glossary document instead of the main content - updated model.xml to read docParts and docPart nodes - SwDOCXReader adds document content as an AutoText entry Change-Id: I9a0cc91c793d6accc8461e1c3aca791c5997d497 Reviewed-on: https://gerrit.libreoffice.org/36753 Tested-by: Jenkins <c...@libreoffice.org> Reviewed-by: Szymon KÅos <szymon.k...@collabora.com> Tested-by: Szymon KÅos <szymon.k...@collabora.com> diff --git a/sw/source/filter/docx/swdocxreader.cxx b/sw/source/filter/docx/swdocxreader.cxx index b8ea965d3504..419d0bc142fb 100644 --- a/sw/source/filter/docx/swdocxreader.cxx +++ b/sw/source/filter/docx/swdocxreader.cxx @@ -29,6 +29,10 @@ #include <comphelper/propertyvalue.hxx> #include <comphelper/sequenceashashmap.hxx> #include <docsh.hxx> +#include <IDocumentStylePoolAccess.hxx> +#include <ndtxt.hxx> +#include <poolfmt.hxx> +#include <svl/urihelper.hxx> #include <swerror.h> #include <tools/ref.hxx> #include <unotxdoc.hxx> @@ -59,34 +63,6 @@ bool SwDOCXReader::HasGlossaries() const bool SwDOCXReader::ReadGlossaries( SwTextBlocks& rBlocks, bool /* bSaveRelFiles */ ) const { - bool bRet = false; - - uno::Reference<xml::dom::XDocument> xDoc = OpenDocument(); - - if( xDoc.is() ) - { - uno::Reference<xml::dom::XNodeList> xList = xDoc->getElementsByTagName( "docPartBody" ); - for( int i = 0; i < xList->getLength(); i++ ) - { - uno::Reference<xml::dom::XNode> xBody = xList->item( i ); - uno::Reference<xml::dom::XNode> xP = xBody->getFirstChild(); - uno::Reference<xml::dom::XNode> xR = xP->getFirstChild(); - uno::Reference<xml::dom::XNode> xT = xR->getFirstChild(); - uno::Reference<xml::dom::XNode> xText = xT->getFirstChild(); - OUString aText = xText->getNodeValue(); - if( !aText.isEmpty() ) - { - rBlocks.PutText( aText, aText, aText ); - bRet = true; - } - } - } - - return bRet; -} - -uno::Reference<xml::dom::XDocument> SwDOCXReader::OpenDocument() const -{ uno::Reference<lang::XMultiServiceFactory> xMultiServiceFactory( comphelper::getProcessServiceFactory() ); @@ -98,54 +74,121 @@ uno::Reference<xml::dom::XDocument> SwDOCXReader::OpenDocument() const uno::Reference<document::XImporter> xImporter( xFilter, uno::UNO_QUERY_THROW ); SfxObjectShellLock xDocSh( new SwDocShell( SfxObjectCreateMode::INTERNAL ) ); - xDocSh->DoInitNew(); - - uno::Reference<lang::XComponent> xDstDoc( xDocSh->GetModel(), uno::UNO_QUERY_THROW ); - xImporter->setTargetDocument( xDstDoc ); + if( xDocSh->DoInitNew() ) + { + uno::Reference<lang::XComponent> xDstDoc( xDocSh->GetModel(), uno::UNO_QUERY_THROW ); + xImporter->setTargetDocument( xDstDoc ); - uno::Sequence<beans::PropertyValue> aDescriptor( 1 ); - aDescriptor[0].Name = "InputStream"; - uno::Reference<io::XStream> xStream( new utl::OStreamWrapper( *pMedium->GetInStream() ) ); - aDescriptor[0].Value <<= xStream; + uno::Reference<io::XStream> xStream( new utl::OStreamWrapper( *pMedium->GetInStream() ) ); - uno::Reference<xml::dom::XDocument> xDoc; + uno::Sequence<beans::PropertyValue> aDescriptor( 2 ); + aDescriptor[0].Name = "InputStream"; + aDescriptor[0].Value <<= xStream; + aDescriptor[1].Name = "ReadGlossaries"; + aDescriptor[1].Value <<= true; - try - { - xFilter->filter( aDescriptor ); + try + { + xFilter->filter( aDescriptor ); + } + catch( uno::Exception const& e ) + { + SAL_WARN("sw.docx", "SwDOCXReader::ReadGlossaries(): exception: " << e.Message); + } - comphelper::SequenceAsHashMap aGrabBag = GetGrabBag( xDstDoc ); - aGrabBag["OOXGlossary"] >>= xDoc; - } - catch (uno::Exception const& e) - { - SAL_WARN("sw.docx", "SwDOCXReader::OpenDocument(): exception: " << e.Message); + return MakeEntries( static_cast<SwDocShell*>( &xDocSh )->GetDoc(), rBlocks ); } - return xDoc; + return false; } -comphelper::SequenceAsHashMap SwDOCXReader::GetGrabBag( const uno::Reference<lang::XComponent>& xDocument ) +bool SwDOCXReader::MakeEntries( SwDoc *pD, SwTextBlocks &rBlocks ) { - if( xDocument.is() ) + const OUString aOldURL( rBlocks.GetBaseURL() ); + rBlocks.SetBaseURL( OUString() ); + + bool bRet = false; + + SwNodeIndex aDocEnd( pD->GetNodes().GetEndOfContent() ); + SwNodeIndex aStart( *aDocEnd.GetNode().StartOfSectionNode() ); + + if( aStart < aDocEnd && ( aDocEnd.GetIndex() - aStart.GetIndex() > 2 ) ) { - // get glossar document from the GrabBag - uno::Reference<beans::XPropertySet> xDocProps( xDocument, uno::UNO_QUERY ); - if( xDocProps.is() ) - { - uno::Reference<beans::XPropertySetInfo> xPropsInfo = xDocProps->getPropertySetInfo(); + SwTextFormatColl* pColl = pD->getIDocumentStylePoolAccess().GetTextCollFromPool + (RES_POOLCOLL_STANDARD, false); + sal_uInt16 nGlosEntry = 0; + SwContentNode* pCNd = nullptr; + do { + SwPaM aPam( aStart ); + { + SwNodeIndex& rIdx = aPam.GetPoint()->nNode; + ++rIdx; + if( nullptr == ( pCNd = rIdx.GetNode().GetTextNode() ) ) + { + pCNd = pD->GetNodes().MakeTextNode( rIdx, pColl ); + rIdx = *pCNd; + } + } - const OUString aGrabBagPropName = "InteropGrabBag"; - if( xPropsInfo.is() && xPropsInfo->hasPropertyByName( aGrabBagPropName ) ) + aPam.GetPoint()->nContent.Assign( pCNd, 0 ); + aPam.SetMark(); { - // get existing grab bag - comphelper::SequenceAsHashMap aGrabBag( xDocProps->getPropertyValue( aGrabBagPropName ) ); - return aGrabBag; + SwNodeIndex& rIdx = aPam.GetPoint()->nNode; + rIdx = aStart.GetNode().EndOfSectionIndex() - 1; + if( ( nullptr == ( pCNd = rIdx.GetNode().GetContentNode() ) ) ) + { + ++rIdx; + pCNd = pD->GetNodes().MakeTextNode( rIdx, pColl ); + rIdx = *pCNd; + } } - } + aPam.GetPoint()->nContent.Assign( pCNd, pCNd->Len() ); + + rBlocks.ClearDoc(); + + // TODO: correct entry name + const OUString rLNm = "ImportedAutoText"; + + OUString sShortcut = rLNm; + + // Need to check make sure the shortcut is not already being used + sal_Int32 nStart = 0; + sal_uInt16 nCurPos = rBlocks.GetIndex( sShortcut ); + sal_Int32 nLen = sShortcut.getLength(); + + while( (sal_uInt16)-1 != nCurPos ) + { + sShortcut = sShortcut.copy( 0, nLen ); + // add an Number to it + sShortcut += OUString::number( ++nStart ); + nCurPos = rBlocks.GetIndex( sShortcut ); + } + + if( rBlocks.BeginPutDoc( sShortcut, sShortcut ) ) + { + SwDoc* pGlDoc = rBlocks.GetDoc(); + SwNodeIndex aIdx( pGlDoc->GetNodes().GetEndOfContent(), -1 ); + pCNd = aIdx.GetNode().GetContentNode(); + SwPosition aPos( aIdx, SwIndex( pCNd, ( pCNd ) ? pCNd->Len() : 0 ) ); + pD->getIDocumentContentOperations().CopyRange( aPam, aPos, /*bCopyAll=*/false, /*bCheckPos=*/true ); + rBlocks.PutDoc(); + } + + if( aStart.GetNodes().Count() <= aStart.GetNode().GetIndex() ) + aStart = aStart.GetNode().EndOfSectionIndex() + 1; + else + break; + + ++nGlosEntry; + + } while( aStart < aDocEnd ); + + bRet = true; } - return comphelper::SequenceAsHashMap(); + rBlocks.SetBaseURL( aOldURL ); + + return bRet; } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/filter/docx/swdocxreader.hxx b/sw/source/filter/docx/swdocxreader.hxx index 2646a963523f..6c6dab0b2d1b 100644 --- a/sw/source/filter/docx/swdocxreader.hxx +++ b/sw/source/filter/docx/swdocxreader.hxx @@ -37,8 +37,7 @@ public: private: virtual sal_uLong Read( SwDoc&, const OUString&, SwPaM&, const OUString& ) override; - uno::Reference<css::xml::dom::XDocument> OpenDocument() const; - static comphelper::SequenceAsHashMap GetGrabBag( const uno::Reference<lang::XComponent>& xDocument ); + static bool MakeEntries( SwDoc *pD, SwTextBlocks &rBlocks ); }; #endif diff --git a/writerfilter/source/ooxml/OOXMLDocumentImpl.cxx b/writerfilter/source/ooxml/OOXMLDocumentImpl.cxx index 45b23b5fbfbd..d313078f22a6 100644 --- a/writerfilter/source/ooxml/OOXMLDocumentImpl.cxx +++ b/writerfilter/source/ooxml/OOXMLDocumentImpl.cxx @@ -436,6 +436,12 @@ void OOXMLDocumentImpl::resolveFooter(Stream & rStream, void OOXMLDocumentImpl::resolve(Stream & rStream) { + if (utl::MediaDescriptor(maMediaDescriptor).getUnpackedValueOrDefault("ReadGlossaries", false)) + { + resolveFastSubStream(rStream, OOXMLStream::GLOSSARY); + return; + } + uno::Reference< xml::sax::XFastParser > xParser (mpStream->getFastParser()); diff --git a/writerfilter/source/ooxml/model.xml b/writerfilter/source/ooxml/model.xml index 19339d3ee040..cfd6d527d4bc 100644 --- a/writerfilter/source/ooxml/model.xml +++ b/writerfilter/source/ooxml/model.xml @@ -19057,6 +19057,8 @@ </resource> <resource name="CT_Document" resource="Stream"/> <resource name="CT_GlossaryDocument" resource="Stream"/> + <resource name="CT_DocParts" resource="Stream"/> + <resource name="CT_DocPart" resource="Stream"/> <resource name="document" resource="Stream"/> <resource name="glossaryDocument" resource="Stream"/> <resource name="CT_TxbxContent" resource="Stream"> commit 269fbb8c0896075d02194d113c0f5df0f3e0b5c2 Author: Szymon KÅos <szymon.k...@collabora.com> Date: Fri Apr 14 20:39:40 2017 +0200 AutoText: loading dotx documents For testing purposes patch introduces simple import. New AutoText entries are imported if document contains single paragraph AutoTexts. Change-Id: I3f0e17c63e109eac6514ae0cb8cc168e8282b55b Reviewed-on: https://gerrit.libreoffice.org/36634 Tested-by: Jenkins <c...@libreoffice.org> Reviewed-by: Szymon KÅos <szymon.k...@collabora.com> diff --git a/sw/source/filter/docx/swdocxreader.cxx b/sw/source/filter/docx/swdocxreader.cxx index 5975f1b862bd..b8ea965d3504 100644 --- a/sw/source/filter/docx/swdocxreader.cxx +++ b/sw/source/filter/docx/swdocxreader.cxx @@ -19,7 +19,22 @@ #include "swdocxreader.hxx" +#include <com/sun/star/document/XFilter.hpp> +#include <com/sun/star/document/XImporter.hpp> +#include <com/sun/star/xml/dom/XDocument.hpp> +#include <com/sun/star/xml/dom/XElement.hpp> +#include <com/sun/star/xml/dom/XNode.hpp> +#include <com/sun/star/xml/dom/XNodeList.hpp> +#include <comphelper/processfactory.hxx> +#include <comphelper/propertyvalue.hxx> +#include <comphelper/sequenceashashmap.hxx> +#include <docsh.hxx> #include <swerror.h> +#include <tools/ref.hxx> +#include <unotxdoc.hxx> +#include <unotools/streamwrap.hxx> + +using namespace css; extern "C" SAL_DLLPUBLIC_EXPORT Reader* SAL_CALL ImportDOCX() { @@ -42,10 +57,95 @@ bool SwDOCXReader::HasGlossaries() const return true; } -bool SwDOCXReader::ReadGlossaries( SwTextBlocks& /* rBlocks */, bool /* bSaveRelFiles */ ) const +bool SwDOCXReader::ReadGlossaries( SwTextBlocks& rBlocks, bool /* bSaveRelFiles */ ) const { - // TODO - return false; + bool bRet = false; + + uno::Reference<xml::dom::XDocument> xDoc = OpenDocument(); + + if( xDoc.is() ) + { + uno::Reference<xml::dom::XNodeList> xList = xDoc->getElementsByTagName( "docPartBody" ); + for( int i = 0; i < xList->getLength(); i++ ) + { + uno::Reference<xml::dom::XNode> xBody = xList->item( i ); + uno::Reference<xml::dom::XNode> xP = xBody->getFirstChild(); + uno::Reference<xml::dom::XNode> xR = xP->getFirstChild(); + uno::Reference<xml::dom::XNode> xT = xR->getFirstChild(); + uno::Reference<xml::dom::XNode> xText = xT->getFirstChild(); + OUString aText = xText->getNodeValue(); + if( !aText.isEmpty() ) + { + rBlocks.PutText( aText, aText, aText ); + bRet = true; + } + } + } + + return bRet; +} + +uno::Reference<xml::dom::XDocument> SwDOCXReader::OpenDocument() const +{ + uno::Reference<lang::XMultiServiceFactory> xMultiServiceFactory( + comphelper::getProcessServiceFactory() ); + + uno::Reference<uno::XInterface> xInterface( + xMultiServiceFactory->createInstance( "com.sun.star.comp.Writer.WriterFilter" ), + uno::UNO_QUERY_THROW ); + + uno::Reference<document::XFilter> xFilter( xInterface, uno::UNO_QUERY_THROW ); + uno::Reference<document::XImporter> xImporter( xFilter, uno::UNO_QUERY_THROW ); + + SfxObjectShellLock xDocSh( new SwDocShell( SfxObjectCreateMode::INTERNAL ) ); + xDocSh->DoInitNew(); + + uno::Reference<lang::XComponent> xDstDoc( xDocSh->GetModel(), uno::UNO_QUERY_THROW ); + xImporter->setTargetDocument( xDstDoc ); + + uno::Sequence<beans::PropertyValue> aDescriptor( 1 ); + aDescriptor[0].Name = "InputStream"; + uno::Reference<io::XStream> xStream( new utl::OStreamWrapper( *pMedium->GetInStream() ) ); + aDescriptor[0].Value <<= xStream; + + uno::Reference<xml::dom::XDocument> xDoc; + + try + { + xFilter->filter( aDescriptor ); + + comphelper::SequenceAsHashMap aGrabBag = GetGrabBag( xDstDoc ); + aGrabBag["OOXGlossary"] >>= xDoc; + } + catch (uno::Exception const& e) + { + SAL_WARN("sw.docx", "SwDOCXReader::OpenDocument(): exception: " << e.Message); + } + + return xDoc; +} + +comphelper::SequenceAsHashMap SwDOCXReader::GetGrabBag( const uno::Reference<lang::XComponent>& xDocument ) +{ + if( xDocument.is() ) + { + // get glossar document from the GrabBag + uno::Reference<beans::XPropertySet> xDocProps( xDocument, uno::UNO_QUERY ); + if( xDocProps.is() ) + { + uno::Reference<beans::XPropertySetInfo> xPropsInfo = xDocProps->getPropertySetInfo(); + + const OUString aGrabBagPropName = "InteropGrabBag"; + if( xPropsInfo.is() && xPropsInfo->hasPropertyByName( aGrabBagPropName ) ) + { + // get existing grab bag + comphelper::SequenceAsHashMap aGrabBag( xDocProps->getPropertyValue( aGrabBagPropName ) ); + return aGrabBag; + } + } + } + + return comphelper::SequenceAsHashMap(); } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/filter/docx/swdocxreader.hxx b/sw/source/filter/docx/swdocxreader.hxx index 35fdee86a643..2646a963523f 100644 --- a/sw/source/filter/docx/swdocxreader.hxx +++ b/sw/source/filter/docx/swdocxreader.hxx @@ -21,6 +21,9 @@ #define INCLUDED_SW_SOURCE_FILTER_DOCX_SWDOCXREADER_HXX #include <shellio.hxx> +#include <comphelper/sequenceashashmap.hxx> +#include <com/sun/star/xml/dom/XDocument.hpp> +#include <tools/ref.hxx> /// Wrapper for the UNO DOCX import filter (in writerfilter) for autotext purposes. class SwDOCXReader : public StgReader @@ -33,6 +36,9 @@ public: private: virtual sal_uLong Read( SwDoc&, const OUString&, SwPaM&, const OUString& ) override; + + uno::Reference<css::xml::dom::XDocument> OpenDocument() const; + static comphelper::SequenceAsHashMap GetGrabBag( const uno::Reference<lang::XComponent>& xDocument ); }; #endif
_______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits