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