xref: /trunk/main/sw/source/core/swg/swblocks.cxx (revision cdf0e10c)
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