1
/////////////////////////////////////////////////////////////////////////////
2
// Name: src/common/cshelp.cpp
3
// Purpose: Context sensitive help class implementation
4
// Author: Julian Smart, Vadim Zeitlin
7
// RCS-ID: $Id: cshelp.cpp,v 1.35 2005/07/21 16:19:39 ABX Exp $
8
// Copyright: (c) 2000 Julian Smart, Vadim Zeitlin
9
// Licence: wxWindows licence
10
/////////////////////////////////////////////////////////////////////////////
12
// ============================================================================
14
// ============================================================================
16
#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
17
#pragma implementation "cshelp.h"
20
// ----------------------------------------------------------------------------
22
// ----------------------------------------------------------------------------
24
// For compilers that support precompilation, includes "wx.h".
25
#include "wx/wxprec.h"
36
#include "wx/tipwin.h"
38
#include "wx/module.h"
39
#include "wx/cshelp.h"
41
// ----------------------------------------------------------------------------
42
// wxContextHelpEvtHandler private class
43
// ----------------------------------------------------------------------------
45
// This class exists in order to eat events until the left mouse button is
47
class wxContextHelpEvtHandler: public wxEvtHandler
50
wxContextHelpEvtHandler(wxContextHelp* contextHelp)
52
m_contextHelp = contextHelp;
55
virtual bool ProcessEvent(wxEvent& event);
58
wxContextHelp* m_contextHelp;
60
DECLARE_NO_COPY_CLASS(wxContextHelpEvtHandler)
63
// ============================================================================
65
// ============================================================================
67
// ----------------------------------------------------------------------------
69
// ----------------------------------------------------------------------------
72
* Invokes context-sensitive help
76
IMPLEMENT_DYNAMIC_CLASS(wxContextHelp, wxObject)
78
wxContextHelp::wxContextHelp(wxWindow* win, bool beginHelp)
83
BeginContextHelp(win);
86
wxContextHelp::~wxContextHelp()
92
// Not currently needed, but on some systems capture may not work as
93
// expected so we'll leave it here for now.
95
static void wxPushOrPopEventHandlers(wxContextHelp* help, wxWindow* win, bool push)
98
win->PushEventHandler(new wxContextHelpEvtHandler(help));
100
win->PopEventHandler(true);
102
wxWindowList::compatibility_iterator node = win->GetChildren().GetFirst();
105
wxWindow* child = node->GetData();
106
wxPushOrPopEventHandlers(help, child, push);
108
node = node->GetNext();
113
// Begin 'context help mode'
114
bool wxContextHelp::BeginContextHelp(wxWindow* win)
117
win = wxTheApp->GetTopWindow();
121
wxCursor cursor(wxCURSOR_QUESTION_ARROW);
122
wxCursor oldCursor = win->GetCursor();
123
win->SetCursor(cursor);
126
// wxSetCursor(cursor);
132
wxPushOrPopEventHandlers(this, win, true);
134
win->PushEventHandler(new wxContextHelpEvtHandler(this));
144
wxPushOrPopEventHandlers(this, win, false);
146
win->PopEventHandler(true);
149
win->SetCursor(oldCursor);
154
wxWindow* winAtPtr = wxFindWindowAtPointer(pt);
159
printf("Picked %s (%d)\n", winAtPtr->GetName().c_str(),
165
DispatchEvent(winAtPtr, pt);
171
bool wxContextHelp::EndContextHelp()
178
bool wxContextHelp::EventLoop()
184
if (wxTheApp->Pending())
186
wxTheApp->Dispatch();
190
wxTheApp->ProcessIdle();
197
bool wxContextHelpEvtHandler::ProcessEvent(wxEvent& event)
199
if (event.GetEventType() == wxEVT_LEFT_DOWN)
201
m_contextHelp->SetStatus(true);
202
m_contextHelp->EndContextHelp();
206
if ((event.GetEventType() == wxEVT_CHAR) ||
207
(event.GetEventType() == wxEVT_KEY_DOWN) ||
208
(event.GetEventType() == wxEVT_ACTIVATE) ||
209
(event.GetEventType() == wxEVT_MOUSE_CAPTURE_CHANGED))
211
// May have already been set to true by a left-click
212
//m_contextHelp->SetStatus(false);
213
m_contextHelp->EndContextHelp();
217
if ((event.GetEventType() == wxEVT_PAINT) ||
218
(event.GetEventType() == wxEVT_ERASE_BACKGROUND))
227
// Dispatch the help event to the relevant window
228
bool wxContextHelp::DispatchEvent(wxWindow* win, const wxPoint& pt)
230
wxWindow* subjectOfHelp = win;
231
bool eventProcessed = false;
232
while (subjectOfHelp && !eventProcessed)
234
wxHelpEvent helpEvent(wxEVT_HELP, subjectOfHelp->GetId(), pt) ;
235
helpEvent.SetEventObject(subjectOfHelp);
237
eventProcessed = win->GetEventHandler()->ProcessEvent(helpEvent);
239
// Go up the window hierarchy until the event is handled (or not).
240
// I.e. keep submitting ancestor windows until one is recognised
241
// by the app code that processes the ids and displays help.
242
subjectOfHelp = subjectOfHelp->GetParent();
244
return eventProcessed;
247
// ----------------------------------------------------------------------------
248
// wxContextHelpButton
249
// ----------------------------------------------------------------------------
252
* wxContextHelpButton
253
* You can add this to your dialogs (especially on non-Windows platforms)
254
* to put the application into context help mode.
259
static const char * csquery_xpm[] = {
277
IMPLEMENT_CLASS(wxContextHelpButton, wxBitmapButton)
279
BEGIN_EVENT_TABLE(wxContextHelpButton, wxBitmapButton)
280
EVT_BUTTON(wxID_CONTEXT_HELP, wxContextHelpButton::OnContextHelp)
283
wxContextHelpButton::wxContextHelpButton(wxWindow* parent,
288
#if defined(__WXPM__)
289
: wxBitmapButton(parent, id, wxBitmap(wxCSQUERY_BITMAP
290
,wxBITMAP_TYPE_RESOURCE
294
: wxBitmapButton(parent, id, wxBitmap(csquery_xpm),
300
void wxContextHelpButton::OnContextHelp(wxCommandEvent& WXUNUSED(event))
302
wxContextHelp contextHelp(GetParent());
305
// ----------------------------------------------------------------------------
307
// ----------------------------------------------------------------------------
309
wxHelpProvider *wxHelpProvider::ms_helpProvider = (wxHelpProvider *)NULL;
311
// trivial implementation of some methods which we don't want to make pure
312
// virtual for convenience
314
void wxHelpProvider::AddHelp(wxWindowBase * WXUNUSED(window),
315
const wxString& WXUNUSED(text))
319
void wxHelpProvider::AddHelp(wxWindowID WXUNUSED(id),
320
const wxString& WXUNUSED(text))
324
// removes the association
325
void wxHelpProvider::RemoveHelp(wxWindowBase* WXUNUSED(window))
329
wxHelpProvider::~wxHelpProvider()
333
// ----------------------------------------------------------------------------
334
// wxSimpleHelpProvider
335
// ----------------------------------------------------------------------------
337
wxString wxSimpleHelpProvider::GetHelp(const wxWindowBase *window)
339
wxLongToStringHashMap::iterator it = m_hashWindows.find((long)window);
341
if ( it == m_hashWindows.end() )
343
it = m_hashIds.find(window->GetId());
344
if ( it == m_hashIds.end() )
345
return wxEmptyString;
351
void wxSimpleHelpProvider::AddHelp(wxWindowBase *window, const wxString& text)
353
m_hashWindows.erase((long)window);
354
m_hashWindows[(long)window] = text;
357
void wxSimpleHelpProvider::AddHelp(wxWindowID id, const wxString& text)
359
wxLongToStringHashMap::key_type key = (wxLongToStringHashMap::key_type)id;
360
m_hashIds.erase(key);
361
m_hashIds[key] = text;
364
// removes the association
365
void wxSimpleHelpProvider::RemoveHelp(wxWindowBase* window)
367
m_hashWindows.erase((long)window);
370
bool wxSimpleHelpProvider::ShowHelp(wxWindowBase *window)
373
static wxTipWindow* s_tipWindow = NULL;
377
// Prevent s_tipWindow being nulled in OnIdle,
378
// thereby removing the chance for the window to be closed by ShowHelp
379
s_tipWindow->SetTipWindowPtr(NULL);
380
s_tipWindow->Close();
384
wxString text = GetHelp(window);
387
s_tipWindow = new wxTipWindow((wxWindow *)window, text, 100, & s_tipWindow);
393
#endif // wxUSE_TIPWINDOW
398
// ----------------------------------------------------------------------------
399
// wxHelpControllerHelpProvider
400
// ----------------------------------------------------------------------------
402
wxHelpControllerHelpProvider::wxHelpControllerHelpProvider(wxHelpControllerBase* hc)
404
m_helpController = hc;
407
bool wxHelpControllerHelpProvider::ShowHelp(wxWindowBase *window)
409
wxString text = GetHelp(window);
412
if (m_helpController)
415
return m_helpController->DisplayContextPopup(wxAtoi(text));
417
// If the help controller is capable of popping up the text...
418
else if (m_helpController->DisplayTextPopup(text, wxGetMousePosition()))
423
// ...else use the default method.
424
return wxSimpleHelpProvider::ShowHelp(window);
427
return wxSimpleHelpProvider::ShowHelp(window);
434
// Convenience function for turning context id into wxString
435
wxString wxContextId(int id)
437
return wxString::Format(_T("%d"), id);
440
// ----------------------------------------------------------------------------
441
// wxHelpProviderModule: module responsible for cleaning up help provider.
442
// ----------------------------------------------------------------------------
444
class wxHelpProviderModule : public wxModule
451
DECLARE_DYNAMIC_CLASS(wxHelpProviderModule)
454
IMPLEMENT_DYNAMIC_CLASS(wxHelpProviderModule, wxModule)
456
bool wxHelpProviderModule::OnInit()
458
// Probably we don't want to do anything by default,
459
// since it could pull in extra code
460
// wxHelpProvider::Set(new wxSimpleHelpProvider);
465
void wxHelpProviderModule::OnExit()
467
if (wxHelpProvider::Get())
469
delete wxHelpProvider::Get();
470
wxHelpProvider::Set(NULL);