[Libreoffice-commits] core.git: Branch 'distro/collabora/cp-5.3' - 7 commits - sw/inc sw/Library_msword.mk sw/Library_sw.mk sw/qa sw/source writerfilter/inc writerfilter/source

Szymon Kłos szymon.klos at collabora.com
Thu May 4 11:22:35 UTC 2017


 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.klos at 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 <ci at libreoffice.org>
    Reviewed-by: Szymon Kłos <szymon.klos at 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.klos at 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.klos at 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 <ci at libreoffice.org>
    Reviewed-by: Miklos Vajna <vmiklos at 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.klos at 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 <ci at libreoffice.org>
    Reviewed-by: Szymon Kłos <szymon.klos at 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.klos at 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 <ci at libreoffice.org>
    Reviewed-by: Szymon Kłos <szymon.klos at 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.klos at 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 <ci at libreoffice.org>
    Reviewed-by: Szymon Kłos <szymon.klos at collabora.com>
    Tested-by: Szymon Kłos <szymon.klos at 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.klos at 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 <ci at libreoffice.org>
    Reviewed-by: Szymon Kłos <szymon.klos at 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


More information about the Libreoffice-commits mailing list