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