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