]> git.saurik.com Git - wxWidgets.git/blame_incremental - src/common/cshelp.cpp
Added -w-inl to CFG section to suppress the annoying messages about event and radiobo...
[wxWidgets.git] / src / common / cshelp.cpp
... / ...
CommitLineData
1/////////////////////////////////////////////////////////////////////////////
2// Name: src/common/cshelp.cpp
3// Purpose: Context sensitive help class implementation
4// Author: Julian Smart, Vadim Zeitlin
5// Modified by:
6// Created: 08/09/2000
7// RCS-ID: $Id$
8// Copyright: (c) 2000 Julian Smart, Vadim Zeitlin
9// Licence: wxWindows licence
10/////////////////////////////////////////////////////////////////////////////
11
12// ============================================================================
13// declarations
14// ============================================================================
15
16#ifdef __GNUG__
17 #pragma implementation "cshelp.h"
18#endif
19
20// ----------------------------------------------------------------------------
21// headers
22// ----------------------------------------------------------------------------
23
24// For compilers that support precompilation, includes "wx.h".
25#include "wx/wxprec.h"
26
27#ifdef __BORLANDC__
28 #pragma hdrstop
29#endif
30
31#if wxUSE_HELP
32
33#ifndef WX_PRECOMP
34#endif
35
36#include "wx/tipwin.h"
37#include "wx/app.h"
38#include "wx/module.h"
39#include "wx/cshelp.h"
40
41// ----------------------------------------------------------------------------
42// wxContextHelpEvtHandler private class
43// ----------------------------------------------------------------------------
44
45// This class exists in order to eat events until the left mouse button is
46// pressed
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 DECLARE_NO_COPY_CLASS(wxContextHelpEvtHandler)
61};
62
63// ============================================================================
64// implementation
65// ============================================================================
66
67// ----------------------------------------------------------------------------
68// wxContextHelp
69// ----------------------------------------------------------------------------
70
71/*
72 * Invokes context-sensitive help
73 */
74
75
76IMPLEMENT_DYNAMIC_CLASS(wxContextHelp, wxObject)
77
78wxContextHelp::wxContextHelp(wxWindow* win, bool beginHelp)
79{
80 m_inHelp = FALSE;
81
82 if (beginHelp)
83 BeginContextHelp(win);
84}
85
86wxContextHelp::~wxContextHelp()
87{
88 if (m_inHelp)
89 EndContextHelp();
90}
91
92// Not currently needed, but on some systems capture may not work as
93// expected so we'll leave it here for now.
94#if 0
95static void wxPushOrPopEventHandlers(wxContextHelp* help, wxWindow* win, bool push)
96{
97 if (push)
98 win->PushEventHandler(new wxContextHelpEvtHandler(help));
99 else
100 win->PopEventHandler();
101
102 wxNode* node = win->GetChildren().First();
103 while (node)
104 {
105 wxWindow* child = (wxWindow*) node->Data();
106 wxPushOrPopEventHandlers(help, child, push);
107
108 node = node->Next();
109 }
110}
111#endif
112
113// Begin 'context help mode'
114bool wxContextHelp::BeginContextHelp(wxWindow* win)
115{
116 if (!win)
117 win = wxTheApp->GetTopWindow();
118 if (!win)
119 return FALSE;
120
121 wxCursor cursor(wxCURSOR_QUESTION_ARROW);
122 wxCursor oldCursor = win->GetCursor();
123 win->SetCursor(cursor);
124
125#ifdef __WXMSW__
126 // wxSetCursor(cursor);
127#endif
128
129 m_status = FALSE;
130
131 win->PushEventHandler(new wxContextHelpEvtHandler(this));
132 //wxPushOrPopEventHandlers(this, win, TRUE);
133
134 win->CaptureMouse();
135
136 EventLoop();
137
138 win->ReleaseMouse();
139
140 win->PopEventHandler(TRUE);
141 //wxPushOrPopEventHandlers(this, win, FALSE);
142
143 win->SetCursor(oldCursor);
144
145 if (m_status)
146 {
147 wxPoint pt;
148 wxWindow* winAtPtr = wxFindWindowAtPointer(pt);
149 /*
150 if (winAtPtr)
151 {
152 wxString msg;
153 msg.Printf("Picked %s (%d)", (const char*) winAtPtr->GetName(), winAtPtr->GetId());
154 cout << msg << '\n';
155 }
156 */
157
158 if (winAtPtr)
159 DispatchEvent(winAtPtr, pt);
160 }
161
162 return TRUE;
163}
164
165bool wxContextHelp::EndContextHelp()
166{
167 m_inHelp = FALSE;
168
169 return TRUE;
170}
171
172bool wxContextHelp::EventLoop()
173{
174 m_inHelp = TRUE;
175
176 while ( m_inHelp )
177 {
178 if (wxTheApp->Pending())
179 {
180 wxTheApp->Dispatch();
181 }
182 else
183 {
184 wxTheApp->ProcessIdle();
185 }
186 }
187
188 return TRUE;
189}
190
191bool wxContextHelpEvtHandler::ProcessEvent(wxEvent& event)
192{
193 if (event.GetEventType() == wxEVT_LEFT_DOWN)
194 {
195 m_contextHelp->SetStatus(TRUE);
196 m_contextHelp->EndContextHelp();
197 return TRUE;
198 }
199
200 if ((event.GetEventType() == wxEVT_CHAR) ||
201 (event.GetEventType() == wxEVT_KEY_DOWN) ||
202 (event.GetEventType() == wxEVT_ACTIVATE) ||
203 (event.GetEventType() == wxEVT_MOUSE_CAPTURE_CHANGED))
204 {
205 // May have already been set to TRUE by a left-click
206 //m_contextHelp->SetStatus(FALSE);
207 m_contextHelp->EndContextHelp();
208 return TRUE;
209 }
210
211 if ((event.GetEventType() == wxEVT_PAINT) ||
212 (event.GetEventType() == wxEVT_ERASE_BACKGROUND))
213 {
214 event.Skip();
215 return FALSE;
216 }
217
218 return TRUE;
219}
220
221// Dispatch the help event to the relevant window
222bool wxContextHelp::DispatchEvent(wxWindow* win, const wxPoint& pt)
223{
224 wxWindow* subjectOfHelp = win;
225 bool eventProcessed = FALSE;
226 while (subjectOfHelp && !eventProcessed)
227 {
228 wxHelpEvent helpEvent(wxEVT_HELP, subjectOfHelp->GetId(), pt) ;
229 helpEvent.SetEventObject(this);
230
231 eventProcessed = win->GetEventHandler()->ProcessEvent(helpEvent);
232
233 // Go up the window hierarchy until the event is handled (or not).
234 // I.e. keep submitting ancestor windows until one is recognised
235 // by the app code that processes the ids and displays help.
236 subjectOfHelp = subjectOfHelp->GetParent();
237 }
238 return eventProcessed;
239}
240
241// ----------------------------------------------------------------------------
242// wxContextHelpButton
243// ----------------------------------------------------------------------------
244
245/*
246 * wxContextHelpButton
247 * You can add this to your dialogs (especially on non-Windows platforms)
248 * to put the application into context help mode.
249 */
250
251#if !defined(__WXMSW__)
252static const char * csquery_xpm[] = {
253"12 11 2 1",
254" c None",
255". c #000000",
256" ",
257" .... ",
258" .. .. ",
259" .. .. ",
260" .. ",
261" .. ",
262" .. ",
263" ",
264" .. ",
265" .. ",
266" "};
267#endif
268
269IMPLEMENT_CLASS(wxContextHelpButton, wxBitmapButton)
270
271BEGIN_EVENT_TABLE(wxContextHelpButton, wxBitmapButton)
272 EVT_BUTTON(wxID_CONTEXT_HELP, wxContextHelpButton::OnContextHelp)
273END_EVENT_TABLE()
274
275wxContextHelpButton::wxContextHelpButton(wxWindow* parent,
276 wxWindowID id,
277 const wxPoint& pos,
278 const wxSize& size,
279 long style)
280#if defined(__WXPM__)
281 : wxBitmapButton(parent, id, wxBitmap(wxCSQUERY_BITMAP
282 ,wxBITMAP_TYPE_RESOURCE
283 ),
284 pos, size, style)
285#else
286 : wxBitmapButton(parent, id, wxBITMAP(csquery),
287 pos, size, style)
288#endif
289{
290}
291
292void wxContextHelpButton::OnContextHelp(wxCommandEvent& WXUNUSED(event))
293{
294 wxContextHelp contextHelp(GetParent());
295}
296
297// ----------------------------------------------------------------------------
298// wxHelpProvider
299// ----------------------------------------------------------------------------
300
301wxHelpProvider *wxHelpProvider::ms_helpProvider = (wxHelpProvider *)NULL;
302
303// trivial implementation of some methods which we don't want to make pure
304// virtual for convenience
305
306void wxHelpProvider::AddHelp(wxWindowBase * WXUNUSED(window),
307 const wxString& WXUNUSED(text))
308{
309}
310
311void wxHelpProvider::AddHelp(wxWindowID WXUNUSED(id),
312 const wxString& WXUNUSED(text))
313{
314}
315
316// removes the association
317void wxHelpProvider::RemoveHelp(wxWindowBase* WXUNUSED(window))
318{
319}
320
321wxHelpProvider::~wxHelpProvider()
322{
323}
324
325// ----------------------------------------------------------------------------
326// wxSimpleHelpProvider
327// ----------------------------------------------------------------------------
328
329wxString wxSimpleHelpProvider::GetHelp(const wxWindowBase *window)
330{
331 bool wasFound;
332 wxString text = m_hashWindows.Get((long)window, &wasFound);
333 if ( !wasFound )
334 text = m_hashIds.Get(window->GetId());
335
336 return text;
337}
338
339void wxSimpleHelpProvider::AddHelp(wxWindowBase *window, const wxString& text)
340{
341 m_hashWindows.Delete((long)window);
342 m_hashWindows.Put((long)window, text);
343}
344
345void wxSimpleHelpProvider::AddHelp(wxWindowID id, const wxString& text)
346{
347 m_hashIds.Delete((long)id);
348 m_hashIds.Put(id, text);
349}
350
351// removes the association
352void wxSimpleHelpProvider::RemoveHelp(wxWindowBase* window)
353{
354 m_hashWindows.Delete((long)window);
355}
356
357bool wxSimpleHelpProvider::ShowHelp(wxWindowBase *window)
358{
359#if wxUSE_TIPWINDOW
360 static wxTipWindow* s_tipWindow = NULL;
361
362 if (s_tipWindow)
363 {
364 // Prevent s_tipWindow being nulled in OnIdle,
365 // thereby removing the chance for the window to be closed by ShowHelp
366 s_tipWindow->SetTipWindowPtr(NULL);
367 s_tipWindow->Close();
368 }
369 s_tipWindow = NULL;
370
371 wxString text = GetHelp(window);
372 if ( !text.empty() )
373 {
374 s_tipWindow = new wxTipWindow((wxWindow *)window, text, 100, & s_tipWindow);
375
376 return TRUE;
377 }
378#endif // wxUSE_TIPWINDOW
379
380 return FALSE;
381}
382
383// ----------------------------------------------------------------------------
384// wxHelpControllerHelpProvider
385// ----------------------------------------------------------------------------
386
387wxHelpControllerHelpProvider::wxHelpControllerHelpProvider(wxHelpControllerBase* hc)
388{
389 m_helpController = hc;
390}
391
392bool wxHelpControllerHelpProvider::ShowHelp(wxWindowBase *window)
393{
394 wxString text = GetHelp(window);
395 if ( !text.empty() )
396 {
397 if (m_helpController)
398 {
399 if (text.IsNumber())
400 return m_helpController->DisplayContextPopup(wxAtoi(text));
401
402 // If the help controller is capable of popping up the text...
403 else if (m_helpController->DisplayTextPopup(text, wxGetMousePosition()))
404 {
405 return TRUE;
406 }
407 else
408 // ...else use the default method.
409 return wxSimpleHelpProvider::ShowHelp(window);
410 }
411 else
412 return wxSimpleHelpProvider::ShowHelp(window);
413
414 }
415
416 return FALSE;
417}
418
419// Convenience function for turning context id into wxString
420wxString wxContextId(int id)
421{
422 return wxString::Format(_T("%d"), id);
423}
424
425// ----------------------------------------------------------------------------
426// wxHelpProviderModule: module responsible for cleaning up help provider.
427// ----------------------------------------------------------------------------
428
429class wxHelpProviderModule : public wxModule
430{
431public:
432 bool OnInit();
433 void OnExit();
434
435private:
436 DECLARE_DYNAMIC_CLASS(wxHelpProviderModule)
437};
438
439IMPLEMENT_DYNAMIC_CLASS(wxHelpProviderModule, wxModule)
440
441bool wxHelpProviderModule::OnInit()
442{
443 // Probably we don't want to do anything by default,
444 // since it could pull in extra code
445 // wxHelpProvider::Set(new wxSimpleHelpProvider);
446
447 return TRUE;
448}
449
450void wxHelpProviderModule::OnExit()
451{
452 if (wxHelpProvider::Get())
453 {
454 delete wxHelpProvider::Get();
455 wxHelpProvider::Set(NULL);
456 }
457}
458
459#endif // wxUSE_HELP