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_svx.hxx"
30 #include <svx/dialmgr.hxx>
31 #ifndef _SVX_DIALOGS_HRC
32 #include <svx/dialogs.hrc>
33 #endif
34 #include <tools/shl.hxx>
35 #include <i18npool/mslangid.hxx>
36 #include <svtools/valueset.hxx>
37 #include <svl/languageoptions.hxx>
38 #ifndef _SVX_HELPID_HRC
39 #include <helpid.hrc>
40 #endif
41 #include <editeng/numitem.hxx>
42 #include <svl/eitem.hxx>
43 #include <vcl/svapp.hxx>
44 #include <svx/gallery.hxx>
45 #include <svl/urihelper.hxx>
46 #include <editeng/brshitem.hxx>
47 #include <svl/intitem.hxx>
48 #include <sfx2/objsh.hxx>
49 #include <vcl/graph.hxx>
50 #include <vcl/msgbox.hxx>
51 #include <editeng/flstitem.hxx>
52 #include <svx/dlgutil.hxx>
53 #ifndef _XTABLE_HXX //autogen
54 
55 #include <svx/xtable.hxx>
56 #endif
57 #include <svx/drawitem.hxx>
58 #include <svx/numvset.hxx>
59 #include <svx/htmlmode.hxx>
60 #include <unotools/pathoptions.hxx>
61 #include <svtools/ctrltool.hxx>
62 #include <editeng/unolingu.hxx>
63 #include <com/sun/star/style/NumberingType.hpp>
64 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
65 #include <com/sun/star/container/XIndexAccess.hpp>
66 #include <com/sun/star/text/XDefaultNumberingProvider.hpp>
67 #include <com/sun/star/text/XNumberingFormatter.hpp>
68 #include <com/sun/star/beans/PropertyValue.hpp>
69 #include <comphelper/processfactory.hxx>
70 #include <com/sun/star/text/XNumberingTypeInfo.hpp>
71 
72 #include <algorithm>
73 #include <sfx2/opengrf.hxx>
74 
75 using namespace com::sun::star::uno;
76 using namespace com::sun::star::beans;
77 using namespace com::sun::star::lang;
78 using namespace com::sun::star::i18n;
79 using namespace com::sun::star::text;
80 using namespace com::sun::star::container;
81 using namespace com::sun::star::style;
82 using rtl::OUString;
83 
84 #define C2U(cChar) OUString::createFromAscii(cChar)
85 #define NUM_PAGETYPE_BULLET			0
86 #define NUM_PAGETYPE_SINGLENUM      1
87 #define NUM_PAGETYPE_NUM            2
88 #define NUM_PAGETYPE_BMP            3
89 #define PAGETYPE_USER_START         10
90 
91 #define SHOW_NUMBERING				0
92 #define SHOW_BULLET					1
93 #define SHOW_BITMAP					2
94 
95 #define MAX_BMP_WIDTH				16
96 #define MAX_BMP_HEIGHT				16
97 
98 static const sal_Char cNumberingType[] = "NumberingType";
99 static const sal_Char cValue[] = "Value";
100 static const sal_Char cParentNumbering[] = "ParentNumbering";
101 static const sal_Char cPrefix[] = "Prefix";
102 static const sal_Char cSuffix[] = "Suffix";
103 static const sal_Char cBulletChar[] = "BulletChar";
104 static const sal_Char cBulletFontName[] = "BulletFontName";
105 
106 /* -----------------28.10.98 08:32-------------------
107  *
108  * --------------------------------------------------*/
109 // Die Auswahl an Bullets aus den StarSymbol
110 static const sal_Unicode aBulletTypes[] =
111 {
112 	0x2022,
113 	0x25cf,
114 	0xe00c,
115 	0xe00a,
116 	0x2794,
117 	0x27a2,
118 	0x2717,
119 	0x2714
120 };
121 
122 static Font& lcl_GetDefaultBulletFont()
123 {
124 	static sal_Bool bInit = 0;
125 	static Font aDefBulletFont( UniString::CreateFromAscii(
126 		                        RTL_CONSTASCII_STRINGPARAM( "StarSymbol" ) ),
127 								String(), Size( 0, 14 ) );
128 	if(!bInit)
129 	{
130         aDefBulletFont.SetCharSet( RTL_TEXTENCODING_SYMBOL );
131 		aDefBulletFont.SetFamily( FAMILY_DONTKNOW );
132 		aDefBulletFont.SetPitch( PITCH_DONTKNOW );
133 		aDefBulletFont.SetWeight( WEIGHT_DONTKNOW );
134 		aDefBulletFont.SetTransparent( sal_True );
135 		bInit = sal_True;
136 	}
137 	return aDefBulletFont;
138 }
139 
140 static void lcl_PaintLevel(OutputDevice* pVDev, sal_Int16 nNumberingType,
141                         const OUString& rBulletChar, const OUString& rText, const OUString& rFontName,
142                         Point& rLeft, Font& rRuleFont, const Font& rTextFont)
143 {
144 
145     if(NumberingType::CHAR_SPECIAL == nNumberingType )
146     {
147         rRuleFont.SetStyleName(rFontName);
148         pVDev->SetFont(rRuleFont);
149         pVDev->DrawText(rLeft, rBulletChar);
150         rLeft.X() += pVDev->GetTextWidth(rBulletChar);
151     }
152     else
153     {
154         pVDev->SetFont(rTextFont);
155         pVDev->DrawText(rLeft, rText);
156         rLeft.X() += pVDev->GetTextWidth(rText);
157     }
158 }
159 void  SvxNumValueSet::UserDraw( const UserDrawEvent& rUDEvt )
160 {
161 	static sal_uInt16 __READONLY_DATA aLinesArr[] =
162 	{
163 		15, 10,
164 		20, 30,
165 		25, 50,
166 		30, 70,
167 		35, 90,	// up to here line positions
168         05, 10, // character positions
169         10, 30,
170         15, 50,
171         20, 70,
172         25, 90,
173 	};
174 
175     const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
176     const Color aBackColor = rStyleSettings.GetFieldColor();
177     const Color aTextColor = rStyleSettings.GetFieldTextColor();
178 
179     OutputDevice*  pDev = rUDEvt.GetDevice();
180 	Rectangle aRect = rUDEvt.GetRect();
181 	sal_uInt16	nItemId = rUDEvt.GetItemId();
182 	long nRectWidth = aRect.GetWidth();
183 	long nRectHeight = aRect.GetHeight();
184 	Size aRectSize(nRectWidth, aRect.GetHeight());
185 	Point aBLPos = aRect.TopLeft();
186 	Font aOldFont = pDev->GetFont();
187 	Color aOldColor = pDev->GetLineColor();
188     pDev->SetLineColor(aTextColor);
189     Font aFont(OutputDevice::GetDefaultFont(
190                 DEFAULTFONT_UI_SANS, MsLangId::getSystemLanguage(), DEFAULTFONT_FLAGS_ONLYONE));
191 
192     Size aSize = aFont.GetSize();
193 
194 	Font aRuleFont( lcl_GetDefaultBulletFont() );
195 	aSize.Height() = nRectHeight/6;
196 	aRuleFont.SetSize(aSize);
197     aRuleFont.SetColor(aTextColor);
198     aRuleFont.SetFillColor(aBackColor);
199 	if(nPageType == NUM_PAGETYPE_BULLET)
200 		aFont = aRuleFont;
201 	else if(nPageType == NUM_PAGETYPE_NUM)
202 	{
203 		aSize.Height() = nRectHeight/8;
204 	}
205 	aFont.SetColor(aTextColor);
206 	aFont.SetFillColor(aBackColor);
207 	aFont.SetSize( aSize );
208 	pDev->SetFont(aFont);
209 
210 	if(!pVDev)
211 	{
212 		// Die Linien werden nur einmalig in das VirtualDevice gepainted
213 		// nur die Gliederungspage bekommt es aktuell
214 		pVDev = new VirtualDevice(*pDev);
215 		pVDev->SetMapMode(pDev->GetMapMode());
216 		pVDev->EnableRTL( IsRTLEnabled() );
217  		pVDev->SetOutputSize( aRectSize );
218 		aOrgRect = aRect;
219 		pVDev->SetFillColor( aBackColor );
220 		pVDev->DrawRect(aOrgRect);
221 
222         if(aBackColor == aLineColor)
223             aLineColor.Invert();
224         pVDev->SetLineColor(aLineColor);
225 		// Linien nur einmalig Zeichnen
226 		if(nPageType != NUM_PAGETYPE_NUM)
227 		{
228 			Point aStart(aBLPos.X() + nRectWidth *25 / 100,0);
229 			Point aEnd(aBLPos.X() + nRectWidth * 9 / 10,0);
230 			for( sal_uInt16 i = 11; i < 100; i += 33)
231 			{
232 				aStart.Y() = aEnd.Y() = aBLPos.Y() + nRectHeight  * i / 100;
233 				pVDev->DrawLine(aStart, aEnd);
234 				aStart.Y() = aEnd.Y() = aBLPos.Y() + nRectHeight  * (i + 11) / 100;
235 				pVDev->DrawLine(aStart, aEnd);
236 			}
237 		}
238 	}
239 	pDev->DrawOutDev(	aRect.TopLeft(), aRectSize,
240 						aOrgRect.TopLeft(), aRectSize,
241 						*pVDev );
242 	// jetzt kommt der Text
243 	const OUString sValue(C2U(cValue));
244     if( NUM_PAGETYPE_SINGLENUM == nPageType ||
245 			NUM_PAGETYPE_BULLET == nPageType )
246 	{
247 		Point aStart(aBLPos.X() + nRectWidth / 9,0);
248 		for( sal_uInt16 i = 0; i < 3; i++ )
249 		{
250 			sal_uInt16 nY = 11 + i * 33;
251 			aStart.Y() = aBLPos.Y() + nRectHeight  * nY / 100;
252 			String sText;
253 			if(nPageType == NUM_PAGETYPE_BULLET)
254 			{
255 				sText = aBulletTypes[nItemId - 1];
256 				aStart.Y() -= pDev->GetTextHeight()/2;
257 				aStart.X() = aBLPos.X() + 5;
258 			}
259 			else
260 			{
261 				if(xFormatter.is() && aNumSettings.getLength() > nItemId - 1)
262 				{
263 					Sequence<PropertyValue> aLevel = aNumSettings.getConstArray()[nItemId - 1];
264 					try
265 					{
266 						aLevel.realloc(aLevel.getLength() + 1);
267 						PropertyValue& rValue = aLevel.getArray()[aLevel.getLength() - 1];
268 						rValue.Name = sValue;
269 						rValue.Value <<= (sal_Int32)(i + 1);
270 						sText = xFormatter->makeNumberingString( aLevel, aLocale );
271 					}
272 					catch(Exception&)
273 					{
274 						DBG_ERROR("Exception in DefaultNumberingProvider::makeNumberingString");
275 					}
276 				}
277 				// knapp neben dem linken Rand beginnen
278 				aStart.X() = aBLPos.X() + 2;
279 				aStart.Y() -= pDev->GetTextHeight()/2;
280 			}
281 			pDev->DrawText(aStart, sText);
282 		}
283 	}
284 	else if(NUM_PAGETYPE_NUM == nPageType )
285 	{
286 		// Outline numbering has to be painted into the virtual device
287 		// to get correct lines
288 		// has to be made again
289 		pVDev->DrawRect(aOrgRect);
290         long nStartX = aOrgRect.TopLeft().X();
291 		long nStartY = aOrgRect.TopLeft().Y();
292 
293 		if(xFormatter.is() && aOutlineSettings.getLength() > nItemId - 1)
294 		{
295 			Reference<XIndexAccess> xLevel = aOutlineSettings.getArray()[nItemId - 1];
296 			try
297 			{
298                 OUString sLevelTexts[5];
299                 OUString sFontNames[5];
300                 OUString sBulletChars[5];
301                 sal_Int16 aNumberingTypes[5];
302                 OUString sPrefixes[5];
303                 OUString sSuffixes[5];
304                 sal_Int16 aParentNumberings[5];
305 
306                 sal_Int32 nLevelCount = xLevel->getCount();
307                 if(nLevelCount > 5)
308                     nLevelCount = 5;
309                 for( sal_Int32 i = 0; i < nLevelCount && i < 5; i++)
310 				{
311                     long nTop = nStartY + nRectHeight * (aLinesArr[2 * i + 11])/100 ;
312 					Point aLeft(nStartX + nRectWidth *  (aLinesArr[2 * i + 10])/ 100, nTop );
313 
314                     Any aLevelAny = xLevel->getByIndex(i);
315 					Sequence<PropertyValue> aLevel;
316 					aLevelAny >>= aLevel;
317                     const PropertyValue* pValues = aLevel.getConstArray();
318                     aNumberingTypes[i] = 0;
319                     for(sal_Int32 nProperty = 0; nProperty < aLevel.getLength() - 1; nProperty++)
320                     {
321                         if(pValues[nProperty].Name.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM(cNumberingType)))
322                             pValues[nProperty].Value >>= aNumberingTypes[i];
323                         else if(pValues[nProperty].Name.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM(cBulletFontName)))
324                             pValues[nProperty].Value >>= sFontNames[i];
325                         else if(pValues[nProperty].Name.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM(cBulletChar)))
326                             pValues[nProperty].Value >>= sBulletChars[i];
327                         else if(pValues[nProperty].Name.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM(cPrefix)))
328                             pValues[nProperty].Value >>= sPrefixes[i];
329                         else if(pValues[nProperty].Name.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM(cSuffix)))
330                             pValues[nProperty].Value >>= sSuffixes[i];
331                         else if(pValues[nProperty].Name.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM(cParentNumbering)))
332                             pValues[nProperty].Value >>= aParentNumberings[i];
333                     }
334                     Sequence< PropertyValue > aProperties(2);
335                     PropertyValue* pProperties = aProperties.getArray();
336                     pProperties[0].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("NumberingType"));
337                     pProperties[0].Value <<= aNumberingTypes[i];
338                     pProperties[1].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Value"));
339                     pProperties[1].Value <<= (sal_Int32)1;
340                     try
341 					{
342                         sLevelTexts[i] = xFormatter->makeNumberingString( aProperties, aLocale );
343 					}
344 					catch(Exception&)
345 					{
346 						DBG_ERROR("Exception in DefaultNumberingProvider::makeNumberingString");
347 					}
348 
349                     aLeft.Y() -= (pDev->GetTextHeight()/2);
350                     if(sPrefixes[i].getLength() &&
351                         !sPrefixes[i].equalsAsciiL(" ", 1) &&
352                         sPrefixes[i].getStr()[0] != 0)
353                     {
354                         pVDev->SetFont(aFont);
355                         pVDev->DrawText(aLeft, sPrefixes[i]);
356                         aLeft.X() += pDev->GetTextWidth(sPrefixes[i]);
357                     }
358                     if(aParentNumberings[i])
359                     {
360                         //insert old numberings here
361                         sal_Int32 nStartLevel = std::min((sal_Int32)aParentNumberings[i], i);
362                         for(sal_Int32 nParentLevel = i - nStartLevel; nParentLevel < i; nParentLevel++)
363                         {
364                             OUString sTmp(sLevelTexts[nParentLevel]);
365                             sTmp += C2U(".");
366                             lcl_PaintLevel(pVDev,
367                                     aNumberingTypes[nParentLevel],
368                                     sBulletChars[nParentLevel],
369                                     sTmp,
370                                     sFontNames[nParentLevel],
371                                     aLeft,
372                                     aRuleFont,
373                                     aFont);
374                         }
375                     }
376                     lcl_PaintLevel(pVDev,
377                                     aNumberingTypes[i],
378                                     sBulletChars[i],
379                                     sLevelTexts[i],
380                                     sFontNames[i],
381                                     aLeft,
382                                     aRuleFont,
383                                     aFont);
384                     if(sSuffixes[i].getLength()&&
385                         !sSuffixes[i].equalsAsciiL(" ", 1) &&
386                         sSuffixes[i].getStr()[0] != 0)
387                     {
388                         pVDev->SetFont(aFont);
389                         pVDev->DrawText(aLeft, sSuffixes[i]);
390                         aLeft.X() += pDev->GetTextWidth(sSuffixes[i]);
391                     }
392 
393 					long nLineTop = nStartY + nRectHeight * aLinesArr[2 * i + 1]/100 ;
394                     Point aLineLeft(aLeft.X() /*+ nStartX + nRectWidth * aLinesArr[2 * i]/ 100*/, nLineTop );
395 					Point aLineRight(nStartX + nRectWidth * 90 /100, nLineTop );
396 					pVDev->DrawLine(aLineLeft,	aLineRight);
397                 }
398 
399             }
400 #ifdef DBG_UTIL
401 			catch(Exception&)
402 			{
403 				static sal_Bool bAssert = sal_False;
404 				if(!bAssert)
405 				{
406 					DBG_ERROR("exception in ::UserDraw");
407 					bAssert = sal_True;
408 				}
409 			}
410 #else
411 			catch(Exception&)
412 			{
413 			}
414 #endif
415 		}
416 		pDev->DrawOutDev(	aRect.TopLeft(), aRectSize,
417 							aOrgRect.TopLeft(), aRectSize,
418 							*pVDev );
419 	}
420 
421 	pDev->SetFont(aOldFont);
422 	pDev->SetLineColor(aOldColor);
423 }
424 
425 /**************************************************************************/
426 /*                                                                        */
427 /*                                                                        */
428 /**************************************************************************/
429 
430 SvxNumValueSet::SvxNumValueSet( Window* pParent, const ResId& rResId, sal_uInt16 nType ) :
431 
432 	ValueSet( pParent, rResId ),
433 
434     aLineColor  ( COL_LIGHTGRAY ),
435     nPageType   ( nType ),
436     bHTMLMode   ( sal_False ),
437     pVDev       ( NULL )
438 {
439 	SetColCount( 4 );
440     SetLineCount( 2 );
441 	SetStyle( GetStyle() | WB_ITEMBORDER | WB_DOUBLEBORDER );
442 	if(NUM_PAGETYPE_BULLET == nType)
443 	{
444 		for	( sal_uInt16 i = 0; i < 8; i++ )
445         {
446 			InsertItem( i + 1, i );
447             SetItemText( i + 1, SVX_RESSTR( RID_SVXSTR_BULLET_DESCRIPTIONS + i ) );
448         }
449 	}
450 }
451 
452 /*-----------------08.02.97 12.38-------------------
453 
454 --------------------------------------------------*/
455 
456  SvxNumValueSet::~SvxNumValueSet()
457 {
458 	delete pVDev;
459 }
460 /* -----------------------------30.01.01 16:24--------------------------------
461 
462  ---------------------------------------------------------------------------*/
463 void SvxNumValueSet::SetNumberingSettings(
464 	const Sequence<Sequence<PropertyValue> >& aNum,
465 	Reference<XNumberingFormatter>& xFormat,
466 	const Locale& rLocale	)
467 {
468 	aNumSettings = aNum;
469 	xFormatter = xFormat;
470 	aLocale = rLocale;
471     if(aNum.getLength() > 8)
472             SetStyle( GetStyle()|WB_VSCROLL);
473     for ( sal_uInt16 i = 0; i < aNum.getLength(); i++ )
474     {
475 			InsertItem( i + 1, i );
476             if( i < 8 )
477                 SetItemText( i + 1, SVX_RESSTR( RID_SVXSTR_SINGLENUM_DESCRIPTIONS + i ));
478     }
479 }
480 /* -----------------------------31.01.01 09:50--------------------------------
481 
482  ---------------------------------------------------------------------------*/
483 void SvxNumValueSet::SetOutlineNumberingSettings(
484 			Sequence<Reference<XIndexAccess> >& rOutline,
485 			Reference<XNumberingFormatter>& xFormat,
486 			const Locale& rLocale)
487 {
488 	aOutlineSettings = rOutline;
489 	xFormatter = xFormat;
490 	aLocale = rLocale;
491     if(aOutlineSettings.getLength() > 8)
492         SetStyle( GetStyle() | WB_VSCROLL );
493     for ( sal_uInt16 i = 0; i < aOutlineSettings.getLength(); i++ )
494     {
495 		InsertItem( i + 1, i );
496         if( i < 8 )
497             SetItemText( i + 1, SVX_RESSTR( RID_SVXSTR_OUTLINENUM_DESCRIPTIONS + i ));
498     }
499 }
500 
501 SvxBmpNumValueSet::SvxBmpNumValueSet( Window* pParent, const ResId& rResId/*, const List& rStrNames*/ ) :
502 
503 	SvxNumValueSet( pParent, rResId, NUM_PAGETYPE_BMP ),
504 //    rStrList    ( rStrNames ),
505 	bGrfNotFound( sal_False )
506 
507 {
508     GalleryExplorer::BeginLocking(GALLERY_THEME_BULLETS);
509     SetStyle( GetStyle() | WB_VSCROLL );
510 	SetLineCount( 3 );
511 	aFormatTimer.SetTimeout(300);
512 	aFormatTimer.SetTimeoutHdl(LINK(this, SvxBmpNumValueSet, FormatHdl_Impl));
513 }
514 
515 /*-----------------13.02.97 09.41-------------------
516 
517 --------------------------------------------------*/
518 
519  SvxBmpNumValueSet::~SvxBmpNumValueSet()
520 {
521     GalleryExplorer::EndLocking(GALLERY_THEME_BULLETS);
522     aFormatTimer.Stop();
523 }
524 /*-----------------13.02.97 09.41-------------------
525 
526 --------------------------------------------------*/
527 
528 void   	SvxBmpNumValueSet::UserDraw( const UserDrawEvent& rUDEvt )
529 {
530 	SvxNumValueSet::UserDraw(rUDEvt);
531 
532 	Rectangle aRect = rUDEvt.GetRect();
533 	OutputDevice*  pDev = rUDEvt.GetDevice();
534 	sal_uInt16	nItemId = rUDEvt.GetItemId();
535 	Point aBLPos = aRect.TopLeft();
536 
537 	int nRectHeight = aRect.GetHeight();
538 	Size aSize(nRectHeight/8, nRectHeight/8);
539 
540     Graphic aGraphic;
541     if(!GalleryExplorer::GetGraphicObj( GALLERY_THEME_BULLETS, nItemId - 1,
542                         &aGraphic, NULL))
543     {
544         bGrfNotFound = sal_True;
545     }
546     else
547     {
548         Point aPos(aBLPos.X() + 5, 0);
549         for( sal_uInt16 i = 0; i < 3; i++ )
550         {
551             sal_uInt16 nY = 11 + i * 33;
552             aPos.Y() = aBLPos.Y() + nRectHeight  * nY / 100;
553             aGraphic.Draw( pDev, aPos, aSize );
554         }
555     }
556 }
557 
558 /*-----------------14.02.97 07.34-------------------
559 
560 --------------------------------------------------*/
561 
562 IMPL_LINK(SvxBmpNumValueSet, FormatHdl_Impl, Timer*, EMPTYARG)
563 {
564 	// nur, wenn eine Grafik nicht da war, muss formatiert werden
565 	if(bGrfNotFound)
566 	{
567 		bGrfNotFound = sal_False;
568 		Format();
569 	}
570 	Invalidate();
571 	return 0;
572 }
573