X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/bd83cb56d29385e2a87840eeb3876b976a5afc43..894406521a0058c3e06b957f32564043f23ad231:/src/common/cshelp.cpp?ds=sidebyside diff --git a/src/common/cshelp.cpp b/src/common/cshelp.cpp index c9a033d8a6..a7da4a1cf5 100644 --- a/src/common/cshelp.cpp +++ b/src/common/cshelp.cpp @@ -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 @@ -31,14 +31,11 @@ #if wxUSE_HELP #ifndef WX_PRECOMP - // FIXME: temporary needed for wxSimpleHelpProvider compilation, to be - // removed later - #include "wx/intl.h" - #include "wx/msgdlg.h" #endif +#include "wx/tipwin.h" #include "wx/app.h" - +#include "wx/module.h" #include "wx/cshelp.h" // ---------------------------------------------------------------------------- @@ -59,6 +56,8 @@ public: //// Data wxContextHelp* m_contextHelp; + + DECLARE_NO_COPY_CLASS(wxContextHelpEvtHandler) }; // ============================================================================ @@ -90,6 +89,27 @@ 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) { @@ -106,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(); @@ -114,7 +140,11 @@ bool wxContextHelp::BeginContextHelp(wxWindow* win) win->ReleaseMouse(); +#ifdef __WXMOTIF__ + wxPushOrPopEventHandlers(this, win, FALSE); +#else win->PopEventHandler(TRUE); +#endif win->SetCursor(oldCursor); @@ -122,6 +152,15 @@ bool wxContextHelp::BeginContextHelp(wxWindow* win) { wxPoint pt; wxWindow* winAtPtr = wxFindWindowAtPointer(pt); + +#if 0 + if (winAtPtr) + { + printf("Picked %s (%d)\n", winAtPtr->GetName().c_str(), + winAtPtr->GetId()); + } +#endif + if (winAtPtr) DispatchEvent(winAtPtr, pt); } @@ -139,6 +178,7 @@ bool wxContextHelp::EndContextHelp() bool wxContextHelp::EventLoop() { m_inHelp = TRUE; + while ( m_inHelp ) { if (wxTheApp->Pending()) @@ -150,38 +190,35 @@ bool wxContextHelp::EventLoop() wxTheApp->ProcessIdle(); } } + return TRUE; } bool wxContextHelpEvtHandler::ProcessEvent(wxEvent& event) { - switch (event.GetEventType()) + if (event.GetEventType() == wxEVT_LEFT_DOWN) { - case wxEVT_LEFT_DOWN: - { - //wxMouseEvent& mouseEvent = (wxMouseEvent&) event; - m_contextHelp->SetStatus(TRUE); - m_contextHelp->EndContextHelp(); - return TRUE; - break; - } - case wxEVT_CHAR: - case wxEVT_KEY_DOWN: - case wxEVT_ACTIVATE: - case wxEVT_MOUSE_CAPTURE_CHANGED: - { - m_contextHelp->SetStatus(FALSE); - m_contextHelp->EndContextHelp(); - return TRUE; - break; - } - case wxEVT_PAINT: - case wxEVT_ERASE_BACKGROUND: - { - event.Skip(); - return FALSE; - break; - } + m_contextHelp->SetStatus(TRUE); + m_contextHelp->EndContextHelp(); + return TRUE; + } + + if ((event.GetEventType() == wxEVT_CHAR) || + (event.GetEventType() == wxEVT_KEY_DOWN) || + (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); + m_contextHelp->EndContextHelp(); + return TRUE; + } + + if ((event.GetEventType() == wxEVT_PAINT) || + (event.GetEventType() == wxEVT_ERASE_BACKGROUND)) + { + event.Skip(); + return FALSE; } return TRUE; @@ -196,8 +233,9 @@ bool wxContextHelp::DispatchEvent(wxWindow* win, const wxPoint& pt) { wxHelpEvent helpEvent(wxEVT_HELP, subjectOfHelp->GetId(), pt) ; helpEvent.SetEventObject(this); + 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. @@ -216,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", @@ -232,7 +269,6 @@ static char * csquery_xpm[] = { " .. ", " .. ", " "}; -#endif IMPLEMENT_CLASS(wxContextHelpButton, wxBitmapButton) @@ -245,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()); } @@ -274,6 +317,11 @@ void wxHelpProvider::AddHelp(wxWindowID WXUNUSED(id), { } +// removes the association +void wxHelpProvider::RemoveHelp(wxWindowBase* WXUNUSED(window)) +{ +} + wxHelpProvider::~wxHelpProvider() { } @@ -284,36 +332,136 @@ 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); + m_hashIds.erase((long)id); + m_hashIds[id] = 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) + { + // 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; + wxString text = GetHelp(window); if ( !text.empty() ) { - wxMessageBox(text, _("Help"), wxICON_INFORMATION | wxOK, - (wxWindow *)window); + s_tipWindow = new wxTipWindow((wxWindow *)window, text, 100, & s_tipWindow); return TRUE; } +#endif // wxUSE_TIPWINDOW return FALSE; } +// ---------------------------------------------------------------------------- +// wxHelpControllerHelpProvider +// ---------------------------------------------------------------------------- + +wxHelpControllerHelpProvider::wxHelpControllerHelpProvider(wxHelpControllerBase* hc) +{ + m_helpController = hc; +} + +bool wxHelpControllerHelpProvider::ShowHelp(wxWindowBase *window) +{ + wxString text = GetHelp(window); + if ( !text.empty() ) + { + if (m_helpController) + { + if (text.IsNumber()) + return m_helpController->DisplayContextPopup(wxAtoi(text)); + + // 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); + + } + + return FALSE; +} + +// Convenience function for turning context id into wxString +wxString wxContextId(int id) +{ + return wxString::Format(_T("%d"), id); +} + +// ---------------------------------------------------------------------------- +// wxHelpProviderModule: module responsible for cleaning up help provider. +// ---------------------------------------------------------------------------- + +class wxHelpProviderModule : public wxModule +{ +public: + bool OnInit(); + void OnExit(); + +private: + DECLARE_DYNAMIC_CLASS(wxHelpProviderModule) +}; + +IMPLEMENT_DYNAMIC_CLASS(wxHelpProviderModule, wxModule) + +bool wxHelpProviderModule::OnInit() +{ + // Probably we don't want to do anything by default, + // since it could pull in extra code + // wxHelpProvider::Set(new wxSimpleHelpProvider); + + return TRUE; +} + +void wxHelpProviderModule::OnExit() +{ + if (wxHelpProvider::Get()) + { + delete wxHelpProvider::Get(); + wxHelpProvider::Set(NULL); + } +} + #endif // wxUSE_HELP