1 ///////////////////////////////////////////////////////////////////////////// 
   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 
   8 // Copyright:   (c) Harm van der Heijden and Vaclav Slavik 
   9 // Licence:     wxWindows licence 
  10 ///////////////////////////////////////////////////////////////////////////// 
  12 #if defined(__GNUG__) && !defined(NO_GCC_PRAGMA) 
  13 #pragma implementation "helpfrm.h" 
  16 // For compilers that support precompilation, includes "wx.h" 
  18 #include "wx/wxprec.h" 
  30     #include "wx/object.h" 
  33     #include "wx/bmpbuttn.h" 
  34     #include "wx/statbox.h" 
  35     #include "wx/radiobox.h" 
  40     #include "wx/msgdlg.h" 
  43 #include "wx/html/helpfrm.h" 
  44 #include "wx/html/helpctrl.h" 
  45 #include "wx/textctrl.h" 
  46 #include "wx/notebook.h" 
  47 #include "wx/imaglist.h" 
  48 #include "wx/treectrl.h" 
  49 #include "wx/tokenzr.h" 
  50 #include "wx/wfstream.h" 
  51 #include "wx/html/htmlwin.h" 
  52 #include "wx/busyinfo.h" 
  53 #include "wx/progdlg.h" 
  54 #include "wx/toolbar.h" 
  55 #include "wx/fontenum.h" 
  56 #include "wx/stream.h" 
  57 #include "wx/filedlg.h" 
  58 #include "wx/artprov.h" 
  59 #include "wx/spinctrl.h" 
  60 #include "wx/dynarray.h" 
  61 #include "wx/choicdlg.h" 
  63 // what is considered "small index"? 
  64 #define INDEX_IS_SMALL 100 
  66 /* Motif defines this as a macro */ 
  71 //-------------------------------------------------------------------------- 
  72 // wxHtmlHelpTreeItemData (private) 
  73 //-------------------------------------------------------------------------- 
  75 class wxHtmlHelpTreeItemData 
: public wxTreeItemData
 
  78 #if defined(__VISAGECPP__) 
  79 //  VA needs a default ctor for some reason.... 
  80         wxHtmlHelpTreeItemData() : wxTreeItemData() 
  83         wxHtmlHelpTreeItemData(int id
) : wxTreeItemData() 
  90 //-------------------------------------------------------------------------- 
  91 // wxHtmlHelpHashData (private) 
  92 //-------------------------------------------------------------------------- 
  94 class wxHtmlHelpHashData 
: public wxObject
 
  97         wxHtmlHelpHashData(int index
, wxTreeItemId id
) : wxObject() 
  98             { m_Index 
= index
; m_Id 
= id
;} 
  99         ~wxHtmlHelpHashData() {} 
 106 //-------------------------------------------------------------------------- 
 107 // wxHtmlHelpHtmlWindow (private) 
 108 //-------------------------------------------------------------------------- 
 110 class wxHtmlHelpHtmlWindow 
: public wxHtmlWindow
 
 113         wxHtmlHelpHtmlWindow(wxHtmlHelpFrame 
*fr
, wxWindow 
*parent
) : wxHtmlWindow(parent
), m_Frame(fr
) {} 
 115         virtual void OnLinkClicked(const wxHtmlLinkInfo
& link
) 
 117             wxHtmlWindow::OnLinkClicked(link
); 
 118             const wxMouseEvent 
*e 
= link
.GetEvent(); 
 119             if (e 
== NULL 
|| e
->LeftUp()) 
 120                 m_Frame
->NotifyPageChanged(); 
 124         wxHtmlHelpFrame 
*m_Frame
; 
 126     DECLARE_NO_COPY_CLASS(wxHtmlHelpHtmlWindow
) 
 130 //--------------------------------------------------------------------------- 
 131 // wxHtmlHelpFrame::m_mergedIndex 
 132 //--------------------------------------------------------------------------- 
 134 WX_DEFINE_ARRAY_PTR(const wxHtmlHelpDataItem
*, wxHtmlHelpDataItemPtrArray
); 
 136 struct wxHtmlHelpMergedIndexItem
 
 138     wxHtmlHelpMergedIndexItem 
*parent
; 
 140     wxHtmlHelpDataItemPtrArray items
; 
 143 WX_DECLARE_OBJARRAY(wxHtmlHelpMergedIndexItem
, wxHtmlHelpMergedIndex
); 
 144 #include "wx/arrimpl.cpp" 
 145 WX_DEFINE_OBJARRAY(wxHtmlHelpMergedIndex
) 
 147 void wxHtmlHelpFrame::UpdateMergedIndex() 
 149     delete m_mergedIndex
; 
 150     m_mergedIndex 
= new wxHtmlHelpMergedIndex
; 
 151     wxHtmlHelpMergedIndex
& merged 
= *m_mergedIndex
; 
 153     const wxHtmlHelpDataItems
& items 
= m_Data
->GetIndexArray(); 
 154     size_t len 
= items
.size(); 
 156     wxHtmlHelpMergedIndexItem 
*history
[128] = {NULL
}; 
 158     for (size_t i 
= 0; i 
< len
; i
++) 
 160         const wxHtmlHelpDataItem
& item 
= items
[i
]; 
 161         wxASSERT_MSG( item
.level 
< 128, _T("nested index entries too deep") ); 
 163         if (history
[item
.level
] && 
 164             history
[item
.level
]->items
[0]->name 
== item
.name
) 
 166             // same index entry as previous one, update list of items 
 167             history
[item
.level
]->items
.Add(&item
); 
 172             wxHtmlHelpMergedIndexItem 
*mi 
= new wxHtmlHelpMergedIndexItem(); 
 173             mi
->name 
= item
.GetIndentedName(); 
 174             mi
->items
.Add(&item
); 
 175             mi
->parent 
= (item
.level 
== 0) ? NULL 
: history
[item
.level 
- 1]; 
 176             history
[item
.level
] = mi
; 
 183 //--------------------------------------------------------------------------- 
 185 //--------------------------------------------------------------------------- 
 190     //wxID_HTML_HELPFRAME = wxID_HIGHEST + 1, 
 191     wxID_HTML_PANEL 
= wxID_HIGHEST 
+ 2, 
 200     wxID_HTML_BOOKMARKSLIST
, 
 201     wxID_HTML_BOOKMARKSADD
, 
 202     wxID_HTML_BOOKMARKSREMOVE
, 
 207     wxID_HTML_INDEXBUTTON
, 
 208     wxID_HTML_INDEXBUTTONALL
, 
 210     wxID_HTML_SEARCHPAGE
, 
 211     wxID_HTML_SEARCHTEXT
, 
 212     wxID_HTML_SEARCHLIST
, 
 213     wxID_HTML_SEARCHBUTTON
, 
 214     wxID_HTML_SEARCHCHOICE
, 
 219 IMPLEMENT_DYNAMIC_CLASS(wxHtmlHelpFrame
, wxFrame
) 
 221 wxHtmlHelpFrame::wxHtmlHelpFrame(wxWindow
* parent
, wxWindowID id
, const wxString
& title
, 
 222                                  int style
, wxHtmlHelpData
* data
) 
 225     Create(parent
, id
, title
, style
); 
 228 void wxHtmlHelpFrame::Init(wxHtmlHelpData
* data
) 
 233         m_DataCreated 
= false; 
 236         m_Data 
= new wxHtmlHelpData(); 
 237         m_DataCreated 
= true; 
 240     m_ContentsBox 
= NULL
; 
 242     m_IndexButton 
= NULL
; 
 243     m_IndexButtonAll 
= NULL
; 
 246     m_SearchButton 
= NULL
; 
 248     m_SearchChoice 
= NULL
; 
 249     m_IndexCountInfo 
= NULL
; 
 252     m_NavigNotebook 
= NULL
; 
 255     m_SearchCaseSensitive 
= NULL
; 
 256     m_SearchWholeWords 
= NULL
; 
 258     m_mergedIndex 
= NULL
; 
 261     m_ConfigRoot 
= wxEmptyString
; 
 263     m_Cfg
.x 
= m_Cfg
.y 
= 0; 
 267     m_Cfg
.navig_on 
= true; 
 269     m_NormalFonts 
= m_FixedFonts 
= NULL
; 
 270     m_NormalFace 
= m_FixedFace 
= wxEmptyString
; 
 277 #if wxUSE_PRINTING_ARCHITECTURE 
 282     m_UpdateContents 
= true; 
 283     m_helpController 
= (wxHelpControllerBase
*) NULL
; 
 286 // Create: builds the GUI components. 
 287 // with the style flag it's possible to toggle the toolbar, contents, index and search 
 289 // m_HtmlWin will *always* be created, but it's important to realize that 
 290 // m_ContentsBox, m_IndexList, m_SearchList, m_SearchButton, m_SearchText and 
 291 // m_SearchButton may be NULL. 
 292 // moreover, if no contents, index or searchpage is needed, m_Splitter and 
 293 // m_NavigPan will be NULL too (with m_HtmlWin directly connected to the frame) 
 295 bool wxHtmlHelpFrame::Create(wxWindow
* parent
, wxWindowID id
, 
 296                              const wxString
& WXUNUSED(title
), int style
) 
 300     wxImageList 
*ContentsImageList 
= new wxImageList(16, 16); 
 301     ContentsImageList
->Add(wxArtProvider::GetIcon(wxART_HELP_BOOK
, 
 304     ContentsImageList
->Add(wxArtProvider::GetIcon(wxART_HELP_FOLDER
, 
 307     ContentsImageList
->Add(wxArtProvider::GetIcon(wxART_HELP_PAGE
, 
 311     // Do the config in two steps. We read the HtmlWindow customization after we 
 312     // create the window. 
 314         ReadCustomization(m_Config
, m_ConfigRoot
); 
 316     wxFrame::Create(parent
, id
, _("Help"), 
 317                     wxPoint(m_Cfg
.x
, m_Cfg
.y
), wxSize(m_Cfg
.w
, m_Cfg
.h
), 
 318                     wxDEFAULT_FRAME_STYLE
, wxT("wxHtmlHelp")); 
 320     GetPosition(&m_Cfg
.x
, &m_Cfg
.y
); 
 322     SetIcon(wxArtProvider::GetIcon(wxART_HELP
, wxART_HELP_BROWSER
)); 
 324     // On the Mac, each modeless frame must have a menubar. 
 325     // TODO: add more menu items, and perhaps add a style to show 
 326     // the menubar: compulsory on the Mac, optional elsewhere. 
 328     wxMenuBar
* menuBar 
= new wxMenuBar
; 
 330     wxMenu
* fileMenu 
= new wxMenu
; 
 331     fileMenu
->Append(wxID_HTML_OPENFILE
, _("&Open...")); 
 332     fileMenu
->AppendSeparator(); 
 333     fileMenu
->Append(wxID_CLOSE
, _("&Close")); 
 335     wxMenu
* helpMenu 
= new wxMenu
; 
 336     helpMenu
->Append(wxID_ABOUT
, _("&About...")); 
 337     // Ensures we don't get an empty help menu 
 338     helpMenu
->Append(wxID_HELP_CONTENTS
, _("&About...")); 
 340     menuBar
->Append(fileMenu
,_("&File")); 
 341     menuBar
->Append(helpMenu
,_("&Help")); 
 345     int notebook_page 
= 0; 
 349 #endif // wxUSE_STATUSBAR 
 353     if (style 
& (wxHF_TOOLBAR 
| wxHF_FLAT_TOOLBAR
)) 
 355         wxToolBar 
*toolBar 
= CreateToolBar(wxNO_BORDER 
| wxTB_HORIZONTAL 
| 
 357                                            (style 
& wxHF_FLAT_TOOLBAR 
? wxTB_FLAT 
: 0)); 
 358         toolBar
->SetMargins( 2, 2 ); 
 359         AddToolbarButtons(toolBar
, style
); 
 362 #endif //wxUSE_TOOLBAR 
 364     wxSizer 
*navigSizer 
= NULL
; 
 366     if (style 
& (wxHF_CONTENTS 
| wxHF_INDEX 
| wxHF_SEARCH
)) 
 368         // traditional help controller; splitter window with html page on the 
 369         // right and a notebook containing various pages on the left 
 370         m_Splitter 
= new wxSplitterWindow(this); 
 372         m_HtmlWin 
= new wxHtmlHelpHtmlWindow(this, m_Splitter
); 
 373         m_NavigPan 
= new wxPanel(m_Splitter
, wxID_ANY
); 
 374         m_NavigNotebook 
= new wxNotebook(m_NavigPan
, wxID_HTML_NOTEBOOK
, 
 375                                          wxDefaultPosition
, wxDefaultSize
); 
 377         navigSizer 
= new wxBoxSizer(wxVERTICAL
); 
 378         navigSizer
->Add(m_NavigNotebook
, 1, wxEXPAND
); 
 380         m_NavigPan
->SetSizer(navigSizer
); 
 383     { // only html window, no notebook with index,contents etc 
 384         m_HtmlWin 
= new wxHtmlWindow(this); 
 387     m_HtmlWin
->SetRelatedFrame(this, m_TitleFormat
); 
 389     m_HtmlWin
->SetRelatedStatusBar(0); 
 390 #endif // wxUSE_STATUSBAR 
 392         m_HtmlWin
->ReadCustomization(m_Config
, m_ConfigRoot
); 
 394     // contents tree panel? 
 395     if ( style 
& wxHF_CONTENTS 
) 
 397         wxWindow 
*dummy 
= new wxPanel(m_NavigNotebook
, wxID_HTML_INDEXPAGE
); 
 398         wxSizer 
*topsizer 
= new wxBoxSizer(wxVERTICAL
); 
 400         topsizer
->Add(0, 10); 
 402         dummy
->SetSizer(topsizer
); 
 404         if ( style 
& wxHF_BOOKMARKS 
) 
 406             m_Bookmarks 
= new wxComboBox(dummy
, wxID_HTML_BOOKMARKSLIST
, 
 408                                          wxDefaultPosition
, wxDefaultSize
, 
 409                                          0, NULL
, wxCB_READONLY 
| wxCB_SORT
); 
 410             m_Bookmarks
->Append(_("(bookmarks)")); 
 411             for (unsigned i 
= 0; i 
< m_BookmarksNames
.GetCount(); i
++) 
 412                 m_Bookmarks
->Append(m_BookmarksNames
[i
]); 
 413             m_Bookmarks
->SetSelection(0); 
 415             wxBitmapButton 
*bmpbt1
, *bmpbt2
; 
 416             bmpbt1 
= new wxBitmapButton(dummy
, wxID_HTML_BOOKMARKSADD
, 
 417                                  wxArtProvider::GetBitmap(wxART_ADD_BOOKMARK
, 
 419             bmpbt2 
= new wxBitmapButton(dummy
, wxID_HTML_BOOKMARKSREMOVE
, 
 420                                  wxArtProvider::GetBitmap(wxART_DEL_BOOKMARK
, 
 423             bmpbt1
->SetToolTip(_("Add current page to bookmarks")); 
 424             bmpbt2
->SetToolTip(_("Remove current page from bookmarks")); 
 425 #endif // wxUSE_TOOLTIPS 
 427             wxSizer 
*sizer 
= new wxBoxSizer(wxHORIZONTAL
); 
 429             sizer
->Add(m_Bookmarks
, 1, wxALIGN_CENTRE_VERTICAL 
| wxRIGHT
, 5); 
 430             sizer
->Add(bmpbt1
, 0, wxALIGN_CENTRE_VERTICAL 
| wxRIGHT
, 2); 
 431             sizer
->Add(bmpbt2
, 0, wxALIGN_CENTRE_VERTICAL
, 0); 
 433             topsizer
->Add(sizer
, 0, wxEXPAND 
| wxLEFT 
| wxBOTTOM 
| wxRIGHT
, 10); 
 436         m_ContentsBox 
= new wxTreeCtrl(dummy
, wxID_HTML_TREECTRL
, 
 437                                        wxDefaultPosition
, wxDefaultSize
, 
 439                                        wxTR_HAS_BUTTONS 
| wxTR_HIDE_ROOT 
| 
 442         m_ContentsBox
->AssignImageList(ContentsImageList
); 
 444         topsizer
->Add(m_ContentsBox
, 1, 
 445                       wxEXPAND 
| wxLEFT 
| wxBOTTOM 
| wxRIGHT
, 
 448         m_NavigNotebook
->AddPage(dummy
, _("Contents")); 
 449         m_ContentsPage 
= notebook_page
++; 
 452     // index listbox panel? 
 453     if ( style 
& wxHF_INDEX 
) 
 455         wxWindow 
*dummy 
= new wxPanel(m_NavigNotebook
, wxID_HTML_INDEXPAGE
); 
 456         wxSizer 
*topsizer 
= new wxBoxSizer(wxVERTICAL
); 
 458         dummy
->SetSizer(topsizer
); 
 460         m_IndexText 
= new wxTextCtrl(dummy
, wxID_HTML_INDEXTEXT
, wxEmptyString
, 
 461                                      wxDefaultPosition
, wxDefaultSize
, 
 463         m_IndexButton 
= new wxButton(dummy
, wxID_HTML_INDEXBUTTON
, _("Find")); 
 464         m_IndexButtonAll 
= new wxButton(dummy
, wxID_HTML_INDEXBUTTONALL
, 
 466         m_IndexCountInfo 
= new wxStaticText(dummy
, wxID_HTML_COUNTINFO
, 
 467                                             wxEmptyString
, wxDefaultPosition
, 
 469                                             wxALIGN_RIGHT 
| wxST_NO_AUTORESIZE
); 
 470         m_IndexList 
= new wxListBox(dummy
, wxID_HTML_INDEXLIST
, 
 471                                     wxDefaultPosition
, wxDefaultSize
, 
 472                                     0, NULL
, wxLB_SINGLE
); 
 475         m_IndexButton
->SetToolTip(_("Display all index items that contain given substring. Search is case insensitive.")); 
 476         m_IndexButtonAll
->SetToolTip(_("Show all items in index")); 
 477 #endif //wxUSE_TOOLTIPS 
 479         topsizer
->Add(m_IndexText
, 0, wxEXPAND 
| wxALL
, 10); 
 480         wxSizer 
*btsizer 
= new wxBoxSizer(wxHORIZONTAL
); 
 481         btsizer
->Add(m_IndexButton
, 0, wxRIGHT
, 2); 
 482         btsizer
->Add(m_IndexButtonAll
); 
 483         topsizer
->Add(btsizer
, 0, 
 484                       wxALIGN_RIGHT 
| wxLEFT 
| wxRIGHT 
| wxBOTTOM
, 10); 
 485         topsizer
->Add(m_IndexCountInfo
, 0, wxEXPAND 
| wxLEFT 
| wxRIGHT
, 2); 
 486         topsizer
->Add(m_IndexList
, 1, wxEXPAND 
| wxALL
, 2); 
 488         m_NavigNotebook
->AddPage(dummy
, _("Index")); 
 489         m_IndexPage 
= notebook_page
++; 
 492     // search list panel? 
 493     if ( style 
& wxHF_SEARCH 
) 
 495         wxWindow 
*dummy 
= new wxPanel(m_NavigNotebook
, wxID_HTML_INDEXPAGE
); 
 496         wxSizer 
*sizer 
= new wxBoxSizer(wxVERTICAL
); 
 498         dummy
->SetSizer(sizer
); 
 500         m_SearchText 
= new wxTextCtrl(dummy
, wxID_HTML_SEARCHTEXT
, 
 502                                       wxDefaultPosition
, wxDefaultSize
, 
 504         m_SearchChoice 
= new wxChoice(dummy
, wxID_HTML_SEARCHCHOICE
, 
 505                                       wxDefaultPosition
, wxDefaultSize
); 
 506         m_SearchCaseSensitive 
= new wxCheckBox(dummy
, wxID_ANY
, _("Case sensitive")); 
 507         m_SearchWholeWords 
= new wxCheckBox(dummy
, wxID_ANY
, _("Whole words only")); 
 508         m_SearchButton 
= new wxButton(dummy
, wxID_HTML_SEARCHBUTTON
, _("Search")); 
 510         m_SearchButton
->SetToolTip(_("Search contents of help book(s) for all occurences of the text you typed above")); 
 511 #endif //wxUSE_TOOLTIPS 
 512         m_SearchList 
= new wxListBox(dummy
, wxID_HTML_SEARCHLIST
, 
 513                                      wxDefaultPosition
, wxDefaultSize
, 
 514                                      0, NULL
, wxLB_SINGLE
); 
 516         sizer
->Add(m_SearchText
, 0, wxEXPAND 
| wxALL
, 10); 
 517         sizer
->Add(m_SearchChoice
, 0, wxEXPAND 
| wxLEFT 
| wxRIGHT 
| wxBOTTOM
, 10); 
 518         sizer
->Add(m_SearchCaseSensitive
, 0, wxLEFT 
| wxRIGHT
, 10); 
 519         sizer
->Add(m_SearchWholeWords
, 0, wxLEFT 
| wxRIGHT
, 10); 
 520         sizer
->Add(m_SearchButton
, 0, wxALL 
| wxALIGN_RIGHT
, 8); 
 521         sizer
->Add(m_SearchList
, 1, wxALL 
| wxEXPAND
, 2); 
 523         m_NavigNotebook
->AddPage(dummy
, _("Search")); 
 524         m_SearchPage 
= notebook_page
; 
 533         navigSizer
->SetSizeHints(m_NavigPan
); 
 534         m_NavigPan
->Layout(); 
 538     if ( m_NavigPan 
&& m_Splitter 
) 
 540         m_Splitter
->SetMinimumPaneSize(20); 
 541         if ( m_Cfg
.navig_on 
) 
 542             m_Splitter
->SplitVertically(m_NavigPan
, m_HtmlWin
, m_Cfg
.sashpos
); 
 544         if ( m_Cfg
.navig_on 
) 
 547             m_Splitter
->SplitVertically(m_NavigPan
, m_HtmlWin
, m_Cfg
.sashpos
); 
 551             m_NavigPan
->Show(false); 
 552             m_Splitter
->Initialize(m_HtmlWin
); 
 556     // Reduce flicker by updating the splitter pane sizes before the 
 558     wxSizeEvent 
sizeEvent(GetSize(), GetId()); 
 559     ProcessEvent(sizeEvent
); 
 561     m_Splitter
->UpdateSize(); 
 566 wxHtmlHelpFrame::~wxHtmlHelpFrame() 
 568     delete m_mergedIndex
; 
 570     // PopEventHandler(); // wxhtmlhelpcontroller (not any more!) 
 573     if (m_NormalFonts
) delete m_NormalFonts
; 
 574     if (m_FixedFonts
) delete m_FixedFonts
; 
 577         WX_CLEAR_HASH_TABLE(*m_PagesHash
); 
 580 #if wxUSE_PRINTING_ARCHITECTURE 
 581     if (m_Printer
) delete m_Printer
; 
 587 void wxHtmlHelpFrame::AddToolbarButtons(wxToolBar 
*toolBar
, int style
) 
 589     wxBitmap wpanelBitmap 
= 
 590         wxArtProvider::GetBitmap(wxART_HELP_SIDE_PANEL
, wxART_TOOLBAR
); 
 591     wxBitmap wbackBitmap 
= 
 592         wxArtProvider::GetBitmap(wxART_GO_BACK
, wxART_TOOLBAR
); 
 593     wxBitmap wforwardBitmap 
= 
 594         wxArtProvider::GetBitmap(wxART_GO_FORWARD
, wxART_TOOLBAR
); 
 595     wxBitmap wupnodeBitmap 
= 
 596         wxArtProvider::GetBitmap(wxART_GO_TO_PARENT
, wxART_TOOLBAR
); 
 598         wxArtProvider::GetBitmap(wxART_GO_UP
, wxART_TOOLBAR
); 
 599     wxBitmap wdownBitmap 
= 
 600         wxArtProvider::GetBitmap(wxART_GO_DOWN
, wxART_TOOLBAR
); 
 601     wxBitmap wopenBitmap 
= 
 602         wxArtProvider::GetBitmap(wxART_FILE_OPEN
, wxART_TOOLBAR
); 
 603     wxBitmap wprintBitmap 
= 
 604         wxArtProvider::GetBitmap(wxART_PRINT
, wxART_TOOLBAR
); 
 605     wxBitmap woptionsBitmap 
= 
 606         wxArtProvider::GetBitmap(wxART_HELP_SETTINGS
, wxART_TOOLBAR
); 
 608     wxASSERT_MSG( (wpanelBitmap
.Ok() && wbackBitmap
.Ok() && 
 609                    wforwardBitmap
.Ok() && wupnodeBitmap
.Ok() && 
 610                    wupBitmap
.Ok() && wdownBitmap
.Ok() && 
 611                    wopenBitmap
.Ok() && wprintBitmap
.Ok() && 
 612                    woptionsBitmap
.Ok()), 
 613                   wxT("One or more HTML help frame toolbar bitmap could not be loaded.")) ; 
 616     toolBar
->AddTool(wxID_HTML_PANEL
, wpanelBitmap
, wxNullBitmap
, 
 617                        false, -1, -1, (wxObject 
*) NULL
, 
 618                        _("Show/hide navigation panel")); 
 620     toolBar
->AddSeparator(); 
 621     toolBar
->AddTool(wxID_HTML_BACK
, wbackBitmap
, wxNullBitmap
, 
 622                        false, -1, -1, (wxObject 
*) NULL
, 
 624     toolBar
->AddTool(wxID_HTML_FORWARD
, wforwardBitmap
, wxNullBitmap
, 
 625                        false, -1, -1, (wxObject 
*) NULL
, 
 627     toolBar
->AddSeparator(); 
 629     toolBar
->AddTool(wxID_HTML_UPNODE
, wupnodeBitmap
, wxNullBitmap
, 
 630                        false, -1, -1, (wxObject 
*) NULL
, 
 631                        _("Go one level up in document hierarchy")); 
 632     toolBar
->AddTool(wxID_HTML_UP
, wupBitmap
, wxNullBitmap
, 
 633                        false, -1, -1, (wxObject 
*) NULL
, 
 635     toolBar
->AddTool(wxID_HTML_DOWN
, wdownBitmap
, wxNullBitmap
, 
 636                        false, -1, -1, (wxObject 
*) NULL
, 
 639     if ((style 
& wxHF_PRINT
) || (style 
& wxHF_OPEN_FILES
)) 
 640         toolBar
->AddSeparator(); 
 642     if (style 
& wxHF_OPEN_FILES
) 
 643         toolBar
->AddTool(wxID_HTML_OPENFILE
, wopenBitmap
, wxNullBitmap
, 
 644                            false, -1, -1, (wxObject 
*) NULL
, 
 645                            _("Open HTML document")); 
 647 #if wxUSE_PRINTING_ARCHITECTURE 
 648     if (style 
& wxHF_PRINT
) 
 649         toolBar
->AddTool(wxID_HTML_PRINT
, wprintBitmap
, wxNullBitmap
, 
 650                            false, -1, -1, (wxObject 
*) NULL
, 
 651                            _("Print this page")); 
 654     toolBar
->AddSeparator(); 
 655     toolBar
->AddTool(wxID_HTML_OPTIONS
, woptionsBitmap
, wxNullBitmap
, 
 656                        false, -1, -1, (wxObject 
*) NULL
, 
 657                        _("Display options dialog")); 
 659 #endif //wxUSE_TOOLBAR 
 662 void wxHtmlHelpFrame::SetTitleFormat(const wxString
& format
) 
 665         m_HtmlWin
->SetRelatedFrame(this, format
); 
 666     m_TitleFormat 
= format
; 
 670 bool wxHtmlHelpFrame::Display(const wxString
& x
) 
 672     wxString url 
= m_Data
->FindPageByName(x
); 
 675         m_HtmlWin
->LoadPage(url
); 
 683 bool wxHtmlHelpFrame::Display(const int id
) 
 685     wxString url 
= m_Data
->FindPageById(id
); 
 688         m_HtmlWin
->LoadPage(url
); 
 698 bool wxHtmlHelpFrame::DisplayContents() 
 703     if (!m_Splitter
->IsSplit()) 
 707         m_Splitter
->SplitVertically(m_NavigPan
, m_HtmlWin
, m_Cfg
.sashpos
); 
 708         m_Cfg
.navig_on 
= true; 
 711     m_NavigNotebook
->SetSelection(0); 
 713     if (m_Data
->GetBookRecArray().GetCount() > 0) 
 715         wxHtmlBookRecord
& book 
= m_Data
->GetBookRecArray()[0]; 
 716         if (!book
.GetStart().IsEmpty()) 
 717             m_HtmlWin
->LoadPage(book
.GetFullPath(book
.GetStart())); 
 725 bool wxHtmlHelpFrame::DisplayIndex() 
 730     if (!m_Splitter
->IsSplit()) 
 734         m_Splitter
->SplitVertically(m_NavigPan
, m_HtmlWin
, m_Cfg
.sashpos
); 
 737     m_NavigNotebook
->SetSelection(1); 
 739     if (m_Data
->GetBookRecArray().GetCount() > 0) 
 741         wxHtmlBookRecord
& book 
= m_Data
->GetBookRecArray()[0]; 
 742         if (!book
.GetStart().IsEmpty()) 
 743             m_HtmlWin
->LoadPage(book
.GetFullPath(book
.GetStart())); 
 749 void wxHtmlHelpFrame::DisplayIndexItem(const wxHtmlHelpMergedIndexItem 
*it
) 
 751     if (it
->items
.size() == 1) 
 753         if (!it
->items
[0]->page
.empty()) 
 755             m_HtmlWin
->LoadPage(it
->items
[0]->GetFullPath()); 
 761         wxBusyCursor busy_cursor
; 
 763         // more pages associated with this index item -- let the user choose 
 764         // which one she/he wants from a list: 
 766         size_t len 
= it
->items
.size(); 
 767         for (size_t i 
= 0; i 
< len
; i
++) 
 769             wxString page 
= it
->items
[i
]->page
; 
 770             // try to find page's title in contents: 
 771             const wxHtmlHelpDataItems
& contents 
= m_Data
->GetContentsArray(); 
 772             size_t clen 
= contents
.size(); 
 773             for (size_t j 
= 0; j 
< clen
; j
++) 
 775                 if (contents
[j
].page 
== page
) 
 777                     page 
= contents
[j
].name
; 
 784         wxSingleChoiceDialog 
dlg(this, 
 785                                  _("Please choose the page to display:"), 
 787                                  arr
, NULL
, wxCHOICEDLG_STYLE 
& ~wxCENTRE
); 
 788         if (dlg
.ShowModal() == wxID_OK
) 
 790             m_HtmlWin
->LoadPage(it
->items
[dlg
.GetSelection()]->GetFullPath()); 
 797 bool wxHtmlHelpFrame::KeywordSearch(const wxString
& keyword
, 
 798                                     wxHelpSearchMode mode
) 
 800     if (mode 
== wxHELP_SEARCH_ALL
) 
 802         if ( !(m_SearchList 
&& 
 803                m_SearchButton 
&& m_SearchText 
&& m_SearchChoice
) ) 
 806     else if (mode 
== wxHELP_SEARCH_INDEX
) 
 808         if ( !(m_IndexList 
&& 
 809                m_IndexButton 
&& m_IndexButtonAll 
&& m_IndexText
) ) 
 815     wxString book 
= wxEmptyString
; 
 817     if (!m_Splitter
->IsSplit()) 
 821         m_Splitter
->SplitVertically(m_NavigPan
, m_HtmlWin
, m_Cfg
.sashpos
); 
 824     if (mode 
== wxHELP_SEARCH_ALL
) 
 826         m_NavigNotebook
->SetSelection(m_SearchPage
); 
 827         m_SearchList
->Clear(); 
 828         m_SearchText
->SetValue(keyword
); 
 829         m_SearchButton
->Disable(); 
 831         if (m_SearchChoice
->GetSelection() != 0) 
 832             book 
= m_SearchChoice
->GetStringSelection(); 
 834         wxHtmlSearchStatus 
status(m_Data
, keyword
, 
 835                                   m_SearchCaseSensitive
->GetValue(), 
 836                                   m_SearchWholeWords
->GetValue(), 
 839 #if wxUSE_PROGRESSDLG 
 840         wxProgressDialog 
progress(_("Searching..."), 
 841                                   _("No matching page found yet"), 
 842                                   status
.GetMaxIndex(), this, 
 843                                   wxPD_APP_MODAL 
| wxPD_CAN_ABORT 
| wxPD_AUTO_HIDE
); 
 847         while (status
.IsActive()) 
 849             curi 
= status
.GetCurIndex(); 
 851 #if wxUSE_PROGRESSDLG 
 852                 && !progress
.Update(curi
) 
 858                 foundstr
.Printf(_("Found %i matches"), ++foundcnt
); 
 859 #if wxUSE_PROGRESSDLG 
 860                 progress
.Update(status
.GetCurIndex(), foundstr
); 
 862                 m_SearchList
->Append(status
.GetName(), (void*)status
.GetCurItem()); 
 866         m_SearchButton
->Enable(); 
 867         m_SearchText
->SetSelection(0, keyword
.Length()); 
 868         m_SearchText
->SetFocus(); 
 870     else if (mode 
== wxHELP_SEARCH_INDEX
) 
 872         m_NavigNotebook
->SetSelection(m_IndexPage
); 
 873         m_IndexList
->Clear(); 
 874         m_IndexButton
->Disable(); 
 875         m_IndexButtonAll
->Disable(); 
 876         m_IndexText
->SetValue(keyword
); 
 878         wxCommandEvent dummy
; 
 879         OnIndexFind(dummy
); // what a hack... 
 880         m_IndexButton
->Enable(); 
 881         m_IndexButtonAll
->Enable(); 
 882         foundcnt 
= m_IndexList
->GetCount(); 
 890                 wxFAIL_MSG( _T("unknown help search mode") ); 
 893             case wxHELP_SEARCH_ALL
: 
 895                 wxHtmlHelpDataItem 
*it 
= 
 896                     (wxHtmlHelpDataItem
*) m_SearchList
->GetClientData(0); 
 899                     m_HtmlWin
->LoadPage(it
->GetFullPath()); 
 905             case wxHELP_SEARCH_INDEX
: 
 907                 wxHtmlHelpMergedIndexItem
* it 
=  
 908                     (wxHtmlHelpMergedIndexItem
*) m_IndexList
->GetClientData(0); 
 910                     DisplayIndexItem(it
); 
 920 void wxHtmlHelpFrame::CreateContents() 
 927         WX_CLEAR_HASH_TABLE(*m_PagesHash
); 
 931     const wxHtmlHelpDataItems
& contents 
= m_Data
->GetContentsArray(); 
 933     size_t cnt 
= contents
.size(); 
 935     m_PagesHash 
= new wxHashTable(wxKEY_STRING
, 2 * cnt
); 
 937     const int MAX_ROOTS 
= 64; 
 938     wxTreeItemId roots
[MAX_ROOTS
]; 
 939     // VS: this array holds information about whether we've set item icon at 
 940     //     given level. This is neccessary because m_Data has flat structure 
 941     //     and there's no way of recognizing if some item has subitems or not. 
 942     //     We set the icon later: when we find an item with level=n, we know 
 943     //     that the last item with level=n-1 was folder with subitems, so we 
 944     //     set its icon accordingly 
 945     bool imaged
[MAX_ROOTS
]; 
 946     m_ContentsBox
->DeleteAllItems(); 
 948     roots
[0] = m_ContentsBox
->AddRoot(_("(Help)")); 
 951     for (size_t i 
= 0; i 
< cnt
; i
++) 
 953         wxHtmlHelpDataItem 
*it 
= &contents
[i
]; 
 957             if (m_hfStyle 
& wxHF_MERGE_BOOKS
) 
 958                 // VS: we don't want book nodes, books' content should 
 959                 //    appear under tree's root. This line will create "fake" 
 960                 //    record about book node so that the rest of this look 
 961                 //    will believe there really _is_ book node and will 
 966                 roots
[1] = m_ContentsBox
->AppendItem(roots
[0], 
 967                                          it
->name
, IMG_Book
, -1, 
 968                                          new wxHtmlHelpTreeItemData(i
)); 
 969                 m_ContentsBox
->SetItemBold(roots
[1], true); 
 973         // ...and their contents: 
 976             roots
[it
->level 
+ 1] = m_ContentsBox
->AppendItem( 
 977                                      roots
[it
->level
], it
->name
, IMG_Page
, 
 978                                      -1, new wxHtmlHelpTreeItemData(i
)); 
 979             imaged
[it
->level 
+ 1] = false; 
 982         m_PagesHash
->Put(it
->GetFullPath(), 
 983                          new wxHtmlHelpHashData(i
, roots
[it
->level 
+ 1])); 
 985         // Set the icon for the node one level up in the hiearachy, 
 986         // unless already done (see comment above imaged[] declaration) 
 987         if (!imaged
[it
->level
]) 
 989             int image 
= IMG_Folder
; 
 990             if (m_hfStyle 
& wxHF_ICONS_BOOK
) 
 992             else if (m_hfStyle 
& wxHF_ICONS_BOOK_CHAPTER
) 
 993                 image 
= (it
->level 
== 1) ? IMG_Book 
: IMG_Folder
; 
 994             m_ContentsBox
->SetItemImage(roots
[it
->level
], image
); 
 995             m_ContentsBox
->SetItemImage(roots
[it
->level
], image
, 
 996                                         wxTreeItemIcon_Selected
); 
 997             imaged
[it
->level
] = true; 
1003 void wxHtmlHelpFrame::CreateIndex() 
1008     m_IndexList
->Clear(); 
1010     size_t cnt 
= m_mergedIndex
->size(); 
1013     if (cnt 
> INDEX_IS_SMALL
) 
1014         cnttext
.Printf(_("%i of %i"), 0, cnt
); 
1016         cnttext
.Printf(_("%i of %i"), cnt
, cnt
); 
1017     m_IndexCountInfo
->SetLabel(cnttext
); 
1018     if (cnt 
> INDEX_IS_SMALL
) 
1021     for (size_t i 
= 0; i 
< cnt
; i
++) 
1022         m_IndexList
->Append((*m_mergedIndex
)[i
].name
, 
1023                             (char*)(&(*m_mergedIndex
)[i
])); 
1026 void wxHtmlHelpFrame::CreateSearch() 
1028     if (! (m_SearchList 
&& m_SearchChoice
)) 
1030     m_SearchList
->Clear(); 
1031     m_SearchChoice
->Clear(); 
1032     m_SearchChoice
->Append(_("Search in all books")); 
1033     const wxHtmlBookRecArray
& bookrec 
= m_Data
->GetBookRecArray(); 
1034     int i
, cnt 
= bookrec
.GetCount(); 
1035     for (i 
= 0; i 
< cnt
; i
++) 
1036         m_SearchChoice
->Append(bookrec
[i
].GetTitle()); 
1037     m_SearchChoice
->SetSelection(0); 
1041 void wxHtmlHelpFrame::RefreshLists() 
1043     // Update m_mergedIndex: 
1044     UpdateMergedIndex(); 
1045     // Update the controls 
1051 void wxHtmlHelpFrame::ReadCustomization(wxConfigBase 
*cfg
, const wxString
& path
) 
1056     if (path 
!= wxEmptyString
) 
1058         oldpath 
= cfg
->GetPath(); 
1059         cfg
->SetPath(_T("/") + path
); 
1062     m_Cfg
.navig_on 
= cfg
->Read(wxT("hcNavigPanel"), m_Cfg
.navig_on
) != 0; 
1063     m_Cfg
.sashpos 
= cfg
->Read(wxT("hcSashPos"), m_Cfg
.sashpos
); 
1064     m_Cfg
.x 
= cfg
->Read(wxT("hcX"), m_Cfg
.x
); 
1065     m_Cfg
.y 
= cfg
->Read(wxT("hcY"), m_Cfg
.y
); 
1066     m_Cfg
.w 
= cfg
->Read(wxT("hcW"), m_Cfg
.w
); 
1067     m_Cfg
.h 
= cfg
->Read(wxT("hcH"), m_Cfg
.h
); 
1069     m_FixedFace 
= cfg
->Read(wxT("hcFixedFace"), m_FixedFace
); 
1070     m_NormalFace 
= cfg
->Read(wxT("hcNormalFace"), m_NormalFace
); 
1071     m_FontSize 
= cfg
->Read(wxT("hcBaseFontSize"), m_FontSize
); 
1078         cnt 
= cfg
->Read(wxT("hcBookmarksCnt"), 0L); 
1081             m_BookmarksNames
.Clear(); 
1082             m_BookmarksPages
.Clear(); 
1085                 m_Bookmarks
->Clear(); 
1086                 m_Bookmarks
->Append(_("(bookmarks)")); 
1089             for (i 
= 0; i 
< cnt
; i
++) 
1091                 val
.Printf(wxT("hcBookmark_%i"), i
); 
1093                 m_BookmarksNames
.Add(s
); 
1094                 if (m_Bookmarks
) m_Bookmarks
->Append(s
); 
1095                 val
.Printf(wxT("hcBookmark_%i_url"), i
); 
1097                 m_BookmarksPages
.Add(s
); 
1103         m_HtmlWin
->ReadCustomization(cfg
); 
1105     if (path 
!= wxEmptyString
) 
1106         cfg
->SetPath(oldpath
); 
1109 void wxHtmlHelpFrame::WriteCustomization(wxConfigBase 
*cfg
, const wxString
& path
) 
1114     if (path 
!= wxEmptyString
) 
1116         oldpath 
= cfg
->GetPath(); 
1117         cfg
->SetPath(_T("/") + path
); 
1120     cfg
->Write(wxT("hcNavigPanel"), m_Cfg
.navig_on
); 
1121     cfg
->Write(wxT("hcSashPos"), (long)m_Cfg
.sashpos
); 
1122     if ( !IsIconized() ) 
1124         //  Don't write if iconized as this would make the window 
1125         //  disappear next time it is shown! 
1126         cfg
->Write(wxT("hcX"), (long)m_Cfg
.x
); 
1127         cfg
->Write(wxT("hcY"), (long)m_Cfg
.y
); 
1128         cfg
->Write(wxT("hcW"), (long)m_Cfg
.w
); 
1129         cfg
->Write(wxT("hcH"), (long)m_Cfg
.h
); 
1131     cfg
->Write(wxT("hcFixedFace"), m_FixedFace
); 
1132     cfg
->Write(wxT("hcNormalFace"), m_NormalFace
); 
1133     cfg
->Write(wxT("hcBaseFontSize"), (long)m_FontSize
); 
1138         int cnt 
= m_BookmarksNames
.GetCount(); 
1141         cfg
->Write(wxT("hcBookmarksCnt"), (long)cnt
); 
1142         for (i 
= 0; i 
< cnt
; i
++) 
1144             val
.Printf(wxT("hcBookmark_%i"), i
); 
1145             cfg
->Write(val
, m_BookmarksNames
[i
]); 
1146             val
.Printf(wxT("hcBookmark_%i_url"), i
); 
1147             cfg
->Write(val
, m_BookmarksPages
[i
]); 
1152         m_HtmlWin
->WriteCustomization(cfg
); 
1154     if (path 
!= wxEmptyString
) 
1155         cfg
->SetPath(oldpath
); 
1162 static void SetFontsToHtmlWin(wxHtmlWindow 
*win
, wxString scalf
, wxString fixf
, int size
) 
1165     f_sizes
[0] = int(size 
* 0.6); 
1166     f_sizes
[1] = int(size 
* 0.8); 
1168     f_sizes
[3] = int(size 
* 1.2); 
1169     f_sizes
[4] = int(size 
* 1.4); 
1170     f_sizes
[5] = int(size 
* 1.6); 
1171     f_sizes
[6] = int(size 
* 1.8); 
1173     win
->SetFonts(scalf
, fixf
, f_sizes
); 
1177 class wxHtmlHelpFrameOptionsDialog 
: public wxDialog
 
1180     wxComboBox 
*NormalFont
, *FixedFont
; 
1181     wxSpinCtrl 
*FontSize
; 
1182     wxHtmlWindow 
*TestWin
; 
1184     wxHtmlHelpFrameOptionsDialog(wxWindow 
*parent
) 
1185         : wxDialog(parent
, wxID_ANY
, wxString(_("Help Browser Options"))) 
1187         wxBoxSizer 
*topsizer 
= new wxBoxSizer(wxVERTICAL
); 
1188         wxFlexGridSizer 
*sizer 
= new wxFlexGridSizer(2, 3, 2, 5); 
1190         sizer
->Add(new wxStaticText(this, wxID_ANY
, _("Normal font:"))); 
1191         sizer
->Add(new wxStaticText(this, wxID_ANY
, _("Fixed font:"))); 
1192         sizer
->Add(new wxStaticText(this, wxID_ANY
, _("Font size:"))); 
1194         sizer
->Add(NormalFont 
= new wxComboBox(this, wxID_ANY
, wxEmptyString
, wxDefaultPosition
, 
1196                       0, NULL
, wxCB_DROPDOWN 
| wxCB_READONLY
)); 
1198         sizer
->Add(FixedFont 
= new wxComboBox(this, wxID_ANY
, wxEmptyString
, wxDefaultPosition
, 
1200                       0, NULL
, wxCB_DROPDOWN 
| wxCB_READONLY
)); 
1202         sizer
->Add(FontSize 
= new wxSpinCtrl(this, wxID_ANY
)); 
1203         FontSize
->SetRange(2, 100); 
1205         topsizer
->Add(sizer
, 0, wxLEFT
|wxRIGHT
|wxTOP
, 10); 
1207         topsizer
->Add(new wxStaticText(this, wxID_ANY
, _("Preview:")), 
1208                         0, wxLEFT 
| wxTOP
, 10); 
1209         topsizer
->Add(TestWin 
= new wxHtmlWindow(this, wxID_ANY
, wxDefaultPosition
, wxSize(20, 150), 
1210                                                  wxHW_SCROLLBAR_AUTO 
| wxSUNKEN_BORDER
), 
1211                         1, wxEXPAND 
| wxLEFT
|wxTOP
|wxRIGHT
, 10); 
1213         wxBoxSizer 
*sizer2 
= new wxBoxSizer(wxHORIZONTAL
); 
1215         sizer2
->Add(ok 
= new wxButton(this, wxID_OK
), 0, wxALL
, 10); 
1217         sizer2
->Add(new wxButton(this, wxID_CANCEL
), 0, wxALL
, 10); 
1218         topsizer
->Add(sizer2
, 0, wxALIGN_RIGHT
); 
1221         topsizer
->Fit(this); 
1226     void UpdateTestWin() 
1229         SetFontsToHtmlWin(TestWin
, 
1230                           NormalFont
->GetStringSelection(), 
1231                           FixedFont
->GetStringSelection(), 
1232                           FontSize
->GetValue()); 
1234         wxString 
content(_("font size")); 
1236         content 
= _T("<font size=-2>") + content 
+ _T(" -2</font><br>") 
1237                   _T("<font size=-1>") + content 
+ _T(" -1</font><br>") 
1238                   _T("<font size=+0>") + content 
+ _T(" +0</font><br>") 
1239                   _T("<font size=+1>") + content 
+ _T(" +1</font><br>") 
1240                   _T("<font size=+2>") + content 
+ _T(" +2</font><br>") 
1241                   _T("<font size=+3>") + content 
+ _T(" +3</font><br>") 
1242                   _T("<font size=+4>") + content 
+ _T(" +4</font><br>") ; 
1244         content 
= wxString( _T("<html><body><table><tr><td>") ) + 
1245                   _("Normal face<br>and <u>underlined</u>. ") + 
1246                   _("<i>Italic face.</i> ") + 
1247                   _("<b>Bold face.</b> ") + 
1248                   _("<b><i>Bold italic face.</i></b><br>") + 
1250                   wxString( _T("</td><td><tt>") ) + 
1251                   _("Fixed size face.<br> <b>bold</b> <i>italic</i> ") + 
1252                   _("<b><i>bold italic <u>underlined</u></i></b><br>") + 
1254                   _T("</tt></td></tr></table></body></html>"); 
1256         TestWin
->SetPage( content 
); 
1259     void OnUpdate(wxCommandEvent
& WXUNUSED(event
)) 
1263     void OnUpdateSpin(wxSpinEvent
& WXUNUSED(event
)) 
1268     DECLARE_EVENT_TABLE() 
1269     DECLARE_NO_COPY_CLASS(wxHtmlHelpFrameOptionsDialog
) 
1272 BEGIN_EVENT_TABLE(wxHtmlHelpFrameOptionsDialog
, wxDialog
) 
1273     EVT_COMBOBOX(wxID_ANY
, wxHtmlHelpFrameOptionsDialog::OnUpdate
) 
1274     EVT_SPINCTRL(wxID_ANY
, wxHtmlHelpFrameOptionsDialog::OnUpdateSpin
) 
1277 void wxHtmlHelpFrame::OptionsDialog() 
1279     wxHtmlHelpFrameOptionsDialog 
dlg(this); 
1282     if (m_NormalFonts 
== NULL
) 
1284         wxFontEnumerator enu
; 
1285         enu
.EnumerateFacenames(); 
1286         m_NormalFonts 
= new wxArrayString
; 
1287         *m_NormalFonts 
= *enu
.GetFacenames(); 
1288         m_NormalFonts
->Sort(); // ascending sort 
1290     if (m_FixedFonts 
== NULL
) 
1292         wxFontEnumerator enu
; 
1293         enu
.EnumerateFacenames(wxFONTENCODING_SYSTEM
, true /*enum fixed width only*/); 
1294         m_FixedFonts 
= new wxArrayString
; 
1295         *m_FixedFonts 
= *enu
.GetFacenames(); 
1296         m_FixedFonts
->Sort(); // ascending sort 
1299     // VS: We want to show the font that is actually used by wxHtmlWindow. 
1300     //     If customization dialog wasn't used yet, facenames are empty and 
1301     //     wxHtmlWindow uses default fonts -- let's find out what they 
1302     //     are so that we can pass them to the dialog: 
1303     if (m_NormalFace
.empty()) 
1305         wxFont 
fnt(m_FontSize
, wxSWISS
, wxNORMAL
, wxNORMAL
, false); 
1306         m_NormalFace 
= fnt
.GetFaceName(); 
1308     if (m_FixedFace
.empty()) 
1310         wxFont 
fnt(m_FontSize
, wxMODERN
, wxNORMAL
, wxNORMAL
, false); 
1311         m_FixedFace 
= fnt
.GetFaceName(); 
1314     for (i 
= 0; i 
< m_NormalFonts
->GetCount(); i
++) 
1315         dlg
.NormalFont
->Append((*m_NormalFonts
)[i
]); 
1316     for (i 
= 0; i 
< m_FixedFonts
->GetCount(); i
++) 
1317         dlg
.FixedFont
->Append((*m_FixedFonts
)[i
]); 
1318     if (!m_NormalFace
.empty()) 
1319         dlg
.NormalFont
->SetStringSelection(m_NormalFace
); 
1321         dlg
.NormalFont
->SetSelection(0); 
1322     if (!m_FixedFace
.empty()) 
1323         dlg
.FixedFont
->SetStringSelection(m_FixedFace
); 
1325         dlg
.FixedFont
->SetSelection(0); 
1326     dlg
.FontSize
->SetValue(m_FontSize
); 
1327     dlg
.UpdateTestWin(); 
1329     if (dlg
.ShowModal() == wxID_OK
) 
1331         m_NormalFace 
= dlg
.NormalFont
->GetStringSelection(); 
1332         m_FixedFace 
= dlg
.FixedFont
->GetStringSelection(); 
1333         m_FontSize 
= dlg
.FontSize
->GetValue(); 
1334         SetFontsToHtmlWin(m_HtmlWin
, m_NormalFace
, m_FixedFace
, m_FontSize
); 
1340 void wxHtmlHelpFrame::NotifyPageChanged() 
1342     if (m_UpdateContents 
&& m_PagesHash
) 
1344         wxString an 
= m_HtmlWin
->GetOpenedAnchor(); 
1345         wxHtmlHelpHashData 
*ha
; 
1347             ha 
= (wxHtmlHelpHashData
*) m_PagesHash
->Get(m_HtmlWin
->GetOpenedPage()); 
1349             ha 
= (wxHtmlHelpHashData
*) m_PagesHash
->Get(m_HtmlWin
->GetOpenedPage() + wxT("#") + an
); 
1352             bool olduc 
= m_UpdateContents
; 
1353             m_UpdateContents 
= false; 
1354             m_ContentsBox
->SelectItem(ha
->m_Id
); 
1355             m_ContentsBox
->EnsureVisible(ha
->m_Id
); 
1356             m_UpdateContents 
= olduc
; 
1368 void wxHtmlHelpFrame::OnActivate(wxActivateEvent
& event
) 
1370     // This saves one mouse click when using the 
1371     // wxHTML for context sensitive help systems 
1373     // NB: wxActivateEvent is a bit broken in wxGTK 
1374     //     and is sometimes sent when it should not be 
1375     if (event
.GetActive() && m_HtmlWin
) 
1376         m_HtmlWin
->SetFocus(); 
1382 void wxHtmlHelpFrame::OnToolbar(wxCommandEvent
& event
) 
1384     switch (event
.GetId()) 
1386         case wxID_HTML_BACK 
: 
1387             m_HtmlWin
->HistoryBack(); 
1388             NotifyPageChanged(); 
1391         case wxID_HTML_FORWARD 
: 
1392             m_HtmlWin
->HistoryForward(); 
1393             NotifyPageChanged(); 
1399                 wxString an 
= m_HtmlWin
->GetOpenedAnchor(); 
1400                 wxHtmlHelpHashData 
*ha
; 
1402                     ha 
= (wxHtmlHelpHashData
*) m_PagesHash
->Get(m_HtmlWin
->GetOpenedPage()); 
1404                     ha 
= (wxHtmlHelpHashData
*) m_PagesHash
->Get(m_HtmlWin
->GetOpenedPage() + wxT("#") + an
); 
1405                 if (ha 
&& ha
->m_Index 
> 0) 
1407                     const wxHtmlHelpDataItem
& it 
= m_Data
->GetContentsArray()[ha
->m_Index 
- 1]; 
1408                     if (!it
.page
.empty()) 
1410                         m_HtmlWin
->LoadPage(it
.GetFullPath()); 
1411                         NotifyPageChanged(); 
1417         case wxID_HTML_UPNODE 
: 
1420                 wxString an 
= m_HtmlWin
->GetOpenedAnchor(); 
1421                 wxHtmlHelpHashData 
*ha
; 
1423                     ha 
= (wxHtmlHelpHashData
*) m_PagesHash
->Get(m_HtmlWin
->GetOpenedPage()); 
1425                     ha 
= (wxHtmlHelpHashData
*) m_PagesHash
->Get(m_HtmlWin
->GetOpenedPage() + wxT("#") + an
); 
1426                 if (ha 
&& ha
->m_Index 
> 0) 
1429                         m_Data
->GetContentsArray()[ha
->m_Index
].level 
- 1; 
1430                     int ind 
= ha
->m_Index 
- 1; 
1432                     const wxHtmlHelpDataItem 
*it 
=  
1433                         &m_Data
->GetContentsArray()[ind
]; 
1434                     while (ind 
>= 0 && it
->level 
!= level
) 
1437                         it 
= &m_Data
->GetContentsArray()[ind
]; 
1441                         if (!it
->page
.empty()) 
1443                             m_HtmlWin
->LoadPage(it
->GetFullPath()); 
1444                             NotifyPageChanged(); 
1451         case wxID_HTML_DOWN 
: 
1454                 wxString an 
= m_HtmlWin
->GetOpenedAnchor(); 
1456                 wxHtmlHelpHashData 
*ha
; 
1458                 if (an
.IsEmpty()) adr 
= m_HtmlWin
->GetOpenedPage(); 
1459                 else adr 
= m_HtmlWin
->GetOpenedPage() + wxT("#") + an
; 
1461                 ha 
= (wxHtmlHelpHashData
*) m_PagesHash
->Get(adr
); 
1463                 const wxHtmlHelpDataItems
& contents 
= m_Data
->GetContentsArray(); 
1464                 if (ha 
&& ha
->m_Index 
< (int)contents
.size() - 1) 
1466                     size_t idx 
= ha
->m_Index 
+ 1; 
1468                     while (contents
[idx
].GetFullPath() == adr
) idx
++; 
1470                     if (!contents
[idx
].page
.empty()) 
1472                         m_HtmlWin
->LoadPage(contents
[idx
].GetFullPath()); 
1473                         NotifyPageChanged(); 
1479         case wxID_HTML_PANEL 
: 
1481                 if (! (m_Splitter 
&& m_NavigPan
)) 
1483                 if (m_Splitter
->IsSplit()) 
1485                     m_Cfg
.sashpos 
= m_Splitter
->GetSashPosition(); 
1486                     m_Splitter
->Unsplit(m_NavigPan
); 
1487                     m_Cfg
.navig_on 
= false; 
1493                     m_Splitter
->SplitVertically(m_NavigPan
, m_HtmlWin
, m_Cfg
.sashpos
); 
1494                     m_Cfg
.navig_on 
= true; 
1499         case wxID_HTML_OPTIONS 
: 
1503         case wxID_HTML_BOOKMARKSADD 
: 
1508                 item 
= m_HtmlWin
->GetOpenedPageTitle(); 
1509                 url 
= m_HtmlWin
->GetOpenedPage(); 
1510                 if (item 
== wxEmptyString
) 
1511                     item 
= url
.AfterLast(wxT('/')); 
1512                 if (m_BookmarksPages
.Index(url
) == wxNOT_FOUND
) 
1514                     m_Bookmarks
->Append(item
); 
1515                     m_BookmarksNames
.Add(item
); 
1516                     m_BookmarksPages
.Add(url
); 
1521         case wxID_HTML_BOOKMARKSREMOVE 
: 
1526                 item 
= m_Bookmarks
->GetStringSelection(); 
1527                 pos 
= m_BookmarksNames
.Index(item
); 
1528                 if (pos 
!= wxNOT_FOUND
) 
1530                     m_BookmarksNames
.RemoveAt(pos
); 
1531                     m_BookmarksPages
.RemoveAt(pos
); 
1532                     m_Bookmarks
->Delete(m_Bookmarks
->GetSelection()); 
1537 #if wxUSE_PRINTING_ARCHITECTURE 
1538         case wxID_HTML_PRINT 
: 
1540                 if (m_Printer 
== NULL
) 
1541                     m_Printer 
= new wxHtmlEasyPrinting(_("Help Printing"), this); 
1542                 if (!m_HtmlWin
->GetOpenedPage()) 
1543                     wxLogWarning(_("Cannot print empty page.")); 
1545                     m_Printer
->PrintFile(m_HtmlWin
->GetOpenedPage()); 
1550         case wxID_HTML_OPENFILE 
: 
1552                 wxString filemask 
= wxString( 
1553                     _("HTML files (*.html;*.htm)|*.html;*.htm|")) + 
1554                     _("Help books (*.htb)|*.htb|Help books (*.zip)|*.zip|") + 
1555                     _("HTML Help Project (*.hhp)|*.hhp|") + 
1557                     _("Compressed HTML Help file (*.chm)|*.chm|") + 
1559                     _("All files (*.*)|*"); 
1560                 wxString s 
= wxFileSelector(_("Open HTML document"), 
1565                                             wxOPEN 
| wxFILE_MUST_EXIST
, 
1569                     wxString ext 
= s
.Right(4).Lower(); 
1570                     if (ext 
== _T(".zip") || ext 
== _T(".htb") || 
1572                         ext 
== _T(".chm") || 
1581                         m_HtmlWin
->LoadPage(s
); 
1590 void wxHtmlHelpFrame::OnContentsSel(wxTreeEvent
& event
) 
1592     wxHtmlHelpTreeItemData 
*pg
; 
1594     pg 
= (wxHtmlHelpTreeItemData
*) m_ContentsBox
->GetItemData(event
.GetItem()); 
1596     if (pg 
&& m_UpdateContents
) 
1598         const wxHtmlHelpDataItems
& contents 
= m_Data
->GetContentsArray(); 
1599         m_UpdateContents 
= false; 
1600         if (!contents
[pg
->m_Id
].page
.empty()) 
1601             m_HtmlWin
->LoadPage(contents
[pg
->m_Id
].GetFullPath()); 
1602         m_UpdateContents 
= true; 
1608 void wxHtmlHelpFrame::OnIndexSel(wxCommandEvent
& WXUNUSED(event
)) 
1610     wxHtmlHelpMergedIndexItem 
*it 
= (wxHtmlHelpMergedIndexItem
*)  
1611         m_IndexList
->GetClientData(m_IndexList
->GetSelection()); 
1613         DisplayIndexItem(it
); 
1617 void wxHtmlHelpFrame::OnIndexFind(wxCommandEvent
& event
) 
1619     wxString sr 
= m_IndexText
->GetLineText(0); 
1621     if (sr 
== wxEmptyString
) 
1629         m_IndexList
->Clear(); 
1630         const wxHtmlHelpMergedIndex
& index 
= *m_mergedIndex
; 
1631         size_t cnt 
= index
.size(); 
1634         for (size_t i 
= 0; i 
< cnt
; i
++) 
1636             if (index
[i
].name
.Lower().find(sr
) != wxString::npos
) 
1638                 int pos 
= m_IndexList
->Append(index
[i
].name
, 
1639                                               (char*)(&index
[i
])); 
1643                     // don't automatically show topic selector if this 
1644                     // item points to multiple pages: 
1645                     if (index
[i
].items
.size() == 1) 
1647                         m_IndexList
->SetSelection(0); 
1648                         DisplayIndexItem(&index
[i
]); 
1652                 // if this is nested item of the index, show its parent(s) 
1653                 // as well, otherwise it would not be clear what entry is 
1655                 wxHtmlHelpMergedIndexItem 
*parent 
= index
[i
].parent
; 
1659                         (index
.Index(*(wxHtmlHelpMergedIndexItem
*)m_IndexList
->GetClientData(pos
-1))) < index
.Index(*parent
)) 
1661                         m_IndexList
->Insert(parent
->name
, 
1662                                             pos
, (char*)parent
); 
1663                         parent 
= parent
->parent
; 
1668                 // finally, it the item we just added is itself a parent for 
1669                 // other items, show them as well, because they are refinements 
1670                 // of the displayed index entry (i.e. it is implicitly contained 
1671                 // in them: "foo" with parent "bar" reads as "bar, foo"): 
1672                 short int level 
= index
[i
].items
[0]->level
; 
1674                 while (i 
< cnt 
&& index
[i
].items
[0]->level 
> level
) 
1676                     m_IndexList
->Append(index
[i
].name
, (char*)(&index
[i
])); 
1684         cnttext
.Printf(_("%i of %i"), displ
, cnt
); 
1685         m_IndexCountInfo
->SetLabel(cnttext
); 
1687         m_IndexText
->SetSelection(0, sr
.Length()); 
1688         m_IndexText
->SetFocus(); 
1692 void wxHtmlHelpFrame::OnIndexAll(wxCommandEvent
& WXUNUSED(event
)) 
1696     m_IndexList
->Clear(); 
1697     const wxHtmlHelpMergedIndex
& index 
= *m_mergedIndex
; 
1698     size_t cnt 
= index
.size(); 
1701     for (size_t i 
= 0; i 
< cnt
; i
++) 
1703         m_IndexList
->Append(index
[i
].name
, (char*)(&index
[i
])); 
1706             // don't automatically show topic selector if this 
1707             // item points to multiple pages: 
1708             if (index
[i
].items
.size() == 1) 
1710                 DisplayIndexItem(&index
[i
]); 
1717     cnttext
.Printf(_("%i of %i"), cnt
, cnt
); 
1718     m_IndexCountInfo
->SetLabel(cnttext
); 
1722 void wxHtmlHelpFrame::OnSearchSel(wxCommandEvent
& WXUNUSED(event
)) 
1724     wxHtmlHelpDataItem 
*it 
= (wxHtmlHelpDataItem
*) m_SearchList
->GetClientData(m_SearchList
->GetSelection()); 
1727         if (!it
->page
.empty()) 
1728             m_HtmlWin
->LoadPage(it
->GetFullPath()); 
1729         NotifyPageChanged(); 
1733 void wxHtmlHelpFrame::OnSearch(wxCommandEvent
& WXUNUSED(event
)) 
1735     wxString sr 
= m_SearchText
->GetLineText(0); 
1738         KeywordSearch(sr
, wxHELP_SEARCH_ALL
); 
1741 void wxHtmlHelpFrame::OnBookmarksSel(wxCommandEvent
& WXUNUSED(event
)) 
1743     wxString sr 
= m_Bookmarks
->GetStringSelection(); 
1745     if (sr 
!= wxEmptyString 
&& sr 
!= _("(bookmarks)")) 
1747        m_HtmlWin
->LoadPage(m_BookmarksPages
[m_BookmarksNames
.Index(sr
)]); 
1748        NotifyPageChanged(); 
1752 void wxHtmlHelpFrame::OnCloseWindow(wxCloseEvent
& evt
) 
1754     GetSize(&m_Cfg
.w
, &m_Cfg
.h
); 
1755     GetPosition(&m_Cfg
.x
, &m_Cfg
.y
); 
1764     if (m_Splitter 
&& m_Cfg
.navig_on
) m_Cfg
.sashpos 
= m_Splitter
->GetSashPosition(); 
1767         WriteCustomization(m_Config
, m_ConfigRoot
); 
1769     if (m_helpController 
&& m_helpController
->IsKindOf(CLASSINFO(wxHtmlHelpController
))) 
1771         ((wxHtmlHelpController
*) m_helpController
)->OnCloseFrame(evt
); 
1778 void wxHtmlHelpFrame::OnClose(wxCommandEvent
& event
) 
1783 void wxHtmlHelpFrame::OnAbout(wxCommandEvent
& event
) 
1785     wxMessageBox(wxT("wxWidgets HTML Help Viewer (c) 1998-2004, Vaclav Slavik et al"), wxT("HelpView"), 
1786         wxICON_INFORMATION
|wxOK
, this); 
1790 BEGIN_EVENT_TABLE(wxHtmlHelpFrame
, wxFrame
) 
1791     EVT_ACTIVATE(wxHtmlHelpFrame::OnActivate
) 
1792     EVT_TOOL_RANGE(wxID_HTML_PANEL
, wxID_HTML_OPTIONS
, wxHtmlHelpFrame::OnToolbar
) 
1793     EVT_BUTTON(wxID_HTML_BOOKMARKSREMOVE
, wxHtmlHelpFrame::OnToolbar
) 
1794     EVT_BUTTON(wxID_HTML_BOOKMARKSADD
, wxHtmlHelpFrame::OnToolbar
) 
1795     EVT_TREE_SEL_CHANGED(wxID_HTML_TREECTRL
, wxHtmlHelpFrame::OnContentsSel
) 
1796     EVT_LISTBOX(wxID_HTML_INDEXLIST
, wxHtmlHelpFrame::OnIndexSel
) 
1797     EVT_LISTBOX(wxID_HTML_SEARCHLIST
, wxHtmlHelpFrame::OnSearchSel
) 
1798     EVT_BUTTON(wxID_HTML_SEARCHBUTTON
, wxHtmlHelpFrame::OnSearch
) 
1799     EVT_TEXT_ENTER(wxID_HTML_SEARCHTEXT
, wxHtmlHelpFrame::OnSearch
) 
1800     EVT_BUTTON(wxID_HTML_INDEXBUTTON
, wxHtmlHelpFrame::OnIndexFind
) 
1801     EVT_TEXT_ENTER(wxID_HTML_INDEXTEXT
, wxHtmlHelpFrame::OnIndexFind
) 
1802     EVT_BUTTON(wxID_HTML_INDEXBUTTONALL
, wxHtmlHelpFrame::OnIndexAll
) 
1803     EVT_COMBOBOX(wxID_HTML_BOOKMARKSLIST
, wxHtmlHelpFrame::OnBookmarksSel
) 
1804     EVT_CLOSE(wxHtmlHelpFrame::OnCloseWindow
) 
1806     EVT_MENU(wxID_CLOSE
, wxHtmlHelpFrame::OnClose
) 
1807     EVT_MENU(wxID_ABOUT
, wxHtmlHelpFrame::OnAbout
) 
1808     EVT_MENU(wxID_HELP_CONTENTS
, wxHtmlHelpFrame::OnAbout
) 
1813 #endif // wxUSE_WXHTML_HELP