1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: ctrlbox.cxx,v $
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"
35 #include <tools/debug.hxx>
37 #include <vcl/svapp.hxx>
40 #include <vcl/field.hxx>
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 // ========================================================================
60 // ========================================================================
62 // --------------------
63 // - ImplColorListData -
64 // --------------------
66 struct ImplColorListData
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
);
102 // -----------------------------------------------------------------------
104 ColorListBox::ColorListBox( Window
* pParent
, WinBits nWinStyle
) :
105 ListBox( pParent
, nWinStyle
)
110 // -----------------------------------------------------------------------
112 ColorListBox::ColorListBox( Window
* pParent
, const ResId
& rResId
) :
113 ListBox( pParent
, rResId
)
118 // -----------------------------------------------------------------------
120 ColorListBox::~ColorListBox()
122 ImplDestroyColorEntries();
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
);
139 // -----------------------------------------------------------------------
141 USHORT
ColorListBox::InsertEntry( const Color
& rColor
, const XubString
& rStr
,
144 nPos
= ListBox::InsertEntry( rStr
, nPos
);
145 if ( nPos
!= LISTBOX_ERROR
)
147 ImplColorListData
* pData
= new ImplColorListData( rColor
);
148 pColorList
->Insert( pData
, 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();
177 // -----------------------------------------------------------------------
179 void ColorListBox::CopyEntries( const ColorListBox
& rBox
)
182 ImplDestroyColorEntries();
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
) )
205 return LISTBOX_ENTRY_NOTFOUND
;
208 // -----------------------------------------------------------------------
210 Color
ColorListBox::GetEntryColor( USHORT nPos
) const
213 ImplColorListData
* pData
= pColorList
->GetObject( nPos
);
214 if ( pData
&& pData
->bColor
)
215 aColor
= pData
->aColor
;
219 // -----------------------------------------------------------------------
221 void ColorListBox::UserDraw( const UserDrawEvent
& rUDEvt
)
223 ImplColorListData
* pData
= pColorList
->GetObject( rUDEvt
.GetItemId() );
228 Point
aPos( rUDEvt
.GetRect().TopLeft() );
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
);
239 ListBox::DrawEntry( rUDEvt
, FALSE
, TRUE
, TRUE
);
242 ListBox::DrawEntry( rUDEvt
, TRUE
, TRUE
, FALSE
);
245 // =======================================================================
247 // =======================================================================
249 // -------------------
250 // - ImpListListData -
251 // -------------------
253 struct ImpLineListData
260 DECLARE_LIST( ImpLineList
, ImpLineListData
* )
262 // -----------------------------------------------------------------------
264 inline const Color
& LineListBox::GetPaintColor( void ) const
269 // -----------------------------------------------------------------------
271 void LineListBox::ImpGetLine( long nLine1
, long nLine2
, long nDistance
,
272 Bitmap
& rBmp
, XubString
& rStr
)
274 Size aSize
= GetOutputSizePixel();
276 aSize
.Width() -= aTxtSize
.Width();
277 aSize
.Height() = aTxtSize
.Height();
279 // SourceUnit nach Twips
280 if ( eSourceUnit
== FUNIT_POINT
)
286 else if ( eSourceUnit
== FUNIT_MM
)
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;
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
) );
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
) );
333 if ( eUnit
== FUNIT_POINT
)
338 rStr
.AssignAscii( " pt" );
340 else if ( eUnit
== FUNIT_MM
)
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
;
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
),
376 maPaintCol( COL_BLACK
)
381 // -----------------------------------------------------------------------
383 LineListBox::LineListBox( Window
* pParent
, const ResId
& rResId
) :
384 ListBox( pParent
, rResId
),
386 maPaintCol( COL_BLACK
)
391 // -----------------------------------------------------------------------
393 LineListBox::~LineListBox()
396 ULONG nCount
= pLineList
->Count();
399 ImpLineListData
* pData
= pLineList
->GetObject( n
);
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
);
417 // -----------------------------------------------------------------------
419 USHORT
LineListBox::InsertEntry( long nLine1
, long nLine2
, long nDistance
,
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
);
438 // -----------------------------------------------------------------------
440 void LineListBox::RemoveEntry( USHORT nPos
)
442 ListBox::RemoveEntry( nPos
);
443 ImpLineListData
* pData
= pLineList
->Remove( nPos
);
448 // -----------------------------------------------------------------------
450 void LineListBox::Clear()
453 ULONG nCount
= pLineList
->Count();
456 ImpLineListData
* pData
= pLineList
->GetObject( n
);
466 // -----------------------------------------------------------------------
468 USHORT
LineListBox::GetEntryPos( long nLine1
, long nLine2
,
469 long nDistance
) const
472 ULONG nCount
= pLineList
->Count();
475 ImpLineListData
* pData
= pLineList
->GetObject( n
);
478 if ( (pData
->nLine1
== nLine1
) &&
479 (pData
->nLine2
== nLine2
) &&
480 (pData
->nDistance
== nDistance
) )
487 return LISTBOX_ENTRY_NOTFOUND
;
490 // -----------------------------------------------------------------------
492 long LineListBox::GetEntryLine1( USHORT nPos
) const
494 ImpLineListData
* pData
= pLineList
->GetObject( nPos
);
496 return pData
->nLine1
;
501 // -----------------------------------------------------------------------
503 long LineListBox::GetEntryLine2( USHORT nPos
) const
505 ImpLineListData
* pData
= pLineList
->GetObject( nPos
);
507 return pData
->nLine2
;
512 // -----------------------------------------------------------------------
514 long LineListBox::GetEntryDistance( USHORT nPos
) const
516 ImpLineListData
* pData
= pLineList
->GetObject( nPos
);
518 return pData
->nDistance
;
523 // -----------------------------------------------------------------------
525 void LineListBox::UpdateLineColors( void )
527 if( UpdatePaintLineColor() )
529 ULONG nCount
= pLineList
->Count();
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
);
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
);
560 // -----------------------------------------------------------------------
562 BOOL
LineListBox::UpdatePaintLineColor( void )
565 const StyleSettings
& rSettings
= GetSettings().GetStyleSettings();
566 Color
aNewCol( rSettings
.GetWindowColor().IsDark()? rSettings
.GetLabelTextColor() : aColor
);
568 bRet
= aNewCol
!= maPaintCol
;
571 maPaintCol
= aNewCol
;
576 // -----------------------------------------------------------------------
578 void LineListBox::DataChanged( const DataChangedEvent
& rDCEvt
)
580 ListBox::DataChanged( rDCEvt
);
582 if( ( rDCEvt
.GetType() == DATACHANGED_SETTINGS
) && ( rDCEvt
.GetFlags() & SETTINGS_STYLE
) )
586 // ===================================================================
588 // ===================================================================
590 struct ImplFontNameListData
595 ImplFontNameListData( const FontInfo
& rInfo
,
602 DECLARE_LIST( ImplFontList
, ImplFontNameListData
* )
604 // -------------------------------------------------------------------
606 FontNameBox::FontNameBox( Window
* pParent
, WinBits nWinStyle
) :
607 ComboBox( pParent
, nWinStyle
)
615 // -------------------------------------------------------------------
617 FontNameBox::FontNameBox( Window
* pParent
, const ResId
& rResId
) :
618 ComboBox( pParent
, rResId
)
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
) )
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()
661 ImplFontNameListData
* pInfo
= mpFontList
->First();
665 pInfo
= mpFontList
->Next();
671 // -------------------------------------------------------------------
673 void FontNameBox::Fill( const FontList
* pList
)
675 // store old text and clear box
676 XubString aOldText
= GetText();
679 ImplDestroyFontList();
680 mpFontList
= new ImplFontList
;
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();
699 if ( aOldText
.Len() )
703 // -------------------------------------------------------------------
705 void FontNameBox::EnableWYSIWYG( BOOL bEnable
)
707 if ( bEnable
!= mbWYSIWYG
)
710 EnableUserDraw( mbWYSIWYG
| mbSymbols
);
711 ImplCalcUserItemSize();
715 // -------------------------------------------------------------------
717 void FontNameBox::EnableSymbols( BOOL bEnable
)
719 if ( bEnable
!= mbSymbols
)
722 EnableUserDraw( mbWYSIWYG
| mbSymbols
);
723 ImplCalcUserItemSize();
727 // -------------------------------------------------------------------
729 void FontNameBox::ImplCalcUserItemSize()
732 if ( mbWYSIWYG
&& mpFontList
)
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
)
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...
760 int nLength
= sizeof(aImplSymbolFontText
)/sizeof(aImplSymbolFontText
[0]) - 1;
761 int nLength2
= sizeof(aImplStarSymbolText
)/sizeof(aImplStarSymbolText
[0]) - 1;
762 if( bStarSymbol
&& (nLength
< nLength2
) )
764 aSz
.Width() += aOneCharSz
.Width() * nLength
;
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();
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
;
800 pImg
= &maImageBitmapFont
;
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
)
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
;
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
;
836 aFont
.SetSize( aSize
);
837 rUDEvt
.GetDevice()->SetFont( aFont
);
838 rUDEvt
.GetDevice()->SetTextColor( aTextColor
);
840 FontCharMap aFontCharMap
;
841 bool bHasCharMap
= rUDEvt
.GetDevice()->GetFontCharMap( aFontCharMap
);
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;
861 // on MacOSX there are too many non-presentable symbols above the codepoint 0x0192
865 const int nMaxCount
= sizeof(aText
)/sizeof(*aText
) - 1;
866 int nSkip
= aFontCharMap
.GetCharCount() / nMaxCount
;
869 else if( nSkip
<= 0 )
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
)
878 aText
[ i
] = static_cast<sal_Unicode
>(cNewChar
); // TODO: support UCS4 samples
882 aString
= String( aText
);
886 const sal_Unicode
* pText
= aImplSymbolFontText
;
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
902 DrawEntry( rUDEvt
, TRUE
, TRUE
);
906 // ===================================================================
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();
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
) );
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
);
986 // does a font with this name already exist?
987 sal_Handle hFontInfo
= pList
->GetFirstFontInfo( rName
);
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
;
997 BOOL bBoldItalic
= FALSE
;
998 BOOL bInsert
= FALSE
;
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
) )
1013 InsertEntry( aStyleText
);
1015 if ( eWeight
<= WEIGHT_NORMAL
)
1017 if ( eItalic
!= ITALIC_NONE
)
1024 if ( eItalic
!= ITALIC_NONE
)
1030 // For wrong StyleNames we replace this with the correct once
1031 aStyleText
= pList
->GetStyleName( aInfo
);
1032 bInsert
= GetEntryPos( aStyleText
) == LISTBOX_ENTRY_NOTFOUND
;
1035 aStyleText
= pList
->GetStyleName( eWeight
, eItalic
);
1036 bInsert
= GetEntryPos( aStyleText
) == LISTBOX_ENTRY_NOTFOUND
;
1039 eLastWeight
= eWeight
;
1040 eLastItalic
= eItalic
;
1041 eLastWidth
= eWidth
;
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()) )
1062 else if ( !bBold
&& (aStyleText
== pList
->GetBoldStr()) )
1064 else if ( !bBoldItalic
&& (aStyleText
== pList
->GetBoldItalicStr()) )
1067 hFontInfo
= pList
->GetNextFontInfo( hFontInfo
);
1071 InsertEntry( aStyleText
);
1073 // Bestimmte Styles als Nachbildung
1077 InsertEntry( pList
->GetItalicStr() );
1079 InsertEntry( pList
->GetBoldStr() );
1083 if ( bNormal
|| bItalic
|| bBold
)
1084 InsertEntry( pList
->GetBoldItalicStr() );
1086 if ( aOldText
.Len() )
1088 if ( GetEntryPos( aLastStyle
) != LISTBOX_ENTRY_NOTFOUND
)
1089 ComboBox::SetText( aLastStyle
);
1092 if ( nPos
>= GetEntryCount() )
1093 ComboBox::SetText( GetEntry( 0 ) );
1095 ComboBox::SetText( GetEntry( nPos
) );
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 ) );
1111 ComboBox::SetText( GetEntry( nPos
) );
1116 // ===================================================================
1118 // ===================================================================
1120 FontSizeBox::FontSizeBox( Window
* pParent
, WinBits nWinSize
) :
1121 MetricBox( pParent
, nWinSize
)
1126 // -----------------------------------------------------------------------
1128 FontSizeBox::FontSizeBox( Window
* pParent
, const ResId
& rResId
) :
1129 MetricBox( pParent
, rResId
)
1134 // -----------------------------------------------------------------------
1136 FontSizeBox::~FontSizeBox()
1140 // -----------------------------------------------------------------------
1142 void FontSizeBox::ImplInit()
1144 EnableAutocomplete( FALSE
);
1146 bRelativeMode
= FALSE
;
1147 bPtRelative
= FALSE
;
1152 SetShowTrailingZeros( FALSE
);
1153 SetDecimalDigits( 1 );
1158 // -----------------------------------------------------------------------
1160 void FontSizeBox::Reformat()
1162 FontSizeNames
aFontSizeNames( GetSettings().GetUILanguage() );
1163 if ( !bRelativeMode
|| !aFontSizeNames
.IsEmpty() )
1165 long nNewValue
= aFontSizeNames
.Name2Size( GetText() );
1168 mnLastValue
= nNewValue
;
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
;
1192 bPtRelative
= FALSE
;
1193 const xub_Unicode
* pStr
= aStr
.GetBuffer();
1196 if ( ((*pStr
< '0') || (*pStr
> '9')) && (*pStr
!= '%') )
1198 if ( ('-' == *pStr
|| '+' == *pStr
) && !bPtRelative
)
1200 else if ( bPtRelative
&& 'p' == *pStr
&& 't' == *++pStr
)
1213 if ( STRING_NOTFOUND
!= aStr
.Search( '%' ) )
1216 bPtRelative
= FALSE
;
1219 if ( '-' == aStr
.GetChar( 0 ) || '+' == aStr
.GetChar( 0 ) )
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
1238 // no font sizes need to be set for relative mode
1243 const long* pTempAry
;
1244 const long* pAry
= 0;
1249 pAry
= pList
->GetSizeAry( *pInfo
);
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() )
1268 Selection aSelection
= GetSelection();
1269 XubString aStr
= GetText();
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
1291 // for fixed size fonts only selectable font size names
1295 String aSizeName
= aFontSizeNames
.Size2Name( *pTempAry
);
1296 if ( aSizeName
.Len() )
1298 ComboBox::InsertEntry( aSizeName
, nPos
);
1299 ComboBox::SetEntryData( nPos
, (void*)(-(*pTempAry
)) ); // mark as special
1307 // then insert numerical font size values
1311 InsertValue( *pTempAry
, FUNIT_NONE
, nPos
);
1312 ComboBox::SetEntryData( nPos
, (void*)(*pTempAry
) );
1318 SetSelection( aSelection
);
1321 // -----------------------------------------------------------------------
1323 void FontSizeBox::EnableRelativeMode( USHORT nMin
, USHORT nMax
, USHORT nStep
)
1325 bRelativeMode
= TRUE
;
1329 SetUnit( FUNIT_POINT
);
1332 // -----------------------------------------------------------------------
1334 void FontSizeBox::EnablePtRelativeMode( short nMin
, short nMax
, short nStep
)
1336 bRelativeMode
= TRUE
;
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();
1360 SetDecimalDigits( 1 );
1361 SetMin( nPtRelMin
);
1362 SetMax( nPtRelMax
);
1363 SetUnit( FUNIT_POINT
);
1367 short i
= nPtRelMin
, n
= 0;
1368 // JP 30.06.98: more than 100 values are not useful
1369 while ( i
<= nPtRelMax
&& n
++ < 100 )
1377 SetDecimalDigits( 0 );
1380 SetCustomUnitText( '%' );
1381 SetUnit( FUNIT_CUSTOM
);
1385 while ( i
<= nRelMax
)
1394 bRelative
= bPtRelative
= FALSE
;
1395 SetDecimalDigits( 1 );
1398 SetUnit( FUNIT_POINT
);
1400 Fill( &aFontInfo
, pFontList
);
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 );
1418 // -----------------------------------------------------------------------
1420 void FontSizeBox::SetValue( sal_Int64 nNewValue
, FieldUnit eInUnit
)
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
;
1433 mnFieldValue
= mnLastValue
;
1434 SetEmptyFieldValueData( FALSE
);
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
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(),
1463 // do normal font size processing
1464 sal_Int64 nRetValue
= MetricBox::GetValue( nPos
, eOutUnit
);
1468 // -----------------------------------------------------------------------
1470 sal_Int64
FontSizeBox::GetValue( FieldUnit eOutUnit
) const
1474 FontSizeNames
aFontSizeNames( GetSettings().GetUILanguage() );
1475 sal_Int64 nValue
= aFontSizeNames
.Name2Size( GetText() );
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
)
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
;
1510 MetricBox::SetUserValue( nNewValue
, eInUnit
);