]> git.saurik.com Git - wxWidgets.git/blame - src/html/helpwnd.cpp
Add virtual ~wxAnyScrollHelperBase() to fix compiler warning.
[wxWidgets.git] / src / html / helpwnd.cpp
CommitLineData
3755cfa6 1/////////////////////////////////////////////////////////////////////////////
548b5377 2// Name: src/html/helpwnd.cpp
3755cfa6
JS
3// Purpose: wxHtmlHelpWindow
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
3755cfa6
JS
7// Copyright: (c) Harm van der Heijden and Vaclav Slavik
8// Licence: wxWindows licence
9/////////////////////////////////////////////////////////////////////////////
10
11// For compilers that support precompilation, includes "wx.h"
12
13#include "wx/wxprec.h"
14
15#ifdef __BORLANDC__
8e3f3880 16 #pragma hdrstop
3755cfa6
JS
17#endif
18
19#if wxUSE_WXHTML_HELP
20
b4f4d3dd 21#ifndef WX_PRECOMP
8e3f3880 22 #include "wx/object.h"
ad9835c9 23 #include "wx/dynarray.h"
3755cfa6
JS
24 #include "wx/intl.h"
25 #include "wx/log.h"
530ecef0
WS
26 #if wxUSE_STREAMS
27 #include "wx/stream.h"
28 #endif
3755cfa6 29
3755cfa6
JS
30 #include "wx/sizer.h"
31
32 #include "wx/bmpbuttn.h"
33 #include "wx/statbox.h"
34 #include "wx/radiobox.h"
3b3dc801 35 #include "wx/menu.h"
9eddec69 36 #include "wx/settings.h"
3755cfa6 37 #include "wx/msgdlg.h"
fec9cc08 38 #include "wx/textctrl.h"
4e3e485b 39 #include "wx/toolbar.h"
949c9f74
WS
40 #include "wx/choicdlg.h"
41 #include "wx/filedlg.h"
b4f4d3dd 42#endif // WX_PRECOMP
3755cfa6
JS
43
44#include "wx/html/helpfrm.h"
45#include "wx/html/helpdlg.h"
46#include "wx/html/helpctrl.h"
3755cfa6
JS
47#include "wx/notebook.h"
48#include "wx/imaglist.h"
49#include "wx/treectrl.h"
50#include "wx/tokenzr.h"
51#include "wx/wfstream.h"
52#include "wx/html/htmlwin.h"
53#include "wx/busyinfo.h"
54#include "wx/progdlg.h"
3755cfa6 55#include "wx/fontenum.h"
3755cfa6
JS
56#include "wx/artprov.h"
57#include "wx/spinctrl.h"
3755cfa6
JS
58
59// what is considered "small index"?
ad7922b8 60#define INDEX_IS_SMALL 1000
3755cfa6 61
a55602fa
VZ
62// minimum width for content tree and index
63// (we cannot let minimum size be determined from content, else long titles
64// make the help frame unusable)
65const wxCoord CONTENT_TREE_INDEX_MIN_WIDTH = 150;
66
3755cfa6
JS
67/* Motif defines this as a macro */
68#ifdef Below
69#undef Below
70#endif
71
72//--------------------------------------------------------------------------
73// wxHtmlHelpTreeItemData (private)
74//--------------------------------------------------------------------------
75
76class wxHtmlHelpTreeItemData : public wxTreeItemData
77{
78 public:
79#if defined(__VISAGECPP__)
80// VA needs a default ctor for some reason....
81 wxHtmlHelpTreeItemData() : wxTreeItemData()
82 { m_Id = 0; }
83#endif
84 wxHtmlHelpTreeItemData(int id) : wxTreeItemData()
85 { m_Id = id;}
86
87 int m_Id;
88};
89
90
91//--------------------------------------------------------------------------
92// wxHtmlHelpHashData (private)
93//--------------------------------------------------------------------------
94
95class wxHtmlHelpHashData : public wxObject
96{
97 public:
98 wxHtmlHelpHashData(int index, wxTreeItemId id) : wxObject()
99 { m_Index = index; m_Id = id;}
d3c7fc99 100 virtual ~wxHtmlHelpHashData() {}
3755cfa6
JS
101
102 int m_Index;
103 wxTreeItemId m_Id;
104};
105
106
107//--------------------------------------------------------------------------
108// wxHtmlHelpHtmlWindow (private)
109//--------------------------------------------------------------------------
110
3755cfa6
JS
111
112class wxHtmlHelpHtmlWindow : public wxHtmlWindow
113{
630906de 114public:
6f3f9b50
JS
115 wxHtmlHelpHtmlWindow(wxHtmlHelpWindow *win, wxWindow *parent, wxWindowID id = wxID_ANY,
116 const wxPoint& pos = wxDefaultPosition, const wxSize& sz = wxDefaultSize, long style = wxHW_DEFAULT_STYLE)
117 : wxHtmlWindow(parent, id, pos, sz, style), m_Window(win)
630906de
VZ
118 {
119 SetStandardFonts();
120 }
121
432d207e 122 virtual bool LoadPage(const wxString& location)
630906de 123 {
432d207e
VS
124 if ( !wxHtmlWindow::LoadPage(location) )
125 return false;
325219cb 126
432d207e
VS
127 m_Window->NotifyPageChanged();
128 return true;
630906de
VZ
129 }
130
131 // Returns full location with anchor (helper)
132 static wxString GetOpenedPageWithAnchor(wxHtmlWindow *win)
133 {
134 if(!win)
135 return wxEmptyString;
136
137 wxString an = win->GetOpenedAnchor();
138 wxString pg = win->GetOpenedPage();
139 if(!an.empty())
3755cfa6 140 {
630906de 141 pg << wxT("#") << an;
3755cfa6 142 }
630906de
VZ
143 return pg;
144 }
3755cfa6 145
630906de
VZ
146private:
147 wxHtmlHelpWindow *m_Window;
3755cfa6 148
c0c133e1 149 wxDECLARE_NO_COPY_CLASS(wxHtmlHelpHtmlWindow);
3755cfa6
JS
150};
151
152
153//---------------------------------------------------------------------------
154// wxHtmlHelpWindow::m_mergedIndex
155//---------------------------------------------------------------------------
156
157WX_DEFINE_ARRAY_PTR(const wxHtmlHelpDataItem*, wxHtmlHelpDataItemPtrArray);
158
159struct wxHtmlHelpMergedIndexItem
160{
161 wxHtmlHelpMergedIndexItem *parent;
162 wxString name;
163 wxHtmlHelpDataItemPtrArray items;
164};
165
166WX_DECLARE_OBJARRAY(wxHtmlHelpMergedIndexItem, wxHtmlHelpMergedIndex);
167#include "wx/arrimpl.cpp"
168WX_DEFINE_OBJARRAY(wxHtmlHelpMergedIndex)
169
170void wxHtmlHelpWindow::UpdateMergedIndex()
171{
172 delete m_mergedIndex;
173 m_mergedIndex = new wxHtmlHelpMergedIndex;
174 wxHtmlHelpMergedIndex& merged = *m_mergedIndex;
175
176 const wxHtmlHelpDataItems& items = m_Data->GetIndexArray();
177 size_t len = items.size();
178
179 wxHtmlHelpMergedIndexItem *history[128] = {NULL};
180
181 for (size_t i = 0; i < len; i++)
182 {
183 const wxHtmlHelpDataItem& item = items[i];
9a83f860 184 wxASSERT_MSG( item.level < 128, wxT("nested index entries too deep") );
3755cfa6
JS
185
186 if (history[item.level] &&
187 history[item.level]->items[0]->name == item.name)
188 {
189 // same index entry as previous one, update list of items
190 history[item.level]->items.Add(&item);
191 }
192 else
193 {
194 // new index entry
195 wxHtmlHelpMergedIndexItem *mi = new wxHtmlHelpMergedIndexItem();
196 mi->name = item.GetIndentedName();
197 mi->items.Add(&item);
198 mi->parent = (item.level == 0) ? NULL : history[item.level - 1];
199 history[item.level] = mi;
200 merged.Add(mi);
201 }
202 }
203}
204
205//---------------------------------------------------------------------------
206// wxHtmlHelpWindow
207//---------------------------------------------------------------------------
208
3755cfa6
JS
209IMPLEMENT_DYNAMIC_CLASS(wxHtmlHelpWindow, wxWindow)
210
211BEGIN_EVENT_TABLE(wxHtmlHelpWindow, wxWindow)
212 EVT_TOOL_RANGE(wxID_HTML_PANEL, wxID_HTML_OPTIONS, wxHtmlHelpWindow::OnToolbar)
213 EVT_BUTTON(wxID_HTML_BOOKMARKSREMOVE, wxHtmlHelpWindow::OnToolbar)
214 EVT_BUTTON(wxID_HTML_BOOKMARKSADD, wxHtmlHelpWindow::OnToolbar)
215 EVT_TREE_SEL_CHANGED(wxID_HTML_TREECTRL, wxHtmlHelpWindow::OnContentsSel)
216 EVT_LISTBOX(wxID_HTML_INDEXLIST, wxHtmlHelpWindow::OnIndexSel)
217 EVT_LISTBOX(wxID_HTML_SEARCHLIST, wxHtmlHelpWindow::OnSearchSel)
218 EVT_BUTTON(wxID_HTML_SEARCHBUTTON, wxHtmlHelpWindow::OnSearch)
219 EVT_TEXT_ENTER(wxID_HTML_SEARCHTEXT, wxHtmlHelpWindow::OnSearch)
220 EVT_BUTTON(wxID_HTML_INDEXBUTTON, wxHtmlHelpWindow::OnIndexFind)
221 EVT_TEXT_ENTER(wxID_HTML_INDEXTEXT, wxHtmlHelpWindow::OnIndexFind)
222 EVT_BUTTON(wxID_HTML_INDEXBUTTONALL, wxHtmlHelpWindow::OnIndexAll)
223 EVT_COMBOBOX(wxID_HTML_BOOKMARKSLIST, wxHtmlHelpWindow::OnBookmarksSel)
224 EVT_SIZE(wxHtmlHelpWindow::OnSize)
225END_EVENT_TABLE()
226
227wxHtmlHelpWindow::wxHtmlHelpWindow(wxWindow* parent, wxWindowID id,
228 const wxPoint& pos,
229 const wxSize& size,
230 int style, int helpStyle, wxHtmlHelpData* data)
231{
232 Init(data);
233 Create(parent, id, pos, size, style, helpStyle);
234}
235
236void wxHtmlHelpWindow::Init(wxHtmlHelpData* data)
237{
238 if (data)
239 {
240 m_Data = data;
241 m_DataCreated = false;
242 }
243 else
244 {
245 m_Data = new wxHtmlHelpData();
246 m_DataCreated = true;
247 }
248
249 m_ContentsPage = 0;
250 m_IndexPage = 0;
251 m_SearchPage = 0;
252
253 m_ContentsBox = NULL;
254 m_IndexList = NULL;
255 m_IndexButton = NULL;
256 m_IndexButtonAll = NULL;
257 m_IndexText = NULL;
258 m_SearchList = NULL;
259 m_SearchButton = NULL;
260 m_SearchText = NULL;
261 m_SearchChoice = NULL;
262 m_IndexCountInfo = NULL;
263 m_Splitter = NULL;
264 m_NavigPan = NULL;
265 m_NavigNotebook = NULL;
266 m_HtmlWin = NULL;
267 m_Bookmarks = NULL;
268 m_SearchCaseSensitive = NULL;
269 m_SearchWholeWords = NULL;
270
271 m_mergedIndex = NULL;
272
b4246849 273#if wxUSE_CONFIG
3755cfa6
JS
274 m_Config = NULL;
275 m_ConfigRoot = wxEmptyString;
b4246849 276#endif // wxUSE_CONFIG
3755cfa6
JS
277
278 m_Cfg.x = m_Cfg.y = wxDefaultCoord;
279 m_Cfg.w = 700;
280 m_Cfg.h = 480;
281 m_Cfg.sashpos = 240;
282 m_Cfg.navig_on = true;
283
284 m_NormalFonts = m_FixedFonts = NULL;
285 m_NormalFace = m_FixedFace = wxEmptyString;
286#ifdef __WXMSW__
287 m_FontSize = 10;
288#else
289 m_FontSize = 14;
290#endif
291
292#if wxUSE_PRINTING_ARCHITECTURE
293 m_Printer = NULL;
294#endif
295
296 m_PagesHash = NULL;
297 m_UpdateContents = true;
298 m_toolBar = NULL;
d3b9f782 299 m_helpController = NULL;
3755cfa6
JS
300}
301
302// Create: builds the GUI components.
303// with the style flag it's possible to toggle the toolbar, contents, index and search
304// controls.
305// m_HtmlWin will *always* be created, but it's important to realize that
306// m_ContentsBox, m_IndexList, m_SearchList, m_SearchButton, m_SearchText and
307// m_SearchButton may be NULL.
308// moreover, if no contents, index or searchpage is needed, m_Splitter and
309// m_NavigPan will be NULL too (with m_HtmlWin directly connected to the frame)
310
311bool wxHtmlHelpWindow::Create(wxWindow* parent, wxWindowID id,
312 const wxPoint& pos, const wxSize& size,
313 int style, int helpStyle)
314{
315 m_hfStyle = helpStyle;
316
b4246849 317#if wxUSE_CONFIG
3755cfa6
JS
318 // Do the config in two steps. We read the HtmlWindow customization after we
319 // create the window.
320 if (m_Config)
321 ReadCustomization(m_Config, m_ConfigRoot);
b4246849 322#endif // wxUSE_CONFIG
3755cfa6
JS
323
324 wxWindow::Create(parent, id, pos, size, style, wxT("wxHtmlHelp"));
325
326 SetHelpText(_("Displays help as you browse the books on the left."));
327
328 GetPosition(&m_Cfg.x, &m_Cfg.y);
329
330 int notebook_page = 0;
331
332 // The sizer for the whole top-level window.
333 wxSizer *topWindowSizer = new wxBoxSizer(wxVERTICAL);
334 SetSizer(topWindowSizer);
548b5377 335 SetAutoLayout(true);
3755cfa6
JS
336
337#if wxUSE_TOOLBAR
338 // toolbar?
339 if (helpStyle & (wxHF_TOOLBAR | wxHF_FLAT_TOOLBAR))
340 {
548b5377 341 wxToolBar *toolBar = new wxToolBar(this, wxID_ANY, wxDefaultPosition, wxDefaultSize,
3755cfa6
JS
342 wxNO_BORDER | wxTB_HORIZONTAL |
343 wxTB_DOCKABLE | wxTB_NODIVIDER |
344 (helpStyle & wxHF_FLAT_TOOLBAR ? wxTB_FLAT : 0));
345 toolBar->SetMargins( 2, 2 );
4e0d4206 346 toolBar->SetToolBitmapSize( wxSize(22,22) );
3755cfa6
JS
347 AddToolbarButtons(toolBar, helpStyle);
348 toolBar->Realize();
349 topWindowSizer->Add(toolBar, 0, wxEXPAND);
350 m_toolBar = toolBar;
351 }
352#endif //wxUSE_TOOLBAR
353
354 wxSizer *navigSizer = NULL;
355
6f3f9b50 356#ifdef __WXMSW__
10844331 357 wxBorder htmlWindowBorder = wxBORDER_THEME;
6f3f9b50 358#else
3395d7b4 359 wxBorder htmlWindowBorder = wxBORDER_SUNKEN;
6f3f9b50
JS
360#endif
361
3755cfa6
JS
362 if (helpStyle & (wxHF_CONTENTS | wxHF_INDEX | wxHF_SEARCH))
363 {
364 // traditional help controller; splitter window with html page on the
365 // right and a notebook containing various pages on the left
8e7da426
JS
366 long splitterStyle = wxSP_3D;
367 // Drawing moving sash can cause problems on wxMac
368#ifdef __WXMAC__
c901a24c 369 splitterStyle = 0; // 3D style looks poor on Mac
8e7da426
JS
370 splitterStyle |= wxSP_LIVE_UPDATE;
371#endif
372 m_Splitter = new wxSplitterWindow(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, splitterStyle);
3755cfa6
JS
373
374 topWindowSizer->Add(m_Splitter, 1, wxEXPAND);
375
6f3f9b50 376 m_HtmlWin = new wxHtmlHelpHtmlWindow(this, m_Splitter, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxHW_DEFAULT_STYLE|htmlWindowBorder);
3755cfa6
JS
377 m_NavigPan = new wxPanel(m_Splitter, wxID_ANY);
378 m_NavigNotebook = new wxNotebook(m_NavigPan, wxID_HTML_NOTEBOOK,
379 wxDefaultPosition, wxDefaultSize);
1f5cd20e
JS
380#ifdef __WXMAC__
381 m_NavigNotebook->SetWindowVariant(wxWINDOW_VARIANT_SMALL);
382#endif
3755cfa6
JS
383
384 navigSizer = new wxBoxSizer(wxVERTICAL);
385 navigSizer->Add(m_NavigNotebook, 1, wxEXPAND);
386
387 m_NavigPan->SetSizer(navigSizer);
388 }
389 else
390 {
391 // only html window, no notebook with index,contents etc
6f3f9b50 392 m_HtmlWin = new wxHtmlWindow(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxHW_DEFAULT_STYLE|htmlWindowBorder);
3755cfa6
JS
393 topWindowSizer->Add(m_HtmlWin, 1, wxEXPAND);
394 }
395
b4246849 396#if wxUSE_CONFIG
3755cfa6
JS
397 if ( m_Config )
398 m_HtmlWin->ReadCustomization(m_Config, m_ConfigRoot);
b4246849 399#endif // wxUSE_CONFIG
3755cfa6
JS
400
401 // contents tree panel?
402 if ( helpStyle & wxHF_CONTENTS )
403 {
404 wxWindow *dummy = new wxPanel(m_NavigNotebook, wxID_HTML_INDEXPAGE);
1f5cd20e
JS
405#ifdef __WXMAC__
406 dummy->SetWindowVariant(wxWINDOW_VARIANT_NORMAL);
407#endif
3755cfa6
JS
408 wxSizer *topsizer = new wxBoxSizer(wxVERTICAL);
409
410 topsizer->Add(0, 10);
411
412 dummy->SetSizer(topsizer);
413
414 if ( helpStyle & wxHF_BOOKMARKS )
415 {
69f270e0
JS
416 long comboStyle = wxCB_READONLY;
417#ifndef __WXMAC__
418 // Not supported on OSX/Cocoa presently
419 comboStyle |= wxCB_SORT;
420
421#endif
3755cfa6
JS
422 m_Bookmarks = new wxComboBox(dummy, wxID_HTML_BOOKMARKSLIST,
423 wxEmptyString,
424 wxDefaultPosition, wxDefaultSize,
69f270e0 425 0, NULL, comboStyle);
3755cfa6
JS
426 m_Bookmarks->Append(_("(bookmarks)"));
427 for (unsigned i = 0; i < m_BookmarksNames.GetCount(); i++)
428 m_Bookmarks->Append(m_BookmarksNames[i]);
429 m_Bookmarks->SetSelection(0);
430
431 wxBitmapButton *bmpbt1, *bmpbt2;
432 bmpbt1 = new wxBitmapButton(dummy, wxID_HTML_BOOKMARKSADD,
433 wxArtProvider::GetBitmap(wxART_ADD_BOOKMARK,
434 wxART_BUTTON));
435 bmpbt2 = new wxBitmapButton(dummy, wxID_HTML_BOOKMARKSREMOVE,
436 wxArtProvider::GetBitmap(wxART_DEL_BOOKMARK,
437 wxART_BUTTON));
438#if wxUSE_TOOLTIPS
439 bmpbt1->SetToolTip(_("Add current page to bookmarks"));
440 bmpbt2->SetToolTip(_("Remove current page from bookmarks"));
441#endif // wxUSE_TOOLTIPS
442
443 wxSizer *sizer = new wxBoxSizer(wxHORIZONTAL);
444
445 sizer->Add(m_Bookmarks, 1, wxALIGN_CENTRE_VERTICAL | wxRIGHT, 5);
446 sizer->Add(bmpbt1, 0, wxALIGN_CENTRE_VERTICAL | wxRIGHT, 2);
447 sizer->Add(bmpbt2, 0, wxALIGN_CENTRE_VERTICAL, 0);
448
449 topsizer->Add(sizer, 0, wxEXPAND | wxLEFT | wxBOTTOM | wxRIGHT, 10);
450 }
451
452 m_ContentsBox = new wxTreeCtrl(dummy, wxID_HTML_TREECTRL,
453 wxDefaultPosition, wxDefaultSize,
4e0d4206 454#if defined(__WXGTK20__) || defined(__WXMAC__)
3755cfa6
JS
455 wxSUNKEN_BORDER |
456 wxTR_HAS_BUTTONS | wxTR_HIDE_ROOT |
457 wxTR_NO_LINES
458#else
459 wxSUNKEN_BORDER |
460 wxTR_HAS_BUTTONS | wxTR_HIDE_ROOT |
461 wxTR_LINES_AT_ROOT
462#endif
463 );
464
51cd3519
VZ
465 wxImageList *ContentsImageList = new wxImageList(16, 16);
466 ContentsImageList->Add(wxArtProvider::GetIcon(wxART_HELP_BOOK,
467 wxART_HELP_BROWSER,
468 wxSize(16, 16)));
469 ContentsImageList->Add(wxArtProvider::GetIcon(wxART_HELP_FOLDER,
470 wxART_HELP_BROWSER,
471 wxSize(16, 16)));
472 ContentsImageList->Add(wxArtProvider::GetIcon(wxART_HELP_PAGE,
473 wxART_HELP_BROWSER,
474 wxSize(16, 16)));
475
3755cfa6
JS
476 m_ContentsBox->AssignImageList(ContentsImageList);
477
478 topsizer->Add(m_ContentsBox, 1,
479 wxEXPAND | wxLEFT | wxBOTTOM | wxRIGHT,
480 2);
481
482 m_NavigNotebook->AddPage(dummy, _("Contents"));
483 m_ContentsPage = notebook_page++;
484 }
485
486 // index listbox panel?
487 if ( helpStyle & wxHF_INDEX )
488 {
489 wxWindow *dummy = new wxPanel(m_NavigNotebook, wxID_HTML_INDEXPAGE);
1f5cd20e
JS
490#ifdef __WXMAC__
491 dummy->SetWindowVariant(wxWINDOW_VARIANT_NORMAL);
492#endif
3755cfa6
JS
493 wxSizer *topsizer = new wxBoxSizer(wxVERTICAL);
494
495 dummy->SetSizer(topsizer);
496
497 m_IndexText = new wxTextCtrl(dummy, wxID_HTML_INDEXTEXT, wxEmptyString,
498 wxDefaultPosition, wxDefaultSize,
499 wxTE_PROCESS_ENTER);
500 m_IndexButton = new wxButton(dummy, wxID_HTML_INDEXBUTTON, _("Find"));
501 m_IndexButtonAll = new wxButton(dummy, wxID_HTML_INDEXBUTTONALL,
502 _("Show all"));
503 m_IndexCountInfo = new wxStaticText(dummy, wxID_HTML_COUNTINFO,
504 wxEmptyString, wxDefaultPosition,
505 wxDefaultSize,
506 wxALIGN_RIGHT | wxST_NO_AUTORESIZE);
507 m_IndexList = new wxListBox(dummy, wxID_HTML_INDEXLIST,
508 wxDefaultPosition, wxDefaultSize,
509 0, NULL, wxLB_SINGLE);
510
511#if wxUSE_TOOLTIPS
512 m_IndexButton->SetToolTip(_("Display all index items that contain given substring. Search is case insensitive."));
513 m_IndexButtonAll->SetToolTip(_("Show all items in index"));
514#endif //wxUSE_TOOLTIPS
515
516 topsizer->Add(m_IndexText, 0, wxEXPAND | wxALL, 10);
517 wxSizer *btsizer = new wxBoxSizer(wxHORIZONTAL);
518 btsizer->Add(m_IndexButton, 0, wxRIGHT, 2);
519 btsizer->Add(m_IndexButtonAll);
520 topsizer->Add(btsizer, 0,
521 wxALIGN_RIGHT | wxLEFT | wxRIGHT | wxBOTTOM, 10);
522 topsizer->Add(m_IndexCountInfo, 0, wxEXPAND | wxLEFT | wxRIGHT, 2);
523 topsizer->Add(m_IndexList, 1, wxEXPAND | wxALL, 2);
524
525 m_NavigNotebook->AddPage(dummy, _("Index"));
526 m_IndexPage = notebook_page++;
527 }
528
529 // search list panel?
530 if ( helpStyle & wxHF_SEARCH )
531 {
532 wxWindow *dummy = new wxPanel(m_NavigNotebook, wxID_HTML_INDEXPAGE);
1f5cd20e
JS
533#ifdef __WXMAC__
534 dummy->SetWindowVariant(wxWINDOW_VARIANT_NORMAL);
535#endif
3755cfa6
JS
536 wxSizer *sizer = new wxBoxSizer(wxVERTICAL);
537
538 dummy->SetSizer(sizer);
539
540 m_SearchText = new wxTextCtrl(dummy, wxID_HTML_SEARCHTEXT,
541 wxEmptyString,
542 wxDefaultPosition, wxDefaultSize,
543 wxTE_PROCESS_ENTER);
544 m_SearchChoice = new wxChoice(dummy, wxID_HTML_SEARCHCHOICE,
545 wxDefaultPosition, wxSize(125,wxDefaultCoord));
546 m_SearchCaseSensitive = new wxCheckBox(dummy, wxID_ANY, _("Case sensitive"));
547 m_SearchWholeWords = new wxCheckBox(dummy, wxID_ANY, _("Whole words only"));
548 m_SearchButton = new wxButton(dummy, wxID_HTML_SEARCHBUTTON, _("Search"));
549#if wxUSE_TOOLTIPS
7929902d 550 m_SearchButton->SetToolTip(_("Search contents of help book(s) for all occurrences of the text you typed above"));
3755cfa6
JS
551#endif //wxUSE_TOOLTIPS
552 m_SearchList = new wxListBox(dummy, wxID_HTML_SEARCHLIST,
553 wxDefaultPosition, wxDefaultSize,
554 0, NULL, wxLB_SINGLE);
555
556 sizer->Add(m_SearchText, 0, wxEXPAND | wxALL, 10);
557 sizer->Add(m_SearchChoice, 0, wxEXPAND | wxLEFT | wxRIGHT | wxBOTTOM, 10);
558 sizer->Add(m_SearchCaseSensitive, 0, wxLEFT | wxRIGHT, 10);
559 sizer->Add(m_SearchWholeWords, 0, wxLEFT | wxRIGHT, 10);
560 sizer->Add(m_SearchButton, 0, wxALL | wxALIGN_RIGHT, 8);
561 sizer->Add(m_SearchList, 1, wxALL | wxEXPAND, 2);
562
563 m_NavigNotebook->AddPage(dummy, _("Search"));
564 m_SearchPage = notebook_page;
565 }
566
567 m_HtmlWin->Show();
568
569 RefreshLists();
570
571 if ( navigSizer )
572 {
573 navigSizer->SetSizeHints(m_NavigPan);
574 m_NavigPan->Layout();
575 }
576
577 // showtime
578 if ( m_NavigPan && m_Splitter )
579 {
6738c472
JS
580 // The panel will have its own min size which the splitter
581 // should respect
582 //if (m_NavigPan)
583 // m_Splitter->SetMinimumPaneSize(m_NavigPan->GetBestSize().x);
584 //else
585 m_Splitter->SetMinimumPaneSize(20);
3755cfa6
JS
586
587 if ( m_Cfg.navig_on )
588 {
589 m_NavigPan->Show();
590 m_Splitter->SplitVertically(m_NavigPan, m_HtmlWin, m_Cfg.sashpos);
591 }
592 else
593 {
594 m_NavigPan->Show(false);
595 m_Splitter->Initialize(m_HtmlWin);
596 }
597 }
598
599 // Reduce flicker by updating the splitter pane sizes before the
600 // frame is shown
601 wxSizeEvent sizeEvent(GetSize(), GetId());
004867db 602 GetEventHandler()->ProcessEvent(sizeEvent);
3755cfa6
JS
603
604 if (m_Splitter)
605 m_Splitter->UpdateSize();
606
607 return true;
608}
609
610wxHtmlHelpWindow::~wxHtmlHelpWindow()
611{
664d1729
VS
612 if ( m_helpController )
613 m_helpController->SetHelpWindow(NULL);
614
3755cfa6
JS
615 delete m_mergedIndex;
616
617 // PopEventHandler(); // wxhtmlhelpcontroller (not any more!)
618 if (m_DataCreated)
619 delete m_Data;
620 if (m_NormalFonts) delete m_NormalFonts;
621 if (m_FixedFonts) delete m_FixedFonts;
622 if (m_PagesHash)
623 {
624 WX_CLEAR_HASH_TABLE(*m_PagesHash);
625 delete m_PagesHash;
626 }
627#if wxUSE_PRINTING_ARCHITECTURE
628 if (m_Printer) delete m_Printer;
629#endif
630}
631
632void wxHtmlHelpWindow::SetController(wxHtmlHelpController* controller)
633{
634 if (m_DataCreated)
635 delete m_Data;
636 m_helpController = controller;
637 m_Data = controller->GetHelpData();
638 m_DataCreated = false;
639}
640
641#if wxUSE_TOOLBAR
642void wxHtmlHelpWindow::AddToolbarButtons(wxToolBar *toolBar, int style)
643{
644 wxBitmap wpanelBitmap =
645 wxArtProvider::GetBitmap(wxART_HELP_SIDE_PANEL, wxART_TOOLBAR);
646 wxBitmap wbackBitmap =
647 wxArtProvider::GetBitmap(wxART_GO_BACK, wxART_TOOLBAR);
648 wxBitmap wforwardBitmap =
649 wxArtProvider::GetBitmap(wxART_GO_FORWARD, wxART_TOOLBAR);
650 wxBitmap wupnodeBitmap =
651 wxArtProvider::GetBitmap(wxART_GO_TO_PARENT, wxART_TOOLBAR);
652 wxBitmap wupBitmap =
653 wxArtProvider::GetBitmap(wxART_GO_UP, wxART_TOOLBAR);
654 wxBitmap wdownBitmap =
655 wxArtProvider::GetBitmap(wxART_GO_DOWN, wxART_TOOLBAR);
656 wxBitmap wopenBitmap =
657 wxArtProvider::GetBitmap(wxART_FILE_OPEN, wxART_TOOLBAR);
658 wxBitmap wprintBitmap =
659 wxArtProvider::GetBitmap(wxART_PRINT, wxART_TOOLBAR);
660 wxBitmap woptionsBitmap =
661 wxArtProvider::GetBitmap(wxART_HELP_SETTINGS, wxART_TOOLBAR);
662
a1b806b9
DS
663 wxASSERT_MSG( (wpanelBitmap.IsOk() && wbackBitmap.IsOk() &&
664 wforwardBitmap.IsOk() && wupnodeBitmap.IsOk() &&
665 wupBitmap.IsOk() && wdownBitmap.IsOk() &&
666 wopenBitmap.IsOk() && wprintBitmap.IsOk() &&
667 woptionsBitmap.IsOk()),
3755cfa6
JS
668 wxT("One or more HTML help frame toolbar bitmap could not be loaded.")) ;
669
670
bbe28fbb 671 toolBar->AddTool(wxID_HTML_PANEL, wxEmptyString, wpanelBitmap, _("Show/hide navigation panel"));
3755cfa6 672 toolBar->AddSeparator();
bbe28fbb
PC
673 toolBar->AddTool(wxID_HTML_BACK, wxEmptyString, wbackBitmap, _("Go back"));
674 toolBar->AddTool(wxID_HTML_FORWARD, wxEmptyString, wforwardBitmap, _("Go forward"));
3755cfa6 675 toolBar->AddSeparator();
bbe28fbb
PC
676 toolBar->AddTool(wxID_HTML_UPNODE, wxEmptyString, wupnodeBitmap, _("Go one level up in document hierarchy"));
677 toolBar->AddTool(wxID_HTML_UP, wxEmptyString, wupBitmap, _("Previous page"));
678 toolBar->AddTool(wxID_HTML_DOWN, wxEmptyString, wdownBitmap, _("Next page"));
3755cfa6
JS
679
680 if ((style & wxHF_PRINT) || (style & wxHF_OPEN_FILES))
681 toolBar->AddSeparator();
682
683 if (style & wxHF_OPEN_FILES)
bbe28fbb 684 toolBar->AddTool(wxID_HTML_OPENFILE, wxEmptyString, wopenBitmap, _("Open HTML document"));
3755cfa6
JS
685
686#if wxUSE_PRINTING_ARCHITECTURE
687 if (style & wxHF_PRINT)
bbe28fbb 688 toolBar->AddTool(wxID_HTML_PRINT, wxEmptyString, wprintBitmap, _("Print this page"));
3755cfa6
JS
689#endif
690
691 toolBar->AddSeparator();
bbe28fbb 692 toolBar->AddTool(wxID_HTML_OPTIONS, wxEmptyString, woptionsBitmap, _("Display options dialog"));
3755cfa6
JS
693
694 // Allow application to add custom buttons
695 wxHtmlHelpFrame* parentFrame = wxDynamicCast(GetParent(), wxHtmlHelpFrame);
696 wxHtmlHelpDialog* parentDialog = wxDynamicCast(GetParent(), wxHtmlHelpDialog);
697 if (parentFrame)
698 parentFrame->AddToolbarButtons(toolBar, style);
699 if (parentDialog)
700 parentDialog->AddToolbarButtons(toolBar, style);
701}
702#endif //wxUSE_TOOLBAR
703
704
705bool wxHtmlHelpWindow::Display(const wxString& x)
706{
707 wxString url = m_Data->FindPageByName(x);
708 if (!url.empty())
709 {
710 m_HtmlWin->LoadPage(url);
3755cfa6
JS
711 return true;
712 }
713
714 return false;
715}
716
717bool wxHtmlHelpWindow::Display(const int id)
718{
719 wxString url = m_Data->FindPageById(id);
720 if (!url.empty())
721 {
722 m_HtmlWin->LoadPage(url);
3755cfa6
JS
723 return true;
724 }
725
726 return false;
727}
728
729bool wxHtmlHelpWindow::DisplayContents()
730{
731 if (! m_ContentsBox)
732 return false;
733
734 if (!m_Splitter->IsSplit())
735 {
736 m_NavigPan->Show();
737 m_HtmlWin->Show();
738 m_Splitter->SplitVertically(m_NavigPan, m_HtmlWin, m_Cfg.sashpos);
739 m_Cfg.navig_on = true;
740 }
741
742 m_NavigNotebook->SetSelection(m_ContentsPage);
743
744 if (m_Data->GetBookRecArray().GetCount() > 0)
745 {
746 wxHtmlBookRecord& book = m_Data->GetBookRecArray()[0];
747 if (!book.GetStart().empty())
748 m_HtmlWin->LoadPage(book.GetFullPath(book.GetStart()));
749 }
750
751 return true;
752}
753
754bool wxHtmlHelpWindow::DisplayIndex()
755{
756 if (! m_IndexList)
757 return false;
758
759 if (!m_Splitter->IsSplit())
760 {
761 m_NavigPan->Show();
762 m_HtmlWin->Show();
763 m_Splitter->SplitVertically(m_NavigPan, m_HtmlWin, m_Cfg.sashpos);
764 }
765
766 m_NavigNotebook->SetSelection(m_IndexPage);
767
768 if (m_Data->GetBookRecArray().GetCount() > 0)
769 {
770 wxHtmlBookRecord& book = m_Data->GetBookRecArray()[0];
771 if (!book.GetStart().empty())
772 m_HtmlWin->LoadPage(book.GetFullPath(book.GetStart()));
773 }
774
775 return true;
776}
777
778void wxHtmlHelpWindow::DisplayIndexItem(const wxHtmlHelpMergedIndexItem *it)
779{
780 if (it->items.size() == 1)
781 {
782 if (!it->items[0]->page.empty())
783 {
784 m_HtmlWin->LoadPage(it->items[0]->GetFullPath());
3755cfa6
JS
785 }
786 }
787 else
788 {
789 wxBusyCursor busy_cursor;
790
791 // more pages associated with this index item -- let the user choose
792 // which one she/he wants from a list:
793 wxArrayString arr;
794 size_t len = it->items.size();
795 for (size_t i = 0; i < len; i++)
796 {
797 wxString page = it->items[i]->page;
798 // try to find page's title in contents:
799 const wxHtmlHelpDataItems& contents = m_Data->GetContentsArray();
800 size_t clen = contents.size();
801 for (size_t j = 0; j < clen; j++)
802 {
803 if (contents[j].page == page)
804 {
805 page = contents[j].name;
806 break;
807 }
808 }
809 arr.push_back(page);
810 }
811
812 wxSingleChoiceDialog dlg(this,
813 _("Please choose the page to display:"),
814 _("Help Topics"),
fc12b1f1
VZ
815 arr,
816 (void**)NULL, // No client data
817 wxCHOICEDLG_STYLE & ~wxCENTRE);
3755cfa6
JS
818 if (dlg.ShowModal() == wxID_OK)
819 {
820 m_HtmlWin->LoadPage(it->items[dlg.GetSelection()]->GetFullPath());
3755cfa6
JS
821 }
822 }
823}
824
825bool wxHtmlHelpWindow::KeywordSearch(const wxString& keyword,
826 wxHelpSearchMode mode)
827{
ed8c374d
VZ
828 wxCHECK_MSG( !keyword.empty(), false, "must have a non empty keyword" );
829
3755cfa6
JS
830 if (mode == wxHELP_SEARCH_ALL)
831 {
832 if ( !(m_SearchList &&
833 m_SearchButton && m_SearchText && m_SearchChoice) )
834 return false;
835 }
836 else if (mode == wxHELP_SEARCH_INDEX)
837 {
838 if ( !(m_IndexList &&
839 m_IndexButton && m_IndexButtonAll && m_IndexText) )
840 return false;
841 }
842
843 int foundcnt = 0;
844 wxString foundstr;
845 wxString book = wxEmptyString;
846
847 if (!m_Splitter->IsSplit())
848 {
849 m_NavigPan->Show();
850 m_HtmlWin->Show();
851 m_Splitter->SplitVertically(m_NavigPan, m_HtmlWin, m_Cfg.sashpos);
852 }
853
854 if (mode == wxHELP_SEARCH_ALL)
855 {
856 m_NavigNotebook->SetSelection(m_SearchPage);
857 m_SearchList->Clear();
858 m_SearchText->SetValue(keyword);
859 m_SearchButton->Disable();
860
861 if (m_SearchChoice->GetSelection() != 0)
862 book = m_SearchChoice->GetStringSelection();
863
864 wxHtmlSearchStatus status(m_Data, keyword,
865 m_SearchCaseSensitive->GetValue(),
866 m_SearchWholeWords->GetValue(),
867 book);
868
869#if wxUSE_PROGRESSDLG
870 wxProgressDialog progress(_("Searching..."),
871 _("No matching page found yet"),
872 status.GetMaxIndex(), this,
873 wxPD_APP_MODAL | wxPD_CAN_ABORT | wxPD_AUTO_HIDE);
874#endif
875
876 int curi;
877 while (status.IsActive())
878 {
879 curi = status.GetCurIndex();
880 if (curi % 32 == 0
881#if wxUSE_PROGRESSDLG
882 && !progress.Update(curi)
883#endif
884 )
885 break;
886 if (status.Search())
887 {
888 foundstr.Printf(_("Found %i matches"), ++foundcnt);
889#if wxUSE_PROGRESSDLG
890 progress.Update(status.GetCurIndex(), foundstr);
891#endif
892 m_SearchList->Append(status.GetName(), (void*)status.GetCurItem());
893 }
894 }
895
896 m_SearchButton->Enable();
548b5377 897 m_SearchText->SetSelection(0, keyword.length());
3755cfa6
JS
898 m_SearchText->SetFocus();
899 }
900 else if (mode == wxHELP_SEARCH_INDEX)
901 {
902 m_NavigNotebook->SetSelection(m_IndexPage);
903 m_IndexList->Clear();
904 m_IndexButton->Disable();
905 m_IndexButtonAll->Disable();
906 m_IndexText->SetValue(keyword);
907
548b5377 908 DoIndexFind();
3755cfa6
JS
909 m_IndexButton->Enable();
910 m_IndexButtonAll->Enable();
911 foundcnt = m_IndexList->GetCount();
912 }
913
914 if (foundcnt)
915 {
916 switch ( mode )
917 {
918 default:
9a83f860 919 wxFAIL_MSG( wxT("unknown help search mode") );
3755cfa6
JS
920 // fall back
921
922 case wxHELP_SEARCH_ALL:
923 {
924 wxHtmlHelpDataItem *it =
925 (wxHtmlHelpDataItem*) m_SearchList->GetClientData(0);
926 if (it)
927 {
928 m_HtmlWin->LoadPage(it->GetFullPath());
3755cfa6
JS
929 }
930 break;
931 }
932
933 case wxHELP_SEARCH_INDEX:
934 {
935 wxHtmlHelpMergedIndexItem* it =
936 (wxHtmlHelpMergedIndexItem*) m_IndexList->GetClientData(0);
937 if (it)
938 DisplayIndexItem(it);
939 break;
940 }
941 }
942
943 }
944
945 return foundcnt > 0;
946}
947
948void wxHtmlHelpWindow::CreateContents()
949{
950 if (! m_ContentsBox)
951 return ;
952
953 if (m_PagesHash)
954 {
955 WX_CLEAR_HASH_TABLE(*m_PagesHash);
956 delete m_PagesHash;
957 }
958
959 const wxHtmlHelpDataItems& contents = m_Data->GetContentsArray();
960
961 size_t cnt = contents.size();
962
963 m_PagesHash = new wxHashTable(wxKEY_STRING, 2 * cnt);
964
965 const int MAX_ROOTS = 64;
966 wxTreeItemId roots[MAX_ROOTS];
967 // VS: this array holds information about whether we've set item icon at
968 // given level. This is necessary because m_Data has a flat structure
969 // and there's no way of recognizing if some item has subitems or not.
970 // We set the icon later: when we find an item with level=n, we know
971 // that the last item with level=n-1 was afolder with subitems, so we
972 // set its icon accordingly
973 bool imaged[MAX_ROOTS];
974 m_ContentsBox->DeleteAllItems();
975
976 roots[0] = m_ContentsBox->AddRoot(_("(Help)"));
977 imaged[0] = true;
978
979 for (size_t i = 0; i < cnt; i++)
980 {
981 wxHtmlHelpDataItem *it = &contents[i];
982 // Handle books:
983 if (it->level == 0)
984 {
985 if (m_hfStyle & wxHF_MERGE_BOOKS)
986 // VS: we don't want book nodes, books' content should
987 // appear under tree's root. This line will create a "fake"
988 // record about book node so that the rest of this look
989 // will believe there really _is_ a book node and will
990 // behave correctly.
991 roots[1] = roots[0];
992 else
993 {
994 roots[1] = m_ContentsBox->AppendItem(roots[0],
995 it->name, IMG_Book, -1,
996 new wxHtmlHelpTreeItemData(i));
997 m_ContentsBox->SetItemBold(roots[1], true);
998 }
999 imaged[1] = true;
1000 }
1001 // ...and their contents:
1002 else
1003 {
1004 roots[it->level + 1] = m_ContentsBox->AppendItem(
1005 roots[it->level], it->name, IMG_Page,
1006 -1, new wxHtmlHelpTreeItemData(i));
1007 imaged[it->level + 1] = false;
1008 }
1009
1010 m_PagesHash->Put(it->GetFullPath(),
1011 new wxHtmlHelpHashData(i, roots[it->level + 1]));
1012
1013 // Set the icon for the node one level up in the hierarchy,
1014 // unless already done (see comment above imaged[] declaration)
1015 if (!imaged[it->level])
1016 {
1017 int image = IMG_Folder;
1018 if (m_hfStyle & wxHF_ICONS_BOOK)
1019 image = IMG_Book;
1020 else if (m_hfStyle & wxHF_ICONS_BOOK_CHAPTER)
1021 image = (it->level == 1) ? IMG_Book : IMG_Folder;
1022 m_ContentsBox->SetItemImage(roots[it->level], image);
1023 m_ContentsBox->SetItemImage(roots[it->level], image,
1024 wxTreeItemIcon_Selected);
1025 imaged[it->level] = true;
1026 }
1027 }
a55602fa
VZ
1028
1029 m_ContentsBox->SetMinSize(wxSize(CONTENT_TREE_INDEX_MIN_WIDTH,
1030 m_ContentsBox->GetMinHeight()));
3755cfa6
JS
1031}
1032
1033void wxHtmlHelpWindow::CreateIndex()
1034{
1035 if (! m_IndexList)
1036 return ;
1037
1038 m_IndexList->Clear();
1039
34a14142 1040 unsigned long cnt = m_mergedIndex->size();
3755cfa6
JS
1041
1042 wxString cnttext;
1043 if (cnt > INDEX_IS_SMALL)
34a14142 1044 cnttext.Printf(_("%d of %lu"), 0, cnt);
3755cfa6 1045 else
34a14142 1046 cnttext.Printf(_("%lu of %lu"), cnt, cnt);
3755cfa6
JS
1047 m_IndexCountInfo->SetLabel(cnttext);
1048 if (cnt > INDEX_IS_SMALL)
1049 return;
1050
1051 for (size_t i = 0; i < cnt; i++)
1052 m_IndexList->Append((*m_mergedIndex)[i].name,
1053 (char*)(&(*m_mergedIndex)[i]));
a55602fa
VZ
1054
1055 m_IndexList->SetMinSize(wxSize(CONTENT_TREE_INDEX_MIN_WIDTH,
1056 m_IndexList->GetMinHeight()));
3755cfa6
JS
1057}
1058
1059void wxHtmlHelpWindow::CreateSearch()
1060{
1061 if (! (m_SearchList && m_SearchChoice))
1062 return ;
1063 m_SearchList->Clear();
1064 m_SearchChoice->Clear();
1065 m_SearchChoice->Append(_("Search in all books"));
1066 const wxHtmlBookRecArray& bookrec = m_Data->GetBookRecArray();
1067 int i, cnt = bookrec.GetCount();
1068 for (i = 0; i < cnt; i++)
1069 m_SearchChoice->Append(bookrec[i].GetTitle());
1070 m_SearchChoice->SetSelection(0);
1071}
1072
1073void wxHtmlHelpWindow::RefreshLists()
1074{
1075 // Update m_mergedIndex:
1076 UpdateMergedIndex();
1077 // Update the controls
1078 CreateContents();
1079 CreateIndex();
1080 CreateSearch();
1081}
1082
b4246849 1083#if wxUSE_CONFIG
3755cfa6
JS
1084void wxHtmlHelpWindow::ReadCustomization(wxConfigBase *cfg, const wxString& path)
1085{
1086 wxString oldpath;
1087 wxString tmp;
1088
1089 if (path != wxEmptyString)
1090 {
1091 oldpath = cfg->GetPath();
9a83f860 1092 cfg->SetPath(wxT("/") + path);
3755cfa6
JS
1093 }
1094
1095 m_Cfg.navig_on = cfg->Read(wxT("hcNavigPanel"), m_Cfg.navig_on) != 0;
1096 m_Cfg.sashpos = cfg->Read(wxT("hcSashPos"), m_Cfg.sashpos);
1097 m_Cfg.x = cfg->Read(wxT("hcX"), m_Cfg.x);
1098 m_Cfg.y = cfg->Read(wxT("hcY"), m_Cfg.y);
1099 m_Cfg.w = cfg->Read(wxT("hcW"), m_Cfg.w);
1100 m_Cfg.h = cfg->Read(wxT("hcH"), m_Cfg.h);
1101
1102 m_FixedFace = cfg->Read(wxT("hcFixedFace"), m_FixedFace);
1103 m_NormalFace = cfg->Read(wxT("hcNormalFace"), m_NormalFace);
1104 m_FontSize = cfg->Read(wxT("hcBaseFontSize"), m_FontSize);
1105
1106 {
1107 int i;
1108 int cnt;
1109 wxString val, s;
1110
1111 cnt = cfg->Read(wxT("hcBookmarksCnt"), 0L);
1112 if (cnt != 0)
1113 {
1114 m_BookmarksNames.Clear();
1115 m_BookmarksPages.Clear();
1116 if (m_Bookmarks)
1117 {
1118 m_Bookmarks->Clear();
1119 m_Bookmarks->Append(_("(bookmarks)"));
1120 }
1121
1122 for (i = 0; i < cnt; i++)
1123 {
1124 val.Printf(wxT("hcBookmark_%i"), i);
1125 s = cfg->Read(val);
1126 m_BookmarksNames.Add(s);
1127 if (m_Bookmarks) m_Bookmarks->Append(s);
1128 val.Printf(wxT("hcBookmark_%i_url"), i);
1129 s = cfg->Read(val);
1130 m_BookmarksPages.Add(s);
1131 }
1132 }
1133 }
1134
1135 if (m_HtmlWin)
1136 m_HtmlWin->ReadCustomization(cfg);
1137
1138 if (path != wxEmptyString)
1139 cfg->SetPath(oldpath);
1140}
1141
1142void wxHtmlHelpWindow::WriteCustomization(wxConfigBase *cfg, const wxString& path)
1143{
1144 wxString oldpath;
1145 wxString tmp;
1146
1147 if (path != wxEmptyString)
1148 {
1149 oldpath = cfg->GetPath();
9a83f860 1150 cfg->SetPath(wxT("/") + path);
3755cfa6
JS
1151 }
1152
1153 cfg->Write(wxT("hcNavigPanel"), m_Cfg.navig_on);
1154 cfg->Write(wxT("hcSashPos"), (long)m_Cfg.sashpos);
1155
1156 // Don't write if iconized as this would make the window
1157 // disappear next time it is shown!
1158 cfg->Write(wxT("hcX"), (long)m_Cfg.x);
1159 cfg->Write(wxT("hcY"), (long)m_Cfg.y);
1160 cfg->Write(wxT("hcW"), (long)m_Cfg.w);
1161 cfg->Write(wxT("hcH"), (long)m_Cfg.h);
1162
1163 cfg->Write(wxT("hcFixedFace"), m_FixedFace);
1164 cfg->Write(wxT("hcNormalFace"), m_NormalFace);
1165 cfg->Write(wxT("hcBaseFontSize"), (long)m_FontSize);
1166
1167 if (m_Bookmarks)
1168 {
1169 int i;
1170 int cnt = m_BookmarksNames.GetCount();
1171 wxString val;
1172
1173 cfg->Write(wxT("hcBookmarksCnt"), (long)cnt);
1174 for (i = 0; i < cnt; i++)
1175 {
1176 val.Printf(wxT("hcBookmark_%i"), i);
1177 cfg->Write(val, m_BookmarksNames[i]);
1178 val.Printf(wxT("hcBookmark_%i_url"), i);
1179 cfg->Write(val, m_BookmarksPages[i]);
1180 }
1181 }
1182
1183 if (m_HtmlWin)
1184 m_HtmlWin->WriteCustomization(cfg);
1185
1186 if (path != wxEmptyString)
1187 cfg->SetPath(oldpath);
1188}
b4246849 1189#endif // wxUSE_CONFIG
3755cfa6
JS
1190
1191static void SetFontsToHtmlWin(wxHtmlWindow *win, const wxString& scalf, const wxString& fixf, int size)
1192{
1193 int f_sizes[7];
1194 f_sizes[0] = int(size * 0.6);
1195 f_sizes[1] = int(size * 0.8);
1196 f_sizes[2] = size;
1197 f_sizes[3] = int(size * 1.2);
1198 f_sizes[4] = int(size * 1.4);
1199 f_sizes[5] = int(size * 1.6);
1200 f_sizes[6] = int(size * 1.8);
1201
1202 win->SetFonts(scalf, fixf, f_sizes);
1203}
1204
1205class wxHtmlHelpWindowOptionsDialog : public wxDialog
1206{
1207public:
1208 wxComboBox *NormalFont, *FixedFont;
1209 wxSpinCtrl *FontSize;
1210 wxHtmlWindow *TestWin;
1211
1212 wxHtmlHelpWindowOptionsDialog(wxWindow *parent)
1213 : wxDialog(parent, wxID_ANY, wxString(_("Help Browser Options")))
1214 {
1215 wxBoxSizer *topsizer = new wxBoxSizer(wxVERTICAL);
1216 wxFlexGridSizer *sizer = new wxFlexGridSizer(2, 3, 2, 5);
1217
1218 sizer->Add(new wxStaticText(this, wxID_ANY, _("Normal font:")));
1219 sizer->Add(new wxStaticText(this, wxID_ANY, _("Fixed font:")));
1220 sizer->Add(new wxStaticText(this, wxID_ANY, _("Font size:")));
1221
1222 sizer->Add(NormalFont = new wxComboBox(this, wxID_ANY, wxEmptyString, wxDefaultPosition,
1223 wxSize(200, wxDefaultCoord),
1224 0, NULL, wxCB_DROPDOWN | wxCB_READONLY));
1225
1226 sizer->Add(FixedFont = new wxComboBox(this, wxID_ANY, wxEmptyString, wxDefaultPosition,
1227 wxSize(200, wxDefaultCoord),
1228 0, NULL, wxCB_DROPDOWN | wxCB_READONLY));
1229
50415ad7 1230 sizer->Add(FontSize = new wxSpinCtrl(this, wxID_ANY, wxEmptyString, wxDefaultPosition,
9a83f860 1231 wxDefaultSize, wxSP_ARROW_KEYS, 2, 100, 2, wxT("wxSpinCtrl")));
3755cfa6
JS
1232
1233 topsizer->Add(sizer, 0, wxLEFT|wxRIGHT|wxTOP, 10);
1234
1235 topsizer->Add(new wxStaticText(this, wxID_ANY, _("Preview:")),
1236 0, wxLEFT | wxTOP, 10);
6e47d216
JS
1237
1238 topsizer->AddSpacer(5);
1239
3755cfa6 1240 topsizer->Add(TestWin = new wxHtmlWindow(this, wxID_ANY, wxDefaultPosition, wxSize(20, 150),
6e47d216
JS
1241 wxHW_SCROLLBAR_AUTO|wxBORDER_THEME),
1242 1, wxEXPAND | wxLEFT | wxRIGHT, 10);
3755cfa6
JS
1243
1244 wxBoxSizer *sizer2 = new wxBoxSizer(wxHORIZONTAL);
1245 wxButton *ok;
1246 sizer2->Add(ok = new wxButton(this, wxID_OK), 0, wxALL, 10);
1247 ok->SetDefault();
1248 sizer2->Add(new wxButton(this, wxID_CANCEL), 0, wxALL, 10);
1249 topsizer->Add(sizer2, 0, wxALIGN_RIGHT);
1250
1251 SetSizer(topsizer);
1252 topsizer->Fit(this);
1253 Centre(wxBOTH);
1254 }
1255
1256
1257 void UpdateTestWin()
1258 {
1259 wxBusyCursor bcur;
1260 SetFontsToHtmlWin(TestWin,
1261 NormalFont->GetStringSelection(),
1262 FixedFont->GetStringSelection(),
1263 FontSize->GetValue());
1264
1265 wxString content(_("font size"));
1266
9a83f860
VZ
1267 content = wxT("<font size=-2>") + content + wxT(" -2</font><br>")
1268 wxT("<font size=-1>") + content + wxT(" -1</font><br>")
1269 wxT("<font size=+0>") + content + wxT(" +0</font><br>")
1270 wxT("<font size=+1>") + content + wxT(" +1</font><br>")
1271 wxT("<font size=+2>") + content + wxT(" +2</font><br>")
1272 wxT("<font size=+3>") + content + wxT(" +3</font><br>")
1273 wxT("<font size=+4>") + content + wxT(" +4</font><br>") ;
3755cfa6 1274
9a83f860 1275 content = wxString( wxT("<html><body><table><tr><td>") ) +
3755cfa6
JS
1276 _("Normal face<br>and <u>underlined</u>. ") +
1277 _("<i>Italic face.</i> ") +
1278 _("<b>Bold face.</b> ") +
1279 _("<b><i>Bold italic face.</i></b><br>") +
1280 content +
9a83f860 1281 wxString( wxT("</td><td><tt>") ) +
3755cfa6
JS
1282 _("Fixed size face.<br> <b>bold</b> <i>italic</i> ") +
1283 _("<b><i>bold italic <u>underlined</u></i></b><br>") +
1284 content +
9a83f860 1285 wxT("</tt></td></tr></table></body></html>");
3755cfa6
JS
1286
1287 TestWin->SetPage( content );
1288 }
1289
1290 void OnUpdate(wxCommandEvent& WXUNUSED(event))
1291 {
1292 UpdateTestWin();
1293 }
1294 void OnUpdateSpin(wxSpinEvent& WXUNUSED(event))
1295 {
1296 UpdateTestWin();
1297 }
1298
1299 DECLARE_EVENT_TABLE()
c0c133e1 1300 wxDECLARE_NO_COPY_CLASS(wxHtmlHelpWindowOptionsDialog);
3755cfa6
JS
1301};
1302
1303BEGIN_EVENT_TABLE(wxHtmlHelpWindowOptionsDialog, wxDialog)
1304 EVT_COMBOBOX(wxID_ANY, wxHtmlHelpWindowOptionsDialog::OnUpdate)
1305 EVT_SPINCTRL(wxID_ANY, wxHtmlHelpWindowOptionsDialog::OnUpdateSpin)
1306END_EVENT_TABLE()
1307
1308void wxHtmlHelpWindow::OptionsDialog()
1309{
1310 wxHtmlHelpWindowOptionsDialog dlg(this);
1311 unsigned i;
1312
1313 if (m_NormalFonts == NULL)
1314 {
6540132f 1315 m_NormalFonts = new wxArrayString(wxFontEnumerator::GetFacenames());
3755cfa6
JS
1316 m_NormalFonts->Sort(); // ascending sort
1317 }
1318 if (m_FixedFonts == NULL)
1319 {
6540132f
VZ
1320 m_FixedFonts = new wxArrayString(
1321 wxFontEnumerator::GetFacenames(wxFONTENCODING_SYSTEM,
1322 true /*enum fixed width only*/));
3755cfa6
JS
1323 m_FixedFonts->Sort(); // ascending sort
1324 }
1325
1326 // VS: We want to show the font that is actually used by wxHtmlWindow.
1327 // If customization dialog wasn't used yet, facenames are empty and
1328 // wxHtmlWindow uses default fonts -- let's find out what they
1329 // are so that we can pass them to the dialog:
1330 if (m_NormalFace.empty())
1331 {
1332 wxFont fnt(m_FontSize, wxSWISS, wxNORMAL, wxNORMAL, false);
1333 m_NormalFace = fnt.GetFaceName();
1334 }
1335 if (m_FixedFace.empty())
1336 {
1337 wxFont fnt(m_FontSize, wxMODERN, wxNORMAL, wxNORMAL, false);
1338 m_FixedFace = fnt.GetFaceName();
1339 }
1340
1341 for (i = 0; i < m_NormalFonts->GetCount(); i++)
1342 dlg.NormalFont->Append((*m_NormalFonts)[i]);
1343 for (i = 0; i < m_FixedFonts->GetCount(); i++)
1344 dlg.FixedFont->Append((*m_FixedFonts)[i]);
1345 if (!m_NormalFace.empty())
1346 dlg.NormalFont->SetStringSelection(m_NormalFace);
1347 else
1348 dlg.NormalFont->SetSelection(0);
1349 if (!m_FixedFace.empty())
1350 dlg.FixedFont->SetStringSelection(m_FixedFace);
1351 else
1352 dlg.FixedFont->SetSelection(0);
1353 dlg.FontSize->SetValue(m_FontSize);
1354 dlg.UpdateTestWin();
1355
1356 if (dlg.ShowModal() == wxID_OK)
1357 {
1358 m_NormalFace = dlg.NormalFont->GetStringSelection();
1359 m_FixedFace = dlg.FixedFont->GetStringSelection();
1360 m_FontSize = dlg.FontSize->GetValue();
1361 SetFontsToHtmlWin(m_HtmlWin, m_NormalFace, m_FixedFace, m_FontSize);
1362 }
1363}
1364
1365void wxHtmlHelpWindow::NotifyPageChanged()
1366{
1367 if (m_UpdateContents && m_PagesHash)
1368 {
1369 wxString page = wxHtmlHelpHtmlWindow::GetOpenedPageWithAnchor(m_HtmlWin);
1370 wxHtmlHelpHashData *ha = NULL;
1371 if (!page.empty())
1372 ha = (wxHtmlHelpHashData*) m_PagesHash->Get(page);
1373
1374 if (ha)
1375 {
1376 bool olduc = m_UpdateContents;
1377 m_UpdateContents = false;
1378 m_ContentsBox->SelectItem(ha->m_Id);
1379 m_ContentsBox->EnsureVisible(ha->m_Id);
1380 m_UpdateContents = olduc;
1381 }
1382 }
1383}
1384
1385/*
1386EVENT HANDLING :
1387*/
1388
1389
1390void wxHtmlHelpWindow::OnToolbar(wxCommandEvent& event)
1391{
1392 switch (event.GetId())
1393 {
1394 case wxID_HTML_BACK :
1395 m_HtmlWin->HistoryBack();
3755cfa6
JS
1396 break;
1397
1398 case wxID_HTML_FORWARD :
1399 m_HtmlWin->HistoryForward();
3755cfa6
JS
1400 break;
1401
1402 case wxID_HTML_UP :
1403 if (m_PagesHash)
1404 {
1405 wxString page = wxHtmlHelpHtmlWindow::GetOpenedPageWithAnchor(m_HtmlWin);
1406 wxHtmlHelpHashData *ha = NULL;
1407 if (!page.empty())
1408 ha = (wxHtmlHelpHashData*) m_PagesHash->Get(page);
1409 if (ha && ha->m_Index > 0)
1410 {
1411 const wxHtmlHelpDataItem& it = m_Data->GetContentsArray()[ha->m_Index - 1];
1412 if (!it.page.empty())
1413 {
1414 m_HtmlWin->LoadPage(it.GetFullPath());
3755cfa6
JS
1415 }
1416 }
1417 }
1418 break;
1419
1420 case wxID_HTML_UPNODE :
1421 if (m_PagesHash)
1422 {
1423 wxString page = wxHtmlHelpHtmlWindow::GetOpenedPageWithAnchor(m_HtmlWin);
1424 wxHtmlHelpHashData *ha = NULL;
1425 if (!page.empty())
1426 ha = (wxHtmlHelpHashData*) m_PagesHash->Get(page);
1427 if (ha && ha->m_Index > 0)
1428 {
1429 int level =
1430 m_Data->GetContentsArray()[ha->m_Index].level - 1;
1431 int ind = ha->m_Index - 1;
1432
1433 const wxHtmlHelpDataItem *it =
1434 &m_Data->GetContentsArray()[ind];
1435 while (ind >= 0 && it->level != level)
1436 {
1437 ind--;
1438 it = &m_Data->GetContentsArray()[ind];
1439 }
1440 if (ind >= 0)
1441 {
1442 if (!it->page.empty())
3755cfa6 1443 m_HtmlWin->LoadPage(it->GetFullPath());
3755cfa6
JS
1444 }
1445 }
1446 }
1447 break;
1448
1449 case wxID_HTML_DOWN :
1450 if (m_PagesHash)
1451 {
1452 wxString page = wxHtmlHelpHtmlWindow::GetOpenedPageWithAnchor(m_HtmlWin);
1453 wxHtmlHelpHashData *ha = NULL;
1454 if (!page.empty())
1455 ha = (wxHtmlHelpHashData*) m_PagesHash->Get(page);
1456
1457 const wxHtmlHelpDataItems& contents = m_Data->GetContentsArray();
1458 if (ha && ha->m_Index < (int)contents.size() - 1)
1459 {
1460 size_t idx = ha->m_Index + 1;
1461
1462 while (contents[idx].GetFullPath() == page) idx++;
1463
1464 if (!contents[idx].page.empty())
3755cfa6 1465 m_HtmlWin->LoadPage(contents[idx].GetFullPath());
3755cfa6
JS
1466 }
1467 }
1468 break;
1469
1470 case wxID_HTML_PANEL :
1471 {
1472 if (! (m_Splitter && m_NavigPan))
1473 return ;
1474 if (m_Splitter->IsSplit())
1475 {
1476 m_Cfg.sashpos = m_Splitter->GetSashPosition();
1477 m_Splitter->Unsplit(m_NavigPan);
1478 m_Cfg.navig_on = false;
1479 }
1480 else
1481 {
1482 m_NavigPan->Show();
1483 m_HtmlWin->Show();
1484 m_Splitter->SplitVertically(m_NavigPan, m_HtmlWin, m_Cfg.sashpos);
1485 m_Cfg.navig_on = true;
1486 }
1487 }
1488 break;
1489
1490 case wxID_HTML_OPTIONS :
1491 OptionsDialog();
1492 break;
1493
1494 case wxID_HTML_BOOKMARKSADD :
1495 {
1496 wxString item;
1497 wxString url;
1498
1499 item = m_HtmlWin->GetOpenedPageTitle();
1500 url = m_HtmlWin->GetOpenedPage();
1501 if (item == wxEmptyString)
1502 item = url.AfterLast(wxT('/'));
1503 if (m_BookmarksPages.Index(url) == wxNOT_FOUND)
1504 {
1505 m_Bookmarks->Append(item);
1506 m_BookmarksNames.Add(item);
1507 m_BookmarksPages.Add(url);
1508 }
1509 }
1510 break;
1511
1512 case wxID_HTML_BOOKMARKSREMOVE :
1513 {
1514 wxString item;
1515 int pos;
1516
1517 item = m_Bookmarks->GetStringSelection();
1518 pos = m_BookmarksNames.Index(item);
1519 if (pos != wxNOT_FOUND)
1520 {
1521 m_BookmarksNames.RemoveAt(pos);
1522 m_BookmarksPages.RemoveAt(pos);
a8b9c344
WS
1523 pos = m_Bookmarks->GetSelection();
1524 wxASSERT_MSG( pos != wxNOT_FOUND , wxT("Unknown bookmark position") ) ;
1525 m_Bookmarks->Delete((unsigned int)pos);
3755cfa6
JS
1526 }
1527 }
1528 break;
1529
1530#if wxUSE_PRINTING_ARCHITECTURE
1531 case wxID_HTML_PRINT :
1532 {
1533 if (m_Printer == NULL)
1534 m_Printer = new wxHtmlEasyPrinting(_("Help Printing"), this);
1535 if (!m_HtmlWin->GetOpenedPage())
43b2d5e7 1536 {
3755cfa6 1537 wxLogWarning(_("Cannot print empty page."));
43b2d5e7 1538 }
3755cfa6 1539 else
43b2d5e7 1540 {
3755cfa6 1541 m_Printer->PrintFile(m_HtmlWin->GetOpenedPage());
43b2d5e7 1542 }
3755cfa6
JS
1543 }
1544 break;
1545#endif
1546
1547 case wxID_HTML_OPENFILE :
1548 {
1549 wxString filemask = wxString(
1550 _("HTML files (*.html;*.htm)|*.html;*.htm|")) +
1551 _("Help books (*.htb)|*.htb|Help books (*.zip)|*.zip|") +
1552 _("HTML Help Project (*.hhp)|*.hhp|") +
1553#if wxUSE_LIBMSPACK
1554 _("Compressed HTML Help file (*.chm)|*.chm|") +
1555#endif
b82f92a8 1556 wxALL_FILES;
3755cfa6
JS
1557 wxString s = wxFileSelector(_("Open HTML document"),
1558 wxEmptyString,
1559 wxEmptyString,
1560 wxEmptyString,
1561 filemask,
ff3e84ff 1562 wxFD_OPEN | wxFD_FILE_MUST_EXIST,
3755cfa6
JS
1563 this);
1564 if (!s.empty())
1565 {
1566 wxString ext = s.Right(4).Lower();
9a83f860 1567 if (ext == wxT(".zip") || ext == wxT(".htb") ||
3755cfa6 1568#if wxUSE_LIBMSPACK
9a83f860 1569 ext == wxT(".chm") ||
3755cfa6 1570#endif
9a83f860 1571 ext == wxT(".hhp"))
3755cfa6
JS
1572 {
1573 wxBusyCursor bcur;
1574 m_Data->AddBook(s);
1575 RefreshLists();
1576 }
1577 else
1578 m_HtmlWin->LoadPage(s);
1579 }
1580 }
1581 break;
1582 }
1583}
1584
1585void wxHtmlHelpWindow::OnContentsSel(wxTreeEvent& event)
1586{
1587 wxHtmlHelpTreeItemData *pg;
1588
1589 pg = (wxHtmlHelpTreeItemData*) m_ContentsBox->GetItemData(event.GetItem());
1590
1591 if (pg && m_UpdateContents)
1592 {
1593 const wxHtmlHelpDataItems& contents = m_Data->GetContentsArray();
1594 m_UpdateContents = false;
1595 if (!contents[pg->m_Id].page.empty())
1596 m_HtmlWin->LoadPage(contents[pg->m_Id].GetFullPath());
1597 m_UpdateContents = true;
1598 }
1599}
1600
1601void wxHtmlHelpWindow::OnIndexSel(wxCommandEvent& WXUNUSED(event))
1602{
1603 wxHtmlHelpMergedIndexItem *it = (wxHtmlHelpMergedIndexItem*)
1604 m_IndexList->GetClientData(m_IndexList->GetSelection());
1605 if (it)
1606 DisplayIndexItem(it);
1607}
1608
548b5377
WS
1609void wxHtmlHelpWindow::OnIndexFind(wxCommandEvent& WXUNUSED(event))
1610{
1611 DoIndexFind();
1612}
1613
1614void wxHtmlHelpWindow::DoIndexFind()
3755cfa6
JS
1615{
1616 wxString sr = m_IndexText->GetLineText(0);
1617 sr.MakeLower();
1618 if (sr == wxEmptyString)
1619 {
548b5377 1620 DoIndexAll();
3755cfa6
JS
1621 }
1622 else
1623 {
1624 wxBusyCursor bcur;
1625
1626 m_IndexList->Clear();
1627 const wxHtmlHelpMergedIndex& index = *m_mergedIndex;
1628 size_t cnt = index.size();
1629
1630 int displ = 0;
1631 for (size_t i = 0; i < cnt; i++)
1632 {
1633 if (index[i].name.Lower().find(sr) != wxString::npos)
1634 {
1635 int pos = m_IndexList->Append(index[i].name,
1636 (char*)(&index[i]));
1637
1638 if (displ++ == 0)
1639 {
1640 // don't automatically show topic selector if this
1641 // item points to multiple pages:
1642 if (index[i].items.size() == 1)
1643 {
1644 m_IndexList->SetSelection(0);
1645 DisplayIndexItem(&index[i]);
1646 }
1647 }
1648
1649 // if this is nested item of the index, show its parent(s)
1650 // as well, otherwise it would not be clear what entry is
1651 // shown:
1652 wxHtmlHelpMergedIndexItem *parent = index[i].parent;
1653 while (parent)
1654 {
1655 if (pos == 0 ||
1656 (index.Index(*(wxHtmlHelpMergedIndexItem*)m_IndexList->GetClientData(pos-1))) < index.Index(*parent))
1657 {
1658 m_IndexList->Insert(parent->name,
1659 pos, (char*)parent);
1660 parent = parent->parent;
1661 }
1662 else break;
1663 }
1664
1665 // finally, it the item we just added is itself a parent for
1666 // other items, show them as well, because they are refinements
1667 // of the displayed index entry (i.e. it is implicitly contained
1668 // in them: "foo" with parent "bar" reads as "bar, foo"):
1669 int level = index[i].items[0]->level;
1670 i++;
1671 while (i < cnt && index[i].items[0]->level > level)
1672 {
1673 m_IndexList->Append(index[i].name, (char*)(&index[i]));
1674 i++;
1675 }
1676 i--;
1677 }
1678 }
1679
1680 wxString cnttext;
1681 cnttext.Printf(_("%i of %i"), displ, cnt);
1682 m_IndexCountInfo->SetLabel(cnttext);
1683
548b5377 1684 m_IndexText->SetSelection(0, sr.length());
3755cfa6
JS
1685 m_IndexText->SetFocus();
1686 }
1687}
1688
1689void wxHtmlHelpWindow::OnIndexAll(wxCommandEvent& WXUNUSED(event))
548b5377
WS
1690{
1691 DoIndexAll();
1692}
1693
1694void wxHtmlHelpWindow::DoIndexAll()
3755cfa6
JS
1695{
1696 wxBusyCursor bcur;
1697
1698 m_IndexList->Clear();
1699 const wxHtmlHelpMergedIndex& index = *m_mergedIndex;
1700 size_t cnt = index.size();
1701 bool first = true;
1702
1703 for (size_t i = 0; i < cnt; i++)
1704 {
1705 m_IndexList->Append(index[i].name, (char*)(&index[i]));
1706 if (first)
1707 {
1708 // don't automatically show topic selector if this
1709 // item points to multiple pages:
1710 if (index[i].items.size() == 1)
1711 {
1712 DisplayIndexItem(&index[i]);
1713 }
1714 first = false;
1715 }
1716 }
1717
1718 wxString cnttext;
1719 cnttext.Printf(_("%i of %i"), cnt, cnt);
1720 m_IndexCountInfo->SetLabel(cnttext);
1721}
1722
1723void wxHtmlHelpWindow::OnSearchSel(wxCommandEvent& WXUNUSED(event))
1724{
1725 wxHtmlHelpDataItem *it = (wxHtmlHelpDataItem*) m_SearchList->GetClientData(m_SearchList->GetSelection());
1726 if (it)
1727 {
1728 if (!it->page.empty())
1729 m_HtmlWin->LoadPage(it->GetFullPath());
3755cfa6
JS
1730 }
1731}
1732
1733void wxHtmlHelpWindow::OnSearch(wxCommandEvent& WXUNUSED(event))
1734{
1735 wxString sr = m_SearchText->GetLineText(0);
1736
1737 if (!sr.empty())
1738 KeywordSearch(sr, wxHELP_SEARCH_ALL);
1739}
1740
1741void wxHtmlHelpWindow::OnBookmarksSel(wxCommandEvent& WXUNUSED(event))
1742{
9f322c6d
WS
1743 wxString str = m_Bookmarks->GetStringSelection();
1744 int idx = m_BookmarksNames.Index(str);
1745 if (!str.empty() && str != _("(bookmarks)") && idx != wxNOT_FOUND)
3755cfa6 1746 {
9f322c6d 1747 m_HtmlWin->LoadPage(m_BookmarksPages[(size_t)idx]);
3755cfa6
JS
1748 }
1749}
1750
1751void wxHtmlHelpWindow::OnSize(wxSizeEvent& WXUNUSED(event))
1752{
1753 Layout();
1754}
1755
1756#endif // wxUSE_WXHTML_HELP