]> git.saurik.com Git - wxWidgets.git/blame - src/html/helpctrl.cpp
using common GetContentScaleFactor throughout part 2/2
[wxWidgets.git] / src / html / helpctrl.cpp
CommitLineData
8ec2b484 1/////////////////////////////////////////////////////////////////////////////
80fdcdb9 2// Name: src/html/helpctrl.cpp
8ec2b484 3// Purpose: wxHtmlHelpController
f42b1601 4// Notes: Based on htmlhelp.cpp, implementing a monolithic
8ec2b484
HH
5// HTML Help controller class, by Vaclav Slavik
6// Author: Harm van der Heijden and Vaclav Slavik
69941f05 7// RCS-ID: $Id$
8ec2b484 8// Copyright: (c) Harm van der Heijden and Vaclav Slavik
65571936 9// Licence: wxWindows licence
8ec2b484
HH
10/////////////////////////////////////////////////////////////////////////////
11
8ec2b484
HH
12// For compilers that support precompilation, includes "wx.h".
13#include "wx/wxprec.h"
14
15#ifdef __BORLANDC__
16#pragma hdrstop
17#endif
18
3379ed37 19#if wxUSE_WXHTML_HELP
8ec2b484 20
07b8d7ec
VZ
21#ifndef WX_PRECOMP
22 #include "wx/app.h"
23 #include "wx/intl.h"
24#endif // WX_PRECOMP
25
8ec2b484 26#include "wx/busyinfo.h"
3755cfa6 27#include "wx/html/helpctrl.h"
f3e156ef 28#include "wx/html/helpwnd.h"
3755cfa6
JS
29#include "wx/html/helpfrm.h"
30#include "wx/html/helpdlg.h"
c010d6a9 31
673dfcfa 32#if wxUSE_HELP
c010d6a9 33 #include "wx/tipwin.h"
673dfcfa 34#endif
d1da8872 35
3527f29c
VS
36#if wxUSE_LIBMSPACK
37#include "wx/html/forcelnk.h"
38FORCE_LINK(wxhtml_chm_support)
39#endif
673dfcfa 40
b4414c1f 41IMPLEMENT_DYNAMIC_CLASS(wxHtmlHelpController, wxHelpControllerBase)
f42b1601 42
3db52265
JS
43wxHtmlHelpController::wxHtmlHelpController(int style, wxWindow* parentWindow):
44 wxHelpControllerBase(parentWindow)
895c1bc0
RD
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)
8ec2b484 56{
3755cfa6 57 m_helpWindow = NULL;
f3e156ef
JS
58 m_helpFrame = NULL;
59 m_helpDialog = NULL;
b4246849 60#if wxUSE_CONFIG
8ec2b484
HH
61 m_Config = NULL;
62 m_ConfigRoot = wxEmptyString;
b4246849 63#endif // wxUSE_CONFIG
8ec2b484 64 m_titleFormat = _("Help: %s");
d5bb85a0 65 m_FrameStyle = style;
bd45b3e1 66 m_shouldPreventAppExit = false;
8ec2b484
HH
67}
68
895c1bc0 69
8ec2b484
HH
70wxHtmlHelpController::~wxHtmlHelpController()
71{
b4246849 72#if wxUSE_CONFIG
f6bcfd97
BP
73 if (m_Config)
74 WriteCustomization(m_Config, m_ConfigRoot);
b4246849 75#endif // wxUSE_CONFIG
3755cfa6 76 if (m_helpWindow)
b854b7b8 77 DestroyHelpWindow();
8ec2b484
HH
78}
79
b854b7b8
VS
80
81void wxHtmlHelpController::DestroyHelpWindow()
82{
3755cfa6
JS
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 }
f3e156ef
JS
99 m_helpDialog = NULL;
100 m_helpFrame = NULL;
b854b7b8
VS
101}
102
b4414c1f 103void wxHtmlHelpController::OnCloseFrame(wxCloseEvent& evt)
b854b7b8 104{
b4246849 105#if wxUSE_CONFIG
3755cfa6
JS
106 if (m_Config)
107 WriteCustomization(m_Config, m_ConfigRoot);
b4246849 108#endif // wxUSE_CONFIG
664d1729 109
b4414c1f 110 evt.Skip();
b854b7b8 111
b4414c1f 112 OnQuit();
b854b7b8 113
664d1729
VS
114 if ( m_helpWindow )
115 m_helpWindow->SetController(NULL);
3755cfa6 116 m_helpWindow = NULL;
f3e156ef
JS
117 m_helpDialog = NULL;
118 m_helpFrame = NULL;
b4414c1f 119}
b854b7b8 120
bd45b3e1
VZ
121void wxHtmlHelpController::SetShouldPreventAppExit(bool enable)
122{
123 m_shouldPreventAppExit = enable;
124 if ( m_helpFrame )
125 m_helpFrame->SetShouldPreventAppExit(enable);
126}
127
8ec2b484
HH
128void wxHtmlHelpController::SetTitleFormat(const wxString& title)
129{
130 m_titleFormat = title;
3755cfa6
JS
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);
8ec2b484
HH
139}
140
3755cfa6
JS
141// Find the top-most parent window
142wxWindow* wxHtmlHelpController::FindTopLevelWindow()
143{
9df05aab 144 return wxGetTopLevelParent(m_helpWindow);
3755cfa6 145}
d5bb85a0 146
fcf77487
VS
147bool wxHtmlHelpController::AddBook(const wxFileName& book_file, bool show_wait_msg)
148{
149 return AddBook(wxFileSystem::FileNameToURL(book_file), show_wait_msg);
150}
151
8ec2b484
HH
152bool wxHtmlHelpController::AddBook(const wxString& book, bool show_wait_msg)
153{
154 wxBusyCursor cur;
155#if wxUSE_BUSYINFO
69941f05 156 wxBusyInfo* busy = NULL;
8ec2b484 157 wxString info;
33ac7e6f 158 if (show_wait_msg)
4f9297b0 159 {
d5bb85a0
VS
160 info.Printf(_("Adding book %s"), book.c_str());
161 busy = new wxBusyInfo(info);
8ec2b484
HH
162 }
163#endif
164 bool retval = m_helpData.AddBook(book);
165#if wxUSE_BUSYINFO
166 if (show_wait_msg)
d5bb85a0 167 delete busy;
132a5928
WS
168#else
169 wxUnusedVar(show_wait_msg);
33ac7e6f 170#endif
3755cfa6
JS
171 if (m_helpWindow)
172 m_helpWindow->RefreshLists();
8ec2b484
HH
173 return retval;
174}
175
3755cfa6 176wxHtmlHelpFrame* wxHtmlHelpController::CreateHelpFrame(wxHtmlHelpData *data)
b854b7b8 177{
3755cfa6
JS
178 wxHtmlHelpFrame* frame = new wxHtmlHelpFrame(data);
179 frame->SetController(this);
b4246849
VZ
180 frame->Create(m_parentWindow, -1, wxEmptyString, m_FrameStyle
181#if wxUSE_CONFIG
182 , m_Config, m_ConfigRoot
183#endif // wxUSE_CONFIG
184 );
bd365871 185 frame->SetTitleFormat(m_titleFormat);
bd45b3e1 186 frame->SetShouldPreventAppExit(m_shouldPreventAppExit);
f3e156ef 187 m_helpFrame = frame;
3755cfa6 188 return frame;
b854b7b8
VS
189}
190
3755cfa6
JS
191wxHtmlHelpDialog* wxHtmlHelpController::CreateHelpDialog(wxHtmlHelpData *data)
192{
193 wxHtmlHelpDialog* dialog = new wxHtmlHelpDialog(data);
194 dialog->SetController(this);
bd365871 195 dialog->SetTitleFormat(m_titleFormat);
3755cfa6 196 dialog->Create(m_parentWindow, -1, wxEmptyString, m_FrameStyle);
f3e156ef 197 m_helpDialog = dialog;
3755cfa6
JS
198 return dialog;
199}
b854b7b8 200
3755cfa6 201wxWindow* wxHtmlHelpController::CreateHelpWindow()
8ec2b484 202{
3755cfa6 203 if (m_helpWindow)
4f9297b0 204 {
3755cfa6
JS
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;
8ec2b484 212 }
d5bb85a0 213
b4246849 214#if wxUSE_CONFIG
33ac7e6f 215 if (m_Config == NULL)
74accc50 216 {
d1da8872 217 m_Config = wxConfigBase::Get(false);
74accc50 218 if (m_Config != NULL)
9a83f860 219 m_ConfigRoot = wxT("wxWindows/wxHtmlHelpController");
74accc50 220 }
b4246849 221#endif // wxUSE_CONFIG
74accc50 222
3755cfa6
JS
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 }
7e521b01 239
3755cfa6 240 return m_helpWindow;
8ec2b484
HH
241}
242
b4246849 243#if wxUSE_CONFIG
8ec2b484
HH
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 */
3755cfa6
JS
248 if (m_helpWindow && cfg)
249 m_helpWindow->ReadCustomization(cfg, path);
8ec2b484
HH
250}
251
252void wxHtmlHelpController::WriteCustomization(wxConfigBase* cfg, const wxString& path)
253{
254 /* typically called by the controllers OnCloseFrame handler */
3755cfa6
JS
255 if (m_helpWindow && cfg)
256 m_helpWindow->WriteCustomization(cfg, path);
8ec2b484
HH
257}
258
721ab905
VS
259void wxHtmlHelpController::UseConfig(wxConfigBase *config, const wxString& rootpath)
260{
261 m_Config = config;
262 m_ConfigRoot = rootpath;
3755cfa6 263 if (m_helpWindow) m_helpWindow->UseConfig(config, rootpath);
721ab905
VS
264 ReadCustomization(config, rootpath);
265}
b4246849 266#endif // wxUSE_CONFIG
721ab905 267
b4414c1f
JS
268//// Backward compatibility with wxHelpController API
269
270bool wxHtmlHelpController::Initialize(const wxString& file)
271{
272 wxString dir, filename, ext;
bd365871 273 wxFileName::SplitPath(file, & dir, & filename, & ext);
b4414c1f 274
ddc80eb4 275 if (!dir.empty())
0222a60b 276 dir = dir + wxFILE_SEP_PATH;
b4414c1f
JS
277
278 // Try to find a suitable file
e81910e0 279 wxString actualFilename = dir + filename + wxString(wxT(".zip"));
b4414c1f
JS
280 if (!wxFileExists(actualFilename))
281 {
e81910e0 282 actualFilename = dir + filename + wxString(wxT(".htb"));
b4414c1f
JS
283 if (!wxFileExists(actualFilename))
284 {
e81910e0 285 actualFilename = dir + filename + wxString(wxT(".hhp"));
b4414c1f 286 if (!wxFileExists(actualFilename))
3527f29c
VS
287 {
288#if wxUSE_LIBMSPACK
289 actualFilename = dir + filename + wxString(wxT(".chm"));
290 if (!wxFileExists(actualFilename))
291#endif
292 return false;
293 }
b4414c1f
JS
294 }
295 }
fcf77487 296 return AddBook(wxFileName(actualFilename));
b4414c1f
JS
297}
298
299bool wxHtmlHelpController::LoadFile(const wxString& WXUNUSED(file))
300{
301 // Don't reload the file or we'll have it appear again, presumably.
d1da8872 302 return true;
b4414c1f
JS
303}
304
305bool wxHtmlHelpController::DisplaySection(int sectionNo)
306{
307 return Display(sectionNo);
308}
309
673dfcfa
JS
310bool wxHtmlHelpController::DisplayTextPopup(const wxString& text, const wxPoint& WXUNUSED(pos))
311{
f38bcae5 312#if wxUSE_TIPWINDOW
673dfcfa
JS
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
d1da8872 328 return true;
673dfcfa 329 }
ddc80eb4
WS
330#else
331 wxUnusedVar(text);
f38bcae5
VZ
332#endif // wxUSE_TIPWINDOW
333
d1da8872 334 return false;
673dfcfa
JS
335}
336
3755cfa6
JS
337void wxHtmlHelpController::SetHelpWindow(wxHtmlHelpWindow* helpWindow)
338{
339 m_helpWindow = helpWindow;
340 if (helpWindow)
341 helpWindow->SetController(this);
342}
343
eae48ea1 344void wxHtmlHelpController::SetFrameParameters(const wxString& titleFormat,
b4414c1f
JS
345 const wxSize& size,
346 const wxPoint& pos,
347 bool WXUNUSED(newFrameEachTime))
348{
eae48ea1 349 SetTitleFormat(titleFormat);
3755cfa6
JS
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);
b4414c1f
JS
356}
357
358wxFrame* wxHtmlHelpController::GetFrameParameters(wxSize *size,
359 wxPoint *pos,
360 bool *newFrameEachTime)
361{
362 if (newFrameEachTime)
d1da8872 363 (* newFrameEachTime) = false;
3755cfa6
JS
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;
b4414c1f
JS
384}
385
386bool wxHtmlHelpController::Quit()
387{
388 DestroyHelpWindow();
d1da8872 389 return true;
b4414c1f
JS
390}
391
5152b0e5
JS
392// Make the help controller's frame 'modal' if
393// needed
3755cfa6 394void wxHtmlHelpController::MakeModalIfNeeded()
5152b0e5 395{
3755cfa6 396 if ((m_FrameStyle & wxHF_EMBEDDED) == 0)
5152b0e5 397 {
3755cfa6
JS
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 }
5152b0e5 406 }
5152b0e5
JS
407}
408
409bool wxHtmlHelpController::Display(const wxString& x)
410{
411 CreateHelpWindow();
3755cfa6
JS
412 bool success = m_helpWindow->Display(x);
413 MakeModalIfNeeded();
d1da8872 414 return success;
5152b0e5
JS
415}
416
417bool wxHtmlHelpController::Display(int id)
418{
419 CreateHelpWindow();
3755cfa6
JS
420 bool success = m_helpWindow->Display(id);
421 MakeModalIfNeeded();
5152b0e5
JS
422 return success;
423}
424
425bool wxHtmlHelpController::DisplayContents()
426{
427 CreateHelpWindow();
3755cfa6
JS
428 bool success = m_helpWindow->DisplayContents();
429 MakeModalIfNeeded();
5152b0e5
JS
430 return success;
431}
432
433bool wxHtmlHelpController::DisplayIndex()
434{
435 CreateHelpWindow();
3755cfa6
JS
436 bool success = m_helpWindow->DisplayIndex();
437 MakeModalIfNeeded();
5152b0e5
JS
438 return success;
439}
440
69b5cec2
VS
441bool wxHtmlHelpController::KeywordSearch(const wxString& keyword,
442 wxHelpSearchMode mode)
5152b0e5
JS
443{
444 CreateHelpWindow();
3755cfa6
JS
445 bool success = m_helpWindow->KeywordSearch(keyword, mode);
446 MakeModalIfNeeded();
5152b0e5
JS
447 return success;
448}
449
3755cfa6
JS
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
3379ed37
VZ
471#endif // wxUSE_WXHTML_HELP
472