]> git.saurik.com Git - wxWidgets.git/blobdiff - src/common/cshelp.cpp
Applied patch [ 1192917 ] Grids with no row or col headers cause AV under wxGTK
[wxWidgets.git] / src / common / cshelp.cpp
index 3921a21c963c1e5fd5a43c3efba079a256cd9c56..31af18593eccb88fb6c91207a4619f393198d0d6 100644 (file)
@@ -6,14 +6,14 @@
 // Created:     08/09/2000
 // RCS-ID:      $Id$
 // Copyright:   (c) 2000 Julian Smart, Vadim Zeitlin
-// Licence:    wxWindows licence
+// Licence:     wxWindows licence
 /////////////////////////////////////////////////////////////////////////////
 
 // ============================================================================
 // declarations
 // ============================================================================
 
-#ifdef __GNUG__
+#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
     #pragma implementation "cshelp.h"
 #endif
 
@@ -56,6 +56,8 @@ public:
 
 //// Data
     wxContextHelp* m_contextHelp;
+
+    DECLARE_NO_COPY_CLASS(wxContextHelpEvtHandler)
 };
 
 // ============================================================================
@@ -75,7 +77,7 @@ IMPLEMENT_DYNAMIC_CLASS(wxContextHelp, wxObject)
 
 wxContextHelp::wxContextHelp(wxWindow* win, bool beginHelp)
 {
-    m_inHelp = FALSE;
+    m_inHelp = false;
 
     if (beginHelp)
         BeginContextHelp(win);
@@ -87,13 +89,34 @@ wxContextHelp::~wxContextHelp()
         EndContextHelp();
 }
 
+// Not currently needed, but on some systems capture may not work as
+// expected so we'll leave it here for now.
+#ifdef __WXMOTIF__
+static void wxPushOrPopEventHandlers(wxContextHelp* help, wxWindow* win, bool push)
+{
+    if (push)
+        win->PushEventHandler(new wxContextHelpEvtHandler(help));
+    else
+        win->PopEventHandler(true);
+
+    wxWindowList::compatibility_iterator node = win->GetChildren().GetFirst();
+    while (node)
+    {
+        wxWindow* child = node->GetData();
+        wxPushOrPopEventHandlers(help, child, push);
+
+        node = node->GetNext();
+    }
+}
+#endif
+
 // Begin 'context help mode'
 bool wxContextHelp::BeginContextHelp(wxWindow* win)
 {
     if (!win)
         win = wxTheApp->GetTopWindow();
     if (!win)
-        return FALSE;
+        return false;
 
     wxCursor cursor(wxCURSOR_QUESTION_ARROW);
     wxCursor oldCursor = win->GetCursor();
@@ -103,7 +126,13 @@ bool wxContextHelp::BeginContextHelp(wxWindow* win)
     //    wxSetCursor(cursor);
 #endif
 
+    m_status = false;
+
+#ifdef __WXMOTIF__
+    wxPushOrPopEventHandlers(this, win, true);
+#else
     win->PushEventHandler(new wxContextHelpEvtHandler(this));
+#endif
 
     win->CaptureMouse();
 
@@ -111,7 +140,11 @@ bool wxContextHelp::BeginContextHelp(wxWindow* win)
 
     win->ReleaseMouse();
 
-    win->PopEventHandler(TRUE);
+#ifdef __WXMOTIF__
+    wxPushOrPopEventHandlers(this, win, false);
+#else
+    win->PopEventHandler(true);
+#endif
 
     win->SetCursor(oldCursor);
 
@@ -119,32 +152,33 @@ bool wxContextHelp::BeginContextHelp(wxWindow* win)
     {
         wxPoint pt;
         wxWindow* winAtPtr = wxFindWindowAtPointer(pt);
-       /*
+
+#if 0
         if (winAtPtr)
         {
-       wxString msg;
-        msg.Printf("Picked %s (%d)", (const char*) winAtPtr->GetName(), winAtPtr->GetId());
-        cout << msg << '\n';
+            printf("Picked %s (%d)\n", winAtPtr->GetName().c_str(),
+                   winAtPtr->GetId());
         }
-       */
+#endif
 
         if (winAtPtr)
             DispatchEvent(winAtPtr, pt);
     }
 
-    return TRUE;
+    return true;
 }
 
 bool wxContextHelp::EndContextHelp()
 {
-    m_inHelp = FALSE;
+    m_inHelp = false;
 
-    return TRUE;
+    return true;
 }
 
 bool wxContextHelp::EventLoop()
 {
-    m_inHelp = TRUE;
+    m_inHelp = true;
+
     while ( m_inHelp )
     {
         if (wxTheApp->Pending())
@@ -156,49 +190,52 @@ bool wxContextHelp::EventLoop()
             wxTheApp->ProcessIdle();
         }
     }
-    return TRUE;
+
+    return true;
 }
 
 bool wxContextHelpEvtHandler::ProcessEvent(wxEvent& event)
 {
     if (event.GetEventType() == wxEVT_LEFT_DOWN)
     {
-        m_contextHelp->SetStatus(TRUE);
+        m_contextHelp->SetStatus(true);
         m_contextHelp->EndContextHelp();
-        return TRUE;
+        return true;
     }
-    
+
     if ((event.GetEventType() == wxEVT_CHAR) ||
         (event.GetEventType() == wxEVT_KEY_DOWN) ||
         (event.GetEventType() == wxEVT_ACTIVATE) ||
         (event.GetEventType() == wxEVT_MOUSE_CAPTURE_CHANGED))
     {
-        m_contextHelp->SetStatus(FALSE);
+        // May have already been set to true by a left-click
+        //m_contextHelp->SetStatus(false);
         m_contextHelp->EndContextHelp();
-        return TRUE;
+        return true;
     }
-    
+
     if ((event.GetEventType() == wxEVT_PAINT) ||
         (event.GetEventType() == wxEVT_ERASE_BACKGROUND))
     {
         event.Skip();
-        return FALSE;
+        return false;
     }
-    
-    return TRUE;
+
+    return true;
 }
 
 // Dispatch the help event to the relevant window
 bool wxContextHelp::DispatchEvent(wxWindow* win, const wxPoint& pt)
 {
     wxWindow* subjectOfHelp = win;
-    bool eventProcessed = FALSE;
+    bool eventProcessed = false;
     while (subjectOfHelp && !eventProcessed)
     {
         wxHelpEvent helpEvent(wxEVT_HELP, subjectOfHelp->GetId(), pt) ;
-        helpEvent.SetEventObject(this);
+        helpEvent.SetEventObject(subjectOfHelp);
+
         eventProcessed = win->GetEventHandler()->ProcessEvent(helpEvent);
-        
+
         // Go up the window hierarchy until the event is handled (or not).
         // I.e. keep submitting ancestor windows until one is recognised
         // by the app code that processes the ids and displays help.
@@ -217,8 +254,7 @@ bool wxContextHelp::DispatchEvent(wxWindow* win, const wxPoint& pt)
  * to put the application into context help mode.
  */
 
-#if !defined(__WXMSW__)
-static char * csquery_xpm[] = {
+static const char * csquery_xpm[] = {
 "12 11 2 1",
 "  c None",
 ". c #000000",
@@ -233,7 +269,6 @@ static char * csquery_xpm[] = {
 "     ..     ",
 "     ..     ",
 "            "};
-#endif
 
 IMPLEMENT_CLASS(wxContextHelpButton, wxBitmapButton)
 
@@ -246,12 +281,19 @@ wxContextHelpButton::wxContextHelpButton(wxWindow* parent,
                                          const wxPoint& pos,
                                          const wxSize& size,
                                          long style)
-                   : wxBitmapButton(parent, id, wxBITMAP(csquery),
+#if defined(__WXPM__)
+                   : wxBitmapButton(parent, id, wxBitmap(wxCSQUERY_BITMAP
+                                                         ,wxBITMAP_TYPE_RESOURCE
+                                                        ),
+                                    pos, size, style)
+#else
+                   : wxBitmapButton(parent, id, wxBitmap(csquery_xpm),
                                     pos, size, style)
+#endif
 {
 }
 
-void wxContextHelpButton::OnContextHelp(wxCommandEvent& event)
+void wxContextHelpButton::OnContextHelp(wxCommandEvent& WXUNUSED(event))
 {
     wxContextHelp contextHelp(GetParent());
 }
@@ -275,6 +317,11 @@ void wxHelpProvider::AddHelp(wxWindowID WXUNUSED(id),
 {
 }
 
+// removes the association
+void wxHelpProvider::RemoveHelp(wxWindowBase* WXUNUSED(window))
+{
+}
+
 wxHelpProvider::~wxHelpProvider()
 {
 }
@@ -285,26 +332,40 @@ wxHelpProvider::~wxHelpProvider()
 
 wxString wxSimpleHelpProvider::GetHelp(const wxWindowBase *window)
 {
-    bool wasFound;
-    wxString text = m_hashWindows.Get((long)window, &wasFound);
-    if ( !wasFound )
-        text = m_hashIds.Get(window->GetId());
+    wxLongToStringHashMap::iterator it = m_hashWindows.find((long)window);
+
+    if ( it == m_hashWindows.end() )
+    {
+        it = m_hashIds.find(window->GetId());
+        if ( it == m_hashIds.end() )
+            return wxEmptyString;
+    }
 
-    return text;
+    return it->second;
 }
 
 void wxSimpleHelpProvider::AddHelp(wxWindowBase *window, const wxString& text)
 {
-    m_hashWindows.Put((long)window, text);
+    m_hashWindows.erase((long)window);
+    m_hashWindows[(long)window] = text;
 }
 
 void wxSimpleHelpProvider::AddHelp(wxWindowID id, const wxString& text)
 {
-    m_hashIds.Put(id, text);
+    wxLongToStringHashMap::key_type key = (wxLongToStringHashMap::key_type)id;
+    m_hashIds.erase(key);
+    m_hashIds[key] = text;
+}
+
+// removes the association
+void wxSimpleHelpProvider::RemoveHelp(wxWindowBase* window)
+{
+    m_hashWindows.erase((long)window);
 }
 
 bool wxSimpleHelpProvider::ShowHelp(wxWindowBase *window)
 {
+#if wxUSE_TIPWINDOW
     static wxTipWindow* s_tipWindow = NULL;
 
     if (s_tipWindow)
@@ -321,10 +382,13 @@ bool wxSimpleHelpProvider::ShowHelp(wxWindowBase *window)
     {
         s_tipWindow = new wxTipWindow((wxWindow *)window, text, 100, & s_tipWindow);
 
-        return TRUE;
+        return true;
     }
+#else
+    wxUnusedVar(window);
+#endif // wxUSE_TIPWINDOW
 
-    return FALSE;
+    return false;
 }
 
 // ----------------------------------------------------------------------------
@@ -349,7 +413,7 @@ bool wxHelpControllerHelpProvider::ShowHelp(wxWindowBase *window)
             // If the help controller is capable of popping up the text...
             else if (m_helpController->DisplayTextPopup(text, wxGetMousePosition()))
             {
-                return TRUE;
+                return true;
             }
             else
             // ...else use the default method.
@@ -360,13 +424,13 @@ bool wxHelpControllerHelpProvider::ShowHelp(wxWindowBase *window)
 
     }
 
-    return FALSE;
+    return false;
 }
 
 // Convenience function for turning context id into wxString
 wxString wxContextId(int id)
 {
-    return wxString(IntToString(id));
+    return wxString::Format(_T("%d"), id);
 }
 
 // ----------------------------------------------------------------------------
@@ -391,7 +455,7 @@ bool wxHelpProviderModule::OnInit()
     // since it could pull in extra code
     // wxHelpProvider::Set(new wxSimpleHelpProvider);
 
-    return TRUE;
+    return true;
 }
 
 void wxHelpProviderModule::OnExit()