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