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