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