]> git.saurik.com Git - wxWidgets.git/blame - src/common/cshelp.cpp
fix from Robert
[wxWidgets.git] / src / common / cshelp.cpp
CommitLineData
fb6261e9 1/////////////////////////////////////////////////////////////////////////////
bd83cb56 2// Name: src/common/cshelp.cpp
fb6261e9 3// Purpose: Context sensitive help class implementation
bd83cb56 4// Author: Julian Smart, Vadim Zeitlin
fb6261e9
JS
5// Modified by:
6// Created: 08/09/2000
7// RCS-ID: $Id$
bd83cb56 8// Copyright: (c) 2000 Julian Smart, Vadim Zeitlin
fb6261e9
JS
9// Licence: wxWindows licence
10/////////////////////////////////////////////////////////////////////////////
11
bd83cb56
VZ
12// ============================================================================
13// declarations
14// ============================================================================
15
fb6261e9 16#ifdef __GNUG__
bd83cb56 17 #pragma implementation "cshelp.h"
fb6261e9
JS
18#endif
19
bd83cb56
VZ
20// ----------------------------------------------------------------------------
21// headers
22// ----------------------------------------------------------------------------
23
fb6261e9
JS
24// For compilers that support precompilation, includes "wx.h".
25#include "wx/wxprec.h"
26
27#ifdef __BORLANDC__
bd83cb56 28 #pragma hdrstop
fb6261e9
JS
29#endif
30
bd83cb56
VZ
31#if wxUSE_HELP
32
fb6261e9 33#ifndef WX_PRECOMP
fb6261e9
JS
34#endif
35
afb02ca5 36#include "wx/tipwin.h"
fb6261e9 37#include "wx/app.h"
129caadd 38#include "wx/module.h"
fb6261e9
JS
39#include "wx/cshelp.h"
40
bd83cb56
VZ
41// ----------------------------------------------------------------------------
42// wxContextHelpEvtHandler private class
43// ----------------------------------------------------------------------------
fb6261e9 44
bd83cb56
VZ
45// This class exists in order to eat events until the left mouse button is
46// pressed
fb6261e9
JS
47class wxContextHelpEvtHandler: public wxEvtHandler
48{
49public:
50 wxContextHelpEvtHandler(wxContextHelp* contextHelp)
51 {
52 m_contextHelp = contextHelp;
53 }
54
55 virtual bool ProcessEvent(wxEvent& event);
56
57//// Data
58 wxContextHelp* m_contextHelp;
59};
60
bd83cb56
VZ
61// ============================================================================
62// implementation
63// ============================================================================
64
65// ----------------------------------------------------------------------------
66// wxContextHelp
67// ----------------------------------------------------------------------------
68
69/*
70 * Invokes context-sensitive help
71 */
72
73
fb6261e9
JS
74IMPLEMENT_DYNAMIC_CLASS(wxContextHelp, wxObject)
75
76wxContextHelp::wxContextHelp(wxWindow* win, bool beginHelp)
77{
78 m_inHelp = FALSE;
79
80 if (beginHelp)
81 BeginContextHelp(win);
82}
83
84wxContextHelp::~wxContextHelp()
85{
86 if (m_inHelp)
87 EndContextHelp();
88}
89
90// Begin 'context help mode'
91bool wxContextHelp::BeginContextHelp(wxWindow* win)
92{
93 if (!win)
94 win = wxTheApp->GetTopWindow();
95 if (!win)
96 return FALSE;
97
98 wxCursor cursor(wxCURSOR_QUESTION_ARROW);
99 wxCursor oldCursor = win->GetCursor();
100 win->SetCursor(cursor);
101
102#ifdef __WXMSW__
103 // wxSetCursor(cursor);
104#endif
105
106 win->PushEventHandler(new wxContextHelpEvtHandler(this));
107
108 win->CaptureMouse();
109
110 EventLoop();
111
112 win->ReleaseMouse();
113
114 win->PopEventHandler(TRUE);
115
116 win->SetCursor(oldCursor);
117
118 if (m_status)
119 {
120 wxPoint pt;
121 wxWindow* winAtPtr = wxFindWindowAtPointer(pt);
122 if (winAtPtr)
123 DispatchEvent(winAtPtr, pt);
124 }
125
126 return TRUE;
127}
128
129bool wxContextHelp::EndContextHelp()
130{
131 m_inHelp = FALSE;
132
133 return TRUE;
134}
135
136bool wxContextHelp::EventLoop()
137{
138 m_inHelp = TRUE;
139 while ( m_inHelp )
140 {
141 if (wxTheApp->Pending())
142 {
143 wxTheApp->Dispatch();
144 }
145 else
146 {
147 wxTheApp->ProcessIdle();
148 }
149 }
150 return TRUE;
151}
152
153bool wxContextHelpEvtHandler::ProcessEvent(wxEvent& event)
154{
155 switch (event.GetEventType())
156 {
157 case wxEVT_LEFT_DOWN:
158 {
159 //wxMouseEvent& mouseEvent = (wxMouseEvent&) event;
160 m_contextHelp->SetStatus(TRUE);
161 m_contextHelp->EndContextHelp();
162 return TRUE;
163 break;
164 }
165 case wxEVT_CHAR:
166 case wxEVT_KEY_DOWN:
167 case wxEVT_ACTIVATE:
168 case wxEVT_MOUSE_CAPTURE_CHANGED:
169 {
170 m_contextHelp->SetStatus(FALSE);
171 m_contextHelp->EndContextHelp();
172 return TRUE;
173 break;
174 }
175 case wxEVT_PAINT:
176 case wxEVT_ERASE_BACKGROUND:
177 {
178 event.Skip();
179 return FALSE;
180 break;
181 }
182 }
183
184 return TRUE;
185}
186
187// Dispatch the help event to the relevant window
188bool wxContextHelp::DispatchEvent(wxWindow* win, const wxPoint& pt)
189{
190 wxWindow* subjectOfHelp = win;
191 bool eventProcessed = FALSE;
192 while (subjectOfHelp && !eventProcessed)
193 {
194 wxHelpEvent helpEvent(wxEVT_HELP, subjectOfHelp->GetId(), pt) ;
195 helpEvent.SetEventObject(this);
196 eventProcessed = win->GetEventHandler()->ProcessEvent(helpEvent);
197
198 // Go up the window hierarchy until the event is handled (or not).
199 // I.e. keep submitting ancestor windows until one is recognised
200 // by the app code that processes the ids and displays help.
201 subjectOfHelp = subjectOfHelp->GetParent();
202 }
203 return eventProcessed;
204}
205
bd83cb56
VZ
206// ----------------------------------------------------------------------------
207// wxContextHelpButton
208// ----------------------------------------------------------------------------
209
fb6261e9
JS
210/*
211 * wxContextHelpButton
212 * You can add this to your dialogs (especially on non-Windows platforms)
213 * to put the application into context help mode.
214 */
215
216#if !defined(__WXMSW__)
217static char * csquery_xpm[] = {
218"12 11 2 1",
57591e0e
JS
219" c None",
220". c #000000",
fb6261e9
JS
221" ",
222" .... ",
223" .. .. ",
224" .. .. ",
225" .. ",
226" .. ",
227" .. ",
228" ",
229" .. ",
230" .. ",
231" "};
232#endif
233
234IMPLEMENT_CLASS(wxContextHelpButton, wxBitmapButton)
235
236BEGIN_EVENT_TABLE(wxContextHelpButton, wxBitmapButton)
237 EVT_BUTTON(wxID_CONTEXT_HELP, wxContextHelpButton::OnContextHelp)
238END_EVENT_TABLE()
239
84bfc0d5
VZ
240wxContextHelpButton::wxContextHelpButton(wxWindow* parent,
241 wxWindowID id,
242 const wxPoint& pos,
243 const wxSize& size,
244 long style)
245 : wxBitmapButton(parent, id, wxBITMAP(csquery),
246 pos, size, style)
fb6261e9 247{
fb6261e9
JS
248}
249
250void wxContextHelpButton::OnContextHelp(wxCommandEvent& event)
251{
57591e0e 252 wxContextHelp contextHelp(GetParent());
fb6261e9
JS
253}
254
bd83cb56
VZ
255// ----------------------------------------------------------------------------
256// wxHelpProvider
257// ----------------------------------------------------------------------------
258
259wxHelpProvider *wxHelpProvider::ms_helpProvider = (wxHelpProvider *)NULL;
260
261// trivial implementation of some methods which we don't want to make pure
262// virtual for convenience
263
264void wxHelpProvider::AddHelp(wxWindowBase * WXUNUSED(window),
265 const wxString& WXUNUSED(text))
266{
267}
268
269void wxHelpProvider::AddHelp(wxWindowID WXUNUSED(id),
270 const wxString& WXUNUSED(text))
271{
272}
273
274wxHelpProvider::~wxHelpProvider()
275{
276}
277
278// ----------------------------------------------------------------------------
279// wxSimpleHelpProvider
280// ----------------------------------------------------------------------------
281
282wxString wxSimpleHelpProvider::GetHelp(const wxWindowBase *window)
283{
284 bool wasFound;
285 wxString text = m_hashWindows.Get((long)window, &wasFound);
286 if ( !wasFound )
287 text = m_hashIds.Get(window->GetId());
288
289 return text;
290}
291
292void wxSimpleHelpProvider::AddHelp(wxWindowBase *window, const wxString& text)
293{
294 m_hashWindows.Put((long)window, text);
295}
296
297void wxSimpleHelpProvider::AddHelp(wxWindowID id, const wxString& text)
298{
299 m_hashIds.Put(id, text);
300}
301
302bool wxSimpleHelpProvider::ShowHelp(wxWindowBase *window)
303{
304 wxString text = GetHelp(window);
305 if ( !text.empty() )
306 {
01fa3fe7 307 new wxTipWindow((wxWindow *)window, text);
bd83cb56
VZ
308
309 return TRUE;
310 }
311
312 return FALSE;
313}
314
5100cabf
JS
315// ----------------------------------------------------------------------------
316// wxHelpControllerHelpProvider
317// ----------------------------------------------------------------------------
318
319wxHelpControllerHelpProvider::wxHelpControllerHelpProvider(wxHelpControllerBase* hc)
320{
321 m_helpController = hc;
322}
323
324bool wxHelpControllerHelpProvider::ShowHelp(wxWindowBase *window)
325{
326 wxString text = GetHelp(window);
327 if ( !text.empty() )
328 {
329 if (m_helpController)
330 {
331 if (text.IsNumber())
332 return m_helpController->DisplayContextPopup(wxAtoi(text));
333
334 // If the help controller is capable of popping up the text...
335 else if (m_helpController->DisplayTextPopup(text, wxGetMousePosition()))
336 {
337 return TRUE;
338 }
339 else
340 // ...else use the default method.
341 return wxSimpleHelpProvider::ShowHelp(window);
342 }
343 else
344 return wxSimpleHelpProvider::ShowHelp(window);
345
346 }
347
348 return FALSE;
349}
350
351// Convenience function for turning context id into wxString
352wxString wxContextId(int id)
353{
354 return wxString(IntToString(id));
355}
356
129caadd
JS
357// ----------------------------------------------------------------------------
358// wxHelpProviderModule: module responsible for cleaning up help provider.
359// ----------------------------------------------------------------------------
360
361class wxHelpProviderModule : public wxModule
362{
363public:
364 bool OnInit();
365 void OnExit();
366
367private:
368 DECLARE_DYNAMIC_CLASS(wxHelpProviderModule)
369};
370
371IMPLEMENT_DYNAMIC_CLASS(wxHelpProviderModule, wxModule)
372
373bool wxHelpProviderModule::OnInit()
374{
375 // Probably we don't want to do anything by default,
376 // since it could pull in extra code
377 // wxHelpProvider::Set(new wxSimpleHelpProvider);
378
379 return TRUE;
380}
381
382void wxHelpProviderModule::OnExit()
383{
384 if (wxHelpProvider::Get())
385 {
386 delete wxHelpProvider::Get();
387 wxHelpProvider::Set(NULL);
388 }
389}
390
fb6261e9 391#endif // wxUSE_HELP