Line data Source code
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 <hintids.hxx>
21 : #include <tools/date.hxx>
22 : #include <tools/time.hxx>
23 : #include <svl/urihelper.hxx>
24 : #include <svl/fstathelper.hxx>
25 : #include <unotools/moduleoptions.hxx>
26 : #include <sfx2/docfile.hxx>
27 : #include <editeng/lrspitem.hxx>
28 : #include <editeng/ulspitem.hxx>
29 : #include <editeng/boxitem.hxx>
30 : #include <editeng/paperinf.hxx>
31 : #include <node.hxx>
32 : #include <docary.hxx>
33 : #include <fmtanchr.hxx>
34 : #include <fmtfsize.hxx>
35 : #include <fmtpdsc.hxx>
36 : #include <swtypes.hxx>
37 : #include <shellio.hxx>
38 : #include <doc.hxx>
39 : #include <IDocumentUndoRedo.hxx>
40 : #include <IDocumentSettingAccess.hxx>
41 : #include <IDocumentDeviceAccess.hxx>
42 : #include <IDocumentLinksAdministration.hxx>
43 : #include <IDocumentRedlineAccess.hxx>
44 : #include <IDocumentFieldsAccess.hxx>
45 : #include <IDocumentState.hxx>
46 : #include <IDocumentStylePoolAccess.hxx>
47 : #include <pam.hxx>
48 : #include <editsh.hxx>
49 : #include <undobj.hxx>
50 : #include <swundo.hxx>
51 : #include <swtable.hxx>
52 : #include <tblsel.hxx>
53 : #include <pagedesc.hxx>
54 : #include <poolfmt.hxx>
55 : #include <fltini.hxx>
56 : #include <docsh.hxx>
57 : #include <redline.hxx>
58 : #include <swerror.h>
59 : #include <paratr.hxx>
60 : #include <pausethreadstarting.hxx>
61 :
62 : using namespace ::com::sun::star;
63 :
64 440 : sal_uLong SwReader::Read( const Reader& rOptions )
65 : {
66 : // copy variables
67 440 : Reader* po = const_cast<Reader*>(&rOptions);
68 440 : po->pStrm = pStrm;
69 440 : po->pStg = pStg;
70 440 : po->xStg = xStg;
71 440 : po->bInsertMode = 0 != pCrsr;
72 440 : po->bSkipImages = mbSkipImages;
73 :
74 : // if a Medium is selected, get its Stream
75 879 : if( 0 != (po->pMedium = pMedium ) &&
76 439 : !po->SetStrmStgPtr() )
77 : {
78 0 : po->SetReadUTF8( false );
79 0 : po->SetBlockMode( false );
80 0 : po->SetOrganizerMode( false );
81 0 : po->SetIgnoreHTMLComments( false );
82 0 : return ERR_SWG_FILE_FORMAT_ERROR;
83 : }
84 :
85 440 : sal_uLong nError = 0L;
86 :
87 440 : GetDoc();
88 :
89 : // while reading, do not call OLE-Modified
90 440 : Link<> aOLELink( pDoc->GetOle2Link() );
91 440 : pDoc->SetOle2Link( Link<>() );
92 :
93 440 : pDoc->SetInReading( true );
94 440 : pDoc->SetInXMLImport( 0 != dynamic_cast< XMLReader* >(po) );
95 :
96 : SwPaM *pPam;
97 440 : if( pCrsr )
98 1 : pPam = pCrsr;
99 : else
100 : {
101 : // if the Reader was not called by a Shell, create a PaM ourselves
102 439 : SwNodeIndex nNode( pDoc->GetNodes().GetEndOfContent(), -1 );
103 439 : pPam = new SwPaM( nNode );
104 : // For Web documents the default template was set already by InitNew,
105 : // unless the filter is not HTML,
106 : // or a SetTemplateName was called in ConvertFrom.
107 439 : if( !pDoc->getIDocumentSettingAccess().get(DocumentSettingId::HTML_MODE) || ReadHTML != po || !po->pTemplate )
108 438 : po->SetTemplate( *pDoc );
109 : }
110 :
111 : // Pams are connected like rings; stop when we return to the 1st element
112 440 : SwPaM *pEnd = pPam;
113 440 : SwUndoInsDoc* pUndo = 0;
114 :
115 440 : bool bReadPageDescs = false;
116 440 : bool const bDocUndo = pDoc->GetIDocumentUndoRedo().DoesUndo();
117 440 : bool bSaveUndo = bDocUndo && pCrsr;
118 440 : if( bSaveUndo )
119 : {
120 : // the reading of the page template cannot be undone!
121 1 : if( ( bReadPageDescs = po->aOpt.IsPageDescs() ) )
122 : {
123 0 : bSaveUndo = false;
124 0 : pDoc->GetIDocumentUndoRedo().DelAllUndoObj();
125 : }
126 : else
127 : {
128 1 : pDoc->GetIDocumentUndoRedo().ClearRedo();
129 1 : pDoc->GetIDocumentUndoRedo().StartUndo( UNDO_INSDOKUMENT, NULL );
130 : }
131 : }
132 440 : pDoc->GetIDocumentUndoRedo().DoUndo(false);
133 :
134 440 : SwNodeIndex aSplitIdx( pDoc->GetNodes() );
135 :
136 440 : RedlineMode_t eOld = pDoc->getIDocumentRedlineAccess().GetRedlineMode();
137 440 : RedlineMode_t ePostReadRedlineMode( nsRedlineMode_t::REDLINE_IGNORE );
138 :
139 : // Array of FlyFormats
140 880 : SwFrameFormats aFlyFrmArr;
141 : // only read templates? then ignore multi selection!
142 440 : bool bFormatsOnly = po->aOpt.IsFormatsOnly();
143 :
144 : while( true )
145 : {
146 440 : if( bSaveUndo )
147 1 : pUndo = new SwUndoInsDoc( *pPam );
148 :
149 440 : pDoc->getIDocumentRedlineAccess().SetRedlineMode_intern( nsRedlineMode_t::REDLINE_IGNORE );
150 :
151 440 : SwPaM* pUndoPam = 0;
152 440 : if( bDocUndo || pCrsr )
153 : {
154 : // set Pam to the previous node, so that it is not also moved
155 1 : const SwNodeIndex& rTmp = pPam->GetPoint()->nNode;
156 1 : pUndoPam = new SwPaM( rTmp, rTmp, 0, -1 );
157 : }
158 :
159 : // store for now all Fly's
160 440 : if( pCrsr )
161 : {
162 1 : std::copy(pDoc->GetSpzFrameFormats()->begin(),
163 2 : pDoc->GetSpzFrameFormats()->end(), std::back_inserter(aFlyFrmArr));
164 : }
165 :
166 440 : const sal_Int32 nSttContent = pPam->GetPoint()->nContent.GetIndex();
167 :
168 : // make sure the End position is correct for all Readers
169 440 : SwContentNode* pCNd = pPam->GetContentNode();
170 440 : sal_Int32 nEndContent = pCNd ? pCNd->Len() - nSttContent : 0;
171 440 : SwNodeIndex aEndPos( pPam->GetPoint()->nNode, 1 );
172 :
173 440 : pDoc->getIDocumentRedlineAccess().SetRedlineMode_intern( eOld );
174 :
175 440 : nError = po->Read( *pDoc, GetBaseURL(), *pPam, aFileName );
176 :
177 : // an ODF document may contain redline mode in settings.xml; save it!
178 440 : ePostReadRedlineMode = pDoc->getIDocumentRedlineAccess().GetRedlineMode();
179 :
180 440 : pDoc->getIDocumentRedlineAccess().SetRedlineMode_intern( nsRedlineMode_t::REDLINE_IGNORE );
181 :
182 440 : if( !IsError( nError )) // set the End position already
183 : {
184 435 : --aEndPos;
185 435 : pCNd = aEndPos.GetNode().GetContentNode();
186 435 : if( !pCNd && 0 == ( pCNd = SwNodes::GoPrevious( &aEndPos ) ))
187 0 : pCNd = pDoc->GetNodes().GoNext( &aEndPos );
188 :
189 435 : pPam->GetPoint()->nNode = aEndPos;
190 435 : const sal_Int32 nLen = pCNd->Len();
191 435 : if( nLen < nEndContent )
192 0 : nEndContent = 0;
193 : else
194 435 : nEndContent = nLen - nEndContent;
195 435 : pPam->GetPoint()->nContent.Assign( pCNd, nEndContent );
196 :
197 435 : const SwStartNode* pTableBoxStart = pCNd->FindTableBoxStartNode();
198 435 : if ( pTableBoxStart )
199 : {
200 0 : SwTableBox* pBox = pTableBoxStart->GetTableBox();
201 0 : if ( pBox )
202 : {
203 0 : pDoc->ChkBoxNumFormat( *pBox, true );
204 : }
205 : }
206 : }
207 :
208 440 : if( pCrsr )
209 : {
210 1 : *pUndoPam->GetMark() = *pPam->GetPoint();
211 1 : ++pUndoPam->GetPoint()->nNode;
212 1 : SwNode& rNd = pUndoPam->GetNode();
213 1 : if( rNd.IsContentNode() )
214 1 : pUndoPam->GetPoint()->nContent.Assign(
215 2 : static_cast<SwContentNode*>(&rNd), nSttContent );
216 : else
217 0 : pUndoPam->GetPoint()->nContent.Assign( 0, 0 );
218 :
219 2 : bool bChkHeaderFooter = rNd.FindHeaderStartNode() ||
220 2 : rNd.FindFooterStartNode();
221 :
222 : // search all new Fly's, and store them as individual Undo Objects
223 1 : for( SwFrameFormats::size_type n = 0; n < pDoc->GetSpzFrameFormats()->size(); ++n )
224 : {
225 0 : SwFrameFormat* pFrameFormat = (*pDoc->GetSpzFrameFormats())[ n ];
226 0 : const SwFormatAnchor& rAnchor = pFrameFormat->GetAnchor();
227 0 : if( !aFlyFrmArr.Contains( pFrameFormat) )
228 : {
229 : SwPosition const*const pFrameAnchor(
230 0 : rAnchor.GetContentAnchor());
231 0 : if ( (FLY_AT_PAGE == rAnchor.GetAnchorId())
232 0 : || ( pFrameAnchor
233 0 : && ( ( (FLY_AT_PARA == rAnchor.GetAnchorId())
234 0 : && ( (pUndoPam->GetPoint()->nNode ==
235 : pFrameAnchor->nNode)
236 0 : || (pUndoPam->GetMark()->nNode ==
237 : pFrameAnchor->nNode)
238 : )
239 : )
240 : // #i97570# also check frames anchored AT char
241 0 : || ( (FLY_AT_CHAR == rAnchor.GetAnchorId())
242 0 : && !IsDestroyFrameAnchoredAtChar(
243 : *pFrameAnchor,
244 0 : *pUndoPam->GetPoint(),
245 0 : *pUndoPam->GetMark(),
246 0 : pDoc)
247 : )
248 : )
249 : )
250 : )
251 : {
252 0 : if( bChkHeaderFooter &&
253 0 : (FLY_AT_PARA == rAnchor.GetAnchorId()) &&
254 0 : RES_DRAWFRMFMT == pFrameFormat->Which() )
255 : {
256 : // DrawObjects are not allowed in Headers/Footers!
257 0 : pFrameFormat->DelFrms();
258 0 : pDoc->DelFrameFormat( pFrameFormat );
259 0 : --n;
260 : }
261 : else
262 : {
263 0 : if( bSaveUndo )
264 : {
265 0 : pDoc->getIDocumentRedlineAccess().SetRedlineMode_intern( eOld );
266 : // UGLY: temp. enable undo
267 0 : pDoc->GetIDocumentUndoRedo().DoUndo(true);
268 0 : pDoc->GetIDocumentUndoRedo().AppendUndo(
269 0 : new SwUndoInsLayFormat( pFrameFormat,0,0 ) );
270 0 : pDoc->GetIDocumentUndoRedo().DoUndo(false);
271 0 : pDoc->getIDocumentRedlineAccess().SetRedlineMode_intern( nsRedlineMode_t::REDLINE_IGNORE );
272 : }
273 0 : if( pFrameFormat->HasWriterListeners() )
274 : {
275 : // Draw-Objects create a Frame when being inserted; thus delete them
276 0 : pFrameFormat->DelFrms();
277 : }
278 :
279 0 : if (FLY_AT_PAGE == rAnchor.GetAnchorId())
280 : {
281 0 : if( !rAnchor.GetContentAnchor() )
282 : {
283 0 : pFrameFormat->MakeFrms();
284 : }
285 0 : else if( pCrsr )
286 : {
287 0 : pDoc->SetContainsAtPageObjWithContentAnchor( true );
288 : }
289 : }
290 : else
291 0 : pFrameFormat->MakeFrms();
292 : }
293 : }
294 : }
295 : }
296 1 : if( !aFlyFrmArr.empty() )
297 0 : aFlyFrmArr.clear();
298 :
299 1 : pDoc->getIDocumentRedlineAccess().SetRedlineMode_intern( eOld );
300 1 : if( pDoc->getIDocumentRedlineAccess().IsRedlineOn() )
301 0 : pDoc->getIDocumentRedlineAccess().AppendRedline( new SwRangeRedline( nsRedlineType_t::REDLINE_INSERT, *pUndoPam ), true);
302 : else
303 1 : pDoc->getIDocumentRedlineAccess().SplitRedline( *pUndoPam );
304 1 : pDoc->getIDocumentRedlineAccess().SetRedlineMode_intern( nsRedlineMode_t::REDLINE_IGNORE );
305 : }
306 440 : if( bSaveUndo )
307 : {
308 1 : pDoc->getIDocumentRedlineAccess().SetRedlineMode_intern( eOld );
309 1 : pUndo->SetInsertRange( *pUndoPam, false );
310 : // UGLY: temp. enable undo
311 1 : pDoc->GetIDocumentUndoRedo().DoUndo(true);
312 1 : pDoc->GetIDocumentUndoRedo().AppendUndo( pUndo );
313 1 : pDoc->GetIDocumentUndoRedo().DoUndo(false);
314 1 : pDoc->getIDocumentRedlineAccess().SetRedlineMode_intern( nsRedlineMode_t::REDLINE_IGNORE );
315 : }
316 :
317 440 : delete pUndoPam;
318 :
319 440 : pPam = pPam->GetNext();
320 440 : if( pPam == pEnd )
321 440 : break;
322 :
323 : // only read templates? then ignore multi selection! Bug 68593
324 0 : if( bFormatsOnly )
325 0 : break;
326 :
327 : /*
328 : * !!! The Status of the Stream has to be reset directly. !!!
329 : * When Seeking, the current Status-, EOF- und bad-Bit is set;
330 : * nobody knows why
331 : */
332 0 : if( pStrm )
333 : {
334 0 : pStrm->Seek(0);
335 0 : pStrm->ResetError();
336 : }
337 0 : }
338 :
339 440 : pDoc->SetInReading( false );
340 440 : pDoc->SetInXMLImport( false );
341 :
342 440 : pDoc->InvalidateNumRules();
343 440 : pDoc->UpdateNumRule();
344 440 : pDoc->ChkCondColls();
345 440 : pDoc->SetAllUniqueFlyNames();
346 440 : pDoc->getIDocumentState().SetLoaded( true );
347 :
348 440 : pDoc->GetIDocumentUndoRedo().DoUndo(bDocUndo);
349 440 : if (!bReadPageDescs)
350 : {
351 440 : if( bSaveUndo )
352 : {
353 1 : pDoc->getIDocumentRedlineAccess().SetRedlineMode_intern( eOld );
354 1 : pDoc->GetIDocumentUndoRedo().EndUndo( UNDO_INSDOKUMENT, NULL );
355 1 : pDoc->getIDocumentRedlineAccess().SetRedlineMode_intern( nsRedlineMode_t::REDLINE_IGNORE );
356 : }
357 : }
358 :
359 : // delete Pam if it was created only for reading
360 440 : if( !pCrsr )
361 : {
362 439 : delete pPam; // open a new one
363 :
364 : // #i42634# Moved common code of SwReader::Read() and
365 : // SwDocShell::UpdateLinks() to new SwDoc::UpdateLinks():
366 : // ATM still with Update
367 439 : pDoc->getIDocumentLinksAdministration().UpdateLinks( true );
368 :
369 : // not insert: set the redline mode read from settings.xml
370 : eOld = static_cast<RedlineMode_t>(
371 439 : ePostReadRedlineMode & ~nsRedlineMode_t::REDLINE_IGNORE);
372 :
373 439 : pDoc->getIDocumentFieldsAccess().SetFieldsDirty(false, NULL, 0);
374 : }
375 :
376 440 : pDoc->getIDocumentRedlineAccess().SetRedlineMode_intern( eOld );
377 440 : pDoc->SetOle2Link( aOLELink );
378 :
379 440 : if( pCrsr ) // das Doc ist jetzt modifiziert
380 1 : pDoc->getIDocumentState().SetModified();
381 : // #i38810# - If links have been updated, the document
382 : // have to be modified. During update of links the OLE link at the document
383 : // isn't set. Thus, the document's modified state has to be set again after
384 : // the OLE link is restored - see above <pDoc->SetOle2Link( aOLELink )>.
385 440 : if ( pDoc->getIDocumentLinksAdministration().LinksUpdated() )
386 : {
387 0 : pDoc->getIDocumentState().SetModified();
388 : }
389 :
390 440 : po->SetReadUTF8( false );
391 440 : po->SetBlockMode( false );
392 440 : po->SetOrganizerMode( false );
393 440 : po->SetIgnoreHTMLComments( false );
394 :
395 880 : return nError;
396 : }
397 :
398 :
399 439 : SwReader::SwReader(SfxMedium& rMedium, const OUString& rFileName, SwDoc *pDocument)
400 : : SwDocFac(pDocument), pStrm(0), pMedium(&rMedium), pCrsr(0),
401 439 : aFileName(rFileName), mbSkipImages(false)
402 : {
403 439 : SetBaseURL( rMedium.GetBaseURL() );
404 439 : SetSkipImages( rMedium.IsSkipImages() );
405 439 : }
406 :
407 :
408 : // Read into an existing document
409 1 : SwReader::SwReader(SvStream& rStrm, const OUString& rFileName, const OUString& rBaseURL, SwPaM& rPam)
410 : : SwDocFac(rPam.GetDoc()), pStrm(&rStrm), pMedium(0), pCrsr(&rPam),
411 1 : aFileName(rFileName), mbSkipImages(false)
412 : {
413 1 : SetBaseURL( rBaseURL );
414 1 : }
415 :
416 0 : SwReader::SwReader(SfxMedium& rMedium, const OUString& rFileName, SwPaM& rPam)
417 : : SwDocFac(rPam.GetDoc()), pStrm(0), pMedium(&rMedium),
418 0 : pCrsr(&rPam), aFileName(rFileName), mbSkipImages(false)
419 : {
420 0 : SetBaseURL( rMedium.GetBaseURL() );
421 0 : }
422 :
423 0 : SwReader::SwReader( const uno::Reference < embed::XStorage > &rStg, const OUString& rFilename, SwPaM &rPam )
424 0 : : SwDocFac(rPam.GetDoc()), pStrm(0), xStg( rStg ), pMedium(0), pCrsr(&rPam), aFileName(rFilename), mbSkipImages(false)
425 : {
426 0 : }
427 :
428 187 : Reader::Reader()
429 : : pTemplate(0),
430 : aDStamp( Date::EMPTY ),
431 : aTStamp( tools::Time::EMPTY ),
432 : aChkDateTime( DateTime::EMPTY ),
433 : pStrm(0), pMedium(0), bInsertMode(false),
434 : bTmplBrowseMode(false), bReadUTF8(false), bBlockMode(false), bOrganizerMode(false),
435 187 : bHasAskTemplateName(false), bIgnoreHTMLComments(false), bSkipImages(false)
436 : {
437 187 : }
438 :
439 374 : Reader::~Reader()
440 : {
441 187 : delete pTemplate;
442 187 : }
443 :
444 44 : OUString Reader::GetTemplateName() const
445 : {
446 44 : return OUString();
447 : }
448 :
449 : // load the Filter template, set and release
450 457 : SwDoc* Reader::GetTemplateDoc()
451 : {
452 457 : if( !bHasAskTemplateName )
453 : {
454 48 : SetTemplateName( GetTemplateName() );
455 48 : bHasAskTemplateName = true;
456 : }
457 :
458 457 : if( aTemplateNm.isEmpty() )
459 423 : ClearTemplate();
460 : else
461 : {
462 34 : INetURLObject aTDir( aTemplateNm );
463 68 : const OUString aFileName = aTDir.GetMainURL( INetURLObject::NO_DECODE );
464 : OSL_ENSURE( !aTDir.HasError(), "No absolute path for template name!" );
465 34 : DateTime aCurrDateTime( DateTime::SYSTEM );
466 34 : bool bLoad = false;
467 :
468 : // if the template is already loaded, check once-a-minute if it has changed
469 34 : if( !pTemplate || aCurrDateTime >= aChkDateTime )
470 : {
471 4 : Date aTstDate( Date::EMPTY );
472 4 : tools::Time aTstTime( tools::Time::EMPTY );
473 8 : if( FStatHelper::GetModifiedDateTimeOfFile(
474 : aTDir.GetMainURL( INetURLObject::NO_DECODE ),
475 20 : &aTstDate, &aTstTime ) &&
476 4 : ( !pTemplate || aDStamp != aTstDate || aTStamp != aTstTime ))
477 : {
478 4 : bLoad = true;
479 4 : aDStamp = aTstDate;
480 4 : aTStamp = aTstTime;
481 : }
482 :
483 : // only one minute later check if it has changed
484 4 : aChkDateTime = aCurrDateTime;
485 4 : aChkDateTime += tools::Time( 0L, 1L );
486 : }
487 :
488 34 : if( bLoad )
489 : {
490 4 : ClearTemplate();
491 : OSL_ENSURE( !pTemplate, "Who holds the template doc?" );
492 :
493 : // If the writer module is not installed,
494 : // we cannot create a SwDocShell. We could create a
495 : // SwWebDocShell however, because this exists always
496 : // for the help.
497 4 : SvtModuleOptions aModuleOptions;
498 4 : if( aModuleOptions.IsWriter() )
499 : {
500 : SwDocShell *pDocSh =
501 4 : new SwDocShell ( SfxObjectCreateMode::INTERNAL );
502 4 : SfxObjectShellLock xDocSh = pDocSh;
503 4 : if( pDocSh->DoInitNew( 0 ) )
504 : {
505 4 : pTemplate = pDocSh->GetDoc();
506 4 : pTemplate->SetOle2Link( Link<>() );
507 : // always FALSE
508 4 : pTemplate->GetIDocumentUndoRedo().DoUndo( false );
509 4 : pTemplate->getIDocumentSettingAccess().set(DocumentSettingId::BROWSE_MODE, bTmplBrowseMode );
510 4 : pTemplate->RemoveAllFormatLanguageDependencies();
511 :
512 4 : ReadXML->SetOrganizerMode( true );
513 4 : SfxMedium aMedium( aFileName, StreamMode::NONE );
514 8 : SwReader aRdr( aMedium, OUString(), pTemplate );
515 4 : aRdr.Read( *ReadXML );
516 4 : ReadXML->SetOrganizerMode( false );
517 :
518 8 : pTemplate->acquire();
519 4 : }
520 4 : }
521 : }
522 :
523 : OSL_ENSURE( !pTemplate || FStatHelper::IsDocument( aFileName ) || aTemplateNm=="$$Dummy$$",
524 34 : "TemplatePtr but no template exist!" );
525 : }
526 :
527 457 : return pTemplate;
528 : }
529 :
530 440 : bool Reader::SetTemplate( SwDoc& rDoc )
531 : {
532 440 : bool bRet = false;
533 :
534 440 : GetTemplateDoc();
535 440 : if( pTemplate )
536 : {
537 17 : rDoc.RemoveAllFormatLanguageDependencies();
538 17 : rDoc.ReplaceStyles( *pTemplate );
539 17 : rDoc.getIDocumentFieldsAccess().SetFixFields(false, NULL);
540 17 : bRet = true;
541 : }
542 :
543 440 : return bRet;
544 : }
545 :
546 431 : void Reader::ClearTemplate()
547 : {
548 431 : if( pTemplate )
549 : {
550 0 : if( 0 == pTemplate->release() )
551 0 : delete pTemplate;
552 0 : pTemplate = 0;
553 : }
554 431 : }
555 :
556 48 : void Reader::SetTemplateName( const OUString& rDir )
557 : {
558 48 : if( !rDir.isEmpty() && aTemplateNm != rDir )
559 : {
560 4 : ClearTemplate();
561 4 : aTemplateNm = rDir;
562 : }
563 48 : }
564 :
565 0 : void Reader::MakeHTMLDummyTemplateDoc()
566 : {
567 0 : ClearTemplate();
568 0 : pTemplate = new SwDoc;
569 0 : pTemplate->acquire();
570 0 : pTemplate->getIDocumentSettingAccess().set(DocumentSettingId::BROWSE_MODE, bTmplBrowseMode );
571 0 : pTemplate->getIDocumentDeviceAccess().getPrinter( true );
572 0 : pTemplate->RemoveAllFormatLanguageDependencies();
573 0 : aChkDateTime = Date( 1, 1, 2300 ); // year 2300 should be sufficient
574 0 : aTemplateNm = "$$Dummy$$";
575 0 : }
576 :
577 : // Users that do not need to open these Streams / Storages,
578 : // have to override this method
579 423 : bool Reader::SetStrmStgPtr()
580 : {
581 : OSL_ENSURE( pMedium, "Where is the Media??" );
582 :
583 423 : if( pMedium->IsStorage() )
584 : {
585 291 : if( SW_STORAGE_READER & GetReaderType() )
586 : {
587 291 : xStg = pMedium->GetStorage();
588 291 : return true;
589 : }
590 : }
591 : else
592 : {
593 132 : pStrm = pMedium->GetInStream();
594 132 : if ( pStrm && SotStorage::IsStorageFile(pStrm) && (SW_STORAGE_READER & GetReaderType()) )
595 : {
596 125 : pStg = new SotStorage( *pStrm );
597 125 : pStrm = NULL;
598 : }
599 7 : else if ( !(SW_STREAM_READER & GetReaderType()) )
600 : {
601 0 : pStrm = NULL;
602 0 : return false;
603 : }
604 :
605 132 : return true;
606 : }
607 0 : return false;
608 : }
609 :
610 24 : int Reader::GetReaderType()
611 : {
612 24 : return SW_STREAM_READER;
613 : }
614 :
615 20 : void Reader::SetFltName( const OUString& )
616 : {
617 20 : }
618 :
619 0 : void Reader::ResetFrameFormatAttrs( SfxItemSet &rFrmSet )
620 : {
621 0 : rFrmSet.Put( SvxLRSpaceItem(RES_LR_SPACE) );
622 0 : rFrmSet.Put( SvxULSpaceItem(RES_UL_SPACE) );
623 0 : rFrmSet.Put( SvxBoxItem(RES_BOX) );
624 0 : }
625 :
626 143 : void Reader::ResetFrameFormats( SwDoc& rDoc )
627 : {
628 : sal_uInt16 const s_ids[3] = {
629 : RES_POOLFRM_FRAME, RES_POOLFRM_GRAPHIC, RES_POOLFRM_OLE
630 143 : };
631 572 : for (size_t i = 0; i < SAL_N_ELEMENTS(s_ids); ++i)
632 : {
633 429 : SwFrameFormat *const pFrameFormat = rDoc.getIDocumentStylePoolAccess().GetFrameFormatFromPool( s_ids[i] );
634 :
635 429 : pFrameFormat->ResetFormatAttr( RES_LR_SPACE );
636 429 : pFrameFormat->ResetFormatAttr( RES_UL_SPACE );
637 429 : pFrameFormat->ResetFormatAttr( RES_BOX );
638 : }
639 143 : }
640 :
641 : // read the sections of the document, which is equal to the medium.
642 : // returns the count of it
643 0 : size_t Reader::GetSectionList( SfxMedium&, std::vector<OUString*>& ) const
644 : {
645 0 : return 0;
646 : }
647 :
648 0 : bool SwReader::HasGlossaries( const Reader& rOptions )
649 : {
650 : // copy variables
651 0 : Reader* po = const_cast<Reader*>(&rOptions);
652 0 : po->pStrm = pStrm;
653 0 : po->pStg = pStg;
654 0 : po->bInsertMode = false;
655 :
656 : // if a Medium is selected, get its Stream
657 0 : bool bRet = false;
658 0 : if( !( 0 != (po->pMedium = pMedium ) && !po->SetStrmStgPtr() ))
659 0 : bRet = po->HasGlossaries();
660 0 : return bRet;
661 : }
662 :
663 0 : bool SwReader::ReadGlossaries( const Reader& rOptions,
664 : SwTextBlocks& rBlocks, bool bSaveRelFiles )
665 : {
666 : // copy variables
667 0 : Reader* po = const_cast<Reader*>(&rOptions);
668 0 : po->pStrm = pStrm;
669 0 : po->pStg = pStg;
670 0 : po->bInsertMode = false;
671 :
672 : // if a Medium is selected, get its Stream
673 0 : bool bRet = false;
674 0 : if( !( 0 != (po->pMedium = pMedium ) && !po->SetStrmStgPtr() ))
675 0 : bRet = po->ReadGlossaries( rBlocks, bSaveRelFiles );
676 0 : return bRet;
677 : }
678 :
679 0 : bool Reader::HasGlossaries() const
680 : {
681 0 : return false;
682 : }
683 :
684 0 : bool Reader::ReadGlossaries( SwTextBlocks&, bool ) const
685 : {
686 0 : return false;
687 : }
688 :
689 0 : int StgReader::GetReaderType()
690 : {
691 0 : return SW_STORAGE_READER;
692 : }
693 :
694 : /*
695 : * Writer
696 : */
697 :
698 : /*
699 : * Constructors, Destructors are inline (inc/shellio.hxx).
700 : */
701 :
702 1 : SwWriter::SwWriter(SvStream& rStrm, SwCrsrShell &rShell, bool bInWriteAll)
703 : : pStrm(&rStrm), pMedium(0), pOutPam(0), pShell(&rShell),
704 1 : rDoc(*rShell.GetDoc()), bWriteAll(bInWriteAll)
705 : {
706 1 : }
707 :
708 1 : SwWriter::SwWriter(SvStream& rStrm,SwDoc &rDocument)
709 : : pStrm(&rStrm), pMedium(0), pOutPam(0), pShell(0), rDoc(rDocument),
710 1 : bWriteAll(true)
711 : {
712 1 : }
713 :
714 8074 : SwWriter::SwWriter(SvStream& rStrm, SwPaM& rPam, bool bInWriteAll)
715 : : pStrm(&rStrm), pMedium(0), pOutPam(&rPam), pShell(0),
716 8074 : rDoc(*rPam.GetDoc()), bWriteAll(bInWriteAll)
717 : {
718 8074 : }
719 :
720 1 : SwWriter::SwWriter( const uno::Reference < embed::XStorage >& rStg, SwDoc &rDocument)
721 1 : : pStrm(0), xStg( rStg ), pMedium(0), pOutPam(0), pShell(0), rDoc(rDocument), bWriteAll(true)
722 : {
723 1 : }
724 :
725 0 : SwWriter::SwWriter(SfxMedium& rMedium, SwCrsrShell &rShell, bool bInWriteAll)
726 : : pStrm(0), pMedium(&rMedium), pOutPam(0), pShell(&rShell),
727 0 : rDoc(*rShell.GetDoc()), bWriteAll(bInWriteAll)
728 : {
729 0 : }
730 :
731 118 : SwWriter::SwWriter(SfxMedium& rMedium, SwDoc &rDocument)
732 : : pStrm(0), pMedium(&rMedium), pOutPam(0), pShell(0), rDoc(rDocument),
733 118 : bWriteAll(true)
734 : {
735 118 : }
736 :
737 8195 : sal_uLong SwWriter::Write( WriterRef& rxWriter, const OUString* pRealFileName )
738 : {
739 : // #i73788#
740 8195 : SwPauseThreadStarting aPauseThreadStarting;
741 :
742 8195 : bool bHasMark = false;
743 : SwPaM * pPam;
744 :
745 8195 : SwDoc *pDoc = 0;
746 :
747 8195 : if ( pShell && !bWriteAll && pShell->IsTableMode() )
748 : {
749 0 : bWriteAll = true;
750 0 : pDoc = new SwDoc;
751 0 : pDoc->acquire();
752 :
753 : // Copy parts of a table:
754 : // Create a table with the width of the original and copy the selected cells.
755 : // The sizes are corrected by ratio.
756 :
757 : // search the layout for cells
758 0 : SwSelBoxes aBoxes;
759 0 : GetTableSel( *pShell, aBoxes );
760 0 : const SwTableNode* pTableNd = static_cast<const SwTableNode*>(aBoxes[0]->GetSttNd()->StartOfSectionNode());
761 0 : SwNodeIndex aIdx( pDoc->GetNodes().GetEndOfExtras(), 2 );
762 0 : SwContentNode *pNd = aIdx.GetNode().GetContentNode();
763 : OSL_ENSURE( pNd, "Node not found" );
764 0 : SwPosition aPos( aIdx, SwIndex( pNd ) );
765 0 : pTableNd->GetTable().MakeCopy( pDoc, aPos, aBoxes );
766 : }
767 :
768 8195 : if( !bWriteAll && ( pShell || pOutPam ))
769 : {
770 8075 : if( pShell )
771 1 : pPam = pShell->GetCrsr();
772 : else
773 8074 : pPam = pOutPam;
774 :
775 8075 : SwPaM *pEnd = pPam;
776 :
777 : // 1st round: Check if there is a selection
778 : while(true)
779 : {
780 8075 : bHasMark = bHasMark || pPam->HasMark();
781 8075 : pPam = pPam->GetNext();
782 8075 : if(bHasMark || pPam == pEnd)
783 : break;
784 : }
785 :
786 : // if there is no selection, select the whole document
787 8075 : if(!bHasMark)
788 : {
789 0 : if( pShell )
790 : {
791 0 : pShell->Push();
792 0 : pShell->SttEndDoc(true);
793 0 : pShell->SetMark();
794 0 : pShell->SttEndDoc(false);
795 : }
796 : else
797 : {
798 0 : pPam = new SwPaM( *pPam, pPam );
799 0 : pPam->Move( fnMoveBackward, fnGoDoc );
800 0 : pPam->SetMark();
801 0 : pPam->Move( fnMoveForward, fnGoDoc );
802 : }
803 8075 : }
804 : // pPam is still the current Cursor !!
805 : }
806 : else
807 : {
808 : // no Shell or write-everything -> create a Pam
809 120 : SwDoc* pOutDoc = pDoc ? pDoc : &rDoc;
810 120 : pPam = new SwPaM( pOutDoc->GetNodes().GetEndOfContent() );
811 120 : if( pOutDoc->IsClipBoard() )
812 : {
813 1 : pPam->Move( fnMoveBackward, fnGoDoc );
814 1 : pPam->SetMark();
815 1 : pPam->Move( fnMoveForward, fnGoDoc );
816 : }
817 : else
818 : {
819 119 : pPam->SetMark();
820 119 : pPam->Move( fnMoveBackward, fnGoDoc );
821 : }
822 : }
823 :
824 8195 : rxWriter->bWriteAll = bWriteAll;
825 8195 : SwDoc* pOutDoc = pDoc ? pDoc : &rDoc;
826 :
827 : // If the default PageDesc has still the initial value,
828 : // (e.g. if no printer was set) then set it to DIN A4.
829 : // #i37248# - Modifications are only allowed at a new document.
830 : // <pOutDoc> contains a new document, if <pDoc> is set - see above.
831 8195 : if ( pDoc && !pOutDoc->getIDocumentDeviceAccess().getPrinter( false ) )
832 : {
833 0 : const SwPageDesc& rPgDsc = pOutDoc->GetPageDesc( 0 );
834 : //const SwPageDesc& rPgDsc = *pOutDoc->GetPageDescFromPool( RES_POOLPAGE_STANDARD );
835 0 : const SwFormatFrmSize& rSz = rPgDsc.GetMaster().GetFrmSize();
836 : // Clipboard-Document is always created w/o printer; thus the
837 : // default PageDesc is always aug LONG_MAX !! Set then to DIN A4
838 0 : if( LONG_MAX == rSz.GetHeight() || LONG_MAX == rSz.GetWidth() )
839 : {
840 0 : SwPageDesc aNew( rPgDsc );
841 0 : SwFormatFrmSize aNewSz( rSz );
842 0 : Size a4(SvxPaperInfo::GetPaperSize( PAPER_A4 ));
843 0 : aNewSz.SetHeight( a4.Width() );
844 0 : aNewSz.SetWidth( a4.Height() );
845 0 : aNew.GetMaster().SetFormatAttr( aNewSz );
846 0 : pOutDoc->ChgPageDesc( 0, aNew );
847 : }
848 : }
849 :
850 8195 : bool bLockedView(false);
851 8195 : SwEditShell* pESh = pOutDoc->GetEditShell();
852 8195 : if( pESh )
853 : {
854 5634 : bLockedView = pESh->IsViewLocked();
855 5634 : pESh->LockView( true ); //lock visible section
856 5634 : pESh->StartAllAction();
857 : }
858 :
859 8195 : const bool bOrigPurgeOle = pOutDoc->getIDocumentSettingAccess().get(DocumentSettingId::PURGE_OLE);
860 8195 : pOutDoc->getIDocumentSettingAccess().set(DocumentSettingId::PURGE_OLE, false);
861 8195 : const RedlineMode_t nOrigRedlineMode = pOutDoc->getIDocumentRedlineAccess().GetRedlineMode();
862 :
863 8195 : sal_uLong nError = 0;
864 8195 : if( pMedium )
865 118 : nError = rxWriter->Write( *pPam, *pMedium, pRealFileName );
866 8077 : else if( pStg )
867 0 : nError = rxWriter->Write( *pPam, *pStg, pRealFileName );
868 8077 : else if( pStrm )
869 8076 : nError = rxWriter->Write( *pPam, *pStrm, pRealFileName );
870 1 : else if( xStg.is() )
871 1 : nError = rxWriter->Write( *pPam, xStg, pRealFileName );
872 :
873 8195 : pOutDoc->getIDocumentSettingAccess().set(DocumentSettingId::PURGE_OLE, bOrigPurgeOle );
874 :
875 8195 : if( pESh )
876 : {
877 5634 : pESh->EndAllAction();
878 5634 : pESh->LockView( bLockedView );
879 : }
880 :
881 : // If the selection was only created for printing, reset the old cursor before returning
882 8195 : if( !bWriteAll && ( pShell || pOutPam ))
883 : {
884 8075 : if(!bHasMark)
885 : {
886 0 : if( pShell )
887 0 : pShell->Pop( false );
888 : else
889 0 : delete pPam;
890 : }
891 8075 : pOutDoc->getIDocumentRedlineAccess().SetRedlineMode(nOrigRedlineMode);
892 : }
893 : else
894 : {
895 120 : delete pPam; // delete the created Pam
896 120 : pOutDoc->getIDocumentRedlineAccess().SetRedlineMode(nOrigRedlineMode);
897 : // Everything was written successfully? Tell the document!
898 120 : if ( !IsError( nError ) && !pDoc )
899 : {
900 120 : rDoc.getIDocumentState().ResetModified();
901 : // #i38810# - reset also flag, that indicates updated links
902 120 : rDoc.getIDocumentLinksAdministration().SetLinksUpdated( false );
903 : }
904 : }
905 :
906 8195 : if ( pDoc )
907 : {
908 0 : if ( !pDoc->release() )
909 0 : delete pDoc;
910 0 : bWriteAll = false;
911 : }
912 :
913 8195 : return nError;
914 : }
915 :
916 2 : bool SetHTMLTemplate( SwDoc & rDoc )
917 : {
918 : // get template name of the Sfx-HTML-Filter !!!
919 2 : if( !ReadHTML->GetTemplateDoc() )
920 0 : ReadHTML->MakeHTMLDummyTemplateDoc();
921 :
922 2 : bool bRet = ReadHTML->SetTemplate( rDoc );
923 :
924 2 : SwNodes& rNds = rDoc.GetNodes();
925 2 : SwNodeIndex aIdx( rNds.GetEndOfExtras(), 1 );
926 2 : SwContentNode* pCNd = rNds.GoNext( &aIdx );
927 2 : if( pCNd )
928 : {
929 : pCNd->SetAttr
930 2 : ( SwFormatPageDesc(rDoc.getIDocumentStylePoolAccess().GetPageDescFromPool(RES_POOLPAGE_HTML, false) ) );
931 2 : pCNd->ChgFormatColl( rDoc.getIDocumentStylePoolAccess().GetTextCollFromPool( RES_POOLCOLL_TEXT, false ));
932 : }
933 :
934 2 : return bRet;
935 177 : }
936 :
937 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|