xref: /aoo42x/main/svtools/source/control/ctrlbox.cxx (revision a68b38df)
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_svtools.hxx"
26 
27 #define _CTRLBOX_CXX
28 #include <tools/debug.hxx>
29 #include <vcl/svapp.hxx>
30 #include <vcl/field.hxx>
31 #include <comphelper/processfactory.hxx>
32 #include <unotools/charclass.hxx>
33 
34 #include <svtools/svtdata.hxx>
35 #include <svtools/svtools.hrc>
36 #include <svtools/ctrlbox.hxx>
37 #include <svtools/ctrltool.hxx>
38 
39 #include <vcl/i18nhelp.hxx>
40 
41 #define IMGTEXTSPACE    2
42 #define EXTRAFONTSIZE   5
43 
44 static sal_Unicode aImplSymbolFontText[] = {0xF021,0xF032,0xF043,0xF054,0xF065,0xF076,0xF0B7,0xF0C8,0};
45 static sal_Unicode aImplStarSymbolText[] = {0x2706,0x2704,0x270D,0xE033,0x2211,0x2288,0};
46 
47 // ========================================================================
48 // ColorListBox
49 // ========================================================================
50 
51 // --------------------
52 // - ImplColorListData -
53 // --------------------
54 
55 struct ImplColorListData
56 {
57     Color       aColor;
58     sal_Bool        bColor;
59 
60                 ImplColorListData() : aColor( COL_BLACK ) { bColor = sal_False; }
61                 ImplColorListData( const Color& rColor ) : aColor( rColor ) { bColor = sal_True; }
62 };
63 
64 DECLARE_LIST( ImpColorList, ImplColorListData* )
65 
66 // -----------------------------------------------------------------------
67 
68 void ColorListBox::ImplInit()
69 {
70     pColorList = new ImpColorList( 256, 64 );
71     const StyleSettings& rStyleSettings = Application::GetSettings().GetStyleSettings();
72     aImageSize = rStyleSettings.GetListBoxPreviewDefaultPixelSize();
73     EnableUserDraw( sal_True );
74     SetUserItemSize( aImageSize );
75 }
76 
77 // -----------------------------------------------------------------------
78 
79 void ColorListBox::ImplDestroyColorEntries()
80 {
81     for ( sal_uInt16 n = (sal_uInt16) pColorList->Count(); n; )
82     {
83         ImplColorListData* pData = pColorList->GetObject( --n );
84         delete pData;
85     }
86     pColorList->Clear();
87 }
88 
89 // -----------------------------------------------------------------------
90 
91 ColorListBox::ColorListBox( Window* pParent, WinBits nWinStyle ) :
92     ListBox( pParent, nWinStyle )
93 {
94     ImplInit();
95     SetEdgeBlending(true);
96 }
97 
98 // -----------------------------------------------------------------------
99 
100 ColorListBox::ColorListBox( Window* pParent, const ResId& rResId ) :
101     ListBox( pParent, rResId )
102 {
103     ImplInit();
104     SetEdgeBlending(true);
105 }
106 
107 // -----------------------------------------------------------------------
108 
109 ColorListBox::~ColorListBox()
110 {
111     ImplDestroyColorEntries();
112     delete pColorList;
113 }
114 
115 // -----------------------------------------------------------------------
116 
117 sal_uInt16 ColorListBox::InsertEntry( const XubString& rStr, sal_uInt16 nPos )
118 {
119     nPos = ListBox::InsertEntry( rStr, nPos );
120     if ( nPos != LISTBOX_ERROR )
121     {
122         ImplColorListData* pData = new ImplColorListData;
123         pColorList->Insert( pData, nPos );
124     }
125     return nPos;
126 }
127 
128 // -----------------------------------------------------------------------
129 
130 sal_uInt16 ColorListBox::InsertEntry( const Color& rColor, const XubString& rStr,
131                                 sal_uInt16 nPos )
132 {
133     nPos = ListBox::InsertEntry( rStr, nPos );
134     if ( nPos != LISTBOX_ERROR )
135     {
136         ImplColorListData* pData = new ImplColorListData( rColor );
137         pColorList->Insert( pData, nPos );
138     }
139     return nPos;
140 }
141 
142 // -----------------------------------------------------------------------
143 
144 void ColorListBox::InsertAutomaticEntry()
145 {
146     // insert the "Automatic"-entry always on the first position
147     InsertEntry( Color( COL_AUTO ), SvtResId( STR_SVT_AUTOMATIC_COLOR ), 0 );
148 }
149 
150 // -----------------------------------------------------------------------
151 
152 void ColorListBox::RemoveEntry( sal_uInt16 nPos )
153 {
154     ListBox::RemoveEntry( nPos );
155     delete pColorList->Remove( nPos );
156 }
157 
158 // -----------------------------------------------------------------------
159 
160 void ColorListBox::Clear()
161 {
162     ImplDestroyColorEntries();
163     ListBox::Clear();
164 }
165 
166 // -----------------------------------------------------------------------
167 
168 void ColorListBox::CopyEntries( const ColorListBox& rBox )
169 {
170     // Liste leeren
171     ImplDestroyColorEntries();
172 
173     // Daten kopieren
174     sal_uInt16 nCount = (sal_uInt16) rBox.pColorList->Count();
175     for ( sal_uInt16 n = 0; n < nCount; n++ )
176     {
177         ImplColorListData* pData = rBox.pColorList->GetObject( n );
178         sal_uInt16 nPos = InsertEntry( rBox.GetEntry( n ), LISTBOX_APPEND );
179         if ( nPos != LISTBOX_ERROR )
180             pColorList->Insert( new ImplColorListData( *pData ), nPos );
181     }
182 }
183 
184 // -----------------------------------------------------------------------
185 
186 sal_uInt16 ColorListBox::GetEntryPos( const Color& rColor ) const
187 {
188     for( sal_uInt16 n = (sal_uInt16) pColorList->Count(); n; )
189     {
190         ImplColorListData* pData = pColorList->GetObject( --n );
191         if ( pData->bColor && ( pData->aColor == rColor ) )
192             return n;
193     }
194     return LISTBOX_ENTRY_NOTFOUND;
195 }
196 
197 // -----------------------------------------------------------------------
198 
199 Color ColorListBox::GetEntryColor( sal_uInt16 nPos ) const
200 {
201     Color aColor;
202     ImplColorListData* pData = pColorList->GetObject( nPos );
203     if ( pData && pData->bColor )
204         aColor = pData->aColor;
205     return aColor;
206 }
207 
208 // -----------------------------------------------------------------------
209 
210 void ColorListBox::UserDraw( const UserDrawEvent& rUDEvt )
211 {
212     ImplColorListData* pData = pColorList->GetObject( rUDEvt.GetItemId() );
213     if ( pData )
214     {
215         if ( pData->bColor )
216         {
217             Point aPos( rUDEvt.GetRect().TopLeft() );
218 
219             aPos.X() += 2;
220             aPos.Y() += ( rUDEvt.GetRect().GetHeight() - aImageSize.Height() ) / 2;
221 
222             const Rectangle aRect(aPos, aImageSize);
223 
224             rUDEvt.GetDevice()->Push();
225             rUDEvt.GetDevice()->SetFillColor( pData->aColor );
226             rUDEvt.GetDevice()->SetLineColor( rUDEvt.GetDevice()->GetTextColor() );
227             rUDEvt.GetDevice()->DrawRect(aRect);
228             rUDEvt.GetDevice()->Pop();
229 
230             const StyleSettings& rStyleSettings = Application::GetSettings().GetStyleSettings();
231             const sal_uInt16 nEdgeBlendingPercent(GetEdgeBlending() ? rStyleSettings.GetEdgeBlending() : 0);
232 
233             if(nEdgeBlendingPercent)
234             {
235                 Bitmap aBitmap(rUDEvt.GetDevice()->GetBitmap(aRect.TopLeft(), aRect.GetSize()));
236 
237                 if(!aBitmap.IsEmpty())
238                 {
239                     const Color& rTopLeft(rStyleSettings.GetEdgeBlendingTopLeftColor());
240                     const Color& rBottomRight(rStyleSettings.GetEdgeBlendingBottomRightColor());
241                     const sal_uInt8 nAlpha((nEdgeBlendingPercent * 255) / 100);
242 
243                     aBitmap.DrawBlendFrame(nAlpha, rTopLeft, rBottomRight);
244                     rUDEvt.GetDevice()->DrawBitmap(aRect.TopLeft(), aBitmap);
245                 }
246             }
247 
248             ListBox::DrawEntry( rUDEvt, sal_False, sal_True, sal_False );
249         }
250         else
251             ListBox::DrawEntry( rUDEvt, sal_False, sal_True, sal_True );
252     }
253     else
254         ListBox::DrawEntry( rUDEvt, sal_True, sal_True, sal_False );
255 }
256 
257 // =======================================================================
258 // LineListBox
259 // =======================================================================
260 
261 // -------------------
262 // - ImpListListData -
263 // -------------------
264 
265 struct ImpLineListData
266 {
267     long    nLine1;
268     long    nLine2;
269     long    nDistance;
270 };
271 
272 DECLARE_LIST( ImpLineList, ImpLineListData* )
273 
274 // -----------------------------------------------------------------------
275 
276 inline const Color& LineListBox::GetPaintColor( void ) const
277 {
278 	return maPaintCol;
279 }
280 
281 // -----------------------------------------------------------------------
282 
283 void LineListBox::ImpGetLine( long nLine1, long nLine2, long nDistance,
284                             Bitmap& rBmp, XubString& rStr )
285 {
286     Size aSize = GetOutputSizePixel();
287     aSize.Width() -= 20;
288     aSize.Width() -= aTxtSize.Width();
289     aSize.Height() = aTxtSize.Height();
290 
291     // SourceUnit nach Twips
292     if ( eSourceUnit == FUNIT_POINT )
293     {
294         nLine1      *= 20;
295         nLine2      *= 20;
296         nDistance   *= 20;
297     }
298     else if ( eSourceUnit == FUNIT_MM )
299     {
300         nLine1      *= 14440;
301         nLine1      /= 254;
302         nLine2      *= 14440;
303         nLine2      /= 254;
304         nDistance   *= 14440;
305         nDistance   /= 254;
306     }
307 
308     // Linien malen
309     aSize = aVirDev.PixelToLogic( aSize );
310     long nPix = aVirDev.PixelToLogic( Size( 0, 1 ) ).Height();
311     long n1 = nLine1 / 100;
312     long n2 = nLine2 / 100;
313     long nDist  = nDistance / 100;
314     n1 += nPix-1;
315     n1 -= n1%nPix;
316     if ( n2 )
317     {
318         nDist += nPix-1;
319         nDist -= nDist%nPix;
320         n2    += nPix-1;
321         n2    -= n2%nPix;
322     }
323     long nVirHeight = n1+nDist+n2;
324     if ( nVirHeight > aSize.Height() )
325         aSize.Height() = nVirHeight;
326     // negative Breiten muss und darf man nicht painten
327     if ( aSize.Width() > 0 )
328     {
329         Size aVirSize = aVirDev.LogicToPixel( aSize );
330         if ( aVirDev.GetOutputSizePixel() != aVirSize )
331             aVirDev.SetOutputSizePixel( aVirSize );
332         aVirDev.SetFillColor( GetSettings().GetStyleSettings().GetFieldColor() );
333         aVirDev.DrawRect( Rectangle( Point(), aSize ) );
334 
335         aVirDev.SetFillColor( GetPaintColor() );
336         aVirDev.DrawRect( Rectangle( 0, 0, aSize.Width(), n1-nPix ) );
337         if ( n2 )
338         {
339             aVirDev.DrawRect( Rectangle( 0, n1+nDist,
340                                          aSize.Width(), n1+nDist+n2-nPix ) );
341         }
342         rBmp = aVirDev.GetBitmap( Point(), Size( aSize.Width(), n1+nDist+n2 ) );
343     }
344     // Twips nach Unit
345     if ( eUnit == FUNIT_POINT )
346     {
347         nLine1      /= 20;
348         nLine2      /= 20;
349         nDistance   /= 20;
350         rStr.AssignAscii( " pt" );
351     }
352     else if ( eUnit == FUNIT_MM )
353     {
354         nLine1      *= 254;
355         nLine1      /= 14400;
356         nLine2      *= 254;
357         nLine2      /= 14400;
358         nDistance   *= 254;
359         nDistance   /= 14400;
360         rStr.AssignAscii( " mm" );
361     }
362 
363     String aNum( GetSettings().GetLocaleI18nHelper().GetNum( nLine1+nLine2+nDistance, 2 ) );
364     rStr.Insert( aNum, 0 );
365 }
366 
367 // -----------------------------------------------------------------------
368 
369 void LineListBox::ImplInit()
370 {
371     aTxtSize.Width()  = GetTextWidth( XubString( RTL_CONSTASCII_USTRINGPARAM( "99,99 mm" ) ) );
372     aTxtSize.Height() = GetTextHeight();
373     pLineList   = new ImpLineList;
374     eUnit       = FUNIT_POINT;
375     eSourceUnit = FUNIT_POINT;
376 
377     aVirDev.SetLineColor();
378     aVirDev.SetMapMode( MapMode( MAP_TWIP ) );
379 
380 	UpdatePaintLineColor();
381 }
382 
383 // -----------------------------------------------------------------------
384 
385 LineListBox::LineListBox( Window* pParent, WinBits nWinStyle ) :
386     ListBox( pParent, nWinStyle ),
387     aColor( COL_BLACK ),
388 	maPaintCol( COL_BLACK )
389 {
390     ImplInit();
391 }
392 
393 // -----------------------------------------------------------------------
394 
395 LineListBox::LineListBox( Window* pParent, const ResId& rResId ) :
396     ListBox( pParent, rResId ),
397     aColor( COL_BLACK ),
398 	maPaintCol( COL_BLACK )
399 {
400     ImplInit();
401 }
402 
403 // -----------------------------------------------------------------------
404 
405 LineListBox::~LineListBox()
406 {
407     sal_uLong n = 0;
408     sal_uLong nCount = pLineList->Count();
409     while ( n < nCount )
410     {
411         ImpLineListData* pData = pLineList->GetObject( n );
412         if ( pData )
413             delete pData;
414         n++;
415     }
416     delete pLineList;
417 }
418 
419 // -----------------------------------------------------------------------
420 
421 sal_uInt16 LineListBox::InsertEntry( const XubString& rStr, sal_uInt16 nPos )
422 {
423     nPos = ListBox::InsertEntry( rStr, nPos );
424     if ( nPos != LISTBOX_ERROR )
425         pLineList->Insert( NULL, nPos );
426     return nPos;
427 }
428 
429 // -----------------------------------------------------------------------
430 
431 sal_uInt16 LineListBox::InsertEntry( long nLine1, long nLine2, long nDistance,
432                                 sal_uInt16 nPos )
433 {
434     XubString   aStr;
435     Bitmap      aBmp;
436     ImpGetLine( nLine1, nLine2, nDistance, aBmp, aStr );
437     nPos = ListBox::InsertEntry( aStr, aBmp, nPos );
438     if ( nPos != LISTBOX_ERROR )
439     {
440         ImpLineListData* pData = new ImpLineListData;
441         pData->nLine1    = nLine1;
442         pData->nLine2    = nLine2;
443         pData->nDistance = nDistance;
444         pLineList->Insert( pData, nPos );
445     }
446 
447     return nPos;
448 }
449 
450 // -----------------------------------------------------------------------
451 
452 void LineListBox::RemoveEntry( sal_uInt16 nPos )
453 {
454     ListBox::RemoveEntry( nPos );
455     ImpLineListData* pData = pLineList->Remove( nPos );
456     if ( pData )
457         delete pData;
458 }
459 
460 // -----------------------------------------------------------------------
461 
462 void LineListBox::Clear()
463 {
464     sal_uLong n = 0;
465     sal_uLong nCount = pLineList->Count();
466     while ( n < nCount )
467     {
468         ImpLineListData* pData = pLineList->GetObject( n );
469         if ( pData )
470             delete pData;
471         n++;
472     }
473 
474     pLineList->Clear();
475     ListBox::Clear();
476 }
477 
478 // -----------------------------------------------------------------------
479 
480 sal_uInt16 LineListBox::GetEntryPos( long nLine1, long nLine2,
481                                 long nDistance ) const
482 {
483     sal_uLong n = 0;
484     sal_uLong nCount = pLineList->Count();
485     while ( n < nCount )
486     {
487         ImpLineListData* pData = pLineList->GetObject( n );
488         if ( pData )
489         {
490             if ( (pData->nLine1    == nLine1) &&
491                 (pData->nLine2    == nLine2) &&
492                 (pData->nDistance == nDistance) )
493             return (sal_uInt16)n;
494         }
495 
496         n++;
497     }
498 
499     return LISTBOX_ENTRY_NOTFOUND;
500 }
501 
502 // -----------------------------------------------------------------------
503 
504 long LineListBox::GetEntryLine1( sal_uInt16 nPos ) const
505 {
506     ImpLineListData* pData = pLineList->GetObject( nPos );
507     if ( pData )
508         return pData->nLine1;
509     else
510         return 0;
511 }
512 
513 // -----------------------------------------------------------------------
514 
515 long LineListBox::GetEntryLine2( sal_uInt16 nPos ) const
516 {
517     ImpLineListData* pData = pLineList->GetObject( nPos );
518     if ( pData )
519         return pData->nLine2;
520     else
521         return 0;
522 }
523 
524 // -----------------------------------------------------------------------
525 
526 long LineListBox::GetEntryDistance( sal_uInt16 nPos ) const
527 {
528     ImpLineListData* pData = pLineList->GetObject( nPos );
529     if ( pData )
530         return pData->nDistance;
531     else
532         return 0;
533 }
534 
535 // -----------------------------------------------------------------------
536 
537 void LineListBox::UpdateLineColors( void )
538 {
539 	if( UpdatePaintLineColor() )
540 	{
541 		sal_uLong		nCount = pLineList->Count();
542 		if( !nCount )
543 			return;
544 
545 		XubString	aStr;
546 		Bitmap		aBmp;
547 
548 		// exchange entries which containing lines
549 		SetUpdateMode( sal_False );
550 
551 		sal_uInt16		nSelEntry = GetSelectEntryPos();
552 		for( sal_uLong n = 0 ; n < nCount ; ++n )
553 		{
554 			ImpLineListData*	pData = pLineList->GetObject( n );
555 			if( pData )
556 			{
557 				// exchange listbox data
558 				ListBox::RemoveEntry( sal_uInt16( n ) );
559 				ImpGetLine( pData->nLine1, pData->nLine2, pData->nDistance, aBmp, aStr );
560 				ListBox::InsertEntry( aStr, aBmp, sal_uInt16( n ) );
561 			}
562 		}
563 
564 		if( nSelEntry != LISTBOX_ENTRY_NOTFOUND )
565 			SelectEntryPos( nSelEntry );
566 
567 		SetUpdateMode( sal_True );
568 		Invalidate();
569 	}
570 }
571 
572 // -----------------------------------------------------------------------
573 
574 sal_Bool LineListBox::UpdatePaintLineColor( void )
575 {
576 	sal_Bool					bRet = sal_True;
577 	const StyleSettings&	rSettings = GetSettings().GetStyleSettings();
578 	Color					aNewCol( rSettings.GetWindowColor().IsDark()? rSettings.GetLabelTextColor() : aColor );
579 
580 	bRet = aNewCol != maPaintCol;
581 
582 	if( bRet )
583 		maPaintCol = aNewCol;
584 
585 	return bRet;
586 }
587 
588 // -----------------------------------------------------------------------
589 
590 void LineListBox::DataChanged( const DataChangedEvent& rDCEvt )
591 {
592 	ListBox::DataChanged( rDCEvt );
593 
594 	if( ( rDCEvt.GetType() == DATACHANGED_SETTINGS ) && ( rDCEvt.GetFlags() & SETTINGS_STYLE ) )
595 		UpdateLineColors();
596 }
597 
598 // ===================================================================
599 // FontNameBox
600 // ===================================================================
601 
602 struct ImplFontNameListData
603 {
604     FontInfo    maInfo;
605     sal_uInt16      mnType;
606 
607                 ImplFontNameListData( const FontInfo& rInfo,
608                                     sal_uInt16 nType ) :
609                     maInfo( rInfo ),
610                     mnType( nType )
611                 {}
612 };
613 
614 DECLARE_LIST( ImplFontList, ImplFontNameListData* )
615 
616 // -------------------------------------------------------------------
617 
618 FontNameBox::FontNameBox( Window* pParent, WinBits nWinStyle ) :
619     ComboBox( pParent, nWinStyle )
620 {
621     InitBitmaps();
622     mpFontList = NULL;
623     mbWYSIWYG = sal_False;
624     mbSymbols = sal_False;
625 }
626 
627 // -------------------------------------------------------------------
628 
629 FontNameBox::FontNameBox( Window* pParent, const ResId& rResId ) :
630     ComboBox( pParent, rResId )
631 {
632     InitBitmaps();
633     mpFontList = NULL;
634     mbWYSIWYG = sal_False;
635     mbSymbols = sal_False;
636 }
637 
638 // -------------------------------------------------------------------
639 
640 FontNameBox::~FontNameBox()
641 {
642     ImplDestroyFontList();
643 }
644 
645 // -------------------------------------------------------------------
646 
647 void FontNameBox::DataChanged( const DataChangedEvent& rDCEvt )
648 {
649 	ComboBox::DataChanged( rDCEvt );
650 
651 	if( rDCEvt.GetType() == DATACHANGED_SETTINGS && ( rDCEvt.GetFlags() & SETTINGS_STYLE ) )
652 		InitBitmaps();
653 }
654 
655 // -------------------------------------------------------------------
656 
657 void FontNameBox::InitBitmaps( void )
658 {
659 	sal_Bool bHC = GetSettings().GetStyleSettings().GetHighContrastMode();
660 
661 	maImagePrinterFont = Image( SvtResId( bHC? RID_IMG_PRINTERFONT_HC : RID_IMG_PRINTERFONT ) );
662 	maImageBitmapFont = Image( SvtResId( bHC? RID_IMG_BITMAPFONT_HC : RID_IMG_BITMAPFONT ) );
663 	maImageScalableFont = Image( SvtResId( bHC? RID_IMG_SCALABLEFONT_HC : RID_IMG_SCALABLEFONT ) );
664 }
665 
666 // -------------------------------------------------------------------
667 
668 void FontNameBox::ImplDestroyFontList()
669 {
670     if ( mpFontList )
671     {
672         ImplFontNameListData* pInfo = mpFontList->First();
673         while ( pInfo )
674         {
675             delete pInfo;
676             pInfo = mpFontList->Next();
677         }
678         delete mpFontList;
679     }
680 }
681 
682 // -------------------------------------------------------------------
683 
684 void FontNameBox::Fill( const FontList* pList )
685 {
686     // store old text and clear box
687     XubString aOldText = GetText();
688     Clear();
689 
690     ImplDestroyFontList();
691     mpFontList = new ImplFontList;
692 
693     // insert fonts
694     sal_uInt16 nFontCount = pList->GetFontNameCount();
695     for ( sal_uInt16 i = 0; i < nFontCount; i++ )
696     {
697         const FontInfo& rFontInfo = pList->GetFontName( i );
698         sal_uLong nIndex = InsertEntry( rFontInfo.GetName() );
699         if ( nIndex != LISTBOX_ERROR )
700         {
701             sal_uInt16 nType = pList->GetFontNameType( i );
702             ImplFontNameListData* pData = new ImplFontNameListData( rFontInfo, nType );
703             mpFontList->Insert( pData, nIndex );
704         }
705     }
706 
707     ImplCalcUserItemSize();
708 
709     // restore text
710     if ( aOldText.Len() )
711         SetText( aOldText );
712 }
713 
714 // -------------------------------------------------------------------
715 
716 void FontNameBox::EnableWYSIWYG( sal_Bool bEnable )
717 {
718     if ( bEnable != mbWYSIWYG )
719     {
720         mbWYSIWYG = bEnable;
721         EnableUserDraw( mbWYSIWYG | mbSymbols );
722         ImplCalcUserItemSize();
723     }
724 }
725 
726 // -------------------------------------------------------------------
727 
728 void FontNameBox::EnableSymbols( sal_Bool bEnable )
729 {
730     if ( bEnable != mbSymbols )
731     {
732         mbSymbols = bEnable;
733         EnableUserDraw( mbWYSIWYG | mbSymbols );
734         ImplCalcUserItemSize();
735     }
736 }
737 
738 // -------------------------------------------------------------------
739 
740 void FontNameBox::ImplCalcUserItemSize()
741 {
742     Size aUserItemSz;
743     if ( mbWYSIWYG && mpFontList )
744     {
745         sal_uInt16 nMaxLen = 0;
746         sal_Bool bSymbolFont = sal_False;
747         sal_Bool bStarSymbol = sal_False;
748         for ( sal_uInt16 n = GetEntryCount(); n; )
749         {
750             ImplFontNameListData* pData = mpFontList->GetObject( --n );
751             XubString aFontName = pData->maInfo.GetName();
752             if ( aFontName.Len() > nMaxLen )
753                 nMaxLen = aFontName.Len();
754             if ( pData->maInfo.GetCharSet() == RTL_TEXTENCODING_SYMBOL )
755                 bSymbolFont = sal_True;
756             // starsymbol is a unicode font, but gets WYSIWIG symbols
757             if( aFontName.EqualsIgnoreCaseAscii( "starsymbol" )
758             ||  aFontName.EqualsIgnoreCaseAscii( "opensymbol" ) )
759                 bSymbolFont = bStarSymbol = sal_True;
760         }
761 
762         // guess maximimum width
763         Size aOneCharSz( GetTextWidth( String( 'X' ) ), GetTextHeight() );
764         Size aSz( aOneCharSz );
765         aSz.Width() *= nMaxLen;
766         // only XX% of width, because ListBox calculates the normal width...
767         aSz.Width() *= 1;
768         aSz.Width() /= 10;
769         if ( bSymbolFont )
770         {
771             int nLength = sizeof(aImplSymbolFontText)/sizeof(aImplSymbolFontText[0]) - 1;
772             int nLength2 = sizeof(aImplStarSymbolText)/sizeof(aImplStarSymbolText[0]) - 1;
773             if( bStarSymbol && (nLength < nLength2) )
774                 nLength = nLength2;
775             aSz.Width() += aOneCharSz.Width() * nLength;
776         }
777         aSz.Height() *= 14;
778         aSz.Height() /= 10;
779         aUserItemSz = aSz;
780     }
781     if ( mbSymbols )
782     {
783         Size aSz = maImageScalableFont.GetSizePixel();
784         aUserItemSz.Width() += aSz.Width() + IMGTEXTSPACE;
785         if ( aSz.Height() > aUserItemSz.Height() )
786             aUserItemSz.Height() = aSz.Height();
787     }
788     SetUserItemSize( aUserItemSz );
789 }
790 
791 // -------------------------------------------------------------------
792 
793 void FontNameBox::UserDraw( const UserDrawEvent& rUDEvt )
794 {
795     ImplFontNameListData*   pData = mpFontList->GetObject( rUDEvt.GetItemId() );
796     const FontInfo&         rInfo = pData->maInfo;
797     sal_uInt16                  nType = pData->mnType;
798     Point                   aTopLeft = rUDEvt.GetRect().TopLeft();
799     long                    nX = aTopLeft.X();
800     long                    nH = rUDEvt.GetRect().GetHeight();
801 
802     if ( mbSymbols )
803     {
804         nX += IMGTEXTSPACE;
805         Image* pImg = NULL;
806         if ( (nType & (FONTLIST_FONTNAMETYPE_PRINTER | FONTLIST_FONTNAMETYPE_SCREEN)) == FONTLIST_FONTNAMETYPE_PRINTER )
807             pImg = &maImagePrinterFont;
808         else if ( nType & FONTLIST_FONTNAMETYPE_SCALABLE )
809             pImg = &maImageScalableFont;
810         else
811             pImg = &maImageBitmapFont;
812 
813         if ( pImg )
814         {
815             Point aPos( nX, aTopLeft.Y() + (nH-pImg->GetSizePixel().Height())/2 );
816             rUDEvt.GetDevice()->DrawImage( aPos, *pImg );
817         }
818 
819         // X immer um gleiche Breite aendern, auch wenn kein Image ausgegeben.
820         nX += maImagePrinterFont.GetSizePixel().Width();
821     }
822 
823     if ( mbWYSIWYG && mpFontList )
824     {
825         nX += IMGTEXTSPACE;
826 
827         bool bSymbolFont = (rInfo.GetCharSet() == RTL_TEXTENCODING_SYMBOL);
828         // starsymbol is a unicode font, but cannot display its own name
829         const bool bOpenSymbol = rInfo.GetName().EqualsIgnoreCaseAscii( "starsymbol" )
830                               || rInfo.GetName().EqualsIgnoreCaseAscii( "opensymbol" );
831         bSymbolFont |= bOpenSymbol;
832 
833         if( bSymbolFont )
834         {
835             String aText( rInfo.GetName() );
836             aText.AppendAscii( "  " );
837             Point aPos( nX, aTopLeft.Y() + (nH-rUDEvt.GetDevice()->GetTextHeight())/2 );
838             rUDEvt.GetDevice()->DrawText( aPos, aText );
839             nX += rUDEvt.GetDevice()->GetTextWidth( aText );
840         }
841 
842         Color aTextColor = rUDEvt.GetDevice()->GetTextColor();
843         Font aOldFont( rUDEvt.GetDevice()->GetFont() );
844         Size aSize( aOldFont.GetSize() );
845         aSize.Height() += EXTRAFONTSIZE;
846         Font aFont( rInfo );
847         aFont.SetSize( aSize );
848         rUDEvt.GetDevice()->SetFont( aFont );
849         rUDEvt.GetDevice()->SetTextColor( aTextColor );
850 
851         FontCharMap aFontCharMap;
852         bool bHasCharMap = rUDEvt.GetDevice()->GetFontCharMap( aFontCharMap );
853 
854         String aString;
855         if( !bSymbolFont )
856         {
857   	        // preview the font name
858             aString = rInfo.GetName();
859 
860             // reset font if the name cannot be display in the preview font
861             if( STRING_LEN != rUDEvt.GetDevice()->HasGlyphs( aFont, aString ) )
862                 rUDEvt.GetDevice()->SetFont( aOldFont );
863         }
864         else if( bHasCharMap )
865         {
866             // use some sample characters available in the font
867             sal_Unicode aText[8];
868 
869             // start just above the PUA used by most symbol fonts
870             sal_uInt32 cNewChar = 0xFF00;
871 #ifdef QUARTZ
872             // on MacOSX there are too many non-presentable symbols above the codepoint 0x0192
873             if( !bOpenSymbol )
874                 cNewChar = 0x0192;
875 #endif
876             const int nMaxCount = sizeof(aText)/sizeof(*aText) - 1;
877             int nSkip = aFontCharMap.GetCharCount() / nMaxCount;
878             if( nSkip > 10 )
879                 nSkip = 10;
880             else if( nSkip <= 0 )
881                 nSkip = 1;
882             for( int i = 0; i < nMaxCount; ++i )
883             {
884                 sal_uInt32 cOldChar = cNewChar;
885                 for( int j = nSkip; --j >= 0; )
886                     cNewChar = aFontCharMap.GetPrevChar( cNewChar );
887                 if( cOldChar == cNewChar )
888                     break;
889                 aText[ i ] = static_cast<sal_Unicode>(cNewChar); // TODO: support UCS4 samples
890                 aText[ i+1 ] = 0;
891             }
892 
893             aString = String( aText );
894         }
895         else
896         {
897             const sal_Unicode* pText = aImplSymbolFontText;
898             if( bOpenSymbol )
899                 pText = aImplStarSymbolText;
900 
901             aString = String( pText );
902         }
903 
904         long nTextHeight = rUDEvt.GetDevice()->GetTextHeight();
905         Point aPos( nX, aTopLeft.Y() + (nH-nTextHeight)/2 );
906         rUDEvt.GetDevice()->DrawText( aPos, aString );
907 
908         rUDEvt.GetDevice()->SetFont( aOldFont );
909         DrawEntry( rUDEvt, sal_False, sal_False);   // draw seperator
910     }
911     else
912     {
913         DrawEntry( rUDEvt, sal_True, sal_True );
914     }
915 }
916 
917 // ===================================================================
918 // FontStyleBox
919 // ===================================================================
920 
921 FontStyleBox::FontStyleBox( Window* pParent, WinBits nWinStyle ) :
922     ComboBox( pParent, nWinStyle )
923 {
924 }
925 
926 // -------------------------------------------------------------------
927 
928 FontStyleBox::FontStyleBox( Window* pParent, const ResId& rResId ) :
929     ComboBox( pParent, rResId )
930 {
931     aLastStyle = GetText();
932 }
933 
934 // -------------------------------------------------------------------
935 
936 FontStyleBox::~FontStyleBox()
937 {
938 }
939 
940 // -------------------------------------------------------------------
941 
942 void FontStyleBox::Select()
943 {
944     // keep text over fill operation
945     aLastStyle = GetText();
946     ComboBox::Select();
947 }
948 
949 // -------------------------------------------------------------------
950 
951 void FontStyleBox::LoseFocus()
952 {
953     // keep text over fill operation
954     aLastStyle = GetText();
955     ComboBox::LoseFocus();
956 }
957 
958 // -------------------------------------------------------------------
959 
960 void FontStyleBox::Modify()
961 {
962     CharClass   aChrCls( ::comphelper::getProcessServiceFactory(),
963                         GetSettings().GetLocale() );
964     XubString   aStr = GetText();
965     sal_uInt16      nEntryCount = GetEntryCount();
966 
967     if ( GetEntryPos( aStr ) == COMBOBOX_ENTRY_NOTFOUND )
968     {
969         aChrCls.toUpper( aStr );
970         for ( sal_uInt16 i = 0; i < nEntryCount; i++ )
971         {
972             XubString aEntryText = GetEntry( i );
973             aChrCls.toUpper( aEntryText );
974 
975             if ( aStr == aEntryText )
976             {
977                 SetText( GetEntry( i ) );
978                 break;
979             }
980         }
981     }
982 
983     ComboBox::Modify();
984 }
985 
986 // -------------------------------------------------------------------
987 
988 void FontStyleBox::Fill( const XubString& rName, const FontList* pList )
989 {
990     // note: this method must call ComboBox::SetText(),
991     //   else aLastStyle will overwritten
992     // store prior selection position and clear box
993     XubString aOldText = GetText();
994     sal_uInt16 nPos = GetEntryPos( aOldText );
995     Clear();
996 
997     // does a font with this name already exist?
998     sal_Handle hFontInfo = pList->GetFirstFontInfo( rName );
999     if ( hFontInfo )
1000     {
1001         XubString   aStyleText;
1002         FontWeight  eLastWeight = WEIGHT_DONTKNOW;
1003         FontItalic  eLastItalic = ITALIC_NONE;
1004         FontWidth   eLastWidth = WIDTH_DONTKNOW;
1005         sal_Bool        bNormal = sal_False;
1006         sal_Bool        bItalic = sal_False;
1007         sal_Bool        bBold = sal_False;
1008         sal_Bool        bBoldItalic = sal_False;
1009         sal_Bool        bInsert = sal_False;
1010         FontInfo    aInfo;
1011         while ( hFontInfo )
1012         {
1013             aInfo = pList->GetFontInfo( hFontInfo );
1014 
1015             FontWeight  eWeight = aInfo.GetWeight();
1016             FontItalic  eItalic = aInfo.GetItalic();
1017             FontWidth   eWidth = aInfo.GetWidthType();
1018             // Only if the attributes are different, we insert the
1019             // Font to avoid double Entries in different languages
1020             if ( (eWeight != eLastWeight) || (eItalic != eLastItalic) ||
1021                  (eWidth != eLastWidth) )
1022             {
1023                 if ( bInsert )
1024                     InsertEntry( aStyleText );
1025 
1026                 if ( eWeight <= WEIGHT_NORMAL )
1027                 {
1028                     if ( eItalic != ITALIC_NONE )
1029                         bItalic = sal_True;
1030                     else
1031                         bNormal = sal_True;
1032                 }
1033                 else
1034                 {
1035                     if ( eItalic != ITALIC_NONE )
1036                         bBoldItalic = sal_True;
1037                     else
1038                         bBold = sal_True;
1039                 }
1040 
1041                 // For wrong StyleNames we replace this with the correct once
1042                 aStyleText = pList->GetStyleName( aInfo );
1043                 bInsert = GetEntryPos( aStyleText ) == LISTBOX_ENTRY_NOTFOUND;
1044                 if ( !bInsert )
1045                 {
1046                     aStyleText = pList->GetStyleName( eWeight, eItalic );
1047                     bInsert = GetEntryPos( aStyleText ) == LISTBOX_ENTRY_NOTFOUND;
1048                 }
1049 
1050                 eLastWeight = eWeight;
1051                 eLastItalic = eItalic;
1052                 eLastWidth = eWidth;
1053             }
1054             else
1055             {
1056                 if ( bInsert )
1057                 {
1058                     // If we have two names for the same attributes
1059                     // we prefer the translated standard names
1060                     const XubString& rAttrStyleText = pList->GetStyleName( eWeight, eItalic );
1061                     if ( rAttrStyleText != aStyleText )
1062                     {
1063                         XubString aTempStyleText = pList->GetStyleName( aInfo );
1064                         if ( rAttrStyleText == aTempStyleText )
1065                             aStyleText = rAttrStyleText;
1066                         bInsert = GetEntryPos( aStyleText ) == LISTBOX_ENTRY_NOTFOUND;
1067                     }
1068                 }
1069             }
1070 
1071             if ( !bItalic && (aStyleText == pList->GetItalicStr()) )
1072                 bItalic = sal_True;
1073             else if ( !bBold && (aStyleText == pList->GetBoldStr()) )
1074                 bBold = sal_True;
1075             else if ( !bBoldItalic && (aStyleText == pList->GetBoldItalicStr()) )
1076                 bBoldItalic = sal_True;
1077 
1078             hFontInfo = pList->GetNextFontInfo( hFontInfo );
1079         }
1080 
1081         if ( bInsert )
1082             InsertEntry( aStyleText );
1083 
1084         // Bestimmte Styles als Nachbildung
1085         if ( bNormal )
1086         {
1087             if ( !bItalic )
1088                 InsertEntry( pList->GetItalicStr() );
1089             if ( !bBold )
1090                 InsertEntry( pList->GetBoldStr() );
1091         }
1092         if ( !bBoldItalic )
1093         {
1094             if ( bNormal || bItalic || bBold )
1095                 InsertEntry( pList->GetBoldItalicStr() );
1096         }
1097         if ( aOldText.Len() )
1098         {
1099             if ( GetEntryPos( aLastStyle ) != LISTBOX_ENTRY_NOTFOUND )
1100                 ComboBox::SetText( aLastStyle );
1101             else
1102             {
1103                 if ( nPos >= GetEntryCount() )
1104                     ComboBox::SetText( GetEntry( 0 ) );
1105                 else
1106                     ComboBox::SetText( GetEntry( nPos ) );
1107             }
1108         }
1109     }
1110     else
1111     {
1112         // Wenn Font nicht, dann Standard-Styles einfuegen
1113         InsertEntry( pList->GetNormalStr() );
1114         InsertEntry( pList->GetItalicStr() );
1115         InsertEntry( pList->GetBoldStr() );
1116         InsertEntry( pList->GetBoldItalicStr() );
1117         if ( aOldText.Len() )
1118         {
1119             if ( nPos > GetEntryCount() )
1120                 ComboBox::SetText( GetEntry( 0 ) );
1121             else
1122                 ComboBox::SetText( GetEntry( nPos ) );
1123         }
1124     }
1125 }
1126 
1127 // ===================================================================
1128 // FontSizeBox
1129 // ===================================================================
1130 
1131 FontSizeBox::FontSizeBox( Window* pParent, WinBits nWinSize ) :
1132     MetricBox( pParent, nWinSize )
1133 {
1134     ImplInit();
1135 }
1136 
1137 // -----------------------------------------------------------------------
1138 
1139 FontSizeBox::FontSizeBox( Window* pParent, const ResId& rResId ) :
1140     MetricBox( pParent, rResId )
1141 {
1142     ImplInit();
1143 }
1144 
1145 // -----------------------------------------------------------------------
1146 
1147 FontSizeBox::~FontSizeBox()
1148 {
1149 }
1150 
1151 // -----------------------------------------------------------------------
1152 
1153 void FontSizeBox::ImplInit()
1154 {
1155     EnableAutocomplete( sal_False );
1156 
1157     bRelativeMode   = sal_False;
1158     bPtRelative     = sal_False;
1159     bRelative       = sal_False;
1160     bStdSize        = sal_False;
1161     pFontList       = NULL;
1162 
1163     SetShowTrailingZeros( sal_False );
1164     SetDecimalDigits( 1 );
1165     SetMin( 20 );
1166     SetMax( 9999 );
1167     SetProminentEntryType( PROMINENT_MIDDLE );
1168 }
1169 
1170 // -----------------------------------------------------------------------
1171 
1172 void FontSizeBox::Reformat()
1173 {
1174     FontSizeNames aFontSizeNames( GetSettings().GetUILanguage() );
1175     if ( !bRelativeMode || !aFontSizeNames.IsEmpty() )
1176     {
1177         long nNewValue = aFontSizeNames.Name2Size( GetText() );
1178         if ( nNewValue)
1179         {
1180             mnLastValue = nNewValue;
1181             return;
1182         }
1183     }
1184 
1185     MetricBox::Reformat();
1186 }
1187 
1188 // -----------------------------------------------------------------------
1189 
1190 void FontSizeBox::Modify()
1191 {
1192     MetricBox::Modify();
1193 
1194     if ( bRelativeMode )
1195     {
1196         XubString aStr = GetText();
1197         aStr.EraseLeadingChars();
1198 
1199         sal_Bool bNewMode = bRelative;
1200         sal_Bool bOldPtRelMode = bPtRelative;
1201 
1202         if ( bRelative )
1203         {
1204             bPtRelative = sal_False;
1205             const xub_Unicode* pStr = aStr.GetBuffer();
1206             while ( *pStr )
1207             {
1208                 if ( ((*pStr < '0') || (*pStr > '9')) && (*pStr != '%') )
1209                 {
1210                     if ( ('-' == *pStr || '+' == *pStr) && !bPtRelative )
1211                         bPtRelative = sal_True;
1212                     else if ( bPtRelative && 'p' == *pStr && 't' == *++pStr )
1213                         ;
1214                     else
1215                     {
1216                         bNewMode = sal_False;
1217                         break;
1218                     }
1219                 }
1220                 pStr++;
1221             }
1222         }
1223         else
1224         {
1225             if ( STRING_NOTFOUND != aStr.Search( '%' ) )
1226             {
1227                 bNewMode = sal_True;
1228                 bPtRelative = sal_False;
1229             }
1230 
1231             if ( '-' == aStr.GetChar( 0 ) || '+' == aStr.GetChar( 0 ) )
1232             {
1233                 bNewMode = sal_True;
1234                 bPtRelative = sal_True;
1235             }
1236         }
1237 
1238         if ( bNewMode != bRelative || bPtRelative != bOldPtRelMode )
1239             SetRelative( bNewMode );
1240     }
1241 }
1242 
1243 // -----------------------------------------------------------------------
1244 
1245 void FontSizeBox::Fill( const FontInfo* pInfo, const FontList* pList )
1246 {
1247     // remember for relative mode
1248     pFontList = pList;
1249 
1250     // no font sizes need to be set for relative mode
1251     if ( bRelative )
1252         return;
1253 
1254     // query font sizes
1255     const long* pTempAry;
1256     const long* pAry = 0;
1257 
1258 	if( pInfo )
1259 	{
1260 		aFontInfo = *pInfo;
1261 		pAry = pList->GetSizeAry( *pInfo );
1262 	}
1263 	else
1264 	{
1265 		pAry = pList->GetStdSizeAry();
1266 	}
1267 
1268     // first insert font size names (for simplified/traditional chinese)
1269     FontSizeNames aFontSizeNames( GetSettings().GetUILanguage() );
1270     if ( pAry == pList->GetStdSizeAry() )
1271     {
1272         // for standard sizes we don't need to bother
1273         if ( bStdSize && GetEntryCount() && aFontSizeNames.IsEmpty() )
1274             return;
1275         bStdSize = sal_True;
1276     }
1277     else
1278         bStdSize = sal_False;
1279 
1280     Selection aSelection = GetSelection();
1281     XubString aStr = GetText();
1282 
1283     Clear();
1284     sal_uInt16 nPos = 0;
1285 
1286     if ( !aFontSizeNames.IsEmpty() )
1287     {
1288         if ( pAry == pList->GetStdSizeAry() )
1289         {
1290             // for scalable fonts all font size names
1291             sal_uLong nCount = aFontSizeNames.Count();
1292             for( sal_uLong i = 0; i < nCount; i++ )
1293             {
1294                 String  aSizeName = aFontSizeNames.GetIndexName( i );
1295                 long    nSize = aFontSizeNames.GetIndexSize( i );
1296                 ComboBox::InsertEntry( aSizeName, nPos );
1297                 ComboBox::SetEntryData( nPos, (void*)(-nSize) ); // mark as special
1298                 nPos++;
1299             }
1300         }
1301         else
1302         {
1303             // for fixed size fonts only selectable font size names
1304             pTempAry = pAry;
1305             while ( *pTempAry )
1306             {
1307                 String aSizeName = aFontSizeNames.Size2Name( *pTempAry );
1308                 if ( aSizeName.Len() )
1309                 {
1310                     ComboBox::InsertEntry( aSizeName, nPos );
1311                     ComboBox::SetEntryData( nPos, (void*)(-(*pTempAry)) ); // mark as special
1312                     nPos++;
1313                 }
1314                 pTempAry++;
1315             }
1316         }
1317     }
1318 
1319     // then insert numerical font size values
1320     pTempAry = pAry;
1321     while ( *pTempAry )
1322     {
1323         InsertValue( *pTempAry, FUNIT_NONE, nPos );
1324         ComboBox::SetEntryData( nPos, (void*)(*pTempAry) );
1325         nPos++;
1326         pTempAry++;
1327     }
1328 
1329     SetText( aStr );
1330     SetSelection( aSelection );
1331 }
1332 
1333 // -----------------------------------------------------------------------
1334 
1335 void FontSizeBox::EnableRelativeMode( sal_uInt16 nMin, sal_uInt16 nMax, sal_uInt16 nStep )
1336 {
1337     bRelativeMode = sal_True;
1338     nRelMin       = nMin;
1339     nRelMax       = nMax;
1340     nRelStep      = nStep;
1341     SetUnit( FUNIT_POINT );
1342 }
1343 
1344 // -----------------------------------------------------------------------
1345 
1346 void FontSizeBox::EnablePtRelativeMode( short nMin, short nMax, short nStep )
1347 {
1348     bRelativeMode = sal_True;
1349     nPtRelMin     = nMin;
1350     nPtRelMax     = nMax;
1351     nPtRelStep    = nStep;
1352     SetUnit( FUNIT_POINT );
1353 }
1354 
1355 // -----------------------------------------------------------------------
1356 
1357 void FontSizeBox::SetRelative( sal_Bool bNewRelative )
1358 {
1359     if ( bRelativeMode )
1360     {
1361         Selection aSelection = GetSelection();
1362         XubString  aStr = GetText();
1363         aStr.EraseLeadingChars();
1364 
1365         if ( bNewRelative )
1366         {
1367             bRelative = sal_True;
1368             bStdSize = sal_False;
1369 
1370             if ( bPtRelative )
1371             {
1372                 SetDecimalDigits( 1 );
1373                 SetMin( nPtRelMin );
1374                 SetMax( nPtRelMax );
1375                 SetUnit( FUNIT_POINT );
1376 
1377                 Clear();
1378 
1379                 short i = nPtRelMin, n = 0;
1380                 // JP 30.06.98: more than 100 values are not useful
1381                 while ( i <= nPtRelMax && n++ < 100 )
1382                 {
1383                     InsertValue( i );
1384                     i = i + nPtRelStep;
1385                 }
1386             }
1387             else
1388             {
1389                 SetDecimalDigits( 0 );
1390                 SetMin( nRelMin );
1391                 SetMax( nRelMax );
1392                 SetCustomUnitText( '%' );
1393                 SetUnit( FUNIT_CUSTOM );
1394 
1395                 Clear();
1396                 sal_uInt16 i = nRelMin;
1397                 while ( i <= nRelMax )
1398                 {
1399                     InsertValue( i );
1400                     i = i + nRelStep;
1401                 }
1402             }
1403         }
1404         else
1405         {
1406             bRelative = bPtRelative = sal_False;
1407             SetDecimalDigits( 1 );
1408             SetMin( 20 );
1409             SetMax( 9999 );
1410             SetUnit( FUNIT_POINT );
1411             if ( pFontList )
1412                 Fill( &aFontInfo, pFontList );
1413         }
1414 
1415         SetText( aStr );
1416         SetSelection( aSelection );
1417     }
1418 }
1419 
1420 // -----------------------------------------------------------------------
1421 
1422 XubString FontSizeBox::CreateFieldText( sal_Int64 nValue ) const
1423 {
1424     XubString sRet( MetricBox::CreateFieldText( nValue ) );
1425     if ( bRelativeMode && bPtRelative && (0 <= nValue) && sRet.Len() )
1426         sRet.Insert( '+', 0 );
1427     return sRet;
1428 }
1429 
1430 // -----------------------------------------------------------------------
1431 
1432 void FontSizeBox::SetValue( sal_Int64 nNewValue, FieldUnit eInUnit )
1433 {
1434     if ( !bRelative )
1435     {
1436         sal_Int64 nTempValue = MetricField::ConvertValue( nNewValue, GetBaseValue(), GetDecimalDigits(), eInUnit, GetUnit() );
1437         FontSizeNames aFontSizeNames( GetSettings().GetUILanguage() );
1438         // conversion loses precision; however font sizes should
1439         // never have a problem with that
1440         String aName = aFontSizeNames.Size2Name( static_cast<long>(nTempValue) );
1441         if ( aName.Len() && (GetEntryPos( aName ) != LISTBOX_ENTRY_NOTFOUND) )
1442         {
1443             mnLastValue = nTempValue;
1444             SetText( aName );
1445             mnFieldValue = mnLastValue;
1446             SetEmptyFieldValueData( sal_False );
1447 			return;
1448         }
1449     }
1450 
1451     MetricBox::SetValue( nNewValue, eInUnit );
1452 }
1453 
1454 // -----------------------------------------------------------------------
1455 
1456 void FontSizeBox::SetValue( sal_Int64 nNewValue )
1457 {
1458     SetValue( nNewValue, FUNIT_NONE );
1459 }
1460 
1461 // -----------------------------------------------------------------------
1462 
1463 sal_Int64 FontSizeBox::GetValue( sal_uInt16 nPos, FieldUnit eOutUnit ) const
1464 {
1465     if ( !bRelative )
1466     {
1467         sal_Int64 nComboVal = static_cast<sal_Int64>(reinterpret_cast<long>(ComboBox::GetEntryData( nPos )));
1468         if ( nComboVal < 0 )     // marked as special?
1469         {
1470             return MetricField::ConvertValue( -nComboVal, mnBaseValue, GetDecimalDigits(),
1471                                               meUnit, eOutUnit );
1472         }
1473     }
1474 
1475     // do normal font size processing
1476     sal_Int64 nRetValue = MetricBox::GetValue( nPos, eOutUnit );
1477     return nRetValue;
1478 }
1479 
1480 // -----------------------------------------------------------------------
1481 
1482 sal_Int64 FontSizeBox::GetValue( FieldUnit eOutUnit ) const
1483 {
1484     if ( !bRelative )
1485     {
1486         FontSizeNames aFontSizeNames( GetSettings().GetUILanguage() );
1487         sal_Int64 nValue = aFontSizeNames.Name2Size( GetText() );
1488         if ( nValue)
1489             return MetricField::ConvertValue( nValue, GetBaseValue(), GetDecimalDigits(), GetUnit(), eOutUnit );
1490     }
1491 
1492     return MetricBox::GetValue( eOutUnit );
1493 }
1494 
1495 // -----------------------------------------------------------------------
1496 
1497 sal_Int64 FontSizeBox::GetValue() const
1498 {
1499     // implementation not inline, because it is a virtual function
1500     return GetValue( FUNIT_NONE );
1501 }
1502 
1503 // -----------------------------------------------------------------------
1504 
1505 void FontSizeBox::SetUserValue( sal_Int64 nNewValue, FieldUnit eInUnit )
1506 {
1507     if ( !bRelative )
1508     {
1509         sal_Int64 nTempValue = MetricField::ConvertValue( nNewValue, GetBaseValue(), GetDecimalDigits(), eInUnit, GetUnit() );
1510         FontSizeNames aFontSizeNames( GetSettings().GetUILanguage() );
1511         // conversion loses precision
1512         // however font sizes should never have a problem with that
1513         String aName = aFontSizeNames.Size2Name( static_cast<long>(nTempValue) );
1514         if ( aName.Len() && (GetEntryPos( aName ) != LISTBOX_ENTRY_NOTFOUND) )
1515         {
1516             mnLastValue = nTempValue;
1517             SetText( aName );
1518             return;
1519         }
1520     }
1521 
1522     MetricBox::SetUserValue( nNewValue, eInUnit );
1523 }
1524 
1525