LibreOffice Module sw (master) 1
swdocxreader.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 */
19
20#include "swdocxreader.hxx"
21
22#include <com/sun/star/document/XFilter.hpp>
23#include <com/sun/star/document/XImporter.hpp>
24#include <com/sun/star/frame/XModel.hpp>
25#include <com/sun/star/lang/XMultiServiceFactory.hpp>
28#include <doc.hxx>
29#include <docsh.hxx>
31#include <ndtxt.hxx>
32#include <poolfmt.hxx>
33#include <swerror.h>
35#include <unotextrange.hxx>
36#include <sfx2/docfile.hxx>
38
39constexpr OUStringLiteral AUTOTEXT_GALLERY = u"autoTxt";
40
41using namespace css;
42
43extern "C" SAL_DLLPUBLIC_EXPORT Reader* ImportDOCX()
44{
45 return new SwDOCXReader;
46}
47
48ErrCode SwDOCXReader::Read(SwDoc& rDoc, const OUString& /* rBaseURL */, SwPaM& rPam, const OUString& /* FileName */ )
49{
50 if (!m_pMedium->GetInStream())
51 return ERR_SWG_READ_ERROR;
52
53 // We want to work in an empty paragraph.
54 const SwPosition* pPos = rPam.GetPoint();
55 rDoc.getIDocumentContentOperations().SplitNode(*pPos, false);
57
58 uno::Reference<lang::XMultiServiceFactory> xMultiServiceFactory(comphelper::getProcessServiceFactory());
59 uno::Reference<uno::XInterface> xInterface(xMultiServiceFactory->createInstance("com.sun.star.comp.Writer.WriterFilter"), uno::UNO_SET_THROW);
60
61 SwDocShell* pDocShell(rDoc.GetDocShell());
62 uno::Reference<lang::XComponent> xDstDoc(pDocShell->GetModel(), uno::UNO_QUERY_THROW);
63 uno::Reference<document::XImporter> xImporter(xInterface, uno::UNO_QUERY_THROW);
64 xImporter->setTargetDocument(xDstDoc);
65
66 const rtl::Reference<SwXTextRange> xInsertTextRange = SwXTextRange::CreateXTextRange(rDoc, *rPam.GetPoint(), nullptr);
67 uno::Reference<io::XStream> xStream(new utl::OStreamWrapper(*m_pMedium->GetInStream()));
68
69 //SetLoading hack because the document properties will be re-initted
70 //by the xml filter and during the init, while it's considered uninitialized,
71 //setting a property will inform the document it's modified, which attempts
72 //to update the properties, which throws cause the properties are uninitialized
73 pDocShell->SetLoading(SfxLoadedFlags::NONE);
74
75 uno::Sequence<beans::PropertyValue> aDescriptor(comphelper::InitPropertySequence(
76 {
77 { "InputStream", uno::Any(xStream) },
78 { "InsertMode", uno::Any(true) },
79 { "TextInsertModeRange", uno::Any(uno::Reference<text::XTextRange>(xInsertTextRange)) }
80 }));
81
83 uno::Reference<document::XFilter> xFilter(xInterface, uno::UNO_QUERY_THROW);
84 try
85 {
86 xFilter->filter(aDescriptor);
87 }
88 catch (uno::Exception const&)
89 {
90 TOOLS_WARN_EXCEPTION("sw.docx", "SwDOCXReader::Read()");
92 }
93 pDocShell->SetLoading(SfxLoadedFlags::ALL);
94
95 return ret;
96}
97
99{
101}
102
104{
105 // TODO
106 return true;
107}
108
109bool SwDOCXReader::ReadGlossaries( SwTextBlocks& rBlocks, bool /* bSaveRelFiles */ ) const
110{
111 uno::Reference<lang::XMultiServiceFactory> xMultiServiceFactory(
113
114 uno::Reference<uno::XInterface> xInterface(
115 xMultiServiceFactory->createInstance( "com.sun.star.comp.Writer.WriterFilter" ),
116 uno::UNO_SET_THROW );
117
118 uno::Reference<document::XFilter> xFilter( xInterface, uno::UNO_QUERY_THROW );
119 uno::Reference<document::XImporter> xImporter( xFilter, uno::UNO_QUERY_THROW );
120
121 SfxObjectShellLock xDocSh( new SwDocShell( SfxObjectCreateMode::INTERNAL ) );
122 if( xDocSh->DoInitNew() )
123 {
124 uno::Reference<lang::XComponent> xDstDoc( xDocSh->GetModel(), uno::UNO_QUERY_THROW );
125 xImporter->setTargetDocument( xDstDoc );
126
127 uno::Reference<io::XStream> xStream( new utl::OStreamWrapper( *m_pMedium->GetInStream() ) );
128
129 uno::Sequence<beans::PropertyValue> aDescriptor( comphelper::InitPropertySequence({
130 { "InputStream", uno::Any(xStream) },
131 { "ReadGlossaries", uno::Any(true) }
132 }));
133
134 if( xFilter->filter( aDescriptor ) )
135 {
136 if (rBlocks.StartPutMuchBlockEntries())
137 {
138 bool bRet = MakeEntries(static_cast<SwDocShell*>(&xDocSh)->GetDoc(), rBlocks);
139 rBlocks.EndPutMuchBlockEntries();
140 return bRet;
141 }
142 }
143 }
144
145 return false;
146}
147
149{
150 const OUString aOldURL( rBlocks.GetBaseURL() );
151 rBlocks.SetBaseURL( OUString() );
152
153 bool bRet = false;
154
155 SwNodeIndex aDocEnd( pD->GetNodes().GetEndOfContent() );
156 SwNodeIndex aStart( *aDocEnd.GetNode().StartOfSectionNode(), 1 );
157 bool bIsAutoText = false;
158
159 if( aStart < aDocEnd && ( aDocEnd.GetIndex() - aStart.GetIndex() > SwNodeOffset(2) ) )
160 {
162 (RES_POOLCOLL_STANDARD, false);
163 SwContentNode* pCNd = nullptr;
164 bRet = true;
165 do {
166 // Get name - first paragraph
167 OUString aLNm;
168 {
169 SwPaM aPam( aStart );
170 aPam.GetPoint()->Adjust(SwNodeOffset(1));
171 aLNm = aPam.GetPointNode().GetTextNode()->GetText();
172
173 // is AutoText?
174 bIsAutoText = aLNm.startsWith(AUTOTEXT_GALLERY);
175 aLNm = aLNm.copy(AUTOTEXT_GALLERY.getLength() + 1);
176 }
177
178 // Do not copy name
179 ++aStart;
180
181 // Get content
182 SwPaM aPam( aStart );
183 {
184 SwNodeIndex aIdx( aPam.GetPoint()->GetNode(), SwNodeOffset(1) );
185 pCNd = aIdx.GetNode().GetTextNode();
186 if( nullptr == pCNd )
187 {
188 pCNd = pD->GetNodes().MakeTextNode( aIdx.GetNode(), pColl );
189 }
190 }
191
192 aPam.GetPoint()->Assign( *pCNd );
193 aPam.SetMark();
194 {
195 SwNodeIndex aIdx( *aStart.GetNode().EndOfSectionNode(), SwNodeOffset(-1) );
196 // don't add extra empty text node if exist (.dotx but not .dotm)
197 if( aIdx.GetNode().GetTextNode() &&
198 aIdx.GetNode().GetTextNode()->GetText().isEmpty() )
199 aIdx = aStart.GetNode().EndOfSectionIndex() - 2;
200 pCNd = aIdx.GetNode().GetContentNode();
201 if( nullptr == pCNd )
202 {
203 ++aIdx;
204 pCNd = pD->GetNodes().MakeTextNode( aIdx.GetNode(), pColl );
205 }
206 }
207 aPam.GetPoint()->Assign( *pCNd, pCNd->Len() );
208
209 if( bIsAutoText )
210 {
211 // Now we have the right selection for one entry
212 rBlocks.ClearDoc();
213
214 OUString sShortcut = aLNm;
215
216 // Need to check make sure the shortcut is not already being used
217 sal_Int32 nStart = 0;
218 sal_uInt16 nCurPos = rBlocks.GetIndex( sShortcut );
219
220 while( sal_uInt16(-1) != nCurPos )
221 {
222 // add a Number to it
223 sShortcut = aLNm + OUString::number( ++nStart );
224 nCurPos = rBlocks.GetIndex( sShortcut );
225 }
226
227 if( rBlocks.BeginPutDoc( sShortcut, sShortcut ) )
228 {
229 SwDoc* pGlDoc = rBlocks.GetDoc();
230 SwNodeIndex aIdx( pGlDoc->GetNodes().GetEndOfContent(), -1 );
231 pCNd = aIdx.GetNode().GetContentNode();
232 SwPosition aPos( aIdx, pCNd, pCNd ? pCNd->Len() : 0 );
234 rBlocks.PutDoc();
235 }
236 else
237 {
238 bRet = false;
239 }
240 }
241
242 aStart = aStart.GetNode().EndOfSectionIndex() + 1;
243 } while( aStart < aDocEnd && aStart.GetNode().IsStartNode() );
244 }
245
246 rBlocks.SetBaseURL( aOldURL );
247
248 return bRet;
249}
250
251/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
@ CheckPosInFly
check if target position is in fly anchored at source range
Reference< XInputStream > xStream
virtual bool SplitNode(const SwPosition &rPos, bool bChkTableStart)=0
Split a node at rPos (implemented only for TextNode).
virtual bool CopyRange(SwPaM &rPam, SwPosition &rPos, SwCopyFlags flags) const =0
Copy a selected content range to a position.
virtual SwTextFormatColl * GetTextCollFromPool(sal_uInt16 nId, bool bRegardLanguage=true)=0
Return "Auto-Collection with ID.
SfxMedium * m_pMedium
Definition: shellio.hxx:218
SvStream * GetInStream()
css::uno::Reference< css::frame::XModel3 > GetModel() const
void SetLoading(SfxLoadedFlags nFlags)
virtual sal_Int32 Len() const
Definition: node.cxx:1256
Wrapper for the UNO DOCX import filter (in writerfilter) for autotext purposes.
virtual bool HasGlossaries() const override
static bool MakeEntries(SwDoc *pD, SwTextBlocks &rBlocks)
virtual SwReaderType GetReaderType() override
virtual bool ReadGlossaries(SwTextBlocks &rBlocks, bool bSaveRelFiles) const override
virtual ErrCode Read(SwDoc &, const OUString &, SwPaM &, const OUString &) override
Definition: doc.hxx:197
IDocumentContentOperations const & getIDocumentContentOperations() const
Definition: doc.cxx:329
SwNodes & GetNodes()
Definition: doc.hxx:422
IDocumentStylePoolAccess const & getIDocumentStylePoolAccess() const
Definition: doc.cxx:440
bool SetTextFormatColl(const SwPaM &rRg, SwTextFormatColl *pFormat, const bool bReset=true, const bool bResetListAttrs=false, SwRootFrame const *pLayout=nullptr)
Add 4th optional parameter <bResetListAttrs>.
Definition: docfmt.cxx:1100
SwDocShell * GetDocShell()
Definition: doc.hxx:1370
Marks a node in the document model.
Definition: ndindex.hxx:31
SwNode & GetNode() const
Definition: ndindex.hxx:123
SwNodeOffset GetIndex() const
Definition: ndindex.hxx:111
SwTextNode * GetTextNode()
Inline methods from Node.hxx.
Definition: ndtxt.hxx:901
bool IsStartNode() const
Definition: node.hxx:187
const SwStartNode * StartOfSectionNode() const
Definition: node.hxx:153
SwNodeOffset EndOfSectionIndex() const
Definition: node.hxx:691
SwContentNode * GetContentNode()
Definition: node.hxx:666
const SwEndNode * EndOfSectionNode() const
Definition: node.hxx:695
SwTextNode * MakeTextNode(SwNode &rWhere, SwTextFormatColl *pColl, bool bNewFrames=true)
Implementations of "Make...Node" are in the given .cxx-files.
Definition: ndtxt.cxx:121
SwNode & GetEndOfContent() const
Regular ContentSection (i.e. the BodyText).
Definition: ndarr.hxx:165
PaM is Point and Mark: a selection of the document model.
Definition: pam.hxx:188
SwNode & GetPointNode() const
Definition: pam.hxx:275
virtual void SetMark()
Unless this is called, the getter method of Mark will return Point.
Definition: pam.cxx:643
const SwPosition * GetPoint() const
Definition: pam.hxx:253
bool BeginPutDoc(const OUString &, const OUString &)
Definition: swblocks.cxx:385
void EndPutMuchBlockEntries()
Definition: swblocks.cxx:563
SwDoc * GetDoc()
Definition: swblocks.cxx:481
void ClearDoc()
Definition: swblocks.cxx:488
OUString GetBaseURL() const
Definition: swblocks.cxx:569
bool StartPutMuchBlockEntries()
Definition: swblocks.cxx:555
sal_uInt16 PutDoc()
Definition: swblocks.cxx:409
sal_uInt16 GetIndex(const OUString &) const
Definition: swblocks.cxx:261
void SetBaseURL(const OUString &rURL)
Definition: swblocks.cxx:576
Represents the style of a paragraph.
Definition: fmtcol.hxx:61
const OUString & GetText() const
Definition: ndtxt.hxx:244
static rtl::Reference< SwXTextRange > CreateXTextRange(SwDoc &rDoc, const SwPosition &rPos, const SwPosition *const pMark)
Definition: unoobj2.cxx:1221
#define TOOLS_WARN_EXCEPTION(area, stream)
float u
#define ERRCODE_NONE
Reference< XMultiServiceFactory > getProcessServiceFactory()
css::uno::Sequence< css::beans::PropertyValue > InitPropertySequence(::std::initializer_list< ::std::pair< OUString, css::uno::Any > > vInit)
o3tl::strong_int< sal_Int32, struct Tag_SwNodeOffset > SwNodeOffset
Definition: nodeoffset.hxx:16
@ RES_POOLCOLL_STANDARD
Standard.
Definition: poolfmt.hxx:250
SwReaderType
Definition: shellio.hxx:186
Marks a position in the document model.
Definition: pam.hxx:38
void Adjust(SwNodeOffset nDelta)
Adjust node position, and resets content position to zero.
Definition: pam.cxx:257
SwNode & GetNode() const
Definition: pam.hxx:81
void Assign(const SwNode &rNd, SwNodeOffset nDelta, sal_Int32 nContentOffset=0)
These all set both nNode and nContent.
Definition: pam.cxx:231
SAL_DLLPUBLIC_EXPORT Reader * ImportDOCX()
constexpr OUStringLiteral AUTOTEXT_GALLERY
#define ERR_SWG_READ_ERROR
Definition: swerror.h:25