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