xref: /trunk/main/sw/source/core/swg/swblocks.cxx (revision cdf0e10c4e3984b49a9502b011690b615761d4a3)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_sw.hxx"
30 
31 
32 #include <sfx2/docfilt.hxx>
33 #include <sot/storage.hxx>
34 #include <tools/urlobj.hxx>
35 #ifndef SVTOOLS_FSTATHELPER_HXX
36 #include <svl/fstathelper.hxx>
37 #endif
38 #include <svl/macitem.hxx>
39 #include <unotools/charclass.hxx>
40 #include <frmfmt.hxx>
41 #include <doc.hxx>
42 #include <docary.hxx>
43 #include <pam.hxx>
44 #include <shellio.hxx>
45 #include <swblocks.hxx>
46 #include <ndtxt.hxx>
47 #include <mdiexp.hxx>       // Progress
48 #include <SwXMLTextBlocks.hxx>
49 #ifndef _DOCSH_HXX
50 #include <docsh.hxx>
51 #endif
52 #include <swunohelper.hxx>
53 
54 #ifndef _STATSTR_HRC
55 #include <statstr.hrc>
56 #endif
57 #include <swerror.h>
58 
59 SV_IMPL_OP_PTRARR_SORT( SwBlockNames, SwBlockName* );
60 
61 //////////////////////////////////////////////////////////////////////////
62 
63 // Hash-Code errechnen (muss nicht eindeutig sein)
64 
65 
66 sal_uInt16 SwImpBlocks::Hash( const String& r )
67 {
68     sal_uInt16 n = 0;
69     xub_StrLen nLen = r.Len();
70     if( nLen > 8 )
71         nLen = 8;
72     const sal_Unicode* p = r.GetBuffer();
73     while( nLen-- )
74         n = ( n << 1 ) + *p++;
75     return n;
76 }
77 
78 
79 SwBlockName::SwBlockName( const String& rShort, const String& rLong, long n )
80     : nPos( n ), aShort( rShort ), aLong( rLong ), aPackageName (rShort),
81     bIsOnlyTxtFlagInit( sal_False ), bIsOnlyTxt( sal_False )
82 {
83     nHashS = SwImpBlocks::Hash( rShort );
84     nHashL = SwImpBlocks::Hash( rLong );
85 }
86 SwBlockName::SwBlockName( const String& rShort, const String& rLong, const String& rPackageName)
87     : nPos( 0 ), aShort( rShort ), aLong( rLong ), aPackageName (rPackageName),
88     bIsOnlyTxtFlagInit( sal_False ), bIsOnlyTxt( sal_False )
89 {
90     nHashS = SwImpBlocks::Hash( rShort );
91     nHashL = SwImpBlocks::Hash( rLong );
92 }
93 
94 
95 // Ist die angegebene Datei ein Storage oder gibt es sie nicht?
96 
97 short SwImpBlocks::GetFileType( const String& rFile )
98 {
99     if( !FStatHelper::IsDocument( rFile ) )
100         return SWBLK_NO_FILE;
101     if( SwXMLTextBlocks::IsFileUCBStorage( rFile ) )
102         return SWBLK_XML;
103     if( SvStorage::IsStorageFile( rFile ) )
104         return SWBLK_SW3;
105     //otherwise return NONE
106     return SWBLK_NONE;
107 }
108 
109 
110 SwImpBlocks::SwImpBlocks( const String& rFile, sal_Bool )
111     : aFile( rFile ), pDoc( 0 ), nCur( (sal_uInt16)-1 ),
112     bReadOnly( sal_True ), bInPutMuchBlocks( sal_False )
113 {
114     FStatHelper::GetModifiedDateTimeOfFile( rFile,
115                                             &aDateModified, &aTimeModified );
116     INetURLObject aObj(rFile);
117     aObj.setExtension( aEmptyStr );
118     aName = aObj.GetBase();
119 }
120 
121 
122 SwImpBlocks::~SwImpBlocks()
123 {
124     aNames.DeleteAndDestroy( 0, aNames.Count() );
125 }
126 
127 // Loeschen des Inhaltes des Dokuments
128 void SwImpBlocks::ClearDoc()
129 {
130     pDoc->ClearDoc();
131 }
132 
133 sal_uLong SwImpBlocks::GetDocForConversion( sal_uInt16 n )
134 {
135     return GetDoc( n );
136 }
137 
138 // Erzeugen eines PaMs, der das ganze Dokument umfasst
139 SwPaM* SwImpBlocks::MakePaM()
140 {
141     SwPaM* pPam = new SwPaM( pDoc->GetNodes().GetEndOfContent() );
142     pPam->Move( fnMoveBackward, fnGoDoc );
143     pPam->SetMark();
144     pPam->Move( fnMoveForward, fnGoDoc );
145     pPam->Exchange();
146     return pPam;
147 }
148 
149 
150 sal_uInt16 SwImpBlocks::GetCount() const
151 {
152     return aNames.Count();
153 }
154 
155 // Case Insensitive
156 sal_uInt16 SwImpBlocks::GetIndex( const String& rShort ) const
157 {
158     String s( GetAppCharClass().upper( rShort ) );
159     sal_uInt16 nHash = Hash( s );
160     for( sal_uInt16 i = 0; i < aNames.Count(); i++ )
161     {
162         SwBlockName* pName = aNames[ i ];
163         if( pName->nHashS == nHash
164          && pName->aShort == s )
165             return i;
166     }
167     return (sal_uInt16) -1;
168 }
169 
170 
171 sal_uInt16 SwImpBlocks::GetLongIndex( const String& rLong ) const
172 {
173     sal_uInt16 nHash = Hash( rLong );
174     for( sal_uInt16 i = 0; i < aNames.Count(); i++ )
175     {
176         SwBlockName* pName = aNames[ i ];
177         if( pName->nHashL == nHash
178          && pName->aLong == rLong )
179             return i;
180     }
181     return (sal_uInt16) -1;
182 }
183 
184 
185 const String& SwImpBlocks::GetShortName( sal_uInt16 n ) const
186 {
187     if( n < aNames.Count() )
188         return aNames[ n ]->aShort;
189     return aEmptyStr;
190 }
191 
192 
193 const String& SwImpBlocks::GetLongName( sal_uInt16 n ) const
194 {
195     if( n < aNames.Count() )
196         return aNames[ n ]->aLong;
197     return aEmptyStr;
198 }
199 
200 const String& SwImpBlocks::GetPackageName( sal_uInt16 n ) const
201 {
202     if( n < aNames.Count() )
203         return aNames[ n ]->aPackageName;
204     return aEmptyStr;
205 }
206 
207 void SwImpBlocks::AddName( const String& rShort, const String& rLong,
208                             sal_Bool bOnlyTxt )
209 {
210     sal_uInt16 nIdx = GetIndex( rShort );
211     if( nIdx != (sal_uInt16) -1 )
212         aNames.DeleteAndDestroy( nIdx );
213     SwBlockName* pNew = new SwBlockName( rShort, rLong, 0L );
214     pNew->bIsOnlyTxtFlagInit = sal_True;
215     pNew->bIsOnlyTxt = bOnlyTxt;
216     aNames.C40_PTR_INSERT( SwBlockName, pNew );
217 }
218 
219 
220 
221 sal_Bool SwImpBlocks::IsFileChanged() const
222 {
223     Date aTempDateModified( aDateModified );
224     Time aTempTimeModified( aTimeModified );
225     return FStatHelper::GetModifiedDateTimeOfFile( aFile,
226                             &aTempDateModified, &aTempTimeModified ) &&
227           ( aDateModified != aTempDateModified ||
228             aTimeModified != aTempTimeModified );
229 }
230 
231 
232 void SwImpBlocks::Touch()
233 {
234     FStatHelper::GetModifiedDateTimeOfFile( aFile,
235                                             &aDateModified, &aTimeModified );
236 }
237 
238 sal_Bool SwImpBlocks::IsOnlyTextBlock( const String& ) const
239 {
240     return sal_False;
241 }
242 
243 sal_uLong SwImpBlocks::GetMacroTable( sal_uInt16, SvxMacroTableDtor&, sal_Bool )
244 {
245     return 0;
246 }
247 
248 sal_uLong SwImpBlocks::SetMacroTable( sal_uInt16 ,
249                                 const SvxMacroTableDtor& , sal_Bool )
250 {
251     return 0;
252 }
253 
254 sal_Bool SwImpBlocks::PutMuchEntries( sal_Bool )
255 {
256     return sal_False;
257 }
258 
259 ////////////////////////////////////////////////////////////////////////////
260 
261 
262 SwTextBlocks::SwTextBlocks( const String& rFile )
263     : pImp( 0 ), nErr( 0 )
264 {
265     INetURLObject aObj(rFile);
266     String sFileName = aObj.GetMainURL( INetURLObject::NO_DECODE );
267     switch( SwImpBlocks::GetFileType( rFile ) )
268     {
269     //case SWBLK_SW2:     pImp = new Sw2TextBlocks( sFileName );  break;
270     //case SWBLK_SW3:     pImp = new Sw3TextBlocks( sFileName );  break;
271     case SWBLK_XML:     pImp = new SwXMLTextBlocks( sFileName ); break;
272     case SWBLK_NO_FILE: pImp = new SwXMLTextBlocks( sFileName ); break;
273     }
274     if( !pImp )
275         nErr = ERR_SWG_FILE_FORMAT_ERROR;
276 }
277 
278 SwTextBlocks::~SwTextBlocks()
279 {
280     delete pImp;
281 }
282 
283 const String& SwTextBlocks::GetName()
284 {
285     return pImp ? pImp->aName : aEmptyStr;
286 }
287 
288 
289 void SwTextBlocks::SetName( const String& r )
290 {
291     if( pImp )
292         pImp->SetName( r );
293 }
294 
295 
296 sal_Bool SwTextBlocks::IsOld() const
297 {
298     if (pImp)
299     {
300         short nType = pImp->GetFileType();
301         if (SWBLK_SW3 == nType || SWBLK_SW2 == nType )
302             return sal_True;
303     }
304     return sal_False;
305 }
306 
307 
308 /*
309 sal_uLong SwTextBlocks::ConvertToNew()
310 {
311     // Wir nehmen die aktuelle Datei, benennen diese in .BAK um
312     // und kreieren den neuen Storage
313     if( IsOld() )
314     {
315         // Erst mal muessen wir die Datei freigeben
316         short nType = pImp->GetFileType();
317         Sw2TextBlocks *pTwo = NULL;
318         Sw3TextBlocks *pThree = NULL;
319         SwImpBlocks *pOld = NULL;
320 
321         pImp->nCur = (sal_uInt16) -1;
322         String aName( pImp->aFile );
323         delete pImp; pImp = NULL;
324         // Jetzt wird umbenannt
325         INetURLObject aOldFull( aName );
326         INetURLObject aNewFull( aName );
327 
328         aOldFull.SetExtension( String::CreateFromAscii("bak") );
329         String aOld( aOldFull.GetMainURL( INetURLObject::NO_DECODE ) );
330         String aNew( aNewFull.GetMainURL( INetURLObject::NO_DECODE ) );
331 
332         sal_Bool bError = !SWUnoHelper::UCB_CopyFile( aNew, aOld, sal_True );
333         if( bError )
334         {
335             if (nType == SWBLK_SW2)
336                 pImp = new Sw2TextBlocks( aOld );
337             else
338                 pImp = new Sw3TextBlocks( aOld );
339             return nErr = ERR_SWG_CANNOT_WRITE;
340         }
341 
342         // Die Datei ist erfolgreich umbenannt. Jetzt wird der Storage
343         // aufgesetzt
344         if (nType == SWBLK_SW2)
345             pOld = pTwo = new Sw2TextBlocks( aOld );
346         else
347             pOld = pThree = new Sw3TextBlocks( aOld );
348         SwXMLTextBlocks* pNew = new SwXMLTextBlocks( aName );
349         pNew->SetName ( pOld->GetName());
350         // Wir kopieren den Doc-Ptr in das alte System
351         // den alten SvPersist heben wir uns aber auf,
352         // da dieser die ganze Zeit leben bleibt
353         // und lesen die Dateivorlagen erneut ein
354         SvPersist* pPersist2 = pOld->pDoc->GetPersist();
355         if (SWBLK_SW2 == nType )
356         {
357             delete pOld->pDoc;
358             pOld->pDoc = pNew->pDoc;nLinkCt
359             nErr = pTwo->LoadDoc();
360         }
361         else
362         {
363             nErr = pThree->OpenFile ( sal_True );
364             // Within this call, Sw3IoImp::SetDoc calls RemoveLink
365             // on the old document, and deletes it if the
366             // ref count is now zero
367             pThree->SetDoc ( pNew->pDoc );
368             pOld->pDoc->AddLink();
369         }
370         if( !nErr && 0 == ( nErr = pNew->OpenFile( sal_False )) )
371         {
372             nErr = pNew->SetConvertMode( sal_True );
373             // jetzt werden die Bausteine einfach umkopiert!
374             if( !nErr )
375             {
376                 if (SWBLK_SW2 == nType)
377                     pTwo->StatLineStartPercent();
378                 sal_uInt16 nCount = pOld->GetCount();
379                 for( sal_uInt16 i = 0; i < nCount; i++ )
380                 {
381                     pNew->ClearDoc();
382                     String aShort( pOld->GetShortName( i ) );
383                     String aLong( pOld->GetLongName( i ) );
384                     pNew->AddName( aShort, aLong );
385                     if ( SWBLK_SW3 == nType && pThree->IsOnlyTextBlock(aShort) )
386                     {
387                         String sText;
388                         pThree->GetText( aShort, sText );
389                         pNew->PutText( aShort, aLong, sText );
390                     }
391                     else
392                     {
393                         if (SWBLK_SW2 == nType )
394                         {
395                             // I think this is how it should work (!!!!!!) mtg
396                             pNew->pDoc->SetPersist( pPersist2 );
397                         }
398                         nErr = pOld->GetDocForConversion( i );
399                         if( nErr )
400                             break;
401                         nErr = pNew->BeginPutDoc( aShort, aLong );
402                         if( nErr )
403                             break;
404                         nErr = pNew->PutDoc();
405                         if( nErr )
406                             break;
407                     }
408 
409                     // convert macros, too
410                     SvxMacroTableDtor aMacroTable;
411                     pOld->GetMacroTable( i, aMacroTable, sal_True );
412                     pNew->SetMacroTable( i, aMacroTable, sal_True );
413 
414                     if (SWBLK_SW2 == nType )
415                         pNew->pDoc->SetPersist( 0 );
416                 }
417                 if (SWBLK_SW2 == nType )
418                     ::EndProgress( pOld->pDoc->GetDocShell() );
419             }
420             if( !nErr )
421                 nErr = pNew->SetConvertMode( sal_False );
422         }
423         if ( SWBLK_SW3 == nType )
424         {
425             pThree->CloseFile();
426         }
427         else
428         {
429             // Haben wir es geschafft?
430             pOld->pDoc = NULL;
431         }
432         pNew->ClearDoc();
433         if( !nErr )
434         {
435             delete pOld;
436             pImp = pNew;
437             SWUnoHelper::UCB_DeleteFile( aOld );
438             pNew->MakeBlockList();
439         }
440         else
441         {
442             delete pOld; delete pNew;
443             SWUnoHelper::UCB_DeleteFile( aNew );
444             SWUnoHelper::UCB_CopyFile( aOld, aNew, sal_True );
445             if ( SWBLK_SW2 == nType )
446                 pImp = new Sw2TextBlocks( aOld );
447             else
448                 pImp = new Sw3TextBlocks( aOld );
449         }
450         pNew->CloseFile();
451         FStatHelper::GetModifiedDateTimeOfFile( aNew,
452                             &pImp->aDateModified, &pImp->aTimeModified );
453     }
454     return nErr;
455 } */
456 
457 
458 sal_uInt16 SwTextBlocks::GetCount() const
459 {
460     return pImp ? pImp->GetCount() : 0;
461 }
462 
463 
464 sal_uInt16 SwTextBlocks::GetIndex( const String& r ) const
465 {
466     return pImp ? pImp->GetIndex( r ) : (sal_uInt16) -1;
467 }
468 
469 
470 sal_uInt16 SwTextBlocks::GetLongIndex( const String& r ) const
471 {
472     return pImp ? (sal_uInt16)(pImp->GetLongIndex( r )) : (sal_uInt16) -1;
473 }
474 
475 
476 const String& SwTextBlocks::GetShortName( sal_uInt16 n ) const
477 {
478     if( pImp )
479         return pImp->GetShortName( n );
480     return aEmptyStr;
481 }
482 
483 
484 const String& SwTextBlocks::GetLongName( sal_uInt16 n ) const
485 {
486     if( pImp )
487         return pImp->GetLongName( n );
488     return aEmptyStr;
489 }
490 
491 
492 sal_Bool SwTextBlocks::Delete( sal_uInt16 n )
493 {
494     if( pImp && !pImp->bInPutMuchBlocks )
495     {
496         if( pImp->IsFileChanged() )
497             nErr = ERR_TXTBLOCK_NEWFILE_ERROR;
498         else if( 0 == (nErr = pImp->OpenFile( sal_False ) ))
499         {
500             nErr = pImp->Delete( n );
501             if( !nErr )
502                 pImp->aNames.DeleteAndDestroy( n );
503             if( n == pImp->nCur )
504                 pImp->nCur = (sal_uInt16) -1;
505             if( !nErr )
506                 nErr = pImp->MakeBlockList();
507         }
508         pImp->CloseFile();
509         pImp->Touch();
510 
511         return sal_Bool( nErr == 0 );
512     }
513     return sal_False;
514 }
515 
516 
517 sal_uInt16 SwTextBlocks::Rename( sal_uInt16 n, const String* s, const String* l )
518 {
519     sal_uInt16 nIdx = (sal_uInt16)-1;
520     if( pImp && !pImp->bInPutMuchBlocks )
521     {
522         pImp->nCur = nIdx;
523         String aNew, aLong;
524         if( s )
525             aNew = aLong = *s;
526         if( l )
527             aLong = *l;
528         if( !aNew.Len() )
529         {
530             ASSERT( !this, "Kein Kurzname in Rename angegeben" );
531             nErr = ERR_SWG_INTERNAL_ERROR; return (sal_uInt16) -1;
532         }
533 
534         if( pImp->IsFileChanged() )
535             nErr = ERR_TXTBLOCK_NEWFILE_ERROR;
536         else if( 0 == ( nErr = pImp->OpenFile( sal_False )))
537         {
538             // Vorher den neuen Eintrag in die Liste setzen!
539             GetAppCharClass().toUpper( aNew );
540             nErr = pImp->Rename( n, aNew, aLong );
541             if( !nErr )
542             {
543                 sal_Bool bOnlyTxt = pImp->aNames[ n ]->bIsOnlyTxt;
544                 pImp->aNames.DeleteAndDestroy( n );
545                 pImp->AddName( aNew, aLong, bOnlyTxt );
546                 nErr = pImp->MakeBlockList();
547             }
548         }
549         pImp->CloseFile();
550         pImp->Touch();
551         if( !nErr )
552             nIdx = pImp->GetIndex( aNew );
553     }
554     return nIdx;
555 }
556 
557 sal_uLong SwTextBlocks::CopyBlock( SwTextBlocks& rSource, String& rSrcShort,
558                                 const String& rLong )
559 {
560     sal_Bool bIsOld = sal_False;
561     if (rSource.pImp)
562     {
563         short nType = rSource.pImp->GetFileType();
564         if (SWBLK_SW2 == nType || SWBLK_SW3 == nType )
565             bIsOld = sal_True;
566     }
567     if( bIsOld ) //rSource.IsOld() )
568         nErr = ERR_SWG_OLD_GLOSSARY;
569     else if( pImp->bInPutMuchBlocks )
570         nErr = ERR_SWG_INTERNAL_ERROR;
571     else
572         nErr = pImp->CopyBlock(*rSource.pImp, rSrcShort, rLong);
573     return nErr;
574 }
575 
576 sal_Bool SwTextBlocks::BeginGetDoc( sal_uInt16 n )
577 {
578     if( pImp && !pImp->bInPutMuchBlocks )
579     {
580 // diese Optimierierung darf es nicht mehr geben. OLE-Objecte muessen auf
581 // ihre SubStorages zugreifem koennen!
582 //      if( n == pImp->nCur )
583 //          return sal_True;
584 
585         if( pImp->IsFileChanged() )
586             nErr = ERR_TXTBLOCK_NEWFILE_ERROR;
587         else if( 0 == ( nErr = pImp->OpenFile( sal_True )))
588         {
589             pImp->ClearDoc();
590             nErr = pImp->GetDoc( n );
591             if( nErr )
592                 pImp->nCur = (sal_uInt16)-1;
593             else
594                 pImp->nCur = n;
595         }
596         return sal_Bool( nErr == 0 );
597     }
598     return sal_False;
599 }
600 
601 
602 void SwTextBlocks::EndGetDoc()
603 {
604     if( pImp && !pImp->bInPutMuchBlocks )
605         pImp->CloseFile();
606 }
607 
608 
609 sal_Bool SwTextBlocks::BeginPutDoc( const String& s, const String& l )
610 {
611     if( pImp )
612     {
613         sal_Bool bOk = pImp->bInPutMuchBlocks;
614         if( !bOk )
615         {
616             if( pImp->IsFileChanged() )
617                 nErr = ERR_TXTBLOCK_NEWFILE_ERROR;
618             else
619                 nErr = pImp->OpenFile( sal_False );
620             bOk = 0 == nErr;
621         }
622         if( bOk )
623         {
624             String aNew( s );
625             GetAppCharClass().toUpper( aNew );
626             nErr = pImp->BeginPutDoc( aNew, l );
627         }
628         if( nErr )
629             pImp->CloseFile();
630     }
631     return 0 == nErr;
632 }
633 
634 
635 sal_uInt16 SwTextBlocks::PutDoc()
636 {
637     sal_uInt16 nIdx = (sal_uInt16)-1;
638     if( pImp )
639     {
640         nErr = pImp->PutDoc();
641         if( !nErr )
642         {
643             pImp->nCur = GetIndex( pImp->aShort );
644             if( pImp->nCur != (sal_uInt16) -1 )
645                 pImp->aNames[ pImp->nCur ]->aLong = pImp->aLong;
646             else
647             {
648                 pImp->AddName( pImp->aShort, pImp->aLong );
649                 pImp->nCur = pImp->GetIndex( pImp->aShort );
650             }
651             if( !pImp->bInPutMuchBlocks )
652                 nErr = pImp->MakeBlockList();
653         }
654         if( !pImp->bInPutMuchBlocks )
655         {
656             pImp->CloseFile();
657             pImp->Touch();
658         }
659         nIdx = pImp->nCur;
660     }
661     return nIdx;
662 }
663 
664 sal_uInt16 SwTextBlocks::PutText( const String& rShort, const String& rName,
665                               const String& rTxt )
666 {
667     sal_uInt16 nIdx = (sal_uInt16) -1;
668     if( pImp )
669     {
670         sal_Bool bOk = pImp->bInPutMuchBlocks;
671         if( !bOk )
672         {
673             if( pImp->IsFileChanged() )
674                 nErr = ERR_TXTBLOCK_NEWFILE_ERROR;
675             else
676                 nErr = pImp->OpenFile( sal_False );
677             bOk = 0 == nErr;
678         }
679         if( bOk )
680         {
681             String aNew( rShort );
682             GetAppCharClass().toUpper( aNew );
683             nErr = pImp->PutText( aNew, rName, rTxt );
684             pImp->nCur = (sal_uInt16) -1;
685             if( !nErr )
686             {
687                 nIdx = GetIndex( pImp->aShort );
688                 if( nIdx != (sal_uInt16) -1 )
689                     pImp->aNames[ nIdx ]->aLong = rName;
690                 else
691                 {
692                     pImp->AddName( pImp->aShort, rName, sal_True );
693                     nIdx = pImp->GetIndex( pImp->aShort );
694                 }
695                 if( !pImp->bInPutMuchBlocks )
696                     nErr = pImp->MakeBlockList();
697             }
698         }
699         if( !pImp->bInPutMuchBlocks )
700         {
701             pImp->CloseFile();
702             pImp->Touch();
703         }
704     }
705     return nIdx;
706 }
707 
708 
709 SwDoc* SwTextBlocks::GetDoc()
710 {
711     if( pImp )
712         return pImp->pDoc;
713     return 0;
714 }
715 
716 
717 void SwTextBlocks::ClearDoc()
718 {
719     if( pImp )
720         pImp->ClearDoc();
721     pImp->nCur = (sal_uInt16) -1;
722 }
723 
724 
725 const String& SwTextBlocks::GetFileName() const
726 {
727     return pImp->GetFileName();
728 }
729 
730 
731 sal_Bool SwTextBlocks::IsReadOnly() const
732 {
733     return pImp->bReadOnly;
734 }
735 
736 sal_Bool SwTextBlocks::IsOnlyTextBlock( sal_uInt16 nIdx ) const
737 {
738     sal_Bool bRet = sal_False;
739     if( pImp && !pImp->bInPutMuchBlocks )
740     {
741         SwBlockName* pBlkNm = pImp->aNames[ nIdx ];
742         if( !pBlkNm->bIsOnlyTxtFlagInit &&
743             !pImp->IsFileChanged() && !pImp->OpenFile( sal_True ) )
744         {
745             pBlkNm->bIsOnlyTxt = pImp->IsOnlyTextBlock( pBlkNm->aShort );
746             pBlkNm->bIsOnlyTxtFlagInit = sal_True;
747             pImp->CloseFile();
748         }
749         bRet = pBlkNm->bIsOnlyTxt;
750     }
751     return bRet;
752 }
753 
754 sal_Bool SwTextBlocks::IsOnlyTextBlock( const String& rShort ) const
755 {
756     sal_uInt16 nIdx = pImp->GetIndex( rShort );
757     if( USHRT_MAX != nIdx )
758     {
759         if( pImp->aNames[ nIdx ]->bIsOnlyTxtFlagInit )
760             return pImp->aNames[ nIdx ]->bIsOnlyTxt;
761         return IsOnlyTextBlock( nIdx );
762     }
763 
764     ASSERT( !this, "ungueltiger Name" );
765     return sal_False;
766 }
767 
768 sal_Bool SwTextBlocks::GetMacroTable( sal_uInt16 nIdx, SvxMacroTableDtor& rMacroTbl )
769 {
770     sal_Bool bRet = sal_True;
771     if ( pImp && !pImp->bInPutMuchBlocks )
772         bRet = ( 0 == pImp->GetMacroTable( nIdx, rMacroTbl ) );
773     return bRet;
774 }
775 
776 sal_Bool SwTextBlocks::SetMacroTable( sal_uInt16 nIdx,
777                                 const SvxMacroTableDtor& rMacroTbl )
778 {
779     sal_Bool bRet = sal_True;
780     if ( pImp && !pImp->bInPutMuchBlocks )
781         bRet = ( 0 == pImp->SetMacroTable( nIdx, rMacroTbl ) );
782     return bRet;
783 }
784 
785 sal_Bool SwTextBlocks::StartPutMuchBlockEntries()
786 {
787     sal_Bool bRet = sal_False;
788     if( !IsOld() && pImp )
789         bRet = pImp->PutMuchEntries( sal_True );
790     return bRet;
791 }
792 
793 void SwTextBlocks::EndPutMuchBlockEntries()
794 {
795     if( pImp )
796         pImp->PutMuchEntries( sal_False );
797 }
798 
799 /*-- 20.09.2004 10:25:33---------------------------------------------------
800 
801   -----------------------------------------------------------------------*/
802 String    SwTextBlocks::GetBaseURL() const
803 {
804     String sRet;
805     if(pImp)
806         sRet = pImp->GetBaseURL();
807     return sRet;
808 }
809 /*-- 20.09.2004 10:25:33---------------------------------------------------
810 
811   -----------------------------------------------------------------------*/
812 void SwTextBlocks::SetBaseURL( const String& rURL )
813 {
814     if(pImp)
815         pImp->SetBaseURL(rURL);
816 }
817 
818 
819