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