]> git.saurik.com Git - wxWidgets.git/blobdiff - src/common/wincmn.cpp
don't crash on weird line endings like \r\r\n
[wxWidgets.git] / src / common / wincmn.cpp
index 7ce145ca2482df539fa538e4fad26913eab01472..44b93da89dcefb4ad9816151eb0b8ed74597e024 100644 (file)
@@ -83,6 +83,8 @@
     extern const unsigned int gtk_micro_version;
 #endif
 
     extern const unsigned int gtk_micro_version;
 #endif
 
+#include "wx/platinfo.h"
+
 // Windows List
 WXDLLIMPEXP_DATA_CORE(wxWindowList) wxTopLevelWindows;
 
 // Windows List
 WXDLLIMPEXP_DATA_CORE(wxWindowList) wxTopLevelWindows;
 
@@ -198,6 +200,8 @@ wxWindowBase::wxWindowBase()
 
     m_virtualSize = wxDefaultSize;
 
 
     m_virtualSize = wxDefaultSize;
 
+    m_scrollHelper = (wxScrollHelper *) NULL;
+
     m_minVirtualWidth =
     m_maxVirtualWidth = wxDefaultCoord;
     m_minVirtualHeight =
     m_minVirtualWidth =
     m_maxVirtualWidth = wxDefaultCoord;
     m_minVirtualHeight =
@@ -288,6 +292,18 @@ wxWindowBase::~wxWindowBase()
 
     wxASSERT_MSG( GetChildren().GetCount() == 0, wxT("children not destroyed") );
 
 
     wxASSERT_MSG( GetChildren().GetCount() == 0, wxT("children not destroyed") );
 
+    // reset the top-level parent's default item if it is this widget
+    if ( m_parent )
+    {
+        wxTopLevelWindow *tlw = wxDynamicCast(wxGetTopLevelParent((wxWindow*)this),
+                                              wxTopLevelWindow);
+        
+        if ( tlw && tlw->GetDefaultItem() == this )
+            tlw->SetDefaultItem(NULL);
+        if ( tlw && tlw->GetTmpDefaultItem() == this )
+            tlw->SetTmpDefaultItem(NULL);
+    }
+
     // reset the dangling pointer our parent window may keep to us
     if ( m_parent )
     {
     // reset the dangling pointer our parent window may keep to us
     if ( m_parent )
     {
@@ -396,7 +412,7 @@ void wxWindowBase::Fit()
 {
     if ( !GetChildren().empty() )
     {
 {
     if ( !GetChildren().empty() )
     {
-        SetClientSize(GetBestSize());
+        SetSize(GetBestSize());
     }
     //else: do nothing if we have no children
 }
     }
     //else: do nothing if we have no children
 }
@@ -742,6 +758,13 @@ bool wxWindowBase::Enable(bool enable)
         return false;
     }
 }
         return false;
     }
 }
+
+bool wxWindowBase::IsShownOnScreen() const
+{
+    return IsShown() &&
+           (GetParent() == NULL || GetParent()->IsShownOnScreen());
+}
+
 // ----------------------------------------------------------------------------
 // RTTI
 // ----------------------------------------------------------------------------
 // ----------------------------------------------------------------------------
 // RTTI
 // ----------------------------------------------------------------------------
@@ -1138,12 +1161,12 @@ wxRect wxWindowBase::GetUpdateClientRect() const
     return rectUpdate;
 }
 
     return rectUpdate;
 }
 
-bool wxWindowBase::IsExposed(int x, int y) const
+bool wxWindowBase::DoIsExposed(int x, int y) const
 {
     return m_updateRegion.Contains(x, y) != wxOutRegion;
 }
 
 {
     return m_updateRegion.Contains(x, y) != wxOutRegion;
 }
 
-bool wxWindowBase::IsExposed(int x, int y, int w, int h) const
+bool wxWindowBase::DoIsExposed(int x, int y, int w, int h) const
 {
     return m_updateRegion.Contains(x, y, w, h) != wxOutRegion;
 }
 {
     return m_updateRegion.Contains(x, y, w, h) != wxOutRegion;
 }
@@ -1648,12 +1671,21 @@ void wxWindowBase::SetSizer(wxSizer *sizer, bool deleteOld)
     if ( sizer == m_windowSizer)
         return;
 
     if ( sizer == m_windowSizer)
         return;
 
-    if ( deleteOld )
-        delete m_windowSizer;
+    if ( m_windowSizer )
+    {
+        m_windowSizer->SetContainingWindow(NULL);
+
+        if ( deleteOld )
+            delete m_windowSizer;
+    }
 
     m_windowSizer = sizer;
 
     m_windowSizer = sizer;
+    if ( m_windowSizer )
+    {
+        m_windowSizer->SetContainingWindow((wxWindow *)this);
+    }
 
 
-    SetAutoLayout( sizer != NULL );
+    SetAutoLayout(m_windowSizer != NULL);
 }
 
 void wxWindowBase::SetSizerAndFit(wxSizer *sizer, bool deleteOld)
 }
 
 void wxWindowBase::SetSizerAndFit(wxSizer *sizer, bool deleteOld)
@@ -2164,69 +2196,38 @@ void wxWindowBase::OnMiddleClick( wxMouseEvent& event )
 #endif // __WXDEBUG__
 
 #if wxUSE_MSGDLG
 #endif // __WXDEBUG__
 
 #if wxUSE_MSGDLG
-        // don't translate these strings
-        wxString port;
-
-#ifdef __WXUNIVERSAL__
-        port = _T("Univ/");
-#endif // __WXUNIVERSAL__
-
-        switch ( wxGetOsVersion() )
-        {
-            case wxMOTIF_X:            port += _T("Motif"); break;
-            case wxMAC:
-            case wxMAC_DARWIN:         port += _T("Mac"); break;
-            case wxBEOS:               port += _T("BeOS"); break;
-            case wxGTK:
-            case wxGTK_WIN32:
-            case wxGTK_OS2:
-            case wxGTK_BEOS:           port += _T("GTK"); break;
-            case wxWINDOWS:
-            case wxPENWINDOWS:
-            case wxWINDOWS_NT:
-            case wxWIN32S:
-            case wxWIN95:
-            case wxWIN386:             port += _T("MS Windows"); break;
-            case wxMGL_UNIX:
-            case wxMGL_X:
-            case wxMGL_WIN32:
-            case wxMGL_OS2:            port += _T("MGL"); break;
-            case wxWINDOWS_OS2:
-            case wxOS2_PM:             port += _T("OS/2"); break;
-            case wxPALMOS:             port += _T("Palm OS"); break;
-            case wxWINDOWS_CE:         port += _T("Windows CE (generic)"); break;
-            case wxWINDOWS_POCKETPC:   port += _T("Windows CE PocketPC"); break;
-            case wxWINDOWS_SMARTPHONE: port += _T("Windows CE Smartphone"); break;
-            default:            port += _T("unknown"); break;
-        }
-
-        wxMessageBox(wxString::Format(
-                                      _T(
-                                        "       wxWidgets Library (%s port)\nVersion %d.%d.%d%s%s, compiled at %s %s%s\n   Copyright (c) 1995-2006 wxWidgets team"
-                                        ),
-                                      port.c_str(),
-                                      wxMAJOR_VERSION,
-                                      wxMINOR_VERSION,
-                                      wxRELEASE_NUMBER,
+        // don't translate these strings, they're for diagnostics purposes only
+        wxString msg;
+        msg.Printf(_T("wxWidgets Library (%s port)\n")
+                   _T("Version %d.%d.%d%s%s, compiled at %s %s\n")
+                   _T("Runtime version of toolkit used is %d.%d.%s\n")
+                   _T("Copyright (c) 1995-2006 wxWidgets team"),
+                   wxPlatformInfo::Get().GetPortIdName().c_str(),
+                   wxMAJOR_VERSION,
+                   wxMINOR_VERSION,
+                   wxRELEASE_NUMBER,
 #if wxUSE_UNICODE
 #if wxUSE_UNICODE
-                                      L" (Unicode)",
+                   L" (Unicode)",
 #else
 #else
-                                      "",
+                   wxEmptyString,
 #endif
 #ifdef __WXDEBUG__
 #endif
 #ifdef __WXDEBUG__
-                                      _T(" Debug build"),
+                   _T(" Debug build"),
 #else
 #else
-                                      wxEmptyString,
+                   wxEmptyString,
 #endif
 #endif
-                                      __TDATE__,
-                                      __TTIME__,
+                   __TDATE__,
+                   __TTIME__,
+                   wxPlatformInfo::Get().GetToolkitMajorVersion(),
+                   wxPlatformInfo::Get().GetToolkitMinorVersion(),
 #ifdef __WXGTK__
 #ifdef __WXGTK__
-                                      wxString::Format(_T("\nagainst GTK+ %d.%d.%d. Runtime GTK+ version: %d.%d.%d"), GTK_MAJOR_VERSION, GTK_MINOR_VERSION, GTK_MICRO_VERSION, gtk_major_version, gtk_minor_version, gtk_micro_version).c_str()
+                   wxString::Format(_T("\nThe compile-time GTK+ version is %d.%d.%d."), GTK_MAJOR_VERSION, GTK_MINOR_VERSION, GTK_MICRO_VERSION).c_str()
 #else
 #else
-                                      ""
+                   wxEmptyString
 #endif
 #endif
-                                     ),
-                     _T("wxWidgets information"),
+                   );
+
+        wxMessageBox(msg, _T("wxWidgets information"),
                      wxICON_INFORMATION | wxOK,
                      (wxWindow *)this);
     }
                      wxICON_INFORMATION | wxOK,
                      (wxWindow *)this);
     }
@@ -2334,11 +2335,17 @@ struct WXDLLEXPORT wxWindowNext
     wxWindow *win;
     wxWindowNext *next;
 } *wxWindowBase::ms_winCaptureNext = NULL;
     wxWindow *win;
     wxWindowNext *next;
 } *wxWindowBase::ms_winCaptureNext = NULL;
+wxWindow *wxWindowBase::ms_winCaptureCurrent = NULL;
+bool wxWindowBase::ms_winCaptureChanging = false;
 
 void wxWindowBase::CaptureMouse()
 {
     wxLogTrace(_T("mousecapture"), _T("CaptureMouse(%p)"), wx_static_cast(void*, this));
 
 
 void wxWindowBase::CaptureMouse()
 {
     wxLogTrace(_T("mousecapture"), _T("CaptureMouse(%p)"), wx_static_cast(void*, this));
 
+    wxASSERT_MSG( !ms_winCaptureChanging, _T("recursive CaptureMouse call?") );
+
+    ms_winCaptureChanging = true;
+
     wxWindow *winOld = GetCapture();
     if ( winOld )
     {
     wxWindow *winOld = GetCapture();
     if ( winOld )
     {
@@ -2353,19 +2360,28 @@ void wxWindowBase::CaptureMouse()
     //else: no mouse capture to save
 
     DoCaptureMouse();
     //else: no mouse capture to save
 
     DoCaptureMouse();
+    ms_winCaptureCurrent = (wxWindow*)this;
+
+    ms_winCaptureChanging = false;
 }
 
 void wxWindowBase::ReleaseMouse()
 {
     wxLogTrace(_T("mousecapture"), _T("ReleaseMouse(%p)"), wx_static_cast(void*, this));
 
 }
 
 void wxWindowBase::ReleaseMouse()
 {
     wxLogTrace(_T("mousecapture"), _T("ReleaseMouse(%p)"), wx_static_cast(void*, this));
 
+    wxASSERT_MSG( !ms_winCaptureChanging, _T("recursive ReleaseMouse call?") );
+
     wxASSERT_MSG( GetCapture() == this, wxT("attempt to release mouse, but this window hasn't captured it") );
 
     wxASSERT_MSG( GetCapture() == this, wxT("attempt to release mouse, but this window hasn't captured it") );
 
+    ms_winCaptureChanging = true;
+
     DoReleaseMouse();
     DoReleaseMouse();
+    ms_winCaptureCurrent = NULL;
 
     if ( ms_winCaptureNext )
     {
         ((wxWindowBase*)ms_winCaptureNext->win)->DoCaptureMouse();
 
     if ( ms_winCaptureNext )
     {
         ((wxWindowBase*)ms_winCaptureNext->win)->DoCaptureMouse();
+        ms_winCaptureCurrent = ms_winCaptureNext->win;
 
         wxWindowNext *item = ms_winCaptureNext;
         ms_winCaptureNext = item->next;
 
         wxWindowNext *item = ms_winCaptureNext;
         ms_winCaptureNext = item->next;
@@ -2373,11 +2389,51 @@ void wxWindowBase::ReleaseMouse()
     }
     //else: stack is empty, no previous capture
 
     }
     //else: stack is empty, no previous capture
 
+    ms_winCaptureChanging = false;
+
     wxLogTrace(_T("mousecapture"),
         (const wxChar *) _T("After ReleaseMouse() mouse is captured by %p"),
         wx_static_cast(void*, GetCapture()));
 }
 
     wxLogTrace(_T("mousecapture"),
         (const wxChar *) _T("After ReleaseMouse() mouse is captured by %p"),
         wx_static_cast(void*, GetCapture()));
 }
 
+static void DoNotifyWindowAboutCaptureLost(wxWindow *win)
+{
+    wxMouseCaptureLostEvent event(win->GetId());
+    event.SetEventObject(win);
+    if ( !win->GetEventHandler()->ProcessEvent(event) )
+    {
+        wxFAIL_MSG( _T("window that captured the mouse didn't process wxEVT_MOUSE_CAPTURE_LOST") );
+    }
+}
+
+/* static */
+void wxWindowBase::NotifyCaptureLost()
+{
+    // don't do anything if capture lost was expected, i.e. resulted from
+    // a wx call to ReleaseMouse or CaptureMouse:
+    if ( ms_winCaptureChanging )
+        return;
+
+    // if the capture was lost unexpectedly, notify every window that has
+    // capture (on stack or current) about it and clear the stack:
+
+    if ( ms_winCaptureCurrent )
+    {
+        DoNotifyWindowAboutCaptureLost(ms_winCaptureCurrent);
+        ms_winCaptureCurrent = NULL;
+    }
+
+    while ( ms_winCaptureNext )
+    {
+        wxWindowNext *item = ms_winCaptureNext;
+        ms_winCaptureNext = item->next;
+
+        DoNotifyWindowAboutCaptureLost(item->win);
+
+        delete item;
+    }
+}
+
 #if wxUSE_HOTKEY
 
 bool
 #if wxUSE_HOTKEY
 
 bool
@@ -2930,6 +2986,7 @@ wxAccStatus wxWindowAccessible::GetFocus(int* WXUNUSED(childId), wxAccessible**
     return wxACC_NOT_IMPLEMENTED;
 }
 
     return wxACC_NOT_IMPLEMENTED;
 }
 
+#if wxUSE_VARIANT
 // Gets a variant representing the selected children
 // of this object.
 // Acceptable values:
 // Gets a variant representing the selected children
 // of this object.
 // Acceptable values:
@@ -2946,5 +3003,24 @@ wxAccStatus wxWindowAccessible::GetSelections(wxVariant* WXUNUSED(selections))
 
     return wxACC_NOT_IMPLEMENTED;
 }
 
     return wxACC_NOT_IMPLEMENTED;
 }
+#endif // wxUSE_VARIANT
 
 #endif // wxUSE_ACCESSIBILITY
 
 #endif // wxUSE_ACCESSIBILITY
+
+// ----------------------------------------------------------------------------
+// RTL support
+// ----------------------------------------------------------------------------
+
+wxCoord
+wxWindowBase::AdjustForLayoutDirection(wxCoord x,
+                                       wxCoord width,
+                                       wxCoord widthTotal) const
+{
+    if ( GetLayoutDirection() == wxLayout_RightToLeft )
+    {
+        x = widthTotal - x - width;
+    }
+
+    return x;
+}
+