[Libreoffice-commits] core.git: include/vcl toolkit/source vcl/source

Jan-Marek Glogowski (via logerrit) logerrit at kemper.freedesktop.org
Fri Jun 21 14:49:19 UTC 2019


 include/vcl/tabctrl.hxx                     |   21 -
 toolkit/source/awt/vclxtabpagecontainer.cxx |    2 
 vcl/source/control/tabctrl.cxx              |  569 +++++++---------------------
 3 files changed, 154 insertions(+), 438 deletions(-)

New commits:
commit 6540912ae1a570fd8c2318f77b757e07b87c0707
Author:     Jan-Marek Glogowski <glogow at fbihome.de>
AuthorDate: Sun Jun 16 21:41:31 2019 +0000
Commit:     Jan-Marek Glogowski <glogow at fbihome.de>
CommitDate: Fri Jun 21 16:47:47 2019 +0200

    VCL merge most of NotebookbarTabControlBase
    
    NotebookbarTabControlBase (NBBTCB) tried to be clever and save
    a bool per TabControl page, by not adding a mbVisible to the
    ImplTabItem and misuse mbEnabled.
    
    The result is not only a bug with tab highlighting in notebook
    bars, but also a lot of duplicate code and additional virtual
    functions. Normal TabControls highlight correct.
    
    I'm not 100% sure about the dropped Resize()s, but the code in
    ImplPaint() and calculateRequisition() differs by three lines;
    which can be merged by adding the TabControl feature to hide
    tabs and not just disable them. I first tried to additionally
    merge ImplPlaceTabs() too, but the NBBTCB version differs much
    more and I didn't want to touch larger parts of TabControl.
    
    Change-Id: Ie6e18fb03b76b46e3627923eb1ac0f674c3eb7e8
    Reviewed-on: https://gerrit.libreoffice.org/74126
    Tested-by: Jenkins
    Reviewed-by: Jan-Marek Glogowski <glogow at fbihome.de>

diff --git a/include/vcl/tabctrl.hxx b/include/vcl/tabctrl.hxx
index cf64e66efc64..956c5ece7a6b 100644
--- a/include/vcl/tabctrl.hxx
+++ b/include/vcl/tabctrl.hxx
@@ -64,8 +64,10 @@ protected:
     using Control::ImplInitSettings;
     SAL_DLLPRIVATE void         ImplInitSettings( bool bBackground );
     SAL_DLLPRIVATE ImplTabItem* ImplGetItem( sal_uInt16 nId ) const;
+    SAL_DLLPRIVATE ImplTabItem* ImplGetItem(const Point& rPt) const;
     SAL_DLLPRIVATE Size         ImplGetItemSize( ImplTabItem* pItem, long nMaxWidth );
     SAL_DLLPRIVATE tools::Rectangle    ImplGetTabRect( sal_uInt16 nPos, long nWidth = -1, long nHeight = -1 );
+    SAL_DLLPRIVATE tools::Rectangle ImplGetTabRect(const ImplTabItem*, long nWidth = -1, long nHeight = -1);
     SAL_DLLPRIVATE void         ImplChangeTabPage( sal_uInt16 nId, sal_uInt16 nOldId );
     SAL_DLLPRIVATE bool         ImplPosCurTabPage();
     virtual void                ImplActivateTabPage( bool bNext );
@@ -85,9 +87,8 @@ protected:
     virtual void                FillLayoutData() const override;
     virtual const vcl::Font&    GetCanonicalFont( const StyleSettings& _rStyle ) const override;
     virtual const Color&        GetCanonicalTextColor( const StyleSettings& _rStyle ) const override;
-    SAL_DLLPRIVATE tools::Rectangle*   ImplFindPartRect( const Point& rPt );
     virtual bool                ImplPlaceTabs( long nWidth );
-    virtual void                ImplPaint(vcl::RenderContext& rRenderContext, const tools::Rectangle& rRect);
+    SAL_DLLPRIVATE Size ImplCalculateRequisition(sal_uInt16& nHeaderHeight) const;
 
 public:
                         TabControl( vcl::Window* pParent,
@@ -124,21 +125,23 @@ public:
                                     sal_uInt16 nPos = TAB_APPEND );
     void                RemovePage( sal_uInt16 nPageId );
     void                Clear();
-    void                EnablePage( sal_uInt16 nPageId, bool bEnable = true );
+
+    void SetPageEnabled(sal_uInt16 nPageId, bool bEnable = true);
+    void SetPageVisible(sal_uInt16 nPageId, bool bVisible = true);
 
     sal_uInt16          GetPagePos( sal_uInt16 nPageId ) const;
     sal_uInt16          GetPageCount() const;
     sal_uInt16          GetPageId( sal_uInt16 nPos ) const;
-    virtual sal_uInt16  GetPageId( const Point& rPos ) const;
+    sal_uInt16 GetPageId(const Point& rPos) const;
     sal_uInt16          GetPageId( const TabPage& rPage ) const;
     sal_uInt16          GetPageId( const OString& rName ) const;
 
-    virtual void        SetCurPageId( sal_uInt16 nPageId );
+    void SetCurPageId(sal_uInt16 nPageId);
     sal_uInt16          GetCurPageId() const;
 
-    virtual void        SelectTabPage( sal_uInt16 nPageId );
+    void                SelectTabPage( sal_uInt16 nPageId );
 
-    void                SetTabPage( sal_uInt16 nPageId, TabPage* pPage );
+    void SetTabPage(sal_uInt16 nPageId, TabPage* pPage);
     TabPage*            GetTabPage( sal_uInt16 nPageId ) const;
 
     void                SetPageText( sal_uInt16 nPageId, const OUString& rText );
@@ -203,15 +206,11 @@ public:
     ToolBox* GetToolBox() { return m_pShortcuts; }
     PushButton* GetOpenMenu() { return m_pOpenMenu; }
 
-    virtual sal_uInt16  GetPageId( const Point& rPos ) const override;
-    virtual void        SelectTabPage( sal_uInt16 nPageId ) override;
-    virtual void        SetCurPageId( sal_uInt16 nPageId ) override;
     virtual Size        calculateRequisition() const override;
     static sal_uInt16   GetHeaderHeight();
 
 protected:
     virtual bool ImplPlaceTabs( long nWidth ) override;
-    virtual void ImplPaint(vcl::RenderContext& rRenderContext, const tools::Rectangle& rRect) override;
     virtual void ImplActivateTabPage( bool bNext ) override;
 
 private:
diff --git a/toolkit/source/awt/vclxtabpagecontainer.cxx b/toolkit/source/awt/vclxtabpagecontainer.cxx
index 56e492ea8069..25ff686c5466 100644
--- a/toolkit/source/awt/vclxtabpagecontainer.cxx
+++ b/toolkit/source/awt/vclxtabpagecontainer.cxx
@@ -190,7 +190,7 @@ void SAL_CALL VCLXTabPageContainer::elementInserted( const css::container::Conta
     pTabCtrl->SetHelpText(nPageID,xP->getToolTip());
     pTabCtrl->SetPageImage(nPageID,TkResMgr::getImageFromURL(xP->getImageURL()));
     pTabCtrl->SelectTabPage(nPageID);
-    pTabCtrl->EnablePage(nPageID,xP->getEnabled());
+    pTabCtrl->SetPageEnabled(nPageID,xP->getEnabled());
     m_aTabPages.push_back(xTabPage);
 
 }
diff --git a/vcl/source/control/tabctrl.cxx b/vcl/source/control/tabctrl.cxx
index d5b9eeeeacfa..d23db1eaf9cf 100644
--- a/vcl/source/control/tabctrl.cxx
+++ b/vcl/source/control/tabctrl.cxx
@@ -56,12 +56,15 @@ struct ImplTabItem
     tools::Rectangle    maRect;
     sal_uInt16          mnLine;
     bool                mbFullVisible;
-    bool                mbEnabled;
+    bool                m_bEnabled; ///< the tab / page is selectable
+    bool                m_bVisible; ///< the tab / page can be visible
     Image               maTabImage;
 
     ImplTabItem()
     : mnId( 0 ), mpTabPage( nullptr ),
-      mnLine( 0 ), mbFullVisible( false ), mbEnabled( true )
+      mnLine( 0 ), mbFullVisible( false )
+        , m_bEnabled(true)
+        , m_bVisible(true)
     {}
 };
 
@@ -400,6 +403,9 @@ bool TabControl::ImplPlaceTabs( long nWidth )
 
     for (auto & item : mpTabCtrlData->maItemList)
     {
+        if (!item.m_bVisible)
+            continue;
+
         Size aSize = ImplGetItemSize( &item, nMaxWidth );
 
         bool bNewLine = false;
@@ -531,8 +537,8 @@ tools::Rectangle TabControl::ImplGetTabRect( sal_uInt16 nItemPos, long nWidth, l
         long nW = nWidth-TAB_OFFSET*2;
         long nH = nHeight-TAB_OFFSET*2;
         return (nW > 0 && nH > 0)
-        ? tools::Rectangle( Point( TAB_OFFSET, TAB_OFFSET ), Size( nW, nH ) )
-        : tools::Rectangle();
+            ? tools::Rectangle(Point(TAB_OFFSET, TAB_OFFSET), Size(nW, nH))
+            : tools::Rectangle();
     }
 
     if ( nItemPos == TAB_PAGERECT )
@@ -546,19 +552,26 @@ tools::Rectangle TabControl::ImplGetTabRect( sal_uInt16 nItemPos, long nWidth, l
         tools::Rectangle aRect = ImplGetTabRect( nLastPos, nWidth, nHeight );
         if (aRect.IsEmpty())
             return aRect;
+
         long nW = nWidth-TAB_OFFSET*2;
         long nH = nHeight-aRect.Bottom()-TAB_OFFSET*2;
-        aRect = (nW > 0 && nH > 0)
+        return (nW > 0 && nH > 0)
             ? tools::Rectangle( Point( TAB_OFFSET, aRect.Bottom()+TAB_OFFSET ), Size( nW, nH ) )
             : tools::Rectangle();
-        return aRect;
     }
 
-    nWidth -= 1;
+    ImplTabItem* const pItem = (nItemPos < mpTabCtrlData->maItemList.size())
+                               ? &mpTabCtrlData->maItemList[nItemPos] : nullptr;
+    return ImplGetTabRect(pItem, nWidth, nHeight);
+}
 
-    if ( (nWidth <= 0) || (nHeight <= 0) )
+tools::Rectangle TabControl::ImplGetTabRect(const ImplTabItem* pItem, long nWidth, long nHeight)
+{
+    if ((nWidth <= 1) || (nHeight <= 0) || !pItem || !pItem->m_bVisible)
         return tools::Rectangle();
 
+    nWidth -= 1;
+
     if ( mbFormat || (mnLastWidth != nWidth) || (mnLastHeight != nHeight) )
     {
         vcl::Font aFont( GetFont() );
@@ -574,7 +587,7 @@ tools::Rectangle TabControl::ImplGetTabRect( sal_uInt16 nItemPos, long nWidth, l
         mbFormat        = false;
     }
 
-    return size_t(nItemPos) < mpTabCtrlData->maItemList.size() ? mpTabCtrlData->maItemList[nItemPos].maRect : tools::Rectangle();
+    return pItem->maRect;
 }
 
 void TabControl::ImplChangeTabPage( sal_uInt16 nId, sal_uInt16 nOldId )
@@ -763,7 +776,7 @@ void TabControl::ImplShowFocus()
 void TabControl::ImplDrawItem(vcl::RenderContext& rRenderContext, ImplTabItem const * pItem, const tools::Rectangle& rCurRect,
                               bool bFirstInGroup, bool bLastInGroup )
 {
-    if (pItem->maRect.IsEmpty())
+    if (!pItem->m_bVisible || pItem->maRect.IsEmpty())
         return;
 
     const StyleSettings& rStyleSettings = rRenderContext.GetSettings().GetStyleSettings();
@@ -827,13 +840,12 @@ void TabControl::ImplDrawItem(vcl::RenderContext& rRenderContext, ImplTabItem co
     {
         nState |= ControlState::ROLLOVER;
         for (auto const& item : mpTabCtrlData->maItemList)
-        {
-            if( (&item != pItem) && (item.maRect.IsInside(GetPointerPosPixel())))
+            if ((&item != pItem) && item.m_bVisible && item.maRect.IsInside(GetPointerPosPixel()))
             {
                 nState &= ~ControlState::ROLLOVER; // avoid multiple highlighted tabs
                 break;
             }
-        }
+        assert(nState & ControlState::ROLLOVER);
     }
 
     bNativeOK = rRenderContext.IsNativeControlSupported(ControlType::TabItem, ControlPart::Entire);
@@ -923,7 +935,7 @@ void TabControl::ImplDrawItem(vcl::RenderContext& rRenderContext, ImplTabItem co
     if (!pItem->maFormatText.isEmpty())
     {
         DrawTextFlags nStyle = DrawTextFlags::Mnemonic;
-        if (!pItem->mbEnabled)
+        if (!pItem->m_bEnabled)
             nStyle |= DrawTextFlags::Disable;
 
         Color aColor(rStyleSettings.GetTabTextColor());
@@ -948,7 +960,7 @@ void TabControl::ImplDrawItem(vcl::RenderContext& rRenderContext, ImplTabItem co
         Point aImgTL( nXPos, aRect.Top() );
         if (aImageSize.Height() < aRect.GetHeight())
             aImgTL.AdjustY((aRect.GetHeight() - aImageSize.Height()) / 2 );
-        rRenderContext.DrawImage(aImgTL, pItem->maTabImage, pItem->mbEnabled ? DrawImageFlags::NONE : DrawImageFlags::Disable );
+        rRenderContext.DrawImage(aImgTL, pItem->maTabImage, pItem->m_bEnabled ? DrawImageFlags::NONE : DrawImageFlags::Disable );
     }
 }
 
@@ -1005,16 +1017,12 @@ IMPL_LINK( TabControl, ImplWindowEventListener, VclWindowEvent&, rEvent, void )
 
 void TabControl::MouseButtonDown( const MouseEvent& rMEvt )
 {
-    if( mpTabCtrlData->mpListBox.get() == nullptr )
-    {
-        if( rMEvt.IsLeft() )
-        {
-            sal_uInt16 nPageId = GetPageId( rMEvt.GetPosPixel() );
-            ImplTabItem* pItem = ImplGetItem( nPageId );
-            if( pItem && pItem->mbEnabled )
-                SelectTabPage( nPageId );
-        }
-    }
+    if (mpTabCtrlData->mpListBox.get() != nullptr || !rMEvt.IsLeft())
+        return;
+
+    ImplTabItem *pItem = ImplGetItem(rMEvt.GetPosPixel());
+    if (pItem && pItem->m_bEnabled)
+        SelectTabPage(pItem->mnId);
 }
 
 void TabControl::KeyInput( const KeyEvent& rKEvt )
@@ -1036,14 +1044,21 @@ void TabControl::KeyInput( const KeyEvent& rKEvt )
     Control::KeyInput( rKEvt );
 }
 
-void TabControl::Paint( vcl::RenderContext& rRenderContext, const tools::Rectangle& rRect)
+static bool lcl_canPaint(const vcl::RenderContext& rRenderContext, const tools::Rectangle& rDrawRect,
+                         const tools::Rectangle& rItemRect)
 {
-    if (!(GetStyle() & WB_NOBORDER))
-        ImplPaint(rRenderContext, rRect);
+    vcl::Region aClipRgn(rRenderContext.GetActiveClipRegion());
+    aClipRgn.Intersect(rItemRect);
+    if (!rDrawRect.IsEmpty())
+        aClipRgn.Intersect(rDrawRect);
+    return !aClipRgn.IsEmpty();
 }
 
-void TabControl::ImplPaint(vcl::RenderContext& rRenderContext, const tools::Rectangle& rRect)
+void TabControl::Paint( vcl::RenderContext& rRenderContext, const tools::Rectangle& rRect)
 {
+    if (GetStyle() & WB_NOBORDER)
+        return;
+
     HideFocus();
 
     // reformat if needed
@@ -1091,31 +1106,16 @@ void TabControl::ImplPaint(vcl::RenderContext& rRenderContext, const tools::Rect
         if (HasFocus())
             nState |= ControlState::FOCUSED;
 
-        vcl::Region aClipRgn(rRenderContext.GetActiveClipRegion());
-        aClipRgn.Intersect(aRect);
-        if (!rRect.IsEmpty())
-            aClipRgn.Intersect(rRect);
-
-        if (!aClipRgn.IsEmpty())
-        {
+        if (lcl_canPaint(rRenderContext, rRect, aRect))
             rRenderContext.DrawNativeControl(ControlType::TabPane, ControlPart::Entire,
                                              aRect, nState, aControlValue, OUString());
-        }
 
         if (rRenderContext.IsNativeControlSupported(ControlType::TabHeader, ControlPart::Entire))
         {
             tools::Rectangle aHeaderRect(aRect.Left(), 0, aRect.Right(), aRect.Top());
-
-            aClipRgn = rRenderContext.GetActiveClipRegion();
-            aClipRgn.Intersect(aHeaderRect);
-            if (!rRect.IsEmpty())
-                aClipRgn.Intersect(rRect);
-
-            if (!aClipRgn.IsEmpty())
-            {
+            if (lcl_canPaint(rRenderContext, rRect, aHeaderRect))
                 rRenderContext.DrawNativeControl(ControlType::TabHeader, ControlPart::Entire,
                                                  aHeaderRect, nState, aControlValue, OUString());
-            }
         }
     }
     else
@@ -1195,18 +1195,8 @@ void TabControl::ImplPaint(vcl::RenderContext& rRenderContext, const tools::Rect
         {
             ImplTabItem* pItem = &mpTabCtrlData->maItemList[idx];
 
-            if (pItem != pCurItem)
-            {
-                vcl::Region aClipRgn(rRenderContext.GetActiveClipRegion());
-                aClipRgn.Intersect(pItem->maRect);
-                if (!rRect.IsEmpty())
-                    aClipRgn.Intersect(rRect);
-                if (!aClipRgn.IsEmpty())
-                {
-                    ImplDrawItem(rRenderContext, pItem, aCurRect,
-                                 pItem == pFirstTab, pItem == pLastTab);
-                }
-            }
+            if (pItem != pCurItem && pItem->m_bVisible && lcl_canPaint(rRenderContext, rRect, pItem->maRect))
+                ImplDrawItem(rRenderContext, pItem, aCurRect, pItem == pFirstTab, pItem == pLastTab);
 
             if (bDrawTabsRTL)
                 idx--;
@@ -1214,24 +1204,16 @@ void TabControl::ImplPaint(vcl::RenderContext& rRenderContext, const tools::Rect
                 idx++;
         }
 
-        if (pCurItem)
-        {
-            vcl::Region aClipRgn(rRenderContext.GetActiveClipRegion());
-            aClipRgn.Intersect(pCurItem->maRect);
-            if (!rRect.IsEmpty())
-                aClipRgn.Intersect(rRect);
-            if (!aClipRgn.IsEmpty())
-            {
-                ImplDrawItem(rRenderContext, pCurItem, aCurRect,
-                             pCurItem == pFirstTab, pCurItem == pLastTab);
-            }
-        }
+        if (pCurItem && lcl_canPaint(rRenderContext, rRect, pCurItem->maRect))
+            ImplDrawItem(rRenderContext, pCurItem, aCurRect, pCurItem == pFirstTab, pCurItem == pLastTab);
     }
 
     if (HasFocus())
         ImplShowFocus();
 
     mbSmallInvalidate = true;
+
+    Control::Paint(rRenderContext, rRect);
 }
 
 void TabControl::setAllocation(const Size &rAllocation)
@@ -1263,8 +1245,9 @@ void TabControl::setAllocation(const Size &rAllocation)
     long nNewWidth = aNewSize.Width();
     for (auto const& item : mpTabCtrlData->maItemList)
     {
-        if ( !item.mbFullVisible ||
-             (item.maRect.Right()-2 >= nNewWidth) )
+        if (!item.m_bVisible)
+            continue;
+        if (!item.mbFullVisible || (item.maRect.Right()-2 >= nNewWidth))
         {
             mbSmallInvalidate = false;
             break;
@@ -1501,21 +1484,22 @@ void TabControl::DataChanged( const DataChangedEvent& rDCEvt )
     }
 }
 
-tools::Rectangle* TabControl::ImplFindPartRect( const Point& rPt )
+ImplTabItem* TabControl::ImplGetItem(const Point& rPt) const
 {
     ImplTabItem* pFoundItem = nullptr;
     int nFound = 0;
     for (auto & item : mpTabCtrlData->maItemList)
     {
-        if ( item.maRect.IsInside( rPt ) )
+        if (item.m_bVisible && item.maRect.IsInside(rPt))
         {
-            // assure that only one tab is highlighted at a time
             nFound++;
             pFoundItem = &item;
         }
     }
+
     // assure that only one tab is highlighted at a time
-    return nFound == 1 ? &pFoundItem->maRect : nullptr;
+    assert(nFound <= 1);
+    return nFound == 1 ? pFoundItem : nullptr;
 }
 
 bool TabControl::PreNotify( NotifyEvent& rNEvt )
@@ -1529,33 +1513,35 @@ bool TabControl::PreNotify( NotifyEvent& rNEvt )
             // trigger redraw if mouse over state has changed
             if( IsNativeControlSupported(ControlType::TabItem, ControlPart::Entire) )
             {
-                tools::Rectangle* pRect = ImplFindPartRect( GetPointerPosPixel() );
-                tools::Rectangle* pLastRect = ImplFindPartRect( GetLastPointerPosPixel() );
-                if( pRect != pLastRect || (pMouseEvt->IsLeaveWindow() || pMouseEvt->IsEnterWindow()) )
+                ImplTabItem *pItem = ImplGetItem(GetPointerPosPixel());
+                ImplTabItem *pLastItem = ImplGetItem(GetLastPointerPosPixel());
+                if ((pItem != pLastItem) || pMouseEvt->IsLeaveWindow() || pMouseEvt->IsEnterWindow())
                 {
                     vcl::Region aClipRgn;
-                    if( pLastRect )
+                    if (pLastItem)
                     {
                         // allow for slightly bigger tabitems
                         // as used by gtk
                         // TODO: query for the correct sizes
-                        tools::Rectangle aRect(*pLastRect);
+                        tools::Rectangle aRect(pLastItem->maRect);
                         aRect.AdjustLeft( -2 );
                         aRect.AdjustRight(2 );
                         aRect.AdjustTop( -3 );
                         aClipRgn.Union( aRect );
                     }
-                    if( pRect )
+
+                    if (pItem)
                     {
                         // allow for slightly bigger tabitems
                         // as used by gtk
                         // TODO: query for the correct sizes
-                        tools::Rectangle aRect(*pRect);
+                        tools::Rectangle aRect(pItem->maRect);
                         aRect.AdjustLeft( -2 );
                         aRect.AdjustRight(2 );
                         aRect.AdjustTop( -3 );
                         aClipRgn.Union( aRect );
                     }
+
                     if( !aClipRgn.IsEmpty() )
                         Invalidate( aClipRgn );
                 }
@@ -1719,27 +1705,46 @@ void TabControl::Clear()
     CallEventListeners( VclEventId::TabpageRemovedAll );
 }
 
-void TabControl::EnablePage( sal_uInt16 i_nPageId, bool i_bEnable )
+void TabControl::SetPageEnabled( sal_uInt16 i_nPageId, bool i_bEnable )
 {
     ImplTabItem* pItem = ImplGetItem( i_nPageId );
 
-    if ( pItem && pItem->mbEnabled != i_bEnable )
+    if (pItem && pItem->m_bEnabled != i_bEnable)
     {
-        pItem->mbEnabled = i_bEnable;
+        pItem->m_bEnabled = i_bEnable;
+        if (!pItem->m_bVisible)
+            return;
+
         mbFormat = true;
         if( mpTabCtrlData->mpListBox )
             mpTabCtrlData->mpListBox->SetEntryFlags( GetPagePos( i_nPageId ),
                                                      i_bEnable ? ListBoxEntryFlags::NONE : (ListBoxEntryFlags::DisableSelection | ListBoxEntryFlags::DrawDisabled) );
-        if( pItem->mnId == mnCurPageId )
-        {
-             // SetCurPageId will change to an enabled page
+
+        // SetCurPageId will change to a valid page
+        if (pItem->mnId == mnCurPageId)
             SetCurPageId( mnCurPageId );
-        }
         else if ( IsUpdateMode() )
             Invalidate();
     }
 }
 
+void TabControl::SetPageVisible( sal_uInt16 nPageId, bool bVisible )
+{
+    ImplTabItem* pItem = ImplGetItem( nPageId );
+    if (!pItem || pItem->m_bVisible == bVisible)
+        return;
+
+    pItem->m_bVisible = bVisible;
+    pItem->maRect.SetEmpty();
+    mbFormat = true;
+
+    // SetCurPageId will change to a valid page
+    if (pItem->mnId == mnCurPageId)
+        SetCurPageId(mnCurPageId);
+    else if (IsUpdateMode())
+        Invalidate();
+}
+
 sal_uInt16 TabControl::GetPageCount() const
 {
     return static_cast<sal_uInt16>(mpTabCtrlData->maItemList.size());
@@ -1767,42 +1772,32 @@ sal_uInt16 TabControl::GetPagePos( sal_uInt16 nPageId ) const
 
 sal_uInt16 TabControl::GetPageId( const Point& rPos ) const
 {
-    for( size_t i = 0; i < mpTabCtrlData->maItemList.size(); ++i )
-    {
-        if ( const_cast<TabControl*>(this)->ImplGetTabRect( static_cast<sal_uInt16>(i) ).IsInside( rPos ) )
-            return mpTabCtrlData->maItemList[ i ].mnId;
-    }
-
-    return 0;
+    const auto &rList = mpTabCtrlData->maItemList;
+    const auto it = std::find_if(rList.begin(), rList.end(), [&rPos, this](const auto &item) {
+        return const_cast<TabControl*>(this)->ImplGetTabRect(&item).IsInside(rPos); });
+    return (it != rList.end()) ? it->mnId : 0;
 }
 
 sal_uInt16 TabControl::GetPageId( const TabPage& rPage ) const
 {
-    for (auto const& item : mpTabCtrlData->maItemList)
-    {
-        if ( item.mpTabPage == &rPage )
-            return item.mnId;
-    }
-
-    return 0;
+    const auto &rList = mpTabCtrlData->maItemList;
+    const auto it = std::find_if(rList.begin(), rList.end(), [&rPage](const auto &item) {
+        return item.mpTabPage == &rPage; });
+    return (it != rList.end()) ? it->mnId : 0;
 }
 
 sal_uInt16 TabControl::GetPageId( const OString& rName ) const
 {
-    for (auto const& item : mpTabCtrlData->maItemList)
-    {
-        if ( item.maTabName == rName )
-            return item.mnId;
-    }
-
-    return 0;
+    const auto &rList = mpTabCtrlData->maItemList;
+    const auto it = std::find_if(rList.begin(), rList.end(), [&rName](const auto &item) {
+        return item.maTabName == rName; });
+    return (it != rList.end()) ? it->mnId : 0;
 }
 
 void TabControl::SetCurPageId( sal_uInt16 nPageId )
 {
     sal_uInt16 nPos = GetPagePos( nPageId );
-    while( nPos != TAB_PAGE_NOTFOUND &&
-           ! mpTabCtrlData->maItemList[nPos].mbEnabled )
+    while (nPos != TAB_PAGE_NOTFOUND && !mpTabCtrlData->maItemList[nPos].m_bEnabled)
     {
         nPos++;
         if( size_t(nPos) >= mpTabCtrlData->maItemList.size() )
@@ -2055,7 +2050,7 @@ tools::Rectangle TabControl::GetTabBounds( sal_uInt16 nPageId ) const
     tools::Rectangle aRet;
 
     ImplTabItem* pItem = ImplGetItem( nPageId );
-    if(pItem)
+    if (pItem && pItem->m_bVisible)
         aRet = pItem->maRect;
 
     return aRet;
@@ -2075,7 +2070,7 @@ Point TabControl::GetItemsOffset() const
         return Point();
 }
 
-Size TabControl::calculateRequisition() const
+Size TabControl::ImplCalculateRequisition(sal_uInt16& nHeaderHeight) const
 {
     Size aOptimalPageSize(0, 0);
 
@@ -2122,8 +2117,11 @@ Size TabControl::calculateRequisition() const
 
         tools::Rectangle aTabRect = pThis->ImplGetTabRect(nPos, aOptimalPageSize.Width(), LONG_MAX);
         if (aTabRect.Bottom() > nTabLabelsBottom)
+        {
             nTabLabelsBottom = aTabRect.Bottom();
-        if (aTabRect.Right() > nTabLabelsRight)
+            nHeaderHeight = nTabLabelsBottom;
+        }
+        if (!aTabRect.IsEmpty() && aTabRect.Right() > nTabLabelsRight)
             nTabLabelsRight = aTabRect.Right();
     }
 
@@ -2137,6 +2135,12 @@ Size TabControl::calculateRequisition() const
     return aOptimalSize;
 }
 
+Size TabControl::calculateRequisition() const
+{
+    sal_uInt16 nHeaderHeight;
+    return ImplCalculateRequisition(nHeaderHeight);
+}
+
 Size TabControl::GetOptimalSize() const
 {
     return calculateRequisition();
@@ -2201,10 +2205,7 @@ void NotebookbarTabControlBase::SetContext( vcl::EnumContext::Context eContext )
 
             if (pPage)
             {
-                if (pPage->HasContext(eContext) || pPage->HasContext(vcl::EnumContext::Context::Any))
-                    EnablePage(nPageId);
-                else
-                    EnablePage(nPageId, false);
+                SetPageVisible(nPageId, pPage->HasContext(eContext) || pPage->HasContext(vcl::EnumContext::Context::Any));
 
                 if (!bHandled && bLastContextWasSupported
                     && pPage->HasContext(vcl::EnumContext::Context::Default))
@@ -2244,62 +2245,34 @@ void NotebookbarTabControlBase::SetIconClickHdl( Link<NotebookBar*, void> aHdl )
     m_aIconClickHdl = aHdl;
 }
 
-sal_uInt16 NotebookbarTabControlBase::GetPageId( const Point& rPos ) const
+static bool lcl_isValidPage(const ImplTabItem& rItem, bool& bFound)
 {
-    for( size_t i = 0; i < mpTabCtrlData->maItemList.size(); ++i )
-    {
-        if ( const_cast<NotebookbarTabControlBase*>(this)->ImplGetTabRect( static_cast<sal_uInt16>(i) ).IsInside( rPos ) )
-            if ( mpTabCtrlData->maItemList[ i ].mbEnabled )
-                return mpTabCtrlData->maItemList[ i ].mnId;
-    }
-
-    return 0;
-}
-
-void NotebookbarTabControlBase::SelectTabPage( sal_uInt16 nPageId )
-{
-    TabControl::SelectTabPage( nPageId );
-    Resize();
-}
-
-void NotebookbarTabControlBase::SetCurPageId( sal_uInt16 nPageId )
-{
-    TabControl::SetCurPageId( nPageId );
-    Resize();
-    if ( nPageId == GetPageCount() )
-        ImplActivateTabPage( true );
+    if (rItem.m_bVisible && rItem.m_bEnabled)
+        bFound = true;
+    return bFound;
 }
 
 void NotebookbarTabControlBase::ImplActivateTabPage( bool bNext )
 {
-    sal_uInt16 nCurPos = GetPagePos( GetCurPageId() );
+    const sal_uInt16 nOldPos = GetPagePos(GetCurPageId());
+    bool bFound = false;
+    sal_Int32 nCurPos = nOldPos;
 
-    if ( bNext && nCurPos + 1 < GetPageCount() )
+    if (bNext)
     {
-        sal_uInt16 nOldPos = nCurPos;
-        nCurPos++;
-
-        ImplTabItem* pItem = &mpTabCtrlData->maItemList[nCurPos];
-        while ( !pItem->mbEnabled && nCurPos + 1 < GetPageCount())
-        {
-            nCurPos++;
-            pItem = &mpTabCtrlData->maItemList[nCurPos];
-        }
-
-        if ( !pItem->mbEnabled )
-            nCurPos = nOldPos;
+        for (nCurPos++; nCurPos < GetPageCount(); nCurPos++)
+            if (lcl_isValidPage(mpTabCtrlData->maItemList[nCurPos], bFound))
+                break;
     }
-    else if ( !bNext && nCurPos )
+    else
     {
-        nCurPos--;
-        ImplTabItem* pItem = &mpTabCtrlData->maItemList[nCurPos];
-        while ( nCurPos && !pItem->mbEnabled )
-        {
-            nCurPos--;
-            pItem = &mpTabCtrlData->maItemList[nCurPos];
-        }
+        for (nCurPos--; nCurPos >= 0; nCurPos--)
+            if (lcl_isValidPage(mpTabCtrlData->maItemList[nCurPos], bFound))
+                break;
     }
 
+    if (!bFound)
+        nCurPos = nOldPos;
     SelectTabPage( TabControl::GetPageId( nCurPos ) );
 }
 
@@ -2331,7 +2304,7 @@ bool NotebookbarTabControlBase::ImplPlaceTabs( long nWidth )
     std::vector<sal_Int32> aWidths;
     for (auto & item : mpTabCtrlData->maItemList)
     {
-        if( item.mbEnabled )
+        if (item.m_bVisible)
         {
             long aSize = ImplGetItemSize( &item, nMaxWidth ).getWidth();
             if( !item.maText.isEmpty() && aSize < 100)
@@ -2358,12 +2331,10 @@ bool NotebookbarTabControlBase::ImplPlaceTabs( long nWidth )
 
     for (auto & item : mpTabCtrlData->maItemList)
     {
-        Size aSize = ImplGetItemSize( &item, nMaxWidth );
-
-        if ( !item.mbEnabled )
-        {
+        if (!item.m_bVisible)
             continue;
-        }
+
+        Size aSize = ImplGetItemSize( &item, nMaxWidth );
 
         // set minimum tab size
         if( nFullWidth < nMaxWidth && !item.maText.isEmpty() && aSize.getWidth() < 100)
@@ -2409,263 +2380,9 @@ bool NotebookbarTabControlBase::ImplPlaceTabs( long nWidth )
     return true;
 }
 
-void NotebookbarTabControlBase::ImplPaint(vcl::RenderContext& rRenderContext, const tools::Rectangle& rRect)
-{
-    HideFocus();
-
-    // reformat if needed
-    tools::Rectangle aRect = ImplGetTabRect(TAB_PAGERECT);
-
-    // find current item
-    ImplTabItem* pCurItem = nullptr;
-    for (auto & item : mpTabCtrlData->maItemList)
-    {
-        if (item.mnId == mnCurPageId)
-        {
-            pCurItem = &item;
-            break;
-        }
-    }
-
-    // Draw the TabPage border
-    const StyleSettings& rStyleSettings = rRenderContext.GetSettings().GetStyleSettings();
-    tools::Rectangle aCurRect;
-    aRect.AdjustLeft( -(TAB_OFFSET) );
-    aRect.AdjustTop( -(TAB_OFFSET) );
-    aRect.AdjustRight(TAB_OFFSET );
-    aRect.AdjustBottom(TAB_OFFSET );
-
-    // if we have an invisible tabpage or no tabpage at all the tabpage rect should be
-    // increased to avoid round corners that might be drawn by a theme
-    // in this case we're only interested in the top border of the tabpage because the tabitems are used
-    // standalone (eg impress)
-    bool bNoTabPage = false;
-    TabPage* pCurPage = pCurItem ? pCurItem->mpTabPage.get() : nullptr;
-    if (!pCurPage || !pCurPage->IsVisible())
-    {
-        bNoTabPage = true;
-        aRect.AdjustLeft( -10 );
-        aRect.AdjustRight(10 );
-    }
-
-    if (rRenderContext.IsNativeControlSupported(ControlType::TabPane, ControlPart::Entire))
-    {
-        const ImplControlValue aControlValue;
-
-        ControlState nState = ControlState::ENABLED;
-        if (!IsEnabled())
-            nState &= ~ControlState::ENABLED;
-        if (HasFocus())
-            nState |= ControlState::FOCUSED;
-
-        vcl::Region aClipRgn(rRenderContext.GetActiveClipRegion());
-        aClipRgn.Intersect(aRect);
-        if (!rRect.IsEmpty())
-            aClipRgn.Intersect(rRect);
-
-        if (!aClipRgn.IsEmpty())
-        {
-            rRenderContext.DrawNativeControl(ControlType::TabPane, ControlPart::Entire,
-                                             aRect, nState, aControlValue, OUString());
-        }
-
-        if (rRenderContext.IsNativeControlSupported(ControlType::TabHeader, ControlPart::Entire))
-        {
-            tools::Rectangle aHeaderRect(aRect.Left(), 0, aRect.Right(), aRect.Top());
-
-            aClipRgn = rRenderContext.GetActiveClipRegion();
-            aClipRgn.Intersect(aHeaderRect);
-            if (!rRect.IsEmpty())
-                aClipRgn.Intersect(rRect);
-
-            if (!aClipRgn.IsEmpty())
-            {
-                rRenderContext.DrawNativeControl(ControlType::TabHeader, ControlPart::Entire,
-                                                 aHeaderRect, nState, aControlValue, OUString());
-            }
-        }
-    }
-    else
-    {
-        long nTopOff = 1;
-        if (!(rStyleSettings.GetOptions() & StyleSettingsOptions::Mono))
-            rRenderContext.SetLineColor(rStyleSettings.GetLightColor());
-        else
-            rRenderContext.SetLineColor(COL_BLACK);
-        if (pCurItem && !pCurItem->maRect.IsEmpty())
-        {
-            aCurRect = pCurItem->maRect;
-            rRenderContext.DrawLine(aRect.TopLeft(), Point(aCurRect.Left() - 2, aRect.Top()));
-            if (aCurRect.Right() + 1 < aRect.Right())
-            {
-                rRenderContext.DrawLine(Point(aCurRect.Right(), aRect.Top()), aRect.TopRight());
-            }
-            else
-            {
-                nTopOff = 0;
-            }
-        }
-        else
-            rRenderContext.DrawLine(aRect.TopLeft(), aRect.TopRight());
-
-        rRenderContext.DrawLine(aRect.TopLeft(), aRect.BottomLeft());
-
-        if (!(rStyleSettings.GetOptions() & StyleSettingsOptions::Mono))
-        {
-            // if we have not tab page the bottom line of the tab page
-            // directly touches the tab items, so choose a color that fits seamlessly
-            if (bNoTabPage)
-                rRenderContext.SetLineColor(rStyleSettings.GetDialogColor());
-            else
-                rRenderContext.SetLineColor(rStyleSettings.GetShadowColor());
-            rRenderContext.DrawLine(Point(1, aRect.Bottom() - 1), Point(aRect.Right() - 1, aRect.Bottom() - 1));
-            rRenderContext.DrawLine(Point(aRect.Right() - 1, aRect.Top() + nTopOff), Point(aRect.Right() - 1, aRect.Bottom() - 1));
-            if (bNoTabPage)
-                rRenderContext.SetLineColor(rStyleSettings.GetDialogColor());
-            else
-                rRenderContext.SetLineColor(rStyleSettings.GetDarkShadowColor());
-            rRenderContext.DrawLine(Point(0, aRect.Bottom()), Point(aRect.Right(), aRect.Bottom()));
-            rRenderContext.DrawLine(Point(aRect.Right(), aRect.Top() + nTopOff), Point(aRect.Right(), aRect.Bottom()));
-        }
-        else
-        {
-            rRenderContext.DrawLine(aRect.TopRight(), aRect.BottomRight());
-            rRenderContext.DrawLine(aRect.BottomLeft(), aRect.BottomRight());
-        }
-    }
-
-    if (!mpTabCtrlData->maItemList.empty() && mpTabCtrlData->mpListBox == nullptr)
-    {
-        // Some native toolkits (GTK+) draw tabs right-to-left, with an
-        // overlap between adjacent tabs
-        bool bDrawTabsRTL = rRenderContext.IsNativeControlSupported(ControlType::TabItem, ControlPart::TabsDrawRtl);
-        ImplTabItem* pFirstTab = nullptr;
-        ImplTabItem* pLastTab = nullptr;
-        size_t idx;
-
-        // Event though there is a tab overlap with GTK+, the first tab is not
-        // overlapped on the left side. Other toolkits ignore this option.
-        if (bDrawTabsRTL)
-        {
-            pFirstTab = mpTabCtrlData->maItemList.data();
-            pLastTab = pFirstTab + mpTabCtrlData->maItemList.size() - 1;
-            idx = mpTabCtrlData->maItemList.size() - 1;
-        }
-        else
-        {
-            pLastTab = mpTabCtrlData->maItemList.data();
-            pFirstTab = pLastTab + mpTabCtrlData->maItemList.size() - 1;
-            idx = 0;
-        }
-
-        while (idx < mpTabCtrlData->maItemList.size())
-        {
-            ImplTabItem* pItem = &mpTabCtrlData->maItemList[idx];
-
-            if ((pItem != pCurItem) && (pItem->mbEnabled))
-            {
-                vcl::Region aClipRgn(rRenderContext.GetActiveClipRegion());
-                aClipRgn.Intersect(pItem->maRect);
-                if (!rRect.IsEmpty())
-                    aClipRgn.Intersect(rRect);
-                if (!aClipRgn.IsEmpty())
-                {
-                    ImplDrawItem(rRenderContext, pItem, aCurRect,
-                                 pItem == pFirstTab, pItem == pLastTab);
-                }
-            }
-
-            if (bDrawTabsRTL)
-                idx--;
-            else
-                idx++;
-        }
-
-        if (pCurItem)
-        {
-            vcl::Region aClipRgn(rRenderContext.GetActiveClipRegion());
-            aClipRgn.Intersect(pCurItem->maRect);
-            if (!rRect.IsEmpty())
-                aClipRgn.Intersect(rRect);
-            if (!aClipRgn.IsEmpty())
-            {
-                ImplDrawItem(rRenderContext, pCurItem, aCurRect,
-                             pCurItem == pFirstTab, pCurItem == pLastTab);
-            }
-        }
-    }
-
-    if (HasFocus())
-        ImplShowFocus();
-
-    mbSmallInvalidate = true;
-
-    Control::Paint(rRenderContext, rRect);
-}
-
 Size NotebookbarTabControlBase::calculateRequisition() const
 {
-    Size aOptimalPageSize(0, 0);
-
-    sal_uInt16 nOrigPageId = GetCurPageId();
-    for (auto const& item : mpTabCtrlData->maItemList)
-    {
-        const TabPage *pPage = item.mpTabPage;
-        //it's a real nuisance if the page is not inserted yet :-(
-        //We need to force all tabs to exist to get overall optimal size for dialog
-        if (!pPage)
-        {
-            NotebookbarTabControlBase *pThis = const_cast<NotebookbarTabControlBase*>(this);
-            pThis->SetCurPageId(item.mnId);
-            pThis->ActivatePage();
-            pPage = item.mpTabPage;
-        }
-
-        if (!pPage)
-            continue;
-
-        Size aPageSize(VclContainer::getLayoutRequisition(*pPage));
-
-        if (aPageSize.Width() > aOptimalPageSize.Width())
-            aOptimalPageSize.setWidth( aPageSize.Width() );
-        if (aPageSize.Height() > aOptimalPageSize.Height())
-            aOptimalPageSize.setHeight( aPageSize.Height() );
-    }
-
-    //fdo#61940 If we were forced to activate pages in order to on-demand
-    //create them to get their optimal size, then switch back to the original
-    //page and re-activate it
-    if (nOrigPageId != GetCurPageId())
-    {
-        NotebookbarTabControlBase *pThis = const_cast<NotebookbarTabControlBase*>(this);
-        pThis->SetCurPageId(nOrigPageId);
-        pThis->ActivatePage();
-    }
-
-    long nTabLabelsBottom = 0, nTabLabelsRight = 0;
-    for (sal_uInt16 nPos(0), sizeList(static_cast <sal_uInt16> (mpTabCtrlData->maItemList.size()));
-            nPos < sizeList; ++nPos)
-    {
-        NotebookbarTabControlBase* pThis = const_cast<NotebookbarTabControlBase*>(this);
-
-        tools::Rectangle aTabRect = pThis->ImplGetTabRect(nPos, aOptimalPageSize.Width(), LONG_MAX);
-        if (aTabRect.Bottom() > nTabLabelsBottom)
-        {
-            nTabLabelsBottom = aTabRect.Bottom();
-            m_nHeaderHeight = aTabRect.Bottom();
-        }
-        if (aTabRect.Right() > nTabLabelsRight)
-            nTabLabelsRight = aTabRect.Right();
-    }
-
-    Size aOptimalSize(aOptimalPageSize);
-    aOptimalSize.AdjustHeight(nTabLabelsBottom );
-    aOptimalSize.setWidth( std::max(nTabLabelsRight, aOptimalSize.Width()) );
-
-    aOptimalSize.AdjustWidth(TAB_OFFSET * 2 );
-    aOptimalSize.AdjustHeight(TAB_OFFSET * 2 );
-
-    return aOptimalSize;
+    return TabControl::ImplCalculateRequisition(m_nHeaderHeight);
 }
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */


More information about the Libreoffice-commits mailing list