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