[Libreoffice-commits] core.git: Branch 'libreoffice-4-4' - svx/source

Caolán McNamara caolanm at redhat.com
Tue Apr 21 14:18:22 PDT 2015


 svx/source/tbxctrls/tbcontrl.cxx |  184 +++++++++++++++++++++++++--------------
 1 file changed, 119 insertions(+), 65 deletions(-)

New commits:
commit 7c66a574ff2532e27b24aec32ac2e590bedffef1
Author: Caolán McNamara <caolanm at redhat.com>
Date:   Tue Apr 21 14:39:57 2015 +0100

    Resolves: tdf#76825 styles drop down menu is too narrow
    
    fix indent
    
    Change-Id: I2628ac3fbabe9f33c41c7f3612eae608fb854ae3
    (cherry picked from commit 7cf22a0a3202da296c1d1a3dafe6e1e5e1d7405d)
    
    break out text drawing bit as UserDrawEntry
    
    Change-Id: Icb1bcfb5f9f7475f67c9c001efdad2aa7e0d0834
    (cherry picked from commit e29e3f47e687689c824d71718ae2ccaa4846ac51)
    
    draw all entries the same way
    
    Change-Id: I9da3c8dca4db4a02197a67e1fbedd9b525dc7768
    (cherry picked from commit b28ba9dbd00da1094fcd53f6370c04b7caa99d7d)
    
    split out the code that sets up the device for each entry
    
    Change-Id: Iad426e1cb1eaac24edf1e7bb61307f29d33d8786
    (cherry picked from commit e367337e58047c4c69869330b36c1f027f5ca5f0)
    
    refactor for reuse
    
    Change-Id: I46e04464376324c7e48fe0ccf7362c3a4256e3c2
    (cherry picked from commit fa4c2d8a744049b7389d2020ce84bbb28d945c51)
    
    Change-Id: I3d1ba1da40990df2427f0d380a85d5e704f37038
    (cherry picked from commit 856e9b5fe2293bef9c45219391aca664d4a0dd20)
    Reviewed-on: https://gerrit.libreoffice.org/15471
    Reviewed-by: Adolfo Jayme Barrientos <fitojb at ubuntu.com>
    Tested-by: Adolfo Jayme Barrientos <fitojb at ubuntu.com>

diff --git a/svx/source/tbxctrls/tbcontrl.cxx b/svx/source/tbxctrls/tbcontrl.cxx
index 8216a9f7..d12b4bb 100644
--- a/svx/source/tbxctrls/tbcontrl.cxx
+++ b/svx/source/tbxctrls/tbcontrl.cxx
@@ -127,7 +127,7 @@ public:
     virtual ~SvxStyleBox_Impl();
 
     void            SetFamily( SfxStyleFamily eNewFamily );
-    inline bool IsVisible() { return bVisible; }
+    bool            IsVisible() const { return bVisible; }
 
     virtual bool    PreNotify( NotifyEvent& rNEvt ) SAL_OVERRIDE;
     virtual bool    Notify( NotifyEvent& rNEvt ) SAL_OVERRIDE;
@@ -136,10 +136,12 @@ public:
 
     virtual void    UserDraw( const UserDrawEvent& rUDEvt ) SAL_OVERRIDE;
 
-    inline void     SetVisibilityListener( const Link& aVisListener ) { aVisibilityListener = aVisListener; }
+    void            SetVisibilityListener( const Link& aVisListener ) { aVisibilityListener = aVisListener; }
 
     void            SetDefaultStyle( const OUString& rDefault ) { sDefaultStyle = rDefault; }
 
+    void            CalcOptimalExtraUserWidth();
+
 protected:
     virtual void    Select() SAL_OVERRIDE;
 
@@ -162,6 +164,9 @@ private:
 
     void            ReleaseFocus();
     Color           TestColorsVisible(const Color &FontCol, const Color &BackCol);
+    void            UserDrawEntry(const UserDrawEvent& rUDEvt, const OUString &rStyleName);
+    void            SetupEntry(sal_uInt16 nItem, const Rectangle& rRect, OutputDevice *pDevice, const OUString &rStyleName, bool bIsNotSelected);
+    bool            AdjustFontForItemHeight(OutputDevice* pDevice, Rectangle& rTextRect, long nHeight);
     DECL_LINK( MenuSelectHdl, Menu * );
 };
 
@@ -299,6 +304,9 @@ class SfxStyleControllerItem_Impl : public SfxStatusListener
         SvxStyleToolBoxControl& rControl;
 };
 
+#define BUTTON_WIDTH 20
+#define ITEM_HEIGHT 30
+
 SvxStyleBox_Impl::SvxStyleBox_Impl(vcl::Window* pParent,
                                    const OUString& rCommand,
                                    SfxStyleFamily eFamily,
@@ -326,7 +334,7 @@ SvxStyleBox_Impl::SvxStyleBox_Impl(vcl::Window* pParent,
     aLogicalSize = PixelToLogic( GetSizePixel(), MAP_APPFONT );
     EnableAutocomplete( true );
     EnableUserDraw( true );
-    SetUserItemSize( Size( 0, 30 ) );
+    SetUserItemSize( Size( 0, ITEM_HEIGHT ) );
 }
 
 SvxStyleBox_Impl::~SvxStyleBox_Impl()
@@ -550,18 +558,51 @@ void SvxStyleBox_Impl::StateChanged( StateChangedType nStateChange )
     }
 }
 
-void SvxStyleBox_Impl::UserDraw( const UserDrawEvent& rUDEvt )
+bool SvxStyleBox_Impl::AdjustFontForItemHeight(OutputDevice* pDevice, Rectangle& rTextRect, long nHeight)
 {
-    sal_uInt16 nItem = rUDEvt.GetItemId();
+    if (rTextRect.Bottom() > nHeight)
+    {
+        // the text does not fit, adjust the font size
+        double ratio = static_cast< double >( nHeight ) / rTextRect.Bottom();
+        vcl::Font aFont(pDevice->GetFont());
+        Size aPixelSize(aFont.GetSize());
+        aPixelSize.Width() *= ratio;
+        aPixelSize.Height() *= ratio;
+        aFont.SetSize(aPixelSize);
+        pDevice->SetFont(aFont);
+        return true;
+    }
+    return false;
+}
+
+void SvxStyleBox_Impl::UserDrawEntry(const UserDrawEvent& rUDEvt, const OUString &rStyleName)
+{
+    OutputDevice *pDevice = rUDEvt.GetDevice();
+
+    // IMG_TXT_DISTANCE in ilstbox.hxx is 6, then 1 is added as
+    // nBorder, and we are adding 1 in order to look better when
+    // italics is present
+    const int nLeftDistance = 8;
+
+    Rectangle aTextRect;
+    pDevice->GetTextBoundRect(aTextRect, rStyleName);
+
+    Point aPos( rUDEvt.GetRect().TopLeft() );
+    aPos.X() += nLeftDistance;
+
+    if (!AdjustFontForItemHeight(pDevice, aTextRect, rUDEvt.GetRect().GetHeight()))
+        aPos.Y() += ( rUDEvt.GetRect().GetHeight() - aTextRect.Bottom() ) / 2;
 
-    if ( nItem == 0 || nItem == GetEntryCount() - 1 )
+    pDevice->DrawText(aPos, rStyleName);
+}
+
+void SvxStyleBox_Impl::SetupEntry(sal_uInt16 nItem, const Rectangle& rRect, OutputDevice* pDevice, const OUString& rStyleName, bool bIsNotSelected)
+{
+    if (nItem == 0 || nItem == GetEntryCount() - 1)
     {
-        Rectangle aRect(rUDEvt.GetRect());
-        unsigned int nId = (aRect.getY() / aRect.GetSize().Height());
+        unsigned int nId = (rRect.getY() / rRect.GetSize().Height());
         if(nId < MAX_STYLES_ENTRIES && m_pButtons[nId])
             m_pButtons[nId]->Hide();
-        // draw the non-style entries, ie. "Clear Formatting" or "More..."
-        DrawEntry( rUDEvt, true, true );
     }
     else
     {
@@ -569,23 +610,16 @@ void SvxStyleBox_Impl::UserDraw( const UserDrawEvent& rUDEvt )
         SfxStyleSheetBasePool* pPool = pShell->GetStyleSheetPool();
         SfxStyleSheetBase* pStyle = NULL;
 
-        OUString aStyleName( GetEntry( nItem ) );
-
         if ( pPool )
         {
             pPool->SetSearchMask( eStyleFamily, SFXSTYLEBIT_ALL );
 
             pStyle = pPool->First();
-            while ( pStyle && OUString( pStyle->GetName() ) != aStyleName )
+            while (pStyle && pStyle->GetName() != rStyleName)
                 pStyle = pPool->Next();
         }
 
-        if ( !pStyle )
-        {
-            // cannot find the style for whatever reason
-            DrawEntry( rUDEvt, true, true );
-        }
-        else
+        if (pStyle )
         {
             const SfxItemSet& aItemSet = pStyle->GetItemSet();
 
@@ -594,8 +628,6 @@ void SvxStyleBox_Impl::UserDraw( const UserDrawEvent& rUDEvt )
 
             if ( pFontItem && pFontHeightItem )
             {
-                OutputDevice *pDevice = rUDEvt.GetDevice();
-
                 Size aFontSize( 0, pFontHeightItem->GetHeight() );
                 Size aPixelSize( pDevice->LogicToPixel( aFontSize, pShell->GetMapUnit() ) );
 
@@ -647,25 +679,21 @@ void SvxStyleBox_Impl::UserDraw( const UserDrawEvent& rUDEvt )
 
                 // setup the device & draw
                 vcl::Font aOldFont( pDevice->GetFont() );
-                Color aOldColor( pDevice->GetTextColor() );
-                Color aOldFillColor( pDevice->GetFillColor() );
 
                 Color aFontCol = COL_AUTO, aBackCol = COL_AUTO;
 
                 pDevice->SetFont( aFont );
 
-                bool IsNotSelected = rUDEvt.GetItemId() != GetSelectEntryPos();
-
                 pItem = aItemSet.GetItem( SID_ATTR_CHAR_COLOR );
                 // text color, when nothing is selected
-                if ( (NULL != pItem) && IsNotSelected)
+                if ( (NULL != pItem) && bIsNotSelected)
                     aFontCol = Color( static_cast< const SvxColorItem* >( pItem )->GetValue() );
 
                 sal_uInt16 style = drawing::FillStyle_NONE;
                 // which kind of Fill style is selected
                 pItem = aItemSet.GetItem( XATTR_FILLSTYLE );
                 // only when ok and not selected
-                if ( (NULL != pItem) && IsNotSelected)
+                if ( (NULL != pItem) && bIsNotSelected)
                     style = static_cast< const XFillStyleItem* >( pItem )->GetValue();
 
                 switch(style)
@@ -680,13 +708,13 @@ void SvxStyleBox_Impl::UserDraw( const UserDrawEvent& rUDEvt )
                         if ( aBackCol != COL_AUTO )
                         {
                             pDevice->SetFillColor( aBackCol );
-                            pDevice->DrawRect( rUDEvt.GetRect() );
+                            pDevice->DrawRect(rRect);
                         }
                     }
                     break;
 
                     //TODO Draw the other background styles: gradient, hatching and bitmap
-               }
+                }
 
                 // when the font and background color are too similar, adjust the Font-Color
                 if( (aFontCol != COL_AUTO) || (aBackCol != COL_AUTO) )
@@ -697,65 +725,89 @@ void SvxStyleBox_Impl::UserDraw( const UserDrawEvent& rUDEvt )
                     pDevice->SetTextColor( aFontCol );
 
                 // handle the push-button
-                if (IsNotSelected)
+                if (bIsNotSelected)
                 {
-                    Rectangle aRect(rUDEvt.GetRect());
-                    unsigned int nId = (aRect.getY() / aRect.GetSize().Height());
+                    unsigned int nId = (rRect.getY() / rRect.GetSize().Height());
                     if(nId < MAX_STYLES_ENTRIES && m_pButtons[nId])
                         m_pButtons[nId]->Hide();
                 }
                 else
                 {
-                    Rectangle aRect(rUDEvt.GetRect());
-                    unsigned int nId = (aRect.getY() / aRect.GetSize().Height());
+                    unsigned int nId = (rRect.getY() / rRect.GetSize().Height());
                     if(nId < MAX_STYLES_ENTRIES)
                     {
                         if(m_pButtons[nId] == NULL)
                         {
                             m_pButtons[nId] = new MenuButton(static_cast<vcl::Window*>(pDevice), WB_FLATBUTTON | WB_NOPOINTERFOCUS);
-                            m_pButtons[nId]->SetSizePixel(Size(20, aRect.GetSize().Height()));
+                            m_pButtons[nId]->SetSizePixel(Size(BUTTON_WIDTH, rRect.GetSize().Height()));
                             m_pButtons[nId]->SetPopupMenu(&m_aMenu);
                         }
-                        m_pButtons[nId]->SetPosPixel(Point(aRect.GetWidth() - 20, aRect.getY()));
+                        m_pButtons[nId]->SetPosPixel(Point(rRect.GetWidth() - BUTTON_WIDTH, rRect.getY()));
                         m_pButtons[nId]->Show();
                     }
                 }
+            }
+        }
+    }
+}
 
-                // IMG_TXT_DISTANCE in ilstbox.hxx is 6, then 1 is added as
-                // nBorder, and we are adding 1 in order to look better when
-                // italics is present
-                const int nLeftDistance = 8;
+void SvxStyleBox_Impl::UserDraw( const UserDrawEvent& rUDEvt )
+{
+    sal_uInt16 nItem = rUDEvt.GetItemId();
+    OUString aStyleName( GetEntry( nItem ) );
 
-                Rectangle aTextRect;
-                pDevice->GetTextBoundRect( aTextRect, aStyleName );
+    OutputDevice *pDevice = rUDEvt.GetDevice();
+    pDevice->Push(PushFlags::FILLCOLOR | PushFlags::FONT | PushFlags::TEXTCOLOR);
 
-                Point aPos( rUDEvt.GetRect().TopLeft() );
-                aPos.X() += nLeftDistance;
-                if ( aTextRect.Bottom() > rUDEvt.GetRect().GetHeight() )
-                {
-                    // the text does not fit, adjust the font size
-                    double ratio = static_cast< double >( rUDEvt.GetRect().GetHeight() ) / aTextRect.Bottom();
-                    aPixelSize.Width() *= ratio;
-                    aPixelSize.Height() *= ratio;
-                    aFont.SetSize( aPixelSize );
-                    pDevice->SetFont( aFont );
-                }
-                else
-                    aPos.Y() += ( rUDEvt.GetRect().GetHeight() - aTextRect.Bottom() ) / 2;
+    const Rectangle& rRect(rUDEvt.GetRect());
+    bool bIsNotSelected = rUDEvt.GetItemId() != GetSelectEntryPos();
 
-                pDevice->DrawText( aPos, aStyleName );
+    SetupEntry(nItem, rRect, pDevice, aStyleName, bIsNotSelected);
 
-                pDevice->SetFillColor( aOldFillColor );
-                pDevice->SetTextColor( aOldColor );
-                pDevice->SetFont( aOldFont );
+    UserDrawEntry(rUDEvt, aStyleName);
 
-                // draw separator, if present
-                DrawEntry( rUDEvt, false, false );
-            }
-            else
-                DrawEntry( rUDEvt, true, true );
+    pDevice->Pop();
+    // draw separator, if present
+    DrawEntry( rUDEvt, false, false );
+}
+
+void SvxStyleBox_Impl::CalcOptimalExtraUserWidth()
+{
+    long nMaxNormalFontWidth = 0;
+    sal_Int32 nEntryCount = GetEntryCount();
+    for (sal_Int32 i = 0; i < nEntryCount; ++i)
+    {
+        OUString sStyleName(GetEntry(i));
+        Rectangle aTextRectForDefaultFont;
+        GetTextBoundRect(aTextRectForDefaultFont, sStyleName);
+
+        const long nWidth = aTextRectForDefaultFont.GetWidth();
+
+        nMaxNormalFontWidth = std::max(nWidth, nMaxNormalFontWidth);
+    }
+
+    long nMaxUserDrawFontWidth = nMaxNormalFontWidth;
+    for (sal_Int32 i = 1; i < nEntryCount-1; ++i)
+    {
+        OUString sStyleName(GetEntry(i));
+
+        Push(PushFlags::FILLCOLOR | PushFlags::FONT | PushFlags::TEXTCOLOR);
+        SetupEntry(i, Rectangle(0, 0, RECT_MAX, ITEM_HEIGHT), this, sStyleName, false);
+        Rectangle aTextRectForActualFont;
+        GetTextBoundRect(aTextRectForActualFont, sStyleName);
+        if (AdjustFontForItemHeight(this, aTextRectForActualFont, ITEM_HEIGHT))
+        {
+            //Font didn't fit, so it was changed, refetch with final font size
+            GetTextBoundRect(aTextRectForActualFont, sStyleName);
         }
+        Pop();
+
+        const long nWidth = aTextRectForActualFont.GetWidth() + BUTTON_WIDTH;
+
+        nMaxUserDrawFontWidth = std::max(nWidth, nMaxUserDrawFontWidth);
     }
+
+    SetUserItemSize(Size(nMaxUserDrawFontWidth - nMaxNormalFontWidth, ITEM_HEIGHT));
 }
 
 // test is the color between Font- and background-color to be identify
@@ -2094,7 +2146,7 @@ void SvxStyleToolBoxControl::FillStyleBox()
     if ( pStyleSheetPool && pBox && nActFamily!=0xffff )
     {
         const SfxStyleFamily    eFamily     = GetActFamily();
-        sal_uInt16                  nCount      = pStyleSheetPool->Count();
+        sal_uInt16              nCount      = pStyleSheetPool->Count();
         SfxStyleSheetBase*      pStyle      = NULL;
         bool                    bDoFill     = false;
 
@@ -2195,6 +2247,8 @@ void SvxStyleToolBoxControl::FillStyleBox()
             sal_uInt16 nLines = static_cast<sal_uInt16>(
                     std::min( pBox->GetEntryCount(), static_cast<sal_Int32>(MAX_STYLES_ENTRIES)));
             pBox->SetDropDownLineCount( nLines );
+
+            pBox->CalcOptimalExtraUserWidth();
         }
     }
 }


More information about the Libreoffice-commits mailing list