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