X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/e0f4c2c88b809fba4ea419ae9b8cfaf6b4bb9d89..d38315df30415b030d93172123920d69c5c5e3b6:/src/common/cshelp.cpp?ds=sidebyside diff --git a/src/common/cshelp.cpp b/src/common/cshelp.cpp index 8071439665..5bbdd65f52 100644 --- a/src/common/cshelp.cpp +++ b/src/common/cshelp.cpp @@ -13,10 +13,6 @@ // declarations // ============================================================================ -#ifdef __GNUG__ - #pragma implementation "cshelp.h" -#endif - // ---------------------------------------------------------------------------- // headers // ---------------------------------------------------------------------------- @@ -31,13 +27,18 @@ #if wxUSE_HELP #ifndef WX_PRECOMP + #include "wx/app.h" + #include "wx/module.h" #endif #include "wx/tipwin.h" -#include "wx/app.h" -#include "wx/module.h" #include "wx/cshelp.h" +#if wxUSE_MS_HTML_HELP + #include "wx/msw/helpchm.h" // for ShowContextHelpPopup + #include "wx/utils.h" // for wxGetMousePosition() +#endif + // ---------------------------------------------------------------------------- // wxContextHelpEvtHandler private class // ---------------------------------------------------------------------------- @@ -57,7 +58,7 @@ public: //// Data wxContextHelp* m_contextHelp; - DECLARE_NO_COPY_CLASS(wxContextHelpEvtHandler) + wxDECLARE_NO_COPY_CLASS(wxContextHelpEvtHandler); }; // ============================================================================ @@ -77,7 +78,7 @@ IMPLEMENT_DYNAMIC_CLASS(wxContextHelp, wxObject) wxContextHelp::wxContextHelp(wxWindow* win, bool beginHelp) { - m_inHelp = FALSE; + m_inHelp = false; if (beginHelp) BeginContextHelp(win); @@ -91,21 +92,21 @@ wxContextHelp::~wxContextHelp() // Not currently needed, but on some systems capture may not work as // expected so we'll leave it here for now. -#if 0 +#ifdef __WXMOTIF__ static void wxPushOrPopEventHandlers(wxContextHelp* help, wxWindow* win, bool push) { if (push) win->PushEventHandler(new wxContextHelpEvtHandler(help)); else - win->PopEventHandler(); + win->PopEventHandler(true); - wxNode* node = win->GetChildren().First(); + wxWindowList::compatibility_iterator node = win->GetChildren().GetFirst(); while (node) { - wxWindow* child = (wxWindow*) node->Data(); + wxWindow* child = node->GetData(); wxPushOrPopEventHandlers(help, child, push); - node = node->Next(); + node = node->GetNext(); } } #endif @@ -116,20 +117,23 @@ 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(); win->SetCursor(cursor); -#ifdef __WXMSW__ - // wxSetCursor(cursor); +#ifdef __WXMAC__ + wxSetCursor(cursor); #endif - m_status = FALSE; + m_status = false; +#ifdef __WXMOTIF__ + wxPushOrPopEventHandlers(this, win, true); +#else win->PushEventHandler(new wxContextHelpEvtHandler(this)); - //wxPushOrPopEventHandlers(this, win, TRUE); +#endif win->CaptureMouse(); @@ -137,41 +141,48 @@ bool wxContextHelp::BeginContextHelp(wxWindow* win) win->ReleaseMouse(); - win->PopEventHandler(TRUE); - //wxPushOrPopEventHandlers(this, win, FALSE); +#ifdef __WXMOTIF__ + wxPushOrPopEventHandlers(this, win, false); +#else + win->PopEventHandler(true); +#endif win->SetCursor(oldCursor); +#ifdef __WXMAC__ + wxSetCursor(wxNullCursor); +#endif + if (m_status) { 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 ) { @@ -185,16 +196,16 @@ bool wxContextHelp::EventLoop() } } - 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) || @@ -202,40 +213,32 @@ bool wxContextHelpEvtHandler::ProcessEvent(wxEvent& event) (event.GetEventType() == wxEVT_ACTIVATE) || (event.GetEventType() == wxEVT_MOUSE_CAPTURE_CHANGED)) { - // May have already been set to TRUE by a left-click - //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; - while (subjectOfHelp && !eventProcessed) - { - wxHelpEvent helpEvent(wxEVT_HELP, subjectOfHelp->GetId(), pt) ; - helpEvent.SetEventObject(this); + wxCHECK_MSG( win, false, wxT("win parameter can't be NULL") ); - eventProcessed = win->GetEventHandler()->ProcessEvent(helpEvent); + wxHelpEvent helpEvent(wxEVT_HELP, win->GetId(), pt, + wxHelpEvent::Origin_HelpButton); + helpEvent.SetEventObject(win); - // 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. - subjectOfHelp = subjectOfHelp->GetParent(); - } - return eventProcessed; + return win->GetEventHandler()->ProcessEvent(helpEvent); } // ---------------------------------------------------------------------------- @@ -248,6 +251,8 @@ bool wxContextHelp::DispatchEvent(wxWindow* win, const wxPoint& pt) * to put the application into context help mode. */ +#ifndef __WXPM__ + static const char * csquery_xpm[] = { "12 11 2 1", " c None", @@ -264,6 +269,8 @@ static const char * csquery_xpm[] = { " .. ", " "}; +#endif + IMPLEMENT_CLASS(wxContextHelpButton, wxBitmapButton) BEGIN_EVENT_TABLE(wxContextHelpButton, wxBitmapButton) @@ -296,7 +303,7 @@ void wxContextHelpButton::OnContextHelp(wxCommandEvent& WXUNUSED(event)) // wxHelpProvider // ---------------------------------------------------------------------------- -wxHelpProvider *wxHelpProvider::ms_helpProvider = (wxHelpProvider *)NULL; +wxHelpProvider *wxHelpProvider::ms_helpProvider = NULL; // trivial implementation of some methods which we don't want to make pure // virtual for convenience @@ -320,62 +327,113 @@ wxHelpProvider::~wxHelpProvider() { } +wxString wxHelpProvider::GetHelpTextMaybeAtPoint(wxWindowBase *window) +{ + if ( m_helptextAtPoint != wxDefaultPosition || + m_helptextOrigin != wxHelpEvent::Origin_Unknown ) + { + wxCHECK_MSG( window, wxEmptyString, wxT("window must not be NULL") ); + + wxPoint pt = m_helptextAtPoint; + wxHelpEvent::Origin origin = m_helptextOrigin; + + m_helptextAtPoint = wxDefaultPosition; + m_helptextOrigin = wxHelpEvent::Origin_Unknown; + + return window->GetHelpTextAtPoint(pt, origin); + } + + return GetHelp(window); +} + // ---------------------------------------------------------------------------- // wxSimpleHelpProvider // ---------------------------------------------------------------------------- +#define WINHASH_KEY(w) wxPtrToUInt(w) + wxString wxSimpleHelpProvider::GetHelp(const wxWindowBase *window) { - bool wasFound; - wxString text = m_hashWindows.Get((long)window, &wasFound); - if ( !wasFound ) - text = m_hashIds.Get(window->GetId()); + wxSimpleHelpProviderHashMap::iterator it = m_hashWindows.find(WINHASH_KEY(window)); - return text; + if ( it == m_hashWindows.end() ) + { + it = m_hashIds.find(window->GetId()); + if ( it == m_hashIds.end() ) + return wxEmptyString; + } + + return it->second; } void wxSimpleHelpProvider::AddHelp(wxWindowBase *window, const wxString& text) { - m_hashWindows.Delete((long)window); - m_hashWindows.Put((long)window, text); + m_hashWindows.erase(WINHASH_KEY(window)); + m_hashWindows[WINHASH_KEY(window)] = text; } void wxSimpleHelpProvider::AddHelp(wxWindowID id, const wxString& text) { - m_hashIds.Delete((long)id); - m_hashIds.Put(id, text); + wxSimpleHelpProviderHashMap::key_type key = (wxSimpleHelpProviderHashMap::key_type)id; + m_hashIds.erase(key); + m_hashIds[key] = text; } // removes the association void wxSimpleHelpProvider::RemoveHelp(wxWindowBase* window) { - m_hashWindows.Delete((long)window); + m_hashWindows.erase(WINHASH_KEY(window)); } bool wxSimpleHelpProvider::ShowHelp(wxWindowBase *window) { -#if wxUSE_TIPWINDOW - static wxTipWindow* s_tipWindow = NULL; +#if wxUSE_MS_HTML_HELP || wxUSE_TIPWINDOW +#if wxUSE_MS_HTML_HELP + // m_helptextAtPoint will be reset by GetHelpTextMaybeAtPoint(), stash it + const wxPoint posTooltip = m_helptextAtPoint; +#endif // wxUSE_MS_HTML_HELP - if (s_tipWindow) - { - // Prevent s_tipWindow being nulled in OnIdle, - // thereby removing the chance for the window to be closed by ShowHelp - s_tipWindow->SetTipWindowPtr(NULL); - s_tipWindow->Close(); - } - s_tipWindow = NULL; + const wxString text = GetHelpTextMaybeAtPoint(window); - wxString text = GetHelp(window); if ( !text.empty() ) { - s_tipWindow = new wxTipWindow((wxWindow *)window, text, 100, & s_tipWindow); + // use the native help popup style if it's available +#if wxUSE_MS_HTML_HELP + if ( !wxCHMHelpController::ShowContextHelpPopup + ( + text, + posTooltip, + (wxWindow *)window + ) ) +#endif // wxUSE_MS_HTML_HELP + { +#if wxUSE_TIPWINDOW + static wxTipWindow* s_tipWindow = NULL; - return TRUE; - } + if ( s_tipWindow ) + { + // Prevent s_tipWindow being nulled in OnIdle, thereby removing + // the chance for the window to be closed by ShowHelp + s_tipWindow->SetTipWindowPtr(NULL); + s_tipWindow->Close(); + } + + s_tipWindow = new wxTipWindow((wxWindow *)window, text, + 100, &s_tipWindow); +#else // !wxUSE_TIPWINDOW + // we tried wxCHMHelpController but it failed and we don't have + // wxTipWindow to fall back on, so + return false; #endif // wxUSE_TIPWINDOW + } - return FALSE; + return true; + } +#else // !wxUSE_MS_HTML_HELP && !wxUSE_TIPWINDOW + wxUnusedVar(window); +#endif // wxUSE_MS_HTML_HELP || wxUSE_TIPWINDOW + + return false; } // ---------------------------------------------------------------------------- @@ -389,35 +447,32 @@ wxHelpControllerHelpProvider::wxHelpControllerHelpProvider(wxHelpControllerBase* bool wxHelpControllerHelpProvider::ShowHelp(wxWindowBase *window) { - wxString text = GetHelp(window); - if ( !text.empty() ) - { - if (m_helpController) - { - if (text.IsNumber()) - return m_helpController->DisplayContextPopup(wxAtoi(text)); + const wxString text = GetHelpTextMaybeAtPoint(window); - // If the help controller is capable of popping up the text... - else if (m_helpController->DisplayTextPopup(text, wxGetMousePosition())) - { - return TRUE; - } - else - // ...else use the default method. - return wxSimpleHelpProvider::ShowHelp(window); - } - else - return wxSimpleHelpProvider::ShowHelp(window); + if ( text.empty() ) + return false; + if ( m_helpController ) + { + // if it's a numeric topic, show it + long topic; + if ( text.ToLong(&topic) ) + return m_helpController->DisplayContextPopup(topic); + + // otherwise show the text directly + if ( m_helpController->DisplayTextPopup(text, wxGetMousePosition()) ) + return true; } - return FALSE; + // if there is no help controller or it's not capable of showing the help, + // fallback to the default method + return wxSimpleHelpProvider::ShowHelp(window); } // Convenience function for turning context id into wxString wxString wxContextId(int id) { - return wxString::Format(_T("%d"), id); + return wxString::Format(wxT("%d"), id); } // ---------------------------------------------------------------------------- @@ -442,7 +497,7 @@ bool wxHelpProviderModule::OnInit() // since it could pull in extra code // wxHelpProvider::Set(new wxSimpleHelpProvider); - return TRUE; + return true; } void wxHelpProviderModule::OnExit()