]> git.saurik.com Git - wxWidgets.git/blame_incremental - src/html/helpctrl.cpp
wxMessageBox off the main thread lost result code.
[wxWidgets.git] / src / html / helpctrl.cpp
... / ...
CommitLineData
1/////////////////////////////////////////////////////////////////////////////
2// Name: src/html/helpctrl.cpp
3// Purpose: wxHtmlHelpController
4// Notes: Based on htmlhelp.cpp, implementing a monolithic
5// HTML Help controller class, by Vaclav Slavik
6// Author: Harm van der Heijden and Vaclav Slavik
7// Copyright: (c) Harm van der Heijden and Vaclav Slavik
8// Licence: wxWindows licence
9/////////////////////////////////////////////////////////////////////////////
10
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#if wxUSE_WXHTML_HELP
19
20#ifndef WX_PRECOMP
21 #include "wx/app.h"
22 #include "wx/intl.h"
23#endif // WX_PRECOMP
24
25#include "wx/busyinfo.h"
26#include "wx/html/helpctrl.h"
27#include "wx/html/helpwnd.h"
28#include "wx/html/helpfrm.h"
29#include "wx/html/helpdlg.h"
30
31#if wxUSE_HELP
32 #include "wx/tipwin.h"
33#endif
34
35#if wxUSE_LIBMSPACK
36#include "wx/html/forcelnk.h"
37FORCE_LINK(wxhtml_chm_support)
38#endif
39
40IMPLEMENT_DYNAMIC_CLASS(wxHtmlHelpController, wxHelpControllerBase)
41
42wxHtmlHelpController::wxHtmlHelpController(int style, wxWindow* parentWindow):
43 wxHelpControllerBase(parentWindow)
44{
45 Init(style);
46}
47
48wxHtmlHelpController::wxHtmlHelpController(wxWindow* parentWindow, int style):
49 wxHelpControllerBase(parentWindow)
50{
51 Init(style);
52}
53
54void wxHtmlHelpController::Init(int style)
55{
56 m_helpWindow = NULL;
57 m_helpFrame = NULL;
58 m_helpDialog = NULL;
59#if wxUSE_CONFIG
60 m_Config = NULL;
61 m_ConfigRoot = wxEmptyString;
62#endif // wxUSE_CONFIG
63 m_titleFormat = _("Help: %s");
64 m_FrameStyle = style;
65 m_shouldPreventAppExit = false;
66}
67
68
69wxHtmlHelpController::~wxHtmlHelpController()
70{
71#if wxUSE_CONFIG
72 if (m_Config)
73 WriteCustomization(m_Config, m_ConfigRoot);
74#endif // wxUSE_CONFIG
75 if (m_helpWindow)
76 DestroyHelpWindow();
77}
78
79
80void wxHtmlHelpController::DestroyHelpWindow()
81{
82 if (m_FrameStyle & wxHF_EMBEDDED)
83 return;
84
85 // Find top-most parent window
86 // If a modal dialog
87 wxWindow* parent = FindTopLevelWindow();
88 if (parent)
89 {
90 wxDialog* dialog = wxDynamicCast(parent, wxDialog);
91 if (dialog && dialog->IsModal())
92 {
93 dialog->EndModal(wxID_OK);
94 }
95 parent->Destroy();
96 m_helpWindow = NULL;
97 }
98 m_helpDialog = NULL;
99 m_helpFrame = NULL;
100}
101
102void wxHtmlHelpController::OnCloseFrame(wxCloseEvent& evt)
103{
104#if wxUSE_CONFIG
105 if (m_Config)
106 WriteCustomization(m_Config, m_ConfigRoot);
107#endif // wxUSE_CONFIG
108
109 evt.Skip();
110
111 OnQuit();
112
113 if ( m_helpWindow )
114 m_helpWindow->SetController(NULL);
115 m_helpWindow = NULL;
116 m_helpDialog = NULL;
117 m_helpFrame = NULL;
118}
119
120void wxHtmlHelpController::SetShouldPreventAppExit(bool enable)
121{
122 m_shouldPreventAppExit = enable;
123 if ( m_helpFrame )
124 m_helpFrame->SetShouldPreventAppExit(enable);
125}
126
127void wxHtmlHelpController::SetTitleFormat(const wxString& title)
128{
129 m_titleFormat = title;
130 wxHtmlHelpFrame* frame = wxDynamicCast(FindTopLevelWindow(), wxHtmlHelpFrame);
131 wxHtmlHelpDialog* dialog = wxDynamicCast(FindTopLevelWindow(), wxHtmlHelpDialog);
132 if (frame)
133 {
134 frame->SetTitleFormat(title);
135 }
136 else if (dialog)
137 dialog->SetTitleFormat(title);
138}
139
140// Find the top-most parent window
141wxWindow* wxHtmlHelpController::FindTopLevelWindow()
142{
143 return wxGetTopLevelParent(m_helpWindow);
144}
145
146bool wxHtmlHelpController::AddBook(const wxFileName& book_file, bool show_wait_msg)
147{
148 return AddBook(wxFileSystem::FileNameToURL(book_file), show_wait_msg);
149}
150
151bool wxHtmlHelpController::AddBook(const wxString& book, bool show_wait_msg)
152{
153 wxBusyCursor cur;
154#if wxUSE_BUSYINFO
155 wxBusyInfo* busy = NULL;
156 wxString info;
157 if (show_wait_msg)
158 {
159 info.Printf(_("Adding book %s"), book.c_str());
160 busy = new wxBusyInfo(info);
161 }
162#endif
163 bool retval = m_helpData.AddBook(book);
164#if wxUSE_BUSYINFO
165 if (show_wait_msg)
166 delete busy;
167#else
168 wxUnusedVar(show_wait_msg);
169#endif
170 if (m_helpWindow)
171 m_helpWindow->RefreshLists();
172 return retval;
173}
174
175wxHtmlHelpFrame* wxHtmlHelpController::CreateHelpFrame(wxHtmlHelpData *data)
176{
177 wxHtmlHelpFrame* frame = new wxHtmlHelpFrame(data);
178 frame->SetController(this);
179 frame->Create(m_parentWindow, -1, wxEmptyString, m_FrameStyle
180#if wxUSE_CONFIG
181 , m_Config, m_ConfigRoot
182#endif // wxUSE_CONFIG
183 );
184 frame->SetTitleFormat(m_titleFormat);
185 frame->SetShouldPreventAppExit(m_shouldPreventAppExit);
186 m_helpFrame = frame;
187 return frame;
188}
189
190wxHtmlHelpDialog* wxHtmlHelpController::CreateHelpDialog(wxHtmlHelpData *data)
191{
192 wxHtmlHelpDialog* dialog = new wxHtmlHelpDialog(data);
193 dialog->SetController(this);
194 dialog->SetTitleFormat(m_titleFormat);
195 dialog->Create(m_parentWindow, -1, wxEmptyString, m_FrameStyle);
196 m_helpDialog = dialog;
197 return dialog;
198}
199
200wxWindow* wxHtmlHelpController::CreateHelpWindow()
201{
202 if (m_helpWindow)
203 {
204 if (m_FrameStyle & wxHF_EMBEDDED)
205 return m_helpWindow;
206
207 wxWindow* topLevelWindow = FindTopLevelWindow();
208 if (topLevelWindow)
209 topLevelWindow->Raise();
210 return m_helpWindow;
211 }
212
213#if wxUSE_CONFIG
214 if (m_Config == NULL)
215 {
216 m_Config = wxConfigBase::Get(false);
217 if (m_Config != NULL)
218 m_ConfigRoot = wxT("wxWindows/wxHtmlHelpController");
219 }
220#endif // wxUSE_CONFIG
221
222 if (m_FrameStyle & wxHF_DIALOG)
223 {
224 wxHtmlHelpDialog* dialog = CreateHelpDialog(&m_helpData);
225 m_helpWindow = dialog->GetHelpWindow();
226 }
227 else if ((m_FrameStyle & wxHF_EMBEDDED) && m_parentWindow)
228 {
229 m_helpWindow = new wxHtmlHelpWindow(m_parentWindow, -1, wxDefaultPosition, wxDefaultSize,
230 wxTAB_TRAVERSAL|wxNO_BORDER, m_FrameStyle, &m_helpData);
231 }
232 else // wxHF_FRAME
233 {
234 wxHtmlHelpFrame* frame = CreateHelpFrame(&m_helpData);
235 m_helpWindow = frame->GetHelpWindow();
236 frame->Show(true);
237 }
238
239 return m_helpWindow;
240}
241
242#if wxUSE_CONFIG
243void wxHtmlHelpController::ReadCustomization(wxConfigBase* cfg, const wxString& path)
244{
245 /* should not be called by the user; call UseConfig, and the controller
246 * will do the rest */
247 if (m_helpWindow && cfg)
248 m_helpWindow->ReadCustomization(cfg, path);
249}
250
251void wxHtmlHelpController::WriteCustomization(wxConfigBase* cfg, const wxString& path)
252{
253 /* typically called by the controllers OnCloseFrame handler */
254 if (m_helpWindow && cfg)
255 m_helpWindow->WriteCustomization(cfg, path);
256}
257
258void wxHtmlHelpController::UseConfig(wxConfigBase *config, const wxString& rootpath)
259{
260 m_Config = config;
261 m_ConfigRoot = rootpath;
262 if (m_helpWindow) m_helpWindow->UseConfig(config, rootpath);
263 ReadCustomization(config, rootpath);
264}
265#endif // wxUSE_CONFIG
266
267//// Backward compatibility with wxHelpController API
268
269bool wxHtmlHelpController::Initialize(const wxString& file)
270{
271 wxString dir, filename, ext;
272 wxFileName::SplitPath(file, & dir, & filename, & ext);
273
274 if (!dir.empty())
275 dir = dir + wxFILE_SEP_PATH;
276
277 // Try to find a suitable file
278 wxString actualFilename = dir + filename + wxString(wxT(".zip"));
279 if (!wxFileExists(actualFilename))
280 {
281 actualFilename = dir + filename + wxString(wxT(".htb"));
282 if (!wxFileExists(actualFilename))
283 {
284 actualFilename = dir + filename + wxString(wxT(".hhp"));
285 if (!wxFileExists(actualFilename))
286 {
287#if wxUSE_LIBMSPACK
288 actualFilename = dir + filename + wxString(wxT(".chm"));
289 if (!wxFileExists(actualFilename))
290#endif
291 return false;
292 }
293 }
294 }
295 return AddBook(wxFileName(actualFilename));
296}
297
298bool wxHtmlHelpController::LoadFile(const wxString& WXUNUSED(file))
299{
300 // Don't reload the file or we'll have it appear again, presumably.
301 return true;
302}
303
304bool wxHtmlHelpController::DisplaySection(int sectionNo)
305{
306 return Display(sectionNo);
307}
308
309bool wxHtmlHelpController::DisplayTextPopup(const wxString& text, const wxPoint& WXUNUSED(pos))
310{
311#if wxUSE_TIPWINDOW
312 static wxTipWindow* s_tipWindow = NULL;
313
314 if (s_tipWindow)
315 {
316 // Prevent s_tipWindow being nulled in OnIdle,
317 // thereby removing the chance for the window to be closed by ShowHelp
318 s_tipWindow->SetTipWindowPtr(NULL);
319 s_tipWindow->Close();
320 }
321 s_tipWindow = NULL;
322
323 if ( !text.empty() )
324 {
325 s_tipWindow = new wxTipWindow(wxTheApp->GetTopWindow(), text, 100, & s_tipWindow);
326
327 return true;
328 }
329#else
330 wxUnusedVar(text);
331#endif // wxUSE_TIPWINDOW
332
333 return false;
334}
335
336void wxHtmlHelpController::SetHelpWindow(wxHtmlHelpWindow* helpWindow)
337{
338 m_helpWindow = helpWindow;
339 if (helpWindow)
340 helpWindow->SetController(this);
341}
342
343void wxHtmlHelpController::SetFrameParameters(const wxString& titleFormat,
344 const wxSize& size,
345 const wxPoint& pos,
346 bool WXUNUSED(newFrameEachTime))
347{
348 SetTitleFormat(titleFormat);
349 wxHtmlHelpFrame* frame = wxDynamicCast(FindTopLevelWindow(), wxHtmlHelpFrame);
350 wxHtmlHelpDialog* dialog = wxDynamicCast(FindTopLevelWindow(), wxHtmlHelpDialog);
351 if (frame)
352 frame->SetSize(pos.x, pos.y, size.x, size.y);
353 else if (dialog)
354 dialog->SetSize(pos.x, pos.y, size.x, size.y);
355}
356
357wxFrame* wxHtmlHelpController::GetFrameParameters(wxSize *size,
358 wxPoint *pos,
359 bool *newFrameEachTime)
360{
361 if (newFrameEachTime)
362 (* newFrameEachTime) = false;
363
364 wxHtmlHelpFrame* frame = wxDynamicCast(FindTopLevelWindow(), wxHtmlHelpFrame);
365 wxHtmlHelpDialog* dialog = wxDynamicCast(FindTopLevelWindow(), wxHtmlHelpDialog);
366 if (frame)
367 {
368 if (size)
369 (* size) = frame->GetSize();
370 if (pos)
371 (* pos) = frame->GetPosition();
372 return frame;
373 }
374 else if (dialog)
375 {
376 if (size)
377 (* size) = dialog->GetSize();
378 if (pos)
379 (* pos) = dialog->GetPosition();
380 return NULL;
381 }
382 return NULL;
383}
384
385bool wxHtmlHelpController::Quit()
386{
387 DestroyHelpWindow();
388 return true;
389}
390
391// Make the help controller's frame 'modal' if
392// needed
393void wxHtmlHelpController::MakeModalIfNeeded()
394{
395 if ((m_FrameStyle & wxHF_EMBEDDED) == 0)
396 {
397 wxHtmlHelpFrame* frame = wxDynamicCast(FindTopLevelWindow(), wxHtmlHelpFrame);
398 wxHtmlHelpDialog* dialog = wxDynamicCast(FindTopLevelWindow(), wxHtmlHelpDialog);
399 if (frame)
400 frame->AddGrabIfNeeded();
401 else if (dialog && (m_FrameStyle & wxHF_MODAL))
402 {
403 dialog->ShowModal();
404 }
405 }
406}
407
408bool wxHtmlHelpController::Display(const wxString& x)
409{
410 CreateHelpWindow();
411 bool success = m_helpWindow->Display(x);
412 MakeModalIfNeeded();
413 return success;
414}
415
416bool wxHtmlHelpController::Display(int id)
417{
418 CreateHelpWindow();
419 bool success = m_helpWindow->Display(id);
420 MakeModalIfNeeded();
421 return success;
422}
423
424bool wxHtmlHelpController::DisplayContents()
425{
426 CreateHelpWindow();
427 bool success = m_helpWindow->DisplayContents();
428 MakeModalIfNeeded();
429 return success;
430}
431
432bool wxHtmlHelpController::DisplayIndex()
433{
434 CreateHelpWindow();
435 bool success = m_helpWindow->DisplayIndex();
436 MakeModalIfNeeded();
437 return success;
438}
439
440bool wxHtmlHelpController::KeywordSearch(const wxString& keyword,
441 wxHelpSearchMode mode)
442{
443 CreateHelpWindow();
444 bool success = m_helpWindow->KeywordSearch(keyword, mode);
445 MakeModalIfNeeded();
446 return success;
447}
448
449/*
450 * wxHtmlModalHelp
451 * A convenience class, to use like this:
452 *
453 * wxHtmlModalHelp help(parent, helpFile, topic);
454 */
455
456wxHtmlModalHelp::wxHtmlModalHelp(wxWindow* parent, const wxString& helpFile, const wxString& topic, int style)
457{
458 // Force some mandatory styles
459 style |= wxHF_DIALOG | wxHF_MODAL;
460
461 wxHtmlHelpController controller(style, parent);
462 controller.Initialize(helpFile);
463
464 if (topic.IsEmpty())
465 controller.DisplayContents();
466 else
467 controller.DisplaySection(topic);
468}
469
470#endif // wxUSE_WXHTML_HELP
471