/[pcsx2_0.9.7]/trunk/3rdparty/wxWidgets/src/common/cshelp.cpp
ViewVC logotype

Annotation of /trunk/3rdparty/wxWidgets/src/common/cshelp.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 10 - (hide annotations) (download)
Mon Sep 6 11:40:06 2010 UTC (9 years, 11 months ago) by william
File size: 14075 byte(s)
exported r3113 from ./upstream/trunk
1 william 10 /////////////////////////////////////////////////////////////////////////////
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: cshelp.cpp 52329 2008-03-05 13:20:26Z VZ $
8     // Copyright: (c) 2000 Julian Smart, Vadim Zeitlin
9     // Licence: wxWindows licence
10     /////////////////////////////////////////////////////////////////////////////
11    
12     // ============================================================================
13     // declarations
14     // ============================================================================
15    
16     // ----------------------------------------------------------------------------
17     // headers
18     // ----------------------------------------------------------------------------
19    
20     // For compilers that support precompilation, includes "wx.h".
21     #include "wx/wxprec.h"
22    
23     #ifdef __BORLANDC__
24     #pragma hdrstop
25     #endif
26    
27     #if wxUSE_HELP
28    
29     #ifndef WX_PRECOMP
30     #include "wx/app.h"
31     #include "wx/module.h"
32     #endif
33    
34     #include "wx/tipwin.h"
35     #include "wx/cshelp.h"
36    
37     #if wxUSE_MS_HTML_HELP
38     #include "wx/msw/helpchm.h" // for ShowContextHelpPopup
39     #include "wx/utils.h" // for wxGetMousePosition()
40     #endif
41    
42     // ----------------------------------------------------------------------------
43     // wxContextHelpEvtHandler private class
44     // ----------------------------------------------------------------------------
45    
46     // This class exists in order to eat events until the left mouse button is
47     // pressed
48     class wxContextHelpEvtHandler: public wxEvtHandler
49     {
50     public:
51     wxContextHelpEvtHandler(wxContextHelp* contextHelp)
52     {
53     m_contextHelp = contextHelp;
54     }
55    
56     virtual bool ProcessEvent(wxEvent& event);
57    
58     //// Data
59     wxContextHelp* m_contextHelp;
60    
61     DECLARE_NO_COPY_CLASS(wxContextHelpEvtHandler)
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     // Not currently needed, but on some systems capture may not work as
94     // expected so we'll leave it here for now.
95     #ifdef __WXMOTIF__
96     static void wxPushOrPopEventHandlers(wxContextHelp* help, wxWindow* win, bool push)
97     {
98     if (push)
99     win->PushEventHandler(new wxContextHelpEvtHandler(help));
100     else
101     win->PopEventHandler(true);
102    
103     wxWindowList::compatibility_iterator node = win->GetChildren().GetFirst();
104     while (node)
105     {
106     wxWindow* child = node->GetData();
107     wxPushOrPopEventHandlers(help, child, push);
108    
109     node = node->GetNext();
110     }
111     }
112     #endif
113    
114     // Begin 'context help mode'
115     bool wxContextHelp::BeginContextHelp(wxWindow* win)
116     {
117     if (!win)
118     win = wxTheApp->GetTopWindow();
119     if (!win)
120     return false;
121    
122     wxCursor cursor(wxCURSOR_QUESTION_ARROW);
123     wxCursor oldCursor = win->GetCursor();
124     win->SetCursor(cursor);
125    
126     #ifdef __WXMAC__
127     wxSetCursor(cursor);
128     #endif
129    
130     m_status = false;
131    
132     #ifdef __WXMOTIF__
133     wxPushOrPopEventHandlers(this, win, true);
134     #else
135     win->PushEventHandler(new wxContextHelpEvtHandler(this));
136     #endif
137    
138     win->CaptureMouse();
139    
140     EventLoop();
141    
142     win->ReleaseMouse();
143    
144     #ifdef __WXMOTIF__
145     wxPushOrPopEventHandlers(this, win, false);
146     #else
147     win->PopEventHandler(true);
148     #endif
149    
150     win->SetCursor(oldCursor);
151    
152     #ifdef __WXMAC__
153     wxSetCursor(wxNullCursor);
154     #endif
155    
156     if (m_status)
157     {
158     wxPoint pt;
159     wxWindow* winAtPtr = wxFindWindowAtPointer(pt);
160    
161     #if 0
162     if (winAtPtr)
163     {
164     printf("Picked %s (%d)\n", winAtPtr->GetName().c_str(),
165     winAtPtr->GetId());
166     }
167     #endif
168    
169     if (winAtPtr)
170     DispatchEvent(winAtPtr, pt);
171     }
172    
173     return true;
174     }
175    
176     bool wxContextHelp::EndContextHelp()
177     {
178     m_inHelp = false;
179    
180     return true;
181     }
182    
183     bool wxContextHelp::EventLoop()
184     {
185     m_inHelp = true;
186    
187     while ( m_inHelp )
188     {
189     if (wxTheApp->Pending())
190     {
191     wxTheApp->Dispatch();
192     }
193     else
194     {
195     wxTheApp->ProcessIdle();
196     }
197     }
198    
199     return true;
200     }
201    
202     bool wxContextHelpEvtHandler::ProcessEvent(wxEvent& event)
203     {
204     if (event.GetEventType() == wxEVT_LEFT_DOWN)
205     {
206     m_contextHelp->SetStatus(true);
207     m_contextHelp->EndContextHelp();
208     return true;
209     }
210    
211     if ((event.GetEventType() == wxEVT_CHAR) ||
212     (event.GetEventType() == wxEVT_KEY_DOWN) ||
213     (event.GetEventType() == wxEVT_ACTIVATE) ||
214     (event.GetEventType() == wxEVT_MOUSE_CAPTURE_CHANGED))
215     {
216     // May have already been set to true by a left-click
217     //m_contextHelp->SetStatus(false);
218     m_contextHelp->EndContextHelp();
219     return true;
220     }
221    
222     if ((event.GetEventType() == wxEVT_PAINT) ||
223     (event.GetEventType() == wxEVT_ERASE_BACKGROUND))
224     {
225     event.Skip();
226     return false;
227     }
228    
229     return true;
230     }
231    
232     // Dispatch the help event to the relevant window
233     bool wxContextHelp::DispatchEvent(wxWindow* win, const wxPoint& pt)
234     {
235     wxCHECK_MSG( win, false, _T("win parameter can't be NULL") );
236    
237     wxHelpEvent helpEvent(wxEVT_HELP, win->GetId(), pt,
238     wxHelpEvent::Origin_HelpButton);
239     helpEvent.SetEventObject(win);
240    
241     return win->GetEventHandler()->ProcessEvent(helpEvent);
242     }
243    
244     // ----------------------------------------------------------------------------
245     // wxContextHelpButton
246     // ----------------------------------------------------------------------------
247    
248     /*
249     * wxContextHelpButton
250     * You can add this to your dialogs (especially on non-Windows platforms)
251     * to put the application into context help mode.
252     */
253    
254     #ifndef __WXPM__
255    
256     static const char * csquery_xpm[] = {
257     "12 11 2 1",
258     " c None",
259     ". c #000000",
260     " ",
261     " .... ",
262     " .. .. ",
263     " .. .. ",
264     " .. ",
265     " .. ",
266     " .. ",
267     " ",
268     " .. ",
269     " .. ",
270     " "};
271    
272     #endif
273    
274     IMPLEMENT_CLASS(wxContextHelpButton, wxBitmapButton)
275    
276     BEGIN_EVENT_TABLE(wxContextHelpButton, wxBitmapButton)
277     EVT_BUTTON(wxID_CONTEXT_HELP, wxContextHelpButton::OnContextHelp)
278     END_EVENT_TABLE()
279    
280     wxContextHelpButton::wxContextHelpButton(wxWindow* parent,
281     wxWindowID id,
282     const wxPoint& pos,
283     const wxSize& size,
284     long style)
285     #if defined(__WXPM__)
286     : wxBitmapButton(parent, id, wxBitmap(wxCSQUERY_BITMAP
287     ,wxBITMAP_TYPE_RESOURCE
288     ),
289     pos, size, style)
290     #else
291     : wxBitmapButton(parent, id, wxBitmap(csquery_xpm),
292     pos, size, style)
293     #endif
294     {
295     }
296    
297     void wxContextHelpButton::OnContextHelp(wxCommandEvent& WXUNUSED(event))
298     {
299     wxContextHelp contextHelp(GetParent());
300     }
301    
302     // ----------------------------------------------------------------------------
303     // wxHelpProvider
304     // ----------------------------------------------------------------------------
305    
306     wxHelpProvider *wxHelpProvider::ms_helpProvider = (wxHelpProvider *)NULL;
307    
308     // trivial implementation of some methods which we don't want to make pure
309     // virtual for convenience
310    
311     void wxHelpProvider::AddHelp(wxWindowBase * WXUNUSED(window),
312     const wxString& WXUNUSED(text))
313     {
314     }
315    
316     void wxHelpProvider::AddHelp(wxWindowID WXUNUSED(id),
317     const wxString& WXUNUSED(text))
318     {
319     }
320    
321     // removes the association
322     void wxHelpProvider::RemoveHelp(wxWindowBase* WXUNUSED(window))
323     {
324     }
325    
326     wxHelpProvider::~wxHelpProvider()
327     {
328     }
329    
330     wxString wxHelpProvider::GetHelpTextMaybeAtPoint(wxWindowBase *window)
331     {
332     if ( m_helptextAtPoint != wxDefaultPosition ||
333     m_helptextOrigin != wxHelpEvent::Origin_Unknown )
334     {
335     wxCHECK_MSG( window, wxEmptyString, _T("window must not be NULL") );
336    
337     wxPoint pt = m_helptextAtPoint;
338     wxHelpEvent::Origin origin = m_helptextOrigin;
339    
340     m_helptextAtPoint = wxDefaultPosition;
341     m_helptextOrigin = wxHelpEvent::Origin_Unknown;
342    
343     return window->GetHelpTextAtPoint(pt, origin);
344     }
345    
346     return GetHelp(window);
347     }
348    
349     // ----------------------------------------------------------------------------
350     // wxSimpleHelpProvider
351     // ----------------------------------------------------------------------------
352    
353     #define WINHASH_KEY(w) wxPtrToUInt(w)
354    
355     wxString wxSimpleHelpProvider::GetHelp(const wxWindowBase *window)
356     {
357     wxSimpleHelpProviderHashMap::iterator it = m_hashWindows.find(WINHASH_KEY(window));
358    
359     if ( it == m_hashWindows.end() )
360     {
361     it = m_hashIds.find(window->GetId());
362     if ( it == m_hashIds.end() )
363     return wxEmptyString;
364     }
365    
366     return it->second;
367     }
368    
369     void wxSimpleHelpProvider::AddHelp(wxWindowBase *window, const wxString& text)
370     {
371     m_hashWindows.erase(WINHASH_KEY(window));
372     m_hashWindows[WINHASH_KEY(window)] = text;
373     }
374    
375     void wxSimpleHelpProvider::AddHelp(wxWindowID id, const wxString& text)
376     {
377     wxSimpleHelpProviderHashMap::key_type key = (wxSimpleHelpProviderHashMap::key_type)id;
378     m_hashIds.erase(key);
379     m_hashIds[key] = text;
380     }
381    
382     // removes the association
383     void wxSimpleHelpProvider::RemoveHelp(wxWindowBase* window)
384     {
385     m_hashWindows.erase(WINHASH_KEY(window));
386     }
387    
388     bool wxSimpleHelpProvider::ShowHelp(wxWindowBase *window)
389     {
390     #if wxUSE_MS_HTML_HELP || wxUSE_TIPWINDOW
391     #if wxUSE_MS_HTML_HELP
392     // m_helptextAtPoint will be reset by GetHelpTextMaybeAtPoint(), stash it
393     const wxPoint posTooltip = m_helptextAtPoint;
394     #endif // wxUSE_MS_HTML_HELP
395    
396     const wxString text = GetHelpTextMaybeAtPoint(window);
397    
398     if ( !text.empty() )
399     {
400     // use the native help popup style if it's available
401     #if wxUSE_MS_HTML_HELP
402     if ( !wxCHMHelpController::ShowContextHelpPopup
403     (
404     text,
405     posTooltip,
406     (wxWindow *)window
407     ) )
408     #endif // wxUSE_MS_HTML_HELP
409     {
410     #if wxUSE_TIPWINDOW
411     static wxTipWindow* s_tipWindow = NULL;
412    
413     if ( s_tipWindow )
414     {
415     // Prevent s_tipWindow being nulled in OnIdle, thereby removing
416     // the chance for the window to be closed by ShowHelp
417     s_tipWindow->SetTipWindowPtr(NULL);
418     s_tipWindow->Close();
419     }
420    
421     s_tipWindow = new wxTipWindow((wxWindow *)window, text,
422     100, &s_tipWindow);
423     #else // !wxUSE_TIPWINDOW
424     // we tried wxCHMHelpController but it failed and we don't have
425     // wxTipWindow to fall back on, so
426     return false;
427     #endif // wxUSE_TIPWINDOW
428     }
429    
430     return true;
431     }
432     #else // !wxUSE_MS_HTML_HELP && !wxUSE_TIPWINDOW
433     wxUnusedVar(window);
434     #endif // wxUSE_MS_HTML_HELP || wxUSE_TIPWINDOW
435    
436     return false;
437     }
438    
439     // ----------------------------------------------------------------------------
440     // wxHelpControllerHelpProvider
441     // ----------------------------------------------------------------------------
442    
443     wxHelpControllerHelpProvider::wxHelpControllerHelpProvider(wxHelpControllerBase* hc)
444     {
445     m_helpController = hc;
446     }
447    
448     bool wxHelpControllerHelpProvider::ShowHelp(wxWindowBase *window)
449     {
450     const wxString text = GetHelpTextMaybeAtPoint(window);
451    
452     if ( text.empty() )
453     return false;
454    
455     if ( m_helpController )
456     {
457     // if it's a numeric topic, show it
458     long topic;
459     if ( text.ToLong(&topic) )
460     return m_helpController->DisplayContextPopup(topic);
461    
462     // otherwise show the text directly
463     if ( m_helpController->DisplayTextPopup(text, wxGetMousePosition()) )
464     return true;
465     }
466    
467     // if there is no help controller or it's not capable of showing the help,
468     // fallback to the default method
469     return wxSimpleHelpProvider::ShowHelp(window);
470     }
471    
472     // Convenience function for turning context id into wxString
473     wxString wxContextId(int id)
474     {
475     return wxString::Format(_T("%d"), id);
476     }
477    
478     // ----------------------------------------------------------------------------
479     // wxHelpProviderModule: module responsible for cleaning up help provider.
480     // ----------------------------------------------------------------------------
481    
482     class wxHelpProviderModule : public wxModule
483     {
484     public:
485     bool OnInit();
486     void OnExit();
487    
488     private:
489     DECLARE_DYNAMIC_CLASS(wxHelpProviderModule)
490     };
491    
492     IMPLEMENT_DYNAMIC_CLASS(wxHelpProviderModule, wxModule)
493    
494     bool wxHelpProviderModule::OnInit()
495     {
496     // Probably we don't want to do anything by default,
497     // since it could pull in extra code
498     // wxHelpProvider::Set(new wxSimpleHelpProvider);
499    
500     return true;
501     }
502    
503     void wxHelpProviderModule::OnExit()
504     {
505     if (wxHelpProvider::Get())
506     {
507     delete wxHelpProvider::Get();
508     wxHelpProvider::Set(NULL);
509     }
510     }
511    
512     #endif // wxUSE_HELP

  ViewVC Help
Powered by ViewVC 1.1.22