1. added wxHelpProvider and (unfinished) wxSimpleHelpProvider
[wxWidgets.git] / src / common / cshelp.cpp
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 // FIXME: temporary needed for wxSimpleHelpProvider compilation, to be
35 // removed later
36 #include "wx/intl.h"
37 #include "wx/msgdlg.h"
38 #endif
39
40 #include "wx/app.h"
41
42 #include "wx/cshelp.h"
43
44 // ----------------------------------------------------------------------------
45 // wxContextHelpEvtHandler private class
46 // ----------------------------------------------------------------------------
47
48 // This class exists in order to eat events until the left mouse button is
49 // pressed
50 class wxContextHelpEvtHandler: public wxEvtHandler
51 {
52 public:
53 wxContextHelpEvtHandler(wxContextHelp* contextHelp)
54 {
55 m_contextHelp = contextHelp;
56 }
57
58 virtual bool ProcessEvent(wxEvent& event);
59
60 //// Data
61 wxContextHelp* m_contextHelp;
62 };
63
64 // ============================================================================
65 // implementation
66 // ============================================================================
67
68 // ----------------------------------------------------------------------------
69 // wxContextHelp
70 // ----------------------------------------------------------------------------
71
72 /*
73 * Invokes context-sensitive help
74 */
75
76
77 IMPLEMENT_DYNAMIC_CLASS(wxContextHelp, wxObject)
78
79 wxContextHelp::wxContextHelp(wxWindow* win, bool beginHelp)
80 {
81 m_inHelp = FALSE;
82
83 if (beginHelp)
84 BeginContextHelp(win);
85 }
86
87 wxContextHelp::~wxContextHelp()
88 {
89 if (m_inHelp)
90 EndContextHelp();
91 }
92
93 // Begin 'context help mode'
94 bool wxContextHelp::BeginContextHelp(wxWindow* win)
95 {
96 if (!win)
97 win = wxTheApp->GetTopWindow();
98 if (!win)
99 return FALSE;
100
101 wxCursor cursor(wxCURSOR_QUESTION_ARROW);
102 wxCursor oldCursor = win->GetCursor();
103 win->SetCursor(cursor);
104
105 #ifdef __WXMSW__
106 // wxSetCursor(cursor);
107 #endif
108
109 win->PushEventHandler(new wxContextHelpEvtHandler(this));
110
111 win->CaptureMouse();
112
113 EventLoop();
114
115 win->ReleaseMouse();
116
117 win->PopEventHandler(TRUE);
118
119 win->SetCursor(oldCursor);
120
121 if (m_status)
122 {
123 wxPoint pt;
124 wxWindow* winAtPtr = wxFindWindowAtPointer(pt);
125 if (winAtPtr)
126 DispatchEvent(winAtPtr, pt);
127 }
128
129 return TRUE;
130 }
131
132 bool wxContextHelp::EndContextHelp()
133 {
134 m_inHelp = FALSE;
135
136 return TRUE;
137 }
138
139 bool wxContextHelp::EventLoop()
140 {
141 m_inHelp = TRUE;
142 while ( m_inHelp )
143 {
144 if (wxTheApp->Pending())
145 {
146 wxTheApp->Dispatch();
147 }
148 else
149 {
150 wxTheApp->ProcessIdle();
151 }
152 }
153 return TRUE;
154 }
155
156 bool wxContextHelpEvtHandler::ProcessEvent(wxEvent& event)
157 {
158 switch (event.GetEventType())
159 {
160 case wxEVT_LEFT_DOWN:
161 {
162 //wxMouseEvent& mouseEvent = (wxMouseEvent&) event;
163 m_contextHelp->SetStatus(TRUE);
164 m_contextHelp->EndContextHelp();
165 return TRUE;
166 break;
167 }
168 case wxEVT_CHAR:
169 case wxEVT_KEY_DOWN:
170 case wxEVT_ACTIVATE:
171 case wxEVT_MOUSE_CAPTURE_CHANGED:
172 {
173 m_contextHelp->SetStatus(FALSE);
174 m_contextHelp->EndContextHelp();
175 return TRUE;
176 break;
177 }
178 case wxEVT_PAINT:
179 case wxEVT_ERASE_BACKGROUND:
180 {
181 event.Skip();
182 return FALSE;
183 break;
184 }
185 }
186
187 return TRUE;
188 }
189
190 // Dispatch the help event to the relevant window
191 bool wxContextHelp::DispatchEvent(wxWindow* win, const wxPoint& pt)
192 {
193 wxWindow* subjectOfHelp = win;
194 bool eventProcessed = FALSE;
195 while (subjectOfHelp && !eventProcessed)
196 {
197 wxHelpEvent helpEvent(wxEVT_HELP, subjectOfHelp->GetId(), pt) ;
198 helpEvent.SetEventObject(this);
199 eventProcessed = win->GetEventHandler()->ProcessEvent(helpEvent);
200
201 // Go up the window hierarchy until the event is handled (or not).
202 // I.e. keep submitting ancestor windows until one is recognised
203 // by the app code that processes the ids and displays help.
204 subjectOfHelp = subjectOfHelp->GetParent();
205 }
206 return eventProcessed;
207 }
208
209 // ----------------------------------------------------------------------------
210 // wxContextHelpButton
211 // ----------------------------------------------------------------------------
212
213 /*
214 * wxContextHelpButton
215 * You can add this to your dialogs (especially on non-Windows platforms)
216 * to put the application into context help mode.
217 */
218
219 #if !defined(__WXMSW__)
220 static char * csquery_xpm[] = {
221 "12 11 2 1",
222 " c None",
223 ". c #000000",
224 " ",
225 " .... ",
226 " .. .. ",
227 " .. .. ",
228 " .. ",
229 " .. ",
230 " .. ",
231 " ",
232 " .. ",
233 " .. ",
234 " "};
235 #endif
236
237 IMPLEMENT_CLASS(wxContextHelpButton, wxBitmapButton)
238
239 BEGIN_EVENT_TABLE(wxContextHelpButton, wxBitmapButton)
240 EVT_BUTTON(wxID_CONTEXT_HELP, wxContextHelpButton::OnContextHelp)
241 END_EVENT_TABLE()
242
243 wxContextHelpButton::wxContextHelpButton(wxWindow* parent,
244 wxWindowID id,
245 const wxPoint& pos,
246 const wxSize& size,
247 long style)
248 : wxBitmapButton(parent, id, wxBITMAP(csquery),
249 pos, size, style)
250 {
251 }
252
253 void wxContextHelpButton::OnContextHelp(wxCommandEvent& event)
254 {
255 wxContextHelp contextHelp(GetParent());
256 }
257
258 // ----------------------------------------------------------------------------
259 // wxHelpProvider
260 // ----------------------------------------------------------------------------
261
262 wxHelpProvider *wxHelpProvider::ms_helpProvider = (wxHelpProvider *)NULL;
263
264 // trivial implementation of some methods which we don't want to make pure
265 // virtual for convenience
266
267 void wxHelpProvider::AddHelp(wxWindowBase * WXUNUSED(window),
268 const wxString& WXUNUSED(text))
269 {
270 }
271
272 void wxHelpProvider::AddHelp(wxWindowID WXUNUSED(id),
273 const wxString& WXUNUSED(text))
274 {
275 }
276
277 wxHelpProvider::~wxHelpProvider()
278 {
279 }
280
281 // ----------------------------------------------------------------------------
282 // wxSimpleHelpProvider
283 // ----------------------------------------------------------------------------
284
285 wxString wxSimpleHelpProvider::GetHelp(const wxWindowBase *window)
286 {
287 bool wasFound;
288 wxString text = m_hashWindows.Get((long)window, &wasFound);
289 if ( !wasFound )
290 text = m_hashIds.Get(window->GetId());
291
292 return text;
293 }
294
295 void wxSimpleHelpProvider::AddHelp(wxWindowBase *window, const wxString& text)
296 {
297 m_hashWindows.Put((long)window, text);
298 }
299
300 void wxSimpleHelpProvider::AddHelp(wxWindowID id, const wxString& text)
301 {
302 m_hashIds.Put(id, text);
303 }
304
305 bool wxSimpleHelpProvider::ShowHelp(wxWindowBase *window)
306 {
307 wxString text = GetHelp(window);
308 if ( !text.empty() )
309 {
310 wxMessageBox(text, _("Help"), wxICON_INFORMATION | wxOK,
311 (wxWindow *)window);
312
313 return TRUE;
314 }
315
316 return FALSE;
317 }
318
319 #endif // wxUSE_HELP