///////////////////////////////////////////////////////////////////////////// // Name: helpfrm.cpp // Purpose: wxHtmlHelpFrame // Notes: Based on htmlhelp.cpp, implementing a monolithic // HTML Help controller class, by Vaclav Slavik // Author: Harm van der Heijden and Vaclav Slavik // RCS-ID: $Id$ // Copyright: (c) Harm van der Heijden and Vaclav Slavik // Licence: wxWindows licence ///////////////////////////////////////////////////////////////////////////// #ifdef __GNUG__ #pragma implementation "helpfrm.h" #endif // For compilers that support precompilation, includes "wx.h" #include "wx/wxprec.h" #ifdef __BORLANDC__ #pragma hdrstop #endif #if wxUSE_WXHTML_HELP #ifndef WXPRECOMP #include "wx/intl.h" #include "wx/log.h" #include "wx/object.h" #include "wx/sizer.h" #include "wx/bmpbuttn.h" #include "wx/statbox.h" #include "wx/radiobox.h" #endif // WXPRECOMP #include "wx/html/helpfrm.h" #include "wx/html/helpctrl.h" #include "wx/textctrl.h" #include "wx/notebook.h" #include "wx/imaglist.h" #include "wx/treectrl.h" #include "wx/tokenzr.h" #include "wx/wfstream.h" #include "wx/html/htmlwin.h" #include "wx/busyinfo.h" #include "wx/progdlg.h" #include "wx/toolbar.h" #include "wx/fontenum.h" #include "wx/stream.h" #include "wx/filedlg.h" #include "wx/artprov.h" // what is considered "small index"? #define INDEX_IS_SMALL 100 /* Motif defines this as a macro */ #ifdef Below #undef Below #endif //-------------------------------------------------------------------------- // wxHtmlHelpTreeItemData (private) //-------------------------------------------------------------------------- class wxHtmlHelpTreeItemData : public wxTreeItemData { public: #if defined(__VISAGECPP__) // VA needs a default ctor for some reason.... wxHtmlHelpTreeItemData() : wxTreeItemData() { m_Id = 0; } #endif wxHtmlHelpTreeItemData(int id) : wxTreeItemData() { m_Id = id;} int m_Id; }; //-------------------------------------------------------------------------- // wxHtmlHelpHashData (private) //-------------------------------------------------------------------------- class wxHtmlHelpHashData : public wxObject { public: wxHtmlHelpHashData(int index, wxTreeItemId id) : wxObject() { m_Index = index; m_Id = id;} ~wxHtmlHelpHashData() {} int m_Index; wxTreeItemId m_Id; }; //-------------------------------------------------------------------------- // wxHtmlHelpHtmlWindow (private) //-------------------------------------------------------------------------- class wxHtmlHelpHtmlWindow : public wxHtmlWindow { public: wxHtmlHelpHtmlWindow(wxHtmlHelpFrame *fr, wxWindow *parent) : wxHtmlWindow(parent), m_Frame(fr) {} virtual void OnLinkClicked(const wxHtmlLinkInfo& link) { wxHtmlWindow::OnLinkClicked(link); m_Frame->NotifyPageChanged(); } private: wxHtmlHelpFrame *m_Frame; }; //--------------------------------------------------------------------------- // wxHtmlHelpFrame //--------------------------------------------------------------------------- // Command IDs : enum { //wxID_HTML_HELPFRAME = wxID_HIGHEST + 1, wxID_HTML_PANEL = wxID_HIGHEST + 2, wxID_HTML_BACK, wxID_HTML_FORWARD, wxID_HTML_UPNODE, wxID_HTML_UP, wxID_HTML_DOWN, wxID_HTML_PRINT, wxID_HTML_OPENFILE, wxID_HTML_OPTIONS, wxID_HTML_BOOKMARKSLIST, wxID_HTML_BOOKMARKSADD, wxID_HTML_BOOKMARKSREMOVE, wxID_HTML_TREECTRL, wxID_HTML_INDEXPAGE, wxID_HTML_INDEXLIST, wxID_HTML_INDEXTEXT, wxID_HTML_INDEXBUTTON, wxID_HTML_INDEXBUTTONALL, wxID_HTML_NOTEBOOK, wxID_HTML_SEARCHPAGE, wxID_HTML_SEARCHTEXT, wxID_HTML_SEARCHLIST, wxID_HTML_SEARCHBUTTON, wxID_HTML_SEARCHCHOICE, wxID_HTML_COUNTINFO }; IMPLEMENT_DYNAMIC_CLASS(wxHtmlHelpFrame, wxFrame) wxHtmlHelpFrame::wxHtmlHelpFrame(wxWindow* parent, wxWindowID id, const wxString& title, int style, wxHtmlHelpData* data) { Init(data); Create(parent, id, title, style); } void wxHtmlHelpFrame::Init(wxHtmlHelpData* data) { if (data) { m_Data = data; m_DataCreated = FALSE; } else { m_Data = new wxHtmlHelpData(); m_DataCreated = TRUE; } m_ContentsBox = NULL; m_IndexList = NULL; m_IndexButton = NULL; m_IndexButtonAll = NULL; m_IndexText = NULL; m_SearchList = NULL; m_SearchButton = NULL; m_SearchText = NULL; m_SearchChoice = NULL; m_IndexCountInfo = NULL; m_Splitter = NULL; m_NavigPan = NULL; m_NavigNotebook = NULL; m_HtmlWin = NULL; m_Bookmarks = NULL; m_SearchCaseSensitive = NULL; m_SearchWholeWords = NULL; m_Config = NULL; m_ConfigRoot = wxEmptyString; m_Cfg.x = m_Cfg.y = 0; m_Cfg.w = 700; m_Cfg.h = 480; m_Cfg.sashpos = 240; m_Cfg.navig_on = TRUE; m_NormalFonts = m_FixedFonts = NULL; m_NormalFace = m_FixedFace = wxEmptyString; m_FontSize = 1; #if wxUSE_PRINTING_ARCHITECTURE m_Printer = NULL; #endif m_PagesHash = NULL; m_UpdateContents = TRUE; m_helpController = (wxHelpControllerBase*) NULL; } // Create: builds the GUI components. // with the style flag it's possible to toggle the toolbar, contents, index and search // controls. // m_HtmlWin will *always* be created, but it's important to realize that // m_ContentsBox, m_IndexList, m_SearchList, m_SearchButton, m_SearchText and // m_SearchButton may be NULL. // moreover, if no contents, index or searchpage is needed, m_Splitter and // m_NavigPan will be NULL too (with m_HtmlWin directly connected to the frame) bool wxHtmlHelpFrame::Create(wxWindow* parent, wxWindowID id, const wxString& WXUNUSED(title), int style) { m_hfStyle = style; wxImageList *ContentsImageList = new wxImageList(16, 16); ContentsImageList->Add(wxArtProvider::GetIcon(wxART_HELP_BOOK, wxART_HELP_BROWSER)); ContentsImageList->Add(wxArtProvider::GetIcon(wxART_HELP_FOLDER, wxART_HELP_BROWSER)); ContentsImageList->Add(wxArtProvider::GetIcon(wxART_HELP_PAGE, wxART_HELP_BROWSER)); // Do the config in two steps. We read the HtmlWindow customization after we // create the window. if (m_Config) ReadCustomization(m_Config, m_ConfigRoot); wxFrame::Create(parent, id, _("Help"), wxPoint(m_Cfg.x, m_Cfg.y), wxSize(m_Cfg.w, m_Cfg.h), wxDEFAULT_FRAME_STYLE, wxT("wxHtmlHelp")); GetPosition(&m_Cfg.x, &m_Cfg.y); SetIcon(wxArtProvider::GetIcon(wxART_FRAME_ICON, wxART_HELP_BROWSER)); int notebook_page = 0; CreateStatusBar(); // toolbar? if (style & (wxHF_TOOLBAR | wxHF_FLAT_TOOLBAR)) { wxToolBar *toolBar = CreateToolBar(wxNO_BORDER | wxTB_HORIZONTAL | wxTB_DOCKABLE | (style & wxHF_FLAT_TOOLBAR ? wxTB_FLAT : 0)); toolBar->SetMargins( 2, 2 ); AddToolbarButtons(toolBar, style); toolBar->Realize(); } wxSizer *navigSizer = NULL; if (style & (wxHF_CONTENTS | wxHF_INDEX | wxHF_SEARCH)) { // traditional help controller; splitter window with html page on the // right and a notebook containing various pages on the left m_Splitter = new wxSplitterWindow(this); m_HtmlWin = new wxHtmlHelpHtmlWindow(this, m_Splitter); m_NavigPan = new wxPanel(m_Splitter, -1); m_NavigNotebook = new wxNotebook(m_NavigPan, wxID_HTML_NOTEBOOK, wxDefaultPosition, wxDefaultSize); wxNotebookSizer *nbs = new wxNotebookSizer(m_NavigNotebook); navigSizer = new wxBoxSizer(wxVERTICAL); navigSizer->Add(nbs, 1, wxEXPAND); m_NavigPan->SetAutoLayout(TRUE); m_NavigPan->SetSizer(navigSizer); } else { // only html window, no notebook with index,contents etc m_HtmlWin = new wxHtmlWindow(this); } m_HtmlWin->SetRelatedFrame(this, m_TitleFormat); m_HtmlWin->SetRelatedStatusBar(0); if ( m_Config ) m_HtmlWin->ReadCustomization(m_Config, m_ConfigRoot); // contents tree panel? if ( style & wxHF_CONTENTS ) { wxWindow *dummy = new wxPanel(m_NavigNotebook, wxID_HTML_INDEXPAGE); wxSizer *topsizer = new wxBoxSizer(wxVERTICAL); topsizer->Add(0, 10); dummy->SetAutoLayout(TRUE); dummy->SetSizer(topsizer); if ( style & wxHF_BOOKMARKS ) { m_Bookmarks = new wxComboBox(dummy, wxID_HTML_BOOKMARKSLIST, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0, NULL, wxCB_READONLY | wxCB_SORT); m_Bookmarks->Append(_("(bookmarks)")); for (unsigned i = 0; i < m_BookmarksNames.GetCount(); i++) m_Bookmarks->Append(m_BookmarksNames[i]); m_Bookmarks->SetSelection(0); wxBitmapButton *bmpbt1, *bmpbt2; bmpbt1 = new wxBitmapButton(dummy, wxID_HTML_BOOKMARKSADD, wxArtProvider::GetBitmap(wxART_ADD_BOOKMARK, wxART_HELP_BROWSER)); bmpbt2 = new wxBitmapButton(dummy, wxID_HTML_BOOKMARKSREMOVE, wxArtProvider::GetBitmap(wxART_DEL_BOOKMARK, wxART_HELP_BROWSER)); #if wxUSE_TOOLTIPS bmpbt1->SetToolTip(_("Add current page to bookmarks")); bmpbt2->SetToolTip(_("Remove current page from bookmarks")); #endif // wxUSE_TOOLTIPS wxSizer *sizer = new wxBoxSizer(wxHORIZONTAL); sizer->Add(m_Bookmarks, 1, wxALIGN_CENTRE_VERTICAL | wxRIGHT, 5); sizer->Add(bmpbt1, 0, wxALIGN_CENTRE_VERTICAL | wxRIGHT, 2); sizer->Add(bmpbt2, 0, wxALIGN_CENTRE_VERTICAL, 0); topsizer->Add(sizer, 0, wxEXPAND | wxLEFT | wxBOTTOM | wxRIGHT, 10); } m_ContentsBox = new wxTreeCtrl(dummy, wxID_HTML_TREECTRL, wxDefaultPosition, wxDefaultSize, wxSUNKEN_BORDER | wxTR_HAS_BUTTONS | wxTR_HIDE_ROOT | wxTR_LINES_AT_ROOT); m_ContentsBox->AssignImageList(ContentsImageList); topsizer->Add(m_ContentsBox, 1, wxEXPAND | wxLEFT | wxBOTTOM | wxRIGHT, 2); m_NavigNotebook->AddPage(dummy, _("Contents")); m_ContentsPage = notebook_page++; } // index listbox panel? if ( style & wxHF_INDEX ) { wxWindow *dummy = new wxPanel(m_NavigNotebook, wxID_HTML_INDEXPAGE); wxSizer *topsizer = new wxBoxSizer(wxVERTICAL); dummy->SetAutoLayout(TRUE); dummy->SetSizer(topsizer); m_IndexText = new wxTextCtrl(dummy, wxID_HTML_INDEXTEXT, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_PROCESS_ENTER); m_IndexButton = new wxButton(dummy, wxID_HTML_INDEXBUTTON, _("Find")); m_IndexButtonAll = new wxButton(dummy, wxID_HTML_INDEXBUTTONALL, _("Show all")); m_IndexCountInfo = new wxStaticText(dummy, wxID_HTML_COUNTINFO, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxALIGN_RIGHT | wxST_NO_AUTORESIZE); m_IndexList = new wxListBox(dummy, wxID_HTML_INDEXLIST, wxDefaultPosition, wxDefaultSize, 0, NULL, wxLB_SINGLE); #if wxUSE_TOOLTIPS m_IndexButton->SetToolTip(_("Display all index items that contain given substring. Search is case insensitive.")); m_IndexButtonAll->SetToolTip(_("Show all items in index")); #endif //wxUSE_TOOLTIPS topsizer->Add(m_IndexText, 0, wxEXPAND | wxALL, 10); wxSizer *btsizer = new wxBoxSizer(wxHORIZONTAL); btsizer->Add(m_IndexButton, 0, wxRIGHT, 2); btsizer->Add(m_IndexButtonAll); topsizer->Add(btsizer, 0, wxALIGN_RIGHT | wxLEFT | wxRIGHT | wxBOTTOM, 10); topsizer->Add(m_IndexCountInfo, 0, wxEXPAND | wxLEFT | wxRIGHT, 2); topsizer->Add(m_IndexList, 1, wxEXPAND | wxALL, 2); m_NavigNotebook->AddPage(dummy, _("Index")); m_IndexPage = notebook_page++; } // search list panel? if ( style & wxHF_SEARCH ) { wxWindow *dummy = new wxPanel(m_NavigNotebook, wxID_HTML_INDEXPAGE); wxSizer *sizer = new wxBoxSizer(wxVERTICAL); dummy->SetAutoLayout(TRUE); dummy->SetSizer(sizer); m_SearchText = new wxTextCtrl(dummy, wxID_HTML_SEARCHTEXT, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_PROCESS_ENTER); m_SearchChoice = new wxChoice(dummy, wxID_HTML_SEARCHCHOICE, wxDefaultPosition, wxDefaultSize); m_SearchCaseSensitive = new wxCheckBox(dummy, -1, _("Case sensitive")); m_SearchWholeWords = new wxCheckBox(dummy, -1, _("Whole words only")); m_SearchButton = new wxButton(dummy, wxID_HTML_SEARCHBUTTON, _("Search")); #if wxUSE_TOOLTIPS m_SearchButton->SetToolTip(_("Search contents of help book(s) for all occurences of the text you typed above")); #endif //wxUSE_TOOLTIPS m_SearchList = new wxListBox(dummy, wxID_HTML_SEARCHLIST, wxDefaultPosition, wxDefaultSize, 0, NULL, wxLB_SINGLE); sizer->Add(m_SearchText, 0, wxEXPAND | wxALL, 10); sizer->Add(m_SearchChoice, 0, wxEXPAND | wxLEFT | wxRIGHT | wxBOTTOM, 10); sizer->Add(m_SearchCaseSensitive, 0, wxLEFT | wxRIGHT, 10); sizer->Add(m_SearchWholeWords, 0, wxLEFT | wxRIGHT, 10); sizer->Add(m_SearchButton, 0, wxALL | wxALIGN_RIGHT, 8); sizer->Add(m_SearchList, 1, wxALL | wxEXPAND, 2); m_NavigNotebook->AddPage(dummy, _("Search")); m_SearchPage = notebook_page++; } m_HtmlWin->Show(TRUE); RefreshLists(); if ( navigSizer ) { navigSizer->SetSizeHints(m_NavigPan); m_NavigPan->Layout(); } // showtime if ( m_NavigPan && m_Splitter ) { m_Splitter->SetMinimumPaneSize(20); if ( m_Cfg.navig_on ) m_Splitter->SplitVertically(m_NavigPan, m_HtmlWin, m_Cfg.sashpos); if ( m_Cfg.navig_on ) { m_NavigPan->Show(TRUE); m_Splitter->SplitVertically(m_NavigPan, m_HtmlWin, m_Cfg.sashpos); } else { m_NavigPan->Show(FALSE); m_Splitter->Initialize(m_HtmlWin); } } return TRUE; } wxHtmlHelpFrame::~wxHtmlHelpFrame() { // PopEventHandler(); // wxhtmlhelpcontroller (not any more!) if (m_DataCreated) delete m_Data; if (m_NormalFonts) delete m_NormalFonts; if (m_FixedFonts) delete m_FixedFonts; if (m_PagesHash) delete m_PagesHash; } void wxHtmlHelpFrame::AddToolbarButtons(wxToolBar *toolBar, int style) { wxBitmap wpanelBitmap = wxArtProvider::GetBitmap(wxART_HELP_SIDE_PANEL, wxART_HELP_BROWSER); wxBitmap wbackBitmap = wxArtProvider::GetBitmap(wxART_GO_BACK, wxART_HELP_BROWSER); wxBitmap wforwardBitmap = wxArtProvider::GetBitmap(wxART_GO_FORWARD, wxART_HELP_BROWSER); wxBitmap wupnodeBitmap = wxArtProvider::GetBitmap(wxART_GO_TO_PARENT, wxART_HELP_BROWSER); wxBitmap wupBitmap = wxArtProvider::GetBitmap(wxART_GO_UP, wxART_HELP_BROWSER); wxBitmap wdownBitmap = wxArtProvider::GetBitmap(wxART_GO_DOWN, wxART_HELP_BROWSER); wxBitmap wopenBitmap = wxArtProvider::GetBitmap(wxART_FILE_OPEN, wxART_HELP_BROWSER); wxBitmap wprintBitmap = wxArtProvider::GetBitmap(wxART_PRINT, wxART_HELP_BROWSER); wxBitmap woptionsBitmap = wxArtProvider::GetBitmap(wxART_HELP_SETTINGS, wxART_HELP_BROWSER); wxASSERT_MSG( (wpanelBitmap.Ok() && wbackBitmap.Ok() && wforwardBitmap.Ok() && wupnodeBitmap.Ok() && wupBitmap.Ok() && wdownBitmap.Ok() && wopenBitmap.Ok() && wprintBitmap.Ok() && woptionsBitmap.Ok()), wxT("One or more HTML help frame toolbar bitmap could not be loaded.")) ; toolBar->AddTool(wxID_HTML_PANEL, wpanelBitmap, wxNullBitmap, FALSE, -1, -1, (wxObject *) NULL, _("Show/hide navigation panel")); toolBar->AddSeparator(); toolBar->AddTool(wxID_HTML_BACK, wbackBitmap, wxNullBitmap, FALSE, -1, -1, (wxObject *) NULL, _("Go back")); toolBar->AddTool(wxID_HTML_FORWARD, wforwardBitmap, wxNullBitmap, FALSE, -1, -1, (wxObject *) NULL, _("Go forward")); toolBar->AddSeparator(); toolBar->AddTool(wxID_HTML_UPNODE, wupnodeBitmap, wxNullBitmap, FALSE, -1, -1, (wxObject *) NULL, _("Go one level up in document hierarchy")); toolBar->AddTool(wxID_HTML_UP, wupBitmap, wxNullBitmap, FALSE, -1, -1, (wxObject *) NULL, _("Previous page")); toolBar->AddTool(wxID_HTML_DOWN, wdownBitmap, wxNullBitmap, FALSE, -1, -1, (wxObject *) NULL, _("Next page")); if ((style & wxHF_PRINT) || (style & wxHF_OPEN_FILES)) toolBar->AddSeparator(); if (style & wxHF_OPEN_FILES) toolBar->AddTool(wxID_HTML_OPENFILE, wopenBitmap, wxNullBitmap, FALSE, -1, -1, (wxObject *) NULL, _("Open HTML document")); #if wxUSE_PRINTING_ARCHITECTURE if (style & wxHF_PRINT) toolBar->AddTool(wxID_HTML_PRINT, wprintBitmap, wxNullBitmap, FALSE, -1, -1, (wxObject *) NULL, _("Print this page")); #endif toolBar->AddSeparator(); toolBar->AddTool(wxID_HTML_OPTIONS, woptionsBitmap, wxNullBitmap, FALSE, -1, -1, (wxObject *) NULL, _("Display options dialog")); } void wxHtmlHelpFrame::SetTitleFormat(const wxString& format) { if (m_HtmlWin) m_HtmlWin->SetRelatedFrame(this, format); m_TitleFormat = format; } bool wxHtmlHelpFrame::Display(const wxString& x) { wxString url = m_Data->FindPageByName(x); if (!url.IsEmpty()) { m_HtmlWin->LoadPage(url); NotifyPageChanged(); return TRUE; } return FALSE; } bool wxHtmlHelpFrame::Display(const int id) { wxString url = m_Data->FindPageById(id); if (!url.IsEmpty()) { m_HtmlWin->LoadPage(url); NotifyPageChanged(); return TRUE; } return FALSE; } bool wxHtmlHelpFrame::DisplayContents() { if (! m_ContentsBox) return FALSE; if (!m_Splitter->IsSplit()) { m_NavigPan->Show(TRUE); m_HtmlWin->Show(TRUE); m_Splitter->SplitVertically(m_NavigPan, m_HtmlWin, m_Cfg.sashpos); m_Cfg.navig_on = TRUE; } m_NavigNotebook->SetSelection(0); if (m_Data->GetBookRecArray().GetCount() > 0) { wxHtmlBookRecord& book = m_Data->GetBookRecArray()[0]; if (!book.GetStart().IsEmpty()) m_HtmlWin->LoadPage(book.GetFullPath(book.GetStart())); } return TRUE; } bool wxHtmlHelpFrame::DisplayIndex() { if (! m_IndexList) return FALSE; if (!m_Splitter->IsSplit()) { m_NavigPan->Show(TRUE); m_HtmlWin->Show(TRUE); m_Splitter->SplitVertically(m_NavigPan, m_HtmlWin, m_Cfg.sashpos); } m_NavigNotebook->SetSelection(1); if (m_Data->GetBookRecArray().GetCount() > 0) { wxHtmlBookRecord& book = m_Data->GetBookRecArray()[0]; if (!book.GetStart().IsEmpty()) m_HtmlWin->LoadPage(book.GetFullPath(book.GetStart())); } return TRUE; } bool wxHtmlHelpFrame::KeywordSearch(const wxString& keyword) { if (! (m_SearchList && m_SearchButton && m_SearchText && m_SearchChoice)) return FALSE; int foundcnt = 0, curi; wxString foundstr; wxString book = wxEmptyString; if (!m_Splitter->IsSplit()) { m_NavigPan->Show(TRUE); m_HtmlWin->Show(TRUE); m_Splitter->SplitVertically(m_NavigPan, m_HtmlWin, m_Cfg.sashpos); } m_NavigNotebook->SetSelection(m_SearchPage); m_SearchList->Clear(); m_SearchText->SetValue(keyword); m_SearchButton->Enable(FALSE); if (m_SearchChoice->GetSelection() != 0) book = m_SearchChoice->GetStringSelection(); wxHtmlSearchStatus status(m_Data, keyword, m_SearchCaseSensitive->GetValue(), m_SearchWholeWords->GetValue(), book); wxProgressDialog progress(_("Searching..."), _("No matching page found yet"), status.GetMaxIndex(), this, wxPD_APP_MODAL | wxPD_CAN_ABORT | wxPD_AUTO_HIDE); while (status.IsActive()) { curi = status.GetCurIndex(); if (curi % 32 == 0 && progress.Update(curi) == FALSE) break; if (status.Search()) { foundstr.Printf(_("Found %i matches"), ++foundcnt); progress.Update(status.GetCurIndex(), foundstr); m_SearchList->Append(status.GetName(), status.GetContentsItem()); } } m_SearchButton->Enable(TRUE); m_SearchText->SetSelection(0, keyword.Length()); m_SearchText->SetFocus(); if (foundcnt) { wxHtmlContentsItem *it = (wxHtmlContentsItem*) m_SearchList->GetClientData(0); if (it) { m_HtmlWin->LoadPage(it->GetFullPath()); NotifyPageChanged(); } } return (foundcnt > 0); } void wxHtmlHelpFrame::CreateContents() { if (! m_ContentsBox) return ; m_ContentsBox->Clear(); if (m_PagesHash) delete m_PagesHash; m_PagesHash = new wxHashTable(wxKEY_STRING, 2 * m_Data->GetContentsCnt()); m_PagesHash->DeleteContents(TRUE); int cnt = m_Data->GetContentsCnt(); int i; wxHtmlContentsItem *it; const int MAX_ROOTS = 64; wxTreeItemId roots[MAX_ROOTS]; // VS: this array holds information about whether we've set item icon at // given level. This is neccessary because m_Data has flat structure // and there's no way of recognizing if some item has subitems or not. // We set the icon later: when we find an item with level=n, we know // that the last item with level=n-1 was folder with subitems, so we // set its icon accordingly bool imaged[MAX_ROOTS]; m_ContentsBox->DeleteAllItems(); roots[0] = m_ContentsBox->AddRoot(_("(Help)")); imaged[0] = TRUE; for (it = m_Data->GetContents(), i = 0; i < cnt; i++, it++) { // Handle books: if (it->m_Level == 0) { if (m_hfStyle & wxHF_MERGE_BOOKS) // VS: we don't want book nodes, books' content should // appear under tree's root. This line will create "fake" // record about book node so that the rest of this look // will believe there really _is_ book node and will // behave correctly. roots[1] = roots[0]; else { roots[1] = m_ContentsBox->AppendItem(roots[0], it->m_Name, IMG_Book, -1, new wxHtmlHelpTreeItemData(i)); m_ContentsBox->SetItemBold(roots[1], TRUE); } imaged[1] = TRUE; } // ...and their contents: else { roots[it->m_Level + 1] = m_ContentsBox->AppendItem( roots[it->m_Level], it->m_Name, IMG_Page, -1, new wxHtmlHelpTreeItemData(i)); imaged[it->m_Level + 1] = FALSE; } m_PagesHash->Put(it->GetFullPath(), new wxHtmlHelpHashData(i, roots[it->m_Level + 1])); // Set the icon for the node one level up in the hiearachy, // unless already done (see comment above imaged[] declaration) if (!imaged[it->m_Level]) { int image = IMG_Folder; if (m_hfStyle & wxHF_ICONS_BOOK) image = IMG_Book; else if (m_hfStyle & wxHF_ICONS_BOOK_CHAPTER) image = (it->m_Level == 1) ? IMG_Book : IMG_Folder; m_ContentsBox->SetItemImage(roots[it->m_Level], image); m_ContentsBox->SetItemSelectedImage(roots[it->m_Level], image); imaged[it->m_Level] = TRUE; } } } void wxHtmlHelpFrame::CreateIndex() { if (! m_IndexList) return ; m_IndexList->Clear(); int cnt = m_Data->GetIndexCnt(); wxString cnttext; if (cnt > INDEX_IS_SMALL) cnttext.Printf(_("%i of %i"), 0, cnt); else cnttext.Printf(_("%i of %i"), cnt, cnt); m_IndexCountInfo->SetLabel(cnttext); if (cnt > INDEX_IS_SMALL) return; wxHtmlContentsItem* index = m_Data->GetIndex(); for (int i = 0; i < cnt; i++) m_IndexList->Append(index[i].m_Name, (char*)(index + i)); } void wxHtmlHelpFrame::CreateSearch() { if (! (m_SearchList && m_SearchChoice)) return ; m_SearchList->Clear(); m_SearchChoice->Clear(); m_SearchChoice->Append(_("Search in all books")); const wxHtmlBookRecArray& bookrec = m_Data->GetBookRecArray(); int i, cnt = bookrec.GetCount(); for (i = 0; i < cnt; i++) m_SearchChoice->Append(bookrec[i].GetTitle()); m_SearchChoice->SetSelection(0); } void wxHtmlHelpFrame::RefreshLists() { CreateContents(); CreateIndex(); CreateSearch(); } void wxHtmlHelpFrame::ReadCustomization(wxConfigBase *cfg, const wxString& path) { wxString oldpath; wxString tmp; if (path != wxEmptyString) { oldpath = cfg->GetPath(); cfg->SetPath(_T("/") + path); } m_Cfg.navig_on = cfg->Read(wxT("hcNavigPanel"), m_Cfg.navig_on) != 0; m_Cfg.sashpos = cfg->Read(wxT("hcSashPos"), m_Cfg.sashpos); m_Cfg.x = cfg->Read(wxT("hcX"), m_Cfg.x); m_Cfg.y = cfg->Read(wxT("hcY"), m_Cfg.y); m_Cfg.w = cfg->Read(wxT("hcW"), m_Cfg.w); m_Cfg.h = cfg->Read(wxT("hcH"), m_Cfg.h); m_FixedFace = cfg->Read(wxT("hcFixedFace"), m_FixedFace); m_NormalFace = cfg->Read(wxT("hcNormalFace"), m_NormalFace); m_FontSize = cfg->Read(wxT("hcFontSize"), m_FontSize); { int i; int cnt; wxString val, s; cnt = cfg->Read(wxT("hcBookmarksCnt"), 0L); if (cnt != 0) { m_BookmarksNames.Clear(); m_BookmarksPages.Clear(); if (m_Bookmarks) { m_Bookmarks->Clear(); m_Bookmarks->Append(_("(bookmarks)")); } for (i = 0; i < cnt; i++) { val.Printf(wxT("hcBookmark_%i"), i); s = cfg->Read(val); m_BookmarksNames.Add(s); if (m_Bookmarks) m_Bookmarks->Append(s); val.Printf(wxT("hcBookmark_%i_url"), i); s = cfg->Read(val); m_BookmarksPages.Add(s); } } } if (m_HtmlWin) m_HtmlWin->ReadCustomization(cfg); if (path != wxEmptyString) cfg->SetPath(oldpath); } void wxHtmlHelpFrame::WriteCustomization(wxConfigBase *cfg, const wxString& path) { wxString oldpath; wxString tmp; if (path != wxEmptyString) { oldpath = cfg->GetPath(); cfg->SetPath(_T("/") + path); } cfg->Write(wxT("hcNavigPanel"), m_Cfg.navig_on); cfg->Write(wxT("hcSashPos"), (long)m_Cfg.sashpos); cfg->Write(wxT("hcX"), (long)m_Cfg.x); cfg->Write(wxT("hcY"), (long)m_Cfg.y); cfg->Write(wxT("hcW"), (long)m_Cfg.w); cfg->Write(wxT("hcH"), (long)m_Cfg.h); cfg->Write(wxT("hcFixedFace"), m_FixedFace); cfg->Write(wxT("hcNormalFace"), m_NormalFace); cfg->Write(wxT("hcFontSize"), (long)m_FontSize); if (m_Bookmarks) { int i; int cnt = m_BookmarksNames.GetCount(); wxString val; cfg->Write(wxT("hcBookmarksCnt"), (long)cnt); for (i = 0; i < cnt; i++) { val.Printf(wxT("hcBookmark_%i"), i); cfg->Write(val, m_BookmarksNames[i]); val.Printf(wxT("hcBookmark_%i_url"), i); cfg->Write(val, m_BookmarksPages[i]); } } if (m_HtmlWin) m_HtmlWin->WriteCustomization(cfg); if (path != wxEmptyString) cfg->SetPath(oldpath); } static void SetFontsToHtmlWin(wxHtmlWindow *win, wxString scalf, wxString fixf, int size) { static int f_sizes[5][7] = { { 6, 7, 9, 12, 14, 16, 19}, { 8, 9, 12, 14, 16, 19, 22}, {10, 12, 14, 16, 19, 24, 32}, {14, 16, 18, 24, 32, 38, 45}, {16, 20, 24, 32, 38, 45, 50} }; win->SetFonts(scalf, fixf, f_sizes[size]); } class wxHtmlHelpFrameOptionsDialog : public wxDialog { public: wxComboBox *NormalFont, *FixedFont; wxRadioBox *RadioBox; wxHtmlWindow *TestWin; wxHtmlHelpFrameOptionsDialog(wxWindow *parent) : wxDialog(parent, -1, wxString(_("Help Browser Options"))) { wxString choices[5] = {_("very small"), _("small"), _("medium"), _("large"), _("very large")}; wxBoxSizer *topsizer, *sizer, *sizer2; topsizer = new wxBoxSizer(wxVERTICAL); sizer = new wxBoxSizer(wxHORIZONTAL); sizer2 = new wxStaticBoxSizer( new wxStaticBox(this, -1, _("Normal font:")), wxVERTICAL); sizer2->Add(NormalFont = new wxComboBox(this, -1, wxEmptyString, wxDefaultPosition, wxSize(200, 200), 0, NULL, wxCB_DROPDOWN | wxCB_READONLY), 1, wxEXPAND | wxLEFT | wxRIGHT, 10); sizer->Add(sizer2, 0, wxEXPAND | wxLEFT|wxRIGHT|wxTOP, 10); sizer2 = new wxStaticBoxSizer( new wxStaticBox(this, -1, _("Fixed font:")), wxVERTICAL); sizer2->Add(FixedFont = new wxComboBox(this, -1, wxEmptyString, wxDefaultPosition, wxSize(200, 200), 0, NULL, wxCB_DROPDOWN | wxCB_READONLY), 1, wxEXPAND | wxLEFT | wxRIGHT, 10); sizer->Add(sizer2, 0, wxEXPAND | wxLEFT|wxRIGHT|wxTOP, 10); topsizer->Add(sizer); topsizer->Add(RadioBox = new wxRadioBox(this, -1, _("Font size:"), wxDefaultPosition, wxDefaultSize, 5, choices, 5), 0, wxEXPAND | wxLEFT|wxRIGHT|wxTOP, 10); topsizer->Add(new wxStaticText(this, -1, _("Preview:")), 0, wxLEFT | wxTOP, 10); topsizer->Add(TestWin = new wxHtmlWindow(this, -1, wxDefaultPosition, wxSize(20, 150), wxHW_SCROLLBAR_AUTO | wxSUNKEN_BORDER), 1, wxEXPAND | wxLEFT|wxTOP|wxRIGHT, 10); sizer = new wxBoxSizer(wxHORIZONTAL); wxButton *ok; sizer->Add(ok = new wxButton(this, wxID_OK, _("OK")), 0, wxALL, 10); ok->SetDefault(); sizer->Add(new wxButton(this, wxID_CANCEL, _("Cancel")), 0, wxALL, 10); topsizer->Add(sizer, 0, wxALIGN_RIGHT); SetAutoLayout(TRUE); SetSizer(topsizer); topsizer->Fit(this); Centre(wxBOTH); } void UpdateTestWin() { wxBusyCursor bcur; SetFontsToHtmlWin(TestWin, NormalFont->GetStringSelection(), FixedFont->GetStringSelection(), RadioBox->GetSelection()); TestWin->SetPage(_( "
\ Normal faceFixed size face.
bold italic \
bold italic underlined
\
font size -2
\
font size -1
\
font size +0
\
font size +1
\
font size +2
\
font size +3
\
font size +4\
"
));
}
void OnUpdate(wxCommandEvent& WXUNUSED(event))
{
UpdateTestWin();
}
DECLARE_EVENT_TABLE()
};
BEGIN_EVENT_TABLE(wxHtmlHelpFrameOptionsDialog, wxDialog)
EVT_COMBOBOX(-1, wxHtmlHelpFrameOptionsDialog::OnUpdate)
EVT_RADIOBOX(-1, wxHtmlHelpFrameOptionsDialog::OnUpdate)
END_EVENT_TABLE()
void wxHtmlHelpFrame::OptionsDialog()
{
wxHtmlHelpFrameOptionsDialog dlg(this);
unsigned i;
if (m_NormalFonts == NULL)
{
wxFontEnumerator enu;
enu.EnumerateFacenames();
m_NormalFonts = new wxArrayString;
*m_NormalFonts = *enu.GetFacenames();
m_NormalFonts->Sort();
}
if (m_FixedFonts == NULL)
{
wxFontEnumerator enu;
enu.EnumerateFacenames(wxFONTENCODING_SYSTEM, TRUE);
m_FixedFonts = new wxArrayString;
*m_FixedFonts = *enu.GetFacenames();
m_FixedFonts->Sort();
}
for (i = 0; i < m_NormalFonts->GetCount(); i++)
dlg.NormalFont->Append((*m_NormalFonts)[i]);
for (i = 0; i < m_FixedFonts->GetCount(); i++)
dlg.FixedFont->Append((*m_FixedFonts)[i]);
if (!m_NormalFace.IsEmpty()) dlg.NormalFont->SetStringSelection(m_NormalFace);
else dlg.NormalFont->SetSelection(0);
if (!m_FixedFace.IsEmpty()) dlg.FixedFont->SetStringSelection(m_FixedFace);
else dlg.FixedFont->SetSelection(0);
dlg.RadioBox->SetSelection(m_FontSize);
dlg.UpdateTestWin();
if (dlg.ShowModal() == wxID_OK)
{
m_NormalFace = dlg.NormalFont->GetStringSelection();
m_FixedFace = dlg.FixedFont->GetStringSelection();
m_FontSize = dlg.RadioBox->GetSelection();
SetFontsToHtmlWin(m_HtmlWin, m_NormalFace, m_FixedFace, m_FontSize);
}
}
void wxHtmlHelpFrame::NotifyPageChanged()
{
if (m_UpdateContents && m_PagesHash)
{
wxString an = m_HtmlWin->GetOpenedAnchor();
wxHtmlHelpHashData *ha;
if (an.IsEmpty())
ha = (wxHtmlHelpHashData*) m_PagesHash->Get(m_HtmlWin->GetOpenedPage());
else
ha = (wxHtmlHelpHashData*) m_PagesHash->Get(m_HtmlWin->GetOpenedPage() + wxT("#") + an);
if (ha)
{
bool olduc = m_UpdateContents;
m_UpdateContents = FALSE;
m_ContentsBox->SelectItem(ha->m_Id);
m_ContentsBox->EnsureVisible(ha->m_Id);
m_UpdateContents = olduc;
}
}
}
/*
EVENT HANDLING :
*/
void wxHtmlHelpFrame::OnActivate(wxActivateEvent& event)
{
// This saves one mouse click when using the
// wxHTML for context sensitive help systems
if (event.GetActive() && m_HtmlWin)
m_HtmlWin->SetFocus();
}
void wxHtmlHelpFrame::OnToolbar(wxCommandEvent& event)
{
switch (event.GetId())
{
case wxID_HTML_BACK :
m_HtmlWin->HistoryBack();
NotifyPageChanged();
break;
case wxID_HTML_FORWARD :
m_HtmlWin->HistoryForward();
NotifyPageChanged();
break;
case wxID_HTML_UP :
if (m_PagesHash)
{
wxString an = m_HtmlWin->GetOpenedAnchor();
wxHtmlHelpHashData *ha;
if (an.IsEmpty())
ha = (wxHtmlHelpHashData*) m_PagesHash->Get(m_HtmlWin->GetOpenedPage());
else
ha = (wxHtmlHelpHashData*) m_PagesHash->Get(m_HtmlWin->GetOpenedPage() + wxT("#") + an);
if (ha && ha->m_Index > 0)
{
wxHtmlContentsItem *it = m_Data->GetContents() + (ha->m_Index - 1);
if (it->m_Page[0] != 0)
{
m_HtmlWin->LoadPage(it->GetFullPath());
NotifyPageChanged();
}
}
}
break;
case wxID_HTML_UPNODE :
if (m_PagesHash)
{
wxString an = m_HtmlWin->GetOpenedAnchor();
wxHtmlHelpHashData *ha;
if (an.IsEmpty())
ha = (wxHtmlHelpHashData*) m_PagesHash->Get(m_HtmlWin->GetOpenedPage());
else
ha = (wxHtmlHelpHashData*) m_PagesHash->Get(m_HtmlWin->GetOpenedPage() + wxT("#") + an);
if (ha && ha->m_Index > 0)
{
int level = m_Data->GetContents()[ha->m_Index].m_Level - 1;
wxHtmlContentsItem *it;
int ind = ha->m_Index - 1;
it = m_Data->GetContents() + ind;
while (ind >= 0 && it->m_Level != level) ind--, it--;
if (ind >= 0)
{
if (it->m_Page[0] != 0)
{
m_HtmlWin->LoadPage(it->GetFullPath());
NotifyPageChanged();
}
}
}
}
break;
case wxID_HTML_DOWN :
if (m_PagesHash)
{
wxString an = m_HtmlWin->GetOpenedAnchor();
wxString adr;
wxHtmlHelpHashData *ha;
if (an.IsEmpty()) adr = m_HtmlWin->GetOpenedPage();
else adr = m_HtmlWin->GetOpenedPage() + wxT("#") + an;
ha = (wxHtmlHelpHashData*) m_PagesHash->Get(adr);
if (ha && ha->m_Index < m_Data->GetContentsCnt() - 1)
{
wxHtmlContentsItem *it = m_Data->GetContents() + (ha->m_Index + 1);
while (it->GetFullPath() == adr) it++;
if (it->m_Page[0] != 0)
{
m_HtmlWin->LoadPage(it->GetFullPath());
NotifyPageChanged();
}
}
}
break;
case wxID_HTML_PANEL :
{
if (! (m_Splitter && m_NavigPan))
return ;
if (m_Splitter->IsSplit())
{
m_Cfg.sashpos = m_Splitter->GetSashPosition();
m_Splitter->Unsplit(m_NavigPan);
m_Cfg.navig_on = FALSE;
}
else
{
m_NavigPan->Show(TRUE);
m_HtmlWin->Show(TRUE);
m_Splitter->SplitVertically(m_NavigPan, m_HtmlWin, m_Cfg.sashpos);
m_Cfg.navig_on = TRUE;
}
}
break;
case wxID_HTML_OPTIONS :
OptionsDialog();
break;
case wxID_HTML_BOOKMARKSADD :
{
wxString item;
wxString url;
item = m_HtmlWin->GetOpenedPageTitle();
url = m_HtmlWin->GetOpenedPage();
if (item == wxEmptyString)
item = url.AfterLast(wxT('/'));
if (m_BookmarksPages.Index(url) == wxNOT_FOUND)
{
m_Bookmarks->Append(item);
m_BookmarksNames.Add(item);
m_BookmarksPages.Add(url);
}
}
break;
case wxID_HTML_BOOKMARKSREMOVE :
{
wxString item;
int pos;
item = m_Bookmarks->GetStringSelection();
pos = m_BookmarksNames.Index(item);
if (pos != wxNOT_FOUND)
{
m_BookmarksNames.Remove(pos);
m_BookmarksPages.Remove(pos);
m_Bookmarks->Delete(m_Bookmarks->GetSelection());
}
}
break;
#if wxUSE_PRINTING_ARCHITECTURE
case wxID_HTML_PRINT :
{
if (m_Printer == NULL)
m_Printer = new wxHtmlEasyPrinting(_("Help Printing"), this);
if (!m_HtmlWin->GetOpenedPage())
wxLogWarning(_("Cannot print empty page."));
else
m_Printer->PrintFile(m_HtmlWin->GetOpenedPage());
}
break;
#endif
case wxID_HTML_OPENFILE :
{
wxString s = wxFileSelector(_("Open HTML document"),
wxEmptyString,
wxEmptyString,
wxEmptyString,
_(
"HTML files (*.htm)|*.htm|HTML files (*.html)|*.html|\
Help books (*.htb)|*.htb|Help books (*.zip)|*.zip|\
HTML Help Project (*.hhp)|*.hhp|\
All files (*.*)|*"
),
wxOPEN | wxFILE_MUST_EXIST,
this);
if (!s.IsEmpty())
{
wxString ext = s.Right(4).Lower();
if (ext == _T(".zip") || ext == _T(".htb") || ext == _T(".hhp"))
{
wxBusyCursor bcur;
m_Data->AddBook(s);
RefreshLists();
}
else
m_HtmlWin->LoadPage(s);
}
}
break;
}
}
void wxHtmlHelpFrame::OnContentsSel(wxTreeEvent& event)
{
wxHtmlHelpTreeItemData *pg;
wxHtmlContentsItem *it;
pg = (wxHtmlHelpTreeItemData*) m_ContentsBox->GetItemData(event.GetItem());
if (pg && m_UpdateContents)
{
it = m_Data->GetContents() + (pg->m_Id);
m_UpdateContents = FALSE;
if (it->m_Page[0] != 0)
m_HtmlWin->LoadPage(it->GetFullPath());
m_UpdateContents = TRUE;
}
}
void wxHtmlHelpFrame::OnIndexSel(wxCommandEvent& WXUNUSED(event))
{
wxHtmlContentsItem *it = (wxHtmlContentsItem*) m_IndexList->GetClientData(m_IndexList->GetSelection());
if (it->m_Page[0] != 0)
m_HtmlWin->LoadPage(it->GetFullPath());
NotifyPageChanged();
}
void wxHtmlHelpFrame::OnIndexFind(wxCommandEvent& event)
{
wxString sr = m_IndexText->GetLineText(0);
sr.MakeLower();
if (sr == wxEmptyString)
{
OnIndexAll(event);
}
else
{
wxBusyCursor bcur;
const wxChar *cstr = sr.c_str();
wxChar mybuff[512];
wxChar *ptr;
bool first = TRUE;
m_IndexList->Clear();
int cnt = m_Data->GetIndexCnt();
wxHtmlContentsItem* index = m_Data->GetIndex();
int displ = 0;
for (int i = 0; i < cnt; i++)
{
wxStrncpy(mybuff, index[i].m_Name, 512);
mybuff[511] = _T('\0');
for (ptr = mybuff; *ptr != 0; ptr++)
if (*ptr >= _T('A') && *ptr <= _T('Z'))
*ptr -= (wxChar)(_T('A') - _T('a'));
if (wxStrstr(mybuff, cstr) != NULL)
{
m_IndexList->Append(index[i].m_Name, (char*)(index + i));
displ++;
if (first)
{
if (index[i].m_Page[0] != 0)
m_HtmlWin->LoadPage(index[i].GetFullPath());
NotifyPageChanged();
first = FALSE;
}
}
}
wxString cnttext;
cnttext.Printf(_("%i of %i"), displ, cnt);
m_IndexCountInfo->SetLabel(cnttext);
m_IndexText->SetSelection(0, sr.Length());
m_IndexText->SetFocus();
}
}
void wxHtmlHelpFrame::OnIndexAll(wxCommandEvent& WXUNUSED(event))
{
wxBusyCursor bcur;
m_IndexList->Clear();
int cnt = m_Data->GetIndexCnt();
bool first = TRUE;
wxHtmlContentsItem* index = m_Data->GetIndex();
for (int i = 0; i < cnt; i++)
{
m_IndexList->Append(index[i].m_Name, (char*)(index + i));
if (first)
{
if (index[i].m_Page[0] != 0)
m_HtmlWin->LoadPage(index[i].GetFullPath());
NotifyPageChanged();
first = FALSE;
}
}
wxString cnttext;
cnttext.Printf(_("%i of %i"), cnt, cnt);
m_IndexCountInfo->SetLabel(cnttext);
}
void wxHtmlHelpFrame::OnSearchSel(wxCommandEvent& WXUNUSED(event))
{
wxHtmlContentsItem *it = (wxHtmlContentsItem*) m_SearchList->GetClientData(m_SearchList->GetSelection());
if (it)
{
if (it->m_Page[0] != 0)
m_HtmlWin->LoadPage(it->GetFullPath());
NotifyPageChanged();
}
}
void wxHtmlHelpFrame::OnSearch(wxCommandEvent& WXUNUSED(event))
{
wxString sr = m_SearchText->GetLineText(0);
if (sr != wxEmptyString) KeywordSearch(sr);
}
void wxHtmlHelpFrame::OnBookmarksSel(wxCommandEvent& WXUNUSED(event))
{
wxString sr = m_Bookmarks->GetStringSelection();
if (sr != wxEmptyString && sr != _("(bookmarks)"))
{
m_HtmlWin->LoadPage(m_BookmarksPages[m_BookmarksNames.Index(sr)]);
NotifyPageChanged();
}
}
void wxHtmlHelpFrame::OnCloseWindow(wxCloseEvent& evt)
{
GetSize(&m_Cfg.w, &m_Cfg.h);
GetPosition(&m_Cfg.x, &m_Cfg.y);
if (m_Splitter && m_Cfg.navig_on) m_Cfg.sashpos = m_Splitter->GetSashPosition();
if (m_Config)
WriteCustomization(m_Config, m_ConfigRoot);
if (m_helpController && m_helpController->IsKindOf(CLASSINFO(wxHtmlHelpController)))
{
((wxHtmlHelpController*) m_helpController)->OnCloseFrame(evt);
}
evt.Skip();
}
BEGIN_EVENT_TABLE(wxHtmlHelpFrame, wxFrame)
EVT_ACTIVATE(wxHtmlHelpFrame::OnActivate)
EVT_TOOL_RANGE(wxID_HTML_PANEL, wxID_HTML_OPTIONS, wxHtmlHelpFrame::OnToolbar)
EVT_BUTTON(wxID_HTML_BOOKMARKSREMOVE, wxHtmlHelpFrame::OnToolbar)
EVT_BUTTON(wxID_HTML_BOOKMARKSADD, wxHtmlHelpFrame::OnToolbar)
EVT_TREE_SEL_CHANGED(wxID_HTML_TREECTRL, wxHtmlHelpFrame::OnContentsSel)
EVT_LISTBOX(wxID_HTML_INDEXLIST, wxHtmlHelpFrame::OnIndexSel)
EVT_LISTBOX(wxID_HTML_SEARCHLIST, wxHtmlHelpFrame::OnSearchSel)
EVT_BUTTON(wxID_HTML_SEARCHBUTTON, wxHtmlHelpFrame::OnSearch)
EVT_TEXT_ENTER(wxID_HTML_SEARCHTEXT, wxHtmlHelpFrame::OnSearch)
EVT_BUTTON(wxID_HTML_INDEXBUTTON, wxHtmlHelpFrame::OnIndexFind)
EVT_TEXT_ENTER(wxID_HTML_INDEXTEXT, wxHtmlHelpFrame::OnIndexFind)
EVT_BUTTON(wxID_HTML_INDEXBUTTONALL, wxHtmlHelpFrame::OnIndexAll)
EVT_COMBOBOX(wxID_HTML_BOOKMARKSLIST, wxHtmlHelpFrame::OnBookmarksSel)
EVT_CLOSE(wxHtmlHelpFrame::OnCloseWindow)
END_EVENT_TABLE()
#endif // wxUSE_WXHTML_HELP