remhelp.cpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416
  1. /////////////////////////////////////////////////////////////////////////////
  2. // Name: remhelp.cpp
  3. // Purpose: Remote help controller class
  4. // Author: Eric Dowty
  5. // Modified by:
  6. // Created: 2002-11-18
  7. // Copyright: (c) Julian Smart
  8. // Licence: wxWindows licence
  9. /////////////////////////////////////////////////////////////////////////////
  10. // For compilers that support precompilation, includes "wx.h".
  11. #include "wx/wxprec.h"
  12. #ifdef __BORLANDC__
  13. #pragma hdrstop
  14. #endif
  15. #ifndef WX_PRECOMP
  16. #include "wx/wx.h"
  17. #endif
  18. #include <math.h>
  19. #include "wx/process.h"
  20. #include "wx/confbase.h"
  21. // Settings common to both executables: determines whether
  22. // we're using TCP/IP or real DDE.
  23. //#include "ddesetup.h"
  24. //#define wxUSE_DDE_FOR_IPC 0
  25. #ifndef wxHAS_IMAGES_IN_RESOURCES
  26. #include "mondrian.xpm"
  27. #endif
  28. #include "remhelp.h"
  29. #include "client.h"
  30. #if !defined(USE_REMOTE)
  31. #include <wx/html/helpctrl.h>
  32. #endif
  33. //////////////////
  34. //////////////////
  35. // helper classes
  36. rhhcClient::rhhcClient( bool *isconn_a )
  37. {
  38. isconn_2 = isconn_a;
  39. }
  40. wxConnectionBase *rhhcClient::OnMakeConnection()
  41. {
  42. return new rhhcConnection( isconn_2 );
  43. }
  44. rhhcConnection::rhhcConnection( bool *isconn_a )
  45. : wxConnection()
  46. {
  47. isconn_3 = isconn_a;
  48. *isconn_3 = true;
  49. }
  50. rhhcConnection::~rhhcConnection()
  51. {
  52. *isconn_3 = false;
  53. }
  54. bool rhhcConnection::OnAdvise(const wxString& topic, const wxString& item, char *data, int size, wxIPCFormat format)
  55. {
  56. return true;
  57. }
  58. bool rhhcConnection::OnDisconnect()
  59. {
  60. *isconn_3 = false;
  61. return wxConnection::OnDisconnect();
  62. }
  63. //////////////////////////////////////////
  64. /////////////////////////////////////////
  65. // wxRemoteHtmlHelpController class
  66. IMPLEMENT_CLASS(wxRemoteHtmlHelpController, wxHelpControllerBase)
  67. wxRemoteHtmlHelpController::wxRemoteHtmlHelpController(int style )
  68. {
  69. m_style = style;
  70. m_connection = NULL;
  71. m_client = NULL;
  72. m_pid = 0;
  73. isconn_1 = false;
  74. m_process = NULL;
  75. // defaults
  76. //
  77. // server app is assumed to be local
  78. //
  79. // for MSW (DDE classes), a_service is 'service name', apparently an arbitrary string
  80. // for Unix, should be a valid file name (for a nonexistent file)
  81. // for nonMSW, nonUnix, must be port number, for example "4242" (TCP/IP based classes)
  82. // should be unique to the client app
  83. wxString thename = wxGetApp().GetAppName();
  84. #if defined(__WXMSW__)
  85. m_appname = wxT("helpview.exe");
  86. m_service = thename + wxString(wxT("_helpservice"));
  87. #elif defined(__UNIX__)
  88. m_appname = wxT("./helpview");
  89. m_service = wxT("/tmp/") + thename + wxString(wxT("_helpservice"));
  90. #else
  91. m_appname = wxT("./helpview");
  92. m_service = wxT("4242");
  93. #endif
  94. m_book = thename + wxT(".hhp"); // or .htb or .zip
  95. m_windowname = thename + wxT(" Help: %s");
  96. //underscores for spaces
  97. m_windowname.Replace( wxT(" "), wxT("_") );
  98. }
  99. void wxRemoteHtmlHelpController::SetService(wxString& a_service)
  100. {
  101. m_service = a_service;
  102. }
  103. void wxRemoteHtmlHelpController::SetServer(wxString& a_appname)
  104. {
  105. m_appname = a_appname;
  106. }
  107. void wxRemoteHtmlHelpController::OnQuit()
  108. {
  109. //kill the Server here?
  110. //this function is not called ?
  111. }
  112. wxRemoteHtmlHelpController::~wxRemoteHtmlHelpController()
  113. {
  114. if ( isconn_1 )
  115. {
  116. // if (!m_connection->Poke( wxT("--YouAreDead"), wxT("") ) )
  117. // wxLogError(wxT("wxRemoteHtmlHelpController - YouAreDead Failed"));
  118. // Kill the server. This could be an option.
  119. Quit();
  120. m_connection->Disconnect();
  121. delete m_connection;
  122. delete m_process;
  123. m_process = NULL;
  124. }
  125. if( m_client )
  126. delete m_client; //should be automatic?
  127. }
  128. bool wxRemoteHtmlHelpController::DoConnection()
  129. {
  130. wxString cmd, blank;
  131. int nsleep;
  132. blank = wxT(" ");
  133. // ignored under DDE, host name in TCP/IP based classes
  134. wxString hostName = wxT("localhost");
  135. // Create a new client
  136. if( !m_client ) m_client = new rhhcClient(&isconn_1);
  137. nsleep = 0;
  138. // suppress the log messages from MakeConnection()
  139. {
  140. wxLogNull nolog;
  141. //first try to connect assuming server is running
  142. if( !isconn_1 )
  143. m_connection = (rhhcConnection *)m_client->MakeConnection(hostName, m_service, wxT("HELP") );
  144. //if not, start server
  145. if( !isconn_1 ) {
  146. wxString stylestr;
  147. stylestr.Printf( wxT("--Style%d"), m_style );
  148. cmd = m_appname + blank + m_service + blank + m_windowname + blank + m_book + blank + stylestr;
  149. m_process = new wxProcess(NULL);
  150. m_pid = wxExecute( cmd, false, m_process );
  151. // leaks - wxExecute itself (if not deleted) and in wxExecute at
  152. // wxExecuteData *data = new wxExecuteData;
  153. if( m_pid <= 0 ) {
  154. wxLogError( wxT("wxRemoteHtmlHelpController - Failed to start Help server") );
  155. return false;
  156. }
  157. }
  158. while ( !isconn_1 )
  159. {
  160. //try every second for a while, then leave it to user
  161. wxSleep(1);
  162. if( nsleep > 4 ) {
  163. if ( wxMessageBox( wxT("Failed to make connection to Help server.\nRetry?") ,
  164. wxT("wxRemoteHtmlHelpController Error"),
  165. wxICON_ERROR | wxYES_NO | wxCANCEL ) != wxYES )
  166. {
  167. // no server
  168. return false;
  169. }
  170. }
  171. nsleep++;
  172. m_connection = (rhhcConnection *)m_client->MakeConnection(hostName, m_service, wxT("HELP") );
  173. }
  174. }
  175. if (!m_connection->StartAdvise(wxT("Item"))) {
  176. wxLogError(wxT("wxRemoteHtmlHelpController - StartAdvise failed") );
  177. return false;
  178. }
  179. return true;
  180. }
  181. bool wxRemoteHtmlHelpController::LoadFile(const wxString& WXUNUSED(file))
  182. {
  183. return true;
  184. }
  185. bool wxRemoteHtmlHelpController::DisplaySection(int sectionNo)
  186. {
  187. Display(sectionNo);
  188. return true;
  189. }
  190. bool wxRemoteHtmlHelpController::DisplayBlock(long blockNo)
  191. {
  192. return DisplaySection((int)blockNo);
  193. }
  194. bool wxRemoteHtmlHelpController::Quit()
  195. {
  196. //this code from exec sample - branches left in for testing
  197. // sig = 3, 6, 9 or 12 all kill server with no apparent problem
  198. // but give error message on MSW - timout?
  199. int sig = 15; //3 = quit; 6 = abort; 9 = kill; 15 = terminate
  200. /*
  201. switch ( sig )
  202. {
  203. default:
  204. wxFAIL_MSG( wxT("unexpected return value") );
  205. // fall through
  206. case -1:
  207. // cancelled
  208. return false;
  209. case wxSIGNONE:
  210. case wxSIGHUP:
  211. case wxSIGINT:
  212. case wxSIGQUIT:
  213. case wxSIGILL:
  214. case wxSIGTRAP:
  215. case wxSIGABRT:
  216. case wxSIGEMT:
  217. case wxSIGFPE:
  218. case wxSIGKILL:
  219. case wxSIGBUS:
  220. case wxSIGSEGV:
  221. case wxSIGSYS:
  222. case wxSIGPIPE:
  223. case wxSIGALRM:
  224. case wxSIGTERM:
  225. break;
  226. }
  227. */
  228. if ( sig == 0 )
  229. {
  230. if ( wxProcess::Exists(m_pid) )
  231. {
  232. wxLogStatus(wxT("Process %ld is running."), m_pid);
  233. }
  234. else
  235. {
  236. wxLogStatus(wxT("No process with pid = %ld."), m_pid);
  237. }
  238. }
  239. else // not SIGNONE
  240. {
  241. wxKillError rc = wxProcess::Kill(m_pid, (wxSignal)sig);
  242. if ( rc == wxKILL_OK )
  243. {
  244. wxLogStatus(wxT("Process %ld killed with signal %d."), m_pid, sig);
  245. }
  246. else
  247. {
  248. static const wxChar *errorText[] =
  249. {
  250. wxT(""), // no error
  251. wxT("signal not supported"),
  252. wxT("permission denied"),
  253. wxT("no such process"),
  254. wxT("unspecified error"),
  255. };
  256. // sig = 3, 6, 9 or 12 all kill server with no apparent problem
  257. // but give error message on MSW - timout?
  258. //
  259. //wxLogError(wxT("Failed to kill process %ld with signal %d: %s"),
  260. // m_pid, sig, errorText[rc]);
  261. }
  262. }
  263. return true;
  264. }
  265. void wxRemoteHtmlHelpController::Display(const wxString& helpfile)
  266. {
  267. if( !isconn_1 ) {
  268. if( !DoConnection() ) return;
  269. }
  270. if (!m_connection->Execute( helpfile, -1 ) )
  271. wxLogError(wxT("wxRemoteHtmlHelpController - Display Failed"));
  272. }
  273. void wxRemoteHtmlHelpController::Display(const int id)
  274. {
  275. if( !isconn_1 ) {
  276. if( !DoConnection() ) return;
  277. }
  278. wxString intstring;
  279. intstring.Printf( "--intstring%d", id );
  280. if (!m_connection->Execute( intstring, -1 ) )
  281. wxLogError(wxT("wxRemoteHtmlHelpController - Display Failed"));
  282. }
  283. bool wxRemoteHtmlHelpController::AddBook(const wxString& book, bool show_wait_msg)
  284. {
  285. //ignore show_wait_msg - there shouldn't be a delay in this step
  286. //show_wait_msg = true could be transmitted with ++AddBook
  287. m_book = book;
  288. if( isconn_1 ) {
  289. if (!m_connection->Poke( wxT("--AddBook"), (char*)book.c_str() ) )
  290. {
  291. wxLogError(wxT("wxRemoteHtmlHelpController - AddBook Failed"));
  292. }
  293. return false;
  294. }
  295. return true;
  296. }
  297. bool wxRemoteHtmlHelpController::DisplayContents()
  298. {
  299. if( isconn_1 ) {
  300. if (!m_connection->Poke( wxT("--DisplayContents"), wxT("") ) ) {
  301. wxLogError(wxT("wxRemoteHtmlHelpController - DisplayContents Failed"));
  302. return false;
  303. }
  304. }
  305. return true;
  306. }
  307. void wxRemoteHtmlHelpController::DisplayIndex()
  308. {
  309. if( isconn_1 ) {
  310. if (!m_connection->Poke( wxT("--DisplayIndex"), wxT("") ) )
  311. {
  312. wxLogError(wxT("wxRemoteHtmlHelpController - DisplayIndex Failed"));
  313. }
  314. }
  315. }
  316. bool wxRemoteHtmlHelpController::KeywordSearch(const wxString& keyword)
  317. {
  318. if( isconn_1 ) {
  319. if (!m_connection->Poke( wxT("--KeywordSearch"), (char*)keyword.c_str() ) ) {
  320. wxLogError(wxT("wxRemoteHtmlHelpController - KeywordSearch Failed"));
  321. return false;
  322. }
  323. }
  324. return true;
  325. }
  326. void wxRemoteHtmlHelpController::SetTitleFormat(const wxString& format)
  327. {
  328. m_windowname = format;
  329. m_windowname.Replace( wxT(" "), wxT("_") );
  330. if( isconn_1 ) {
  331. if (!m_connection->Poke( wxT("--SetTitleFormat"), (char*)format.c_str() ) )
  332. {
  333. wxLogError(wxT("wxRemoteHtmlHelpController - SetTitleFormat Failed"));
  334. }
  335. }
  336. }
  337. void wxRemoteHtmlHelpController::SetTempDir(const wxString& path)
  338. {
  339. if( isconn_1 ) {
  340. if (!m_connection->Poke( wxT("--SetTempDir"), (char*)path.c_str() ) )
  341. {
  342. wxLogError(wxT("wxRemoteHtmlHelpController - SetTempDir Failed"));
  343. }
  344. }
  345. }