update dev300-m58
[ooovba.git] / svtools / source / control / ctrlbox.cxx
blob01cd7889fcc24c87aa81a4083b3d31403b0824f5
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: ctrlbox.cxx,v $
10 * $Revision: 1.27 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_svtools.hxx"
34 #define _CTRLBOX_CXX
35 #include <tools/debug.hxx>
36 #ifndef _APP_HXX
37 #include <vcl/svapp.hxx>
38 #endif
39 #ifndef _FIELD_HXX
40 #include <vcl/field.hxx>
41 #endif
42 #include <comphelper/processfactory.hxx>
43 #include <unotools/charclass.hxx>
45 #include <svtools/svtdata.hxx>
46 #include <svtools/svtools.hrc>
47 #include <ctrlbox.hxx>
48 #include <ctrltool.hxx>
50 #include <vcl/i18nhelp.hxx>
52 #define IMGTEXTSPACE 2
53 #define EXTRAFONTSIZE 5
55 static sal_Unicode aImplSymbolFontText[] = {0xF021,0xF032,0xF043,0xF054,0xF065,0xF076,0xF0B7,0xF0C8,0};
56 static sal_Unicode aImplStarSymbolText[] = {0x2706,0x2704,0x270D,0xE033,0x2211,0x2288,0};
58 // ========================================================================
59 // ColorListBox
60 // ========================================================================
62 // --------------------
63 // - ImplColorListData -
64 // --------------------
66 struct ImplColorListData
68 Color aColor;
69 BOOL bColor;
71 ImplColorListData() : aColor( COL_BLACK ) { bColor = FALSE; }
72 ImplColorListData( const Color& rColor ) : aColor( rColor ) { bColor = TRUE; }
75 DECLARE_LIST( ImpColorList, ImplColorListData* )
77 // -----------------------------------------------------------------------
79 void ColorListBox::ImplInit()
81 pColorList = new ImpColorList( 256, 64 );
82 aImageSize.Width() = GetTextWidth( XubString( RTL_CONSTASCII_USTRINGPARAM( "xxx" ) ) );
83 aImageSize.Height() = GetTextHeight();
84 aImageSize.Height() -= 2;
86 EnableUserDraw( TRUE );
87 SetUserItemSize( aImageSize );
90 // -----------------------------------------------------------------------
92 void ColorListBox::ImplDestroyColorEntries()
94 for ( USHORT n = (USHORT) pColorList->Count(); n; )
96 ImplColorListData* pData = pColorList->GetObject( --n );
97 delete pData;
99 pColorList->Clear();
102 // -----------------------------------------------------------------------
104 ColorListBox::ColorListBox( Window* pParent, WinBits nWinStyle ) :
105 ListBox( pParent, nWinStyle )
107 ImplInit();
110 // -----------------------------------------------------------------------
112 ColorListBox::ColorListBox( Window* pParent, const ResId& rResId ) :
113 ListBox( pParent, rResId )
115 ImplInit();
118 // -----------------------------------------------------------------------
120 ColorListBox::~ColorListBox()
122 ImplDestroyColorEntries();
123 delete pColorList;
126 // -----------------------------------------------------------------------
128 USHORT ColorListBox::InsertEntry( const XubString& rStr, USHORT nPos )
130 nPos = ListBox::InsertEntry( rStr, nPos );
131 if ( nPos != LISTBOX_ERROR )
133 ImplColorListData* pData = new ImplColorListData;
134 pColorList->Insert( pData, nPos );
136 return nPos;
139 // -----------------------------------------------------------------------
141 USHORT ColorListBox::InsertEntry( const Color& rColor, const XubString& rStr,
142 USHORT nPos )
144 nPos = ListBox::InsertEntry( rStr, nPos );
145 if ( nPos != LISTBOX_ERROR )
147 ImplColorListData* pData = new ImplColorListData( rColor );
148 pColorList->Insert( pData, nPos );
150 return nPos;
153 // -----------------------------------------------------------------------
155 void ColorListBox::InsertAutomaticEntry()
157 // insert the "Automatic"-entry always on the first position
158 InsertEntry( Color( COL_AUTO ), SvtResId( STR_SVT_AUTOMATIC_COLOR ), 0 );
161 // -----------------------------------------------------------------------
163 void ColorListBox::RemoveEntry( USHORT nPos )
165 ListBox::RemoveEntry( nPos );
166 delete pColorList->Remove( nPos );
169 // -----------------------------------------------------------------------
171 void ColorListBox::Clear()
173 ImplDestroyColorEntries();
174 ListBox::Clear();
177 // -----------------------------------------------------------------------
179 void ColorListBox::CopyEntries( const ColorListBox& rBox )
181 // Liste leeren
182 ImplDestroyColorEntries();
184 // Daten kopieren
185 USHORT nCount = (USHORT) rBox.pColorList->Count();
186 for ( USHORT n = 0; n < nCount; n++ )
188 ImplColorListData* pData = rBox.pColorList->GetObject( n );
189 USHORT nPos = InsertEntry( rBox.GetEntry( n ), LISTBOX_APPEND );
190 if ( nPos != LISTBOX_ERROR )
191 pColorList->Insert( new ImplColorListData( *pData ), nPos );
195 // -----------------------------------------------------------------------
197 USHORT ColorListBox::GetEntryPos( const Color& rColor ) const
199 for( USHORT n = (USHORT) pColorList->Count(); n; )
201 ImplColorListData* pData = pColorList->GetObject( --n );
202 if ( pData->bColor && ( pData->aColor == rColor ) )
203 return n;
205 return LISTBOX_ENTRY_NOTFOUND;
208 // -----------------------------------------------------------------------
210 Color ColorListBox::GetEntryColor( USHORT nPos ) const
212 Color aColor;
213 ImplColorListData* pData = pColorList->GetObject( nPos );
214 if ( pData && pData->bColor )
215 aColor = pData->aColor;
216 return aColor;
219 // -----------------------------------------------------------------------
221 void ColorListBox::UserDraw( const UserDrawEvent& rUDEvt )
223 ImplColorListData* pData = pColorList->GetObject( rUDEvt.GetItemId() );
224 if ( pData )
226 if ( pData->bColor )
228 Point aPos( rUDEvt.GetRect().TopLeft() );
229 aPos.X() += 2;
230 aPos.Y() += ( rUDEvt.GetRect().GetHeight() - aImageSize.Height() ) / 2;
231 rUDEvt.GetDevice()->Push();
232 rUDEvt.GetDevice()->SetFillColor( pData->aColor );
233 rUDEvt.GetDevice()->SetLineColor( rUDEvt.GetDevice()->GetTextColor() );
234 rUDEvt.GetDevice()->DrawRect( Rectangle( aPos, aImageSize ) );
235 rUDEvt.GetDevice()->Pop();
236 ListBox::DrawEntry( rUDEvt, FALSE, TRUE, FALSE );
238 else
239 ListBox::DrawEntry( rUDEvt, FALSE, TRUE, TRUE );
241 else
242 ListBox::DrawEntry( rUDEvt, TRUE, TRUE, FALSE );
245 // =======================================================================
246 // LineListBox
247 // =======================================================================
249 // -------------------
250 // - ImpListListData -
251 // -------------------
253 struct ImpLineListData
255 long nLine1;
256 long nLine2;
257 long nDistance;
260 DECLARE_LIST( ImpLineList, ImpLineListData* )
262 // -----------------------------------------------------------------------
264 inline const Color& LineListBox::GetPaintColor( void ) const
266 return maPaintCol;
269 // -----------------------------------------------------------------------
271 void LineListBox::ImpGetLine( long nLine1, long nLine2, long nDistance,
272 Bitmap& rBmp, XubString& rStr )
274 Size aSize = GetOutputSizePixel();
275 aSize.Width() -= 20;
276 aSize.Width() -= aTxtSize.Width();
277 aSize.Height() = aTxtSize.Height();
279 // SourceUnit nach Twips
280 if ( eSourceUnit == FUNIT_POINT )
282 nLine1 *= 20;
283 nLine2 *= 20;
284 nDistance *= 20;
286 else if ( eSourceUnit == FUNIT_MM )
288 nLine1 *= 14440;
289 nLine1 /= 254;
290 nLine2 *= 14440;
291 nLine2 /= 254;
292 nDistance *= 14440;
293 nDistance /= 254;
296 // Linien malen
297 aSize = aVirDev.PixelToLogic( aSize );
298 long nPix = aVirDev.PixelToLogic( Size( 0, 1 ) ).Height();
299 long n1 = nLine1 / 100;
300 long n2 = nLine2 / 100;
301 long nDist = nDistance / 100;
302 n1 += nPix-1;
303 n1 -= n1%nPix;
304 if ( n2 )
306 nDist += nPix-1;
307 nDist -= nDist%nPix;
308 n2 += nPix-1;
309 n2 -= n2%nPix;
311 long nVirHeight = n1+nDist+n2;
312 if ( nVirHeight > aSize.Height() )
313 aSize.Height() = nVirHeight;
314 // negative Breiten muss und darf man nicht painten
315 if ( aSize.Width() > 0 )
317 Size aVirSize = aVirDev.LogicToPixel( aSize );
318 if ( aVirDev.GetOutputSizePixel() != aVirSize )
319 aVirDev.SetOutputSizePixel( aVirSize );
320 aVirDev.SetFillColor( GetSettings().GetStyleSettings().GetFieldColor() );
321 aVirDev.DrawRect( Rectangle( Point(), aSize ) );
323 aVirDev.SetFillColor( GetPaintColor() );
324 aVirDev.DrawRect( Rectangle( 0, 0, aSize.Width(), n1-nPix ) );
325 if ( n2 )
327 aVirDev.DrawRect( Rectangle( 0, n1+nDist,
328 aSize.Width(), n1+nDist+n2-nPix ) );
330 rBmp = aVirDev.GetBitmap( Point(), Size( aSize.Width(), n1+nDist+n2 ) );
332 // Twips nach Unit
333 if ( eUnit == FUNIT_POINT )
335 nLine1 /= 20;
336 nLine2 /= 20;
337 nDistance /= 20;
338 rStr.AssignAscii( " pt" );
340 else if ( eUnit == FUNIT_MM )
342 nLine1 *= 254;
343 nLine1 /= 14400;
344 nLine2 *= 254;
345 nLine2 /= 14400;
346 nDistance *= 254;
347 nDistance /= 14400;
348 rStr.AssignAscii( " mm" );
351 String aNum( GetSettings().GetLocaleI18nHelper().GetNum( nLine1+nLine2+nDistance, 2 ) );
352 rStr.Insert( aNum, 0 );
355 // -----------------------------------------------------------------------
357 void LineListBox::ImplInit()
359 aTxtSize.Width() = GetTextWidth( XubString( RTL_CONSTASCII_USTRINGPARAM( "99,99 mm" ) ) );
360 aTxtSize.Height() = GetTextHeight();
361 pLineList = new ImpLineList;
362 eUnit = FUNIT_POINT;
363 eSourceUnit = FUNIT_POINT;
365 aVirDev.SetLineColor();
366 aVirDev.SetMapMode( MapMode( MAP_TWIP ) );
368 UpdatePaintLineColor();
371 // -----------------------------------------------------------------------
373 LineListBox::LineListBox( Window* pParent, WinBits nWinStyle ) :
374 ListBox( pParent, nWinStyle ),
375 aColor( COL_BLACK ),
376 maPaintCol( COL_BLACK )
378 ImplInit();
381 // -----------------------------------------------------------------------
383 LineListBox::LineListBox( Window* pParent, const ResId& rResId ) :
384 ListBox( pParent, rResId ),
385 aColor( COL_BLACK ),
386 maPaintCol( COL_BLACK )
388 ImplInit();
391 // -----------------------------------------------------------------------
393 LineListBox::~LineListBox()
395 ULONG n = 0;
396 ULONG nCount = pLineList->Count();
397 while ( n < nCount )
399 ImpLineListData* pData = pLineList->GetObject( n );
400 if ( pData )
401 delete pData;
402 n++;
404 delete pLineList;
407 // -----------------------------------------------------------------------
409 USHORT LineListBox::InsertEntry( const XubString& rStr, USHORT nPos )
411 nPos = ListBox::InsertEntry( rStr, nPos );
412 if ( nPos != LISTBOX_ERROR )
413 pLineList->Insert( NULL, nPos );
414 return nPos;
417 // -----------------------------------------------------------------------
419 USHORT LineListBox::InsertEntry( long nLine1, long nLine2, long nDistance,
420 USHORT nPos )
422 XubString aStr;
423 Bitmap aBmp;
424 ImpGetLine( nLine1, nLine2, nDistance, aBmp, aStr );
425 nPos = ListBox::InsertEntry( aStr, aBmp, nPos );
426 if ( nPos != LISTBOX_ERROR )
428 ImpLineListData* pData = new ImpLineListData;
429 pData->nLine1 = nLine1;
430 pData->nLine2 = nLine2;
431 pData->nDistance = nDistance;
432 pLineList->Insert( pData, nPos );
435 return nPos;
438 // -----------------------------------------------------------------------
440 void LineListBox::RemoveEntry( USHORT nPos )
442 ListBox::RemoveEntry( nPos );
443 ImpLineListData* pData = pLineList->Remove( nPos );
444 if ( pData )
445 delete pData;
448 // -----------------------------------------------------------------------
450 void LineListBox::Clear()
452 ULONG n = 0;
453 ULONG nCount = pLineList->Count();
454 while ( n < nCount )
456 ImpLineListData* pData = pLineList->GetObject( n );
457 if ( pData )
458 delete pData;
459 n++;
462 pLineList->Clear();
463 ListBox::Clear();
466 // -----------------------------------------------------------------------
468 USHORT LineListBox::GetEntryPos( long nLine1, long nLine2,
469 long nDistance ) const
471 ULONG n = 0;
472 ULONG nCount = pLineList->Count();
473 while ( n < nCount )
475 ImpLineListData* pData = pLineList->GetObject( n );
476 if ( pData )
478 if ( (pData->nLine1 == nLine1) &&
479 (pData->nLine2 == nLine2) &&
480 (pData->nDistance == nDistance) )
481 return (USHORT)n;
484 n++;
487 return LISTBOX_ENTRY_NOTFOUND;
490 // -----------------------------------------------------------------------
492 long LineListBox::GetEntryLine1( USHORT nPos ) const
494 ImpLineListData* pData = pLineList->GetObject( nPos );
495 if ( pData )
496 return pData->nLine1;
497 else
498 return 0;
501 // -----------------------------------------------------------------------
503 long LineListBox::GetEntryLine2( USHORT nPos ) const
505 ImpLineListData* pData = pLineList->GetObject( nPos );
506 if ( pData )
507 return pData->nLine2;
508 else
509 return 0;
512 // -----------------------------------------------------------------------
514 long LineListBox::GetEntryDistance( USHORT nPos ) const
516 ImpLineListData* pData = pLineList->GetObject( nPos );
517 if ( pData )
518 return pData->nDistance;
519 else
520 return 0;
523 // -----------------------------------------------------------------------
525 void LineListBox::UpdateLineColors( void )
527 if( UpdatePaintLineColor() )
529 ULONG nCount = pLineList->Count();
530 if( !nCount )
531 return;
533 XubString aStr;
534 Bitmap aBmp;
536 // exchange entries which containing lines
537 SetUpdateMode( FALSE );
539 USHORT nSelEntry = GetSelectEntryPos();
540 for( ULONG n = 0 ; n < nCount ; ++n )
542 ImpLineListData* pData = pLineList->GetObject( n );
543 if( pData )
545 // exchange listbox data
546 ListBox::RemoveEntry( USHORT( n ) );
547 ImpGetLine( pData->nLine1, pData->nLine2, pData->nDistance, aBmp, aStr );
548 ListBox::InsertEntry( aStr, aBmp, USHORT( n ) );
552 if( nSelEntry != LISTBOX_ENTRY_NOTFOUND )
553 SelectEntryPos( nSelEntry );
555 SetUpdateMode( TRUE );
556 Invalidate();
560 // -----------------------------------------------------------------------
562 BOOL LineListBox::UpdatePaintLineColor( void )
564 BOOL bRet = TRUE;
565 const StyleSettings& rSettings = GetSettings().GetStyleSettings();
566 Color aNewCol( rSettings.GetWindowColor().IsDark()? rSettings.GetLabelTextColor() : aColor );
568 bRet = aNewCol != maPaintCol;
570 if( bRet )
571 maPaintCol = aNewCol;
573 return bRet;
576 // -----------------------------------------------------------------------
578 void LineListBox::DataChanged( const DataChangedEvent& rDCEvt )
580 ListBox::DataChanged( rDCEvt );
582 if( ( rDCEvt.GetType() == DATACHANGED_SETTINGS ) && ( rDCEvt.GetFlags() & SETTINGS_STYLE ) )
583 UpdateLineColors();
586 // ===================================================================
587 // FontNameBox
588 // ===================================================================
590 struct ImplFontNameListData
592 FontInfo maInfo;
593 USHORT mnType;
595 ImplFontNameListData( const FontInfo& rInfo,
596 USHORT nType ) :
597 maInfo( rInfo ),
598 mnType( nType )
602 DECLARE_LIST( ImplFontList, ImplFontNameListData* )
604 // -------------------------------------------------------------------
606 FontNameBox::FontNameBox( Window* pParent, WinBits nWinStyle ) :
607 ComboBox( pParent, nWinStyle )
609 InitBitmaps();
610 mpFontList = NULL;
611 mbWYSIWYG = FALSE;
612 mbSymbols = FALSE;
615 // -------------------------------------------------------------------
617 FontNameBox::FontNameBox( Window* pParent, const ResId& rResId ) :
618 ComboBox( pParent, rResId )
620 InitBitmaps();
621 mpFontList = NULL;
622 mbWYSIWYG = FALSE;
623 mbSymbols = FALSE;
626 // -------------------------------------------------------------------
628 FontNameBox::~FontNameBox()
630 ImplDestroyFontList();
633 // -------------------------------------------------------------------
635 void FontNameBox::DataChanged( const DataChangedEvent& rDCEvt )
637 ComboBox::DataChanged( rDCEvt );
639 if( rDCEvt.GetType() == DATACHANGED_SETTINGS && ( rDCEvt.GetFlags() & SETTINGS_STYLE ) )
640 InitBitmaps();
643 // -------------------------------------------------------------------
645 void FontNameBox::InitBitmaps( void )
647 Color aCol = GetSettings().GetStyleSettings().GetWindowColor();
648 BOOL bHC = aCol.IsDark();
650 maImagePrinterFont = Image( SvtResId( bHC? RID_IMG_PRINTERFONT_HC : RID_IMG_PRINTERFONT ) );
651 maImageBitmapFont = Image( SvtResId( bHC? RID_IMG_BITMAPFONT_HC : RID_IMG_BITMAPFONT ) );
652 maImageScalableFont = Image( SvtResId( bHC? RID_IMG_SCALABLEFONT_HC : RID_IMG_SCALABLEFONT ) );
655 // -------------------------------------------------------------------
657 void FontNameBox::ImplDestroyFontList()
659 if ( mpFontList )
661 ImplFontNameListData* pInfo = mpFontList->First();
662 while ( pInfo )
664 delete pInfo;
665 pInfo = mpFontList->Next();
667 delete mpFontList;
671 // -------------------------------------------------------------------
673 void FontNameBox::Fill( const FontList* pList )
675 // store old text and clear box
676 XubString aOldText = GetText();
677 Clear();
679 ImplDestroyFontList();
680 mpFontList = new ImplFontList;
682 // insert fonts
683 USHORT nFontCount = pList->GetFontNameCount();
684 for ( USHORT i = 0; i < nFontCount; i++ )
686 const FontInfo& rFontInfo = pList->GetFontName( i );
687 ULONG nIndex = InsertEntry( rFontInfo.GetName() );
688 if ( nIndex != LISTBOX_ERROR )
690 USHORT nType = pList->GetFontNameType( i );
691 ImplFontNameListData* pData = new ImplFontNameListData( rFontInfo, nType );
692 mpFontList->Insert( pData, nIndex );
696 ImplCalcUserItemSize();
698 // restore text
699 if ( aOldText.Len() )
700 SetText( aOldText );
703 // -------------------------------------------------------------------
705 void FontNameBox::EnableWYSIWYG( BOOL bEnable )
707 if ( bEnable != mbWYSIWYG )
709 mbWYSIWYG = bEnable;
710 EnableUserDraw( mbWYSIWYG | mbSymbols );
711 ImplCalcUserItemSize();
715 // -------------------------------------------------------------------
717 void FontNameBox::EnableSymbols( BOOL bEnable )
719 if ( bEnable != mbSymbols )
721 mbSymbols = bEnable;
722 EnableUserDraw( mbWYSIWYG | mbSymbols );
723 ImplCalcUserItemSize();
727 // -------------------------------------------------------------------
729 void FontNameBox::ImplCalcUserItemSize()
731 Size aUserItemSz;
732 if ( mbWYSIWYG && mpFontList )
734 USHORT nMaxLen = 0;
735 BOOL bSymbolFont = FALSE;
736 BOOL bStarSymbol = FALSE;
737 for ( USHORT n = GetEntryCount(); n; )
739 ImplFontNameListData* pData = mpFontList->GetObject( --n );
740 XubString aFontName = pData->maInfo.GetName();
741 if ( aFontName.Len() > nMaxLen )
742 nMaxLen = aFontName.Len();
743 if ( pData->maInfo.GetCharSet() == RTL_TEXTENCODING_SYMBOL )
744 bSymbolFont = TRUE;
745 // starsymbol is a unicode font, but gets WYSIWIG symbols
746 if( aFontName.EqualsIgnoreCaseAscii( "starsymbol" )
747 || aFontName.EqualsIgnoreCaseAscii( "opensymbol" ) )
748 bSymbolFont = bStarSymbol = TRUE;
751 // guess maximimum width
752 Size aOneCharSz( GetTextWidth( String( 'X' ) ), GetTextHeight() );
753 Size aSz( aOneCharSz );
754 aSz.Width() *= nMaxLen;
755 // only XX% of width, because ListBox calculates the normal width...
756 aSz.Width() *= 1;
757 aSz.Width() /= 10;
758 if ( bSymbolFont )
760 int nLength = sizeof(aImplSymbolFontText)/sizeof(aImplSymbolFontText[0]) - 1;
761 int nLength2 = sizeof(aImplStarSymbolText)/sizeof(aImplStarSymbolText[0]) - 1;
762 if( bStarSymbol && (nLength < nLength2) )
763 nLength = nLength2;
764 aSz.Width() += aOneCharSz.Width() * nLength;
766 aSz.Height() *= 14;
767 aSz.Height() /= 10;
768 aUserItemSz = aSz;
770 if ( mbSymbols )
772 Size aSz = maImageScalableFont.GetSizePixel();
773 aUserItemSz.Width() += aSz.Width() + IMGTEXTSPACE;
774 if ( aSz.Height() > aUserItemSz.Height() )
775 aUserItemSz.Height() = aSz.Height();
777 SetUserItemSize( aUserItemSz );
780 // -------------------------------------------------------------------
782 void FontNameBox::UserDraw( const UserDrawEvent& rUDEvt )
784 ImplFontNameListData* pData = mpFontList->GetObject( rUDEvt.GetItemId() );
785 const FontInfo& rInfo = pData->maInfo;
786 USHORT nType = pData->mnType;
787 Point aTopLeft = rUDEvt.GetRect().TopLeft();
788 long nX = aTopLeft.X();
789 long nH = rUDEvt.GetRect().GetHeight();
791 if ( mbSymbols )
793 nX += IMGTEXTSPACE;
794 Image* pImg = NULL;
795 if ( (nType & (FONTLIST_FONTNAMETYPE_PRINTER | FONTLIST_FONTNAMETYPE_SCREEN)) == FONTLIST_FONTNAMETYPE_PRINTER )
796 pImg = &maImagePrinterFont;
797 else if ( nType & FONTLIST_FONTNAMETYPE_SCALABLE )
798 pImg = &maImageScalableFont;
799 else
800 pImg = &maImageBitmapFont;
802 if ( pImg )
804 Point aPos( nX, aTopLeft.Y() + (nH-pImg->GetSizePixel().Height())/2 );
805 rUDEvt.GetDevice()->DrawImage( aPos, *pImg );
808 // X immer um gleiche Breite aendern, auch wenn kein Image ausgegeben.
809 nX += maImagePrinterFont.GetSizePixel().Width();
812 if ( mbWYSIWYG && mpFontList )
814 nX += IMGTEXTSPACE;
816 bool bSymbolFont = (rInfo.GetCharSet() == RTL_TEXTENCODING_SYMBOL);
817 // starsymbol is a unicode font, but cannot display its own name
818 const bool bOpenSymbol = rInfo.GetName().EqualsIgnoreCaseAscii( "starsymbol" )
819 || rInfo.GetName().EqualsIgnoreCaseAscii( "opensymbol" );
820 bSymbolFont |= bOpenSymbol;
822 if( bSymbolFont )
824 String aText( rInfo.GetName() );
825 aText.AppendAscii( " " );
826 Point aPos( nX, aTopLeft.Y() + (nH-rUDEvt.GetDevice()->GetTextHeight())/2 );
827 rUDEvt.GetDevice()->DrawText( aPos, aText );
828 nX += rUDEvt.GetDevice()->GetTextWidth( aText );
831 Color aTextColor = rUDEvt.GetDevice()->GetTextColor();
832 Font aOldFont( rUDEvt.GetDevice()->GetFont() );
833 Size aSize( aOldFont.GetSize() );
834 aSize.Height() += EXTRAFONTSIZE;
835 Font aFont( rInfo );
836 aFont.SetSize( aSize );
837 rUDEvt.GetDevice()->SetFont( aFont );
838 rUDEvt.GetDevice()->SetTextColor( aTextColor );
840 FontCharMap aFontCharMap;
841 bool bHasCharMap = rUDEvt.GetDevice()->GetFontCharMap( aFontCharMap );
843 String aString;
844 if( !bSymbolFont )
846 // preview the font name
847 aString = rInfo.GetName();
849 // reset font if the name cannot be display in the preview font
850 if( STRING_LEN != rUDEvt.GetDevice()->HasGlyphs( aFont, aString ) )
851 rUDEvt.GetDevice()->SetFont( aOldFont );
853 else if( bHasCharMap )
855 // use some sample characters available in the font
856 sal_Unicode aText[8];
858 // start just above the PUA used by most symbol fonts
859 sal_uInt32 cNewChar = 0xFF00;
860 #ifdef QUARTZ
861 // on MacOSX there are too many non-presentable symbols above the codepoint 0x0192
862 if( !bOpenSymbol )
863 cNewChar = 0x0192;
864 #endif
865 const int nMaxCount = sizeof(aText)/sizeof(*aText) - 1;
866 int nSkip = aFontCharMap.GetCharCount() / nMaxCount;
867 if( nSkip > 10 )
868 nSkip = 10;
869 else if( nSkip <= 0 )
870 nSkip = 1;
871 for( int i = 0; i < nMaxCount; ++i )
873 sal_uInt32 cOldChar = cNewChar;
874 for( int j = nSkip; --j >= 0; )
875 cNewChar = aFontCharMap.GetPrevChar( cNewChar );
876 if( cOldChar == cNewChar )
877 break;
878 aText[ i ] = static_cast<sal_Unicode>(cNewChar); // TODO: support UCS4 samples
879 aText[ i+1 ] = 0;
882 aString = String( aText );
884 else
886 const sal_Unicode* pText = aImplSymbolFontText;
887 if( bOpenSymbol )
888 pText = aImplStarSymbolText;
890 aString = String( pText );
893 long nTextHeight = rUDEvt.GetDevice()->GetTextHeight();
894 Point aPos( nX, aTopLeft.Y() + (nH-nTextHeight)/2 );
895 rUDEvt.GetDevice()->DrawText( aPos, aString );
897 rUDEvt.GetDevice()->SetFont( aOldFont );
898 DrawEntry( rUDEvt, FALSE, FALSE); // draw seperator
900 else
902 DrawEntry( rUDEvt, TRUE, TRUE );
906 // ===================================================================
907 // FontStyleBox
908 // ===================================================================
910 FontStyleBox::FontStyleBox( Window* pParent, WinBits nWinStyle ) :
911 ComboBox( pParent, nWinStyle )
915 // -------------------------------------------------------------------
917 FontStyleBox::FontStyleBox( Window* pParent, const ResId& rResId ) :
918 ComboBox( pParent, rResId )
920 aLastStyle = GetText();
923 // -------------------------------------------------------------------
925 FontStyleBox::~FontStyleBox()
929 // -------------------------------------------------------------------
931 void FontStyleBox::Select()
933 // keep text over fill operation
934 aLastStyle = GetText();
935 ComboBox::Select();
938 // -------------------------------------------------------------------
940 void FontStyleBox::LoseFocus()
942 // keep text over fill operation
943 aLastStyle = GetText();
944 ComboBox::LoseFocus();
947 // -------------------------------------------------------------------
949 void FontStyleBox::Modify()
951 CharClass aChrCls( ::comphelper::getProcessServiceFactory(),
952 GetSettings().GetLocale() );
953 XubString aStr = GetText();
954 USHORT nEntryCount = GetEntryCount();
956 if ( GetEntryPos( aStr ) == COMBOBOX_ENTRY_NOTFOUND )
958 aChrCls.toUpper( aStr );
959 for ( USHORT i = 0; i < nEntryCount; i++ )
961 XubString aEntryText = GetEntry( i );
962 aChrCls.toUpper( aEntryText );
964 if ( aStr == aEntryText )
966 SetText( GetEntry( i ) );
967 break;
972 ComboBox::Modify();
975 // -------------------------------------------------------------------
977 void FontStyleBox::Fill( const XubString& rName, const FontList* pList )
979 // note: this method must call ComboBox::SetText(),
980 // else aLastStyle will overwritten
981 // store prior selection position and clear box
982 XubString aOldText = GetText();
983 USHORT nPos = GetEntryPos( aOldText );
984 Clear();
986 // does a font with this name already exist?
987 sal_Handle hFontInfo = pList->GetFirstFontInfo( rName );
988 if ( hFontInfo )
990 XubString aStyleText;
991 FontWeight eLastWeight = WEIGHT_DONTKNOW;
992 FontItalic eLastItalic = ITALIC_NONE;
993 FontWidth eLastWidth = WIDTH_DONTKNOW;
994 BOOL bNormal = FALSE;
995 BOOL bItalic = FALSE;
996 BOOL bBold = FALSE;
997 BOOL bBoldItalic = FALSE;
998 BOOL bInsert = FALSE;
999 FontInfo aInfo;
1000 while ( hFontInfo )
1002 aInfo = pList->GetFontInfo( hFontInfo );
1004 FontWeight eWeight = aInfo.GetWeight();
1005 FontItalic eItalic = aInfo.GetItalic();
1006 FontWidth eWidth = aInfo.GetWidthType();
1007 // Only if the attributes are different, we insert the
1008 // Font to avoid double Entries in different languages
1009 if ( (eWeight != eLastWeight) || (eItalic != eLastItalic) ||
1010 (eWidth != eLastWidth) )
1012 if ( bInsert )
1013 InsertEntry( aStyleText );
1015 if ( eWeight <= WEIGHT_NORMAL )
1017 if ( eItalic != ITALIC_NONE )
1018 bItalic = TRUE;
1019 else
1020 bNormal = TRUE;
1022 else
1024 if ( eItalic != ITALIC_NONE )
1025 bBoldItalic = TRUE;
1026 else
1027 bBold = TRUE;
1030 // For wrong StyleNames we replace this with the correct once
1031 aStyleText = pList->GetStyleName( aInfo );
1032 bInsert = GetEntryPos( aStyleText ) == LISTBOX_ENTRY_NOTFOUND;
1033 if ( !bInsert )
1035 aStyleText = pList->GetStyleName( eWeight, eItalic );
1036 bInsert = GetEntryPos( aStyleText ) == LISTBOX_ENTRY_NOTFOUND;
1039 eLastWeight = eWeight;
1040 eLastItalic = eItalic;
1041 eLastWidth = eWidth;
1043 else
1045 if ( bInsert )
1047 // If we have two names for the same attributes
1048 // we prefer the translated standard names
1049 const XubString& rAttrStyleText = pList->GetStyleName( eWeight, eItalic );
1050 if ( rAttrStyleText != aStyleText )
1052 XubString aTempStyleText = pList->GetStyleName( aInfo );
1053 if ( rAttrStyleText == aTempStyleText )
1054 aStyleText = rAttrStyleText;
1055 bInsert = GetEntryPos( aStyleText ) == LISTBOX_ENTRY_NOTFOUND;
1060 if ( !bItalic && (aStyleText == pList->GetItalicStr()) )
1061 bItalic = TRUE;
1062 else if ( !bBold && (aStyleText == pList->GetBoldStr()) )
1063 bBold = TRUE;
1064 else if ( !bBoldItalic && (aStyleText == pList->GetBoldItalicStr()) )
1065 bBoldItalic = TRUE;
1067 hFontInfo = pList->GetNextFontInfo( hFontInfo );
1070 if ( bInsert )
1071 InsertEntry( aStyleText );
1073 // Bestimmte Styles als Nachbildung
1074 if ( bNormal )
1076 if ( !bItalic )
1077 InsertEntry( pList->GetItalicStr() );
1078 if ( !bBold )
1079 InsertEntry( pList->GetBoldStr() );
1081 if ( !bBoldItalic )
1083 if ( bNormal || bItalic || bBold )
1084 InsertEntry( pList->GetBoldItalicStr() );
1086 if ( aOldText.Len() )
1088 if ( GetEntryPos( aLastStyle ) != LISTBOX_ENTRY_NOTFOUND )
1089 ComboBox::SetText( aLastStyle );
1090 else
1092 if ( nPos >= GetEntryCount() )
1093 ComboBox::SetText( GetEntry( 0 ) );
1094 else
1095 ComboBox::SetText( GetEntry( nPos ) );
1099 else
1101 // Wenn Font nicht, dann Standard-Styles einfuegen
1102 InsertEntry( pList->GetNormalStr() );
1103 InsertEntry( pList->GetItalicStr() );
1104 InsertEntry( pList->GetBoldStr() );
1105 InsertEntry( pList->GetBoldItalicStr() );
1106 if ( aOldText.Len() )
1108 if ( nPos > GetEntryCount() )
1109 ComboBox::SetText( GetEntry( 0 ) );
1110 else
1111 ComboBox::SetText( GetEntry( nPos ) );
1116 // ===================================================================
1117 // FontSizeBox
1118 // ===================================================================
1120 FontSizeBox::FontSizeBox( Window* pParent, WinBits nWinSize ) :
1121 MetricBox( pParent, nWinSize )
1123 ImplInit();
1126 // -----------------------------------------------------------------------
1128 FontSizeBox::FontSizeBox( Window* pParent, const ResId& rResId ) :
1129 MetricBox( pParent, rResId )
1131 ImplInit();
1134 // -----------------------------------------------------------------------
1136 FontSizeBox::~FontSizeBox()
1140 // -----------------------------------------------------------------------
1142 void FontSizeBox::ImplInit()
1144 EnableAutocomplete( FALSE );
1146 bRelativeMode = FALSE;
1147 bPtRelative = FALSE;
1148 bRelative = FALSE;
1149 bStdSize = FALSE;
1150 pFontList = NULL;
1152 SetShowTrailingZeros( FALSE );
1153 SetDecimalDigits( 1 );
1154 SetMin( 20 );
1155 SetMax( 9999 );
1158 // -----------------------------------------------------------------------
1160 void FontSizeBox::Reformat()
1162 FontSizeNames aFontSizeNames( GetSettings().GetUILanguage() );
1163 if ( !bRelativeMode || !aFontSizeNames.IsEmpty() )
1165 long nNewValue = aFontSizeNames.Name2Size( GetText() );
1166 if ( nNewValue)
1168 mnLastValue = nNewValue;
1169 return;
1173 MetricBox::Reformat();
1176 // -----------------------------------------------------------------------
1178 void FontSizeBox::Modify()
1180 MetricBox::Modify();
1182 if ( bRelativeMode )
1184 XubString aStr = GetText();
1185 aStr.EraseLeadingChars();
1187 BOOL bNewMode = bRelative;
1188 BOOL bOldPtRelMode = bPtRelative;
1190 if ( bRelative )
1192 bPtRelative = FALSE;
1193 const xub_Unicode* pStr = aStr.GetBuffer();
1194 while ( *pStr )
1196 if ( ((*pStr < '0') || (*pStr > '9')) && (*pStr != '%') )
1198 if ( ('-' == *pStr || '+' == *pStr) && !bPtRelative )
1199 bPtRelative = TRUE;
1200 else if ( bPtRelative && 'p' == *pStr && 't' == *++pStr )
1202 else
1204 bNewMode = FALSE;
1205 break;
1208 pStr++;
1211 else
1213 if ( STRING_NOTFOUND != aStr.Search( '%' ) )
1215 bNewMode = TRUE;
1216 bPtRelative = FALSE;
1219 if ( '-' == aStr.GetChar( 0 ) || '+' == aStr.GetChar( 0 ) )
1221 bNewMode = TRUE;
1222 bPtRelative = TRUE;
1226 if ( bNewMode != bRelative || bPtRelative != bOldPtRelMode )
1227 SetRelative( bNewMode );
1231 // -----------------------------------------------------------------------
1233 void FontSizeBox::Fill( const FontInfo* pInfo, const FontList* pList )
1235 // remember for relative mode
1236 pFontList = pList;
1238 // no font sizes need to be set for relative mode
1239 if ( bRelative )
1240 return;
1242 // query font sizes
1243 const long* pTempAry;
1244 const long* pAry = 0;
1246 if( pInfo )
1248 aFontInfo = *pInfo;
1249 pAry = pList->GetSizeAry( *pInfo );
1251 else
1253 pAry = pList->GetStdSizeAry();
1256 // first insert font size names (for simplified/traditional chinese)
1257 FontSizeNames aFontSizeNames( GetSettings().GetUILanguage() );
1258 if ( pAry == pList->GetStdSizeAry() )
1260 // for standard sizes we don't need to bother
1261 if ( bStdSize && GetEntryCount() && aFontSizeNames.IsEmpty() )
1262 return;
1263 bStdSize = TRUE;
1265 else
1266 bStdSize = FALSE;
1268 Selection aSelection = GetSelection();
1269 XubString aStr = GetText();
1271 Clear();
1272 USHORT nPos = 0;
1274 if ( !aFontSizeNames.IsEmpty() )
1276 if ( pAry == pList->GetStdSizeAry() )
1278 // for scalable fonts all font size names
1279 ULONG nCount = aFontSizeNames.Count();
1280 for( ULONG i = 0; i < nCount; i++ )
1282 String aSizeName = aFontSizeNames.GetIndexName( i );
1283 long nSize = aFontSizeNames.GetIndexSize( i );
1284 ComboBox::InsertEntry( aSizeName, nPos );
1285 ComboBox::SetEntryData( nPos, (void*)(-nSize) ); // mark as special
1286 nPos++;
1289 else
1291 // for fixed size fonts only selectable font size names
1292 pTempAry = pAry;
1293 while ( *pTempAry )
1295 String aSizeName = aFontSizeNames.Size2Name( *pTempAry );
1296 if ( aSizeName.Len() )
1298 ComboBox::InsertEntry( aSizeName, nPos );
1299 ComboBox::SetEntryData( nPos, (void*)(-(*pTempAry)) ); // mark as special
1300 nPos++;
1302 pTempAry++;
1307 // then insert numerical font size values
1308 pTempAry = pAry;
1309 while ( *pTempAry )
1311 InsertValue( *pTempAry, FUNIT_NONE, nPos );
1312 ComboBox::SetEntryData( nPos, (void*)(*pTempAry) );
1313 nPos++;
1314 pTempAry++;
1317 SetText( aStr );
1318 SetSelection( aSelection );
1321 // -----------------------------------------------------------------------
1323 void FontSizeBox::EnableRelativeMode( USHORT nMin, USHORT nMax, USHORT nStep )
1325 bRelativeMode = TRUE;
1326 nRelMin = nMin;
1327 nRelMax = nMax;
1328 nRelStep = nStep;
1329 SetUnit( FUNIT_POINT );
1332 // -----------------------------------------------------------------------
1334 void FontSizeBox::EnablePtRelativeMode( short nMin, short nMax, short nStep )
1336 bRelativeMode = TRUE;
1337 nPtRelMin = nMin;
1338 nPtRelMax = nMax;
1339 nPtRelStep = nStep;
1340 SetUnit( FUNIT_POINT );
1343 // -----------------------------------------------------------------------
1345 void FontSizeBox::SetRelative( BOOL bNewRelative )
1347 if ( bRelativeMode )
1349 Selection aSelection = GetSelection();
1350 XubString aStr = GetText();
1351 aStr.EraseLeadingChars();
1353 if ( bNewRelative )
1355 bRelative = TRUE;
1356 bStdSize = FALSE;
1358 if ( bPtRelative )
1360 SetDecimalDigits( 1 );
1361 SetMin( nPtRelMin );
1362 SetMax( nPtRelMax );
1363 SetUnit( FUNIT_POINT );
1365 Clear();
1367 short i = nPtRelMin, n = 0;
1368 // JP 30.06.98: more than 100 values are not useful
1369 while ( i <= nPtRelMax && n++ < 100 )
1371 InsertValue( i );
1372 i = i + nPtRelStep;
1375 else
1377 SetDecimalDigits( 0 );
1378 SetMin( nRelMin );
1379 SetMax( nRelMax );
1380 SetCustomUnitText( '%' );
1381 SetUnit( FUNIT_CUSTOM );
1383 Clear();
1384 USHORT i = nRelMin;
1385 while ( i <= nRelMax )
1387 InsertValue( i );
1388 i = i + nRelStep;
1392 else
1394 bRelative = bPtRelative = FALSE;
1395 SetDecimalDigits( 1 );
1396 SetMin( 20 );
1397 SetMax( 9999 );
1398 SetUnit( FUNIT_POINT );
1399 if ( pFontList )
1400 Fill( &aFontInfo, pFontList );
1403 SetText( aStr );
1404 SetSelection( aSelection );
1408 // -----------------------------------------------------------------------
1410 XubString FontSizeBox::CreateFieldText( sal_Int64 nValue ) const
1412 XubString sRet( MetricBox::CreateFieldText( nValue ) );
1413 if ( bRelativeMode && bPtRelative && (0 <= nValue) && sRet.Len() )
1414 sRet.Insert( '+', 0 );
1415 return sRet;
1418 // -----------------------------------------------------------------------
1420 void FontSizeBox::SetValue( sal_Int64 nNewValue, FieldUnit eInUnit )
1422 if ( !bRelative )
1424 sal_Int64 nTempValue = MetricField::ConvertValue( nNewValue, GetBaseValue(), GetDecimalDigits(), eInUnit, GetUnit() );
1425 FontSizeNames aFontSizeNames( GetSettings().GetUILanguage() );
1426 // conversion loses precision; however font sizes should
1427 // never have a problem with that
1428 String aName = aFontSizeNames.Size2Name( static_cast<long>(nTempValue) );
1429 if ( aName.Len() && (GetEntryPos( aName ) != LISTBOX_ENTRY_NOTFOUND) )
1431 mnLastValue = nTempValue;
1432 SetText( aName );
1433 mnFieldValue = mnLastValue;
1434 SetEmptyFieldValueData( FALSE );
1435 return;
1439 MetricBox::SetValue( nNewValue, eInUnit );
1442 // -----------------------------------------------------------------------
1444 void FontSizeBox::SetValue( sal_Int64 nNewValue )
1446 SetValue( nNewValue, FUNIT_NONE );
1449 // -----------------------------------------------------------------------
1451 sal_Int64 FontSizeBox::GetValue( USHORT nPos, FieldUnit eOutUnit ) const
1453 if ( !bRelative )
1455 sal_Int64 nComboVal = static_cast<sal_Int64>(reinterpret_cast<long>(ComboBox::GetEntryData( nPos )));
1456 if ( nComboVal < 0 ) // marked as special?
1458 return MetricField::ConvertValue( -nComboVal, mnBaseValue, GetDecimalDigits(),
1459 meUnit, eOutUnit );
1463 // do normal font size processing
1464 sal_Int64 nRetValue = MetricBox::GetValue( nPos, eOutUnit );
1465 return nRetValue;
1468 // -----------------------------------------------------------------------
1470 sal_Int64 FontSizeBox::GetValue( FieldUnit eOutUnit ) const
1472 if ( !bRelative )
1474 FontSizeNames aFontSizeNames( GetSettings().GetUILanguage() );
1475 sal_Int64 nValue = aFontSizeNames.Name2Size( GetText() );
1476 if ( nValue)
1477 return MetricField::ConvertValue( nValue, GetBaseValue(), GetDecimalDigits(), GetUnit(), eOutUnit );
1480 return MetricBox::GetValue( eOutUnit );
1483 // -----------------------------------------------------------------------
1485 sal_Int64 FontSizeBox::GetValue() const
1487 // implementation not inline, because it is a virtual function
1488 return GetValue( FUNIT_NONE );
1491 // -----------------------------------------------------------------------
1493 void FontSizeBox::SetUserValue( sal_Int64 nNewValue, FieldUnit eInUnit )
1495 if ( !bRelative )
1497 sal_Int64 nTempValue = MetricField::ConvertValue( nNewValue, GetBaseValue(), GetDecimalDigits(), eInUnit, GetUnit() );
1498 FontSizeNames aFontSizeNames( GetSettings().GetUILanguage() );
1499 // conversion loses precision
1500 // however font sizes should never have a problem with that
1501 String aName = aFontSizeNames.Size2Name( static_cast<long>(nTempValue) );
1502 if ( aName.Len() && (GetEntryPos( aName ) != LISTBOX_ENTRY_NOTFOUND) )
1504 mnLastValue = nTempValue;
1505 SetText( aName );
1506 return;
1510 MetricBox::SetUserValue( nNewValue, eInUnit );