]> git.saurik.com Git - wxWidgets.git/blobdiff - src/common/containr.cpp
more fixes to dllexport/import stuff for operator<<()s (still bug 1104372)
[wxWidgets.git] / src / common / containr.cpp
index fe1ea94cab0dace8a5add805a358dfe3ce23d2a8..a08c3b16aeef1c7b38019190c3727c9d4e3e5ed4 100644 (file)
@@ -17,7 +17,7 @@
 // headers
 // ----------------------------------------------------------------------------
 
-#ifdef __GNUG__
+#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
     #pragma implementation "containr.h"
 #endif
 
     #include "wx/scrolbar.h"
 #endif
 
+#ifdef __WXMSW__
+    #include "wx/radiobut.h"
+#endif
+
 // ============================================================================
 // implementation
 // ============================================================================
@@ -51,6 +55,7 @@ wxControlContainer::wxControlContainer(wxWindow *winParent)
     m_winLastFocused =
     m_winTmpDefault =
     m_winDefault = NULL;
+    m_inSetFocus = false;
 }
 
 bool wxControlContainer::AcceptsFocus() const
@@ -61,23 +66,23 @@ bool wxControlContainer::AcceptsFocus() const
         // otherwise we can accept focus either if we have no children at all
         // (in this case we're probably not used as a container) or only when
         // at least one child will accept focus
-        wxWindowList::Node *node = m_winParent->GetChildren().GetFirst();
+        wxWindowList::compatibility_iterator node = m_winParent->GetChildren().GetFirst();
         if ( !node )
-            return TRUE;
+            return true;
 
 #ifdef __WXMAC__
         // wxMac has eventually the two scrollbars as children, they don't count
         // as real children in the algorithm mentioned above
         bool hasRealChildren = false ;
 #endif
-        
+
         while ( node )
         {
             wxWindow *child = node->GetData();
 
             if ( child->AcceptsFocus() )
             {
-                return TRUE;
+                return true;
             }
 
 #ifdef __WXMAC__
@@ -87,14 +92,14 @@ bool wxControlContainer::AcceptsFocus() const
 #endif
             node = node->GetNext();
         }
-        
+
 #ifdef __WXMAC__
         if ( !hasRealChildren )
-            return TRUE ;
+            return true ;
 #endif
     }
 
-    return FALSE;
+    return false;
 }
 
 void wxControlContainer::SetLastFocus(wxWindow *win)
@@ -185,7 +190,7 @@ void wxControlContainer::HandleOnNavigationKey( wxNavigationKeyEvent& event )
 
     // the node of the children list from which we should start looking for the
     // next acceptable child
-    wxWindowList::Node *node, *start_node;
+    wxWindowList::compatibility_iterator node, start_node;
 
     // we should start from the first/last control and not from the one which
     // had focus the last time if we're propagating the event downwards because
@@ -200,7 +205,7 @@ void wxControlContainer::HandleOnNavigationKey( wxNavigationKeyEvent& event )
         node = forward ? children.GetFirst() : children.GetLast();
 
         // we want to cycle over all nodes
-        start_node = (wxWindowList::Node *)NULL;
+        start_node = wxWindowList::compatibility_iterator();
     }
     else
     {
@@ -224,7 +229,7 @@ void wxControlContainer::HandleOnNavigationKey( wxNavigationKeyEvent& event )
         }
         else
         {
-            start_node = (wxWindowList::Node *)NULL;
+            start_node = wxWindowList::compatibility_iterator();
         }
 
         if ( !start_node && m_winLastFocused )
@@ -286,13 +291,53 @@ void wxControlContainer::HandleOnNavigationKey( wxNavigationKeyEvent& event )
 
         wxWindow *child = node->GetData();
 
-        if ( child->AcceptsFocusFromKeyboard() )
+#if defined(__WXMSW__)
+        bool is_not_msw_rb = !m_winLastFocused ||
+                                !wxIsKindOf(m_winLastFocused,wxRadioButton);
+#else
+        static const bool is_not_msw_rb = true;
+#endif
+
+        if ( child->AcceptsFocusFromKeyboard() && is_not_msw_rb )
         {
             // if we're setting the focus to a child panel we should prevent it
             // from giving it to the child which had the focus the last time
             // and instead give it to the first/last child depending from which
             // direction we're coming
             event.SetEventObject(m_winParent);
+
+#if defined(__WXMSW__)
+            // we need to hop to the next activated
+            // radio button, not just the next radio
+            // button under MSW
+            if (wxIsKindOf(child,wxRadioButton))
+            {
+                wxRadioButton *rb = (wxRadioButton*) child;
+                if (!rb->GetValue())
+                {
+                    for (;;)
+                    {
+                        wxWindowList::compatibility_iterator node = children.Find( child );
+                        if (forward)
+                            node = node->GetNext();
+                        else
+                            node = node->GetPrevious();
+                        if (!node)
+                            return; // this would probably an error
+                        child = node->GetData();
+                        if (!wxIsKindOf(child,wxRadioButton))
+                            continue;
+                        rb = (wxRadioButton*) child;
+                        if (rb->GetValue())
+                            break;
+                    }
+                }
+            }
+#endif // __WXMSW__
+
+            // disable propagation for this call as otherwise the event might
+            // bounce back to us.
+            wxPropagationDisabler disableProp(event);
             if ( !child->GetEventHandler()->ProcessEvent(event) )
             {
                 // set it first in case SetFocusFromKbd() results in focus
@@ -304,7 +349,7 @@ void wxControlContainer::HandleOnNavigationKey( wxNavigationKeyEvent& event )
             }
             //else: the child manages its focus itself
 
-            event.Skip( FALSE );
+            event.Skip( false );
 
             return;
         }
@@ -338,6 +383,9 @@ bool wxControlContainer::DoSetFocus()
     wxLogTrace(_T("focus"), _T("SetFocus on wxPanel 0x%08lx."),
                (unsigned long)m_winParent->GetHandle());
 
+    if (m_inSetFocus)
+        return true;
+
     // when the panel gets the focus we move the focus to either the last
     // window that had the focus or the first one that can get it unless the
     // focus had been already set to some other child
@@ -348,7 +396,7 @@ bool wxControlContainer::DoSetFocus()
         if ( win == m_winParent )
         {
             // our child already has focus, don't take it away from it
-            return TRUE;
+            return true;
         }
 
         if ( win->IsTopLevel() )
@@ -361,7 +409,14 @@ bool wxControlContainer::DoSetFocus()
         win = win->GetParent();
     }
 
-    return SetFocusToChild();
+    // protect against infinite recursion:
+    m_inSetFocus = true;
+
+    bool ret = SetFocusToChild();
+
+    m_inSetFocus = false;
+
+    return ret;
 }
 
 void wxControlContainer::HandleOnFocus(wxFocusEvent& event)
@@ -387,8 +442,8 @@ bool wxControlContainer::SetFocusToChild()
 
 bool wxSetFocusToChild(wxWindow *win, wxWindow **childLastFocused)
 {
-    wxCHECK_MSG( win, FALSE, _T("wxSetFocusToChild(): invalid window") );
-    wxCHECK_MSG( childLastFocused, FALSE,
+    wxCHECK_MSG( win, false, _T("wxSetFocusToChild(): invalid window") );
+    wxCHECK_MSG( childLastFocused, false,
                  _T("wxSetFocusToChild(): NULL child poonter") );
 
     if ( *childLastFocused )
@@ -403,7 +458,7 @@ bool wxSetFocusToChild(wxWindow *win, wxWindow **childLastFocused)
             // not SetFocusFromKbd(): we're restoring focus back to the old
             // window and not setting it as the result of a kbd action
             (*childLastFocused)->SetFocus();
-            return TRUE;
+            return true;
         }
         else
         {
@@ -413,7 +468,7 @@ bool wxSetFocusToChild(wxWindow *win, wxWindow **childLastFocused)
     }
 
     // set the focus to the first child who wants it
-    wxWindowList::Node *node = win->GetChildren().GetFirst();
+    wxWindowList::compatibility_iterator node = win->GetChildren().GetFirst();
     while ( node )
     {
         wxWindow *child = node->GetData();
@@ -426,12 +481,12 @@ bool wxSetFocusToChild(wxWindow *win, wxWindow **childLastFocused)
 
             *childLastFocused = child;
             child->SetFocusFromKbd();
-            return TRUE;
+            return true;
         }
 
         node = node->GetNext();
     }
 
-    return FALSE;
+    return false;
 }