LCOV - code coverage report
Current view: top level - svtools/source/control - ctrlbox.cxx (source / functions) Hit Total Coverage
Test: commit 10e77ab3ff6f4314137acd6e2702a6e5c1ce1fae Lines: 396 994 39.8 %
Date: 2014-11-03 Functions: 45 104 43.3 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      11             :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12             :  *   contributor license agreements. See the NOTICE file distributed
      13             :  *   with this work for additional information regarding copyright
      14             :  *   ownership. The ASF licenses this file to you under the Apache
      15             :  *   License, Version 2.0 (the "License"); you may not use this file
      16             :  *   except in compliance with the License. You may obtain a copy of
      17             :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18             :  */
      19             : 
      20             : #include <config_folders.h>
      21             : 
      22             : #include <i18nutil/unicode.hxx>
      23             : #include <tools/stream.hxx>
      24             : #include <vcl/builder.hxx>
      25             : #include <vcl/svapp.hxx>
      26             : #include <vcl/field.hxx>
      27             : #include <vcl/helper.hxx>
      28             : #include <vcl/settings.hxx>
      29             : #include <sal/macros.h>
      30             : #include <comphelper/processfactory.hxx>
      31             : #include <comphelper/string.hxx>
      32             : #include <unotools/charclass.hxx>
      33             : 
      34             : #include <svtools/sampletext.hxx>
      35             : #include <svtools/svtresid.hxx>
      36             : #include <svtools/svtools.hrc>
      37             : #include <svtools/ctrlbox.hxx>
      38             : #include <svtools/ctrltool.hxx>
      39             : #include <svtools/borderhelper.hxx>
      40             : 
      41             : #include <vcl/i18nhelp.hxx>
      42             : #include <vcl/fontcapabilities.hxx>
      43             : #include <basegfx/polygon/b2dpolygon.hxx>
      44             : #include <basegfx/polygon/b2dpolygontools.hxx>
      45             : 
      46             : #include <com/sun/star/table/BorderLineStyle.hpp>
      47             : 
      48             : #include <rtl/bootstrap.hxx>
      49             : 
      50             : #if OSL_DEBUG_LEVEL > 1
      51             : #include <cstdio>
      52             : #endif
      53             : 
      54             : #include <stdio.h>
      55             : 
      56             : #define IMGOUTERTEXTSPACE 5
      57             : #define EXTRAFONTSIZE 5
      58             : #define GAPTOEXTRAPREVIEW 10
      59             : #define MAXPREVIEWWIDTH 120
      60             : #define MINGAPWIDTH 2
      61             : 
      62             : #define FONTNAMEBOXMRUENTRIESFILE "/user/config/fontnameboxmruentries"
      63             : 
      64             : using namespace ::com::sun::star;
      65             : 
      66             : class ImplColorListData
      67             : {
      68             : public:
      69             :     Color       aColor;
      70             :     bool        bColor;
      71             : 
      72           0 :                 ImplColorListData() : aColor( COL_BLACK ) { bColor = false; }
      73        9519 :                 ImplColorListData( const Color& rColor ) : aColor( rColor ) { bColor = true; }
      74             : };
      75             : 
      76         126 : void ColorListBox::ImplInit()
      77             : {
      78         126 :     pColorList = new ImpColorList();
      79             : 
      80         126 :     const StyleSettings& rStyleSettings = Application::GetSettings().GetStyleSettings();
      81         126 :     aImageSize = rStyleSettings.GetListBoxPreviewDefaultPixelSize();
      82         126 :     EnableUserDraw( true );
      83         126 :     SetUserItemSize( aImageSize );
      84         126 : }
      85             : 
      86         183 : void ColorListBox::ImplDestroyColorEntries()
      87             : {
      88        9885 :     for ( size_t n = pColorList->size(); n; )
      89        9519 :         delete (*pColorList)[ --n ];
      90         183 :     pColorList->clear();
      91         183 : }
      92             : 
      93         126 : ColorListBox::ColorListBox( vcl::Window* pParent, WinBits nWinStyle ) :
      94         126 :     ListBox( pParent, nWinStyle )
      95             : {
      96         126 :     ImplInit();
      97         126 :     SetEdgeBlending(true);
      98         126 : }
      99             : 
     100           0 : ColorListBox::ColorListBox( vcl::Window* pParent, const ResId& rResId ) :
     101           0 :     ListBox( pParent, rResId )
     102             : {
     103           0 :     ImplInit();
     104           0 :     SetEdgeBlending(true);
     105           0 : }
     106             : 
     107           0 : extern "C" SAL_DLLPUBLIC_EXPORT vcl::Window* SAL_CALL makeColorListBox(vcl::Window *pParent, VclBuilder::stringmap &rMap)
     108             : {
     109           0 :     bool bDropdown = VclBuilder::extractDropdown(rMap);
     110           0 :     WinBits nWinBits = WB_LEFT|WB_VCENTER|WB_3DLOOK|WB_TABSTOP;
     111           0 :     if (bDropdown)
     112           0 :         nWinBits |= WB_DROPDOWN;
     113           0 :     ColorListBox *pListBox = new ColorListBox(pParent, nWinBits);
     114           0 :     if (bDropdown)
     115           0 :         pListBox->EnableAutoSize(true);
     116           0 :     return pListBox;
     117             : }
     118             : 
     119         252 : ColorListBox::~ColorListBox()
     120             : {
     121         126 :     ImplDestroyColorEntries();
     122         126 :     delete pColorList;
     123         126 : }
     124             : 
     125           0 : sal_Int32 ColorListBox::InsertEntry( const OUString& rStr, sal_Int32 nPos )
     126             : {
     127           0 :     nPos = ListBox::InsertEntry( rStr, nPos );
     128           0 :     if ( nPos != LISTBOX_ERROR )
     129             :     {
     130           0 :         ImplColorListData* pData = new ImplColorListData;
     131           0 :         if ( static_cast<size_t>(nPos) < pColorList->size() )
     132             :         {
     133           0 :             ImpColorList::iterator it = pColorList->begin();
     134           0 :             ::std::advance( it, nPos );
     135           0 :             pColorList->insert( it, pData );
     136             :         }
     137             :         else
     138             :         {
     139           0 :             pColorList->push_back( pData );
     140           0 :             nPos = pColorList->size() - 1;
     141             :         }
     142             :     }
     143           0 :     return nPos;
     144             : }
     145             : 
     146        9519 : sal_Int32 ColorListBox::InsertEntry( const Color& rColor, const OUString& rStr,
     147             :                                 sal_Int32 nPos )
     148             : {
     149        9519 :     nPos = ListBox::InsertEntry( rStr, nPos );
     150        9519 :     if ( nPos != LISTBOX_ERROR )
     151             :     {
     152        9519 :         ImplColorListData* pData = new ImplColorListData( rColor );
     153        9519 :         if ( static_cast<size_t>(nPos) < pColorList->size() )
     154             :         {
     155           0 :             ImpColorList::iterator it = pColorList->begin();
     156           0 :             ::std::advance( it, nPos );
     157           0 :             pColorList->insert( it, pData );
     158             :         }
     159             :         else
     160             :         {
     161        9519 :             pColorList->push_back( pData );
     162        9519 :             nPos = pColorList->size() - 1;
     163             :         }
     164             :     }
     165        9519 :     return nPos;
     166             : }
     167             : 
     168           0 : void ColorListBox::InsertAutomaticEntryColor(const Color &rColor)
     169             : {
     170             :     // insert the "Automatic"-entry always on the first position
     171           0 :     InsertEntry( rColor, SVT_RESSTR(STR_SVT_AUTOMATIC_COLOR), 0 );
     172           0 : }
     173             : 
     174           0 : void ColorListBox::RemoveEntry( sal_Int32 nPos )
     175             : {
     176           0 :     ListBox::RemoveEntry( nPos );
     177           0 :     if ( 0 <= nPos && static_cast<size_t>(nPos) < pColorList->size() )
     178             :     {
     179           0 :             ImpColorList::iterator it = pColorList->begin();
     180           0 :             ::std::advance( it, nPos );
     181           0 :             delete *it;
     182           0 :             pColorList->erase( it );
     183             :     }
     184           0 : }
     185             : 
     186          57 : void ColorListBox::Clear()
     187             : {
     188          57 :     ImplDestroyColorEntries();
     189          57 :     ListBox::Clear();
     190          57 : }
     191             : 
     192           0 : void ColorListBox::CopyEntries( const ColorListBox& rBox )
     193             : {
     194             :     // Liste leeren
     195           0 :     ImplDestroyColorEntries();
     196             : 
     197             :     // Daten kopieren
     198           0 :     size_t nCount = rBox.pColorList->size();
     199           0 :     for ( size_t n = 0; n < nCount; n++ )
     200             :     {
     201           0 :         ImplColorListData* pData = (*rBox.pColorList)[ n ];
     202           0 :         sal_Int32 nPos = InsertEntry( rBox.GetEntry( n ), LISTBOX_APPEND );
     203           0 :         if ( nPos != LISTBOX_ERROR )
     204             :         {
     205           0 :             if ( static_cast<size_t>(nPos) < pColorList->size() )
     206             :             {
     207           0 :                 ImpColorList::iterator it = pColorList->begin();
     208           0 :                 ::std::advance( it, nPos );
     209           0 :                 pColorList->insert( it, new ImplColorListData( *pData ) );
     210             :             }
     211             :             else
     212             :             {
     213           0 :                 pColorList->push_back( new ImplColorListData( *pData ) );
     214             :             }
     215             :         }
     216             :     }
     217           0 : }
     218             : 
     219          57 : sal_Int32 ColorListBox::GetEntryPos( const Color& rColor ) const
     220             : {
     221         171 :     for( sal_Int32 n = (sal_Int32) pColorList->size(); n; )
     222             :     {
     223         114 :         ImplColorListData* pData = (*pColorList)[ --n ];
     224         114 :         if ( pData->bColor && ( pData->aColor == rColor ) )
     225          57 :             return n;
     226             :     }
     227           0 :     return LISTBOX_ENTRY_NOTFOUND;
     228             : }
     229             : 
     230          75 : Color ColorListBox::GetEntryColor( sal_Int32 nPos ) const
     231             : {
     232          75 :     Color aColor;
     233          75 :     ImplColorListData* pData = ( 0 <= nPos && static_cast<size_t>(nPos) < pColorList->size() ) ?
     234         150 :         (*pColorList)[ nPos ] : NULL;
     235          75 :     if ( pData && pData->bColor )
     236          75 :         aColor = pData->aColor;
     237          75 :     return aColor;
     238             : }
     239             : 
     240         199 : void ColorListBox::UserDraw( const UserDrawEvent& rUDEvt )
     241             : {
     242         199 :     size_t nPos = rUDEvt.GetItemId();
     243         199 :     ImplColorListData* pData = ( nPos < pColorList->size() ) ? (*pColorList)[ nPos ] : NULL;
     244         199 :     if ( pData )
     245             :     {
     246         115 :         if ( pData->bColor )
     247             :         {
     248         115 :             Point aPos( rUDEvt.GetRect().TopLeft() );
     249             : 
     250         115 :             aPos.X() += 2;
     251         115 :             aPos.Y() += ( rUDEvt.GetRect().GetHeight() - aImageSize.Height() ) / 2;
     252             : 
     253         115 :             const Rectangle aRect(aPos, aImageSize);
     254             : 
     255         115 :             rUDEvt.GetDevice()->Push();
     256         115 :             rUDEvt.GetDevice()->SetFillColor( pData->aColor );
     257         115 :             rUDEvt.GetDevice()->SetLineColor( rUDEvt.GetDevice()->GetTextColor() );
     258         115 :             rUDEvt.GetDevice()->DrawRect(aRect);
     259         115 :             rUDEvt.GetDevice()->Pop();
     260             : 
     261         115 :             const StyleSettings& rStyleSettings = Application::GetSettings().GetStyleSettings();
     262         115 :             const sal_uInt16 nEdgeBlendingPercent(GetEdgeBlending() ? rStyleSettings.GetEdgeBlending() : 0);
     263             : 
     264         115 :             if(nEdgeBlendingPercent)
     265             :             {
     266         115 :                 const Color& rTopLeft(rStyleSettings.GetEdgeBlendingTopLeftColor());
     267         115 :                 const Color& rBottomRight(rStyleSettings.GetEdgeBlendingBottomRightColor());
     268         115 :                 const sal_uInt8 nAlpha((nEdgeBlendingPercent * 255) / 100);
     269         115 :                 const BitmapEx aBlendFrame(createBlendFrame(aRect.GetSize(), nAlpha, rTopLeft, rBottomRight));
     270             : 
     271         115 :                 if(!aBlendFrame.IsEmpty())
     272             :                 {
     273         115 :                     rUDEvt.GetDevice()->DrawBitmapEx(aRect.TopLeft(), aBlendFrame);
     274         115 :                 }
     275             :             }
     276             : 
     277         115 :             ListBox::DrawEntry( rUDEvt, false, true, false );
     278             :         }
     279             :         else
     280           0 :             ListBox::DrawEntry( rUDEvt, false, true, true );
     281             :     }
     282             :     else
     283          84 :         ListBox::DrawEntry( rUDEvt, true, true, false );
     284         199 : }
     285             : 
     286      939750 : BorderWidthImpl::BorderWidthImpl( sal_uInt16 nFlags, double nRate1, double nRate2, double nRateGap ):
     287             :     m_nFlags( nFlags ),
     288             :     m_nRate1( nRate1 ),
     289             :     m_nRate2( nRate2 ),
     290      939750 :     m_nRateGap( nRateGap )
     291             : {
     292      939750 : }
     293             : 
     294      834733 : BorderWidthImpl& BorderWidthImpl::operator= ( const BorderWidthImpl& r )
     295             : {
     296      834733 :     m_nFlags = r.m_nFlags;
     297      834733 :     m_nRate1 = r.m_nRate1;
     298      834733 :     m_nRate2 = r.m_nRate2;
     299      834733 :     m_nRateGap = r.m_nRateGap;
     300      834733 :     return *this;
     301             : }
     302             : 
     303      372595 : bool BorderWidthImpl::operator== ( const BorderWidthImpl& r ) const
     304             : {
     305      744942 :     return ( m_nFlags == r.m_nFlags ) &&
     306      744616 :            ( m_nRate1 == r.m_nRate1 ) &&
     307     1117061 :            ( m_nRate2 == r.m_nRate2 ) &&
     308      744792 :            ( m_nRateGap == r.m_nRateGap );
     309             : }
     310             : 
     311     2242119 : long BorderWidthImpl::GetLine1( long nWidth ) const
     312             : {
     313     2242119 :     long result = static_cast<long>(m_nRate1);
     314     2242119 :     if ( ( m_nFlags & CHANGE_LINE1 ) > 0 )
     315             :     {
     316     2236735 :         long const nConstant2 = (m_nFlags & CHANGE_LINE2) ? 0 : m_nRate2;
     317     2236735 :         long const nConstantD = (m_nFlags & CHANGE_DIST ) ? 0 : m_nRateGap;
     318             :         result = std::max<long>(0,
     319     2236735 :                     static_cast<long>((m_nRate1 * nWidth) + 0.5)
     320     2236735 :                         - (nConstant2 + nConstantD));
     321     2236735 :         if (result == 0 && m_nRate1 > 0.0 && nWidth > 0)
     322             :         {   // fdo#51777: hack to essentially treat 1 twip DOUBLE border
     323          16 :             result = 1;  // as 1 twip SINGLE border
     324             :         }
     325             :     }
     326     2242119 :     return result;
     327             : }
     328             : 
     329     2244283 : long BorderWidthImpl::GetLine2( long nWidth ) const
     330             : {
     331     2244283 :     long result = static_cast<long>(m_nRate2);
     332     2244283 :     if ( ( m_nFlags & CHANGE_LINE2 ) > 0 )
     333             :     {
     334        2718 :         long const nConstant1 = (m_nFlags & CHANGE_LINE1) ? 0 : m_nRate1;
     335        2718 :         long const nConstantD = (m_nFlags & CHANGE_DIST ) ? 0 : m_nRateGap;
     336             :         result = std::max<long>(0,
     337        2718 :                     static_cast<long>((m_nRate2 * nWidth) + 0.5)
     338        2718 :                         - (nConstant1 + nConstantD));
     339             :     }
     340     2244283 :     return result;
     341             : }
     342             : 
     343     2224683 : long BorderWidthImpl::GetGap( long nWidth ) const
     344             : {
     345     2224683 :     long result = static_cast<long>(m_nRateGap);
     346     2224683 :     if ( ( m_nFlags & CHANGE_DIST ) > 0 )
     347             :     {
     348        6398 :         long const nConstant1 = (m_nFlags & CHANGE_LINE1) ? 0 : m_nRate1;
     349        6398 :         long const nConstant2 = (m_nFlags & CHANGE_LINE2) ? 0 : m_nRate2;
     350             :         result = std::max<long>(0,
     351        6398 :                     static_cast<long>((m_nRateGap * nWidth) + 0.5)
     352        6398 :                         - (nConstant1 + nConstant2));
     353             :     }
     354             : 
     355             :     // Avoid having too small distances (less than 0.1pt)
     356     2224683 :     if ( result < MINGAPWIDTH && m_nRate1 > 0 && m_nRate2 > 0 )
     357          32 :         result = MINGAPWIDTH;
     358             : 
     359     2224683 :     return result;
     360             : }
     361             : 
     362       90834 : static double lcl_getGuessedWidth( long nTested, double nRate, bool nChanging )
     363             : {
     364       90834 :     double nWidth = -1.0;
     365       90834 :     if ( nChanging )
     366       31702 :         nWidth = double( nTested ) / nRate;
     367             :     else
     368             :     {
     369       59132 :         if ( double( nTested ) == nRate )
     370       56740 :             nWidth = nRate;
     371             :     }
     372             : 
     373       90834 :     return nWidth;
     374             : }
     375             : 
     376       30278 : long BorderWidthImpl::GuessWidth( long nLine1, long nLine2, long nGap )
     377             : {
     378       30278 :     std::vector< double > aToCompare;
     379       30278 :     bool bInvalid = false;
     380             : 
     381       30278 :     bool bLine1Change = ( m_nFlags & CHANGE_LINE1 ) > 0;
     382       30278 :     double nWidth1 = lcl_getGuessedWidth( nLine1, m_nRate1, bLine1Change );
     383       30278 :     if ( bLine1Change )
     384       29408 :         aToCompare.push_back( nWidth1 );
     385         870 :     else if ( !bLine1Change && nWidth1 < 0 )
     386         836 :         bInvalid = true;
     387             : 
     388       30278 :     bool bLine2Change = ( m_nFlags & CHANGE_LINE2 ) > 0;
     389       30278 :     double nWidth2 = lcl_getGuessedWidth( nLine2, m_nRate2, bLine2Change );
     390       30278 :     if ( bLine2Change )
     391         928 :         aToCompare.push_back( nWidth2 );
     392       29350 :     else if ( !bLine2Change && nWidth2 < 0 )
     393        1014 :         bInvalid = true;
     394             : 
     395       30278 :     bool bGapChange = ( m_nFlags & CHANGE_DIST ) > 0;
     396       30278 :     double nWidthGap = lcl_getGuessedWidth( nGap, m_nRateGap, bGapChange );
     397       30278 :     if ( bGapChange && nGap > MINGAPWIDTH )
     398        1366 :         aToCompare.push_back( nWidthGap );
     399       28912 :     else if ( !bGapChange && nWidthGap < 0 )
     400         542 :         bInvalid = true;
     401             : 
     402             :     // non-constant line width factors must sum to 1
     403             :     assert((((bLine1Change) ? m_nRate1 : 0) +
     404             :             ((bLine2Change) ? m_nRate2 : 0) +
     405             :             ((bGapChange) ? m_nRateGap : 0)) - 1.0 < 0.00001 );
     406             : 
     407       30278 :     double nWidth = 0.0;
     408       30278 :     if ( (!bInvalid) && (!aToCompare.empty()) )
     409             :     {
     410       29066 :         nWidth = *aToCompare.begin();
     411       29066 :         std::vector< double >::iterator pIt = aToCompare.begin();
     412       88036 :         while ( pIt != aToCompare.end() && !bInvalid )
     413             :         {
     414       29904 :             bInvalid = ( nWidth != *pIt );
     415       29904 :             ++pIt;
     416             :         }
     417       29066 :         nWidth = (bInvalid) ?  0.0 : nLine1 + nLine2 + nGap;
     418             :     }
     419             : 
     420       30278 :     return nWidth;
     421             : }
     422             : 
     423             : /** Utility class storing the border line width, style and colors. The widths
     424             :     are defined in Twips.
     425             :   */
     426             : class ImpLineListData
     427             : {
     428             : private:
     429             :     BorderWidthImpl m_aWidthImpl;
     430             : 
     431             :     Color  ( *m_pColor1Fn )( Color );
     432             :     Color  ( *m_pColor2Fn )( Color );
     433             :     Color  ( *m_pColorDistFn )( Color, Color );
     434             : 
     435             :     long   m_nMinWidth;
     436             :     sal_uInt16 m_nStyle;
     437             : 
     438             : public:
     439             :     ImpLineListData( BorderWidthImpl aWidthImpl, sal_uInt16 nStyle,
     440             :             long nMinWidth=0, Color ( *pColor1Fn ) ( Color ) = &sameColor,
     441             :             Color ( *pColor2Fn ) ( Color ) = &sameColor, Color ( *pColorDistFn ) ( Color, Color ) = &sameDistColor );
     442             : 
     443             :     /** Returns the computed width of the line 1 in twips. */
     444           0 :     long GetLine1ForWidth( long nWidth ) { return m_aWidthImpl.GetLine1( nWidth ); }
     445             : 
     446             :     /** Returns the computed width of the line 2 in twips. */
     447           0 :     long GetLine2ForWidth( long nWidth ) { return m_aWidthImpl.GetLine2( nWidth ); }
     448             : 
     449             :     /** Returns the computed width of the gap in twips. */
     450           0 :     long GetDistForWidth( long nWidth ) { return m_aWidthImpl.GetGap( nWidth ); }
     451             : 
     452             :     Color  GetColorLine1( const Color& aMain );
     453             :     Color  GetColorLine2( const Color& aMain );
     454             :     Color  GetColorDist( const Color& aMain, const Color& rDefault );
     455             : 
     456             :     /** Returns the minimum width in twips */
     457           0 :     long   GetMinWidth( ) { return m_nMinWidth;}
     458           0 :     sal_uInt16 GetStyle( ) { return m_nStyle;}
     459             : };
     460             : 
     461           0 : ImpLineListData::ImpLineListData( BorderWidthImpl aWidthImpl,
     462             :        sal_uInt16 nStyle, long nMinWidth, Color ( *pColor1Fn )( Color ),
     463             :        Color ( *pColor2Fn )( Color ), Color ( *pColorDistFn )( Color, Color ) ) :
     464             :     m_aWidthImpl( aWidthImpl ),
     465             :     m_pColor1Fn( pColor1Fn ),
     466             :     m_pColor2Fn( pColor2Fn ),
     467             :     m_pColorDistFn( pColorDistFn ),
     468             :     m_nMinWidth( nMinWidth ),
     469           0 :     m_nStyle( nStyle )
     470             : {
     471           0 : }
     472             : 
     473             : 
     474           0 : Color ImpLineListData::GetColorLine1( const Color& rMain )
     475             : {
     476           0 :     return ( *m_pColor1Fn )( rMain );
     477             : }
     478             : 
     479           0 : Color ImpLineListData::GetColorLine2( const Color& rMain )
     480             : {
     481           0 :     return ( *m_pColor2Fn )( rMain );
     482             : }
     483             : 
     484           0 : Color ImpLineListData::GetColorDist( const Color& rMain, const Color& rDefault )
     485             : {
     486           0 :     return ( *m_pColorDistFn )( rMain, rDefault );
     487             : }
     488             : 
     489           0 : sal_uInt16 LineListBox::GetSelectEntryStyle( sal_Int32 nSelIndex ) const
     490             : {
     491           0 :     sal_uInt16 nStyle = table::BorderLineStyle::SOLID;
     492           0 :     sal_Int32 nPos = GetSelectEntryPos( nSelIndex );
     493           0 :     if ( nPos != LISTBOX_ENTRY_NOTFOUND )
     494             :     {
     495           0 :         if (!m_sNone.isEmpty())
     496           0 :             nPos--;
     497           0 :         nStyle = GetEntryStyle( nPos );
     498             :     }
     499             : 
     500           0 :     return nStyle;
     501             : }
     502             : 
     503             : 
     504           0 : void lclDrawPolygon( OutputDevice& rDev, const basegfx::B2DPolygon& rPolygon, long nWidth, sal_uInt16 nDashing )
     505             : {
     506           0 :     sal_uInt16 nOldAA = rDev.GetAntialiasing();
     507           0 :     rDev.SetAntialiasing( nOldAA & ~ANTIALIASING_ENABLE_B2DDRAW );
     508             : 
     509           0 :     long nPix = rDev.PixelToLogic(Size(1, 1)).Width();
     510           0 :     basegfx::B2DPolyPolygon aPolygons = svtools::ApplyLineDashing(rPolygon, nDashing, nPix);
     511             : 
     512             :     // Handle problems of width 1px in Pixel mode: 0.5px gives a 1px line
     513           0 :     if (rDev.GetMapMode().GetMapUnit() == MAP_PIXEL && nWidth == nPix)
     514           0 :         nWidth = 0;
     515             : 
     516           0 :     for ( sal_uInt32 i = 0; i < aPolygons.count( ); i++ )
     517             :     {
     518           0 :         basegfx::B2DPolygon aDash = aPolygons.getB2DPolygon( i );
     519           0 :         basegfx::B2DPoint aStart = aDash.getB2DPoint( 0 );
     520           0 :         basegfx::B2DPoint aEnd = aDash.getB2DPoint( aDash.count() - 1 );
     521             : 
     522           0 :         basegfx::B2DVector aVector( aEnd - aStart );
     523           0 :         aVector.normalize( );
     524           0 :         const basegfx::B2DVector aPerpendicular(basegfx::getPerpendicular(aVector));
     525             : 
     526           0 :         const basegfx::B2DVector aWidthOffset( double( nWidth ) / 2 * aPerpendicular);
     527           0 :         basegfx::B2DPolygon aDashPolygon;
     528           0 :         aDashPolygon.append( aStart + aWidthOffset );
     529           0 :         aDashPolygon.append( aEnd + aWidthOffset );
     530           0 :         aDashPolygon.append( aEnd - aWidthOffset );
     531           0 :         aDashPolygon.append( aStart - aWidthOffset );
     532           0 :         aDashPolygon.setClosed( true );
     533             : 
     534           0 :         rDev.DrawPolygon( aDashPolygon );
     535           0 :     }
     536             : 
     537           0 :     rDev.SetAntialiasing( nOldAA );
     538           0 : }
     539             : 
     540             : namespace svtools {
     541             : 
     542             : /**
     543             :  * Dashing array must start with a line width and end with a blank width.
     544             :  */
     545         232 : std::vector<double> GetDashing( sal_uInt16 nDashing )
     546             : {
     547         232 :     std::vector<double> aPattern;
     548         232 :     switch (nDashing)
     549             :     {
     550             :         case table::BorderLineStyle::DOTTED:
     551          96 :             aPattern.push_back( 1.0 ); // line
     552          96 :             aPattern.push_back( 2.0 ); // blank
     553          96 :         break;
     554             :         case table::BorderLineStyle::DASHED:
     555          32 :             aPattern.push_back( 16.0 ); // line
     556          32 :             aPattern.push_back( 5.0 );  // blank
     557          32 :         break;
     558             :         case table::BorderLineStyle::FINE_DASHED:
     559          40 :             aPattern.push_back( 6.0 ); // line
     560          40 :             aPattern.push_back( 2.0 ); // blank
     561          40 :         break;
     562             :         case table::BorderLineStyle::DASH_DOT:
     563           0 :             aPattern.push_back( 16.0 ); // line
     564           0 :             aPattern.push_back( 5.0 );  // blank
     565           0 :             aPattern.push_back( 5.0 );  // line
     566           0 :             aPattern.push_back( 5.0 );  // blank
     567           0 :         break;
     568             :         case table::BorderLineStyle::DASH_DOT_DOT:
     569           0 :             aPattern.push_back( 16.0 ); // line
     570           0 :             aPattern.push_back( 5.0 );  // blank
     571           0 :             aPattern.push_back( 5.0 );  // line
     572           0 :             aPattern.push_back( 5.0 );  // blank
     573           0 :             aPattern.push_back( 5.0 );  // line
     574           0 :             aPattern.push_back( 5.0 );  // blank
     575           0 :         break;
     576             :         default:
     577             :             ;
     578             :     }
     579             : 
     580         232 :     return aPattern;
     581             : }
     582             : 
     583             : namespace {
     584             : 
     585             : class ApplyScale : std::unary_function<double, void>
     586             : {
     587             :     double mfScale;
     588             : public:
     589         232 :     ApplyScale( double fScale ) : mfScale(fScale) {}
     590         336 :     void operator() ( double& rVal )
     591             :     {
     592         336 :         rVal *= mfScale;
     593         336 :     }
     594             : };
     595             : 
     596             : }
     597             : 
     598         158 : std::vector<double> GetLineDashing( sal_uInt16 nDashing, double fScale )
     599             : {
     600         158 :     std::vector<double> aPattern = GetDashing(nDashing);
     601         158 :     std::for_each(aPattern.begin(), aPattern.end(), ApplyScale(fScale));
     602         158 :     return aPattern;
     603             : }
     604             : 
     605          74 : basegfx::B2DPolyPolygon ApplyLineDashing( const basegfx::B2DPolygon& rPolygon, sal_uInt16 nDashing, double fScale )
     606             : {
     607          74 :     std::vector<double> aPattern = GetDashing(nDashing);
     608          74 :     std::for_each(aPattern.begin(), aPattern.end(), ApplyScale(fScale));
     609             : 
     610          74 :     basegfx::B2DPolyPolygon aPolygons;
     611             : 
     612          74 :     if (aPattern.empty())
     613          64 :         aPolygons.append(rPolygon);
     614             :     else
     615          10 :         basegfx::tools::applyLineDashing(rPolygon, aPattern, &aPolygons);
     616             : 
     617          74 :     return aPolygons;
     618             : }
     619             : 
     620           0 : void DrawLine( OutputDevice& rDev, const Point& rP1, const Point& rP2,
     621             :     sal_uInt32 nWidth, sal_uInt16 nDashing )
     622             : {
     623           0 :     DrawLine( rDev, basegfx::B2DPoint( rP1.X(), rP1.Y() ),
     624           0 :             basegfx::B2DPoint( rP2.X(), rP2.Y( ) ), nWidth, nDashing );
     625           0 : }
     626             : 
     627           0 : void DrawLine( OutputDevice& rDev, const basegfx::B2DPoint& rP1, const basegfx::B2DPoint& rP2,
     628             :     sal_uInt32 nWidth, sal_uInt16 nDashing )
     629             : {
     630           0 :     basegfx::B2DPolygon aPolygon;
     631           0 :     aPolygon.append( rP1 );
     632           0 :     aPolygon.append( rP2 );
     633           0 :     lclDrawPolygon( rDev, aPolygon, nWidth, nDashing );
     634           0 : }
     635             : 
     636             : }
     637             : 
     638           0 : void LineListBox::ImpGetLine( long nLine1, long nLine2, long nDistance,
     639             :                             Color aColor1, Color aColor2, Color aColorDist,
     640             :                             sal_uInt16 nStyle, Bitmap& rBmp )
     641             : {
     642             :     //TODO, rather than including the " " text to force
     643             :     //the line height, better would be do drop
     644             :     //this calculation and draw a bitmap of height
     645             :     //equal to normal text line and center the
     646             :     //line within that
     647           0 :     long nMinWidth = GetTextWidth(OUString("----------"));
     648           0 :     Size aSize = CalcSubEditSize();
     649           0 :     aSize.Width() = std::max(nMinWidth, aSize.Width());
     650           0 :     aSize.Width() -= aTxtSize.Width();
     651           0 :     aSize.Width() -= 6;
     652           0 :     aSize.Height() = aTxtSize.Height();
     653             : 
     654             :     // SourceUnit nach Twips
     655           0 :     if ( eSourceUnit == FUNIT_POINT )
     656             :     {
     657           0 :         nLine1      /= 5;
     658           0 :         nLine2      /= 5;
     659           0 :         nDistance   /= 5;
     660             :     }
     661             : 
     662             :     // Linien malen
     663           0 :     aSize = aVirDev.PixelToLogic( aSize );
     664           0 :     long nPix = aVirDev.PixelToLogic( Size( 0, 1 ) ).Height();
     665           0 :     sal_uInt32 n1 = nLine1;
     666           0 :     sal_uInt32 n2 = nLine2;
     667           0 :     long nDist  = nDistance;
     668           0 :     n1 += nPix-1;
     669           0 :     n1 -= n1%nPix;
     670           0 :     if ( n2 )
     671             :     {
     672           0 :         nDist += nPix-1;
     673           0 :         nDist -= nDist%nPix;
     674           0 :         n2    += nPix-1;
     675           0 :         n2    -= n2%nPix;
     676             :     }
     677           0 :     long nVirHeight = n1+nDist+n2;
     678           0 :     if ( nVirHeight > aSize.Height() )
     679           0 :         aSize.Height() = nVirHeight;
     680             :     // negative width should not be drawn
     681           0 :     if ( aSize.Width() > 0 )
     682             :     {
     683           0 :         Size aVirSize = aVirDev.LogicToPixel( aSize );
     684           0 :         if ( aVirDev.GetOutputSizePixel() != aVirSize )
     685           0 :             aVirDev.SetOutputSizePixel( aVirSize );
     686           0 :         aVirDev.SetFillColor( aColorDist );
     687           0 :         aVirDev.DrawRect( Rectangle( Point(), aSize ) );
     688             : 
     689           0 :         aVirDev.SetFillColor( aColor1 );
     690             : 
     691           0 :         double y1 = double( n1 ) / 2;
     692           0 :         svtools::DrawLine( aVirDev, basegfx::B2DPoint( 0, y1 ), basegfx::B2DPoint( aSize.Width( ), y1 ), n1, nStyle );
     693             : 
     694           0 :         if ( n2 )
     695             :         {
     696           0 :             double y2 =  n1 + nDist + double( n2 ) / 2;
     697           0 :             aVirDev.SetFillColor( aColor2 );
     698           0 :             svtools::DrawLine( aVirDev, basegfx::B2DPoint( 0, y2 ), basegfx::B2DPoint( aSize.Width(), y2 ), n2, table::BorderLineStyle::SOLID );
     699             :         }
     700           0 :         rBmp = aVirDev.GetBitmap( Point(), Size( aSize.Width(), n1+nDist+n2 ) );
     701             :     }
     702           0 : }
     703             : 
     704           0 : void LineListBox::ImplInit()
     705             : {
     706           0 :     aTxtSize.Width()  = GetTextWidth( OUString( " " ) );
     707           0 :     aTxtSize.Height() = GetTextHeight();
     708           0 :     pLineList   = new ImpLineList();
     709           0 :     eUnit       = FUNIT_POINT;
     710           0 :     eSourceUnit = FUNIT_POINT;
     711             : 
     712           0 :     aVirDev.SetLineColor();
     713           0 :     aVirDev.SetMapMode( MapMode( MAP_TWIP ) );
     714             : 
     715           0 :     UpdatePaintLineColor();
     716           0 : }
     717             : 
     718           0 : LineListBox::LineListBox( vcl::Window* pParent, WinBits nWinStyle ) :
     719             :     ListBox( pParent, nWinStyle ),
     720             :     m_nWidth( 5 ),
     721             :     m_sNone( ),
     722             :     aColor( COL_BLACK ),
     723           0 :     maPaintCol( COL_BLACK )
     724             : {
     725           0 :     ImplInit();
     726           0 : }
     727             : 
     728           0 : extern "C" SAL_DLLPUBLIC_EXPORT vcl::Window* SAL_CALL makeLineListBox(vcl::Window *pParent, VclBuilder::stringmap &rMap)
     729             : {
     730           0 :     bool bDropdown = VclBuilder::extractDropdown(rMap);
     731           0 :     WinBits nWinBits = WB_LEFT|WB_VCENTER|WB_3DLOOK|WB_TABSTOP;
     732           0 :     if (bDropdown)
     733           0 :         nWinBits |= WB_DROPDOWN;
     734           0 :     LineListBox *pListBox = new LineListBox(pParent, nWinBits);
     735           0 :     if (bDropdown)
     736           0 :         pListBox->EnableAutoSize(true);
     737           0 :     return pListBox;
     738             : }
     739             : 
     740           0 : LineListBox::~LineListBox()
     741             : {
     742           0 :     for ( size_t i = 0, n = pLineList->size(); i < n; ++i ) {
     743           0 :         if ( (*pLineList)[ i ] ) {
     744           0 :             delete (*pLineList)[ i ];
     745             :         }
     746             :     }
     747           0 :     pLineList->clear();
     748           0 :     delete pLineList;
     749           0 : }
     750             : 
     751           0 : sal_Int32 LineListBox::GetStylePos( sal_Int32 nListPos, long nWidth )
     752             : {
     753           0 :     sal_Int32 nPos = LISTBOX_ENTRY_NOTFOUND;
     754           0 :     if (!m_sNone.isEmpty())
     755           0 :         nListPos--;
     756             : 
     757           0 :     sal_Int32 n = 0;
     758           0 :     size_t i = 0;
     759           0 :     size_t nCount = pLineList->size();
     760           0 :     while ( nPos == LISTBOX_ENTRY_NOTFOUND && i < nCount )
     761             :     {
     762           0 :         ImpLineListData* pData = (*pLineList)[ i ];
     763           0 :         if ( pData && pData->GetMinWidth() <= nWidth )
     764             :         {
     765           0 :             if ( nListPos == n )
     766           0 :                 nPos = static_cast<sal_Int32>(i);
     767           0 :             n++;
     768             :         }
     769           0 :         i++;
     770             :     }
     771             : 
     772           0 :     return nPos;
     773             : }
     774             : 
     775           0 : void LineListBox::SelectEntry( sal_uInt16 nStyle, bool bSelect )
     776             : {
     777           0 :     sal_Int32 nPos = GetEntryPos( nStyle );
     778           0 :     if ( nPos != LISTBOX_ENTRY_NOTFOUND )
     779           0 :         ListBox::SelectEntryPos( nPos, bSelect );
     780           0 : }
     781             : 
     782           0 : sal_Int32 LineListBox::InsertEntry( const OUString& rStr, sal_Int32 nPos )
     783             : {
     784           0 :     nPos = ListBox::InsertEntry( rStr, nPos );
     785           0 :     if ( nPos != LISTBOX_ERROR ) {
     786           0 :         if ( static_cast<size_t>(nPos) < pLineList->size() ) {
     787           0 :             ImpLineList::iterator it = pLineList->begin();
     788           0 :             ::std::advance( it, nPos );
     789           0 :             pLineList->insert( it, reinterpret_cast<ImpLineListData *>(NULL) );
     790             :         } else {
     791           0 :             pLineList->push_back( NULL );
     792             :         }
     793             :     }
     794           0 :     return nPos;
     795             : }
     796             : 
     797           0 : void LineListBox::InsertEntry(
     798             :     BorderWidthImpl aWidthImpl, sal_uInt16 nStyle, long nMinWidth,
     799             :     ColorFunc pColor1Fn, ColorFunc pColor2Fn, ColorDistFunc pColorDistFn )
     800             : {
     801             :     ImpLineListData* pData = new ImpLineListData(
     802           0 :         aWidthImpl, nStyle, nMinWidth, pColor1Fn, pColor2Fn, pColorDistFn);
     803           0 :     pLineList->push_back( pData );
     804           0 : }
     805             : 
     806           0 : void LineListBox::RemoveEntry( sal_Int32 nPos )
     807             : {
     808           0 :     ListBox::RemoveEntry( nPos );
     809             : 
     810           0 :     if ( 0 <= nPos && static_cast<size_t>(nPos) < pLineList->size() ) {
     811           0 :         ImpLineList::iterator it = pLineList->begin();
     812           0 :         ::std::advance( it, nPos );
     813           0 :         if ( *it ) delete *it;
     814           0 :         pLineList->erase( it );
     815             :     }
     816           0 : }
     817             : 
     818           0 : void LineListBox::Clear()
     819             : {
     820           0 :     for ( size_t i = 0, n = pLineList->size(); i < n; ++i ) {
     821           0 :         if ( (*pLineList)[ i ] ) {
     822           0 :             delete (*pLineList)[ i ];
     823             :         }
     824             :     }
     825           0 :     pLineList->clear();
     826             : 
     827           0 :     ListBox::Clear();
     828           0 : }
     829             : 
     830           0 : sal_Int32 LineListBox::GetEntryPos( sal_uInt16 nStyle ) const
     831             : {
     832           0 :     for ( size_t i = 0, n = pLineList->size(); i < n; ++i ) {
     833           0 :         ImpLineListData* pData = (*pLineList)[ i ];
     834           0 :         if ( pData )
     835             :         {
     836           0 :             if ( GetEntryStyle( i ) == nStyle )
     837             :             {
     838           0 :                 size_t nPos = i;
     839           0 :                 if (!m_sNone.isEmpty())
     840           0 :                     nPos ++;
     841           0 :                 return (sal_Int32)nPos;
     842             :             }
     843             :         }
     844             :     }
     845           0 :     return LISTBOX_ENTRY_NOTFOUND;
     846             : }
     847             : 
     848           0 : sal_uInt16 LineListBox::GetEntryStyle( sal_Int32 nPos ) const
     849             : {
     850           0 :     ImpLineListData* pData = (0 <= nPos && static_cast<size_t>(nPos) < pLineList->size()) ? (*pLineList)[ nPos ] : NULL;
     851           0 :     return ( pData ) ? pData->GetStyle() : table::BorderLineStyle::NONE;
     852             : }
     853             : 
     854           0 : bool LineListBox::UpdatePaintLineColor( void )
     855             : {
     856           0 :     const StyleSettings&    rSettings = GetSettings().GetStyleSettings();
     857           0 :     Color                   aNewCol( rSettings.GetWindowColor().IsDark()? rSettings.GetLabelTextColor() : aColor );
     858             : 
     859           0 :     bool bRet = aNewCol != maPaintCol;
     860             : 
     861           0 :     if( bRet )
     862           0 :         maPaintCol = aNewCol;
     863             : 
     864           0 :     return bRet;
     865             : }
     866             : 
     867           0 : void LineListBox::UpdateEntries( long nOldWidth )
     868             : {
     869           0 :     SetUpdateMode( false );
     870             : 
     871           0 :     UpdatePaintLineColor( );
     872             : 
     873           0 :     sal_Int32      nSelEntry = GetSelectEntryPos();
     874           0 :     sal_Int32       nTypePos = GetStylePos( nSelEntry, nOldWidth );
     875             : 
     876             :     // Remove the old entries
     877           0 :     while ( GetEntryCount( ) > 0 )
     878           0 :         ListBox::RemoveEntry( 0 );
     879             : 
     880             :     // Add the new entries based on the defined width
     881           0 :     if (!m_sNone.isEmpty())
     882           0 :         ListBox::InsertEntry( m_sNone, LISTBOX_APPEND );
     883             : 
     884           0 :     sal_uInt16 n = 0;
     885           0 :     sal_uInt16 nCount = pLineList->size( );
     886           0 :     while ( n < nCount )
     887             :     {
     888           0 :         ImpLineListData* pData = (*pLineList)[ n ];
     889           0 :         if ( pData && pData->GetMinWidth() <= m_nWidth )
     890             :         {
     891           0 :             Bitmap      aBmp;
     892             :             ImpGetLine( pData->GetLine1ForWidth( m_nWidth ),
     893             :                     pData->GetLine2ForWidth( m_nWidth ),
     894             :                     pData->GetDistForWidth( m_nWidth ),
     895             :                     GetColorLine1( GetEntryCount( ) ),
     896             :                     GetColorLine2( GetEntryCount( ) ),
     897             :                     GetColorDist( GetEntryCount( ) ),
     898           0 :                     pData->GetStyle(), aBmp );
     899           0 :             ListBox::InsertEntry(OUString(" "), Image(aBmp), LISTBOX_APPEND);
     900           0 :             if ( n == nTypePos )
     901           0 :                 SelectEntryPos( GetEntryCount() - 1 );
     902             :         }
     903           0 :         else if ( n == nTypePos )
     904           0 :             SetNoSelection();
     905           0 :         n++;
     906             :     }
     907             : 
     908           0 :     SetUpdateMode( true );
     909           0 :     Invalidate();
     910           0 : }
     911             : 
     912           0 : Color LineListBox::GetColorLine1( sal_Int32 nPos )
     913             : {
     914           0 :     Color rResult = GetPaintColor( );
     915             : 
     916           0 :     sal_uInt16 nStyle = GetStylePos( nPos, m_nWidth );
     917           0 :     ImpLineListData* pData = (*pLineList)[ nStyle ];
     918           0 :     if ( pData )
     919           0 :         rResult = pData->GetColorLine1( GetColor( ) );
     920             : 
     921           0 :     return rResult;
     922             : }
     923             : 
     924           0 : Color LineListBox::GetColorLine2( sal_Int32 nPos )
     925             : {
     926           0 :     Color rResult = GetPaintColor( );
     927             : 
     928           0 :     sal_uInt16 nStyle = GetStylePos( nPos, m_nWidth );
     929           0 :     ImpLineListData* pData = (*pLineList)[ nStyle ];
     930           0 :     if ( pData )
     931           0 :         rResult = pData->GetColorLine2( GetColor( ) );
     932             : 
     933           0 :     return rResult;
     934             : }
     935             : 
     936           0 : Color LineListBox::GetColorDist( sal_Int32 nPos )
     937             : {
     938           0 :     Color rResult = GetSettings().GetStyleSettings().GetFieldColor();
     939             : 
     940           0 :     sal_uInt16 nStyle = GetStylePos( nPos, m_nWidth );
     941           0 :     ImpLineListData* pData = (*pLineList)[ nStyle ];
     942           0 :     if ( pData )
     943           0 :         rResult = pData->GetColorDist( GetColor( ), rResult );
     944             : 
     945           0 :     return rResult;
     946             : }
     947             : 
     948           0 : void LineListBox::DataChanged( const DataChangedEvent& rDCEvt )
     949             : {
     950           0 :     ListBox::DataChanged( rDCEvt );
     951             : 
     952           0 :     if( ( rDCEvt.GetType() == DATACHANGED_SETTINGS ) && ( rDCEvt.GetFlags() & SETTINGS_STYLE ) )
     953           0 :         UpdateEntries( m_nWidth );
     954           0 : }
     955             : 
     956        1954 : FontNameBox::FontNameBox( vcl::Window* pParent, WinBits nWinStyle ) :
     957        1954 :     ComboBox( pParent, nWinStyle )
     958             : {
     959        1954 :     mpFontList = NULL;
     960        1954 :     mbWYSIWYG = false;
     961        1954 :     InitFontMRUEntriesFile();
     962        1954 : }
     963             : 
     964           0 : extern "C" SAL_DLLPUBLIC_EXPORT vcl::Window* SAL_CALL makeFontNameBox(vcl::Window *pParent, VclBuilder::stringmap &rMap)
     965             : {
     966           0 :     bool bDropdown = VclBuilder::extractDropdown(rMap);
     967           0 :     WinBits nWinBits = WB_LEFT|WB_VCENTER|WB_3DLOOK|WB_TABSTOP;
     968           0 :     if (bDropdown)
     969           0 :         nWinBits |= WB_DROPDOWN;
     970           0 :     FontNameBox *pListBox = new FontNameBox(pParent, nWinBits);
     971           0 :     if (bDropdown)
     972           0 :         pListBox->EnableAutoSize(true);
     973           0 :     return pListBox;
     974             : }
     975             : 
     976        3908 : FontNameBox::~FontNameBox()
     977             : {
     978        1954 :     SaveMRUEntries (maFontMRUEntriesFile);
     979        1954 :     ImplDestroyFontList();
     980        1954 : }
     981             : 
     982        1954 : void FontNameBox::SaveMRUEntries( const OUString& aFontMRUEntriesFile, sal_Unicode cSep ) const
     983             : {
     984             :     OString aEntries(OUStringToOString(GetMRUEntries(cSep),
     985        1954 :         RTL_TEXTENCODING_UTF8));
     986             : 
     987        1954 :     if (aEntries.isEmpty() || aFontMRUEntriesFile.isEmpty())
     988        1954 :         return;
     989             : 
     990           0 :     SvFileStream aStream;
     991           0 :     aStream.Open( aFontMRUEntriesFile, STREAM_WRITE | STREAM_TRUNC );
     992           0 :     if( ! (aStream.IsOpen() && aStream.IsWritable()) )
     993             :     {
     994             : #if OSL_DEBUG_LEVEL > 1
     995             :         fprintf( stderr, "FontNameBox::SaveMRUEntries: opening mru entries file %s failed\n", OUStringToOString(aFontMRUEntriesFile, RTL_TEXTENCODING_UTF8 ).getStr() );
     996             : #endif
     997           0 :         return;
     998             :     }
     999             : 
    1000           0 :     aStream.SetLineDelimiter( LINEEND_LF );
    1001           0 :     aStream.WriteLine( aEntries );
    1002           0 :     aStream.WriteLine( OString() );
    1003             : }
    1004             : 
    1005        1684 : void FontNameBox::LoadMRUEntries( const OUString& aFontMRUEntriesFile, sal_Unicode cSep )
    1006             : {
    1007        1684 :     if( aFontMRUEntriesFile.isEmpty() )
    1008        1684 :         return;
    1009             : 
    1010        1684 :     SvFileStream aStream( aFontMRUEntriesFile, STREAM_READ );
    1011        1684 :     if( ! aStream.IsOpen() )
    1012             :     {
    1013             : #if OSL_DEBUG_LEVEL > 1
    1014             :         fprintf( stderr, "FontNameBox::LoadMRUEntries: opening mru entries file %s failed\n", OUStringToOString(aFontMRUEntriesFile, RTL_TEXTENCODING_UTF8).getStr() );
    1015             : #endif
    1016        1684 :         return;
    1017             :     }
    1018             : 
    1019           0 :     OString aLine;
    1020           0 :     aStream.ReadLine( aLine );
    1021             :     OUString aEntries = OStringToOUString(aLine,
    1022           0 :         RTL_TEXTENCODING_UTF8);
    1023           0 :     SetMRUEntries( aEntries, cSep );
    1024             : }
    1025             : 
    1026        1954 : void FontNameBox::InitFontMRUEntriesFile()
    1027             : {
    1028        1954 :     OUString sUserConfigDir("${$BRAND_BASE_DIR/" LIBO_ETC_FOLDER "/" SAL_CONFIGFILE( "bootstrap") "::UserInstallation}");
    1029        1954 :     rtl::Bootstrap::expandMacros(sUserConfigDir);
    1030             : 
    1031        1954 :     maFontMRUEntriesFile = sUserConfigDir;
    1032        1954 :     if( !maFontMRUEntriesFile.isEmpty() )
    1033             :     {
    1034        1954 :         maFontMRUEntriesFile += FONTNAMEBOXMRUENTRIESFILE;
    1035        1954 :     }
    1036        1954 : }
    1037             : 
    1038        3638 : void FontNameBox::ImplDestroyFontList()
    1039             : {
    1040        3638 :     delete mpFontList;
    1041        3638 : }
    1042             : 
    1043        1684 : void FontNameBox::Fill( const FontList* pList )
    1044             : {
    1045             :     // store old text and clear box
    1046        1684 :     OUString aOldText = GetText();
    1047        3368 :     OUString rEntries = GetMRUEntries();
    1048        1684 :     bool bLoadFromFile = rEntries.isEmpty();
    1049        1684 :     Clear();
    1050             : 
    1051        1684 :     ImplDestroyFontList();
    1052        1684 :     mpFontList = new ImplFontList;
    1053             : 
    1054             :     // insert fonts
    1055        1684 :     sal_uInt16 nFontCount = pList->GetFontNameCount();
    1056       85884 :     for ( sal_uInt16 i = 0; i < nFontCount; i++ )
    1057             :     {
    1058       84200 :         const vcl::FontInfo& rFontInfo = pList->GetFontName( i );
    1059       84200 :         sal_uLong nIndex = InsertEntry( rFontInfo.GetName() );
    1060       84200 :         if ( nIndex != LISTBOX_ERROR )
    1061             :         {
    1062       84200 :             if ( nIndex < mpFontList->size() ) {
    1063           0 :                 ImplFontList::iterator it = mpFontList->begin();
    1064           0 :                 ::std::advance( it, nIndex );
    1065           0 :                 mpFontList->insert( it, rFontInfo );
    1066             :             } else {
    1067       84200 :                 mpFontList->push_back( rFontInfo );
    1068             :             }
    1069             :         }
    1070             :     }
    1071             : 
    1072        1684 :     if ( bLoadFromFile )
    1073        1684 :         LoadMRUEntries (maFontMRUEntriesFile);
    1074             :     else
    1075           0 :         SetMRUEntries( rEntries );
    1076             : 
    1077        1684 :     ImplCalcUserItemSize();
    1078             : 
    1079             :     // restore text
    1080        1684 :     if (!aOldText.isEmpty())
    1081        3368 :         SetText( aOldText );
    1082        1684 : }
    1083             : 
    1084        1956 : void FontNameBox::EnableWYSIWYG( bool bEnable )
    1085             : {
    1086        1956 :     if ( bEnable != mbWYSIWYG )
    1087             :     {
    1088        1954 :         mbWYSIWYG = bEnable;
    1089        1954 :         EnableUserDraw( mbWYSIWYG );
    1090        1954 :         ImplCalcUserItemSize();
    1091             :     }
    1092        1956 : }
    1093             : 
    1094        3638 : void FontNameBox::ImplCalcUserItemSize()
    1095             : {
    1096        3638 :     Size aUserItemSz;
    1097        3638 :     if ( mbWYSIWYG && mpFontList )
    1098             :     {
    1099        1684 :         aUserItemSz = Size(MAXPREVIEWWIDTH, GetTextHeight() );
    1100        1684 :         aUserItemSz.Height() *= 16;
    1101        1684 :         aUserItemSz.Height() /= 10;
    1102             :     }
    1103        3638 :     SetUserItemSize( aUserItemSz );
    1104        3638 : }
    1105             : 
    1106             : namespace
    1107             : {
    1108        1724 :     long shrinkFontToFit(OUString &rSampleText, long nH, vcl::Font &rFont, OutputDevice &rDevice, Rectangle &rTextRect)
    1109             :     {
    1110        1724 :         long nWidth = 0;
    1111             : 
    1112        1724 :         Size aSize( rFont.GetSize() );
    1113             : 
    1114             :         //Make sure it fits in the available height
    1115        3448 :         while (aSize.Height() > 0)
    1116             :         {
    1117        1724 :             if (!rDevice.GetTextBoundRect(rTextRect, rSampleText, 0, 0))
    1118           0 :                 break;
    1119        1724 :             if (rTextRect.GetHeight() <= nH)
    1120             :             {
    1121        1724 :                 nWidth = rTextRect.GetWidth();
    1122        1724 :                 break;
    1123             :             }
    1124             : 
    1125           0 :             aSize.Height() -= EXTRAFONTSIZE;
    1126           0 :             rFont.SetSize(aSize);
    1127           0 :             rDevice.SetFont(rFont);
    1128             :         }
    1129             : 
    1130        1724 :         return nWidth;
    1131             :     }
    1132             : }
    1133             : 
    1134        1724 : void FontNameBox::UserDraw( const UserDrawEvent& rUDEvt )
    1135             : {
    1136             :     assert( mpFontList );
    1137             : 
    1138        1724 :     vcl::FontInfo& rInfo = (*mpFontList)[ rUDEvt.GetItemId() ];
    1139        1724 :     Point aTopLeft = rUDEvt.GetRect().TopLeft();
    1140        1724 :     long nX = aTopLeft.X();
    1141        1724 :     long nH = rUDEvt.GetRect().GetHeight();
    1142             : 
    1143        1724 :     if ( mbWYSIWYG )
    1144             :     {
    1145        1724 :         nX += IMGOUTERTEXTSPACE;
    1146             : 
    1147        1724 :         const bool bSymbolFont = isSymbolFont(rInfo);
    1148             : 
    1149        1724 :         Color aTextColor = rUDEvt.GetDevice()->GetTextColor();
    1150        1724 :         vcl::Font aOldFont( rUDEvt.GetDevice()->GetFont() );
    1151        1724 :         Size aSize( aOldFont.GetSize() );
    1152        1724 :         aSize.Height() += EXTRAFONTSIZE;
    1153        3448 :         vcl::Font aFont( rInfo );
    1154        1724 :         aFont.SetSize( aSize );
    1155        1724 :         rUDEvt.GetDevice()->SetFont( aFont );
    1156        1724 :         rUDEvt.GetDevice()->SetTextColor( aTextColor );
    1157             : 
    1158        1724 :         bool bUsingCorrectFont = true;
    1159        1724 :         Rectangle aTextRect;
    1160             : 
    1161             :         // Preview the font name
    1162        3448 :         OUString sFontName = rInfo.GetName();
    1163             : 
    1164             :         //If it shouldn't or can't draw its own name because it doesn't have the glyphs
    1165        1724 :         if (!canRenderNameOfSelectedFont(*rUDEvt.GetDevice()))
    1166          12 :             bUsingCorrectFont = false;
    1167             :         else
    1168             :         {
    1169             :             //Make sure it fits in the available height, shrinking the font if necessary
    1170        1712 :             bUsingCorrectFont = shrinkFontToFit(sFontName, nH, aFont, *rUDEvt.GetDevice(), aTextRect) != 0;
    1171             :         }
    1172             : 
    1173        1724 :         if (!bUsingCorrectFont)
    1174             :         {
    1175          12 :             rUDEvt.GetDevice()->SetFont(aOldFont);
    1176          12 :             rUDEvt.GetDevice()->GetTextBoundRect(aTextRect, sFontName, 0, 0);
    1177             :         }
    1178             : 
    1179        1724 :         long nTextHeight = aTextRect.GetHeight();
    1180        1724 :         long nDesiredGap = (nH-nTextHeight)/2;
    1181        1724 :         long nVertAdjust = nDesiredGap - aTextRect.Top();
    1182        1724 :         Point aPos( nX, aTopLeft.Y() + nVertAdjust );
    1183        1724 :         rUDEvt.GetDevice()->DrawText( aPos, sFontName );
    1184        1724 :         long nTextX = aPos.X() + aTextRect.GetWidth() + GAPTOEXTRAPREVIEW;
    1185             : 
    1186        1724 :         if (!bUsingCorrectFont)
    1187          12 :             rUDEvt.GetDevice()->SetFont( aFont );
    1188             : 
    1189        3448 :         OUString sSampleText;
    1190             : 
    1191        1724 :         if (!bSymbolFont)
    1192             :         {
    1193        1712 :             const bool bNameBeginsWithLatinText = rInfo.GetName()[0] <= 'z';
    1194             : 
    1195        1712 :             if (bNameBeginsWithLatinText || !bUsingCorrectFont)
    1196        1712 :                 sSampleText = makeShortRepresentativeTextForSelectedFont(*rUDEvt.GetDevice());
    1197             :         }
    1198             : 
    1199             :         //If we're not a symbol font, but could neither render our own name and
    1200             :         //we can't determine what script it would like to render, then try a
    1201             :         //few well known scripts
    1202        1724 :         if (sSampleText.isEmpty() && !bUsingCorrectFont)
    1203             :         {
    1204             :             static const UScriptCode aScripts[] =
    1205             :             {
    1206             :                 USCRIPT_ARABIC,
    1207             :                 USCRIPT_HEBREW,
    1208             : 
    1209             :                 USCRIPT_BENGALI,
    1210             :                 USCRIPT_GURMUKHI,
    1211             :                 USCRIPT_GUJARATI,
    1212             :                 USCRIPT_ORIYA,
    1213             :                 USCRIPT_TAMIL,
    1214             :                 USCRIPT_TELUGU,
    1215             :                 USCRIPT_KANNADA,
    1216             :                 USCRIPT_MALAYALAM,
    1217             :                 USCRIPT_SINHALA,
    1218             :                 USCRIPT_DEVANAGARI,
    1219             : 
    1220             :                 USCRIPT_THAI,
    1221             :                 USCRIPT_LAO,
    1222             :                 USCRIPT_GEORGIAN,
    1223             :                 USCRIPT_TIBETAN,
    1224             :                 USCRIPT_SYRIAC,
    1225             :                 USCRIPT_MYANMAR,
    1226             :                 USCRIPT_ETHIOPIC,
    1227             :                 USCRIPT_KHMER,
    1228             :                 USCRIPT_MONGOLIAN,
    1229             : 
    1230             :                 USCRIPT_KOREAN,
    1231             :                 USCRIPT_JAPANESE,
    1232             :                 USCRIPT_HAN,
    1233             :                 USCRIPT_SIMPLIFIED_HAN,
    1234             :                 USCRIPT_TRADITIONAL_HAN,
    1235             : 
    1236             :                 USCRIPT_GREEK
    1237             :             };
    1238             : 
    1239         336 :             for (size_t i = 0; i < SAL_N_ELEMENTS(aScripts); ++i)
    1240             :             {
    1241         324 :                 OUString sText = makeShortRepresentativeTextForScript(aScripts[i]);
    1242         324 :                 if (!sText.isEmpty())
    1243             :                 {
    1244         324 :                     bool bHasSampleTextGlyphs = (-1 == rUDEvt.GetDevice()->HasGlyphs(aFont, sText));
    1245         324 :                     if (bHasSampleTextGlyphs)
    1246             :                     {
    1247           0 :                         sSampleText = sText;
    1248           0 :                         break;
    1249             :                     }
    1250             :                 }
    1251         324 :             }
    1252             : 
    1253             :             static const UScriptCode aMinimalScripts[] =
    1254             :             {
    1255             :                 USCRIPT_HEBREW, //e.g. biblical hebrew
    1256             :                 USCRIPT_GREEK
    1257             :             };
    1258             : 
    1259          32 :             for (size_t i = 0; i < SAL_N_ELEMENTS(aMinimalScripts); ++i)
    1260             :             {
    1261          24 :                 OUString sText = makeShortMinimalTextForScript(aMinimalScripts[i]);
    1262          24 :                 if (!sText.isEmpty())
    1263             :                 {
    1264          24 :                     bool bHasSampleTextGlyphs = (-1 == rUDEvt.GetDevice()->HasGlyphs(aFont, sText));
    1265          24 :                     if (bHasSampleTextGlyphs)
    1266             :                     {
    1267           4 :                         sSampleText = sText;
    1268           4 :                         break;
    1269             :                     }
    1270             :                 }
    1271          20 :             }
    1272             :         }
    1273             : 
    1274             :         //If we're a symbol font, or for some reason the font still couldn't
    1275             :         //render something representative of what it would like to render then
    1276             :         //make up some semi-random text that it *can* display
    1277        1724 :         if (bSymbolFont || (!bUsingCorrectFont && sSampleText.isEmpty()))
    1278          12 :             sSampleText = makeShortRepresentativeSymbolTextForSelectedFont(*rUDEvt.GetDevice());
    1279             : 
    1280        1724 :         if (!sSampleText.isEmpty())
    1281             :         {
    1282          12 :             const Size &rItemSize = rUDEvt.GetDevice()->GetOutputSize();
    1283             :             //leave a little border at the edge
    1284          12 :             long nSpace = rItemSize.Width() - nTextX - IMGOUTERTEXTSPACE;
    1285          12 :             if (nSpace >= 0)
    1286             :             {
    1287             :                 //Make sure it fits in the available height, and get how wide that would be
    1288          12 :                 long nWidth = shrinkFontToFit(sSampleText, nH, aFont, *rUDEvt.GetDevice(), aTextRect);
    1289             :                 //Chop letters off until it fits in the available width
    1290          24 :                 while (nWidth > nSpace || nWidth > MAXPREVIEWWIDTH)
    1291             :                 {
    1292           0 :                     sSampleText = sSampleText.copy(0, sSampleText.getLength()-1);
    1293           0 :                     nWidth = rUDEvt.GetDevice()->GetTextBoundRect(aTextRect, sSampleText, 0, 0) ?
    1294           0 :                              aTextRect.GetWidth() : 0;
    1295             :                 }
    1296             : 
    1297             :                 //center the text on the line
    1298          12 :                 if (!sSampleText.isEmpty() && nWidth)
    1299             :                 {
    1300          12 :                     nTextHeight = aTextRect.GetHeight();
    1301          12 :                     nDesiredGap = (nH-nTextHeight)/2;
    1302          12 :                     nVertAdjust = nDesiredGap - aTextRect.Top();
    1303          12 :                     aPos = Point(nTextX + nSpace - nWidth, aTopLeft.Y() + nVertAdjust);
    1304          12 :                     rUDEvt.GetDevice()->DrawText( aPos, sSampleText );
    1305             :                 }
    1306             :             }
    1307             :         }
    1308             : 
    1309        1724 :         rUDEvt.GetDevice()->SetFont( aOldFont );
    1310        3448 :         DrawEntry( rUDEvt, false, false);   // draw separator
    1311             :     }
    1312             :     else
    1313             :     {
    1314           0 :         DrawEntry( rUDEvt, true, true );
    1315             :     }
    1316        1724 : }
    1317             : 
    1318           0 : FontStyleBox::FontStyleBox(vcl::Window* pParent, WinBits nBits)
    1319           0 :     : ComboBox(pParent, nBits)
    1320             : {
    1321             :     //Use the standard texts to get an optimal size and stick to that size.
    1322             :     //That should stop the character dialog dancing around.
    1323           0 :     InsertEntry(SVT_RESSTR(STR_SVT_STYLE_LIGHT));
    1324           0 :     InsertEntry(SVT_RESSTR(STR_SVT_STYLE_LIGHT_ITALIC));
    1325           0 :     InsertEntry(SVT_RESSTR(STR_SVT_STYLE_NORMAL));
    1326           0 :     InsertEntry(SVT_RESSTR(STR_SVT_STYLE_NORMAL_ITALIC));
    1327           0 :     InsertEntry(SVT_RESSTR(STR_SVT_STYLE_BOLD));
    1328           0 :     InsertEntry(SVT_RESSTR(STR_SVT_STYLE_BOLD_ITALIC));
    1329           0 :     InsertEntry(SVT_RESSTR(STR_SVT_STYLE_BLACK));
    1330           0 :     InsertEntry(SVT_RESSTR(STR_SVT_STYLE_BLACK_ITALIC));
    1331           0 :     aOptimalSize = GetOptimalSize();
    1332           0 :     Clear();
    1333           0 : }
    1334             : 
    1335           0 : Size FontStyleBox::GetOptimalSize() const
    1336             : {
    1337           0 :     if (aOptimalSize.Width() || aOptimalSize.Height())
    1338           0 :         return aOptimalSize;
    1339           0 :     return ComboBox::GetOptimalSize();
    1340             : }
    1341             : 
    1342           0 : extern "C" SAL_DLLPUBLIC_EXPORT vcl::Window* SAL_CALL makeFontStyleBox(vcl::Window *pParent, VclBuilder::stringmap &rMap)
    1343             : {
    1344           0 :     bool bDropdown = VclBuilder::extractDropdown(rMap);
    1345           0 :     WinBits nWinBits = WB_LEFT|WB_VCENTER|WB_3DLOOK|WB_TABSTOP;
    1346           0 :     if (bDropdown)
    1347           0 :         nWinBits |= WB_DROPDOWN;
    1348           0 :     FontStyleBox *pListBox = new FontStyleBox(pParent, nWinBits);
    1349           0 :     if (bDropdown)
    1350           0 :         pListBox->EnableAutoSize(true);
    1351           0 :     return pListBox;
    1352             : }
    1353             : 
    1354           0 : FontStyleBox::~FontStyleBox()
    1355             : {
    1356           0 : }
    1357             : 
    1358           0 : void FontStyleBox::Select()
    1359             : {
    1360             :     // keep text over fill operation
    1361           0 :     aLastStyle = GetText();
    1362           0 :     ComboBox::Select();
    1363           0 : }
    1364             : 
    1365           0 : void FontStyleBox::LoseFocus()
    1366             : {
    1367             :     // keep text over fill operation
    1368           0 :     aLastStyle = GetText();
    1369           0 :     ComboBox::LoseFocus();
    1370           0 : }
    1371             : 
    1372           0 : void FontStyleBox::Modify()
    1373             : {
    1374             :     CharClass   aChrCls( ::comphelper::getProcessComponentContext(),
    1375           0 :                         GetSettings().GetLanguageTag() );
    1376           0 :     OUString   aStr = GetText();
    1377           0 :     sal_Int32      nEntryCount = GetEntryCount();
    1378             : 
    1379           0 :     if ( GetEntryPos( aStr ) == COMBOBOX_ENTRY_NOTFOUND )
    1380             :     {
    1381           0 :         aStr = aChrCls.uppercase(aStr);
    1382           0 :         for ( sal_Int32 i = 0; i < nEntryCount; i++ )
    1383             :         {
    1384           0 :             OUString aEntryText = aChrCls.uppercase(GetEntry(i));
    1385             : 
    1386           0 :             if ( aStr == aEntryText )
    1387             :             {
    1388           0 :                 SetText( GetEntry( i ) );
    1389           0 :                 break;
    1390             :             }
    1391           0 :         }
    1392             :     }
    1393             : 
    1394           0 :     ComboBox::Modify();
    1395           0 : }
    1396             : 
    1397           0 : void FontStyleBox::Fill( const OUString& rName, const FontList* pList )
    1398             : {
    1399             :     // note: this method must call ComboBox::SetText(),
    1400             :     //   else aLastStyle will overwritten
    1401             :     // store prior selection position and clear box
    1402           0 :     OUString aOldText = GetText();
    1403           0 :     sal_Int32 nPos = GetEntryPos( aOldText );
    1404           0 :     Clear();
    1405             : 
    1406             :     // does a font with this name already exist?
    1407           0 :     sal_Handle hFontInfo = pList->GetFirstFontInfo( rName );
    1408           0 :     if ( hFontInfo )
    1409             :     {
    1410           0 :         OUString aStyleText;
    1411           0 :         FontWeight  eLastWeight = WEIGHT_DONTKNOW;
    1412           0 :         FontItalic  eLastItalic = ITALIC_NONE;
    1413           0 :         FontWidth   eLastWidth = WIDTH_DONTKNOW;
    1414           0 :         bool        bNormal = false;
    1415           0 :         bool        bItalic = false;
    1416           0 :         bool        bBold = false;
    1417           0 :         bool        bBoldItalic = false;
    1418           0 :         bool        bInsert = false;
    1419           0 :         vcl::FontInfo    aInfo;
    1420           0 :         while ( hFontInfo )
    1421             :         {
    1422           0 :             aInfo = pList->GetFontInfo( hFontInfo );
    1423             : 
    1424           0 :             FontWeight  eWeight = aInfo.GetWeight();
    1425           0 :             FontItalic  eItalic = aInfo.GetItalic();
    1426           0 :             FontWidth   eWidth = aInfo.GetWidthType();
    1427             :             // Only if the attributes are different, we insert the
    1428             :             // Font to avoid double Entries in different languages
    1429           0 :             if ( (eWeight != eLastWeight) || (eItalic != eLastItalic) ||
    1430             :                  (eWidth != eLastWidth) )
    1431             :             {
    1432           0 :                 if ( bInsert )
    1433           0 :                     InsertEntry( aStyleText );
    1434             : 
    1435           0 :                 if ( eWeight <= WEIGHT_NORMAL )
    1436             :                 {
    1437           0 :                     if ( eItalic != ITALIC_NONE )
    1438           0 :                         bItalic = true;
    1439             :                     else
    1440           0 :                         bNormal = true;
    1441             :                 }
    1442             :                 else
    1443             :                 {
    1444           0 :                     if ( eItalic != ITALIC_NONE )
    1445           0 :                         bBoldItalic = true;
    1446             :                     else
    1447           0 :                         bBold = true;
    1448             :                 }
    1449             : 
    1450             :                 // For wrong StyleNames we replace this with the correct once
    1451           0 :                 aStyleText = pList->GetStyleName( aInfo );
    1452           0 :                 bInsert = GetEntryPos( aStyleText ) == LISTBOX_ENTRY_NOTFOUND;
    1453           0 :                 if ( !bInsert )
    1454             :                 {
    1455           0 :                     aStyleText = pList->GetStyleName( eWeight, eItalic );
    1456           0 :                     bInsert = GetEntryPos( aStyleText ) == LISTBOX_ENTRY_NOTFOUND;
    1457             :                 }
    1458             : 
    1459           0 :                 eLastWeight = eWeight;
    1460           0 :                 eLastItalic = eItalic;
    1461           0 :                 eLastWidth = eWidth;
    1462             :             }
    1463             :             else
    1464             :             {
    1465           0 :                 if ( bInsert )
    1466             :                 {
    1467             :                     // If we have two names for the same attributes
    1468             :                     // we prefer the translated standard names
    1469           0 :                     const OUString& rAttrStyleText = pList->GetStyleName( eWeight, eItalic );
    1470           0 :                     if (rAttrStyleText != aStyleText)
    1471             :                     {
    1472           0 :                         OUString aTempStyleText = pList->GetStyleName( aInfo );
    1473           0 :                         if (rAttrStyleText == aTempStyleText)
    1474           0 :                             aStyleText = rAttrStyleText;
    1475           0 :                         bInsert = GetEntryPos( aStyleText ) == LISTBOX_ENTRY_NOTFOUND;
    1476             :                     }
    1477             :                 }
    1478             :             }
    1479             : 
    1480           0 :             if ( !bItalic && (aStyleText == pList->GetItalicStr()) )
    1481           0 :                 bItalic = true;
    1482           0 :             else if ( !bBold && (aStyleText == pList->GetBoldStr()) )
    1483           0 :                 bBold = true;
    1484           0 :             else if ( !bBoldItalic && (aStyleText == pList->GetBoldItalicStr()) )
    1485           0 :                 bBoldItalic = true;
    1486             : 
    1487           0 :             hFontInfo = pList->GetNextFontInfo( hFontInfo );
    1488             :         }
    1489             : 
    1490           0 :         if ( bInsert )
    1491           0 :             InsertEntry( aStyleText );
    1492             : 
    1493             :         // certain style as copy
    1494           0 :         if ( bNormal )
    1495             :         {
    1496           0 :             if ( !bItalic )
    1497           0 :                 InsertEntry( pList->GetItalicStr() );
    1498           0 :             if ( !bBold )
    1499           0 :                 InsertEntry( pList->GetBoldStr() );
    1500             :         }
    1501           0 :         if ( !bBoldItalic )
    1502             :         {
    1503           0 :             if ( bNormal || bItalic || bBold )
    1504           0 :                 InsertEntry( pList->GetBoldItalicStr() );
    1505             :         }
    1506           0 :         if (!aOldText.isEmpty())
    1507             :         {
    1508           0 :             if ( GetEntryPos( aLastStyle ) != LISTBOX_ENTRY_NOTFOUND )
    1509           0 :                 ComboBox::SetText( aLastStyle );
    1510             :             else
    1511             :             {
    1512           0 :                 if ( nPos >= GetEntryCount() )
    1513           0 :                     ComboBox::SetText( GetEntry( 0 ) );
    1514             :                 else
    1515           0 :                     ComboBox::SetText( GetEntry( nPos ) );
    1516             :             }
    1517           0 :         }
    1518             :     }
    1519             :     else
    1520             :     {
    1521             :         // insert standard styles if no font
    1522           0 :         InsertEntry( pList->GetNormalStr() );
    1523           0 :         InsertEntry( pList->GetItalicStr() );
    1524           0 :         InsertEntry( pList->GetBoldStr() );
    1525           0 :         InsertEntry( pList->GetBoldItalicStr() );
    1526           0 :         if (!aOldText.isEmpty())
    1527             :         {
    1528           0 :             if ( nPos > GetEntryCount() )
    1529           0 :                 ComboBox::SetText( GetEntry( 0 ) );
    1530             :             else
    1531           0 :                 ComboBox::SetText( GetEntry( nPos ) );
    1532             :         }
    1533           0 :     }
    1534           0 : }
    1535             : 
    1536        1948 : FontSizeBox::FontSizeBox( vcl::Window* pParent, WinBits nWinSize ) :
    1537        1948 :     MetricBox( pParent, nWinSize )
    1538             : {
    1539        1948 :     ImplInit();
    1540        1948 : }
    1541             : 
    1542           0 : extern "C" SAL_DLLPUBLIC_EXPORT vcl::Window* SAL_CALL makeFontSizeBox(vcl::Window *pParent, VclBuilder::stringmap &rMap)
    1543             : {
    1544           0 :     bool bDropdown = VclBuilder::extractDropdown(rMap);
    1545           0 :     WinBits nWinBits = WB_LEFT|WB_VCENTER|WB_3DLOOK|WB_TABSTOP;
    1546           0 :     if (bDropdown)
    1547           0 :         nWinBits |= WB_DROPDOWN;
    1548           0 :     FontSizeBox* pListBox = new FontSizeBox(pParent, nWinBits);
    1549           0 :     if (bDropdown)
    1550           0 :         pListBox->EnableAutoSize(true);
    1551           0 :     return pListBox;
    1552             : }
    1553             : 
    1554        1948 : FontSizeBox::~FontSizeBox()
    1555             : {
    1556        1948 : }
    1557             : 
    1558        1948 : void FontSizeBox::ImplInit()
    1559             : {
    1560        1948 :     EnableAutocomplete( false );
    1561             : 
    1562        1948 :     bRelativeMode   = false;
    1563        1948 :     bPtRelative     = false;
    1564        1948 :     bRelative       = false;
    1565        1948 :     bStdSize        = false;
    1566        1948 :     pFontList       = NULL;
    1567             : 
    1568        1948 :     SetShowTrailingZeros( false );
    1569        1948 :     SetDecimalDigits( 1 );
    1570        1948 :     SetMin( 20 );
    1571        1948 :     SetMax( 9999 );
    1572        1948 :     SetProminentEntryType( PROMINENT_MIDDLE );
    1573        1948 : }
    1574             : 
    1575           0 : void FontSizeBox::Reformat()
    1576             : {
    1577           0 :     FontSizeNames aFontSizeNames( GetSettings().GetUILanguageTag().getLanguageType() );
    1578           0 :     if ( !bRelativeMode || !aFontSizeNames.IsEmpty() )
    1579             :     {
    1580           0 :         long nNewValue = aFontSizeNames.Name2Size( GetText() );
    1581           0 :         if ( nNewValue)
    1582             :         {
    1583           0 :             mnLastValue = nNewValue;
    1584           0 :             return;
    1585             :         }
    1586             :     }
    1587             : 
    1588           0 :     MetricBox::Reformat();
    1589             : }
    1590             : 
    1591           0 : void FontSizeBox::Modify()
    1592             : {
    1593           0 :     MetricBox::Modify();
    1594             : 
    1595           0 :     if ( bRelativeMode )
    1596             :     {
    1597           0 :         OUString aStr = comphelper::string::stripStart(GetText(), ' ');
    1598             : 
    1599           0 :         bool bNewMode = bRelative;
    1600           0 :         bool bOldPtRelMode = bPtRelative;
    1601             : 
    1602           0 :         if ( bRelative )
    1603             :         {
    1604           0 :             bPtRelative = false;
    1605           0 :             const sal_Unicode* pStr = aStr.getStr();
    1606           0 :             while ( *pStr )
    1607             :             {
    1608           0 :                 if ( ((*pStr < '0') || (*pStr > '9')) && (*pStr != '%') && !unicode::isSpace(*pStr) )
    1609             :                 {
    1610           0 :                     if ( ('-' == *pStr || '+' == *pStr) && !bPtRelative )
    1611           0 :                         bPtRelative = true;
    1612           0 :                     else if ( bPtRelative && 'p' == *pStr && 't' == *++pStr )
    1613             :                         ;
    1614             :                     else
    1615             :                     {
    1616           0 :                         bNewMode = false;
    1617           0 :                         break;
    1618             :                     }
    1619             :                 }
    1620           0 :                 pStr++;
    1621             :             }
    1622             :         }
    1623             :         else
    1624             :         {
    1625           0 :             if ( -1 != aStr.indexOf('%') )
    1626             :             {
    1627           0 :                 bNewMode = true;
    1628           0 :                 bPtRelative = false;
    1629             :             }
    1630             : 
    1631           0 :             if ( '-' == aStr[0] || '+' == aStr[0] )
    1632             :             {
    1633           0 :                 bNewMode = true;
    1634           0 :                 bPtRelative = true;
    1635             :             }
    1636             :         }
    1637             : 
    1638           0 :         if ( bNewMode != bRelative || bPtRelative != bOldPtRelMode )
    1639           0 :             SetRelative( bNewMode );
    1640             :     }
    1641           0 : }
    1642             : 
    1643        4006 : void FontSizeBox::Fill( const vcl::FontInfo* pInfo, const FontList* pList )
    1644             : {
    1645             :     // remember for relative mode
    1646        4006 :     pFontList = pList;
    1647             : 
    1648             :     // no font sizes need to be set for relative mode
    1649        4006 :     if ( bRelative )
    1650        2058 :         return;
    1651             : 
    1652             :     // query font sizes
    1653             :     const sal_IntPtr* pTempAry;
    1654        4006 :     const sal_IntPtr* pAry = 0;
    1655             : 
    1656        4006 :     if( pInfo )
    1657             :     {
    1658        2058 :         aFontInfo = *pInfo;
    1659        2058 :         pAry = pList->GetSizeAry( *pInfo );
    1660             :     }
    1661             :     else
    1662             :     {
    1663        1948 :         pAry = FontList::GetStdSizeAry();
    1664             :     }
    1665             : 
    1666             :     // first insert font size names (for simplified/traditional chinese)
    1667        4006 :     FontSizeNames aFontSizeNames( GetSettings().GetUILanguageTag().getLanguageType() );
    1668        4006 :     if ( pAry == FontList::GetStdSizeAry() )
    1669             :     {
    1670             :         // for standard sizes we don't need to bother
    1671        4006 :         if ( bStdSize && GetEntryCount() && aFontSizeNames.IsEmpty() )
    1672        2058 :             return;
    1673        1948 :         bStdSize = true;
    1674             :     }
    1675             :     else
    1676           0 :         bStdSize = false;
    1677             : 
    1678        1948 :     Selection aSelection = GetSelection();
    1679        1948 :     OUString aStr = GetText();
    1680             : 
    1681        1948 :     Clear();
    1682        1948 :     sal_Int32 nPos = 0;
    1683             : 
    1684        1948 :     if ( !aFontSizeNames.IsEmpty() )
    1685             :     {
    1686           0 :         if ( pAry == FontList::GetStdSizeAry() )
    1687             :         {
    1688             :             // for scalable fonts all font size names
    1689           0 :             sal_uLong nCount = aFontSizeNames.Count();
    1690           0 :             for( sal_uLong i = 0; i < nCount; i++ )
    1691             :             {
    1692           0 :                 OUString    aSizeName = aFontSizeNames.GetIndexName( i );
    1693           0 :                 sal_IntPtr  nSize = aFontSizeNames.GetIndexSize( i );
    1694           0 :                 ComboBox::InsertEntry( aSizeName, nPos );
    1695           0 :                 ComboBox::SetEntryData( nPos, reinterpret_cast<void*>(-nSize) ); // mark as special
    1696           0 :                 nPos++;
    1697           0 :             }
    1698             :         }
    1699             :         else
    1700             :         {
    1701             :             // for fixed size fonts only selectable font size names
    1702           0 :             pTempAry = pAry;
    1703           0 :             while ( *pTempAry )
    1704             :             {
    1705           0 :                 OUString aSizeName = aFontSizeNames.Size2Name( *pTempAry );
    1706           0 :                 if ( !aSizeName.isEmpty() )
    1707             :                 {
    1708           0 :                     ComboBox::InsertEntry( aSizeName, nPos );
    1709           0 :                     ComboBox::SetEntryData( nPos, reinterpret_cast<void*>(-(*pTempAry)) ); // mark as special
    1710           0 :                     nPos++;
    1711             :                 }
    1712           0 :                 pTempAry++;
    1713           0 :             }
    1714             :         }
    1715             :     }
    1716             : 
    1717             :     // then insert numerical font size values
    1718        1948 :     pTempAry = pAry;
    1719       62336 :     while ( *pTempAry )
    1720             :     {
    1721       58440 :         InsertValue( *pTempAry, FUNIT_NONE, nPos );
    1722       58440 :         ComboBox::SetEntryData( nPos, reinterpret_cast<void*>(*pTempAry) );
    1723       58440 :         nPos++;
    1724       58440 :         pTempAry++;
    1725             :     }
    1726             : 
    1727        1948 :     SetText( aStr );
    1728        1948 :     SetSelection( aSelection );
    1729             : }
    1730             : 
    1731           0 : void FontSizeBox::EnableRelativeMode( sal_uInt16 nMin, sal_uInt16 nMax, sal_uInt16 nStep )
    1732             : {
    1733           0 :     bRelativeMode = true;
    1734           0 :     nRelMin       = nMin;
    1735           0 :     nRelMax       = nMax;
    1736           0 :     nRelStep      = nStep;
    1737           0 :     SetUnit( FUNIT_POINT );
    1738           0 : }
    1739             : 
    1740           0 : void FontSizeBox::EnablePtRelativeMode( short nMin, short nMax, short nStep )
    1741             : {
    1742           0 :     bRelativeMode = true;
    1743           0 :     nPtRelMin     = nMin;
    1744           0 :     nPtRelMax     = nMax;
    1745           0 :     nPtRelStep    = nStep;
    1746           0 :     SetUnit( FUNIT_POINT );
    1747           0 : }
    1748             : 
    1749           0 : void FontSizeBox::SetRelative( bool bNewRelative )
    1750             : {
    1751           0 :     if ( bRelativeMode )
    1752             :     {
    1753           0 :         Selection aSelection = GetSelection();
    1754           0 :         OUString aStr = comphelper::string::stripStart(GetText(), ' ');
    1755             : 
    1756           0 :         if ( bNewRelative )
    1757             :         {
    1758           0 :             bRelative = true;
    1759           0 :             bStdSize = false;
    1760             : 
    1761           0 :             if ( bPtRelative )
    1762             :             {
    1763           0 :                 Clear(); //clear early because SetDecimalDigits is a slow recalc
    1764             : 
    1765           0 :                 SetDecimalDigits( 1 );
    1766           0 :                 SetMin( nPtRelMin );
    1767           0 :                 SetMax( nPtRelMax );
    1768           0 :                 SetUnit( FUNIT_POINT );
    1769             : 
    1770           0 :                 short i = nPtRelMin, n = 0;
    1771             :                 // JP 30.06.98: more than 100 values are not useful
    1772           0 :                 while ( i <= nPtRelMax && n++ < 100 )
    1773             :                 {
    1774           0 :                     InsertValue( i );
    1775           0 :                     i = i + nPtRelStep;
    1776             :                 }
    1777             :             }
    1778             :             else
    1779             :             {
    1780           0 :                 Clear(); //clear early because SetDecimalDigits is a slow recalc
    1781             : 
    1782           0 :                 SetDecimalDigits( 0 );
    1783           0 :                 SetMin( nRelMin );
    1784           0 :                 SetMax( nRelMax );
    1785           0 :                 SetUnit( FUNIT_PERCENT );
    1786             : 
    1787           0 :                 sal_uInt16 i = nRelMin;
    1788           0 :                 while ( i <= nRelMax )
    1789             :                 {
    1790           0 :                     InsertValue( i );
    1791           0 :                     i = i + nRelStep;
    1792             :                 }
    1793             :             }
    1794             :         }
    1795             :         else
    1796             :         {
    1797           0 :             if (pFontList)
    1798           0 :                 Clear(); //clear early because SetDecimalDigits is a slow recalc
    1799           0 :             bRelative = bPtRelative = false;
    1800           0 :             SetDecimalDigits( 1 );
    1801           0 :             SetMin( 20 );
    1802           0 :             SetMax( 9999 );
    1803           0 :             SetUnit( FUNIT_POINT );
    1804           0 :             if ( pFontList )
    1805           0 :                 Fill( &aFontInfo, pFontList );
    1806             :         }
    1807             : 
    1808           0 :         SetText( aStr );
    1809           0 :         SetSelection( aSelection );
    1810             :     }
    1811           0 : }
    1812             : 
    1813       77764 : OUString FontSizeBox::CreateFieldText( sal_Int64 nValue ) const
    1814             : {
    1815       77764 :     OUString sRet( MetricBox::CreateFieldText( nValue ) );
    1816       77764 :     if ( bRelativeMode && bPtRelative && (0 <= nValue) && !sRet.isEmpty() )
    1817           0 :         sRet = "+" + sRet;
    1818       77764 :     return sRet;
    1819             : }
    1820             : 
    1821        7636 : void FontSizeBox::SetValue( sal_Int64 nNewValue, FieldUnit eInUnit )
    1822             : {
    1823        7636 :     if ( !bRelative )
    1824             :     {
    1825        7636 :         sal_Int64 nTempValue = MetricField::ConvertValue( nNewValue, GetBaseValue(), GetDecimalDigits(), eInUnit, GetUnit() );
    1826        7636 :         FontSizeNames aFontSizeNames( GetSettings().GetUILanguageTag().getLanguageType() );
    1827             :         // conversion loses precision; however font sizes should
    1828             :         // never have a problem with that
    1829        7636 :         OUString aName = aFontSizeNames.Size2Name( static_cast<long>(nTempValue) );
    1830        7636 :         if ( !aName.isEmpty() && (GetEntryPos( aName ) != LISTBOX_ENTRY_NOTFOUND) )
    1831             :         {
    1832           0 :             mnLastValue = nTempValue;
    1833           0 :             SetText( aName );
    1834           0 :             mnFieldValue = mnLastValue;
    1835           0 :             SetEmptyFieldValueData( false );
    1836        7636 :             return;
    1837        7636 :         }
    1838             :     }
    1839             : 
    1840        7636 :     MetricBox::SetValue( nNewValue, eInUnit );
    1841             : }
    1842             : 
    1843        7636 : void FontSizeBox::SetValue( sal_Int64 nNewValue )
    1844             : {
    1845        7636 :     SetValue( nNewValue, FUNIT_NONE );
    1846        7636 : }
    1847             : 
    1848        6064 : sal_Int64 FontSizeBox::GetValue( FieldUnit eOutUnit ) const
    1849             : {
    1850        6064 :     if ( !bRelative )
    1851             :     {
    1852        6064 :         FontSizeNames aFontSizeNames( GetSettings().GetUILanguageTag().getLanguageType() );
    1853        6064 :         sal_Int64 nValue = aFontSizeNames.Name2Size( GetText() );
    1854        6064 :         if ( nValue)
    1855           0 :             return MetricField::ConvertValue( nValue, GetBaseValue(), GetDecimalDigits(), GetUnit(), eOutUnit );
    1856             :     }
    1857             : 
    1858        6064 :     return MetricBox::GetValue( eOutUnit );
    1859             : }
    1860             : 
    1861        6064 : sal_Int64 FontSizeBox::GetValue() const
    1862             : {
    1863             :     // implementation not inline, because it is a virtual function
    1864        6064 :     return GetValue( FUNIT_NONE );
    1865        1227 : }
    1866             : 
    1867             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10