[Libreoffice-commits] core.git: include/vcl sc/uiconfig sd/uiconfig sfx2/uiconfig sw/uiconfig vcl/Library_vcl.mk vcl/source

Szymon Kłos eszkadev at gmail.com
Mon Jul 18 08:11:57 UTC 2016


 include/vcl/contexttabctrl.hxx         |   39 --
 include/vcl/notebookbar.hxx            |    4 
 include/vcl/tabctrl.hxx                |   30 +-
 sc/uiconfig/scalc/ui/notebookbar.ui    |    2 
 sd/uiconfig/simpress/ui/notebookbar.ui |    2 
 sfx2/uiconfig/ui/notebookbar.ui        |    2 
 sw/uiconfig/swriter/ui/notebookbar.ui  |    2 
 vcl/Library_vcl.mk                     |    1 
 vcl/source/control/contexttabctrl.cxx  |   54 ----
 vcl/source/control/tabctrl.cxx         |  435 +++++++++++++++++++++++++++++++--
 10 files changed, 446 insertions(+), 125 deletions(-)

New commits:
commit 1d3ee7663da5f9f2ab2e2b8181cf2f6be5d6e524
Author: Szymon Kłos <eszkadev at gmail.com>
Date:   Wed Jul 13 15:14:02 2016 +0200

    GSoC notebookbar: don't show empty space for hidden tabs
    
    Change-Id: Ia00f64c1cb5d990e852cc297b6b7bd76df4b1b05
    Reviewed-on: https://gerrit.libreoffice.org/27191
    Tested-by: Jenkins <ci at libreoffice.org>
    Reviewed-by: Samuel Mehrbrodt <Samuel.Mehrbrodt at cib.de>

diff --git a/include/vcl/contexttabctrl.hxx b/include/vcl/contexttabctrl.hxx
deleted file mode 100644
index 452d9f3..0000000
--- a/include/vcl/contexttabctrl.hxx
+++ /dev/null
@@ -1,39 +0,0 @@
-/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-/*
- * This file is part of the LibreOffice project.
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/.
- *
- * This file incorporates work covered by the following license notice:
- *
- *   Licensed to the Apache Software Foundation (ASF) under one or more
- *   contributor license agreements. See the NOTICE file distributed
- *   with this work for additional information regarding copyright
- *   ownership. The ASF licenses this file to you under the Apache
- *   License, Version 2.0 (the "License"); you may not use this file
- *   except in compliance with the License. You may obtain a copy of
- *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
- */
-
-#ifndef INCLUDED_VCL_CONTEXTTABCTRL_HXX
-#define INCLUDED_VCL_CONTEXTTABCTRL_HXX
-
-#include <vcl/EnumContext.hxx>
-#include <vcl/tabctrl.hxx>
-
-class VCL_DLLPUBLIC ContextTabControl : public TabControl
-{
-public:
-    ContextTabControl( vcl::Window* pParent, WinBits nStyle = WB_STDTABCONTROL );
-
-    void SetContext( vcl::EnumContext::Context eContext );
-
-private:
-    vcl::EnumContext::Context eLastContext;
-};
-
-#endif // INCLUDED_VCL_TABCTRL_HXX
-
-/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/vcl/notebookbar.hxx b/include/vcl/notebookbar.hxx
index 128bf8f..05c91a8 100644
--- a/include/vcl/notebookbar.hxx
+++ b/include/vcl/notebookbar.hxx
@@ -12,7 +12,7 @@
 
 #include <vcl/builder.hxx>
 #include <vcl/ctrl.hxx>
-#include <vcl/contexttabctrl.hxx>
+#include <vcl/tabctrl.hxx>
 #include <vcl/EnumContext.hxx>
 #include <com/sun/star/ui/XContextChangeEventListener.hpp>
 
@@ -33,7 +33,7 @@ public:
     const css::uno::Reference<css::ui::XContextChangeEventListener>& getContextChangeEventListener() const { return m_pEventListener; }
 private:
     css::uno::Reference<css::ui::XContextChangeEventListener> m_pEventListener;
-    VclPtr<ContextTabControl> m_pTabControl;
+    VclPtr<NotebookbarTabControl> m_pTabControl;
 };
 
 
diff --git a/include/vcl/tabctrl.hxx b/include/vcl/tabctrl.hxx
index 410cb2b..a708161 100644
--- a/include/vcl/tabctrl.hxx
+++ b/include/vcl/tabctrl.hxx
@@ -22,6 +22,7 @@
 
 #include <vcl/dllapi.h>
 #include <vcl/ctrl.hxx>
+#include <vcl/EnumContext.hxx>
 
 struct ImplTabItem;
 struct ImplTabCtrlData;
@@ -45,7 +46,7 @@ class ListBox;
 
 class VCL_DLLPUBLIC TabControl : public Control
 {
-private:
+protected:
     ImplTabCtrlData*    mpTabCtrlData;
     long                mnLastWidth;
     long                mnLastHeight;
@@ -56,7 +57,6 @@ private:
     bool                mbRestoreHelpId;
     bool                mbSmallInvalidate;
     bool                mbLayoutDirty;
-    bool                mbHideDisabledTabs;
     Link<TabControl*,void> maActivateHdl;
     Link<TabControl*,bool> maDeactivateHdl;
 
@@ -64,7 +64,6 @@ private:
     SAL_DLLPRIVATE void         ImplInitSettings( bool bFont, bool bForeground, bool bBackground );
     SAL_DLLPRIVATE ImplTabItem* ImplGetItem( sal_uInt16 nId ) const;
     SAL_DLLPRIVATE Size         ImplGetItemSize( ImplTabItem* pItem, long nMaxWidth );
-    SAL_DLLPRIVATE bool         ImplPlaceTabs( long nWidth );
     SAL_DLLPRIVATE Rectangle    ImplGetTabRect( sal_uInt16 nPos, long nWidth = -1, long nHeight = -1 );
     SAL_DLLPRIVATE void         ImplChangeTabPage( sal_uInt16 nId, sal_uInt16 nOldId );
     SAL_DLLPRIVATE bool         ImplPosCurTabPage();
@@ -73,15 +72,12 @@ private:
     SAL_DLLPRIVATE void         ImplDrawItem(vcl::RenderContext& rRenderContext, ImplTabItem* pItem,
                                              const Rectangle& rCurRect, bool bFirstInGroup = false,
                                              bool bLastInGroup = false, bool bIsCurrentItem = false);
-    SAL_DLLPRIVATE void         ImplPaint(vcl::RenderContext& rRenderContext, const Rectangle& rRect);
     SAL_DLLPRIVATE void         ImplFreeLayoutData();
     SAL_DLLPRIVATE bool         ImplHandleKeyEvent( const KeyEvent& rKeyEvent );
 
     DECL_DLLPRIVATE_LINK_TYPED( ImplListBoxSelectHdl, ListBox&, void );
     DECL_DLLPRIVATE_LINK_TYPED( ImplWindowEventListener, VclWindowEvent&, void );
 
-
-protected:
     using Window::ImplInit;
     SAL_DLLPRIVATE void         ImplInit( vcl::Window* pParent, WinBits nStyle );
 
@@ -89,6 +85,8 @@ protected:
     virtual const vcl::Font&    GetCanonicalFont( const StyleSettings& _rStyle ) const override;
     virtual const Color&        GetCanonicalTextColor( const StyleSettings& _rStyle ) const override;
     SAL_DLLPRIVATE Rectangle*   ImplFindPartRect( const Point& rPt );
+    virtual bool                ImplPlaceTabs( long nWidth );
+    virtual void                ImplPaint(vcl::RenderContext& rRenderContext, const Rectangle& rRect);
 
 public:
                         TabControl( vcl::Window* pParent,
@@ -126,12 +124,11 @@ public:
     void                RemovePage( sal_uInt16 nPageId );
     void                Clear();
     void                EnablePage( sal_uInt16 nPageId, bool bEnable = true );
-    void                HideDisabledTabs(bool bHide = true);
 
     sal_uInt16          GetPagePos( sal_uInt16 nPageId ) const;
     sal_uInt16          GetPageCount() const;
     sal_uInt16          GetPageId( sal_uInt16 nPos ) const;
-    sal_uInt16          GetPageId( const Point& rPos ) const;
+    virtual sal_uInt16  GetPageId( const Point& rPos ) const;
     sal_uInt16          GetPageId( const TabPage& rPage ) const;
     sal_uInt16          GetPageId( const OString& rName ) const;
 
@@ -197,6 +194,23 @@ public:
     virtual void queue_resize(StateChangedType eReason = StateChangedType::Layout) override;
 };
 
+class VCL_DLLPUBLIC NotebookbarTabControl : public TabControl
+{
+public:
+    NotebookbarTabControl( vcl::Window* pParent, WinBits nStyle = WB_STDTABCONTROL );
+
+    void SetContext( vcl::EnumContext::Context eContext );
+
+    virtual sal_uInt16  GetPageId( const Point& rPos ) const override;
+
+protected:
+    virtual bool ImplPlaceTabs( long nWidth ) override;
+    virtual void ImplPaint(vcl::RenderContext& rRenderContext, const Rectangle& rRect) override;
+
+private:
+    vcl::EnumContext::Context eLastContext;
+};
+
 #endif // INCLUDED_VCL_TABCTRL_HXX
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/uiconfig/scalc/ui/notebookbar.ui b/sc/uiconfig/scalc/ui/notebookbar.ui
index 28f1e28..f0b8693 100644
--- a/sc/uiconfig/scalc/ui/notebookbar.ui
+++ b/sc/uiconfig/scalc/ui/notebookbar.ui
@@ -192,7 +192,7 @@
         <property name="can_focus">False</property>
         <property name="orientation">vertical</property>
         <child>
-          <object class="vcllo-ContextTabControl" id="notebook1">
+          <object class="vcllo-NotebookbarTabControl" id="notebook1">
             <property name="visible">True</property>
             <property name="can_focus">True</property>
             <property name="hexpand">True</property>
diff --git a/sd/uiconfig/simpress/ui/notebookbar.ui b/sd/uiconfig/simpress/ui/notebookbar.ui
index 0ceafc1..6b53d7c 100644
--- a/sd/uiconfig/simpress/ui/notebookbar.ui
+++ b/sd/uiconfig/simpress/ui/notebookbar.ui
@@ -182,7 +182,7 @@
         <property name="can_focus">False</property>
         <property name="orientation">vertical</property>
         <child>
-          <object class="vcllo-ContextTabControl" id="notebook1">
+          <object class="vcllo-NotebookbarTabControl" id="notebook1">
             <property name="visible">True</property>
             <property name="can_focus">True</property>
             <property name="hexpand">True</property>
diff --git a/sfx2/uiconfig/ui/notebookbar.ui b/sfx2/uiconfig/ui/notebookbar.ui
index a0aa02e..1e8885b 100644
--- a/sfx2/uiconfig/ui/notebookbar.ui
+++ b/sfx2/uiconfig/ui/notebookbar.ui
@@ -11,7 +11,7 @@
         <property name="can_focus">False</property>
         <property name="orientation">vertical</property>
         <child>
-          <object class="vcllo-ContextTabControl" id="notebook1">
+          <object class="vcllo-NotebookbarTabControl" id="notebook1">
             <property name="visible">True</property>
             <property name="can_focus">True</property>
             <property name="hexpand">True</property>
diff --git a/sw/uiconfig/swriter/ui/notebookbar.ui b/sw/uiconfig/swriter/ui/notebookbar.ui
index b912273..5558495 100644
--- a/sw/uiconfig/swriter/ui/notebookbar.ui
+++ b/sw/uiconfig/swriter/ui/notebookbar.ui
@@ -213,7 +213,7 @@
         <property name="can_focus">False</property>
         <property name="orientation">vertical</property>
         <child>
-          <object class="vcllo-ContextTabControl" id="notebook1">
+          <object class="vcllo-NotebookbarTabControl" id="notebook1">
             <property name="visible">True</property>
             <property name="can_focus">True</property>
             <property name="hexpand">True</property>
diff --git a/vcl/Library_vcl.mk b/vcl/Library_vcl.mk
index 56a4d2b..0b26fdf 100644
--- a/vcl/Library_vcl.mk
+++ b/vcl/Library_vcl.mk
@@ -193,7 +193,6 @@ $(eval $(call gb_Library_add_exception_objects,vcl,\
     vcl/source/window/EnumContext \
     vcl/source/control/button \
     vcl/source/control/combobox \
-    vcl/source/control/contexttabctrl \
     vcl/source/control/ctrl \
     vcl/source/control/edit \
     vcl/source/control/field2 \
diff --git a/vcl/source/control/contexttabctrl.cxx b/vcl/source/control/contexttabctrl.cxx
deleted file mode 100644
index 5fa526a..0000000
--- a/vcl/source/control/contexttabctrl.cxx
+++ /dev/null
@@ -1,54 +0,0 @@
-/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-/*
- * This file is part of the LibreOffice project.
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/.
- *
- * This file incorporates work covered by the following license notice:
- *
- *   Licensed to the Apache Software Foundation (ASF) under one or more
- *   contributor license agreements. See the NOTICE file distributed
- *   with this work for additional information regarding copyright
- *   ownership. The ASF licenses this file to you under the Apache
- *   License, Version 2.0 (the "License"); you may not use this file
- *   except in compliance with the License. You may obtain a copy of
- *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
- */
-
-#include <vcl/builderfactory.hxx>
-#include <vcl/contexttabctrl.hxx>
-#include <vcl/tabpage.hxx>
-
-VCL_BUILDER_FACTORY(ContextTabControl);
-
-ContextTabControl::ContextTabControl( vcl::Window* pParent, WinBits nStyle ) :
-    TabControl( pParent, nStyle )
-    , eLastContext(vcl::EnumContext::Context::Context_Any)
-{
-    HideDisabledTabs();
-}
-
-void ContextTabControl::SetContext( vcl::EnumContext::Context eContext )
-{
-    if (eLastContext != eContext)
-    {
-        for (int nChild = 0; nChild < GetChildCount(); ++nChild)
-        {
-            TabPage* pPage = static_cast<TabPage*>(GetChild(nChild));
-
-            if (pPage->HasContext(eContext) || pPage->HasContext(vcl::EnumContext::Context::Context_Any))
-                EnablePage(nChild + 1);
-            else
-                EnablePage(nChild + 1, false);
-
-            if (pPage->HasContext(eContext) && eContext != vcl::EnumContext::Context::Context_Any)
-                SetCurPageId(nChild + 1);
-        }
-
-        eLastContext = eContext;
-    }
-}
-
-/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/source/control/tabctrl.cxx b/vcl/source/control/tabctrl.cxx
index 6420817..d532a5e 100644
--- a/vcl/source/control/tabctrl.cxx
+++ b/vcl/source/control/tabctrl.cxx
@@ -32,6 +32,7 @@
 #include <vcl/lstbox.hxx>
 #include <vcl/settings.hxx>
 #include <vcl/uitest/uiobject.hxx>
+#include <vcl/builderfactory.hxx>
 
 #include "controldata.hxx"
 #include "svdata.hxx"
@@ -96,7 +97,6 @@ void TabControl::ImplInit( vcl::Window* pParent, WinBits nStyle )
     mbSmallInvalidate           = false;
     mpTabCtrlData               = new ImplTabCtrlData;
     mpTabCtrlData->mpListBox    = nullptr;
-    mbHideDisabledTabs          = false;
 
     ImplInitSettings( true, true, true );
 
@@ -1199,19 +1199,16 @@ void TabControl::ImplPaint(vcl::RenderContext& rRenderContext, const Rectangle&
         {
             ImplTabItem* pItem = &mpTabCtrlData->maItemList[idx];
 
-            if(!mbHideDisabledTabs || (mbHideDisabledTabs && pItem->mbEnabled))
+            if (pItem != pCurItem)
             {
-                if (pItem != pCurItem)
+                vcl::Region aClipRgn(rRenderContext.GetActiveClipRegion());
+                aClipRgn.Intersect(pItem->maRect);
+                if (!rRect.IsEmpty())
+                    aClipRgn.Intersect(rRect);
+                if (!aClipRgn.IsEmpty())
                 {
-                    vcl::Region aClipRgn(rRenderContext.GetActiveClipRegion());
-                    aClipRgn.Intersect(pItem->maRect);
-                    if (!rRect.IsEmpty())
-                        aClipRgn.Intersect(rRect);
-                    if (!aClipRgn.IsEmpty())
-                    {
-                        ImplDrawItem(rRenderContext, pItem, aCurRect, false/*bLayout*/,
-                                     pItem == pFirstTab, pItem == pLastTab);
-                    }
+                    ImplDrawItem(rRenderContext, pItem, aCurRect, false/*bLayout*/,
+                                    pItem == pFirstTab, pItem == pLastTab);
                 }
             }
 
@@ -1762,11 +1759,6 @@ void TabControl::EnablePage( sal_uInt16 i_nPageId, bool i_bEnable )
     }
 }
 
-void TabControl::HideDisabledTabs(bool bHide)
-{
-    mbHideDisabledTabs = bHide;
-}
-
 sal_uInt16 TabControl::GetPageCount() const
 {
     return (sal_uInt16)mpTabCtrlData->maItemList.size();
@@ -2208,4 +2200,413 @@ FactoryFunction TabControl::GetUITestFactory() const
     return TabControlUIObject::create;
 }
 
+VCL_BUILDER_FACTORY(NotebookbarTabControl);
+
+NotebookbarTabControl::NotebookbarTabControl(vcl::Window* pParent, WinBits nStyle)
+    : TabControl(pParent, nStyle)
+    , eLastContext( vcl::EnumContext::Context::Context_Any )
+{
+}
+
+void NotebookbarTabControl::SetContext( vcl::EnumContext::Context eContext )
+{
+    if (eLastContext != eContext)
+    {
+        for (int nChild = 0; nChild < GetChildCount(); ++nChild)
+        {
+            TabPage* pPage = static_cast<TabPage*>(GetChild(nChild));
+
+            if (pPage->HasContext(eContext) || pPage->HasContext(vcl::EnumContext::Context::Context_Any))
+                EnablePage(nChild + 1);
+            else
+                EnablePage(nChild + 1, false);
+
+            if (pPage->HasContext(eContext) && eContext != vcl::EnumContext::Context::Context_Any)
+                SetCurPageId(nChild + 1);
+        }
+
+        eLastContext = eContext;
+    }
+}
+
+sal_uInt16 NotebookbarTabControl::GetPageId( const Point& rPos ) const
+{
+    for( size_t i = 0; i < mpTabCtrlData->maItemList.size(); ++i )
+    {
+        if ( const_cast<NotebookbarTabControl*>(this)->ImplGetTabRect( static_cast<sal_uInt16>(i) ).IsInside( rPos ) )
+            if (  mpTabCtrlData->maItemList[ i ].mbEnabled )
+                return mpTabCtrlData->maItemList[ i ].mnId;
+    }
+
+    return 0;
+}
+
+bool NotebookbarTabControl::ImplPlaceTabs( long nWidth )
+{
+    if ( nWidth <= 0 )
+        return false;
+    if ( mpTabCtrlData->maItemList.empty() )
+        return false;
+
+    long nMaxWidth = nWidth;
+
+    const long nOffsetX = 2 + GetItemsOffset().X();
+    const long nOffsetY = 2 + GetItemsOffset().Y();
+
+    //fdo#66435 throw Knuth/Tex minimum raggedness algorithm at the problem
+    //of ugly bare tabs on lines of their own
+
+    //collect widths
+    std::vector<sal_Int32> aWidths;
+    for( std::vector<ImplTabItem>::iterator it = mpTabCtrlData->maItemList.begin();
+         it != mpTabCtrlData->maItemList.end(); ++it )
+    {
+        aWidths.push_back(ImplGetItemSize( &(*it), nMaxWidth ).Width());
+    }
+
+    //aBreakIndexes will contain the indexes of the last tab on each row
+    std::deque<size_t> aBreakIndexes(MinimumRaggednessWrap::GetEndOfLineIndexes(aWidths, nMaxWidth - nOffsetX - 2));
+
+    if ( (mnMaxPageWidth > 0) && (mnMaxPageWidth < nMaxWidth) )
+        nMaxWidth = mnMaxPageWidth;
+    nMaxWidth -= GetItemsOffset().X();
+
+    long nX = nOffsetX;
+    long nY = nOffsetY;
+
+    sal_uInt16 nLines = 0;
+    sal_uInt16 nCurLine = 0;
+
+    long nLineWidthAry[100];
+    sal_uInt16 nLinePosAry[101];
+    nLineWidthAry[0] = 0;
+    nLinePosAry[0] = 0;
+
+    size_t nIndex = 0;
+    sal_uInt16 nPos = 0;
+    sal_uInt16 nHiddenWidth = 0;
+
+    for( std::vector<ImplTabItem>::iterator it = mpTabCtrlData->maItemList.begin();
+         it != mpTabCtrlData->maItemList.end(); ++it, ++nIndex )
+    {
+        Size aSize = ImplGetItemSize( &(*it), nMaxWidth );
+
+        bool bNewLine = false;
+        if (!aBreakIndexes.empty() && nIndex > aBreakIndexes.front())
+        {
+            aBreakIndexes.pop_front();
+            bNewLine = true;
+        }
+
+        if ( bNewLine && (nWidth > 2+nOffsetX) )
+        {
+            if ( nLines == 99 )
+                break;
+
+            nX = nOffsetX;
+            nY += aSize.Height();
+            nLines++;
+            nLineWidthAry[nLines] = 0;
+            nLinePosAry[nLines] = nPos;
+        }
+
+        Rectangle aNewRect( Point( nX, nY ), aSize );
+        if ( mbSmallInvalidate && (it->maRect != aNewRect) )
+            mbSmallInvalidate = false;
+
+        // don't show empty space when tab is hidden, move next tabs to the left
+        if ( it->mpTabPage && !it->mpTabPage->HasContext(vcl::EnumContext::Context_Any) )
+        {
+            aNewRect.setX(aNewRect.getX() - nHiddenWidth);
+            nHiddenWidth += aNewRect.getWidth();
+        }
+
+        it->maRect = aNewRect;
+        it->mnLine = nLines;
+        it->mbFullVisible = true;
+
+        nLineWidthAry[nLines] += aSize.Width();
+        nX += aSize.Width();
+
+        if ( it->mnId == mnCurPageId )
+            nCurLine = nLines;
+
+        nPos++;
+    }
+
+    if ( nLines )
+    { // two or more lines
+        long nLineHeightAry[100];
+        long nIH = mpTabCtrlData->maItemList[0].maRect.Bottom()-2;
+
+        for ( sal_uInt16 i = 0; i < nLines+1; i++ )
+        {
+            if ( i <= nCurLine )
+                nLineHeightAry[i] = nIH*(nLines-(nCurLine-i)) + GetItemsOffset().Y();
+            else
+                nLineHeightAry[i] = nIH*(i-nCurLine-1) + GetItemsOffset().Y();
+        }
+
+        nLinePosAry[nLines+1] = (sal_uInt16)mpTabCtrlData->maItemList.size();
+
+        long nDX = 0;
+        long nModDX = 0;
+        long nIDX = 0;
+
+        sal_uInt16 i = 0;
+        sal_uInt16 n = 0;
+        for( std::vector< ImplTabItem >::iterator it = mpTabCtrlData->maItemList.begin();
+             it != mpTabCtrlData->maItemList.end(); ++it )
+        {
+            if ( i == nLinePosAry[n] )
+            {
+                if ( n == nLines+1 )
+                    break;
+
+                nIDX = 0;
+                if( nLinePosAry[n+1]-i > 0 )
+                {
+                    nDX = ( nWidth - nOffsetX - nLineWidthAry[n] ) / ( nLinePosAry[n+1] - i );
+                    nModDX = ( nWidth - nOffsetX - nLineWidthAry[n] ) % ( nLinePosAry[n+1] - i );
+                }
+                else
+                {
+                    // FIXME: this is a case of tabctrl way too small
+                    nDX = 0;
+                    nModDX = 0;
+                }
+                n++;
+            }
+
+            it->maRect.Left() += nIDX;
+            it->maRect.Right() += nIDX + nDX;
+            it->maRect.Top() = nLineHeightAry[n-1];
+            it->maRect.Bottom() = nLineHeightAry[n-1] + nIH;
+            nIDX += nDX;
+
+            if ( nModDX )
+            {
+                nIDX++;
+                it->maRect.Right()++;
+                nModDX--;
+            }
+
+            i++;
+        }
+    }
+    else
+    { // only one line
+        if(ImplGetSVData()->maNWFData.mbCenteredTabs)
+        {
+            int nRightSpace = nMaxWidth;//space left on the right by the tabs
+            for( std::vector< ImplTabItem >::iterator it = mpTabCtrlData->maItemList.begin();
+                 it != mpTabCtrlData->maItemList.end(); ++it )
+            {
+                nRightSpace -= it->maRect.Right()-it->maRect.Left();
+            }
+            for( std::vector< ImplTabItem >::iterator it = mpTabCtrlData->maItemList.begin();
+                 it != mpTabCtrlData->maItemList.end(); ++it )
+            {
+                it->maRect.Left() += nRightSpace / 2;
+                it->maRect.Right() += nRightSpace / 2;
+            }
+        }
+    }
+
+    return true;
+}
+
+void NotebookbarTabControl::ImplPaint(vcl::RenderContext& rRenderContext, const Rectangle& rRect)
+{
+    HideFocus();
+
+    // reformat if needed
+    Rectangle aRect = ImplGetTabRect(TAB_PAGERECT);
+
+    // find current item
+    ImplTabItem* pCurItem = nullptr;
+    for (std::vector< ImplTabItem >::iterator it = mpTabCtrlData->maItemList.begin();
+         it != mpTabCtrlData->maItemList.end(); ++it )
+    {
+        if (it->mnId == mnCurPageId)
+        {
+            pCurItem = &(*it);
+            break;
+        }
+    }
+
+    // Draw the TabPage border
+    const StyleSettings& rStyleSettings = rRenderContext.GetSettings().GetStyleSettings();
+    Rectangle aCurRect;
+    aRect.Left()   -= TAB_OFFSET;
+    aRect.Top()    -= TAB_OFFSET;
+    aRect.Right()  += TAB_OFFSET;
+    aRect.Bottom() += 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.Left() -= 10;
+        aRect.Right() += 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))
+        {
+            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(Color(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.front();
+            pLastTab = &mpTabCtrlData->maItemList.back();
+            idx = mpTabCtrlData->maItemList.size() - 1;
+        }
+        else
+        {
+            pLastTab = &mpTabCtrlData->maItemList.back();
+            pFirstTab = &mpTabCtrlData->maItemList.front();
+            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, false/*bLayout*/,
+                                    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, true);
+            }
+        }
+    }
+
+    if (HasFocus())
+        ImplShowFocus();
+
+    mbSmallInvalidate = true;
+}
+
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */


More information about the Libreoffice-commits mailing list