]> git.saurik.com Git - wxWidgets.git/blobdiff - src/common/wincmn.cpp
Set the correct svn properties on the new files. Correct a minor date typo.
[wxWidgets.git] / src / common / wincmn.cpp
index 19a474f5bef8476f79aee88bf9599baf23042ae4..77729d68c6886f06e986661b1e2dd368391cbe4c 100644 (file)
@@ -1,5 +1,5 @@
 /////////////////////////////////////////////////////////////////////////////
-// Name:        src/common/window.cpp
+// Name:        src/common/wincmn.cpp
 // Purpose:     common (to all ports) wxWindow functions
 // Author:      Julian Smart, Vadim Zeitlin
 // Modified by:
 #endif
 
 #include "wx/platinfo.h"
+#include "wx/private/window.h"
+
+#ifdef __WXMSW__
+    #include "wx/msw/wrapwin.h"
+#endif
 
 // Windows List
 WXDLLIMPEXP_DATA_CORE(wxWindowList) wxTopLevelWindows;
@@ -82,6 +87,8 @@ WXDLLIMPEXP_DATA_CORE(wxWindowList) wxTopLevelWindows;
 wxMenu *wxCurrentPopupMenu = NULL;
 #endif // wxUSE_MENUS
 
+extern WXDLLEXPORT_DATA(const char) wxPanelNameStr[] = "panel";
+
 // ----------------------------------------------------------------------------
 // static data
 // ----------------------------------------------------------------------------
@@ -109,6 +116,138 @@ END_EVENT_TABLE()
 // implementation of the common functionality of the wxWindow class
 // ============================================================================
 
+// ----------------------------------------------------------------------------
+// XTI
+// ----------------------------------------------------------------------------
+
+#if wxUSE_EXTENDED_RTTI
+
+// windows that are created from a parent window during its Create method, 
+// eg. spin controls in a calendar controls must never been streamed out 
+// separately otherwise chaos occurs. Right now easiest is to test for negative ids, 
+// as windows with negative ids never can be recreated anyway
+
+
+bool wxWindowStreamingCallback( const wxObject *object, wxObjectWriter *, 
+                               wxObjectWriterCallback *, const wxStringToAnyHashMap & )
+{
+    const wxWindow * win = wx_dynamic_cast(const wxWindow*, object);
+    if ( win && win->GetId() < 0 )
+        return false;
+    return true;
+}
+
+wxIMPLEMENT_DYNAMIC_CLASS_XTI_CALLBACK(wxWindow, wxWindowBase, "wx/window.h", \
+                                       wxWindowStreamingCallback)
+
+// make wxWindowList known before the property is used
+
+wxCOLLECTION_TYPE_INFO( wxWindow*, wxWindowList );
+
+template<> void wxCollectionToVariantArray( wxWindowList const &theList, 
+                                           wxAnyList &value)
+{
+    wxListCollectionToAnyList<wxWindowList::compatibility_iterator>( theList, value );
+}
+
+wxDEFINE_FLAGS( wxWindowStyle )
+
+wxBEGIN_FLAGS( wxWindowStyle )
+// new style border flags, we put them first to
+// use them for streaming out
+
+wxFLAGS_MEMBER(wxBORDER_SIMPLE)
+wxFLAGS_MEMBER(wxBORDER_SUNKEN)
+wxFLAGS_MEMBER(wxBORDER_DOUBLE)
+wxFLAGS_MEMBER(wxBORDER_RAISED)
+wxFLAGS_MEMBER(wxBORDER_STATIC)
+wxFLAGS_MEMBER(wxBORDER_NONE)
+
+// old style border flags
+wxFLAGS_MEMBER(wxSIMPLE_BORDER)
+wxFLAGS_MEMBER(wxSUNKEN_BORDER)
+wxFLAGS_MEMBER(wxDOUBLE_BORDER)
+wxFLAGS_MEMBER(wxRAISED_BORDER)
+wxFLAGS_MEMBER(wxSTATIC_BORDER)
+wxFLAGS_MEMBER(wxBORDER)
+
+// standard window styles
+wxFLAGS_MEMBER(wxTAB_TRAVERSAL)
+wxFLAGS_MEMBER(wxCLIP_CHILDREN)
+wxFLAGS_MEMBER(wxTRANSPARENT_WINDOW)
+wxFLAGS_MEMBER(wxWANTS_CHARS)
+wxFLAGS_MEMBER(wxFULL_REPAINT_ON_RESIZE)
+wxFLAGS_MEMBER(wxALWAYS_SHOW_SB )
+wxFLAGS_MEMBER(wxVSCROLL)
+wxFLAGS_MEMBER(wxHSCROLL)
+
+wxEND_FLAGS( wxWindowStyle )
+
+wxBEGIN_PROPERTIES_TABLE(wxWindow)
+wxEVENT_PROPERTY( Close, wxEVT_CLOSE_WINDOW, wxCloseEvent)
+wxEVENT_PROPERTY( Create, wxEVT_CREATE, wxWindowCreateEvent )
+wxEVENT_PROPERTY( Destroy, wxEVT_DESTROY, wxWindowDestroyEvent )
+// Always constructor Properties first
+
+wxREADONLY_PROPERTY( Parent,wxWindow*, GetParent, wxEMPTY_PARAMETER_VALUE, \
+                    0 /*flags*/, wxT("Helpstring"), wxT("group"))
+wxPROPERTY( Id,wxWindowID, SetId, GetId, -1 /*wxID_ANY*/, 0 /*flags*/, \
+           wxT("Helpstring"), wxT("group") )
+wxPROPERTY( Position,wxPoint, SetPosition, GetPosition, wxDefaultPosition, \
+           0 /*flags*/, wxT("Helpstring"), wxT("group")) // pos
+wxPROPERTY( Size,wxSize, SetSize, GetSize, wxDefaultSize, 0 /*flags*/, \
+           wxT("Helpstring"), wxT("group")) // size
+wxPROPERTY( WindowStyle, long, SetWindowStyleFlag, GetWindowStyleFlag, \
+           wxEMPTY_PARAMETER_VALUE, 0 /*flags*/, wxT("Helpstring"), wxT("group")) // style
+wxPROPERTY( Name,wxString, SetName, GetName, wxEmptyString, 0 /*flags*/, \
+           wxT("Helpstring"), wxT("group") )
+
+// Then all relations of the object graph
+
+wxREADONLY_PROPERTY_COLLECTION( Children, wxWindowList, wxWindowBase*, \
+                               GetWindowChildren, wxPROP_OBJECT_GRAPH /*flags*/, \
+                               wxT("Helpstring"), wxT("group"))
+
+// and finally all other properties
+
+wxPROPERTY( ExtraStyle, long, SetExtraStyle, GetExtraStyle, wxEMPTY_PARAMETER_VALUE, \
+           0 /*flags*/, wxT("Helpstring"), wxT("group")) // extstyle
+wxPROPERTY( BackgroundColour, wxColour, SetBackgroundColour, GetBackgroundColour, \
+           wxEMPTY_PARAMETER_VALUE, 0 /*flags*/, wxT("Helpstring"), wxT("group")) // bg
+wxPROPERTY( ForegroundColour, wxColour, SetForegroundColour, GetForegroundColour, \
+           wxEMPTY_PARAMETER_VALUE, 0 /*flags*/, wxT("Helpstring"), wxT("group")) // fg
+wxPROPERTY( Enabled, bool, Enable, IsEnabled, wxAny((bool)true), 0 /*flags*/, \
+           wxT("Helpstring"), wxT("group"))
+wxPROPERTY( Shown, bool, Show, IsShown, wxAny((bool)true), 0 /*flags*/, \
+           wxT("Helpstring"), wxT("group"))
+
+#if 0
+// possible property candidates (not in xrc) or not valid in all subclasses
+wxPROPERTY( Title,wxString, SetTitle, GetTitle, wxEmptyString )
+wxPROPERTY( Font, wxFont, SetFont, GetWindowFont , )
+wxPROPERTY( Label,wxString, SetLabel, GetLabel, wxEmptyString )
+// MaxHeight, Width, MinHeight, Width
+// TODO switch label to control and title to toplevels
+
+wxPROPERTY( ThemeEnabled, bool, SetThemeEnabled, GetThemeEnabled, )
+//wxPROPERTY( Cursor, wxCursor, SetCursor, GetCursor, )
+// wxPROPERTY( ToolTip, wxString, SetToolTip, GetToolTipText, )
+wxPROPERTY( AutoLayout, bool, SetAutoLayout, GetAutoLayout, )
+#endif
+wxEND_PROPERTIES_TABLE()
+
+wxEMPTY_HANDLERS_TABLE(wxWindow)
+
+wxCONSTRUCTOR_DUMMY(wxWindow)
+
+#else
+
+#ifndef __WXUNIVERSAL__
+IMPLEMENT_DYNAMIC_CLASS(wxWindow, wxWindowBase)
+#endif
+
+#endif
+
 // ----------------------------------------------------------------------------
 // initialization
 // ----------------------------------------------------------------------------
@@ -213,9 +352,8 @@ wxWindowBase::wxWindowBase()
 bool wxWindowBase::CreateBase(wxWindowBase *parent,
                               wxWindowID id,
                               const wxPoint& WXUNUSED(pos),
-                              const wxSize& WXUNUSED(size),
+                              const wxSize& size,
                               long style,
-                              const wxValidator& wxVALIDATOR_PARAM(validator),
                               const wxString& name)
 {
     // ids are limited to 16 bits under MSW so if you care about portability,
@@ -223,7 +361,7 @@ bool wxWindowBase::CreateBase(wxWindowBase *parent,
     // reserved for wxWidgets own usage)
     wxASSERT_MSG( id == wxID_ANY || (id >= 0 && id < 32767) ||
                   (id >= wxID_AUTO_LOWEST && id <= wxID_AUTO_HIGHEST),
-                  _T("invalid id value") );
+                  wxT("invalid id value") );
 
     // generate a new id if the user doesn't care about it
     if ( id == wxID_ANY )
@@ -240,9 +378,32 @@ bool wxWindowBase::CreateBase(wxWindowBase *parent,
     // flags by updating the window dynamically and we don't need this here
     m_windowStyle = style;
 
+    // assume the user doesn't want this window to shrink beneath its initial
+    // size, this worked like this in wxWidgets 2.8 and before and generally
+    // often makes sense for child windows (for top level ones it definitely
+    // does not as the user should be able to resize the window)
+    //
+    // note that we can't use IsTopLevel() from ctor
+    if ( size != wxDefaultSize && !wxTopLevelWindows.Find((wxWindow *)this) )
+        SetMinSize(size);
+
     SetName(name);
     SetParent(parent);
 
+    return true;
+}
+
+bool wxWindowBase::CreateBase(wxWindowBase *parent,
+                              wxWindowID id,
+                              const wxPoint& pos,
+                              const wxSize& size,
+                              long style,
+                              const wxValidator& wxVALIDATOR_PARAM(validator),
+                              const wxString& name)
+{
+    if ( !CreateBase(parent, id, pos, size, style, name) )
+        return false;
+
 #if wxUSE_VALIDATORS
     SetValidator(validator);
 #endif // wxUSE_VALIDATORS
@@ -260,7 +421,7 @@ bool wxWindowBase::CreateBase(wxWindowBase *parent,
 
 bool wxWindowBase::ToggleWindowStyle(int flag)
 {
-    wxASSERT_MSG( flag, _T("flags with 0 value can't be toggled") );
+    wxASSERT_MSG( flag, wxT("flags with 0 value can't be toggled") );
 
     bool rc;
     long style = GetWindowStyleFlag();
@@ -300,6 +461,12 @@ wxWindowBase::~wxWindowBase()
     // we weren't a dialog class
     wxTopLevelWindows.DeleteObject((wxWindow*)this);
 
+    // Any additional event handlers should be popped before the window is
+    // deleted as otherwise the last handler will be left with a dangling
+    // pointer to this window result in a difficult to diagnose crash later on.
+    wxASSERT_MSG( GetEventHandler() == this,
+                    wxT("any pushed event handlers must have been removed") );
+
 #if wxUSE_MENUS
     // The associated popup menu can still be alive, disassociate from it in
     // this case
@@ -331,8 +498,7 @@ wxWindowBase::~wxWindowBase()
         // This removes any dangling pointers to this window in other windows'
         // constraintsInvolvedIn lists.
         UnsetConstraints(m_constraints);
-        delete m_constraints;
-        m_constraints = NULL;
+        wxDELETE(m_constraints);
     }
 #endif // wxUSE_CONSTRAINTS
 
@@ -388,7 +554,14 @@ void wxWindowBase::SendDestroyEvent()
 
 bool wxWindowBase::Destroy()
 {
-    SendDestroyEvent();
+    // If our handle is invalid, it means that this window has never been
+    // created, either because creating it failed or, more typically, because
+    // this wxWindow object was default-constructed and its Create() method had
+    // never been called. As we didn't send wxWindowCreateEvent in this case
+    // (which is sent after successful creation), don't send the matching
+    // wxWindowDestroyEvent neither.
+    if ( GetHandle() )
+        SendDestroyEvent();
 
     delete this;
 
@@ -439,7 +612,7 @@ bool wxWindowBase::DestroyChildren()
 void wxWindowBase::DoCentre(int dir)
 {
     wxCHECK_RET( !(dir & wxCENTRE_ON_SCREEN) && GetParent(),
-                 _T("this method only implements centering child windows") );
+                 wxT("this method only implements centering child windows") );
 
     SetSize(GetRect().CentreIn(GetParent()->GetClientSize(), dir));
 }
@@ -474,7 +647,7 @@ static bool wxHasRealChildren(const wxWindowBase* win)
           node = node->GetNext() )
     {
         wxWindow *win = node->GetData();
-        if ( !win->IsTopLevel() && win->IsShown() 
+        if ( !win->IsTopLevel() && win->IsShown()
 #if wxUSE_SCROLLBAR
             && !win->IsKindOf(CLASSINFO(wxScrollBar))
 #endif
@@ -593,19 +766,14 @@ wxSize wxWindowBase::DoGetBestSize() const
     }
     else // ! has children
     {
-        // for a generic window there is no natural best size so, if the
-        // minimal size is not set, use the current size but take care to
-        // remember it as minimal size for the next time because our best size
-        // should be constant: otherwise we could get into a situation when the
-        // window is initially at some size, then expanded to a larger size and
-        // then, when the containing window is shrunk back (because our initial
-        // best size had been used for computing the parent min size), we can't
-        // be shrunk back any more because our best size is now bigger
         wxSize size = GetMinSize();
         if ( !size.IsFullySpecified() )
         {
-            size.SetDefaults(GetSize());
-            wxConstCast(this, wxWindowBase)->SetMinSize(size);
+            // if the window doesn't define its best size we assume that it can
+            // be arbitrarily small -- usually this is not the case, of course,
+            // but we have no way to know what the limit is, it should really
+            // override DoGetBestClientSize() itself to tell us
+            size.SetDefaults(wxSize(1, 1));
         }
 
         // return as-is, unadjusted by the client size difference.
@@ -644,7 +812,7 @@ static int wxGetMetricOrDefault(wxSystemMetric what, const wxWindowBase* win)
                 break;
 
             default:
-                wxFAIL_MSG( _T("unexpected wxGetMetricOrDefault() argument") );
+                wxFAIL_MSG( wxT("unexpected wxGetMetricOrDefault() argument") );
                 rc = 0;
         }
     }
@@ -684,7 +852,7 @@ wxSize wxWindowBase::GetWindowBorderSize() const
             break;
 
         default:
-            wxFAIL_MSG(_T("Unknown border style."));
+            wxFAIL_MSG(wxT("Unknown border style."));
             break;
     }
 
@@ -692,6 +860,16 @@ wxSize wxWindowBase::GetWindowBorderSize() const
     return size*2;
 }
 
+bool
+wxWindowBase::InformFirstDirection(int direction,
+                                   int size,
+                                   int availableOtherDir)
+{
+    return GetSizer() && GetSizer()->InformFirstDirection(direction,
+                                                          size,
+                                                          availableOtherDir);
+}
+
 wxSize wxWindowBase::GetEffectiveMinSize() const
 {
     // merge the best size with the min size, giving priority to the min size
@@ -707,6 +885,18 @@ wxSize wxWindowBase::GetEffectiveMinSize() const
     return min;
 }
 
+wxSize wxWindowBase::DoGetBorderSize() const
+{
+    // there is one case in which we can implement it for all ports easily
+    if ( GetBorder() == wxBORDER_NONE )
+        return wxSize(0, 0);
+
+    // otherwise use the difference between the real size and the client size
+    // as a fallback: notice that this is incorrect in general as client size
+    // also doesn't take the scrollbars into account
+    return GetSize() - GetClientSize();
+}
+
 wxSize wxWindowBase::GetBestSize() const
 {
     if ( !m_windowSizer && m_bestSizeCache.IsFullySpecified() )
@@ -797,22 +987,19 @@ void wxWindowBase::DoSetWindowVariant( wxWindowVariant variant )
             break;
 
         case wxWINDOW_VARIANT_SMALL:
-            size *= 3;
-            size /= 4;
+            size = wxRound(size * 3.0 / 4.0);
             break;
 
         case wxWINDOW_VARIANT_MINI:
-            size *= 2;
-            size /= 3;
+            size = wxRound(size * 2.0 / 3.0);
             break;
 
         case wxWINDOW_VARIANT_LARGE:
-            size *= 5;
-            size /= 4;
+            size = wxRound(size * 5.0 / 4.0);
             break;
 
         default:
-            wxFAIL_MSG(_T("unexpected window variant"));
+            wxFAIL_MSG(wxT("unexpected window variant"));
             break;
     }
 
@@ -826,7 +1013,7 @@ void wxWindowBase::DoSetSizeHints( int minW, int minH,
 {
     wxCHECK_RET( (minW == wxDefaultCoord || maxW == wxDefaultCoord || minW <= maxW) &&
                     (minH == wxDefaultCoord || maxH == wxDefaultCoord || minH <= maxH),
-                 _T("min width/height must be less than max width/height!") );
+                 wxT("min width/height must be less than max width/height!") );
 
     m_minWidth = minW;
     m_maxWidth = maxW;
@@ -884,7 +1071,7 @@ void wxWindowBase::SendSizeEvent(int flags)
     wxSizeEvent event(GetSize(), GetId());
     event.SetEventObject(this);
     if ( flags & wxSEND_EVENT_POST )
-        wxPostEvent(this, event);
+        wxPostEvent(GetEventHandler(), event);
     else
         HandleWindowEvent(event);
 }
@@ -896,6 +1083,20 @@ void wxWindowBase::SendSizeEventToParent(int flags)
         parent->SendSizeEvent(flags);
 }
 
+bool wxWindowBase::HasScrollbar(int orient) const
+{
+    // if scrolling in the given direction is disabled, we can't have the
+    // corresponding scrollbar no matter what
+    if ( !CanScroll(orient) )
+        return false;
+
+    const wxSize sizeVirt = GetVirtualSize();
+    const wxSize sizeClient = GetClientSize();
+
+    return orient == wxHORIZONTAL ? sizeVirt.x > sizeClient.x
+                                  : sizeVirt.y > sizeClient.y;
+}
+
 // ----------------------------------------------------------------------------
 // show/hide/enable/disable the window
 // ----------------------------------------------------------------------------
@@ -921,18 +1122,33 @@ bool wxWindowBase::IsEnabled() const
 
 void wxWindowBase::NotifyWindowOnEnableChange(bool enabled)
 {
+    // Under some platforms there is no need to update the window state
+    // explicitly, it will become disabled when its parent is. On other ones we
+    // do need to disable all windows recursively though.
 #ifndef wxHAS_NATIVE_ENABLED_MANAGEMENT
     DoEnable(enabled);
 #endif // !defined(wxHAS_NATIVE_ENABLED_MANAGEMENT)
 
     OnEnabled(enabled);
 
-    // If we are top-level then the logic doesn't apply - otherwise
-    // showing a modal dialog would result in total greying out (and ungreying
-    // out later) of everything which would be really ugly
-    if ( IsTopLevel() )
+    // Disabling a top level window is typically done when showing a modal
+    // dialog and we don't need to disable its children in this case, they will
+    // be logically disabled anyhow (i.e. their IsEnabled() will return false)
+    // and the TLW won't accept any input for them. Moreover, explicitly
+    // disabling them would look ugly as the entire TLW would be greyed out
+    // whenever a modal dialog is shown and no native applications under any
+    // platform behave like this.
+    if ( IsTopLevel() && !enabled )
         return;
 
+    // When disabling (or enabling back) a non-TLW window we need to
+    // recursively propagate the change of the state to its children, otherwise
+    // they would still show as enabled even though they wouldn't actually
+    // accept any input (at least under MSW where children don't accept input
+    // if any of the windows in their parent chain is enabled).
+    //
+    // Notice that we must do this even for wxHAS_NATIVE_ENABLED_MANAGEMENT
+    // platforms as we still need to call the children OnEnabled() recursively.
     for ( wxWindowList::compatibility_iterator node = GetChildren().GetFirst();
           node;
           node = node->GetNext() )
@@ -950,14 +1166,10 @@ bool wxWindowBase::Enable(bool enable)
 
     m_isEnabled = enable;
 
+    // If we call DoEnable() from NotifyWindowOnEnableChange(), we don't need
+    // to do it from here.
 #ifdef wxHAS_NATIVE_ENABLED_MANAGEMENT
     DoEnable(enable);
-#else // !defined(wxHAS_NATIVE_ENABLED_MANAGEMENT)
-    wxWindowBase * const parent = GetParent();
-    if( !IsTopLevel() && parent && !parent->IsEnabled() )
-    {
-        return true;
-    }
 #endif // !defined(wxHAS_NATIVE_ENABLED_MANAGEMENT)
 
     NotifyWindowOnEnableChange(enable);
@@ -1040,7 +1252,7 @@ void wxWindowBase::AddChild(wxWindowBase *child)
     // this should never happen and it will lead to a crash later if it does
     // because RemoveChild() will remove only one node from the children list
     // and the other(s) one(s) will be left with dangling pointers in them
-    wxASSERT_MSG( !GetChildren().Find((wxWindow*)child), _T("AddChild() called twice") );
+    wxASSERT_MSG( !GetChildren().Find((wxWindow*)child), wxT("AddChild() called twice") );
 
     GetChildren().Append((wxWindow*)child);
     child->SetParent(this);
@@ -1197,8 +1409,7 @@ wxEvtHandler *wxWindowBase::PopEventHandler(bool deleteHandler)
 
     if ( deleteHandler )
     {
-        delete firstHandler;
-        firstHandler = NULL;
+        wxDELETE(firstHandler);
     }
 
     return firstHandler;
@@ -1218,7 +1429,7 @@ bool wxWindowBase::RemoveEventHandler(wxEvtHandler *handlerToRemove)
 
     // NOTE: the wxWindow event handler list is always terminated with "this" handler
     wxEvtHandler *handlerCur = GetEventHandler()->GetNextHandler();
-    while ( handlerCur != this )
+    while ( handlerCur != this && handlerCur )
     {
         wxEvtHandler *handlerNext = handlerCur->GetNextHandler();
 
@@ -1234,7 +1445,7 @@ bool wxWindowBase::RemoveEventHandler(wxEvtHandler *handlerToRemove)
         handlerCur = handlerNext;
     }
 
-    wxFAIL_MSG( _T("where has the event handler gone?") );
+    wxFAIL_MSG( wxT("where has the event handler gone?") );
 
     return false;
 }
@@ -1307,13 +1518,13 @@ wxColour wxWindowBase::GetBackgroundColour() const
 {
     if ( !m_backgroundColour.IsOk() )
     {
-        wxASSERT_MSG( !m_hasBgCol, _T("we have invalid explicit bg colour?") );
+        wxASSERT_MSG( !m_hasBgCol, wxT("we have invalid explicit bg colour?") );
 
         // get our default background colour
         wxColour colBg = GetDefaultAttributes().colBg;
 
         // we must return some valid colour to avoid redoing this every time
-        // and also to avoid surprizing the applications written for older
+        // and also to avoid surprising the applications written for older
         // wxWidgets versions where GetBackgroundColour() always returned
         // something -- so give them something even if it doesn't make sense
         // for this window (e.g. it has a themed background)
@@ -1387,7 +1598,7 @@ wxFont wxWindowBase::GetFont() const
     // logic is the same as in GetBackgroundColour()
     if ( !m_font.IsOk() )
     {
-        wxASSERT_MSG( !m_hasFont, _T("we have invalid explicit font?") );
+        wxASSERT_MSG( !m_hasFont, wxT("we have invalid explicit font?") );
 
         wxFont font = GetDefaultAttributes().font;
         if ( !font.IsOk() )
@@ -1878,6 +2089,11 @@ void wxWindowBase::OnHelp(wxHelpEvent& event)
 
 #if wxUSE_TOOLTIPS
 
+wxString wxWindowBase::GetToolTipText() const
+{
+    return m_tooltip ? m_tooltip->GetTip() : wxString();
+}
+
 void wxWindowBase::SetToolTip( const wxString &tip )
 {
     // don't create the new tooltip if we already have one
@@ -2014,8 +2230,7 @@ void wxWindowBase::DeleteRelatedConstraints()
             node = next;
         }
 
-        delete m_constraintsInvolvedIn;
-        m_constraintsInvolvedIn = NULL;
+        wxDELETE(m_constraintsInvolvedIn);
     }
 }
 
@@ -2057,7 +2272,7 @@ void wxWindowBase::SetContainingSizer(wxSizer* sizer)
     // associated wxSizerItem we're going to dereference a dangling
     // pointer; so try to detect this as early as possible
     wxASSERT_MSG( !sizer || m_containingSizer != sizer,
-                  _T("Adding a window to the same sizer twice?") );
+                  wxT("Adding a window to the same sizer twice?") );
 
     m_containingSizer = sizer;
 }
@@ -2235,7 +2450,9 @@ void wxWindowBase::SetConstraintSizes(bool recurse)
         if ( (constr->width.GetRelationship() != wxAsIs ) ||
              (constr->height.GetRelationship() != wxAsIs) )
         {
-            SetSize(x, y, w, h);
+            // We really shouldn't set negative sizes for the windows so make
+            // them at least of 1*1 size
+            SetSize(x, y, w > 0 ? w : 1, h > 0 ? h : 1);
         }
         else
         {
@@ -2400,32 +2617,99 @@ void wxWindowBase::DoUpdateWindowUI(wxUpdateUIEvent& event)
         Show(event.GetShown());
 }
 
+// ----------------------------------------------------------------------------
+// Idle processing
+// ----------------------------------------------------------------------------
+
+// Send idle event to window and all subwindows
+bool wxWindowBase::SendIdleEvents(wxIdleEvent& event)
+{
+    bool needMore = false;
+
+    OnInternalIdle();
+
+    // should we send idle event to this window?
+    if (wxIdleEvent::GetMode() == wxIDLE_PROCESS_ALL ||
+        HasExtraStyle(wxWS_EX_PROCESS_IDLE))
+    {
+        event.SetEventObject(this);
+        HandleWindowEvent(event);
+
+        if (event.MoreRequested())
+            needMore = true;
+    }
+    wxWindowList::compatibility_iterator node = GetChildren().GetFirst();
+    for (; node; node = node->GetNext())
+    {
+        wxWindow* child = node->GetData();
+        if (child->SendIdleEvents(event))
+            needMore = true;
+    }
+
+    return needMore;
+}
+
+void wxWindowBase::OnInternalIdle()
+{
+    if ( wxUpdateUIEvent::CanUpdate(this) )
+        UpdateWindowUI(wxUPDATE_UI_FROMIDLE);
+}
+
 // ----------------------------------------------------------------------------
 // dialog units translations
 // ----------------------------------------------------------------------------
 
-wxPoint wxWindowBase::ConvertPixelsToDialog(const wxPoint& pt)
+// Windows' computes dialog units using average character width over upper-
+// and lower-case ASCII alphabet and not using the average character width
+// metadata stored in the font; see
+// http://support.microsoft.com/default.aspx/kb/145994 for detailed discussion.
+// It's important that we perform the conversion in identical way, because
+// dialog units natively exist only on Windows and Windows HIG is expressed
+// using them.
+wxSize wxWindowBase::GetDlgUnitBase() const
 {
-    int charWidth = GetCharWidth();
-    int charHeight = GetCharHeight();
+    const wxWindowBase * const parent = wxGetTopLevelParent((wxWindow*)this);
+
+    if ( !parent->m_font.IsOk() )
+    {
+        // Default GUI font is used. This is the most common case, so
+        // cache the results.
+        static wxSize s_defFontSize;
+        if ( s_defFontSize.x == 0 )
+            s_defFontSize = wxPrivate::GetAverageASCIILetterSize(*parent);
+        return s_defFontSize;
+    }
+    else
+    {
+        // Custom font, we always need to compute the result
+        return wxPrivate::GetAverageASCIILetterSize(*parent);
+    }
+}
+
+wxPoint wxWindowBase::ConvertPixelsToDialog(const wxPoint& pt) const
+{
+    const wxSize base = GetDlgUnitBase();
+
+    // NB: wxMulDivInt32() is used, because it correctly rounds the result
+
     wxPoint pt2 = wxDefaultPosition;
     if (pt.x != wxDefaultCoord)
-        pt2.x = (int) ((pt.x * 4) / charWidth);
+        pt2.x = wxMulDivInt32(pt.x, 4, base.x);
     if (pt.y != wxDefaultCoord)
-        pt2.y = (int) ((pt.y * 8) / charHeight);
+        pt2.y = wxMulDivInt32(pt.y, 8, base.y);
 
     return pt2;
 }
 
-wxPoint wxWindowBase::ConvertDialogToPixels(const wxPoint& pt)
+wxPoint wxWindowBase::ConvertDialogToPixels(const wxPoint& pt) const
 {
-    int charWidth = GetCharWidth();
-    int charHeight = GetCharHeight();
+    const wxSize base = GetDlgUnitBase();
+
     wxPoint pt2 = wxDefaultPosition;
     if (pt.x != wxDefaultCoord)
-        pt2.x = (int) ((pt.x * charWidth) / 4);
+        pt2.x = wxMulDivInt32(pt.x, base.x, 4);
     if (pt.y != wxDefaultCoord)
-        pt2.y = (int) ((pt.y * charHeight) / 8);
+        pt2.y = wxMulDivInt32(pt.y, base.y, 8);
 
     return pt2;
 }
@@ -2435,7 +2719,7 @@ wxPoint wxWindowBase::ConvertDialogToPixels(const wxPoint& pt)
 // ----------------------------------------------------------------------------
 
 // propagate the colour change event to the subwindows
-void wxWindowBase::OnSysColourChanged(wxSysColourChangedEvent& event)
+void wxWindowBase::OnSysColourChanged(wxSysColourChangedEvent& WXUNUSED(event))
 {
     wxWindowList::compatibility_iterator node = GetChildren().GetFirst();
     while ( node )
@@ -2445,7 +2729,7 @@ void wxWindowBase::OnSysColourChanged(wxSysColourChangedEvent& event)
         if ( !win->IsTopLevel() )
         {
             wxSysColourChangedEvent event2;
-            event.SetEventObject(win);
+            event2.SetEventObject(win);
             win->GetEventHandler()->ProcessEvent(event2);
         }
 
@@ -2476,6 +2760,9 @@ bool wxWindowBase::PopupMenu(wxMenu *menu, int x, int y)
 {
     wxCHECK_MSG( menu, false, "can't popup NULL menu" );
 
+    wxMenuInvokingWindowSetter
+        setInvokingWin(*menu, static_cast<wxWindow *>(this));
+
     wxCurrentPopupMenu = menu;
     const bool rc = DoPopupMenu(menu, x, y);
     wxCurrentPopupMenu = NULL;
@@ -2539,8 +2826,11 @@ wxWindowBase::DoGetPopupMenuSelectionFromUser(wxMenu& menu, int x, int y)
 
 #endif // wxUSE_MENUS
 
-// methods for drawing the sizers in a visible way
-#ifdef __WXDEBUG__
+// methods for drawing the sizers in a visible way: this is currently only
+// enabled for "full debug" builds with wxDEBUG_LEVEL==2 as it doesn't work
+// that well and also because we don't want to leave it enabled in default
+// builds used for production
+#if wxDEBUG_LEVEL > 1
 
 static void DrawSizers(wxWindowBase *win);
 
@@ -2622,22 +2912,27 @@ static void DrawSizers(wxWindowBase *win)
     }
 }
 
-#endif // __WXDEBUG__
+#endif // wxDEBUG_LEVEL
 
 // process special middle clicks
 void wxWindowBase::OnMiddleClick( wxMouseEvent& event )
 {
     if ( event.ControlDown() && event.AltDown() )
     {
-#ifdef __WXDEBUG__
+#if wxDEBUG_LEVEL > 1
         // Ctrl-Alt-Shift-mclick makes the sizers visible in debug builds
         if ( event.ShiftDown() )
         {
             DrawSizers(this);
-            return;
         }
+        else
 #endif // __WXDEBUG__
-        ::wxInfoMessageBox((wxWindow*)this);
+        {
+#if wxUSE_MSGDLG
+            // just Ctrl-Alt-middle click shows information about wx version
+            ::wxInfoMessageBox((wxWindow*)this);
+#endif // wxUSE_MSGDLG
+        }
     }
     else
     {
@@ -2679,19 +2974,19 @@ wxAccessible* wxWindowBase::CreateAccessible()
 // list classes implementation
 // ----------------------------------------------------------------------------
 
-#if wxUSE_STL
+#if wxUSE_STD_CONTAINERS
 
 #include "wx/listimpl.cpp"
 WX_DEFINE_LIST(wxWindowList)
 
-#else // !wxUSE_STL
+#else // !wxUSE_STD_CONTAINERS
 
 void wxWindowListNode::DeleteData()
 {
     delete (wxWindow *)GetData();
 }
 
-#endif // wxUSE_STL/!wxUSE_STL
+#endif // wxUSE_STD_CONTAINERS/!wxUSE_STD_CONTAINERS
 
 // ----------------------------------------------------------------------------
 // borders
@@ -2751,9 +3046,9 @@ bool wxWindowBase::ms_winCaptureChanging = false;
 
 void wxWindowBase::CaptureMouse()
 {
-    wxLogTrace(_T("mousecapture"), _T("CaptureMouse(%p)"), static_cast<void*>(this));
+    wxLogTrace(wxT("mousecapture"), wxT("CaptureMouse(%p)"), static_cast<void*>(this));
 
-    wxASSERT_MSG( !ms_winCaptureChanging, _T("recursive CaptureMouse call?") );
+    wxASSERT_MSG( !ms_winCaptureChanging, wxT("recursive CaptureMouse call?") );
 
     ms_winCaptureChanging = true;
 
@@ -2778,9 +3073,9 @@ void wxWindowBase::CaptureMouse()
 
 void wxWindowBase::ReleaseMouse()
 {
-    wxLogTrace(_T("mousecapture"), _T("ReleaseMouse(%p)"), static_cast<void*>(this));
+    wxLogTrace(wxT("mousecapture"), wxT("ReleaseMouse(%p)"), static_cast<void*>(this));
 
-    wxASSERT_MSG( !ms_winCaptureChanging, _T("recursive ReleaseMouse call?") );
+    wxASSERT_MSG( !ms_winCaptureChanging, wxT("recursive ReleaseMouse call?") );
 
     wxASSERT_MSG( GetCapture() == this,
                   "attempt to release mouse, but this window hasn't captured it" );
@@ -2805,8 +3100,8 @@ void wxWindowBase::ReleaseMouse()
 
     ms_winCaptureChanging = false;
 
-    wxLogTrace(_T("mousecapture"),
-        (const wxChar *) _T("After ReleaseMouse() mouse is captured by %p"),
+    wxLogTrace(wxT("mousecapture"),
+        (const wxChar *) wxT("After ReleaseMouse() mouse is captured by %p"),
         static_cast<void*>(GetCapture()));
 }
 
@@ -2820,7 +3115,7 @@ static void DoNotifyWindowAboutCaptureLost(wxWindow *win)
         // correctly if it loses capture unexpectedly; see the discussion here:
         // http://sourceforge.net/tracker/index.php?func=detail&aid=1153662&group_id=9863&atid=109863
         // http://article.gmane.org/gmane.comp.lib.wxwidgets.devel/82376
-        wxFAIL_MSG( _T("window that captured the mouse didn't process wxEVT_MOUSE_CAPTURE_LOST") );
+        wxFAIL_MSG( wxT("window that captured the mouse didn't process wxEVT_MOUSE_CAPTURE_LOST") );
     }
 }
 
@@ -2883,7 +3178,7 @@ bool wxWindowBase::TryBefore(wxEvent& event)
     if ( event.GetEventObject() == this )
     {
         wxValidator * const validator = GetValidator();
-        if ( validator && validator->ProcessEventHere(event) )
+        if ( validator && validator->ProcessEventLocally(event) )
         {
             return true;
         }
@@ -2925,11 +3220,11 @@ bool wxWindowBase::TryAfter(wxEvent& event)
 wxWindow *wxWindowBase::DoGetSibling(WindowOrder order) const
 {
     wxCHECK_MSG( GetParent(), NULL,
-                    _T("GetPrev/NextSibling() don't work for TLWs!") );
+                    wxT("GetPrev/NextSibling() don't work for TLWs!") );
 
     wxWindowList& siblings = GetParent()->GetChildren();
     wxWindowList::compatibility_iterator i = siblings.Find((wxWindow *)this);
-    wxCHECK_MSG( i, NULL, _T("window not a child of its parent?") );
+    wxCHECK_MSG( i, NULL, wxT("window not a child of its parent?") );
 
     if ( order == OrderBefore )
         i = i->GetPrevious();
@@ -2983,7 +3278,7 @@ void wxWindowBase::DoMoveInTabOrder(wxWindow *win, WindowOrder move)
 {
     // check that we're not a top level window
     wxCHECK_RET( GetParent(),
-                    _T("MoveBefore/AfterInTabOrder() don't work for TLWs!") );
+                    wxT("MoveBefore/AfterInTabOrder() don't work for TLWs!") );
 
     // detect the special case when we have nothing to do anyhow and when the
     // code below wouldn't work
@@ -2993,10 +3288,10 @@ void wxWindowBase::DoMoveInTabOrder(wxWindow *win, WindowOrder move)
     // find the target window in the siblings list
     wxWindowList& siblings = GetParent()->GetChildren();
     wxWindowList::compatibility_iterator i = siblings.Find(win);
-    wxCHECK_RET( i, _T("MoveBefore/AfterInTabOrder(): win is not a sibling") );
+    wxCHECK_RET( i, wxT("MoveBefore/AfterInTabOrder(): win is not a sibling") );
 
-    // unfortunately, when wxUSE_STL == 1 DetachNode() is not implemented so we
-    // can't just move the node around
+    // unfortunately, when wxUSE_STD_CONTAINERS == 1 DetachNode() is not
+    // implemented so we can't just move the node around
     wxWindow *self = (wxWindow *)this;
     siblings.DeleteObject(self);
     if ( move == OrderAfter )