home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / wxos2240.zip / wxWindows-2.4.0 / src / html / helpfrm.cpp < prev    next >
C/C++ Source or Header  |  2002-12-16  |  50KB  |  1,516 lines

  1. /////////////////////////////////////////////////////////////////////////////
  2. // Name:        helpfrm.cpp
  3. // Purpose:     wxHtmlHelpFrame
  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: helpfrm.cpp,v 1.72.2.3 2002/12/16 10:23:20 JS Exp $
  8. // Copyright:   (c) Harm van der Heijden and Vaclav Slavik
  9. // Licence:     wxWindows licence
  10. /////////////////////////////////////////////////////////////////////////////
  11.  
  12. #ifdef __GNUG__
  13. #pragma implementation "helpfrm.h"
  14. #endif
  15.  
  16. // For compilers that support precompilation, includes "wx.h"
  17.  
  18. #include "wx/wxprec.h"
  19.  
  20. #ifdef __BORLANDC__
  21. #pragma hdrstop
  22. #endif
  23.  
  24. #if wxUSE_WXHTML_HELP
  25.  
  26. #ifndef WXPRECOMP
  27.     #include "wx/intl.h"
  28.     #include "wx/log.h"
  29.  
  30.     #include "wx/object.h"
  31.     #include "wx/sizer.h"
  32.  
  33.     #include "wx/bmpbuttn.h"
  34.     #include "wx/statbox.h"
  35.     #include "wx/radiobox.h"
  36. #endif // WXPRECOMP
  37.  
  38. #include "wx/html/helpfrm.h"
  39. #include "wx/html/helpctrl.h"
  40. #include "wx/textctrl.h"
  41. #include "wx/notebook.h"
  42. #include "wx/imaglist.h"
  43. #include "wx/treectrl.h"
  44. #include "wx/tokenzr.h"
  45. #include "wx/wfstream.h"
  46. #include "wx/html/htmlwin.h"
  47. #include "wx/busyinfo.h"
  48. #include "wx/progdlg.h"
  49. #include "wx/toolbar.h"
  50. #include "wx/fontenum.h"
  51. #include "wx/stream.h"
  52. #include "wx/filedlg.h"
  53. #include "wx/artprov.h"
  54. #include "wx/spinctrl.h"
  55.  
  56. // what is considered "small index"?
  57. #define INDEX_IS_SMALL 100
  58.  
  59. /* Motif defines this as a macro */
  60. #ifdef Below
  61. #undef Below
  62. #endif
  63.  
  64. //--------------------------------------------------------------------------
  65. // wxHtmlHelpTreeItemData (private)
  66. //--------------------------------------------------------------------------
  67.  
  68. class wxHtmlHelpTreeItemData : public wxTreeItemData
  69. {
  70.     public:
  71. #if defined(__VISAGECPP__)
  72. //  VA needs a default ctor for some reason....
  73.         wxHtmlHelpTreeItemData() : wxTreeItemData()
  74.             { m_Id = 0; }
  75. #endif
  76.         wxHtmlHelpTreeItemData(int id) : wxTreeItemData()
  77.             { m_Id = id;}
  78.  
  79.         int m_Id;
  80. };
  81.  
  82.  
  83. //--------------------------------------------------------------------------
  84. // wxHtmlHelpHashData (private)
  85. //--------------------------------------------------------------------------
  86.  
  87. class wxHtmlHelpHashData : public wxObject
  88. {
  89.     public:
  90.         wxHtmlHelpHashData(int index, wxTreeItemId id) : wxObject()
  91.             { m_Index = index; m_Id = id;}
  92.         ~wxHtmlHelpHashData() {}
  93.  
  94.         int m_Index;
  95.         wxTreeItemId m_Id;
  96. };
  97.  
  98.  
  99. //--------------------------------------------------------------------------
  100. // wxHtmlHelpHtmlWindow (private)
  101. //--------------------------------------------------------------------------
  102.  
  103. class wxHtmlHelpHtmlWindow : public wxHtmlWindow
  104. {
  105.     public:
  106.         wxHtmlHelpHtmlWindow(wxHtmlHelpFrame *fr, wxWindow *parent) : wxHtmlWindow(parent), m_Frame(fr) {}
  107.  
  108.         virtual void OnLinkClicked(const wxHtmlLinkInfo& link)
  109.         {
  110.             wxHtmlWindow::OnLinkClicked(link);
  111.             m_Frame->NotifyPageChanged();
  112.         }
  113.  
  114.     private:
  115.         wxHtmlHelpFrame *m_Frame;
  116. };
  117.  
  118.  
  119.  
  120. //---------------------------------------------------------------------------
  121. // wxHtmlHelpFrame
  122. //---------------------------------------------------------------------------
  123.  
  124. // Command IDs :
  125. enum
  126. {
  127.     //wxID_HTML_HELPFRAME = wxID_HIGHEST + 1,
  128.     wxID_HTML_PANEL = wxID_HIGHEST + 2,
  129.     wxID_HTML_BACK,
  130.     wxID_HTML_FORWARD,
  131.     wxID_HTML_UPNODE,
  132.     wxID_HTML_UP,
  133.     wxID_HTML_DOWN,
  134.     wxID_HTML_PRINT,
  135.     wxID_HTML_OPENFILE,
  136.     wxID_HTML_OPTIONS,
  137.     wxID_HTML_BOOKMARKSLIST,
  138.     wxID_HTML_BOOKMARKSADD,
  139.     wxID_HTML_BOOKMARKSREMOVE,
  140.     wxID_HTML_TREECTRL,
  141.     wxID_HTML_INDEXPAGE,
  142.     wxID_HTML_INDEXLIST,
  143.     wxID_HTML_INDEXTEXT,
  144.     wxID_HTML_INDEXBUTTON,
  145.     wxID_HTML_INDEXBUTTONALL,
  146.     wxID_HTML_NOTEBOOK,
  147.     wxID_HTML_SEARCHPAGE,
  148.     wxID_HTML_SEARCHTEXT,
  149.     wxID_HTML_SEARCHLIST,
  150.     wxID_HTML_SEARCHBUTTON,
  151.     wxID_HTML_SEARCHCHOICE,
  152.     wxID_HTML_COUNTINFO
  153. };
  154.  
  155.  
  156. IMPLEMENT_DYNAMIC_CLASS(wxHtmlHelpFrame, wxFrame)
  157.  
  158. wxHtmlHelpFrame::wxHtmlHelpFrame(wxWindow* parent, wxWindowID id, const wxString& title,
  159.                                  int style, wxHtmlHelpData* data)
  160. {
  161.     Init(data);
  162.     Create(parent, id, title, style);
  163. }
  164.  
  165. void wxHtmlHelpFrame::Init(wxHtmlHelpData* data)
  166. {
  167.     if (data)
  168.     {
  169.         m_Data = data;
  170.         m_DataCreated = FALSE;
  171.     } else
  172.     {
  173.         m_Data = new wxHtmlHelpData();
  174.         m_DataCreated = TRUE;
  175.     }
  176.  
  177.     m_ContentsBox = NULL;
  178.     m_IndexList = NULL;
  179.     m_IndexButton = NULL;
  180.     m_IndexButtonAll = NULL;
  181.     m_IndexText = NULL;
  182.     m_SearchList = NULL;
  183.     m_SearchButton = NULL;
  184.     m_SearchText = NULL;
  185.     m_SearchChoice = NULL;
  186.     m_IndexCountInfo = NULL;
  187.     m_Splitter = NULL;
  188.     m_NavigPan = NULL;
  189.     m_NavigNotebook = NULL;
  190.     m_HtmlWin = NULL;
  191.     m_Bookmarks = NULL;
  192.     m_SearchCaseSensitive = NULL;
  193.     m_SearchWholeWords = NULL;
  194.  
  195.     m_Config = NULL;
  196.     m_ConfigRoot = wxEmptyString;
  197.  
  198.     m_Cfg.x = m_Cfg.y = 0;
  199.     m_Cfg.w = 700;
  200.     m_Cfg.h = 480;
  201.     m_Cfg.sashpos = 240;
  202.     m_Cfg.navig_on = TRUE;
  203.  
  204.     m_NormalFonts = m_FixedFonts = NULL;
  205.     m_NormalFace = m_FixedFace = wxEmptyString;
  206. #ifdef __WXMSW__
  207.     m_FontSize = 10;
  208. #else
  209.     m_FontSize = 14;
  210. #endif
  211.  
  212. #if wxUSE_PRINTING_ARCHITECTURE
  213.     m_Printer = NULL;
  214. #endif
  215.  
  216.     m_PagesHash = NULL;
  217.     m_UpdateContents = TRUE;
  218.     m_helpController = (wxHelpControllerBase*) NULL;
  219. }
  220.  
  221. // Create: builds the GUI components.
  222. // with the style flag it's possible to toggle the toolbar, contents, index and search
  223. // controls.
  224. // m_HtmlWin will *always* be created, but it's important to realize that
  225. // m_ContentsBox, m_IndexList, m_SearchList, m_SearchButton, m_SearchText and
  226. // m_SearchButton may be NULL.
  227. // moreover, if no contents, index or searchpage is needed, m_Splitter and
  228. // m_NavigPan will be NULL too (with m_HtmlWin directly connected to the frame)
  229.  
  230. bool wxHtmlHelpFrame::Create(wxWindow* parent, wxWindowID id,
  231.                              const wxString& WXUNUSED(title), int style)
  232. {
  233.     m_hfStyle = style;
  234.  
  235.     wxImageList *ContentsImageList = new wxImageList(16, 16);
  236.     ContentsImageList->Add(wxArtProvider::GetIcon(wxART_HELP_BOOK, wxART_HELP_BROWSER));
  237.     ContentsImageList->Add(wxArtProvider::GetIcon(wxART_HELP_FOLDER, wxART_HELP_BROWSER));
  238.     ContentsImageList->Add(wxArtProvider::GetIcon(wxART_HELP_PAGE, wxART_HELP_BROWSER));
  239.  
  240.     // Do the config in two steps. We read the HtmlWindow customization after we
  241.     // create the window.
  242.     if (m_Config)
  243.         ReadCustomization(m_Config, m_ConfigRoot);
  244.  
  245.     wxFrame::Create(parent, id, _("Help"), 
  246.                     wxPoint(m_Cfg.x, m_Cfg.y), wxSize(m_Cfg.w, m_Cfg.h), 
  247.                     wxDEFAULT_FRAME_STYLE, wxT("wxHtmlHelp"));
  248.  
  249.     GetPosition(&m_Cfg.x, &m_Cfg.y);
  250.  
  251.     SetIcon(wxArtProvider::GetIcon(wxART_HELP, wxART_HELP_BROWSER));
  252.  
  253.     int notebook_page = 0;
  254.  
  255.     CreateStatusBar();
  256.  
  257.     // toolbar?
  258.     if (style & (wxHF_TOOLBAR | wxHF_FLAT_TOOLBAR))
  259.     {
  260.         wxToolBar *toolBar = CreateToolBar(wxNO_BORDER | wxTB_HORIZONTAL |
  261.                                            wxTB_DOCKABLE |
  262.                                            (style & wxHF_FLAT_TOOLBAR ? wxTB_FLAT : 0));
  263.         toolBar->SetMargins( 2, 2 );
  264.         AddToolbarButtons(toolBar, style);
  265.         toolBar->Realize();
  266.     }
  267.  
  268.     wxSizer *navigSizer = NULL;
  269.  
  270.     if (style & (wxHF_CONTENTS | wxHF_INDEX | wxHF_SEARCH))
  271.     {
  272.         // traditional help controller; splitter window with html page on the
  273.         // right and a notebook containing various pages on the left
  274.         m_Splitter = new wxSplitterWindow(this);
  275.  
  276.         m_HtmlWin = new wxHtmlHelpHtmlWindow(this, m_Splitter);
  277.         m_NavigPan = new wxPanel(m_Splitter, -1);
  278.         m_NavigNotebook = new wxNotebook(m_NavigPan, wxID_HTML_NOTEBOOK,
  279.                                          wxDefaultPosition, wxDefaultSize);
  280.         wxNotebookSizer *nbs = new wxNotebookSizer(m_NavigNotebook);
  281.         
  282.         navigSizer = new wxBoxSizer(wxVERTICAL);
  283.         navigSizer->Add(nbs, 1, wxEXPAND);
  284.  
  285.         m_NavigPan->SetAutoLayout(TRUE);
  286.         m_NavigPan->SetSizer(navigSizer);
  287.     }
  288.     else
  289.     { // only html window, no notebook with index,contents etc
  290.         m_HtmlWin = new wxHtmlWindow(this);
  291.     }
  292.  
  293.     m_HtmlWin->SetRelatedFrame(this, m_TitleFormat);
  294.     m_HtmlWin->SetRelatedStatusBar(0);
  295.     if ( m_Config )
  296.         m_HtmlWin->ReadCustomization(m_Config, m_ConfigRoot);
  297.  
  298.     // contents tree panel?
  299.     if ( style & wxHF_CONTENTS )
  300.     {
  301.         wxWindow *dummy = new wxPanel(m_NavigNotebook, wxID_HTML_INDEXPAGE);
  302.         wxSizer *topsizer = new wxBoxSizer(wxVERTICAL);
  303.         
  304.         topsizer->Add(0, 10);
  305.         
  306.         dummy->SetAutoLayout(TRUE);
  307.         dummy->SetSizer(topsizer);
  308.  
  309.         if ( style & wxHF_BOOKMARKS )
  310.         {
  311.             m_Bookmarks = new wxComboBox(dummy, wxID_HTML_BOOKMARKSLIST, 
  312.                                          wxEmptyString,
  313.                                          wxDefaultPosition, wxDefaultSize, 
  314.                                          0, NULL, wxCB_READONLY | wxCB_SORT);
  315.             m_Bookmarks->Append(_("(bookmarks)"));
  316.             for (unsigned i = 0; i < m_BookmarksNames.GetCount(); i++)
  317.                 m_Bookmarks->Append(m_BookmarksNames[i]);
  318.             m_Bookmarks->SetSelection(0);
  319.  
  320.             wxBitmapButton *bmpbt1, *bmpbt2;
  321.             bmpbt1 = new wxBitmapButton(dummy, wxID_HTML_BOOKMARKSADD, 
  322.                                  wxArtProvider::GetBitmap(wxART_ADD_BOOKMARK, 
  323.                                                           wxART_HELP_BROWSER));
  324.             bmpbt2 = new wxBitmapButton(dummy, wxID_HTML_BOOKMARKSREMOVE, 
  325.                                  wxArtProvider::GetBitmap(wxART_DEL_BOOKMARK, 
  326.                                                           wxART_HELP_BROWSER));
  327. #if wxUSE_TOOLTIPS
  328.             bmpbt1->SetToolTip(_("Add current page to bookmarks"));
  329.             bmpbt2->SetToolTip(_("Remove current page from bookmarks"));
  330. #endif // wxUSE_TOOLTIPS
  331.  
  332.             wxSizer *sizer = new wxBoxSizer(wxHORIZONTAL);
  333.             
  334.             sizer->Add(m_Bookmarks, 1, wxALIGN_CENTRE_VERTICAL | wxRIGHT, 5);
  335.             sizer->Add(bmpbt1, 0, wxALIGN_CENTRE_VERTICAL | wxRIGHT, 2);
  336.             sizer->Add(bmpbt2, 0, wxALIGN_CENTRE_VERTICAL, 0);
  337.             
  338.             topsizer->Add(sizer, 0, wxEXPAND | wxLEFT | wxBOTTOM | wxRIGHT, 10);
  339.         }
  340.  
  341.         m_ContentsBox = new wxTreeCtrl(dummy, wxID_HTML_TREECTRL,
  342.                                        wxDefaultPosition, wxDefaultSize,
  343.                                        wxSUNKEN_BORDER | 
  344.                                        wxTR_HAS_BUTTONS | wxTR_HIDE_ROOT |
  345.                                        wxTR_LINES_AT_ROOT);
  346.  
  347.         m_ContentsBox->AssignImageList(ContentsImageList);
  348.         
  349.         topsizer->Add(m_ContentsBox, 1, wxEXPAND | wxLEFT | wxBOTTOM | wxRIGHT, 2);
  350.  
  351.         m_NavigNotebook->AddPage(dummy, _("Contents"));
  352.         m_ContentsPage = notebook_page++;
  353.     }
  354.  
  355.     // index listbox panel?
  356.     if ( style & wxHF_INDEX )
  357.     {
  358.         wxWindow *dummy = new wxPanel(m_NavigNotebook, wxID_HTML_INDEXPAGE);       
  359.         wxSizer *topsizer = new wxBoxSizer(wxVERTICAL);
  360.  
  361.         dummy->SetAutoLayout(TRUE);
  362.         dummy->SetSizer(topsizer);
  363.  
  364.         m_IndexText = new wxTextCtrl(dummy, wxID_HTML_INDEXTEXT, wxEmptyString, 
  365.                                      wxDefaultPosition, wxDefaultSize, 
  366.                                      wxTE_PROCESS_ENTER);
  367.         m_IndexButton = new wxButton(dummy, wxID_HTML_INDEXBUTTON, _("Find"));
  368.         m_IndexButtonAll = new wxButton(dummy, wxID_HTML_INDEXBUTTONALL, 
  369.                                         _("Show all"));
  370.         m_IndexCountInfo = new wxStaticText(dummy, wxID_HTML_COUNTINFO, 
  371.                                             wxEmptyString, wxDefaultPosition,
  372.                                             wxDefaultSize, 
  373.                                             wxALIGN_RIGHT | wxST_NO_AUTORESIZE);
  374.         m_IndexList = new wxListBox(dummy, wxID_HTML_INDEXLIST, 
  375.                                     wxDefaultPosition, wxDefaultSize, 
  376.                                     0, NULL, wxLB_SINGLE);
  377.  
  378. #if wxUSE_TOOLTIPS
  379.         m_IndexButton->SetToolTip(_("Display all index items that contain given substring. Search is case insensitive."));
  380.         m_IndexButtonAll->SetToolTip(_("Show all items in index"));
  381. #endif //wxUSE_TOOLTIPS
  382.  
  383.         topsizer->Add(m_IndexText, 0, wxEXPAND | wxALL, 10);
  384.         wxSizer *btsizer = new wxBoxSizer(wxHORIZONTAL);
  385.         btsizer->Add(m_IndexButton, 0, wxRIGHT, 2);
  386.         btsizer->Add(m_IndexButtonAll);
  387.         topsizer->Add(btsizer, 0, 
  388.                       wxALIGN_RIGHT | wxLEFT | wxRIGHT | wxBOTTOM, 10);
  389.         topsizer->Add(m_IndexCountInfo, 0, wxEXPAND | wxLEFT | wxRIGHT, 2);
  390.         topsizer->Add(m_IndexList, 1, wxEXPAND | wxALL, 2);
  391.  
  392.         m_NavigNotebook->AddPage(dummy, _("Index"));
  393.         m_IndexPage = notebook_page++;
  394.     }
  395.  
  396.     // search list panel?
  397.     if ( style & wxHF_SEARCH )
  398.     {
  399.         wxWindow *dummy = new wxPanel(m_NavigNotebook, wxID_HTML_INDEXPAGE);       
  400.         wxSizer *sizer = new wxBoxSizer(wxVERTICAL);
  401.  
  402.         dummy->SetAutoLayout(TRUE);
  403.         dummy->SetSizer(sizer);
  404.  
  405.         m_SearchText = new wxTextCtrl(dummy, wxID_HTML_SEARCHTEXT, 
  406.                                       wxEmptyString, 
  407.                                       wxDefaultPosition, wxDefaultSize, 
  408.                                       wxTE_PROCESS_ENTER);
  409.         m_SearchChoice = new wxChoice(dummy, wxID_HTML_SEARCHCHOICE, 
  410.                                       wxDefaultPosition, wxDefaultSize);
  411.         m_SearchCaseSensitive = new wxCheckBox(dummy, -1, _("Case sensitive"));
  412.         m_SearchWholeWords = new wxCheckBox(dummy, -1, _("Whole words only"));
  413.         m_SearchButton = new wxButton(dummy, wxID_HTML_SEARCHBUTTON, _("Search"));
  414. #if wxUSE_TOOLTIPS
  415.         m_SearchButton->SetToolTip(_("Search contents of help book(s) for all occurences of the text you typed above"));
  416. #endif //wxUSE_TOOLTIPS
  417.         m_SearchList = new wxListBox(dummy, wxID_HTML_SEARCHLIST, 
  418.                                      wxDefaultPosition, wxDefaultSize, 
  419.                                      0, NULL, wxLB_SINGLE);
  420.                                      
  421.         sizer->Add(m_SearchText, 0, wxEXPAND | wxALL, 10);
  422.         sizer->Add(m_SearchChoice, 0, wxEXPAND | wxLEFT | wxRIGHT | wxBOTTOM, 10);
  423.         sizer->Add(m_SearchCaseSensitive, 0, wxLEFT | wxRIGHT, 10);
  424.         sizer->Add(m_SearchWholeWords, 0, wxLEFT | wxRIGHT, 10);
  425.         sizer->Add(m_SearchButton, 0, wxALL | wxALIGN_RIGHT, 8);
  426.         sizer->Add(m_SearchList, 1, wxALL | wxEXPAND, 2);
  427.  
  428.         m_NavigNotebook->AddPage(dummy, _("Search"));
  429.         m_SearchPage = notebook_page++;
  430.     }
  431.  
  432.     m_HtmlWin->Show(TRUE);
  433.  
  434.     RefreshLists();
  435.  
  436.     if ( navigSizer )
  437.     {
  438.         navigSizer->SetSizeHints(m_NavigPan);
  439.         m_NavigPan->Layout();
  440.     }
  441.  
  442.     // showtime
  443.     if ( m_NavigPan && m_Splitter )
  444.     {
  445.         m_Splitter->SetMinimumPaneSize(20);
  446.         if ( m_Cfg.navig_on )
  447.             m_Splitter->SplitVertically(m_NavigPan, m_HtmlWin, m_Cfg.sashpos);
  448.  
  449.         if ( m_Cfg.navig_on )
  450.         {
  451.             m_NavigPan->Show(TRUE);
  452.             m_Splitter->SplitVertically(m_NavigPan, m_HtmlWin, m_Cfg.sashpos);
  453.         }
  454.         else
  455.         {
  456.             m_NavigPan->Show(FALSE);
  457.             m_Splitter->Initialize(m_HtmlWin);
  458.         }
  459.     }
  460.     
  461.     return TRUE;
  462. }
  463.  
  464. wxHtmlHelpFrame::~wxHtmlHelpFrame()
  465. {
  466.     // PopEventHandler(); // wxhtmlhelpcontroller (not any more!)
  467.     if (m_DataCreated)
  468.         delete m_Data;
  469.     if (m_NormalFonts) delete m_NormalFonts;
  470.     if (m_FixedFonts) delete m_FixedFonts;
  471.     if (m_PagesHash) delete m_PagesHash;
  472. }
  473.  
  474.  
  475. void wxHtmlHelpFrame::AddToolbarButtons(wxToolBar *toolBar, int style)
  476. {
  477.     wxBitmap wpanelBitmap = 
  478.         wxArtProvider::GetBitmap(wxART_HELP_SIDE_PANEL, wxART_HELP_BROWSER);
  479.     wxBitmap wbackBitmap = 
  480.         wxArtProvider::GetBitmap(wxART_GO_BACK, wxART_HELP_BROWSER);
  481.     wxBitmap wforwardBitmap = 
  482.         wxArtProvider::GetBitmap(wxART_GO_FORWARD, wxART_HELP_BROWSER);
  483.     wxBitmap wupnodeBitmap = 
  484.         wxArtProvider::GetBitmap(wxART_GO_TO_PARENT, wxART_HELP_BROWSER);
  485.     wxBitmap wupBitmap = 
  486.         wxArtProvider::GetBitmap(wxART_GO_UP, wxART_HELP_BROWSER);
  487.     wxBitmap wdownBitmap = 
  488.         wxArtProvider::GetBitmap(wxART_GO_DOWN, wxART_HELP_BROWSER);
  489.     wxBitmap wopenBitmap = 
  490.         wxArtProvider::GetBitmap(wxART_FILE_OPEN, wxART_HELP_BROWSER);
  491.     wxBitmap wprintBitmap = 
  492.         wxArtProvider::GetBitmap(wxART_PRINT, wxART_HELP_BROWSER);
  493.     wxBitmap woptionsBitmap = 
  494.         wxArtProvider::GetBitmap(wxART_HELP_SETTINGS, wxART_HELP_BROWSER);
  495.  
  496.     wxASSERT_MSG( (wpanelBitmap.Ok() && wbackBitmap.Ok() &&
  497.                    wforwardBitmap.Ok() && wupnodeBitmap.Ok() &&
  498.                    wupBitmap.Ok() && wdownBitmap.Ok() &&
  499.                    wopenBitmap.Ok() && wprintBitmap.Ok() &&
  500.                    woptionsBitmap.Ok()),
  501.                   wxT("One or more HTML help frame toolbar bitmap could not be loaded.")) ;
  502.  
  503.  
  504.     toolBar->AddTool(wxID_HTML_PANEL, wpanelBitmap, wxNullBitmap,
  505.                        FALSE, -1, -1, (wxObject *) NULL,
  506.                        _("Show/hide navigation panel"));
  507.  
  508.     toolBar->AddSeparator();
  509.     toolBar->AddTool(wxID_HTML_BACK, wbackBitmap, wxNullBitmap,
  510.                        FALSE, -1, -1, (wxObject *) NULL,
  511.                        _("Go back"));
  512.     toolBar->AddTool(wxID_HTML_FORWARD, wforwardBitmap, wxNullBitmap,
  513.                        FALSE, -1, -1, (wxObject *) NULL,
  514.                        _("Go forward"));
  515.     toolBar->AddSeparator();
  516.  
  517.     toolBar->AddTool(wxID_HTML_UPNODE, wupnodeBitmap, wxNullBitmap,
  518.                        FALSE, -1, -1, (wxObject *) NULL,
  519.                        _("Go one level up in document hierarchy"));
  520.     toolBar->AddTool(wxID_HTML_UP, wupBitmap, wxNullBitmap,
  521.                        FALSE, -1, -1, (wxObject *) NULL,
  522.                        _("Previous page"));
  523.     toolBar->AddTool(wxID_HTML_DOWN, wdownBitmap, wxNullBitmap,
  524.                        FALSE, -1, -1, (wxObject *) NULL,
  525.                        _("Next page"));
  526.  
  527.     if ((style & wxHF_PRINT) || (style & wxHF_OPEN_FILES))
  528.         toolBar->AddSeparator();
  529.  
  530.     if (style & wxHF_OPEN_FILES)
  531.         toolBar->AddTool(wxID_HTML_OPENFILE, wopenBitmap, wxNullBitmap,
  532.                            FALSE, -1, -1, (wxObject *) NULL,
  533.                            _("Open HTML document"));
  534.  
  535. #if wxUSE_PRINTING_ARCHITECTURE
  536.     if (style & wxHF_PRINT)
  537.         toolBar->AddTool(wxID_HTML_PRINT, wprintBitmap, wxNullBitmap,
  538.                            FALSE, -1, -1, (wxObject *) NULL,
  539.                            _("Print this page"));
  540. #endif
  541.  
  542.     toolBar->AddSeparator();
  543.     toolBar->AddTool(wxID_HTML_OPTIONS, woptionsBitmap, wxNullBitmap,
  544.                        FALSE, -1, -1, (wxObject *) NULL,
  545.                        _("Display options dialog"));
  546. }
  547.  
  548.  
  549. void wxHtmlHelpFrame::SetTitleFormat(const wxString& format)
  550. {
  551.     if (m_HtmlWin)
  552.         m_HtmlWin->SetRelatedFrame(this, format);
  553.     m_TitleFormat = format;
  554. }
  555.  
  556.  
  557. bool wxHtmlHelpFrame::Display(const wxString& x)
  558. {
  559.     wxString url = m_Data->FindPageByName(x);
  560.     if (!url.IsEmpty())
  561.     {
  562.         m_HtmlWin->LoadPage(url);
  563.         NotifyPageChanged();
  564.         return TRUE;
  565.     }
  566.     return FALSE;
  567. }
  568.  
  569. bool wxHtmlHelpFrame::Display(const int id)
  570. {
  571.     wxString url = m_Data->FindPageById(id);
  572.     if (!url.IsEmpty())
  573.     {
  574.         m_HtmlWin->LoadPage(url);
  575.         NotifyPageChanged();
  576.         return TRUE;
  577.     }
  578.     return FALSE;
  579. }
  580.  
  581.  
  582.  
  583. bool wxHtmlHelpFrame::DisplayContents()
  584. {
  585.     if (! m_ContentsBox)
  586.         return FALSE;
  587.     if (!m_Splitter->IsSplit())
  588.     {
  589.         m_NavigPan->Show(TRUE);
  590.         m_HtmlWin->Show(TRUE);
  591.         m_Splitter->SplitVertically(m_NavigPan, m_HtmlWin, m_Cfg.sashpos);
  592.         m_Cfg.navig_on = TRUE;
  593.     }
  594.     m_NavigNotebook->SetSelection(0);
  595.     if (m_Data->GetBookRecArray().GetCount() > 0)
  596.     {
  597.         wxHtmlBookRecord& book = m_Data->GetBookRecArray()[0];
  598.         if (!book.GetStart().IsEmpty())
  599.             m_HtmlWin->LoadPage(book.GetFullPath(book.GetStart()));
  600.     }
  601.     return TRUE;
  602. }
  603.  
  604.  
  605.  
  606. bool wxHtmlHelpFrame::DisplayIndex()
  607. {
  608.     if (! m_IndexList)
  609.         return FALSE;
  610.     if (!m_Splitter->IsSplit())
  611.     {
  612.         m_NavigPan->Show(TRUE);
  613.         m_HtmlWin->Show(TRUE);
  614.         m_Splitter->SplitVertically(m_NavigPan, m_HtmlWin, m_Cfg.sashpos);
  615.     }
  616.     m_NavigNotebook->SetSelection(1);
  617.     if (m_Data->GetBookRecArray().GetCount() > 0)
  618.     {
  619.         wxHtmlBookRecord& book = m_Data->GetBookRecArray()[0];
  620.         if (!book.GetStart().IsEmpty())
  621.             m_HtmlWin->LoadPage(book.GetFullPath(book.GetStart()));
  622.     }
  623.     return TRUE;
  624. }
  625.  
  626.  
  627.  
  628. bool wxHtmlHelpFrame::KeywordSearch(const wxString& keyword)
  629. {
  630.     if (! (m_SearchList && m_SearchButton && m_SearchText && m_SearchChoice))
  631.         return FALSE;
  632.  
  633.     int foundcnt = 0, curi;
  634.     wxString foundstr;
  635.     wxString book = wxEmptyString;
  636.  
  637.     if (!m_Splitter->IsSplit())
  638.     {
  639.         m_NavigPan->Show(TRUE);
  640.         m_HtmlWin->Show(TRUE);
  641.         m_Splitter->SplitVertically(m_NavigPan, m_HtmlWin, m_Cfg.sashpos);
  642.     }
  643.     m_NavigNotebook->SetSelection(m_SearchPage);
  644.     m_SearchList->Clear();
  645.     m_SearchText->SetValue(keyword);
  646.     m_SearchButton->Enable(FALSE);
  647.  
  648.     if (m_SearchChoice->GetSelection() != 0)
  649.         book = m_SearchChoice->GetStringSelection();
  650.  
  651.     wxHtmlSearchStatus status(m_Data, keyword,
  652.                               m_SearchCaseSensitive->GetValue(), m_SearchWholeWords->GetValue(),
  653.                               book);
  654.  
  655.     wxProgressDialog progress(_("Searching..."), _("No matching page found yet"),
  656.                               status.GetMaxIndex(), this,
  657.                               wxPD_APP_MODAL | wxPD_CAN_ABORT | wxPD_AUTO_HIDE);
  658.  
  659.     while (status.IsActive())
  660.     {
  661.         curi = status.GetCurIndex();
  662.         if (curi % 32 == 0 && progress.Update(curi) == FALSE)
  663.             break;
  664.         if (status.Search())
  665.         {
  666.             foundstr.Printf(_("Found %i matches"), ++foundcnt);
  667.             progress.Update(status.GetCurIndex(), foundstr);
  668.             m_SearchList->Append(status.GetName(), status.GetContentsItem());
  669.         }
  670.     }
  671.  
  672.     m_SearchButton->Enable(TRUE);
  673.     m_SearchText->SetSelection(0, keyword.Length());
  674.     m_SearchText->SetFocus();
  675.     if (foundcnt)
  676.     {
  677.         wxHtmlContentsItem *it = (wxHtmlContentsItem*) m_SearchList->GetClientData(0);
  678.         if (it)
  679.         {
  680.             m_HtmlWin->LoadPage(it->GetFullPath());
  681.             NotifyPageChanged();
  682.         }
  683.     }
  684.     return (foundcnt > 0);
  685. }
  686.  
  687. void wxHtmlHelpFrame::CreateContents()
  688. {
  689.     if (! m_ContentsBox)
  690.         return ;
  691.  
  692.     m_ContentsBox->Clear();
  693.  
  694.     if (m_PagesHash) delete m_PagesHash;
  695.     m_PagesHash = new wxHashTable(wxKEY_STRING, 2 * m_Data->GetContentsCnt());
  696.     m_PagesHash->DeleteContents(TRUE);
  697.  
  698.     int cnt = m_Data->GetContentsCnt();
  699.     int i;
  700.  
  701.     wxHtmlContentsItem *it;
  702.  
  703.     const int MAX_ROOTS = 64;
  704.     wxTreeItemId roots[MAX_ROOTS];
  705.     // VS: this array holds information about whether we've set item icon at
  706.     //     given level. This is neccessary because m_Data has flat structure
  707.     //     and there's no way of recognizing if some item has subitems or not.
  708.     //     We set the icon later: when we find an item with level=n, we know
  709.     //     that the last item with level=n-1 was folder with subitems, so we
  710.     //     set its icon accordingly
  711.     bool imaged[MAX_ROOTS];
  712.     m_ContentsBox->DeleteAllItems();
  713.     
  714.     roots[0] = m_ContentsBox->AddRoot(_("(Help)"));
  715.     imaged[0] = TRUE;
  716.  
  717.     for (it = m_Data->GetContents(), i = 0; i < cnt; i++, it++)
  718.     {
  719.         // Handle books:
  720.         if (it->m_Level == 0)
  721.         {
  722.             if (m_hfStyle & wxHF_MERGE_BOOKS)
  723.                 // VS: we don't want book nodes, books' content should
  724.                 //    appear under tree's root. This line will create "fake"
  725.                 //    record about book node so that the rest of this look
  726.                 //    will believe there really _is_ book node and will
  727.                 //    behave correctly.
  728.                 roots[1] = roots[0];
  729.             else
  730.             {
  731.                 roots[1] = m_ContentsBox->AppendItem(roots[0],
  732.                                          it->m_Name, IMG_Book, -1,
  733.                                          new wxHtmlHelpTreeItemData(i));
  734.                 m_ContentsBox->SetItemBold(roots[1], TRUE);
  735.             }
  736.             imaged[1] = TRUE;
  737.         }
  738.         // ...and their contents:
  739.         else
  740.         {
  741.             roots[it->m_Level + 1] = m_ContentsBox->AppendItem(
  742.                                      roots[it->m_Level], it->m_Name, IMG_Page,
  743.                                      -1, new wxHtmlHelpTreeItemData(i));
  744.             imaged[it->m_Level + 1] = FALSE;
  745.         }
  746.  
  747.         m_PagesHash->Put(it->GetFullPath(),
  748.                            new wxHtmlHelpHashData(i, roots[it->m_Level + 1]));
  749.  
  750.         // Set the icon for the node one level up in the hiearachy,
  751.         // unless already done (see comment above imaged[] declaration)
  752.         if (!imaged[it->m_Level])
  753.         {
  754.             int image = IMG_Folder;
  755.             if (m_hfStyle & wxHF_ICONS_BOOK)
  756.                 image = IMG_Book;
  757.             else if (m_hfStyle & wxHF_ICONS_BOOK_CHAPTER)
  758.                 image = (it->m_Level == 1) ? IMG_Book : IMG_Folder;
  759.             m_ContentsBox->SetItemImage(roots[it->m_Level], image);
  760.             m_ContentsBox->SetItemSelectedImage(roots[it->m_Level], image);
  761.             imaged[it->m_Level] = TRUE;
  762.         }
  763.     }
  764. }
  765.  
  766.  
  767. void wxHtmlHelpFrame::CreateIndex()
  768. {
  769.     if (! m_IndexList)
  770.         return ;
  771.  
  772.     m_IndexList->Clear();
  773.  
  774.     int cnt = m_Data->GetIndexCnt();
  775.  
  776.     wxString cnttext;
  777.     if (cnt > INDEX_IS_SMALL) cnttext.Printf(_("%i of %i"), 0, cnt);
  778.     else cnttext.Printf(_("%i of %i"), cnt, cnt);
  779.     m_IndexCountInfo->SetLabel(cnttext);
  780.     if (cnt > INDEX_IS_SMALL) return;
  781.  
  782.     wxHtmlContentsItem* index = m_Data->GetIndex();
  783.  
  784.     for (int i = 0; i < cnt; i++)
  785.         m_IndexList->Append(index[i].m_Name, (char*)(index + i));
  786. }
  787.  
  788. void wxHtmlHelpFrame::CreateSearch()
  789. {
  790.     if (! (m_SearchList && m_SearchChoice))
  791.         return ;
  792.     m_SearchList->Clear();
  793.     m_SearchChoice->Clear();
  794.     m_SearchChoice->Append(_("Search in all books"));
  795.     const wxHtmlBookRecArray& bookrec = m_Data->GetBookRecArray();
  796.     int i, cnt = bookrec.GetCount();
  797.     for (i = 0; i < cnt; i++)
  798.         m_SearchChoice->Append(bookrec[i].GetTitle());
  799.     m_SearchChoice->SetSelection(0);
  800. }
  801.  
  802.  
  803. void wxHtmlHelpFrame::RefreshLists()
  804. {
  805.     CreateContents();
  806.     CreateIndex();
  807.     CreateSearch();
  808. }
  809.  
  810. void wxHtmlHelpFrame::ReadCustomization(wxConfigBase *cfg, const wxString& path)
  811. {
  812.     wxString oldpath;
  813.     wxString tmp;
  814.  
  815.     if (path != wxEmptyString)
  816.     {
  817.         oldpath = cfg->GetPath();
  818.         cfg->SetPath(_T("/") + path);
  819.     }
  820.  
  821.     m_Cfg.navig_on = cfg->Read(wxT("hcNavigPanel"), m_Cfg.navig_on) != 0;
  822.     m_Cfg.sashpos = cfg->Read(wxT("hcSashPos"), m_Cfg.sashpos);
  823.     m_Cfg.x = cfg->Read(wxT("hcX"), m_Cfg.x);
  824.     m_Cfg.y = cfg->Read(wxT("hcY"), m_Cfg.y);
  825.     m_Cfg.w = cfg->Read(wxT("hcW"), m_Cfg.w);
  826.     m_Cfg.h = cfg->Read(wxT("hcH"), m_Cfg.h);
  827.  
  828.     m_FixedFace = cfg->Read(wxT("hcFixedFace"), m_FixedFace);
  829.     m_NormalFace = cfg->Read(wxT("hcNormalFace"), m_NormalFace);
  830.     m_FontSize = cfg->Read(wxT("hcBaseFontSize"), m_FontSize);
  831.  
  832.     {
  833.         int i;
  834.         int cnt;
  835.         wxString val, s;
  836.  
  837.         cnt = cfg->Read(wxT("hcBookmarksCnt"), 0L);
  838.         if (cnt != 0)
  839.         {
  840.             m_BookmarksNames.Clear();
  841.             m_BookmarksPages.Clear();
  842.             if (m_Bookmarks)
  843.             {
  844.                 m_Bookmarks->Clear();
  845.                 m_Bookmarks->Append(_("(bookmarks)"));
  846.             }
  847.  
  848.             for (i = 0; i < cnt; i++)
  849.             {
  850.                 val.Printf(wxT("hcBookmark_%i"), i);
  851.                 s = cfg->Read(val);
  852.                 m_BookmarksNames.Add(s);
  853.                 if (m_Bookmarks) m_Bookmarks->Append(s);
  854.                 val.Printf(wxT("hcBookmark_%i_url"), i);
  855.                 s = cfg->Read(val);
  856.                 m_BookmarksPages.Add(s);
  857.             }
  858.         }
  859.     }
  860.  
  861.     if (m_HtmlWin)
  862.         m_HtmlWin->ReadCustomization(cfg);
  863.  
  864.     if (path != wxEmptyString)
  865.         cfg->SetPath(oldpath);
  866. }
  867.  
  868. void wxHtmlHelpFrame::WriteCustomization(wxConfigBase *cfg, const wxString& path)
  869. {
  870.     wxString oldpath;
  871.     wxString tmp;
  872.  
  873.     if (path != wxEmptyString)
  874.     {
  875.         oldpath = cfg->GetPath();
  876.         cfg->SetPath(_T("/") + path);
  877.     }
  878.  
  879.     cfg->Write(wxT("hcNavigPanel"), m_Cfg.navig_on);
  880.     cfg->Write(wxT("hcSashPos"), (long)m_Cfg.sashpos);
  881.     if ( !IsIconized() )
  882.     {
  883.         //  Don't write if iconized as this would make the window
  884.         //  disappear next time it is shown!
  885.         cfg->Write(wxT("hcX"), (long)m_Cfg.x);
  886.         cfg->Write(wxT("hcY"), (long)m_Cfg.y);
  887.         cfg->Write(wxT("hcW"), (long)m_Cfg.w);
  888.         cfg->Write(wxT("hcH"), (long)m_Cfg.h);
  889.     }
  890.     cfg->Write(wxT("hcFixedFace"), m_FixedFace);
  891.     cfg->Write(wxT("hcNormalFace"), m_NormalFace);
  892.     cfg->Write(wxT("hcBaseFontSize"), (long)m_FontSize);
  893.  
  894.     if (m_Bookmarks)
  895.     {
  896.         int i;
  897.         int cnt = m_BookmarksNames.GetCount();
  898.         wxString val;
  899.  
  900.         cfg->Write(wxT("hcBookmarksCnt"), (long)cnt);
  901.         for (i = 0; i < cnt; i++)
  902.         {
  903.             val.Printf(wxT("hcBookmark_%i"), i);
  904.             cfg->Write(val, m_BookmarksNames[i]);
  905.             val.Printf(wxT("hcBookmark_%i_url"), i);
  906.             cfg->Write(val, m_BookmarksPages[i]);
  907.         }
  908.     }
  909.  
  910.     if (m_HtmlWin)
  911.         m_HtmlWin->WriteCustomization(cfg);
  912.  
  913.     if (path != wxEmptyString)
  914.         cfg->SetPath(oldpath);
  915. }
  916.  
  917.  
  918.  
  919.  
  920.  
  921. static void SetFontsToHtmlWin(wxHtmlWindow *win, wxString scalf, wxString fixf, int size)
  922. {
  923.     int f_sizes[7];
  924.     f_sizes[0] = int(size * 0.6);
  925.     f_sizes[1] = int(size * 0.8);
  926.     f_sizes[2] = size;
  927.     f_sizes[3] = int(size * 1.2);
  928.     f_sizes[4] = int(size * 1.4);
  929.     f_sizes[5] = int(size * 1.6);
  930.     f_sizes[6] = int(size * 1.8);
  931.  
  932.     win->SetFonts(scalf, fixf, f_sizes);
  933. }
  934.  
  935.  
  936. class wxHtmlHelpFrameOptionsDialog : public wxDialog
  937. {
  938. public:
  939.     wxComboBox *NormalFont, *FixedFont;
  940.     wxSpinCtrl *FontSize;
  941.     wxHtmlWindow *TestWin;
  942.  
  943.     wxHtmlHelpFrameOptionsDialog(wxWindow *parent) 
  944.         : wxDialog(parent, -1, wxString(_("Help Browser Options")))
  945.     {
  946.         wxBoxSizer *topsizer = new wxBoxSizer(wxVERTICAL);
  947.         wxFlexGridSizer *sizer = new wxFlexGridSizer(2, 3, 2, 5);
  948.  
  949.         sizer->Add(new wxStaticText(this, -1, _("Normal font:")));
  950.         sizer->Add(new wxStaticText(this, -1, _("Fixed font:")));
  951.         sizer->Add(new wxStaticText(this, -1, _("Font size:")));
  952.  
  953.         sizer->Add(NormalFont = new wxComboBox(this, -1, wxEmptyString, wxDefaultPosition,
  954.                       wxSize(200, 200),
  955.                       0, NULL, wxCB_DROPDOWN | wxCB_READONLY));
  956.  
  957.         sizer->Add(FixedFont = new wxComboBox(this, -1, wxEmptyString, wxDefaultPosition,
  958.                       wxSize(200, 200),
  959.                       0, NULL, wxCB_DROPDOWN | wxCB_READONLY));
  960.  
  961.         sizer->Add(FontSize = new wxSpinCtrl(this, -1));
  962.         FontSize->SetRange(2, 100);
  963.  
  964.         topsizer->Add(sizer, 0, wxLEFT|wxRIGHT|wxTOP, 10);
  965.  
  966.         topsizer->Add(new wxStaticText(this, -1, _("Preview:")),
  967.                         0, wxLEFT | wxTOP, 10);
  968.         topsizer->Add(TestWin = new wxHtmlWindow(this, -1, wxDefaultPosition, wxSize(20, 150),
  969.                                                  wxHW_SCROLLBAR_AUTO | wxSUNKEN_BORDER),
  970.                         1, wxEXPAND | wxLEFT|wxTOP|wxRIGHT, 10);
  971.  
  972.         wxBoxSizer *sizer2 = new wxBoxSizer(wxHORIZONTAL);
  973.         wxButton *ok;
  974.         sizer2->Add(ok = new wxButton(this, wxID_OK, _("OK")), 0, wxALL, 10);
  975.         ok->SetDefault();
  976.         sizer2->Add(new wxButton(this, wxID_CANCEL, _("Cancel")), 0, wxALL, 10);
  977.         topsizer->Add(sizer2, 0, wxALIGN_RIGHT);
  978.  
  979.         SetAutoLayout(TRUE);
  980.         SetSizer(topsizer);
  981.         topsizer->Fit(this);
  982.         Centre(wxBOTH);
  983.     }
  984.  
  985.  
  986.     void UpdateTestWin()
  987.     {
  988.         wxBusyCursor bcur;
  989.         SetFontsToHtmlWin(TestWin,
  990.                           NormalFont->GetStringSelection(),
  991.                           FixedFont->GetStringSelection(),
  992.                           FontSize->GetValue());
  993.         TestWin->SetPage(_(
  994. "<html><body>\
  995. <table><tr><td>\
  996. Normal face<br>(and <u>underlined</u>. <i>Italic face.</i> \
  997. <b>Bold face.</b> <b><i>Bold italic face.</i></b><br>\
  998. <font size=-2>font size -2</font><br>\
  999. <font size=-1>font size -1</font><br>\
  1000. <font size=+0>font size +0</font><br>\
  1001. <font size=+1>font size +1</font><br>\
  1002. <font size=+2>font size +2</font><br>\
  1003. <font size=+3>font size +3</font><br>\
  1004. <font size=+4>font size +4</font><br>\
  1005. <td>\
  1006. <p><tt>Fixed size face.<br> <b>bold</b> <i>italic</i> \
  1007. <b><i>bold italic <u>underlined</u></i></b><br>\
  1008. <font size=-2>font size -2</font><br>\
  1009. <font size=-1>font size -1</font><br>\
  1010. <font size=+0>font size +0</font><br>\
  1011. <font size=+1>font size +1</font><br>\
  1012. <font size=+2>font size +2</font><br>\
  1013. <font size=+3>font size +3</font><br>\
  1014. <font size=+4>font size +4</font></tt>\
  1015. </table></body></html>"
  1016.                           ));
  1017.     }
  1018.  
  1019.     void OnUpdate(wxCommandEvent& WXUNUSED(event))
  1020.     {
  1021.         UpdateTestWin();
  1022.     }
  1023.     void OnUpdateSpin(wxSpinEvent& WXUNUSED(event))
  1024.     {
  1025.         UpdateTestWin();
  1026.     }
  1027.  
  1028.     DECLARE_EVENT_TABLE()
  1029. };
  1030.  
  1031. BEGIN_EVENT_TABLE(wxHtmlHelpFrameOptionsDialog, wxDialog)
  1032.     EVT_COMBOBOX(-1, wxHtmlHelpFrameOptionsDialog::OnUpdate)
  1033.     EVT_SPINCTRL(-1, wxHtmlHelpFrameOptionsDialog::OnUpdateSpin)
  1034. END_EVENT_TABLE()
  1035.  
  1036.  
  1037. void wxHtmlHelpFrame::OptionsDialog()
  1038. {
  1039.     wxHtmlHelpFrameOptionsDialog dlg(this);
  1040.     unsigned i;
  1041.  
  1042.     if (m_NormalFonts == NULL)
  1043.     {
  1044.         wxFontEnumerator enu;
  1045.         enu.EnumerateFacenames();
  1046.         m_NormalFonts = new wxArrayString;
  1047.         *m_NormalFonts = *enu.GetFacenames();
  1048.         m_NormalFonts->Sort();
  1049.     }
  1050.     if (m_FixedFonts == NULL)
  1051.     {
  1052.         wxFontEnumerator enu;
  1053.         enu.EnumerateFacenames(wxFONTENCODING_SYSTEM, TRUE);
  1054.         m_FixedFonts = new wxArrayString;
  1055.         *m_FixedFonts = *enu.GetFacenames();
  1056.         m_FixedFonts->Sort();
  1057.     }
  1058.     
  1059.     // VS: We want to show the font that is actually used by wxHtmlWindow.
  1060.     //     If customization dialog wasn't used yet, facenames are empty and
  1061.     //     wxHtmlWindow uses default fonts -- let's find out what they
  1062.     //     are so that we can pass them to the dialog:
  1063.     if (m_NormalFace.empty())
  1064.     {
  1065.         wxFont fnt(m_FontSize, wxSWISS, wxNORMAL, wxNORMAL, FALSE);
  1066.         m_NormalFace = fnt.GetFaceName();
  1067.     }
  1068.     if (m_FixedFace.empty())
  1069.     {
  1070.         wxFont fnt(m_FontSize, wxMODERN, wxNORMAL, wxNORMAL, FALSE);
  1071.         m_FixedFace = fnt.GetFaceName();
  1072.     }
  1073.  
  1074.     for (i = 0; i < m_NormalFonts->GetCount(); i++)
  1075.         dlg.NormalFont->Append((*m_NormalFonts)[i]);
  1076.     for (i = 0; i < m_FixedFonts->GetCount(); i++)
  1077.         dlg.FixedFont->Append((*m_FixedFonts)[i]);
  1078.     if (!m_NormalFace.empty())
  1079.         dlg.NormalFont->SetStringSelection(m_NormalFace);
  1080.     else
  1081.         dlg.NormalFont->SetSelection(0);
  1082.     if (!m_FixedFace.empty())
  1083.         dlg.FixedFont->SetStringSelection(m_FixedFace);
  1084.     else
  1085.         dlg.FixedFont->SetSelection(0);
  1086.     dlg.FontSize->SetValue(m_FontSize);
  1087.     dlg.UpdateTestWin();
  1088.  
  1089.     if (dlg.ShowModal() == wxID_OK)
  1090.     {
  1091.         m_NormalFace = dlg.NormalFont->GetStringSelection();
  1092.         m_FixedFace = dlg.FixedFont->GetStringSelection();
  1093.         m_FontSize = dlg.FontSize->GetValue();
  1094.         SetFontsToHtmlWin(m_HtmlWin, m_NormalFace, m_FixedFace, m_FontSize);
  1095.     }
  1096. }
  1097.  
  1098.  
  1099.  
  1100. void wxHtmlHelpFrame::NotifyPageChanged()
  1101. {
  1102.     if (m_UpdateContents && m_PagesHash)
  1103.     {
  1104.         wxString an = m_HtmlWin->GetOpenedAnchor();
  1105.         wxHtmlHelpHashData *ha;
  1106.         if (an.IsEmpty())
  1107.             ha = (wxHtmlHelpHashData*) m_PagesHash->Get(m_HtmlWin->GetOpenedPage());
  1108.         else
  1109.             ha = (wxHtmlHelpHashData*) m_PagesHash->Get(m_HtmlWin->GetOpenedPage() + wxT("#") + an);
  1110.         if (ha)
  1111.         {
  1112.             bool olduc = m_UpdateContents;
  1113.             m_UpdateContents = FALSE;
  1114.             m_ContentsBox->SelectItem(ha->m_Id);
  1115.             m_ContentsBox->EnsureVisible(ha->m_Id);
  1116.             m_UpdateContents = olduc;
  1117.         }
  1118.     }
  1119. }
  1120.  
  1121.  
  1122.  
  1123. /*
  1124. EVENT HANDLING :
  1125. */
  1126.  
  1127.  
  1128. void wxHtmlHelpFrame::OnActivate(wxActivateEvent& event)
  1129. {
  1130.     // This saves one mouse click when using the
  1131.     // wxHTML for context sensitive help systems
  1132. #ifndef __WXGTK__
  1133.     // NB: wxActivateEvent is a bit broken in wxGTK
  1134.     //     and is sometimes sent when it should not be
  1135.     if (event.GetActive() && m_HtmlWin)
  1136.         m_HtmlWin->SetFocus();
  1137. #endif
  1138.  
  1139.     event.Skip();
  1140. }
  1141.  
  1142. void wxHtmlHelpFrame::OnToolbar(wxCommandEvent& event)
  1143. {
  1144.     switch (event.GetId())
  1145.     {
  1146.         case wxID_HTML_BACK :
  1147.             m_HtmlWin->HistoryBack();
  1148.             NotifyPageChanged();
  1149.             break;
  1150.  
  1151.         case wxID_HTML_FORWARD :
  1152.             m_HtmlWin->HistoryForward();
  1153.             NotifyPageChanged();
  1154.             break;
  1155.  
  1156.         case wxID_HTML_UP :
  1157.             if (m_PagesHash)
  1158.             {
  1159.                 wxString an = m_HtmlWin->GetOpenedAnchor();
  1160.                 wxHtmlHelpHashData *ha;
  1161.                 if (an.IsEmpty())
  1162.                     ha = (wxHtmlHelpHashData*) m_PagesHash->Get(m_HtmlWin->GetOpenedPage());
  1163.                 else
  1164.                     ha = (wxHtmlHelpHashData*) m_PagesHash->Get(m_HtmlWin->GetOpenedPage() + wxT("#") + an);
  1165.                 if (ha && ha->m_Index > 0)
  1166.                 {
  1167.                     wxHtmlContentsItem *it = m_Data->GetContents() + (ha->m_Index - 1);
  1168.                     if (it->m_Page[0] != 0)
  1169.                     {
  1170.                         m_HtmlWin->LoadPage(it->GetFullPath());
  1171.                         NotifyPageChanged();
  1172.                     }
  1173.                 }
  1174.             }
  1175.             break;
  1176.  
  1177.         case wxID_HTML_UPNODE :
  1178.             if (m_PagesHash)
  1179.             {
  1180.                 wxString an = m_HtmlWin->GetOpenedAnchor();
  1181.                 wxHtmlHelpHashData *ha;
  1182.                 if (an.IsEmpty())
  1183.                     ha = (wxHtmlHelpHashData*) m_PagesHash->Get(m_HtmlWin->GetOpenedPage());
  1184.                 else
  1185.                     ha = (wxHtmlHelpHashData*) m_PagesHash->Get(m_HtmlWin->GetOpenedPage() + wxT("#") + an);
  1186.                 if (ha && ha->m_Index > 0)
  1187.                 {
  1188.                     int level = m_Data->GetContents()[ha->m_Index].m_Level - 1;
  1189.                     wxHtmlContentsItem *it;
  1190.                     int ind = ha->m_Index - 1;
  1191.  
  1192.                     it = m_Data->GetContents() + ind;
  1193.                     while (ind >= 0 && it->m_Level != level) ind--, it--;
  1194.                     if (ind >= 0)
  1195.                     {
  1196.                         if (it->m_Page[0] != 0)
  1197.                         {
  1198.                             m_HtmlWin->LoadPage(it->GetFullPath());
  1199.                             NotifyPageChanged();
  1200.                         }
  1201.                     }
  1202.                 }
  1203.             }
  1204.             break;
  1205.  
  1206.         case wxID_HTML_DOWN :
  1207.             if (m_PagesHash)
  1208.             {
  1209.                 wxString an = m_HtmlWin->GetOpenedAnchor();
  1210.                 wxString adr;
  1211.                 wxHtmlHelpHashData *ha;
  1212.  
  1213.                 if (an.IsEmpty()) adr = m_HtmlWin->GetOpenedPage();
  1214.                 else adr = m_HtmlWin->GetOpenedPage() + wxT("#") + an;
  1215.  
  1216.                 ha = (wxHtmlHelpHashData*) m_PagesHash->Get(adr);
  1217.  
  1218.                 if (ha && ha->m_Index < m_Data->GetContentsCnt() - 1)
  1219.                 {
  1220.                     wxHtmlContentsItem *it = m_Data->GetContents() + (ha->m_Index + 1);
  1221.  
  1222.                     while (it->GetFullPath() == adr) it++;
  1223.  
  1224.                     if (it->m_Page[0] != 0)
  1225.                     {
  1226.                         m_HtmlWin->LoadPage(it->GetFullPath());
  1227.                         NotifyPageChanged();
  1228.                     }
  1229.                 }
  1230.             }
  1231.             break;
  1232.  
  1233.         case wxID_HTML_PANEL :
  1234.             {
  1235.                 if (! (m_Splitter && m_NavigPan))
  1236.                     return ;
  1237.                 if (m_Splitter->IsSplit())
  1238.                 {
  1239.                     m_Cfg.sashpos = m_Splitter->GetSashPosition();
  1240.                     m_Splitter->Unsplit(m_NavigPan);
  1241.                     m_Cfg.navig_on = FALSE;
  1242.                 }
  1243.                 else
  1244.                 {
  1245.                     m_NavigPan->Show(TRUE);
  1246.                     m_HtmlWin->Show(TRUE);
  1247.                     m_Splitter->SplitVertically(m_NavigPan, m_HtmlWin, m_Cfg.sashpos);
  1248.                     m_Cfg.navig_on = TRUE;
  1249.                 }
  1250.             }
  1251.             break;
  1252.  
  1253.         case wxID_HTML_OPTIONS :
  1254.             OptionsDialog();
  1255.             break;
  1256.  
  1257.         case wxID_HTML_BOOKMARKSADD :
  1258.             {
  1259.                 wxString item;
  1260.                 wxString url;
  1261.  
  1262.                 item = m_HtmlWin->GetOpenedPageTitle();
  1263.                 url = m_HtmlWin->GetOpenedPage();
  1264.                 if (item == wxEmptyString)
  1265.                     item = url.AfterLast(wxT('/'));
  1266.                 if (m_BookmarksPages.Index(url) == wxNOT_FOUND)
  1267.                 {
  1268.                     m_Bookmarks->Append(item);
  1269.                     m_BookmarksNames.Add(item);
  1270.                     m_BookmarksPages.Add(url);
  1271.                 }
  1272.             }
  1273.             break;
  1274.  
  1275.         case wxID_HTML_BOOKMARKSREMOVE :
  1276.             {
  1277.                 wxString item;
  1278.                 int pos;
  1279.  
  1280.                 item = m_Bookmarks->GetStringSelection();
  1281.                 pos = m_BookmarksNames.Index(item);
  1282.                 if (pos != wxNOT_FOUND)
  1283.                 {
  1284.                     m_BookmarksNames.Remove(pos);
  1285.                     m_BookmarksPages.Remove(pos);
  1286.                     m_Bookmarks->Delete(m_Bookmarks->GetSelection());
  1287.                 }
  1288.             }
  1289.             break;
  1290.  
  1291. #if wxUSE_PRINTING_ARCHITECTURE
  1292.         case wxID_HTML_PRINT :
  1293.             {
  1294.                 if (m_Printer == NULL)
  1295.                     m_Printer = new wxHtmlEasyPrinting(_("Help Printing"), this);
  1296.                 if (!m_HtmlWin->GetOpenedPage())
  1297.                     wxLogWarning(_("Cannot print empty page."));
  1298.                 else
  1299.                     m_Printer->PrintFile(m_HtmlWin->GetOpenedPage());
  1300.             }
  1301.             break;
  1302. #endif
  1303.  
  1304.         case wxID_HTML_OPENFILE :
  1305.             {
  1306.                 wxString s = wxFileSelector(_("Open HTML document"),
  1307.                                             wxEmptyString,
  1308.                                             wxEmptyString,
  1309.                                             wxEmptyString,
  1310.                                             _(
  1311. "HTML files (*.htm)|*.htm|HTML files (*.html)|*.html|\
  1312. Help books (*.htb)|*.htb|Help books (*.zip)|*.zip|\
  1313. HTML Help Project (*.hhp)|*.hhp|\
  1314. All files (*.*)|*"
  1315.                                             ),
  1316.                                             wxOPEN | wxFILE_MUST_EXIST,
  1317.                                             this);
  1318.                 if (!s.IsEmpty())
  1319.                 {
  1320.                     wxString ext = s.Right(4).Lower();
  1321.                     if (ext == _T(".zip") || ext == _T(".htb") || ext == _T(".hhp"))
  1322.                     {
  1323.                         wxBusyCursor bcur;
  1324.                         m_Data->AddBook(s);
  1325.                         RefreshLists();
  1326.                     }
  1327.                     else
  1328.                         m_HtmlWin->LoadPage(s);
  1329.                 }
  1330.             }
  1331.             break;
  1332.     }
  1333. }
  1334.  
  1335.  
  1336.  
  1337. void wxHtmlHelpFrame::OnContentsSel(wxTreeEvent& event)
  1338. {
  1339.     wxHtmlHelpTreeItemData *pg;
  1340.     wxHtmlContentsItem *it;
  1341.  
  1342.     pg = (wxHtmlHelpTreeItemData*) m_ContentsBox->GetItemData(event.GetItem());
  1343.  
  1344.     if (pg && m_UpdateContents)
  1345.     {
  1346.         it = m_Data->GetContents() + (pg->m_Id);
  1347.         m_UpdateContents = FALSE;
  1348.         if (it->m_Page[0] != 0)
  1349.             m_HtmlWin->LoadPage(it->GetFullPath());
  1350.         m_UpdateContents = TRUE;
  1351.     }
  1352. }
  1353.  
  1354.  
  1355.  
  1356. void wxHtmlHelpFrame::OnIndexSel(wxCommandEvent& WXUNUSED(event))
  1357. {
  1358.     wxHtmlContentsItem *it = (wxHtmlContentsItem*) m_IndexList->GetClientData(m_IndexList->GetSelection());
  1359.     if (it->m_Page[0] != 0)
  1360.         m_HtmlWin->LoadPage(it->GetFullPath());
  1361.     NotifyPageChanged();
  1362. }
  1363.  
  1364.  
  1365. void wxHtmlHelpFrame::OnIndexFind(wxCommandEvent& event)
  1366. {
  1367.     wxString sr = m_IndexText->GetLineText(0);
  1368.     sr.MakeLower();
  1369.     if (sr == wxEmptyString)
  1370.     {
  1371.         OnIndexAll(event);
  1372.     }
  1373.     else
  1374.     {
  1375.         wxBusyCursor bcur;
  1376.         const wxChar *cstr = sr.c_str();
  1377.         wxChar mybuff[512];
  1378.         wxChar *ptr;
  1379.         bool first = TRUE;
  1380.  
  1381.         m_IndexList->Clear();
  1382.         int cnt = m_Data->GetIndexCnt();
  1383.         wxHtmlContentsItem* index = m_Data->GetIndex();
  1384.  
  1385.         int displ = 0;
  1386.         for (int i = 0; i < cnt; i++)
  1387.         {
  1388.             wxStrncpy(mybuff, index[i].m_Name, 512);
  1389.             mybuff[511] = _T('\0');
  1390.             for (ptr = mybuff; *ptr != 0; ptr++)
  1391.                 if (*ptr >= _T('A') && *ptr <= _T('Z'))
  1392.                     *ptr -= (wxChar)(_T('A') - _T('a'));
  1393.             if (wxStrstr(mybuff, cstr) != NULL)
  1394.             {
  1395.                 m_IndexList->Append(index[i].m_Name, (char*)(index + i));
  1396.                 displ++;
  1397.                 if (first)
  1398.                 {
  1399.                     if (index[i].m_Page[0] != 0)
  1400.                         m_HtmlWin->LoadPage(index[i].GetFullPath());
  1401.                     NotifyPageChanged();
  1402.                     first = FALSE;
  1403.                 }
  1404.             }
  1405.         }
  1406.  
  1407.         wxString cnttext;
  1408.         cnttext.Printf(_("%i of %i"), displ, cnt);
  1409.         m_IndexCountInfo->SetLabel(cnttext);
  1410.  
  1411.         m_IndexText->SetSelection(0, sr.Length());
  1412.         m_IndexText->SetFocus();
  1413.     }
  1414. }
  1415.  
  1416. void wxHtmlHelpFrame::OnIndexAll(wxCommandEvent& WXUNUSED(event))
  1417. {
  1418.     wxBusyCursor bcur;
  1419.  
  1420.     m_IndexList->Clear();
  1421.     int cnt = m_Data->GetIndexCnt();
  1422.     bool first = TRUE;
  1423.     wxHtmlContentsItem* index = m_Data->GetIndex();
  1424.  
  1425.     for (int i = 0; i < cnt; i++)
  1426.     {
  1427.         m_IndexList->Append(index[i].m_Name, (char*)(index + i));
  1428.         if (first)
  1429.         {
  1430.             if (index[i].m_Page[0] != 0)
  1431.                 m_HtmlWin->LoadPage(index[i].GetFullPath());
  1432.             NotifyPageChanged();
  1433.             first = FALSE;
  1434.         }
  1435.     }
  1436.  
  1437.     wxString cnttext;
  1438.     cnttext.Printf(_("%i of %i"), cnt, cnt);
  1439.     m_IndexCountInfo->SetLabel(cnttext);
  1440. }
  1441.  
  1442.  
  1443. void wxHtmlHelpFrame::OnSearchSel(wxCommandEvent& WXUNUSED(event))
  1444. {
  1445.     wxHtmlContentsItem *it = (wxHtmlContentsItem*) m_SearchList->GetClientData(m_SearchList->GetSelection());
  1446.     if (it)
  1447.     {
  1448.         if (it->m_Page[0] != 0)
  1449.             m_HtmlWin->LoadPage(it->GetFullPath());
  1450.         NotifyPageChanged();
  1451.     }
  1452. }
  1453.  
  1454. void wxHtmlHelpFrame::OnSearch(wxCommandEvent& WXUNUSED(event))
  1455. {
  1456.     wxString sr = m_SearchText->GetLineText(0);
  1457.  
  1458.     if (sr != wxEmptyString) KeywordSearch(sr);
  1459. }
  1460.  
  1461. void wxHtmlHelpFrame::OnBookmarksSel(wxCommandEvent& WXUNUSED(event))
  1462. {
  1463.     wxString sr = m_Bookmarks->GetStringSelection();
  1464.  
  1465.     if (sr != wxEmptyString && sr != _("(bookmarks)"))
  1466.     {
  1467.        m_HtmlWin->LoadPage(m_BookmarksPages[m_BookmarksNames.Index(sr)]);
  1468.        NotifyPageChanged();
  1469.     }
  1470. }
  1471.  
  1472. void wxHtmlHelpFrame::OnCloseWindow(wxCloseEvent& evt)
  1473. {
  1474.     GetSize(&m_Cfg.w, &m_Cfg.h);
  1475.     GetPosition(&m_Cfg.x, &m_Cfg.y);
  1476.  
  1477. #ifdef __WXGTK__
  1478.     if (IsGrabbed())
  1479.     {
  1480.         RemoveGrab();
  1481.     }
  1482. #endif
  1483.     
  1484.     if (m_Splitter && m_Cfg.navig_on) m_Cfg.sashpos = m_Splitter->GetSashPosition();
  1485.  
  1486.     if (m_Config)
  1487.         WriteCustomization(m_Config, m_ConfigRoot);
  1488.  
  1489.     if (m_helpController && m_helpController->IsKindOf(CLASSINFO(wxHtmlHelpController)))
  1490.     {
  1491.         ((wxHtmlHelpController*) m_helpController)->OnCloseFrame(evt);
  1492.     }
  1493.  
  1494.     evt.Skip();
  1495. }
  1496.  
  1497. BEGIN_EVENT_TABLE(wxHtmlHelpFrame, wxFrame)
  1498.     EVT_ACTIVATE(wxHtmlHelpFrame::OnActivate)
  1499.     EVT_TOOL_RANGE(wxID_HTML_PANEL, wxID_HTML_OPTIONS, wxHtmlHelpFrame::OnToolbar)
  1500.     EVT_BUTTON(wxID_HTML_BOOKMARKSREMOVE, wxHtmlHelpFrame::OnToolbar)
  1501.     EVT_BUTTON(wxID_HTML_BOOKMARKSADD, wxHtmlHelpFrame::OnToolbar)
  1502.     EVT_TREE_SEL_CHANGED(wxID_HTML_TREECTRL, wxHtmlHelpFrame::OnContentsSel)
  1503.     EVT_LISTBOX(wxID_HTML_INDEXLIST, wxHtmlHelpFrame::OnIndexSel)
  1504.     EVT_LISTBOX(wxID_HTML_SEARCHLIST, wxHtmlHelpFrame::OnSearchSel)
  1505.     EVT_BUTTON(wxID_HTML_SEARCHBUTTON, wxHtmlHelpFrame::OnSearch)
  1506.     EVT_TEXT_ENTER(wxID_HTML_SEARCHTEXT, wxHtmlHelpFrame::OnSearch)
  1507.     EVT_BUTTON(wxID_HTML_INDEXBUTTON, wxHtmlHelpFrame::OnIndexFind)
  1508.     EVT_TEXT_ENTER(wxID_HTML_INDEXTEXT, wxHtmlHelpFrame::OnIndexFind)
  1509.     EVT_BUTTON(wxID_HTML_INDEXBUTTONALL, wxHtmlHelpFrame::OnIndexAll)
  1510.     EVT_COMBOBOX(wxID_HTML_BOOKMARKSLIST, wxHtmlHelpFrame::OnBookmarksSel)
  1511.     EVT_CLOSE(wxHtmlHelpFrame::OnCloseWindow)
  1512. END_EVENT_TABLE()
  1513.  
  1514. #endif // wxUSE_WXHTML_HELP
  1515.  
  1516.