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