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