vcl: ensure that VclBuilder is disposed before parent window.
Move VclBuilder to use VclPtr, link to documentation, and fix more
double dispose issues.
Change-Id: I4900b69dbb381bd7d6fda97f2a5e623bb58e0a9f
diff --git a/cui/source/options/optcolor.cxx b/cui/source/options/optcolor.cxx
index 3eb0229..c96cb62 100644
--- a/cui/source/options/optcolor.cxx
+++ b/cui/source/options/optcolor.cxx
@@ -174,6 +174,8 @@ class ColorConfigWindow_Impl
{
public:
ColorConfigWindow_Impl(vcl::Window* pParent);
~ColorConfigWindow_Impl() { dispose(); }
virtual void dispose() SAL_OVERRIDE;
public:
void SetLinks (Link const&, Link const&, Link const&);
@@ -508,6 +510,12 @@ ColorConfigWindow_Impl::ColorConfigWindow_Impl(vcl::Window* pParent)
SetAppearance();
}
void ColorConfigWindow_Impl::dispose()
{
disposeBuilder();
VclContainer::dispose();
}
Size ColorConfigWindow_Impl::calculateRequisition() const
{
return getLayoutRequisition(*m_pGrid);
@@ -913,9 +921,14 @@ ColorConfigCtrl_Impl::~ColorConfigCtrl_Impl()
void ColorConfigCtrl_Impl::dispose()
{
delete m_pVScroll;
m_pVScroll = NULL;
delete m_pScrollWindow;
m_pScrollWindow = NULL;
delete m_pBody;
m_pBody = NULL;
delete m_pHeaderHB;
m_pHeaderHB = NULL;
VclVBox::dispose();
}
diff --git a/include/vcl/builder.hxx b/include/vcl/builder.hxx
index 179ca33..aba3f08 100644
--- a/include/vcl/builder.hxx
+++ b/include/vcl/builder.hxx
@@ -16,6 +16,7 @@
#include <tools/fldunit.hxx>
#include <vcl/dllapi.h>
#include <vcl/window.hxx>
#include <vcl/vclptr.hxx>
#include <map>
#include <set>
#include <stack>
@@ -55,6 +56,9 @@ public:
const css::uno::Reference<css::frame::XFrame> &rFrame = css::uno::Reference<css::frame::XFrame>());
~VclBuilder();
///releases references and disposes all children.
void disposeBuilder();
//sID must exist and be of type T
template <typename T> T* get(T*& ret, const OString& sID);
@@ -146,7 +150,7 @@ private:
struct WinAndId
{
OString m_sID;
vcl::Window *m_pWindow;
VclPtr<vcl::Window> m_pWindow;
short m_nResponseId;
PackingData m_aPackingData;
WinAndId(const OString &rId, vcl::Window *pWindow, bool bVertical)
@@ -445,12 +449,17 @@ inline PopupMenu* VclBuilder::get_menu(PopupMenu*& ret, const OString& sID)
//
//i.e. class Dialog : public SystemWindow, public VclBuilderContainer
//not class Dialog : public VclBuilderContainer, public SystemWindow
//
//With the new 'dispose' framework, it is necessary to force the builder
//dispose before the Window dispose; so a Dialog::dispose() method would
//finish: disposeBuilder(); SystemWindow::dispose() to capture this ordering.
class VCL_DLLPUBLIC VclBuilderContainer
{
public:
VclBuilderContainer();
virtual ~VclBuilderContainer();
void disposeBuilder();
static OUString getUIRootDir();
bool hasBuilder() const { return m_pUIBuilder != NULL; }
diff --git a/include/vcl/tabpage.hxx b/include/vcl/tabpage.hxx
index c736197..7294d48 100644
--- a/include/vcl/tabpage.hxx
+++ b/include/vcl/tabpage.hxx
@@ -41,6 +41,8 @@ private:
public:
explicit TabPage( vcl::Window* pParent, WinBits nStyle = 0 );
explicit TabPage( vcl::Window *pParent, const OString& rID, const OUString& rUIXMLDescription );
~TabPage();
virtual void dispose() SAL_OVERRIDE;
virtual void Paint( const Rectangle& rRect ) SAL_OVERRIDE;
virtual void Draw( OutputDevice* pDev, const Point& rPos, const Size& rSize, sal_uLong nFlags ) SAL_OVERRIDE;
diff --git a/include/vcl/vclptr.hxx b/include/vcl/vclptr.hxx
index 37da714..50a87ba 100644
--- a/include/vcl/vclptr.hxx
+++ b/include/vcl/vclptr.hxx
@@ -70,6 +70,9 @@ public:
/**
* A thin wrapper around rtl::Reference to implement the acquire and dispose semantics we want for references to vcl::Window subclasses.
*
* For more details on the design please see vcl/README.lifecycle
*
* @param reference_type must be a subclass of vcl::Window
*/
template <class reference_type>
@@ -136,6 +139,11 @@ public:
m_rInnerRef.set(pBody);
}
inline void SAL_CALL reset(reference_type *pBody)
{
m_rInnerRef.set(pBody);
}
inline VclPtr<reference_type>& SAL_CALL operator= (reference_type * pBody)
{
m_rInnerRef.set(pBody);
@@ -152,6 +160,16 @@ public:
return m_rInnerRef.get() != NULL;
}
inline void SAL_CALL clear()
{
m_rInnerRef.clear();
}
inline void SAL_CALL reset()
{
m_rInnerRef.clear();
}
inline void disposeAndClear()
{
// hold it alive for the lifetime of this method
diff --git a/reportdesign/source/ui/dlg/Condition.cxx b/reportdesign/source/ui/dlg/Condition.cxx
index c5e131a2..fb86522 100644
--- a/reportdesign/source/ui/dlg/Condition.cxx
+++ b/reportdesign/source/ui/dlg/Condition.cxx
@@ -162,6 +162,7 @@ OColorPopup::~OColorPopup()
void OColorPopup::dispose()
{
m_aColorSet.disposeAndClear();
disposeBuilder();
FloatingWindow::dispose();
}
diff --git a/sfx2/source/appl/newhelp.cxx b/sfx2/source/appl/newhelp.cxx
index 9a80a2e..78c2df2 100644
--- a/sfx2/source/appl/newhelp.cxx
+++ b/sfx2/source/appl/newhelp.cxx
@@ -1457,6 +1457,9 @@ void SfxHelpIndexWindow_Impl::dispose()
SvtViewOptions aViewOpt( E_TABDIALOG, CONFIGNAME_INDEXWIN );
aViewOpt.SetPageID( (sal_Int32)m_pTabCtrl->GetCurPageId() );
disposeBuilder();
vcl::Window::dispose();
}
diff --git a/sfx2/source/dialog/backingwindow.cxx b/sfx2/source/dialog/backingwindow.cxx
index fa3f403..fcb9074e 100644
--- a/sfx2/source/dialog/backingwindow.cxx
+++ b/sfx2/source/dialog/backingwindow.cxx
@@ -217,6 +217,7 @@ void BackingWindow::dispose()
}
mxDropTargetListener = css::uno::Reference< css::datatransfer::dnd::XDropTargetListener >();
}
disposeBuilder();
vcl::Window::dispose();
}
diff --git a/sfx2/source/dialog/dockwin.cxx b/sfx2/source/dialog/dockwin.cxx
index c3e0e3d..e17c3b2 100644
--- a/sfx2/source/dialog/dockwin.cxx
+++ b/sfx2/source/dialog/dockwin.cxx
@@ -259,6 +259,8 @@ SfxTitleDockingWindow::~SfxTitleDockingWindow()
void SfxTitleDockingWindow::dispose()
{
delete m_pWrappedWindow;
m_pWrappedWindow = NULL;
SfxDockingWindow::dispose();
}
diff --git a/svx/source/dialog/ctredlin.cxx b/svx/source/dialog/ctredlin.cxx
index 48b50b0..0d2e530 100644
--- a/svx/source/dialog/ctredlin.cxx
+++ b/svx/source/dialog/ctredlin.cxx
@@ -118,6 +118,7 @@ SvxRedlinTable::~SvxRedlinTable()
void SvxRedlinTable::dispose()
{
delete pCommentSearcher;
pCommentSearcher = NULL;
SvSimpleTable::dispose();
}
@@ -1084,7 +1085,10 @@ SvxAcceptChgCtr::~SvxAcceptChgCtr()
void SvxAcceptChgCtr::dispose()
{
delete pTPView;
pTPView = NULL;
delete pTPFilter;
pTPFilter = NULL;
disposeBuilder();
TabControl::dispose();
}
diff --git a/svx/source/form/datanavi.cxx b/svx/source/form/datanavi.cxx
index 148a747..c09637e 100644
--- a/svx/source/form/datanavi.cxx
+++ b/svx/source/form/datanavi.cxx
@@ -1419,17 +1419,23 @@ namespace svxform
aViewOpt.SetUserItem(CFGNAME_SHOWDETAILS,aAny);
delete m_pInstPage;
m_pInstPage = NULL;
delete m_pSubmissionPage;
m_pSubmissionPage = NULL;
delete m_pBindingPage;
m_pBindingPage = NULL;
sal_Int32 i, nCount = m_aPageList.size();
for ( i = 0; i < nCount; ++i )
delete m_aPageList[i];
m_aPageList.clear();
Reference< XFrameActionListener > xListener(
static_cast< XFrameActionListener* >( m_xDataListener.get() ), UNO_QUERY );
m_xFrame->removeFrameActionListener( xListener );
RemoveBroadcaster();
m_xDataListener.clear();
disposeBuilder();
vcl::Window::dispose();
}
diff --git a/svx/source/sidebar/PanelLayout.cxx b/svx/source/sidebar/PanelLayout.cxx
index 23934f6..5224725 100644
--- a/svx/source/sidebar/PanelLayout.cxx
+++ b/svx/source/sidebar/PanelLayout.cxx
@@ -33,6 +33,7 @@ void PanelLayout::dispose()
{
m_bInClose = true;
m_aPanelLayoutIdle.Stop();
disposeBuilder();
Control::dispose();
}
diff --git a/sw/source/ui/index/cnttab.cxx b/sw/source/ui/index/cnttab.cxx
index 9bcaa1f..0005136 100644
--- a/sw/source/ui/index/cnttab.cxx
+++ b/sw/source/ui/index/cnttab.cxx
@@ -2658,6 +2658,8 @@ void SwTokenWindow::dispose()
pControl->SetLoseFocusHdl( Link() );
delete pControl;
}
aControlList.clear();
disposeBuilder();
VclHBox::dispose();
}
diff --git a/sw/source/uibase/sidebar/PagePropertyPanel.cxx b/sw/source/uibase/sidebar/PagePropertyPanel.cxx
index dd2fac9..13db321 100644
--- a/sw/source/uibase/sidebar/PagePropertyPanel.cxx
+++ b/sw/source/uibase/sidebar/PagePropertyPanel.cxx
@@ -206,7 +206,15 @@ PagePropertyPanel::~PagePropertyPanel()
void PagePropertyPanel::dispose()
{
delete[] maImgSize;
maImgSize = NULL;
delete[] maImgSize_L;
maImgSize_L = NULL;
mpPageItem.reset();
mpPageLRMarginItem.reset();
mpPageULMarginItem.reset();
mpPageSizeItem.reset();
PanelLayout::dispose();
}
diff --git a/vcl/source/window/builder.cxx b/vcl/source/window/builder.cxx
index 3efccec..278a3e5 100644
--- a/vcl/source/window/builder.cxx
+++ b/vcl/source/window/builder.cxx
@@ -525,17 +525,24 @@ VclBuilder::VclBuilder(vcl::Window *pParent, const OUString& sUIDir, const OUStr
VclBuilder::~VclBuilder()
{
disposeBuilder();
}
void VclBuilder::disposeBuilder()
{
for (std::vector<WinAndId>::reverse_iterator aI = m_aChildren.rbegin(),
aEnd = m_aChildren.rend(); aI != aEnd; ++aI)
{
delete aI->m_pWindow;
aI->m_pWindow.disposeAndClear();
}
m_aChildren.clear();
for (std::vector<MenuAndId>::reverse_iterator aI = m_aMenus.rbegin(),
aEnd = m_aMenus.rend(); aI != aEnd; ++aI)
{
delete aI->m_pMenu;
}
m_aMenus.clear();
}
void VclBuilder::handleTranslations(xmlreader::XmlReader &reader)
@@ -3213,7 +3220,7 @@ void VclBuilder::collectAccelerator(xmlreader::XmlReader &reader, stringmap &rMa
vcl::Window *VclBuilder::get_widget_root()
{
return m_aChildren.empty() ? NULL : m_aChildren[0].m_pWindow;
return m_aChildren.empty() ? NULL : m_aChildren[0].m_pWindow.get();
}
vcl::Window *VclBuilder::get_by_name(const OString& sID)
diff --git a/vcl/source/window/dialog.cxx b/vcl/source/window/dialog.cxx
index 8178788..9975c97 100644
--- a/vcl/source/window/dialog.cxx
+++ b/vcl/source/window/dialog.cxx
@@ -456,6 +456,12 @@ Dialog::Dialog( WindowType nType )
ImplInitDialogData();
}
void VclBuilderContainer::disposeBuilder()
{
if (m_pUIBuilder)
m_pUIBuilder->disposeBuilder();
}
OUString VclBuilderContainer::getUIRootDir()
{
/*to-do, check if user config has an override before using shared one, etc*/
diff --git a/vcl/source/window/dockwin.cxx b/vcl/source/window/dockwin.cxx
index 549d8c4..bc1740e 100644
--- a/vcl/source/window/dockwin.cxx
+++ b/vcl/source/window/dockwin.cxx
@@ -119,6 +119,9 @@ void ImplDockFloatWin::dispose()
{
if( mnLastUserEvent )
Application::RemoveUserEvent( mnLastUserEvent );
disposeBuilder();
FloatingWindow::dispose();
}
diff --git a/vcl/source/window/syswin.cxx b/vcl/source/window/syswin.cxx
index 19768d7..3bc802f 100644
--- a/vcl/source/window/syswin.cxx
+++ b/vcl/source/window/syswin.cxx
@@ -118,6 +118,7 @@ void SystemWindow::dispose()
// Hack to make sure code called from base ~Window does not interpret this
// as a SystemWindow (which it no longer is by then):
mpWindowImpl->mbSysWin = false;
disposeBuilder();
Window::dispose();
}
diff --git a/vcl/source/window/tabpage.cxx b/vcl/source/window/tabpage.cxx
index d554964..995438f 100644
--- a/vcl/source/window/tabpage.cxx
+++ b/vcl/source/window/tabpage.cxx
@@ -85,6 +85,17 @@ TabPage::TabPage(vcl::Window *pParent, const OString& rID, const OUString& rUIXM
set_expand(true);
}
TabPage::~TabPage()
{
dispose();
}
void TabPage::dispose()
{
disposeBuilder();
vcl::Window::dispose();
}
void TabPage::StateChanged( StateChangedType nType )
{
Window::StateChanged( nType );