home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / wxos2233.zip / wxOS2-2_3_3.zip / wxWindows-2.3.3 / src / html / helpfrm.cpp < prev    next >
C/C++ Source or Header  |  2002-09-04  |  50KB  |  1,501 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.71 2002/09/01 11:41:01 VS 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.     cfg->Write(wxT("hcX"), (long)m_Cfg.x);
  882.     cfg->Write(wxT("hcY"), (long)m_Cfg.y);
  883.     cfg->Write(wxT("hcW"), (long)m_Cfg.w);
  884.     cfg->Write(wxT("hcH"), (long)m_Cfg.h);
  885.     cfg->Write(wxT("hcFixedFace"), m_FixedFace);
  886.     cfg->Write(wxT("hcNormalFace"), m_NormalFace);
  887.     cfg->Write(wxT("hcBaseFontSize"), (long)m_FontSize);
  888.  
  889.     if (m_Bookmarks)
  890.     {
  891.         int i;
  892.         int cnt = m_BookmarksNames.GetCount();
  893.         wxString val;
  894.  
  895.         cfg->Write(wxT("hcBookmarksCnt"), (long)cnt);
  896.         for (i = 0; i < cnt; i++)
  897.         {
  898.             val.Printf(wxT("hcBookmark_%i"), i);
  899.             cfg->Write(val, m_BookmarksNames[i]);
  900.             val.Printf(wxT("hcBookmark_%i_url"), i);
  901.             cfg->Write(val, m_BookmarksPages[i]);
  902.         }
  903.     }
  904.  
  905.     if (m_HtmlWin)
  906.         m_HtmlWin->WriteCustomization(cfg);
  907.  
  908.     if (path != wxEmptyString)
  909.         cfg->SetPath(oldpath);
  910. }
  911.  
  912.  
  913.  
  914.  
  915.  
  916. static void SetFontsToHtmlWin(wxHtmlWindow *win, wxString scalf, wxString fixf, int size)
  917. {
  918.     int f_sizes[7];
  919.     f_sizes[0] = int(size * 0.6);
  920.     f_sizes[1] = int(size * 0.8);
  921.     f_sizes[2] = size;
  922.     f_sizes[3] = int(size * 1.2);
  923.     f_sizes[4] = int(size * 1.4);
  924.     f_sizes[5] = int(size * 1.6);
  925.     f_sizes[6] = int(size * 1.8);
  926.  
  927.     win->SetFonts(scalf, fixf, f_sizes);
  928. }
  929.  
  930.  
  931. class wxHtmlHelpFrameOptionsDialog : public wxDialog
  932. {
  933. public:
  934.     wxComboBox *NormalFont, *FixedFont;
  935.     wxSpinCtrl *FontSize;
  936.     wxHtmlWindow *TestWin;
  937.  
  938.     wxHtmlHelpFrameOptionsDialog(wxWindow *parent) 
  939.         : wxDialog(parent, -1, wxString(_("Help Browser Options")))
  940.     {
  941.         wxBoxSizer *topsizer = new wxBoxSizer(wxVERTICAL);
  942.         wxFlexGridSizer *sizer = new wxFlexGridSizer(2, 3, 2, 5);
  943.  
  944.         sizer->Add(new wxStaticText(this, -1, _("Normal font:")));
  945.         sizer->Add(new wxStaticText(this, -1, _("Fixed font:")));
  946.         sizer->Add(new wxStaticText(this, -1, _("Font size:")));
  947.  
  948.         sizer->Add(NormalFont = new wxComboBox(this, -1, wxEmptyString, wxDefaultPosition,
  949.                       wxSize(200, 200),
  950.                       0, NULL, wxCB_DROPDOWN | wxCB_READONLY));
  951.  
  952.         sizer->Add(FixedFont = new wxComboBox(this, -1, wxEmptyString, wxDefaultPosition,
  953.                       wxSize(200, 200),
  954.                       0, NULL, wxCB_DROPDOWN | wxCB_READONLY));
  955.  
  956.         sizer->Add(FontSize = new wxSpinCtrl(this, -1));
  957.         FontSize->SetRange(2, 100);
  958.  
  959.         topsizer->Add(sizer, 0, wxLEFT|wxRIGHT|wxTOP, 10);
  960.  
  961.         topsizer->Add(new wxStaticText(this, -1, _("Preview:")),
  962.                         0, wxLEFT | wxTOP, 10);
  963.         topsizer->Add(TestWin = new wxHtmlWindow(this, -1, wxDefaultPosition, wxSize(20, 150),
  964.                                                  wxHW_SCROLLBAR_AUTO | wxSUNKEN_BORDER),
  965.                         1, wxEXPAND | wxLEFT|wxTOP|wxRIGHT, 10);
  966.  
  967.         wxBoxSizer *sizer2 = new wxBoxSizer(wxHORIZONTAL);
  968.         wxButton *ok;
  969.         sizer2->Add(ok = new wxButton(this, wxID_OK, _("OK")), 0, wxALL, 10);
  970.         ok->SetDefault();
  971.         sizer2->Add(new wxButton(this, wxID_CANCEL, _("Cancel")), 0, wxALL, 10);
  972.         topsizer->Add(sizer2, 0, wxALIGN_RIGHT);
  973.  
  974.         SetAutoLayout(TRUE);
  975.         SetSizer(topsizer);
  976.         topsizer->Fit(this);
  977.         Centre(wxBOTH);
  978.     }
  979.  
  980.  
  981.     void UpdateTestWin()
  982.     {
  983.         wxBusyCursor bcur;
  984.         SetFontsToHtmlWin(TestWin,
  985.                           NormalFont->GetStringSelection(),
  986.                           FixedFont->GetStringSelection(),
  987.                           FontSize->GetValue());
  988.         TestWin->SetPage(_(
  989. "<html><body>\
  990. <table><tr><td>\
  991. Normal face<br>(and <u>underlined</u>. <i>Italic face.</i> \
  992. <b>Bold face.</b> <b><i>Bold italic face.</i></b><br>\
  993. <font size=-2>font size -2</font><br>\
  994. <font size=-1>font size -1</font><br>\
  995. <font size=+0>font size +0</font><br>\
  996. <font size=+1>font size +1</font><br>\
  997. <font size=+2>font size +2</font><br>\
  998. <font size=+3>font size +3</font><br>\
  999. <font size=+4>font size +4</font><br>\
  1000. <td>\
  1001. <p><tt>Fixed size face.<br> <b>bold</b> <i>italic</i> \
  1002. <b><i>bold italic <u>underlined</u></i></b><br>\
  1003. <font size=-2>font size -2</font><br>\
  1004. <font size=-1>font size -1</font><br>\
  1005. <font size=+0>font size +0</font><br>\
  1006. <font size=+1>font size +1</font><br>\
  1007. <font size=+2>font size +2</font><br>\
  1008. <font size=+3>font size +3</font><br>\
  1009. <font size=+4>font size +4</font></tt>\
  1010. </table></body></html>"
  1011.                           ));
  1012.     }
  1013.  
  1014.     void OnUpdate(wxCommandEvent& WXUNUSED(event))
  1015.     {
  1016.         UpdateTestWin();
  1017.     }
  1018.  
  1019.     DECLARE_EVENT_TABLE()
  1020. };
  1021.  
  1022. BEGIN_EVENT_TABLE(wxHtmlHelpFrameOptionsDialog, wxDialog)
  1023.     EVT_COMBOBOX(-1, wxHtmlHelpFrameOptionsDialog::OnUpdate)
  1024.     EVT_SPINCTRL(-1, wxHtmlHelpFrameOptionsDialog::OnUpdate)
  1025. END_EVENT_TABLE()
  1026.  
  1027.  
  1028. void wxHtmlHelpFrame::OptionsDialog()
  1029. {
  1030.     wxHtmlHelpFrameOptionsDialog dlg(this);
  1031.     unsigned i;
  1032.  
  1033.     if (m_NormalFonts == NULL)
  1034.     {
  1035.         wxFontEnumerator enu;
  1036.         enu.EnumerateFacenames();
  1037.         m_NormalFonts = new wxArrayString;
  1038.         *m_NormalFonts = *enu.GetFacenames();
  1039.         m_NormalFonts->Sort();
  1040.     }
  1041.     if (m_FixedFonts == NULL)
  1042.     {
  1043.         wxFontEnumerator enu;
  1044.         enu.EnumerateFacenames(wxFONTENCODING_SYSTEM, TRUE);
  1045.         m_FixedFonts = new wxArrayString;
  1046.         *m_FixedFonts = *enu.GetFacenames();
  1047.         m_FixedFonts->Sort();
  1048.     }
  1049.     
  1050.     // VS: We want to show the font that is actually used by wxHtmlWindow.
  1051.     //     If customization dialog wasn't used yet, facenames are empty and
  1052.     //     wxHtmlWindow uses default fonts -- let's find out what they
  1053.     //     are so that we can pass them to the dialog:
  1054.     if (m_NormalFace.empty())
  1055.     {
  1056.         wxFont fnt(m_FontSize, wxSWISS, wxNORMAL, wxNORMAL, FALSE);
  1057.         m_NormalFace = fnt.GetFaceName();
  1058.     }
  1059.     if (m_FixedFace.empty())
  1060.     {
  1061.         wxFont fnt(m_FontSize, wxMODERN, wxNORMAL, wxNORMAL, FALSE);
  1062.         m_FixedFace = fnt.GetFaceName();
  1063.     }
  1064.  
  1065.     for (i = 0; i < m_NormalFonts->GetCount(); i++)
  1066.         dlg.NormalFont->Append((*m_NormalFonts)[i]);
  1067.     for (i = 0; i < m_FixedFonts->GetCount(); i++)
  1068.         dlg.FixedFont->Append((*m_FixedFonts)[i]);
  1069.     if (!m_NormalFace.empty())
  1070.         dlg.NormalFont->SetStringSelection(m_NormalFace);
  1071.     else
  1072.         dlg.NormalFont->SetSelection(0);
  1073.     if (!m_FixedFace.empty())
  1074.         dlg.FixedFont->SetStringSelection(m_FixedFace);
  1075.     else
  1076.         dlg.FixedFont->SetSelection(0);
  1077.     dlg.FontSize->SetValue(m_FontSize);
  1078.     dlg.UpdateTestWin();
  1079.  
  1080.     if (dlg.ShowModal() == wxID_OK)
  1081.     {
  1082.         m_NormalFace = dlg.NormalFont->GetStringSelection();
  1083.         m_FixedFace = dlg.FixedFont->GetStringSelection();
  1084.         m_FontSize = dlg.FontSize->GetValue();
  1085.         SetFontsToHtmlWin(m_HtmlWin, m_NormalFace, m_FixedFace, m_FontSize);
  1086.     }
  1087. }
  1088.  
  1089.  
  1090.  
  1091. void wxHtmlHelpFrame::NotifyPageChanged()
  1092. {
  1093.     if (m_UpdateContents && m_PagesHash)
  1094.     {
  1095.         wxString an = m_HtmlWin->GetOpenedAnchor();
  1096.         wxHtmlHelpHashData *ha;
  1097.         if (an.IsEmpty())
  1098.             ha = (wxHtmlHelpHashData*) m_PagesHash->Get(m_HtmlWin->GetOpenedPage());
  1099.         else
  1100.             ha = (wxHtmlHelpHashData*) m_PagesHash->Get(m_HtmlWin->GetOpenedPage() + wxT("#") + an);
  1101.         if (ha)
  1102.         {
  1103.             bool olduc = m_UpdateContents;
  1104.             m_UpdateContents = FALSE;
  1105.             m_ContentsBox->SelectItem(ha->m_Id);
  1106.             m_ContentsBox->EnsureVisible(ha->m_Id);
  1107.             m_UpdateContents = olduc;
  1108.         }
  1109.     }
  1110. }
  1111.  
  1112.  
  1113.  
  1114. /*
  1115. EVENT HANDLING :
  1116. */
  1117.  
  1118.  
  1119. void wxHtmlHelpFrame::OnActivate(wxActivateEvent& event)
  1120. {
  1121.     // This saves one mouse click when using the
  1122.     // wxHTML for context sensitive help systems
  1123.     if (event.GetActive() && m_HtmlWin)
  1124.         m_HtmlWin->SetFocus();
  1125. }
  1126.  
  1127. void wxHtmlHelpFrame::OnToolbar(wxCommandEvent& event)
  1128. {
  1129.     switch (event.GetId())
  1130.     {
  1131.         case wxID_HTML_BACK :
  1132.             m_HtmlWin->HistoryBack();
  1133.             NotifyPageChanged();
  1134.             break;
  1135.  
  1136.         case wxID_HTML_FORWARD :
  1137.             m_HtmlWin->HistoryForward();
  1138.             NotifyPageChanged();
  1139.             break;
  1140.  
  1141.         case wxID_HTML_UP :
  1142.             if (m_PagesHash)
  1143.             {
  1144.                 wxString an = m_HtmlWin->GetOpenedAnchor();
  1145.                 wxHtmlHelpHashData *ha;
  1146.                 if (an.IsEmpty())
  1147.                     ha = (wxHtmlHelpHashData*) m_PagesHash->Get(m_HtmlWin->GetOpenedPage());
  1148.                 else
  1149.                     ha = (wxHtmlHelpHashData*) m_PagesHash->Get(m_HtmlWin->GetOpenedPage() + wxT("#") + an);
  1150.                 if (ha && ha->m_Index > 0)
  1151.                 {
  1152.                     wxHtmlContentsItem *it = m_Data->GetContents() + (ha->m_Index - 1);
  1153.                     if (it->m_Page[0] != 0)
  1154.                     {
  1155.                         m_HtmlWin->LoadPage(it->GetFullPath());
  1156.                         NotifyPageChanged();
  1157.                     }
  1158.                 }
  1159.             }
  1160.             break;
  1161.  
  1162.         case wxID_HTML_UPNODE :
  1163.             if (m_PagesHash)
  1164.             {
  1165.                 wxString an = m_HtmlWin->GetOpenedAnchor();
  1166.                 wxHtmlHelpHashData *ha;
  1167.                 if (an.IsEmpty())
  1168.                     ha = (wxHtmlHelpHashData*) m_PagesHash->Get(m_HtmlWin->GetOpenedPage());
  1169.                 else
  1170.                     ha = (wxHtmlHelpHashData*) m_PagesHash->Get(m_HtmlWin->GetOpenedPage() + wxT("#") + an);
  1171.                 if (ha && ha->m_Index > 0)
  1172.                 {
  1173.                     int level = m_Data->GetContents()[ha->m_Index].m_Level - 1;
  1174.                     wxHtmlContentsItem *it;
  1175.                     int ind = ha->m_Index - 1;
  1176.  
  1177.                     it = m_Data->GetContents() + ind;
  1178.                     while (ind >= 0 && it->m_Level != level) ind--, it--;
  1179.                     if (ind >= 0)
  1180.                     {
  1181.                         if (it->m_Page[0] != 0)
  1182.                         {
  1183.                             m_HtmlWin->LoadPage(it->GetFullPath());
  1184.                             NotifyPageChanged();
  1185.                         }
  1186.                     }
  1187.                 }
  1188.             }
  1189.             break;
  1190.  
  1191.         case wxID_HTML_DOWN :
  1192.             if (m_PagesHash)
  1193.             {
  1194.                 wxString an = m_HtmlWin->GetOpenedAnchor();
  1195.                 wxString adr;
  1196.                 wxHtmlHelpHashData *ha;
  1197.  
  1198.                 if (an.IsEmpty()) adr = m_HtmlWin->GetOpenedPage();
  1199.                 else adr = m_HtmlWin->GetOpenedPage() + wxT("#") + an;
  1200.  
  1201.                 ha = (wxHtmlHelpHashData*) m_PagesHash->Get(adr);
  1202.  
  1203.                 if (ha && ha->m_Index < m_Data->GetContentsCnt() - 1)
  1204.                 {
  1205.                     wxHtmlContentsItem *it = m_Data->GetContents() + (ha->m_Index + 1);
  1206.  
  1207.                     while (it->GetFullPath() == adr) it++;
  1208.  
  1209.                     if (it->m_Page[0] != 0)
  1210.                     {
  1211.                         m_HtmlWin->LoadPage(it->GetFullPath());
  1212.                         NotifyPageChanged();
  1213.                     }
  1214.                 }
  1215.             }
  1216.             break;
  1217.  
  1218.         case wxID_HTML_PANEL :
  1219.             {
  1220.                 if (! (m_Splitter && m_NavigPan))
  1221.                     return ;
  1222.                 if (m_Splitter->IsSplit())
  1223.                 {
  1224.                     m_Cfg.sashpos = m_Splitter->GetSashPosition();
  1225.                     m_Splitter->Unsplit(m_NavigPan);
  1226.                     m_Cfg.navig_on = FALSE;
  1227.                 }
  1228.                 else
  1229.                 {
  1230.                     m_NavigPan->Show(TRUE);
  1231.                     m_HtmlWin->Show(TRUE);
  1232.                     m_Splitter->SplitVertically(m_NavigPan, m_HtmlWin, m_Cfg.sashpos);
  1233.                     m_Cfg.navig_on = TRUE;
  1234.                 }
  1235.             }
  1236.             break;
  1237.  
  1238.         case wxID_HTML_OPTIONS :
  1239.             OptionsDialog();
  1240.             break;
  1241.  
  1242.         case wxID_HTML_BOOKMARKSADD :
  1243.             {
  1244.                 wxString item;
  1245.                 wxString url;
  1246.  
  1247.                 item = m_HtmlWin->GetOpenedPageTitle();
  1248.                 url = m_HtmlWin->GetOpenedPage();
  1249.                 if (item == wxEmptyString)
  1250.                     item = url.AfterLast(wxT('/'));
  1251.                 if (m_BookmarksPages.Index(url) == wxNOT_FOUND)
  1252.                 {
  1253.                     m_Bookmarks->Append(item);
  1254.                     m_BookmarksNames.Add(item);
  1255.                     m_BookmarksPages.Add(url);
  1256.                 }
  1257.             }
  1258.             break;
  1259.  
  1260.         case wxID_HTML_BOOKMARKSREMOVE :
  1261.             {
  1262.                 wxString item;
  1263.                 int pos;
  1264.  
  1265.                 item = m_Bookmarks->GetStringSelection();
  1266.                 pos = m_BookmarksNames.Index(item);
  1267.                 if (pos != wxNOT_FOUND)
  1268.                 {
  1269.                     m_BookmarksNames.Remove(pos);
  1270.                     m_BookmarksPages.Remove(pos);
  1271.                     m_Bookmarks->Delete(m_Bookmarks->GetSelection());
  1272.                 }
  1273.             }
  1274.             break;
  1275.  
  1276. #if wxUSE_PRINTING_ARCHITECTURE
  1277.         case wxID_HTML_PRINT :
  1278.             {
  1279.                 if (m_Printer == NULL)
  1280.                     m_Printer = new wxHtmlEasyPrinting(_("Help Printing"), this);
  1281.                 if (!m_HtmlWin->GetOpenedPage())
  1282.                     wxLogWarning(_("Cannot print empty page."));
  1283.                 else
  1284.                     m_Printer->PrintFile(m_HtmlWin->GetOpenedPage());
  1285.             }
  1286.             break;
  1287. #endif
  1288.  
  1289.         case wxID_HTML_OPENFILE :
  1290.             {
  1291.                 wxString s = wxFileSelector(_("Open HTML document"),
  1292.                                             wxEmptyString,
  1293.                                             wxEmptyString,
  1294.                                             wxEmptyString,
  1295.                                             _(
  1296. "HTML files (*.htm)|*.htm|HTML files (*.html)|*.html|\
  1297. Help books (*.htb)|*.htb|Help books (*.zip)|*.zip|\
  1298. HTML Help Project (*.hhp)|*.hhp|\
  1299. All files (*.*)|*"
  1300.                                             ),
  1301.                                             wxOPEN | wxFILE_MUST_EXIST,
  1302.                                             this);
  1303.                 if (!s.IsEmpty())
  1304.                 {
  1305.                     wxString ext = s.Right(4).Lower();
  1306.                     if (ext == _T(".zip") || ext == _T(".htb") || ext == _T(".hhp"))
  1307.                     {
  1308.                         wxBusyCursor bcur;
  1309.                         m_Data->AddBook(s);
  1310.                         RefreshLists();
  1311.                     }
  1312.                     else
  1313.                         m_HtmlWin->LoadPage(s);
  1314.                 }
  1315.             }
  1316.             break;
  1317.     }
  1318. }
  1319.  
  1320.  
  1321.  
  1322. void wxHtmlHelpFrame::OnContentsSel(wxTreeEvent& event)
  1323. {
  1324.     wxHtmlHelpTreeItemData *pg;
  1325.     wxHtmlContentsItem *it;
  1326.  
  1327.     pg = (wxHtmlHelpTreeItemData*) m_ContentsBox->GetItemData(event.GetItem());
  1328.  
  1329.     if (pg && m_UpdateContents)
  1330.     {
  1331.         it = m_Data->GetContents() + (pg->m_Id);
  1332.         m_UpdateContents = FALSE;
  1333.         if (it->m_Page[0] != 0)
  1334.             m_HtmlWin->LoadPage(it->GetFullPath());
  1335.         m_UpdateContents = TRUE;
  1336.     }
  1337. }
  1338.  
  1339.  
  1340.  
  1341. void wxHtmlHelpFrame::OnIndexSel(wxCommandEvent& WXUNUSED(event))
  1342. {
  1343.     wxHtmlContentsItem *it = (wxHtmlContentsItem*) m_IndexList->GetClientData(m_IndexList->GetSelection());
  1344.     if (it->m_Page[0] != 0)
  1345.         m_HtmlWin->LoadPage(it->GetFullPath());
  1346.     NotifyPageChanged();
  1347. }
  1348.  
  1349.  
  1350. void wxHtmlHelpFrame::OnIndexFind(wxCommandEvent& event)
  1351. {
  1352.     wxString sr = m_IndexText->GetLineText(0);
  1353.     sr.MakeLower();
  1354.     if (sr == wxEmptyString)
  1355.     {
  1356.         OnIndexAll(event);
  1357.     }
  1358.     else
  1359.     {
  1360.         wxBusyCursor bcur;
  1361.         const wxChar *cstr = sr.c_str();
  1362.         wxChar mybuff[512];
  1363.         wxChar *ptr;
  1364.         bool first = TRUE;
  1365.  
  1366.         m_IndexList->Clear();
  1367.         int cnt = m_Data->GetIndexCnt();
  1368.         wxHtmlContentsItem* index = m_Data->GetIndex();
  1369.  
  1370.         int displ = 0;
  1371.         for (int i = 0; i < cnt; i++)
  1372.         {
  1373.             wxStrncpy(mybuff, index[i].m_Name, 512);
  1374.             mybuff[511] = _T('\0');
  1375.             for (ptr = mybuff; *ptr != 0; ptr++)
  1376.                 if (*ptr >= _T('A') && *ptr <= _T('Z'))
  1377.                     *ptr -= (wxChar)(_T('A') - _T('a'));
  1378.             if (wxStrstr(mybuff, cstr) != NULL)
  1379.             {
  1380.                 m_IndexList->Append(index[i].m_Name, (char*)(index + i));
  1381.                 displ++;
  1382.                 if (first)
  1383.                 {
  1384.                     if (index[i].m_Page[0] != 0)
  1385.                         m_HtmlWin->LoadPage(index[i].GetFullPath());
  1386.                     NotifyPageChanged();
  1387.                     first = FALSE;
  1388.                 }
  1389.             }
  1390.         }
  1391.  
  1392.         wxString cnttext;
  1393.         cnttext.Printf(_("%i of %i"), displ, cnt);
  1394.         m_IndexCountInfo->SetLabel(cnttext);
  1395.  
  1396.         m_IndexText->SetSelection(0, sr.Length());
  1397.         m_IndexText->SetFocus();
  1398.     }
  1399. }
  1400.  
  1401. void wxHtmlHelpFrame::OnIndexAll(wxCommandEvent& WXUNUSED(event))
  1402. {
  1403.     wxBusyCursor bcur;
  1404.  
  1405.     m_IndexList->Clear();
  1406.     int cnt = m_Data->GetIndexCnt();
  1407.     bool first = TRUE;
  1408.     wxHtmlContentsItem* index = m_Data->GetIndex();
  1409.  
  1410.     for (int i = 0; i < cnt; i++)
  1411.     {
  1412.         m_IndexList->Append(index[i].m_Name, (char*)(index + i));
  1413.         if (first)
  1414.         {
  1415.             if (index[i].m_Page[0] != 0)
  1416.                 m_HtmlWin->LoadPage(index[i].GetFullPath());
  1417.             NotifyPageChanged();
  1418.             first = FALSE;
  1419.         }
  1420.     }
  1421.  
  1422.     wxString cnttext;
  1423.     cnttext.Printf(_("%i of %i"), cnt, cnt);
  1424.     m_IndexCountInfo->SetLabel(cnttext);
  1425. }
  1426.  
  1427.  
  1428. void wxHtmlHelpFrame::OnSearchSel(wxCommandEvent& WXUNUSED(event))
  1429. {
  1430.     wxHtmlContentsItem *it = (wxHtmlContentsItem*) m_SearchList->GetClientData(m_SearchList->GetSelection());
  1431.     if (it)
  1432.     {
  1433.         if (it->m_Page[0] != 0)
  1434.             m_HtmlWin->LoadPage(it->GetFullPath());
  1435.         NotifyPageChanged();
  1436.     }
  1437. }
  1438.  
  1439. void wxHtmlHelpFrame::OnSearch(wxCommandEvent& WXUNUSED(event))
  1440. {
  1441.     wxString sr = m_SearchText->GetLineText(0);
  1442.  
  1443.     if (sr != wxEmptyString) KeywordSearch(sr);
  1444. }
  1445.  
  1446. void wxHtmlHelpFrame::OnBookmarksSel(wxCommandEvent& WXUNUSED(event))
  1447. {
  1448.     wxString sr = m_Bookmarks->GetStringSelection();
  1449.  
  1450.     if (sr != wxEmptyString && sr != _("(bookmarks)"))
  1451.     {
  1452.        m_HtmlWin->LoadPage(m_BookmarksPages[m_BookmarksNames.Index(sr)]);
  1453.        NotifyPageChanged();
  1454.     }
  1455. }
  1456.  
  1457. void wxHtmlHelpFrame::OnCloseWindow(wxCloseEvent& evt)
  1458. {
  1459.     GetSize(&m_Cfg.w, &m_Cfg.h);
  1460.     GetPosition(&m_Cfg.x, &m_Cfg.y);
  1461.  
  1462. #ifdef __WXGTK__
  1463.     if (IsGrabbed())
  1464.     {
  1465.         RemoveGrab();
  1466.     }
  1467. #endif
  1468.     
  1469.     if (m_Splitter && m_Cfg.navig_on) m_Cfg.sashpos = m_Splitter->GetSashPosition();
  1470.  
  1471.     if (m_Config)
  1472.         WriteCustomization(m_Config, m_ConfigRoot);
  1473.  
  1474.     if (m_helpController && m_helpController->IsKindOf(CLASSINFO(wxHtmlHelpController)))
  1475.     {
  1476.         ((wxHtmlHelpController*) m_helpController)->OnCloseFrame(evt);
  1477.     }
  1478.  
  1479.     evt.Skip();
  1480. }
  1481.  
  1482. BEGIN_EVENT_TABLE(wxHtmlHelpFrame, wxFrame)
  1483.     EVT_ACTIVATE(wxHtmlHelpFrame::OnActivate)
  1484.     EVT_TOOL_RANGE(wxID_HTML_PANEL, wxID_HTML_OPTIONS, wxHtmlHelpFrame::OnToolbar)
  1485.     EVT_BUTTON(wxID_HTML_BOOKMARKSREMOVE, wxHtmlHelpFrame::OnToolbar)
  1486.     EVT_BUTTON(wxID_HTML_BOOKMARKSADD, wxHtmlHelpFrame::OnToolbar)
  1487.     EVT_TREE_SEL_CHANGED(wxID_HTML_TREECTRL, wxHtmlHelpFrame::OnContentsSel)
  1488.     EVT_LISTBOX(wxID_HTML_INDEXLIST, wxHtmlHelpFrame::OnIndexSel)
  1489.     EVT_LISTBOX(wxID_HTML_SEARCHLIST, wxHtmlHelpFrame::OnSearchSel)
  1490.     EVT_BUTTON(wxID_HTML_SEARCHBUTTON, wxHtmlHelpFrame::OnSearch)
  1491.     EVT_TEXT_ENTER(wxID_HTML_SEARCHTEXT, wxHtmlHelpFrame::OnSearch)
  1492.     EVT_BUTTON(wxID_HTML_INDEXBUTTON, wxHtmlHelpFrame::OnIndexFind)
  1493.     EVT_TEXT_ENTER(wxID_HTML_INDEXTEXT, wxHtmlHelpFrame::OnIndexFind)
  1494.     EVT_BUTTON(wxID_HTML_INDEXBUTTONALL, wxHtmlHelpFrame::OnIndexAll)
  1495.     EVT_COMBOBOX(wxID_HTML_BOOKMARKSLIST, wxHtmlHelpFrame::OnBookmarksSel)
  1496.     EVT_CLOSE(wxHtmlHelpFrame::OnCloseWindow)
  1497. END_EVENT_TABLE()
  1498.  
  1499. #endif // wxUSE_WXHTML_HELP
  1500.  
  1501.