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 :
21 : #include <hintids.hxx>
22 : #include <tools/date.hxx>
23 : #include <tools/time.hxx>
24 : #include <svl/urihelper.hxx>
25 : #include <svl/fstathelper.hxx>
26 : #include <unotools/moduleoptions.hxx>
27 : #include <sfx2/docfile.hxx>
28 : #include <editeng/lrspitem.hxx>
29 : #include <editeng/ulspitem.hxx>
30 : #include <editeng/boxitem.hxx>
31 : #include <editeng/paperinf.hxx>
32 : #include <node.hxx>
33 : #include <docary.hxx>
34 : #include <fmtanchr.hxx>
35 : #include <fmtfsize.hxx>
36 : #include <fmtpdsc.hxx>
37 : #include <swtypes.hxx>
38 : #include <shellio.hxx>
39 : #include <doc.hxx>
40 : #include <IDocumentUndoRedo.hxx>
41 : #include <pam.hxx>
42 : #include <editsh.hxx>
43 : #include <undobj.hxx> // fuer Undo Insert-Dokument
44 : #include <swundo.hxx> // fuer Undo Insert-Dokument
45 : #include <swtable.hxx>
46 : #include <tblsel.hxx>
47 : #include <pagedesc.hxx>
48 : #include <poolfmt.hxx>
49 : #include <fltini.hxx>
50 : #include <docsh.hxx>
51 : #include <redline.hxx>
52 : #include <swerror.h>
53 : #include <paratr.hxx>
54 :
55 : // #i73788#
56 : #include <pausethreadstarting.hxx>
57 :
58 : using namespace ::com::sun::star;
59 :
60 : //////////////////////////////////////////////////////////////////////////
61 :
62 55 : sal_uLong SwReader::Read( const Reader& rOptions )
63 : {
64 : // Variable uebertragen
65 55 : Reader* po = (Reader*) &rOptions;
66 55 : po->pStrm = pStrm;
67 55 : po->pStg = pStg;
68 55 : po->xStg = xStg;
69 55 : po->bInsertMode = 0 != pCrsr;
70 :
71 : // ist ein Medium angegeben, dann aus diesem die Streams besorgen
72 110 : if( 0 != (po->pMedium = pMedium ) &&
73 55 : !po->SetStrmStgPtr() )
74 : {
75 0 : po->SetReadUTF8( sal_False );
76 0 : po->SetBlockMode( sal_False );
77 0 : po->SetOrganizerMode( sal_False );
78 0 : po->SetIgnoreHTMLComments( sal_False );
79 0 : return ERR_SWG_FILE_FORMAT_ERROR;
80 : }
81 :
82 55 : sal_uLong nError = 0L;
83 :
84 55 : GetDoc();
85 :
86 : // waehrend des einlesens kein OLE-Modified rufen
87 55 : Link aOLELink( pDoc->GetOle2Link() );
88 55 : pDoc->SetOle2Link( Link() );
89 :
90 55 : pDoc->SetInReading( true );
91 55 : pDoc->SetInXMLImport( 0 != dynamic_cast< XMLReader* >(po) );
92 :
93 : SwPaM *pPam;
94 55 : if( pCrsr )
95 0 : pPam = pCrsr;
96 : else
97 : {
98 : // Wenn der Reader nicht mit einem Shell konstruiert wurde,
99 : // selber einen Pam machen.
100 55 : SwNodeIndex nNode( pDoc->GetNodes().GetEndOfContent(), -1 );
101 55 : pPam = new SwPaM( nNode );
102 : // Bei Web-Dokumenten wird die Default-Vorlage schon im InitNew
103 : // gesetzt und braucht deshalb nicht nochmal gesetzt zu werden.
104 : // Das gilt natuerlich nicht, wenn der Filter nicht der HTML-Filter
105 : // ist oder im ConvertFrom zuvor ein SetTemplateName gerufen
106 : // wurde.
107 55 : if( !pDoc->get(IDocumentSettingAccess::HTML_MODE) || ReadHTML != po || !po->pTemplate )
108 55 : po->SetTemplate( *pDoc );
109 : }
110 :
111 : // Pams sind ringfoermig verkettet. Aufhoeren, wenn man wieder beim
112 : // ersten ist.
113 55 : SwPaM *pEnd = pPam;
114 55 : SwUndoInsDoc* pUndo = 0;
115 :
116 55 : sal_Bool bReadPageDescs = sal_False;
117 55 : bool const bDocUndo = pDoc->GetIDocumentUndoRedo().DoesUndo();
118 55 : bool bSaveUndo = bDocUndo && pCrsr;
119 55 : if( bSaveUndo )
120 : {
121 : // das Einlesen von Seitenvorlagen ist nicht Undofaehig!
122 0 : if( 0 != ( bReadPageDescs = po->aOpt.IsPageDescs() ) )
123 : {
124 0 : bSaveUndo = false;
125 0 : pDoc->GetIDocumentUndoRedo().DelAllUndoObj();
126 : }
127 : else
128 : {
129 0 : pDoc->GetIDocumentUndoRedo().ClearRedo();
130 0 : pDoc->GetIDocumentUndoRedo().StartUndo( UNDO_INSDOKUMENT, NULL );
131 : }
132 : }
133 55 : pDoc->GetIDocumentUndoRedo().DoUndo(false);
134 :
135 55 : SwNodeIndex aSplitIdx( pDoc->GetNodes() );
136 :
137 55 : RedlineMode_t eOld = pDoc->GetRedlineMode();
138 55 : RedlineMode_t ePostReadRedlineMode( nsRedlineMode_t::REDLINE_IGNORE );
139 :
140 : // Array von FlyFormaten
141 55 : SwFrmFmts aFlyFrmArr;
142 : // only read templates? then ignore multi selection!
143 55 : sal_Bool bFmtsOnly = po->aOpt.IsFmtsOnly();
144 :
145 0 : while( true )
146 : {
147 55 : if( bSaveUndo )
148 0 : pUndo = new SwUndoInsDoc( *pPam );
149 :
150 55 : pDoc->SetRedlineMode_intern( nsRedlineMode_t::REDLINE_IGNORE );
151 :
152 55 : SwPaM* pUndoPam = 0;
153 55 : if( bDocUndo || pCrsr )
154 : {
155 : // Pam auf den Node davor setzen damit er nicht mit verschoben wird
156 0 : const SwNodeIndex& rTmp = pPam->GetPoint()->nNode;
157 0 : pUndoPam = new SwPaM( rTmp, rTmp, 0, -1 );
158 : }
159 :
160 : // Speicher mal alle Fly's
161 55 : if( pCrsr )
162 : {
163 0 : std::copy(pDoc->GetSpzFrmFmts()->begin(),
164 0 : pDoc->GetSpzFrmFmts()->end(), std::back_inserter(aFlyFrmArr));
165 : }
166 :
167 55 : xub_StrLen nSttCntnt = pPam->GetPoint()->nContent.GetIndex();
168 :
169 : // damit fuer alle Reader die Ende-Position immer stimmt, hier
170 : // pflegen.
171 55 : SwCntntNode* pCNd = pPam->GetCntntNode();
172 55 : xub_StrLen nEndCntnt = pCNd ? pCNd->Len() - nSttCntnt : 0;
173 55 : SwNodeIndex aEndPos( pPam->GetPoint()->nNode, 1 );
174 :
175 55 : pDoc->SetRedlineMode_intern( eOld );
176 :
177 55 : nError = po->Read( *pDoc, GetBaseURL(), *pPam, aFileName );
178 :
179 : // an ODF document may contain redline mode in settings.xml; save it!
180 55 : ePostReadRedlineMode = pDoc->GetRedlineMode();
181 :
182 55 : pDoc->SetRedlineMode_intern( nsRedlineMode_t::REDLINE_IGNORE );
183 :
184 55 : if( !IsError( nError )) // dann setzen wir das Ende mal richtig
185 : {
186 51 : aEndPos--;
187 51 : pCNd = aEndPos.GetNode().GetCntntNode();
188 51 : if( !pCNd && 0 == ( pCNd = pDoc->GetNodes().GoPrevious( &aEndPos ) ))
189 0 : pCNd = pDoc->GetNodes().GoNext( &aEndPos );
190 :
191 51 : pPam->GetPoint()->nNode = aEndPos;
192 51 : xub_StrLen nLen = pCNd->Len();
193 51 : if( nLen < nEndCntnt )
194 0 : nEndCntnt = 0;
195 : else
196 51 : nEndCntnt = nLen - nEndCntnt;
197 51 : pPam->GetPoint()->nContent.Assign( pCNd, nEndCntnt );
198 :
199 51 : const SwStartNode* pTblBoxStart = pCNd->FindTableBoxStartNode();
200 51 : if ( pTblBoxStart )
201 : {
202 0 : SwTableBox* pBox = pTblBoxStart->GetTblBox();
203 0 : if ( pBox )
204 : {
205 0 : pDoc->ChkBoxNumFmt( *pBox, sal_True );
206 : }
207 : }
208 : }
209 :
210 55 : if( pCrsr )
211 : {
212 0 : *pUndoPam->GetMark() = *pPam->GetPoint();
213 0 : pUndoPam->GetPoint()->nNode++;
214 0 : SwNode* pNd = pUndoPam->GetNode();
215 0 : if( pNd->IsCntntNode() )
216 0 : pUndoPam->GetPoint()->nContent.Assign(
217 0 : (SwCntntNode*)pNd, nSttCntnt );
218 : else
219 0 : pUndoPam->GetPoint()->nContent.Assign( 0, 0 );
220 :
221 0 : int bChkHeaderFooter = pNd->FindHeaderStartNode() ||
222 0 : pNd->FindFooterStartNode();
223 :
224 : // Suche alle neuen Fly's und speicher sie als einzelne Undo
225 : // Objecte
226 0 : for( sal_uInt16 n = 0; n < pDoc->GetSpzFrmFmts()->size(); ++n )
227 : {
228 0 : SwFrmFmt* pFrmFmt = (*pDoc->GetSpzFrmFmts())[ n ];
229 0 : const SwFmtAnchor& rAnchor = pFrmFmt->GetAnchor();
230 0 : if( USHRT_MAX == aFlyFrmArr.GetPos( pFrmFmt) )
231 : {
232 : SwPosition const*const pFrameAnchor(
233 0 : rAnchor.GetCntntAnchor());
234 0 : if ( (FLY_AT_PAGE == rAnchor.GetAnchorId())
235 : || ( pFrameAnchor
236 0 : && ( ( (FLY_AT_PARA == rAnchor.GetAnchorId())
237 0 : && ( (pUndoPam->GetPoint()->nNode ==
238 0 : pFrameAnchor->nNode)
239 0 : || (pUndoPam->GetMark()->nNode ==
240 0 : pFrameAnchor->nNode)
241 : )
242 : )
243 : // #i97570# also check frames anchored AT char
244 0 : || ( (FLY_AT_CHAR == rAnchor.GetAnchorId())
245 : && !IsDestroyFrameAnchoredAtChar(
246 : *pFrameAnchor,
247 0 : *pUndoPam->GetPoint(),
248 0 : *pUndoPam->GetMark())
249 : )
250 : )
251 : )
252 : )
253 : {
254 0 : if( bChkHeaderFooter &&
255 0 : (FLY_AT_PARA == rAnchor.GetAnchorId()) &&
256 0 : RES_DRAWFRMFMT == pFrmFmt->Which() )
257 : {
258 : // DrawObjecte in Kopf-/Fusszeilen ist nicht
259 : // erlaubt!
260 0 : pFrmFmt->DelFrms();
261 0 : pDoc->DelFrmFmt( pFrmFmt );
262 0 : --n;
263 : }
264 : else
265 : {
266 0 : if( bSaveUndo )
267 : {
268 0 : pDoc->SetRedlineMode_intern( eOld );
269 : // UGLY: temp. enable undo
270 0 : pDoc->GetIDocumentUndoRedo().DoUndo(true);
271 0 : pDoc->GetIDocumentUndoRedo().AppendUndo(
272 0 : new SwUndoInsLayFmt( pFrmFmt,0,0 ) );
273 0 : pDoc->GetIDocumentUndoRedo().DoUndo(false);
274 0 : pDoc->SetRedlineMode_intern( nsRedlineMode_t::REDLINE_IGNORE );
275 : }
276 0 : if( pFrmFmt->GetDepends() )
277 : {
278 : // beim Insert legen Draw-Objecte einen Frame an
279 : // also weg damit.
280 0 : pFrmFmt->DelFrms();
281 : }
282 :
283 0 : if (FLY_AT_PAGE == rAnchor.GetAnchorId())
284 : {
285 0 : if( !rAnchor.GetCntntAnchor() )
286 : {
287 0 : pFrmFmt->MakeFrms();
288 : }
289 0 : else if( pCrsr )
290 : {
291 : // seitengebundene Flys eingefuegt, dann schalte
292 : // die Optimierungs-Flags vom SwDoc ab. Sonst
293 : // werden die Flys nicht an der Position erzeugt.
294 0 : pDoc->SetLoaded( sal_False );
295 : }
296 : }
297 : else
298 0 : pFrmFmt->MakeFrms();
299 : }
300 : }
301 : }
302 : }
303 0 : if( !aFlyFrmArr.empty() )
304 0 : aFlyFrmArr.clear();
305 :
306 0 : pDoc->SetRedlineMode_intern( eOld );
307 0 : if( pDoc->IsRedlineOn() )
308 0 : pDoc->AppendRedline( new SwRedline( nsRedlineType_t::REDLINE_INSERT, *pUndoPam ), true);
309 : else
310 0 : pDoc->SplitRedline( *pUndoPam );
311 0 : pDoc->SetRedlineMode_intern( nsRedlineMode_t::REDLINE_IGNORE );
312 : }
313 55 : if( bSaveUndo )
314 : {
315 0 : pDoc->SetRedlineMode_intern( eOld );
316 0 : pUndo->SetInsertRange( *pUndoPam, sal_False );
317 : // UGLY: temp. enable undo
318 0 : pDoc->GetIDocumentUndoRedo().DoUndo(true);
319 0 : pDoc->GetIDocumentUndoRedo().AppendUndo( pUndo );
320 0 : pDoc->GetIDocumentUndoRedo().DoUndo(false);
321 0 : pDoc->SetRedlineMode_intern( nsRedlineMode_t::REDLINE_IGNORE );
322 : }
323 :
324 55 : delete pUndoPam;
325 :
326 55 : pPam = (SwPaM *) pPam->GetNext();
327 55 : if( pPam == pEnd )
328 : break;
329 :
330 : // only read templates? then ignore multi selection! Bug 68593
331 0 : if( bFmtsOnly )
332 : break;
333 :
334 : /*
335 : * !!! man muss selbst den Status vom Stream zuruecksetzen. !!!
336 : * Beim seekg wird der akt. Status, eof- und bad-Bit
337 : * gesetzt, warum weiss keiner
338 : */
339 0 : if( pStrm )
340 : {
341 0 : pStrm->Seek(0);
342 0 : pStrm->ResetError();
343 : }
344 55 : }
345 :
346 55 : pDoc->SetInReading( false );
347 55 : pDoc->SetInXMLImport( false );
348 :
349 55 : pDoc->InvalidateNumRules();
350 55 : pDoc->UpdateNumRule();
351 55 : pDoc->ChkCondColls();
352 55 : pDoc->SetAllUniqueFlyNames();
353 :
354 55 : pDoc->GetIDocumentUndoRedo().DoUndo(bDocUndo);
355 55 : if (!bReadPageDescs)
356 : {
357 55 : if( bSaveUndo )
358 : {
359 0 : pDoc->SetRedlineMode_intern( eOld );
360 0 : pDoc->GetIDocumentUndoRedo().EndUndo( UNDO_INSDOKUMENT, NULL );
361 0 : pDoc->SetRedlineMode_intern( nsRedlineMode_t::REDLINE_IGNORE );
362 : }
363 : }
364 :
365 : // Wenn der Pam nur fuers Lesen konstruiert wurde, jetzt zerstoeren.
366 55 : if( !pCrsr )
367 : {
368 55 : delete pPam; // ein neues aufgemacht.
369 :
370 : // #i42634# Moved common code of SwReader::Read() and
371 : // SwDocShell::UpdateLinks() to new SwDoc::UpdateLinks():
372 : // ATM still with Update
373 55 : pDoc->UpdateLinks( true );
374 :
375 : // not insert: set the redline mode read from settings.xml
376 : eOld = static_cast<RedlineMode_t>(
377 55 : ePostReadRedlineMode & ~nsRedlineMode_t::REDLINE_IGNORE);
378 :
379 55 : pDoc->SetFieldsDirty(false, NULL, 0);
380 : }
381 :
382 55 : pDoc->SetRedlineMode_intern( eOld );
383 55 : pDoc->SetOle2Link( aOLELink );
384 :
385 55 : if( pCrsr ) // das Doc ist jetzt modifiziert
386 0 : pDoc->SetModified();
387 : // #i38810# - If links have been updated, the document
388 : // have to be modified. During update of links the OLE link at the document
389 : // isn't set. Thus, the document's modified state has to be set again after
390 : // the OLE link is restored - see above <pDoc->SetOle2Link( aOLELink )>.
391 55 : if ( pDoc->LinksUpdated() )
392 : {
393 0 : pDoc->SetModified();
394 : }
395 :
396 55 : po->SetReadUTF8( sal_False );
397 55 : po->SetBlockMode( sal_False );
398 55 : po->SetOrganizerMode( sal_False );
399 55 : po->SetIgnoreHTMLComments( sal_False );
400 :
401 55 : return nError;
402 : }
403 :
404 :
405 : /*
406 : * Konstruktoren, Destruktor
407 : */
408 :
409 55 : SwReader::SwReader(SfxMedium& rMedium, const String& rFileName, SwDoc *pDocument)
410 : : SwDocFac(pDocument), pStrm(0), pMedium(&rMedium), pCrsr(0),
411 55 : aFileName(rFileName)
412 : {
413 55 : SetBaseURL( rMedium.GetBaseURL() );
414 55 : }
415 :
416 : // In ein existierendes Dokument einlesen
417 :
418 0 : SwReader::SwReader(SvStream& rStrm, const String& rFileName, const String& rBaseURL, SwPaM& rPam)
419 : : SwDocFac(rPam.GetDoc()), pStrm(&rStrm), pMedium(0), pCrsr(&rPam),
420 0 : aFileName(rFileName)
421 : {
422 0 : SetBaseURL( rBaseURL );
423 0 : }
424 :
425 0 : SwReader::SwReader(SfxMedium& rMedium, const String& rFileName, SwPaM& rPam)
426 : : SwDocFac(rPam.GetDoc()), pStrm(0), pMedium(&rMedium),
427 0 : pCrsr(&rPam), aFileName(rFileName)
428 : {
429 0 : SetBaseURL( rMedium.GetBaseURL() );
430 0 : }
431 :
432 0 : SwReader::SwReader( const uno::Reference < embed::XStorage > &rStg, const String& rFilename, SwPaM &rPam )
433 0 : : SwDocFac(rPam.GetDoc()), pStrm(0), xStg( rStg ), pMedium(0), pCrsr(&rPam), aFileName(rFilename)
434 : {
435 0 : }
436 :
437 43 : Reader::Reader()
438 : : pTemplate(0),
439 : aDStamp( Date::EMPTY ),
440 : aTStamp( Time::EMPTY ),
441 : aChkDateTime( DateTime::EMPTY ),
442 : pStrm(0), pMedium(0), bInsertMode(0),
443 : bTmplBrowseMode(0), bReadUTF8(0), bBlockMode(0), bOrganizerMode(0),
444 43 : bHasAskTemplateName(0), bIgnoreHTMLComments(0)
445 : {
446 43 : }
447 :
448 86 : Reader::~Reader()
449 : {
450 43 : delete pTemplate;
451 43 : }
452 :
453 9 : String Reader::GetTemplateName() const
454 : {
455 9 : return aEmptyStr;
456 : }
457 :
458 : // Die Filter-Vorlage laden, setzen und wieder freigeben
459 55 : SwDoc* Reader::GetTemplateDoc()
460 : {
461 55 : if( !bHasAskTemplateName )
462 : {
463 9 : SetTemplateName( GetTemplateName() );
464 9 : bHasAskTemplateName = sal_True;
465 : }
466 :
467 55 : if( !aTemplateNm.Len() )
468 55 : ClearTemplate();
469 : else
470 : {
471 0 : INetURLObject aTDir( aTemplateNm );
472 0 : String aFileName = aTDir.GetMainURL( INetURLObject::NO_DECODE );
473 : OSL_ENSURE( !aTDir.HasError(), "No absolute path for template name!" );
474 0 : DateTime aCurrDateTime( DateTime::SYSTEM );
475 0 : bool bLoad = false;
476 :
477 : // Wenn das Template schon mal geladen wurde, nur einmal pro
478 : // Minute nachschauen, ob es geaendert wurde.
479 0 : if( !pTemplate || aCurrDateTime >= aChkDateTime )
480 : {
481 0 : Date aTstDate( Date::EMPTY );
482 0 : Time aTstTime( Time::EMPTY );
483 0 : if( FStatHelper::GetModifiedDateTimeOfFile(
484 : aTDir.GetMainURL( INetURLObject::NO_DECODE ),
485 0 : &aTstDate, &aTstTime ) &&
486 0 : ( !pTemplate || aDStamp != aTstDate || aTStamp != aTstTime ))
487 : {
488 0 : bLoad = true;
489 0 : aDStamp = aTstDate;
490 0 : aTStamp = aTstTime;
491 : }
492 :
493 : // Erst in einer Minute wieder mal nachschauen, ob sich die
494 : // Vorlage geaendert hat.
495 0 : aChkDateTime = aCurrDateTime;
496 0 : aChkDateTime += Time( 0L, 1L );
497 : }
498 :
499 0 : if( bLoad )
500 : {
501 0 : ClearTemplate();
502 : OSL_ENSURE( !pTemplate, "Who holds the template doc?" );
503 :
504 : // If the writer module is not installed,
505 : // we cannot create a SwDocShell. We could create a
506 : // SwWebDocShell however, because this exists always
507 : // for the help.
508 0 : SvtModuleOptions aModuleOptions;
509 0 : if( aModuleOptions.IsWriter() )
510 : {
511 : SwDocShell *pDocSh =
512 0 : new SwDocShell ( SFX_CREATE_MODE_INTERNAL );
513 0 : SfxObjectShellLock xDocSh = pDocSh;
514 0 : if( pDocSh->DoInitNew( 0 ) )
515 : {
516 0 : pTemplate = pDocSh->GetDoc();
517 0 : pTemplate->SetOle2Link( Link() );
518 : // always FALSE
519 0 : pTemplate->GetIDocumentUndoRedo().DoUndo( false );
520 0 : pTemplate->set(IDocumentSettingAccess::BROWSE_MODE, bTmplBrowseMode );
521 0 : pTemplate->RemoveAllFmtLanguageDependencies();
522 :
523 0 : ReadXML->SetOrganizerMode( sal_True );
524 0 : SfxMedium aMedium( aFileName, sal_False );
525 0 : SwReader aRdr( aMedium, aEmptyStr, pTemplate );
526 0 : aRdr.Read( *ReadXML );
527 0 : ReadXML->SetOrganizerMode( sal_False );
528 :
529 0 : pTemplate->acquire();
530 0 : }
531 0 : }
532 : }
533 :
534 : OSL_ENSURE( !pTemplate || FStatHelper::IsDocument( aFileName ) ||
535 : aTemplateNm.EqualsAscii( "$$Dummy$$" ),
536 0 : "TemplatePtr but no template exist!" );
537 : }
538 :
539 55 : return pTemplate;
540 : }
541 :
542 55 : sal_Bool Reader::SetTemplate( SwDoc& rDoc )
543 : {
544 55 : sal_Bool bRet = sal_False;
545 :
546 55 : GetTemplateDoc();
547 55 : if( pTemplate )
548 : {
549 0 : rDoc.RemoveAllFmtLanguageDependencies();
550 0 : rDoc.ReplaceStyles( *pTemplate );
551 0 : rDoc.SetFixFields(false, NULL);
552 0 : bRet = sal_True;
553 : }
554 :
555 55 : return bRet;
556 : }
557 :
558 55 : void Reader::ClearTemplate()
559 : {
560 55 : if( pTemplate )
561 : {
562 0 : if( 0 == pTemplate->release() )
563 0 : delete pTemplate,
564 0 : pTemplate = 0;
565 : }
566 55 : }
567 :
568 9 : void Reader::SetTemplateName( const String& rDir )
569 : {
570 9 : if( rDir.Len() && aTemplateNm != rDir )
571 : {
572 0 : ClearTemplate();
573 0 : aTemplateNm = rDir;
574 : }
575 9 : }
576 :
577 0 : void Reader::MakeHTMLDummyTemplateDoc()
578 : {
579 0 : ClearTemplate();
580 0 : pTemplate = new SwDoc;
581 0 : pTemplate->acquire();
582 0 : pTemplate->set(IDocumentSettingAccess::BROWSE_MODE, bTmplBrowseMode );
583 0 : pTemplate->getPrinter( true );
584 0 : pTemplate->RemoveAllFmtLanguageDependencies();
585 0 : aChkDateTime = Date( 1, 1, 2300 ); // 2300. Jahrtausend sollte reichen
586 0 : aTemplateNm.AssignAscii( "$$Dummy$$" );
587 0 : }
588 :
589 : // alle die die Streams / Storages nicht geoeffnet brauchen,
590 : // muessen die Methode ueberladen
591 55 : int Reader::SetStrmStgPtr()
592 : {
593 : OSL_ENSURE( pMedium, "Wo ist das Medium??" );
594 :
595 55 : if( pMedium->IsStorage() )
596 : {
597 18 : if( SW_STORAGE_READER & GetReaderType() )
598 : {
599 18 : xStg = pMedium->GetStorage();
600 18 : return sal_True;
601 : }
602 : }
603 : else
604 : {
605 37 : pStrm = pMedium->GetInStream();
606 37 : if ( pStrm && SotStorage::IsStorageFile(pStrm) && (SW_STORAGE_READER & GetReaderType()) )
607 : {
608 33 : pStg = new SotStorage( *pStrm );
609 33 : pStrm = NULL;
610 : }
611 4 : else if ( !(SW_STREAM_READER & GetReaderType()) )
612 : {
613 0 : pStrm = NULL;
614 0 : return sal_False;
615 : }
616 :
617 37 : return sal_True;
618 : }
619 0 : return sal_False;
620 : }
621 :
622 :
623 6 : int Reader::GetReaderType()
624 : {
625 6 : return SW_STREAM_READER;
626 : }
627 :
628 :
629 3 : void Reader::SetFltName( const String& )
630 : {
631 3 : }
632 :
633 :
634 0 : void Reader::ResetFrmFmtAttrs( SfxItemSet &rFrmSet )
635 : {
636 0 : rFrmSet.Put( SvxLRSpaceItem(RES_LR_SPACE) );
637 0 : rFrmSet.Put( SvxULSpaceItem(RES_UL_SPACE) );
638 0 : rFrmSet.Put( SvxBoxItem(RES_BOX) );
639 0 : }
640 :
641 :
642 33 : void Reader::ResetFrmFmts( SwDoc& rDoc )
643 : {
644 132 : for (sal_uInt16 i=0; i<3; ++i)
645 : {
646 : sal_uInt16 nPoolId;
647 99 : switch (i)
648 : {
649 : default:
650 : OSL_ENSURE(i == 0, "Impossible");
651 : //fallthrough
652 : case 0:
653 33 : nPoolId = RES_POOLFRM_FRAME;
654 33 : break;
655 : case 1:
656 33 : nPoolId = RES_POOLFRM_GRAPHIC;
657 33 : break;
658 : case 2:
659 33 : nPoolId = RES_POOLFRM_OLE;
660 33 : break;
661 : }
662 :
663 99 : SwFrmFmt *pFrmFmt = rDoc.GetFrmFmtFromPool( nPoolId );
664 :
665 99 : pFrmFmt->ResetFmtAttr( RES_LR_SPACE );
666 99 : pFrmFmt->ResetFmtAttr( RES_UL_SPACE );
667 99 : pFrmFmt->ResetFmtAttr( RES_BOX );
668 : }
669 33 : }
670 :
671 : // read the sections of the document, which is equal to the medium.
672 : // returns the count of it
673 0 : size_t Reader::GetSectionList( SfxMedium&, std::vector<String*>& ) const
674 : {
675 0 : return 0;
676 : }
677 :
678 : // ------------------------------------------------
679 0 : sal_Bool SwReader::HasGlossaries( const Reader& rOptions )
680 : {
681 : // Variable uebertragen
682 0 : Reader* po = (Reader*) &rOptions;
683 0 : po->pStrm = pStrm;
684 0 : po->pStg = pStg;
685 0 : po->bInsertMode = sal_False;
686 :
687 : // ist ein Medium angegeben, dann aus diesem die Streams besorgen
688 0 : sal_Bool bRet = sal_False;
689 0 : if( !( 0 != (po->pMedium = pMedium ) && !po->SetStrmStgPtr() ))
690 0 : bRet = po->HasGlossaries();
691 0 : return bRet;
692 : }
693 :
694 0 : sal_Bool SwReader::ReadGlossaries( const Reader& rOptions,
695 : SwTextBlocks& rBlocks, sal_Bool bSaveRelFiles )
696 : {
697 : // Variable uebertragen
698 0 : Reader* po = (Reader*) &rOptions;
699 0 : po->pStrm = pStrm;
700 0 : po->pStg = pStg;
701 0 : po->bInsertMode = sal_False;
702 :
703 : // ist ein Medium angegeben, dann aus diesem die Streams besorgen
704 0 : sal_Bool bRet = sal_False;
705 0 : if( !( 0 != (po->pMedium = pMedium ) && !po->SetStrmStgPtr() ))
706 0 : bRet = po->ReadGlossaries( rBlocks, bSaveRelFiles );
707 0 : return bRet;
708 : }
709 :
710 0 : sal_Bool Reader::HasGlossaries() const
711 : {
712 0 : return sal_False;
713 : }
714 :
715 0 : sal_Bool Reader::ReadGlossaries( SwTextBlocks&, sal_Bool ) const
716 : {
717 0 : return sal_False;
718 : }
719 :
720 : // ------------------------------------------------
721 :
722 0 : int StgReader::GetReaderType()
723 : {
724 0 : return SW_STORAGE_READER;
725 : }
726 :
727 :
728 :
729 :
730 : /*
731 : * Writer
732 : */
733 :
734 : /*
735 : * Konstruktoren, Destruktoren sind inline (inc/shellio.hxx).
736 : */
737 :
738 0 : SwWriter::SwWriter(SvStream& rStrm, SwCrsrShell &rShell, sal_Bool bInWriteAll)
739 : : pStrm(&rStrm), pMedium(0), pOutPam(0), pShell(&rShell),
740 0 : rDoc(*rShell.GetDoc()), bWriteAll(bInWriteAll)
741 : {
742 0 : }
743 :
744 0 : SwWriter::SwWriter(SvStream& rStrm,SwDoc &rDocument)
745 : : pStrm(&rStrm), pMedium(0), pOutPam(0), pShell(0), rDoc(rDocument),
746 0 : bWriteAll(true)
747 : {
748 0 : }
749 :
750 20 : SwWriter::SwWriter(SvStream& rStrm, SwPaM& rPam, sal_Bool bInWriteAll)
751 : : pStrm(&rStrm), pMedium(0), pOutPam(&rPam), pShell(0),
752 20 : rDoc(*rPam.GetDoc()), bWriteAll(bInWriteAll)
753 : {
754 20 : }
755 :
756 0 : SwWriter::SwWriter( const uno::Reference < embed::XStorage >& rStg, SwDoc &rDocument)
757 0 : : pStrm(0), xStg( rStg ), pMedium(0), pOutPam(0), pShell(0), rDoc(rDocument), bWriteAll(true)
758 : {
759 0 : }
760 :
761 0 : SwWriter::SwWriter(SfxMedium& rMedium, SwCrsrShell &rShell, sal_Bool bInWriteAll)
762 : : pStrm(0), pMedium(&rMedium), pOutPam(0), pShell(&rShell),
763 0 : rDoc(*rShell.GetDoc()), bWriteAll(bInWriteAll)
764 : {
765 0 : }
766 :
767 3 : SwWriter::SwWriter(SfxMedium& rMedium, SwDoc &rDocument)
768 : : pStrm(0), pMedium(&rMedium), pOutPam(0), pShell(0), rDoc(rDocument),
769 3 : bWriteAll(true)
770 : {
771 3 : }
772 :
773 23 : sal_uLong SwWriter::Write( WriterRef& rxWriter, const String* pRealFileName )
774 : {
775 : // #i73788#
776 23 : SwPauseThreadStarting aPauseThreadStarting;
777 :
778 23 : sal_Bool bHasMark = sal_False;
779 : SwPaM * pPam;
780 :
781 23 : SwDoc *pDoc = 0;
782 :
783 23 : if ( pShell && !bWriteAll && pShell->IsTableMode() )
784 : {
785 0 : bWriteAll = sal_True;
786 0 : pDoc = new SwDoc;
787 0 : pDoc->acquire();
788 :
789 : // kopiere Teile aus einer Tabelle: lege eine Tabelle mit der Breite
790 : // von der Originalen an und kopiere die selectierten Boxen.
791 : // Die Groessen werden prozentual korrigiert.
792 :
793 : // lasse ueber das Layout die Boxen suchen
794 0 : SwSelBoxes aBoxes;
795 0 : GetTblSel( *pShell, aBoxes );
796 0 : SwTableNode* pTblNd = (SwTableNode*)aBoxes[0]->GetSttNd()->StartOfSectionNode();
797 0 : SwNodeIndex aIdx( pDoc->GetNodes().GetEndOfExtras(), 2 );
798 0 : SwCntntNode *pNd = aIdx.GetNode().GetCntntNode();
799 : OSL_ENSURE( pNd, "Node not found" );
800 0 : SwPosition aPos( aIdx, SwIndex( pNd ) );
801 0 : pTblNd->GetTable().MakeCopy( pDoc, aPos, aBoxes );
802 : }
803 :
804 23 : if( !bWriteAll && ( pShell || pOutPam ))
805 : {
806 20 : if( pShell )
807 0 : pPam = pShell->GetCrsr();
808 : else
809 20 : pPam = pOutPam;
810 :
811 20 : SwPaM *pEnd = pPam;
812 :
813 : // Erste Runde: Nachsehen, ob eine Selektion besteht.
814 0 : while(sal_True)
815 : {
816 20 : bHasMark = bHasMark || pPam->HasMark();
817 20 : pPam = (SwPaM *) pPam->GetNext();
818 20 : if(bHasMark || pPam == pEnd)
819 20 : break;
820 : }
821 :
822 : // Wenn keine Selektion besteht, eine ueber das ganze Dokument aufspannen.
823 20 : if(!bHasMark)
824 : {
825 0 : if( pShell )
826 : {
827 0 : pShell->Push();
828 0 : pShell->SttEndDoc(sal_True);
829 0 : pShell->SetMark();
830 0 : pShell->SttEndDoc(sal_False);
831 : }
832 : else
833 : {
834 0 : pPam = new SwPaM( *pPam );
835 0 : pPam->Move( fnMoveBackward, fnGoDoc );
836 0 : pPam->SetMark();
837 0 : pPam->Move( fnMoveForward, fnGoDoc );
838 : }
839 20 : }
840 : // pPam ist immer noch der akt. Cursor !!
841 : }
842 : else
843 : {
844 : // keine Shell oder alles schreiben -> eigenen Pam erzeugen
845 3 : SwDoc* pOutDoc = pDoc ? pDoc : &rDoc;
846 3 : pPam = new SwPaM( pOutDoc->GetNodes().GetEndOfContent() );
847 3 : if( pOutDoc->IsClipBoard() )
848 : {
849 0 : pPam->Move( fnMoveBackward, fnGoDoc );
850 0 : pPam->SetMark();
851 0 : pPam->Move( fnMoveForward, fnGoDoc );
852 : }
853 : else
854 : {
855 3 : pPam->SetMark();
856 3 : pPam->Move( fnMoveBackward, fnGoDoc );
857 : }
858 : }
859 :
860 23 : rxWriter->bWriteAll = bWriteAll;
861 23 : SwDoc* pOutDoc = pDoc ? pDoc : &rDoc;
862 :
863 : // falls der Standart PageDesc. immer noch auf initalen Werten steht
864 : // (wenn z.B. kein Drucker gesetzt wurde) dann setze jetzt auf DIN A4
865 : // #i37248# - Modifications are only allowed at a new document.
866 : // <pOutDoc> contains a new document, if <pDoc> is set - see above.
867 23 : if ( pDoc && !pOutDoc->getPrinter( false ) )
868 : {
869 0 : const SwPageDesc& rPgDsc = pOutDoc->GetPageDesc( 0 );
870 : //const SwPageDesc& rPgDsc = *pOutDoc->GetPageDescFromPool( RES_POOLPAGE_STANDARD );
871 0 : const SwFmtFrmSize& rSz = rPgDsc.GetMaster().GetFrmSize();
872 : // Clipboard-Dokument wird immer ohne Drucker angelegt, so ist
873 : // der Std.PageDesc immer aug LONG_MAX !! Mappe dann auf DIN A4
874 0 : if( LONG_MAX == rSz.GetHeight() || LONG_MAX == rSz.GetWidth() )
875 : {
876 0 : SwPageDesc aNew( rPgDsc );
877 0 : SwFmtFrmSize aNewSz( rSz );
878 0 : Size a4(SvxPaperInfo::GetPaperSize( PAPER_A4 ));
879 0 : aNewSz.SetHeight( a4.Width() );
880 0 : aNewSz.SetWidth( a4.Height() );
881 0 : aNew.GetMaster().SetFmtAttr( aNewSz );
882 0 : pOutDoc->ChgPageDesc( 0, aNew );
883 : }
884 : }
885 :
886 23 : sal_Bool bLockedView(sal_False);
887 23 : SwEditShell* pESh = pOutDoc->GetEditShell();
888 23 : if( pESh )
889 : {
890 22 : bLockedView = pESh->IsViewLocked();
891 22 : pESh->LockView( sal_True ); //lock visible section
892 22 : pESh->StartAllAction();
893 : }
894 :
895 23 : sal_Bool bWasPurgeOle = pOutDoc->get(IDocumentSettingAccess::PURGE_OLE);
896 23 : pOutDoc->set(IDocumentSettingAccess::PURGE_OLE, false);
897 :
898 23 : sal_uLong nError = 0;
899 23 : if( pMedium )
900 3 : nError = rxWriter->Write( *pPam, *pMedium, pRealFileName );
901 20 : else if( pStg )
902 0 : nError = rxWriter->Write( *pPam, *pStg, pRealFileName );
903 20 : else if( pStrm )
904 20 : nError = rxWriter->Write( *pPam, *pStrm, pRealFileName );
905 0 : else if( xStg.is() )
906 0 : nError = rxWriter->Write( *pPam, xStg, pRealFileName );
907 :
908 23 : pOutDoc->set(IDocumentSettingAccess::PURGE_OLE, bWasPurgeOle );
909 :
910 23 : if( pESh )
911 : {
912 22 : pESh->EndAllAction();
913 22 : pESh->LockView( bLockedView );
914 : }
915 :
916 : // Falls nur zum Schreiben eine Selektion aufgespannt wurde, vor der
917 : // Rueckkehr den alten Crsr wieder herstellen.
918 23 : if( !bWriteAll && ( pShell || pOutPam ))
919 : {
920 40 : if(!bHasMark)
921 : {
922 0 : if( pShell )
923 0 : pShell->Pop( sal_False );
924 : else
925 0 : delete pPam;
926 : }
927 : }
928 : else
929 : {
930 3 : delete pPam; // loesche den hier erzeugten Pam
931 : // Alles erfolgreich geschrieben? Sag' das dem Dokument!
932 3 : if ( !IsError( nError ) && !pDoc )
933 : {
934 3 : rDoc.ResetModified();
935 : // #i38810# - reset also flag, that indicates updated links
936 3 : rDoc.SetLinksUpdated( sal_False );
937 : }
938 : }
939 :
940 23 : if ( pDoc )
941 : {
942 0 : if ( !pDoc->release() )
943 0 : delete pDoc;
944 0 : bWriteAll = sal_False;
945 : }
946 :
947 23 : return nError;
948 : }
949 :
950 :
951 :
952 : // ----------------------------------------------------------------------
953 :
954 :
955 0 : sal_Bool SetHTMLTemplate( SwDoc & rDoc )
956 : {
957 : // Vorlagennamen von den Sfx-HTML-Filter besorgen!!!
958 0 : if( !ReadHTML->GetTemplateDoc() )
959 0 : ReadHTML->MakeHTMLDummyTemplateDoc();
960 :
961 0 : sal_Bool bRet = ReadHTML->SetTemplate( rDoc );
962 :
963 0 : SwNodes& rNds = rDoc.GetNodes();
964 0 : SwNodeIndex aIdx( rNds.GetEndOfExtras(), 1 );
965 0 : SwCntntNode* pCNd = rNds.GoNext( &aIdx );
966 0 : if( pCNd )
967 : {
968 : pCNd->SetAttr
969 0 : ( SwFmtPageDesc(rDoc.GetPageDescFromPool(RES_POOLPAGE_HTML, false) ) );
970 0 : pCNd->ChgFmtColl( rDoc.GetTxtCollFromPool( RES_POOLCOLL_TEXT, false ));
971 : }
972 :
973 0 : return bRet;
974 : }
975 :
976 :
977 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|