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