home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / wxos2240.zip / wxWindows-2.4.0 / src / common / cshelp.cpp < prev    next >
C/C++ Source or Header  |  2002-08-09  |  12KB  |  458 lines

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