[Libreoffice-commits] .: Branch 'feature/cmclayout' - 9 commits - sfx2/inc sfx2/source tools/inc vcl/inc vcl/qa vcl/source

Caolán McNamara caolan at kemper.freedesktop.org
Mon Jun 18 07:26:57 PDT 2012


 sfx2/inc/sfx2/tabdlg.hxx             |    2 
 sfx2/source/dialog/tabdlg.cxx        |   34 ++++++++-------
 tools/inc/tools/wintypes.hxx         |    2 
 vcl/inc/vcl/dialog.hxx               |    2 
 vcl/inc/vcl/layout.hxx               |    4 +
 vcl/qa/cppunit/builder/demo.ui       |    1 
 vcl/source/control/tabctrl.cxx       |    8 ++-
 vcl/source/uipreviewer/previewer.cxx |    4 +
 vcl/source/window/dialog.cxx         |   75 ++++++++++++-----------------------
 vcl/source/window/layout.cxx         |   75 ++++++++++++++++++++++++++++++-----
 vcl/source/window/tabdlg.cxx         |   12 ++++-
 vcl/source/window/tabpage.cxx        |    3 -
 vcl/source/window/window.cxx         |   36 ++++++++++++++--
 13 files changed, 171 insertions(+), 87 deletions(-)

New commits:
commit 8f9edf76a0c55c7ded76b40db3b5e9118e5b56e4
Author: Caolán McNamara <caolanm at redhat.com>
Date:   Mon Jun 18 14:38:37 2012 +0100

    hook up tooltips

diff --git a/vcl/qa/cppunit/builder/demo.ui b/vcl/qa/cppunit/builder/demo.ui
index 681212e..f1517ba 100644
--- a/vcl/qa/cppunit/builder/demo.ui
+++ b/vcl/qa/cppunit/builder/demo.ui
@@ -177,6 +177,7 @@
                         <property name="visible">True</property>
                         <property name="can_focus">True</property>
                         <property name="receives_default">True</property>
+                        <property name="tooltip_text" translatable="yes">A tooltip example</property>
                         <property name="use_action_appearance">False</property>
                       </object>
                       <packing>
diff --git a/vcl/source/uipreviewer/previewer.cxx b/vcl/source/uipreviewer/previewer.cxx
index 5a09974..e18730b 100644
--- a/vcl/source/uipreviewer/previewer.cxx
+++ b/vcl/source/uipreviewer/previewer.cxx
@@ -36,6 +36,7 @@
 #include <ucbhelper/contentbroker.hxx>
 #include <vcl/builder.hxx>
 #include <vcl/dialog.hxx>
+#include <vcl/help.hxx>
 #include <vcl/svapp.hxx>
 
 class UIPreviewApp : public Application
@@ -76,6 +77,9 @@ int UIPreviewApp::Main()
     aArgs[ 1 ] <<= rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(UCB_CONFIGURATION_KEY2_OFFICE));
     ::ucbhelper::ContentBroker::initialize(xSFactory, aArgs);
 
+    // turn on tooltips
+    Help::EnableQuickHelp();
+
     try
     {
         Dialog *pDialog = new Dialog(NULL, WB_STDDIALOG);
diff --git a/vcl/source/window/window.cxx b/vcl/source/window/window.cxx
index ba09b98..a8a3754 100644
--- a/vcl/source/window/window.cxx
+++ b/vcl/source/window/window.cxx
@@ -9945,6 +9945,10 @@ bool Window::set_property(const rtl::OString &rKey, const rtl::OString &rValue)
         set_halign(toAlign(rValue));
     else if (rKey.equalsL(RTL_CONSTASCII_STRINGPARAM("valign")))
         set_valign(toAlign(rValue));
+    else if (rKey.equalsL(RTL_CONSTASCII_STRINGPARAM("tooltip-markup")))
+        SetQuickHelpText(rtl::OStringToOUString(rValue, RTL_TEXTENCODING_UTF8));
+    else if (rKey.equalsL(RTL_CONSTASCII_STRINGPARAM("tooltip-text")))
+        SetQuickHelpText(rtl::OStringToOUString(rValue, RTL_TEXTENCODING_UTF8));
     else
     {
         fprintf(stderr, "unhandled property %s\n", rKey.getStr());
commit 3c59fcb030daab7581c89bcf31fcd339ac49f690
Author: Caolán McNamara <caolanm at redhat.com>
Date:   Mon Jun 18 13:21:15 2012 +0100

    make isLayoutEnabled stricter
    
    dialog/tabpage must have only one child that is a container

diff --git a/vcl/source/window/dialog.cxx b/vcl/source/window/dialog.cxx
index 5c41f18..dfe9aa5 100644
--- a/vcl/source/window/dialog.cxx
+++ b/vcl/source/window/dialog.cxx
@@ -694,9 +694,6 @@ void Dialog::StateChanged( StateChangedType nType )
             SetMinOutputSizePixel(aSize);
             SetSizePixel(aSize);
             setPosSizeOnContainee(aSize, *pBox);
-
-            fprintf(stderr, "101 dialog sized to %d %d\n", aSize.Width(),
-                aSize.Height());
         }
 
         if ( GetSettings().GetStyleSettings().GetAutoMnemonic() )
@@ -1184,9 +1181,9 @@ void Dialog::Draw( OutputDevice* pDev, const Point& rPos, const Size& rSize, sal
 
 bool Dialog::isLayoutEnabled() const
 {
-    //Child is a container => we're layout enabled
+    //Single child is a container => we're layout enabled
     const Window *pChild = GetWindow(WINDOW_FIRSTCHILD);
-    return pChild && pChild->GetType() == WINDOW_CONTAINER;
+    return pChild && pChild->GetType() == WINDOW_CONTAINER && !pChild->GetWindow(WINDOW_NEXT);
 }
 
 Size Dialog::GetOptimalSize(WindowSizeType eType) const
@@ -1221,12 +1218,14 @@ IMPL_LINK( Dialog, ImplHandleLayoutTimerHdl, void*, EMPTYARG )
 {
     fprintf(stderr, "ImplHandleLayoutTimerHdl\n");
 
-    VclBox *pBox = static_cast<VclBox*>(GetWindow(WINDOW_FIRSTCHILD));
-    if (!pBox)
+    if (!isLayoutEnabled())
     {
-        fprintf(stderr, "WTF!\n");
+        fprintf(stderr, "Dialog has become non-layout because extra children have been added directly to it!\n");
         return 0;
     }
+
+    VclBox *pBox = static_cast<VclBox*>(GetWindow(WINDOW_FIRSTCHILD));
+    assert(pBox);
     setPosSizeOnContainee(GetSizePixel(), *pBox);
     return 0;
 }
diff --git a/vcl/source/window/layout.cxx b/vcl/source/window/layout.cxx
index 418b056..d3a8ab4 100644
--- a/vcl/source/window/layout.cxx
+++ b/vcl/source/window/layout.cxx
@@ -49,8 +49,6 @@ Size VclContainer::GetOptimalSize(WindowSizeType eType) const
 
 void VclContainer::SetPosSizePixel(const Point& rAllocPos, const Size& rAllocation)
 {
-    fprintf(stderr, "VclContainer::SetPosSizePixel\n");
-
     Size aAllocation = rAllocation;
     aAllocation.Width() -= m_nBorderWidth*2;
     aAllocation.Height() -= m_nBorderWidth*2;
@@ -69,10 +67,7 @@ void VclContainer::SetPosSizePixel(const Point& rAllocPos, const Size& rAllocati
         Window::SetSizePixel(aAllocation);
 
     if (bSizeChanged)
-    {
-        fprintf(stderr, "VclContainer::setAllocation\n");
         setAllocation(aAllocation);
-    }
 }
 
 void VclContainer::SetPosPixel(const Point& rAllocPos)
@@ -94,7 +89,6 @@ void VclContainer::SetSizePixel(const Size& rAllocation)
     if (aAllocation != GetSizePixel())
     {
         Window::SetSizePixel(aAllocation);
-        fprintf(stderr, "VclContainer::setAllocation\n");
         setAllocation(aAllocation);
     }
 }
diff --git a/vcl/source/window/tabpage.cxx b/vcl/source/window/tabpage.cxx
index c552ee4..a778c7f 100644
--- a/vcl/source/window/tabpage.cxx
+++ b/vcl/source/window/tabpage.cxx
@@ -213,7 +213,7 @@ bool TabPage::isLayoutEnabled() const
 {
     //Child is a container => we're layout enabled
     const Window *pChild = GetWindow(WINDOW_FIRSTCHILD);
-    return pChild && pChild->GetType() == WINDOW_CONTAINER;
+    return pChild && pChild->GetType() == WINDOW_CONTAINER && !pChild->GetWindow(WINDOW_NEXT);
 }
 
 Size TabPage::GetOptimalSize(WindowSizeType eType) const
commit 3365289b5545e8371ebdb35b1b2f04a2f4dcca0c
Author: Caolán McNamara <caolanm at redhat.com>
Date:   Mon Jun 18 13:08:59 2012 +0100

    for legacy TabDialogs dialogs hack the hack to reposition the TabControl
    
    hack to get tab dialogs that add extra widgets to a SfxTabDialog
    parent to continue to work as before now that the SfxTabDialog
    contains a Container rather than a raw TabControl

diff --git a/vcl/source/window/tabdlg.cxx b/vcl/source/window/tabdlg.cxx
index 2019e52..6a04f6e 100644
--- a/vcl/source/window/tabdlg.cxx
+++ b/vcl/source/window/tabdlg.cxx
@@ -53,15 +53,16 @@ void TabDialog::ImplPosControls()
     Size        aCtrlSize( IMPL_MINSIZE_BUTTON_WIDTH, IMPL_MINSIZE_BUTTON_HEIGHT );
     long        nDownCtrl = 0;
     long        nOffY = 0;
-    TabControl* pTabControl = NULL;
+    Window*     pTabControl = NULL;
 
     Window* pChild = GetWindow( WINDOW_FIRSTCHILD );
     while ( pChild )
     {
         if ( pChild->IsVisible() && (pChild != mpViewWindow) )
         {
-            if ( pChild->GetType() == WINDOW_TABCONTROL )
-                pTabControl = (TabControl*)pChild;
+            WindowType eChildType = pChild->GetType();
+            if ( eChildType == WINDOW_TABCONTROL || eChildType == WINDOW_CONTAINER )
+                pTabControl = pChild;
             else if ( pTabControl )
             {
                 Size aOptimalSize( pChild->GetOptimalSize( WINDOWSIZE_PREFERRED ) );
@@ -92,7 +93,12 @@ void TabDialog::ImplPosControls()
             nOffY += IMPL_DIALOG_BAR_OFFSET*2 + 2;
 
         Point   aTabOffset( IMPL_DIALOG_OFFSET, IMPL_DIALOG_OFFSET+nOffY );
+
+        if (pTabControl->GetType() == WINDOW_CONTAINER)
+            pTabControl->SetSizePixel(pTabControl->GetOptimalSize(WINDOWSIZE_PREFERRED));
+
         Size    aTabSize = pTabControl->GetSizePixel();
+
         Size    aDlgSize( aTabSize.Width() + IMPL_DIALOG_OFFSET*2,
                           aTabSize.Height() + IMPL_DIALOG_OFFSET*2 + nOffY );
         long    nBtnEx = 0;
commit e23e28717c5751507fd8617789753ccc74b7e563
Author: Caolán McNamara <caolanm at redhat.com>
Date:   Mon Jun 18 08:10:30 2012 +0100

    further improvements to tabcontrol optimal size
    
    One calculation takes the vertical offset into account, which we want
    for height. But that one calculates the label width according to the
    double-decker layout for over-wide layout, which we don't want.

diff --git a/vcl/source/control/tabctrl.cxx b/vcl/source/control/tabctrl.cxx
index bca23c8..6921ec6 100644
--- a/vcl/source/control/tabctrl.cxx
+++ b/vcl/source/control/tabctrl.cxx
@@ -2198,12 +2198,16 @@ Size TabControl::GetOptimalSize(WindowSizeType eType) const
             if (aPageSize.Height() > aOptimalPageSize.Height())
                 aOptimalPageSize.Height() = aPageSize.Height();
 
-            sal_uInt16 nPos = it - mpTabCtrlData->maItemList.begin();
             TabControl* pThis = const_cast<TabControl*>(this);
+
+            sal_uInt16 nPos = it - mpTabCtrlData->maItemList.begin();
             Rectangle aTabRect = pThis->ImplGetTabRect(nPos, aPageSize.Width(), aPageSize.Height());
             if (aTabRect.Bottom() > nTabLabelsBottom)
                 nTabLabelsBottom = aTabRect.Bottom();
-            nTotalTabLabelWidths += aTabRect.GetWidth();
+
+            ImplTabItem* pItem = const_cast<ImplTabItem*>(&(*it));
+            Size aTabSize = pThis->ImplGetItemSize(pItem, LONG_MAX);
+            nTotalTabLabelWidths += aTabSize.Width();
         }
 
         Size aOptimalSize(aOptimalPageSize);
commit 9bb01df1f000e755bf2e117c4c71bf92272a7731
Author: Caolán McNamara <caolanm at redhat.com>
Date:   Sat Jun 16 23:25:37 2012 +0100

    put apply button into button action area

diff --git a/sfx2/inc/sfx2/tabdlg.hxx b/sfx2/inc/sfx2/tabdlg.hxx
index bcb205c..a507f52 100644
--- a/sfx2/inc/sfx2/tabdlg.hxx
+++ b/sfx2/inc/sfx2/tabdlg.hxx
@@ -80,6 +80,7 @@ friend class SfxTabDialogController;
 
     VclHButtonBox *m_pActionArea;
     OKButton *m_pOKBtn;
+    PushButton* m_pApplyBtn;
     PushButton* m_pUserBtn;
     CancelButton* m_pCancelBtn;
     HelpButton* m_pHelpBtn;
@@ -90,6 +91,7 @@ friend class SfxTabDialogController;
     bool m_bOwnsTabCtrl;
     bool m_bOwnsActionArea;
     bool m_bOwnsOKBtn;
+    bool m_bOwnsApplyBtn;
     bool m_bOwnsUserBtn;
     bool m_bOwnsCancelBtn;
     bool m_bOwnsHelpBtn;
diff --git a/sfx2/source/dialog/tabdlg.cxx b/sfx2/source/dialog/tabdlg.cxx
index 42da338..a3aef6e 100644
--- a/sfx2/source/dialog/tabdlg.cxx
+++ b/sfx2/source/dialog/tabdlg.cxx
@@ -175,7 +175,6 @@ struct TabDlg_Impl
                         bHideResetBtn   : 1;
     SfxTabDlgData_Impl* pData;
 
-    PushButton*         pApplyButton;
     SfxTabDialogController* pController;
 
     TabDlg_Impl( sal_uInt8 nCnt ) :
@@ -185,7 +184,6 @@ struct TabDlg_Impl
         bInOK           ( sal_False ),
         bHideResetBtn   ( sal_False ),
         pData           ( new SfxTabDlgData_Impl( nCnt ) ),
-        pApplyButton    ( NULL ),
         pController     ( NULL )
     {}
 };
@@ -491,7 +489,6 @@ SfxTabDialog::~SfxTabDialog()
     }
 
     delete pImpl->pController;
-    delete pImpl->pApplyButton;
     delete pImpl->pData;
     delete pImpl;
     delete pOutSet;
@@ -508,6 +505,8 @@ SfxTabDialog::~SfxTabDialog()
         delete m_pCancelBtn;
     if (m_bOwnsUserBtn)
         delete m_pUserBtn;
+    if (m_bOwnsApplyBtn)
+        delete m_pApplyBtn;
     if (m_bOwnsOKBtn)
         delete m_pOKBtn;
     if (m_bOwnsActionArea)
@@ -564,10 +563,15 @@ void SfxTabDialog::Init_Impl( sal_Bool bFmtFlag, const String* pUserButtonText,
     if (m_bOwnsOKBtn)
         m_pOKBtn = new OKButton(m_pActionArea);
 
+    m_pApplyBtn = m_pUIBuilder ? static_cast<PushButton*>(m_pUIBuilder->get_by_name("apply")) : NULL;
+    m_bOwnsApplyBtn = m_pApplyBtn == NULL;
+    if (m_bOwnsApplyBtn)
+        m_pApplyBtn = NULL;
+
     m_pUserBtn = m_pUIBuilder ? static_cast<PushButton*>(m_pUIBuilder->get_by_name("user")) : NULL;
     m_bOwnsUserBtn = m_pUserBtn == NULL;
     if (m_bOwnsUserBtn)
-        m_pUserBtn = pUserButtonText ? new PushButton(m_pActionArea) : 0;
+        m_pUserBtn = pUserButtonText ? new PushButton(m_pActionArea) : NULL;
 
     m_pCancelBtn = m_pUIBuilder ? static_cast<CancelButton*>(m_pUIBuilder->get_by_name("cancel")) : NULL;
     m_bOwnsCancelBtn = m_pCancelBtn == NULL;
@@ -687,9 +691,9 @@ void SfxTabDialog::Start( sal_Bool bShow )
 
 void SfxTabDialog::SetApplyHandler(const Link& _rHdl)
 {
-    DBG_ASSERT( pImpl->pApplyButton, "SfxTabDialog::GetApplyHandler: no apply button enabled!" );
-    if ( pImpl->pApplyButton )
-        pImpl->pApplyButton->SetClickHdl( _rHdl );
+    DBG_ASSERT( m_pApplyBtn, "SfxTabDialog::GetApplyHandler: no apply button enabled!" );
+    if ( m_pApplyBtn )
+        m_pApplyBtn->SetClickHdl( _rHdl );
 }
 
 // -----------------------------------------------------------------------
@@ -703,18 +707,18 @@ void SfxTabDialog::EnableApplyButton(sal_Bool bEnable)
     // create or remove the apply button
     if ( bEnable )
     {
-        pImpl->pApplyButton = new PushButton( this );
+        m_pApplyBtn = new PushButton(m_pActionArea);
         // in the z-order, the apply button should be behind the ok button, thus appearing at the right side of it
-        pImpl->pApplyButton->SetZOrder(m_pOKBtn, WINDOW_ZORDER_BEHIND);
-        pImpl->pApplyButton->SetText( String( SfxResId( STR_APPLY ) ) );
-        pImpl->pApplyButton->Show();
+        m_pApplyBtn->SetZOrder(m_pOKBtn, WINDOW_ZORDER_BEHIND);
+        m_pApplyBtn->SetText( String( SfxResId( STR_APPLY ) ) );
+        m_pApplyBtn->Show();
 
-        pImpl->pApplyButton->SetHelpId( HID_TABDLG_APPLY_BTN );
+        m_pApplyBtn->SetHelpId( HID_TABDLG_APPLY_BTN );
     }
     else
     {
-        delete pImpl->pApplyButton;
-        pImpl->pApplyButton = NULL;
+        delete m_pApplyBtn;
+        m_pApplyBtn = NULL;
     }
 
     // adjust the layout
@@ -726,7 +730,7 @@ void SfxTabDialog::EnableApplyButton(sal_Bool bEnable)
 
 sal_Bool SfxTabDialog::IsApplyButtonEnabled() const
 {
-    return ( NULL != pImpl->pApplyButton );
+    return ( NULL != m_pApplyBtn );
 }
 
 // -----------------------------------------------------------------------
commit 18d88998f1c46e7296e8fa8173764ab281ccfcab
Author: Caolán McNamara <caolanm at redhat.com>
Date:   Sat Jun 16 20:23:31 2012 +0100

    add and use a "WINDOW_CONTAINER" type
    
    use it instead of dynamic_cast seeing as we already are dragging
    the window type information around with us

diff --git a/tools/inc/tools/wintypes.hxx b/tools/inc/tools/wintypes.hxx
index e4f0a0d..ee28461 100644
--- a/tools/inc/tools/wintypes.hxx
+++ b/tools/inc/tools/wintypes.hxx
@@ -46,7 +46,7 @@ typedef sal_uInt16 WindowType;
 #define WINDOW_WINDOW               (WINDOW_FIRST + 0x05)
 #define WINDOW_SYSWINDOW            (WINDOW_FIRST + 0x06)
 #define WINDOW_WORKWINDOW           (WINDOW_FIRST + 0x07)
-// #define WINDOW_MDIWINDOW            (WINDOW_FIRST + 0x08)
+#define WINDOW_CONTAINER            (WINDOW_FIRST + 0x08)
 #define WINDOW_FLOATINGWINDOW       (WINDOW_FIRST + 0x09)
 #define WINDOW_DIALOG               (WINDOW_FIRST + 0x0a)
 #define WINDOW_MODELESSDIALOG       (WINDOW_FIRST + 0x0b)
diff --git a/vcl/inc/vcl/dialog.hxx b/vcl/inc/vcl/dialog.hxx
index b4d9fbe..c5c4583 100644
--- a/vcl/inc/vcl/dialog.hxx
+++ b/vcl/inc/vcl/dialog.hxx
@@ -44,7 +44,7 @@
 // ----------
 struct DialogImpl;
 class VclBuilder;
-class VclBox;
+class VclContainer;
 
 class VCL_DLLPUBLIC Dialog
     : public SystemWindow
@@ -79,7 +79,7 @@ protected:
     SAL_DLLPRIVATE void    ImplDialogRes( const ResId& rResId );
     SAL_DLLPRIVATE WinBits init(Window *pParent, const ResId& rResId);
 
-    SAL_DLLPRIVATE void    setPosSizeOnContainee(Size aSize, VclBox &rBox);
+    SAL_DLLPRIVATE void    setPosSizeOnContainee(Size aSize, VclContainer &rBox);
 public:
     SAL_DLLPRIVATE sal_Bool    IsInClose() const { return mbInClose; }
     SAL_DLLPRIVATE bool hasPendingLayout() const { return maLayoutTimer.IsActive(); }
diff --git a/vcl/inc/vcl/layout.hxx b/vcl/inc/vcl/layout.hxx
index e5308e1..e9ed52e 100644
--- a/vcl/inc/vcl/layout.hxx
+++ b/vcl/inc/vcl/layout.hxx
@@ -35,7 +35,7 @@
 class VCL_DLLPUBLIC VclContainer : public Window
 {
 public:
-    VclContainer(Window *pParent) : Window(pParent), m_nBorderWidth(0) {}
+    VclContainer(Window *pParent);
     virtual Size GetOptimalSize(WindowSizeType eType) const;
     using Window::SetPosSizePixel;
     virtual void SetPosSizePixel(const Point& rNewPos, const Size& rNewSize);
diff --git a/vcl/source/window/dialog.cxx b/vcl/source/window/dialog.cxx
index c9313f0..5c41f18 100644
--- a/vcl/source/window/dialog.cxx
+++ b/vcl/source/window/dialog.cxx
@@ -126,7 +126,7 @@ Window * nextLogicalChildOfParent(Window *pTopLevel, Window *pChild)
 {
     Window *pLastChild = pChild;
 
-    if (dynamic_cast<VclContainer*>(pChild))
+    if (pChild->GetType() == WINDOW_CONTAINER)
         pChild = pChild->GetWindow(WINDOW_FIRSTCHILD);
     else
         pChild = pChild->GetWindow(WINDOW_NEXT);
@@ -142,7 +142,7 @@ Window * nextLogicalChildOfParent(Window *pTopLevel, Window *pChild)
         pChild = pParent->GetWindow(WINDOW_NEXT);
     }
 
-    if (dynamic_cast<VclContainer*>(pChild))
+    if (pChild && pChild->GetType() == WINDOW_CONTAINER)
         pChild = nextLogicalChildOfParent(pTopLevel, pChild);
 
     return pChild;
@@ -152,7 +152,7 @@ Window * prevLogicalChildOfParent(Window *pTopLevel, Window *pChild)
 {
     Window *pLastChild = pChild;
 
-    if (dynamic_cast<VclContainer*>(pChild))
+    if (pChild->GetType() == WINDOW_CONTAINER)
         pChild = pChild->GetWindow(WINDOW_LASTCHILD);
     else
         pChild = pChild->GetWindow(WINDOW_PREV);
@@ -168,7 +168,7 @@ Window * prevLogicalChildOfParent(Window *pTopLevel, Window *pChild)
         pChild = pParent->GetWindow(WINDOW_PREV);
     }
 
-    if (dynamic_cast<VclContainer*>(pChild))
+    if (pChild && pChild->GetType() == WINDOW_CONTAINER)
         pChild = prevLogicalChildOfParent(pTopLevel, pChild);
 
     return pChild;
@@ -671,7 +671,7 @@ void Dialog::StateChanged( StateChangedType nType )
             maLayoutTimer.Stop();
 
             //resize dialog to fit requisition on initial show
-            VclBox *pBox = dynamic_cast<VclBox*>(GetWindow(WINDOW_FIRSTCHILD));
+            VclBox *pBox = static_cast<VclBox*>(GetWindow(WINDOW_FIRSTCHILD));
 
             const DialogStyle& rDialogStyle =
                 GetSettings().GetStyleSettings().GetDialogStyle();
@@ -1185,7 +1185,8 @@ void Dialog::Draw( OutputDevice* pDev, const Point& rPos, const Size& rSize, sal
 bool Dialog::isLayoutEnabled() const
 {
     //Child is a container => we're layout enabled
-    return dynamic_cast<const VclContainer*>(GetWindow(WINDOW_FIRSTCHILD));
+    const Window *pChild = GetWindow(WINDOW_FIRSTCHILD);
+    return pChild && pChild->GetType() == WINDOW_CONTAINER;
 }
 
 Size Dialog::GetOptimalSize(WindowSizeType eType) const
@@ -1203,7 +1204,7 @@ Size Dialog::GetOptimalSize(WindowSizeType eType) const
     return Window::CalcWindowSize(aSize);
 }
 
-void Dialog::setPosSizeOnContainee(Size aSize, VclBox &rBox)
+void Dialog::setPosSizeOnContainee(Size aSize, VclContainer &rBox)
 {
     aSize.Width() -= mpWindowImpl->mnLeftBorder + mpWindowImpl->mnRightBorder
         + 2 * m_nBorderWidth;
@@ -1220,7 +1221,7 @@ IMPL_LINK( Dialog, ImplHandleLayoutTimerHdl, void*, EMPTYARG )
 {
     fprintf(stderr, "ImplHandleLayoutTimerHdl\n");
 
-    VclBox *pBox = dynamic_cast<VclBox*>(GetWindow(WINDOW_FIRSTCHILD));
+    VclBox *pBox = static_cast<VclBox*>(GetWindow(WINDOW_FIRSTCHILD));
     if (!pBox)
     {
         fprintf(stderr, "WTF!\n");
diff --git a/vcl/source/window/layout.cxx b/vcl/source/window/layout.cxx
index b4ca472..418b056 100644
--- a/vcl/source/window/layout.cxx
+++ b/vcl/source/window/layout.cxx
@@ -29,6 +29,13 @@
 #include <vcl/layout.hxx>
 #include "window.h"
 
+VclContainer::VclContainer(Window *pParent)
+    : Window(WINDOW_CONTAINER)
+    , m_nBorderWidth(0)
+{
+    ImplInit(pParent, 0, NULL);
+}
+
 Size VclContainer::GetOptimalSize(WindowSizeType eType) const
 {
     if (eType == WINDOWSIZE_MAXIMUM)
@@ -893,7 +900,7 @@ Size getLegacyBestSizeForChildren(const Window &rWindow)
 
 Window* getLegacyNonLayoutParent(Window *pParent)
 {
-    while (pParent && dynamic_cast<const VclContainer*>(pParent))
+    while (pParent && pParent->GetType() == WINDOW_CONTAINER)
     {
         pParent = pParent->GetParent();
     }
diff --git a/vcl/source/window/tabpage.cxx b/vcl/source/window/tabpage.cxx
index b39ba02..c552ee4 100644
--- a/vcl/source/window/tabpage.cxx
+++ b/vcl/source/window/tabpage.cxx
@@ -212,7 +212,8 @@ void TabPage::DeactivatePage()
 bool TabPage::isLayoutEnabled() const
 {
     //Child is a container => we're layout enabled
-    return dynamic_cast<const VclContainer*>(GetWindow(WINDOW_FIRSTCHILD));
+    const Window *pChild = GetWindow(WINDOW_FIRSTCHILD);
+    return pChild && pChild->GetType() == WINDOW_CONTAINER;
 }
 
 Size TabPage::GetOptimalSize(WindowSizeType eType) const
commit e6b4f72cad402c421746180cc3a5bd7761e07370
Author: Caolán McNamara <caolanm at redhat.com>
Date:   Sat Jun 16 16:43:25 2012 +0100

    improve queue_resize

diff --git a/vcl/inc/vcl/dialog.hxx b/vcl/inc/vcl/dialog.hxx
index 2d7928f..b4d9fbe 100644
--- a/vcl/inc/vcl/dialog.hxx
+++ b/vcl/inc/vcl/dialog.hxx
@@ -44,6 +44,7 @@
 // ----------
 struct DialogImpl;
 class VclBuilder;
+class VclBox;
 
 class VCL_DLLPUBLIC Dialog
     : public SystemWindow
@@ -78,6 +79,7 @@ protected:
     SAL_DLLPRIVATE void    ImplDialogRes( const ResId& rResId );
     SAL_DLLPRIVATE WinBits init(Window *pParent, const ResId& rResId);
 
+    SAL_DLLPRIVATE void    setPosSizeOnContainee(Size aSize, VclBox &rBox);
 public:
     SAL_DLLPRIVATE sal_Bool    IsInClose() const { return mbInClose; }
     SAL_DLLPRIVATE bool hasPendingLayout() const { return maLayoutTimer.IsActive(); }
diff --git a/vcl/source/window/dialog.cxx b/vcl/source/window/dialog.cxx
index c12c29b..c9313f0 100644
--- a/vcl/source/window/dialog.cxx
+++ b/vcl/source/window/dialog.cxx
@@ -687,21 +687,16 @@ void Dialog::StateChanged( StateChangedType nType )
 
             Size aSize = get_preferred_size();
 
-            fprintf(stderr, "100 dialog sized to %d %d\n", aSize.Width(),
-                aSize.Height());
-
             Size aMax = GetOptimalSize(WINDOWSIZE_MAXIMUM);
             aSize.Width() = std::min(aMax.Width(), aSize.Width());
             aSize.Height() = std::min(aMax.Height(), aSize.Height());
 
             SetMinOutputSizePixel(aSize);
             SetSizePixel(aSize);
-
-            aSize = GetSizePixel();
+            setPosSizeOnContainee(aSize, *pBox);
 
             fprintf(stderr, "101 dialog sized to %d %d\n", aSize.Width(),
                 aSize.Height());
-
         }
 
         if ( GetSettings().GetStyleSettings().GetAutoMnemonic() )
@@ -1208,6 +1203,19 @@ Size Dialog::GetOptimalSize(WindowSizeType eType) const
     return Window::CalcWindowSize(aSize);
 }
 
+void Dialog::setPosSizeOnContainee(Size aSize, VclBox &rBox)
+{
+    aSize.Width() -= mpWindowImpl->mnLeftBorder + mpWindowImpl->mnRightBorder
+        + 2 * m_nBorderWidth;
+    aSize.Height() -= mpWindowImpl->mnTopBorder + mpWindowImpl->mnBottomBorder
+        + 2 * m_nBorderWidth;
+
+    Point aPos(mpWindowImpl->mnLeftBorder + m_nBorderWidth,
+        mpWindowImpl->mnTopBorder + m_nBorderWidth);
+
+    rBox.SetPosSizePixel(aPos, aSize);
+}
+
 IMPL_LINK( Dialog, ImplHandleLayoutTimerHdl, void*, EMPTYARG )
 {
     fprintf(stderr, "ImplHandleLayoutTimerHdl\n");
@@ -1218,17 +1226,7 @@ IMPL_LINK( Dialog, ImplHandleLayoutTimerHdl, void*, EMPTYARG )
         fprintf(stderr, "WTF!\n");
         return 0;
     }
-    Size aSize = GetSizePixel();
-
-    aSize.Width() -= mpWindowImpl->mnLeftBorder + mpWindowImpl->mnRightBorder
-        + 2 * m_nBorderWidth;
-    aSize.Height() -= mpWindowImpl->mnTopBorder + mpWindowImpl->mnBottomBorder
-        + 2 * m_nBorderWidth;
-
-    Point aPos(mpWindowImpl->mnLeftBorder + m_nBorderWidth,
-        mpWindowImpl->mnTopBorder + m_nBorderWidth);
-
-    pBox->SetPosSizePixel(aPos, aSize);
+    setPosSizeOnContainee(GetSizePixel(), *pBox);
     return 0;
 }
 
diff --git a/vcl/source/window/window.cxx b/vcl/source/window/window.cxx
index 483e3c2..ba09b98 100644
--- a/vcl/source/window/window.cxx
+++ b/vcl/source/window/window.cxx
@@ -4949,6 +4949,7 @@ void Window::StateChanged( StateChangedType eType )
         case STATE_CHANGE_ENABLE:
         case STATE_CHANGE_STATE:
         case STATE_CHANGE_DATA:
+        case STATE_CHANGE_INITSHOW:
             break;
         //stuff that does invalidate the layout
         default:
@@ -9685,14 +9686,16 @@ Selection Window::GetSurroundingTextSelection() const
   return Selection( 0, 0 );
 }
 
-//Poor man's equivalent, when widget wants to renegotiate
-//size, get parent dialog and call resize on it
+//When a widget wants to renegotiate size, get toplevel parent dialog and call
+//resize on it. Maybe better to just find direct parent and if its a container
+//chain it upwards one step at a time until a dialog is found.
 void Window::queue_resize()
 {
     Dialog *pParent = GetParentDialog();
-    if (!pParent)
+    if (!pParent || pParent == this)
         return;
-    pParent->Resize();
+    if (pParent->isLayoutEnabled())
+        pParent->Resize();
 }
 
 void Window::setChildAnyProperty(const rtl::OString &rString, const Any &rValue)
commit 45d353363d5c1bfb8894eb9a5952f737dfb24c3f
Author: Caolán McNamara <caolanm at redhat.com>
Date:   Sat Jun 16 13:29:15 2012 +0100

    avoid redraws when size/pos is unchanged

diff --git a/vcl/inc/vcl/layout.hxx b/vcl/inc/vcl/layout.hxx
index b0fe34f..e5308e1 100644
--- a/vcl/inc/vcl/layout.hxx
+++ b/vcl/inc/vcl/layout.hxx
@@ -39,6 +39,8 @@ public:
     virtual Size GetOptimalSize(WindowSizeType eType) const;
     using Window::SetPosSizePixel;
     virtual void SetPosSizePixel(const Point& rNewPos, const Size& rNewSize);
+    virtual void SetPosPixel(const Point& rAllocPos);
+    virtual void SetSizePixel(const Size& rAllocation);
     virtual bool set_property(const rtl::OString &rKey, const rtl::OString &rValue);
 
     void set_border_width(int nBorderWidth)
diff --git a/vcl/source/window/dialog.cxx b/vcl/source/window/dialog.cxx
index 1a2e1ec..c12c29b 100644
--- a/vcl/source/window/dialog.cxx
+++ b/vcl/source/window/dialog.cxx
@@ -1190,9 +1190,7 @@ void Dialog::Draw( OutputDevice* pDev, const Point& rPos, const Size& rSize, sal
 bool Dialog::isLayoutEnabled() const
 {
     //Child is a container => we're layout enabled
-    bool bRet = dynamic_cast<const VclContainer*>(GetWindow(WINDOW_FIRSTCHILD));
-    fprintf(stderr, "isLayoutEnabled is %d\n", bRet);
-    return bRet;
+    return dynamic_cast<const VclContainer*>(GetWindow(WINDOW_FIRSTCHILD));
 }
 
 Size Dialog::GetOptimalSize(WindowSizeType eType) const
@@ -1202,27 +1200,18 @@ Size Dialog::GetOptimalSize(WindowSizeType eType) const
 
     Size aSize = GetWindow(WINDOW_FIRSTCHILD)->GetOptimalSize(eType);
 
-    fprintf(stderr, "dialog contents wanted to be %d %d\n", aSize.Width(),
-        aSize.Height());
-
     aSize.Height() += mpWindowImpl->mnLeftBorder + mpWindowImpl->mnRightBorder
         + 2*m_nBorderWidth;
     aSize.Width() += mpWindowImpl->mnTopBorder + mpWindowImpl->mnBottomBorder
         + 2*m_nBorderWidth;
 
-    fprintf(stderr, "stage 2 dialog wanted to be %d %d\n", aSize.Width(),
-        aSize.Height());
-
-    aSize = Window::CalcWindowSize(aSize);
-
-    fprintf(stderr, "stage 3 dialog wanted to be %d %d\n", aSize.Width(),
-        aSize.Height());
-
-    return aSize;
+    return Window::CalcWindowSize(aSize);
 }
 
 IMPL_LINK( Dialog, ImplHandleLayoutTimerHdl, void*, EMPTYARG )
 {
+    fprintf(stderr, "ImplHandleLayoutTimerHdl\n");
+
     VclBox *pBox = dynamic_cast<VclBox*>(GetWindow(WINDOW_FIRSTCHILD));
     if (!pBox)
     {
@@ -1231,19 +1220,11 @@ IMPL_LINK( Dialog, ImplHandleLayoutTimerHdl, void*, EMPTYARG )
     }
     Size aSize = GetSizePixel();
 
-    fprintf(stderr, "stage 4 dialog claimed to be %d %d\n", aSize.Width(),
-        aSize.Height());
-
     aSize.Width() -= mpWindowImpl->mnLeftBorder + mpWindowImpl->mnRightBorder
         + 2 * m_nBorderWidth;
     aSize.Height() -= mpWindowImpl->mnTopBorder + mpWindowImpl->mnBottomBorder
         + 2 * m_nBorderWidth;
 
-    fprintf(stderr, "stage 5 space for contents ends up as %d %d\n", aSize.Width(),
-        aSize.Height());
-    fprintf(stderr, "dialog got given %d %d\n", aSize.Width(),
-        aSize.Height());
-
     Point aPos(mpWindowImpl->mnLeftBorder + m_nBorderWidth,
         mpWindowImpl->mnTopBorder + m_nBorderWidth);
 
diff --git a/vcl/source/window/layout.cxx b/vcl/source/window/layout.cxx
index e74ebdf..b4ca472 100644
--- a/vcl/source/window/layout.cxx
+++ b/vcl/source/window/layout.cxx
@@ -42,6 +42,8 @@ Size VclContainer::GetOptimalSize(WindowSizeType eType) const
 
 void VclContainer::SetPosSizePixel(const Point& rAllocPos, const Size& rAllocation)
 {
+    fprintf(stderr, "VclContainer::SetPosSizePixel\n");
+
     Size aAllocation = rAllocation;
     aAllocation.Width() -= m_nBorderWidth*2;
     aAllocation.Height() -= m_nBorderWidth*2;
@@ -50,8 +52,44 @@ void VclContainer::SetPosSizePixel(const Point& rAllocPos, const Size& rAllocati
     aAllocPos.X() += m_nBorderWidth;
     aAllocPos.Y() += m_nBorderWidth;
 
-    Window::SetPosSizePixel(aAllocPos, aAllocation);
-    setAllocation(aAllocation);
+    bool bPosChanged = aAllocPos != GetPosPixel();
+    bool bSizeChanged = aAllocation != GetSizePixel();
+    if (bPosChanged && bSizeChanged)
+        Window::SetPosSizePixel(aAllocPos, aAllocation);
+    else if (bPosChanged)
+        Window::SetPosPixel(aAllocPos);
+    else if (bSizeChanged)
+        Window::SetSizePixel(aAllocation);
+
+    if (bSizeChanged)
+    {
+        fprintf(stderr, "VclContainer::setAllocation\n");
+        setAllocation(aAllocation);
+    }
+}
+
+void VclContainer::SetPosPixel(const Point& rAllocPos)
+{
+    Point aAllocPos = rAllocPos;
+    aAllocPos.X() += m_nBorderWidth;
+    aAllocPos.Y() += m_nBorderWidth;
+
+    if (aAllocPos != GetPosPixel())
+        Window::SetPosPixel(aAllocPos);
+}
+
+void VclContainer::SetSizePixel(const Size& rAllocation)
+{
+    Size aAllocation = rAllocation;
+    aAllocation.Width() -= m_nBorderWidth*2;
+    aAllocation.Height() -= m_nBorderWidth*2;
+
+    if (aAllocation != GetSizePixel())
+    {
+        Window::SetSizePixel(aAllocation);
+        fprintf(stderr, "VclContainer::setAllocation\n");
+        setAllocation(aAllocation);
+    }
 }
 
 bool VclContainer::set_property(const rtl::OString &rKey, const rtl::OString &rValue)
@@ -103,6 +141,22 @@ Size VclBox::calculateRequisition() const
     return aSize;
 }
 
+namespace
+{
+    //avoid redraws when size/pos is unchanged
+    void setPosSizePixel(Window &rWindow, const Point& rAllocPos, const Size& rAllocation)
+    {
+        bool bPosChanged = rAllocPos != rWindow.GetPosPixel();
+        bool bSizeChanged = rAllocation != rWindow.GetSizePixel();
+        if (bPosChanged && bSizeChanged)
+            rWindow.SetPosSizePixel(rAllocPos, rAllocation);
+        else if (bPosChanged)
+            rWindow.SetPosPixel(rAllocPos);
+        else if (bSizeChanged)
+            rWindow.SetSizePixel(rAllocation);
+    }
+}
+
 void VclBox::setAllocation(const Size &rAllocation)
 {
     //SetBackground( Color(0x00, 0xFF, 0x00) );
@@ -207,7 +261,7 @@ void VclBox::setAllocation(const Size &rAllocation)
                     getPrimaryDimension(aBoxSize));
             }
 
-            pChild->SetPosSizePixel(aChildPos, aChildSize);
+            setPosSizePixel(*pChild, aChildPos, aChildSize);
         }
     }
 }
@@ -336,7 +390,7 @@ void VclButtonBox::setAllocation(const Size &rAllocation)
         setSecondaryDimension(aChildSize, getSecondaryDimension(aSize));
         setPrimaryDimension(aChildSize, nHomogeneousDimension);
 
-        pChild->SetPosSizePixel(aPos, aChildSize);
+        setPosSizePixel(*pChild, aPos, aChildSize);
 
         nPrimaryCoordinate = getPrimaryCoordinate(aPos);
         setPrimaryCoordinate(aPos, nPrimaryCoordinate + nHomogeneousDimension + m_nSpacing);
@@ -627,7 +681,7 @@ void VclGrid::setAllocation(const Size& rAllocation)
                         break;
                 }
 
-                pChild->SetPosSizePixel(aChildPos, aChildSize);
+                setPosSizePixel(*pChild, aChildPos, aChildSize);
             }
             aAllocPos.Y() += aHeights[y] + get_row_spacing();
         }
@@ -694,7 +748,7 @@ void VclBin::setAllocation(const Size &rAllocation)
 {
     Window *pChild = get_child();
     if (pChild && pChild->IsVisible())
-        pChild->SetPosSizePixel(Point(0, 0), rAllocation);
+        setPosSizePixel(*pChild, Point(0, 0), rAllocation);
 }
 
 //To-Do, hook a DecorationView into VclFrame ?
@@ -747,13 +801,13 @@ void VclFrame::setAllocation(const Size &rAllocation)
         Size aLabelSize = pLabel->GetOptimalSize(WINDOWSIZE_PREFERRED);
         aLabelSize.Height() = std::min(aLabelSize.Height(), aAllocation.Height());
         aLabelSize.Width() = std::min(aLabelSize.Width(), aAllocation.Width());
-        pLabel->SetPosSizePixel(aChildPos, aLabelSize);
+        setPosSizePixel(*pLabel, aChildPos, aLabelSize);
         aAllocation.Height() -= aLabelSize.Height();
         aChildPos.Y() += aLabelSize.Height();
     }
 
     if (pChild && pChild->IsVisible())
-        pChild->SetPosSizePixel(aChildPos, aAllocation);
+        setPosSizePixel(*pChild, aChildPos, aAllocation);
 }
 
 Size VclAlignment::calculateRequisition() const
@@ -786,7 +840,7 @@ void VclAlignment::setAllocation(const Size &rAllocation)
     aAllocation.Width() = rAllocation.Width() - (m_nLeftPadding + m_nRightPadding);
     aAllocation.Height() = rAllocation.Height() - (m_nTopPadding + m_nBottomPadding);
 
-    pChild->SetPosSizePixel(aChildPos, aAllocation);
+    setPosSizePixel(*pChild, aChildPos, aAllocation);
 }
 
 bool VclAlignment::set_property(const rtl::OString &rKey, const rtl::OString &rValue)
commit 5af035284b8b0a0e0b834a284f2553f535e0f6b5
Author: Caolán McNamara <caolanm at redhat.com>
Date:   Sat Jun 16 12:38:51 2012 +0100

    skip queue_resize on irrelevant state changes

diff --git a/vcl/source/window/window.cxx b/vcl/source/window/window.cxx
index 033eb6e..483e3c2 100644
--- a/vcl/source/window/window.cxx
+++ b/vcl/source/window/window.cxx
@@ -4935,10 +4935,27 @@ void Window::UserEvent( sal_uLong, void* )
 
 // -----------------------------------------------------------------------
 
-void Window::StateChanged( StateChangedType )
+void Window::StateChanged( StateChangedType eType )
 {
-    queue_resize();
     DBG_CHKTHIS( Window, ImplDbgCheckWindow );
+    switch (eType)
+    {
+        //stuff that doesn't invalidate the layout
+        case STATE_CHANGE_CONTROLFOREGROUND:
+        case STATE_CHANGE_CONTROLBACKGROUND:
+        case STATE_CHANGE_TRANSPARENT:
+        case STATE_CHANGE_UPDATEMODE:
+        case STATE_CHANGE_READONLY:
+        case STATE_CHANGE_ENABLE:
+        case STATE_CHANGE_STATE:
+        case STATE_CHANGE_DATA:
+            break;
+        //stuff that does invalidate the layout
+        default:
+            fprintf(stderr, "queue_resize due to %d\n", eType);
+            queue_resize();
+            break;
+    }
 }
 
 // -----------------------------------------------------------------------


More information about the Libreoffice-commits mailing list