From eae0338fcb421ac03c0f78a0c0f30b9a766cdeec Mon Sep 17 00:00:00 2001
From: Robert Roebling <robert@roebling.de>
Date: Sun, 3 Sep 2006 11:48:49 +0000
Subject: [PATCH]   Commited patch for wxSizer::Replace()

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@40977 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
---
 docs/latex/wx/sizer.tex | 24 +++++++++++++
 include/wx/sizer.h      |  4 +++
 src/common/sizer.cpp    | 74 +++++++++++++++++++++++++++++++++++++++++
 3 files changed, 102 insertions(+)

diff --git a/docs/latex/wx/sizer.tex b/docs/latex/wx/sizer.tex
index 0b0c0e58cf..50a7756a82 100644
--- a/docs/latex/wx/sizer.tex
+++ b/docs/latex/wx/sizer.tex
@@ -416,6 +416,30 @@ currently no wxSizer method that will both detach and destroy a wxWindow item.
 Returns true if the child item was found and removed, false otherwise.
 
 
+\membersection{wxSizer::Replace}\label{wxsizerreplace}
+
+\func{bool}{Replace}{\param{wxWindow* }{oldwin}, \param{wxWindow* }{newwin}, \param{bool }{recursive = false}}
+
+\func{bool}{Replace}{\param{wxSizer* }{oldsz}, \param{wxSizer* }{newsz}, \param{bool }{recursive = false}}
+
+\func{bool}{Remove}{\param{size\_t }{oldindex}, \param{wxSizerItem* }{newitem}}
+
+Detaches the given \arg{oldwin}, \arg{oldsz} child from the sizer and 
+replaces it with the given window, sizer, or wxSizerItem.
+
+The detached child is removed {\bf only} if it is a sizer or a spacer
+(because windows are owned by their parent window, not the sizer).
+
+Use parameter \arg{recursive} to search the given element recursively in subsizers.
+
+
+This method does not cause any layout or resizing to take place, call
+\helpref{wxSizer::Layout}{wxsizerlayout} to update the layout "on screen" after replacing a
+child from the sizer.
+
+Returns true if the child item was found and removed, false otherwise.
+
+
 \membersection{wxSizer::SetDimension}\label{wxsizersetdimension}
 
 \func{void}{SetDimension}{\param{int }{x}, \param{int }{y}, \param{int }{width}, \param{int }{height}}
diff --git a/include/wx/sizer.h b/include/wx/sizer.h
index 62b49e6815..9044840a99 100644
--- a/include/wx/sizer.h
+++ b/include/wx/sizer.h
@@ -424,6 +424,10 @@ public:
     virtual bool Detach( wxSizer *sizer );
     virtual bool Detach( int index );
 
+    virtual bool Replace( wxWindow *oldwin, wxWindow *newwin, bool recursive = false );  
+    virtual bool Replace( wxSizer *oldsz, wxSizer *newsz, bool recursive = false );  
+    virtual bool Replace( size_t index, wxSizerItem *newitem );  
+
     virtual void Clear( bool delete_windows = false );
     virtual void DeleteWindows();
 
diff --git a/src/common/sizer.cpp b/src/common/sizer.cpp
index 02ca47f8f8..d645137e7c 100644
--- a/src/common/sizer.cpp
+++ b/src/common/sizer.cpp
@@ -621,6 +621,80 @@ bool wxSizer::Detach( int index )
     return true;
 }
 
+bool wxSizer::Replace( wxWindow *oldwin, wxWindow *newwin, bool recursive )
+{
+    wxASSERT_MSG( oldwin, _T("Replacing NULL window") );
+    wxASSERT_MSG( newwin, _T("Replacing with NULL window") );
+
+    wxSizerItemList::compatibility_iterator node = m_children.GetFirst();
+    while (node)
+    {
+        wxSizerItem     *item = node->GetData();
+
+        if (item->GetWindow() == oldwin)
+        {
+            item->GetWindow()->SetContainingSizer( NULL );
+            item->SetWindow(newwin);
+            newwin->SetContainingSizer( this );
+            return true;
+        }
+        else if (recursive && item->IsSizer())
+        {
+            if (item->GetSizer()->Replace( oldwin, newwin, true ))
+                return true;
+        }
+        
+        node = node->GetNext();
+    }
+
+    return false;
+}
+
+bool wxSizer::Replace( wxSizer *oldsz, wxSizer *newsz, bool recursive )
+{
+    wxASSERT_MSG( oldsz, _T("Replacing NULL sizer") );
+    wxASSERT_MSG( newsz, _T("Replacing with NULL sizer") );
+
+    wxSizerItemList::compatibility_iterator node = m_children.GetFirst();
+    while (node)
+    {
+        wxSizerItem     *item = node->GetData();
+
+        if (item->GetSizer() == oldsz)
+        {
+            wxSizer *old = item->GetSizer();
+            item->SetSizer(newsz);
+            delete old;
+            return true;
+        }
+        else if (recursive && item->IsSizer())
+        {
+            if (item->GetSizer()->Replace( oldsz, newsz, true ))
+                return true;
+        }        
+        
+        node = node->GetNext();
+    }
+
+    return false;
+}
+
+bool wxSizer::Replace( size_t old, wxSizerItem *newitem )
+{
+    wxCHECK_MSG( old < m_children.GetCount(), false, _T("Replace index is out of range") );
+    wxASSERT_MSG( newitem, _T("Replacing with NULL item") );
+
+    wxSizerItemList::compatibility_iterator node = m_children.Item( old );
+
+    wxCHECK_MSG( node, false, _T("Failed to find child node") );
+
+    wxSizerItem *item = node->GetData();
+    node->SetData(newitem);
+    delete item;    
+
+    return true;
+}
+
 void wxSizer::Clear( bool delete_windows )
 {
     // First clear the ContainingSizer pointers
-- 
2.50.0

