1 ///////////////////////////////////////////////////////////////////////////// 
   2 // Name:        src/html/helpwnd.cpp 
   3 // Purpose:     wxHtmlHelpWindow 
   4 // Notes:       Based on htmlhelp.cpp, implementing a monolithic 
   5 //              HTML Help controller class,  by Vaclav Slavik 
   6 // Author:      Harm van der Heijden and Vaclav Slavik 
   8 // Copyright:   (c) Harm van der Heijden and Vaclav Slavik 
   9 // Licence:     wxWindows licence 
  10 ///////////////////////////////////////////////////////////////////////////// 
  12 // For compilers that support precompilation, includes "wx.h" 
  14 #include "wx/wxprec.h" 
  23     #include "wx/object.h" 
  24     #include "wx/dynarray.h" 
  28         #include "wx/stream.h" 
  33     #include "wx/bmpbuttn.h" 
  34     #include "wx/statbox.h" 
  35     #include "wx/radiobox.h" 
  37     #include "wx/settings.h" 
  38     #include "wx/msgdlg.h" 
  39     #include "wx/textctrl.h" 
  40     #include "wx/toolbar.h" 
  41     #include "wx/choicdlg.h" 
  42     #include "wx/filedlg.h" 
  45 #include "wx/html/helpfrm.h" 
  46 #include "wx/html/helpdlg.h" 
  47 #include "wx/html/helpctrl.h" 
  48 #include "wx/notebook.h" 
  49 #include "wx/imaglist.h" 
  50 #include "wx/treectrl.h" 
  51 #include "wx/tokenzr.h" 
  52 #include "wx/wfstream.h" 
  53 #include "wx/html/htmlwin.h" 
  54 #include "wx/busyinfo.h" 
  55 #include "wx/progdlg.h" 
  56 #include "wx/fontenum.h" 
  57 #include "wx/artprov.h" 
  58 #include "wx/spinctrl.h" 
  60 // what is considered "small index"? 
  61 #define INDEX_IS_SMALL 100 
  63 /* Motif defines this as a macro */ 
  68 //-------------------------------------------------------------------------- 
  69 // wxHtmlHelpTreeItemData (private) 
  70 //-------------------------------------------------------------------------- 
  72 class wxHtmlHelpTreeItemData 
: public wxTreeItemData
 
  75 #if defined(__VISAGECPP__) 
  76 //  VA needs a default ctor for some reason.... 
  77         wxHtmlHelpTreeItemData() : wxTreeItemData() 
  80         wxHtmlHelpTreeItemData(int id
) : wxTreeItemData() 
  87 //-------------------------------------------------------------------------- 
  88 // wxHtmlHelpHashData (private) 
  89 //-------------------------------------------------------------------------- 
  91 class wxHtmlHelpHashData 
: public wxObject
 
  94         wxHtmlHelpHashData(int index
, wxTreeItemId id
) : wxObject() 
  95             { m_Index 
= index
; m_Id 
= id
;} 
  96         virtual ~wxHtmlHelpHashData() {} 
 103 //-------------------------------------------------------------------------- 
 104 // wxHtmlHelpHtmlWindow (private) 
 105 //-------------------------------------------------------------------------- 
 108 class wxHtmlHelpHtmlWindow 
: public wxHtmlWindow
 
 111     wxHtmlHelpHtmlWindow(wxHtmlHelpWindow 
*win
, wxWindow 
*parent
, wxWindowID id 
= wxID_ANY
, 
 112                          const wxPoint
& pos 
= wxDefaultPosition
, const wxSize
& sz 
= wxDefaultSize
, long style 
= wxHW_DEFAULT_STYLE
) 
 113         : wxHtmlWindow(parent
, id
, pos
, sz
, style
), m_Window(win
) 
 118     void OnLink(wxHtmlLinkEvent
& ev
) 
 120         const wxMouseEvent 
*e 
= ev
.GetLinkInfo().GetEvent(); 
 121         if (e 
== NULL 
|| e
->LeftUp()) 
 122             m_Window
->NotifyPageChanged(); 
 124         // skip the event so that normal processing (i.e. following the link) 
 129     // Returns full location with anchor (helper) 
 130     static wxString 
GetOpenedPageWithAnchor(wxHtmlWindow 
*win
) 
 133             return wxEmptyString
; 
 135         wxString an 
= win
->GetOpenedAnchor(); 
 136         wxString pg 
= win
->GetOpenedPage(); 
 139             pg 
<< wxT("#") << an
; 
 145     wxHtmlHelpWindow 
*m_Window
; 
 147     wxDECLARE_NO_COPY_CLASS(wxHtmlHelpHtmlWindow
); 
 148     DECLARE_EVENT_TABLE() 
 151 BEGIN_EVENT_TABLE(wxHtmlHelpHtmlWindow
, wxHtmlWindow
) 
 152     EVT_HTML_LINK_CLICKED(wxID_ANY
, wxHtmlHelpHtmlWindow::OnLink
) 
 156 //--------------------------------------------------------------------------- 
 157 // wxHtmlHelpWindow::m_mergedIndex 
 158 //--------------------------------------------------------------------------- 
 160 WX_DEFINE_ARRAY_PTR(const wxHtmlHelpDataItem
*, wxHtmlHelpDataItemPtrArray
); 
 162 struct wxHtmlHelpMergedIndexItem
 
 164     wxHtmlHelpMergedIndexItem 
*parent
; 
 166     wxHtmlHelpDataItemPtrArray items
; 
 169 WX_DECLARE_OBJARRAY(wxHtmlHelpMergedIndexItem
, wxHtmlHelpMergedIndex
); 
 170 #include "wx/arrimpl.cpp" 
 171 WX_DEFINE_OBJARRAY(wxHtmlHelpMergedIndex
) 
 173 void wxHtmlHelpWindow::UpdateMergedIndex() 
 175     delete m_mergedIndex
; 
 176     m_mergedIndex 
= new wxHtmlHelpMergedIndex
; 
 177     wxHtmlHelpMergedIndex
& merged 
= *m_mergedIndex
; 
 179     const wxHtmlHelpDataItems
& items 
= m_Data
->GetIndexArray(); 
 180     size_t len 
= items
.size(); 
 182     wxHtmlHelpMergedIndexItem 
*history
[128] = {NULL
}; 
 184     for (size_t i 
= 0; i 
< len
; i
++) 
 186         const wxHtmlHelpDataItem
& item 
= items
[i
]; 
 187         wxASSERT_MSG( item
.level 
< 128, wxT("nested index entries too deep") ); 
 189         if (history
[item
.level
] && 
 190             history
[item
.level
]->items
[0]->name 
== item
.name
) 
 192             // same index entry as previous one, update list of items 
 193             history
[item
.level
]->items
.Add(&item
); 
 198             wxHtmlHelpMergedIndexItem 
*mi 
= new wxHtmlHelpMergedIndexItem(); 
 199             mi
->name 
= item
.GetIndentedName(); 
 200             mi
->items
.Add(&item
); 
 201             mi
->parent 
= (item
.level 
== 0) ? NULL 
: history
[item
.level 
- 1]; 
 202             history
[item
.level
] = mi
; 
 208 //--------------------------------------------------------------------------- 
 210 //--------------------------------------------------------------------------- 
 212 IMPLEMENT_DYNAMIC_CLASS(wxHtmlHelpWindow
, wxWindow
) 
 214 BEGIN_EVENT_TABLE(wxHtmlHelpWindow
, wxWindow
) 
 215     EVT_TOOL_RANGE(wxID_HTML_PANEL
, wxID_HTML_OPTIONS
, wxHtmlHelpWindow::OnToolbar
) 
 216     EVT_BUTTON(wxID_HTML_BOOKMARKSREMOVE
, wxHtmlHelpWindow::OnToolbar
) 
 217     EVT_BUTTON(wxID_HTML_BOOKMARKSADD
, wxHtmlHelpWindow::OnToolbar
) 
 218     EVT_TREE_SEL_CHANGED(wxID_HTML_TREECTRL
, wxHtmlHelpWindow::OnContentsSel
) 
 219     EVT_LISTBOX(wxID_HTML_INDEXLIST
, wxHtmlHelpWindow::OnIndexSel
) 
 220     EVT_LISTBOX(wxID_HTML_SEARCHLIST
, wxHtmlHelpWindow::OnSearchSel
) 
 221     EVT_BUTTON(wxID_HTML_SEARCHBUTTON
, wxHtmlHelpWindow::OnSearch
) 
 222     EVT_TEXT_ENTER(wxID_HTML_SEARCHTEXT
, wxHtmlHelpWindow::OnSearch
) 
 223     EVT_BUTTON(wxID_HTML_INDEXBUTTON
, wxHtmlHelpWindow::OnIndexFind
) 
 224     EVT_TEXT_ENTER(wxID_HTML_INDEXTEXT
, wxHtmlHelpWindow::OnIndexFind
) 
 225     EVT_BUTTON(wxID_HTML_INDEXBUTTONALL
, wxHtmlHelpWindow::OnIndexAll
) 
 226     EVT_COMBOBOX(wxID_HTML_BOOKMARKSLIST
, wxHtmlHelpWindow::OnBookmarksSel
) 
 227     EVT_SIZE(wxHtmlHelpWindow::OnSize
) 
 230 wxHtmlHelpWindow::wxHtmlHelpWindow(wxWindow
* parent
, wxWindowID id
, 
 233                                     int style
, int helpStyle
, wxHtmlHelpData
* data
) 
 236     Create(parent
, id
, pos
, size
, style
, helpStyle
); 
 239 void wxHtmlHelpWindow::Init(wxHtmlHelpData
* data
) 
 244         m_DataCreated 
= false; 
 248         m_Data 
= new wxHtmlHelpData(); 
 249         m_DataCreated 
= true; 
 256     m_ContentsBox 
= NULL
; 
 258     m_IndexButton 
= NULL
; 
 259     m_IndexButtonAll 
= NULL
; 
 262     m_SearchButton 
= NULL
; 
 264     m_SearchChoice 
= NULL
; 
 265     m_IndexCountInfo 
= NULL
; 
 268     m_NavigNotebook 
= NULL
; 
 271     m_SearchCaseSensitive 
= NULL
; 
 272     m_SearchWholeWords 
= NULL
; 
 274     m_mergedIndex 
= NULL
; 
 277     m_ConfigRoot 
= wxEmptyString
; 
 279     m_Cfg
.x 
= m_Cfg
.y 
= wxDefaultCoord
; 
 283     m_Cfg
.navig_on 
= true; 
 285     m_NormalFonts 
= m_FixedFonts 
= NULL
; 
 286     m_NormalFace 
= m_FixedFace 
= wxEmptyString
; 
 293 #if wxUSE_PRINTING_ARCHITECTURE 
 298     m_UpdateContents 
= true; 
 300     m_helpController 
= NULL
; 
 303 // Create: builds the GUI components. 
 304 // with the style flag it's possible to toggle the toolbar, contents, index and search 
 306 // m_HtmlWin will *always* be created, but it's important to realize that 
 307 // m_ContentsBox, m_IndexList, m_SearchList, m_SearchButton, m_SearchText and 
 308 // m_SearchButton may be NULL. 
 309 // moreover, if no contents, index or searchpage is needed, m_Splitter and 
 310 // m_NavigPan will be NULL too (with m_HtmlWin directly connected to the frame) 
 312 bool wxHtmlHelpWindow::Create(wxWindow
* parent
, wxWindowID id
, 
 313                              const wxPoint
& pos
, const wxSize
& size
, 
 314                              int style
, int helpStyle
) 
 316     m_hfStyle 
= helpStyle
; 
 318     // Do the config in two steps. We read the HtmlWindow customization after we 
 319     // create the window. 
 321         ReadCustomization(m_Config
, m_ConfigRoot
); 
 323     wxWindow::Create(parent
, id
, pos
, size
, style
, wxT("wxHtmlHelp")); 
 325     SetHelpText(_("Displays help as you browse the books on the left.")); 
 327     GetPosition(&m_Cfg
.x
, &m_Cfg
.y
); 
 329     int notebook_page 
= 0; 
 331     // The sizer for the whole top-level window. 
 332     wxSizer 
*topWindowSizer 
= new wxBoxSizer(wxVERTICAL
); 
 333     SetSizer(topWindowSizer
); 
 338     if (helpStyle 
& (wxHF_TOOLBAR 
| wxHF_FLAT_TOOLBAR
)) 
 340         wxToolBar 
*toolBar 
= new wxToolBar(this, wxID_ANY
, wxDefaultPosition
, wxDefaultSize
, 
 341                                            wxNO_BORDER 
| wxTB_HORIZONTAL 
| 
 342                                            wxTB_DOCKABLE 
| wxTB_NODIVIDER 
| 
 343                                            (helpStyle 
& wxHF_FLAT_TOOLBAR 
? wxTB_FLAT 
: 0)); 
 344         toolBar
->SetMargins( 2, 2 ); 
 345         toolBar
->SetToolBitmapSize( wxSize(22,22) ); 
 346         AddToolbarButtons(toolBar
, helpStyle
); 
 348         topWindowSizer
->Add(toolBar
, 0, wxEXPAND
); 
 351 #endif //wxUSE_TOOLBAR 
 353     wxSizer 
*navigSizer 
= NULL
; 
 356     wxBorder htmlWindowBorder 
= GetDefaultBorder(); 
 357     if (htmlWindowBorder 
== wxBORDER_SUNKEN
) 
 358         htmlWindowBorder 
= wxBORDER_SIMPLE
; 
 360     wxBorder htmlWindowBorder 
= wxBORDER_SIMPLE
; 
 363     if (helpStyle 
& (wxHF_CONTENTS 
| wxHF_INDEX 
| wxHF_SEARCH
)) 
 365         // traditional help controller; splitter window with html page on the 
 366         // right and a notebook containing various pages on the left 
 367         long splitterStyle 
= wxSP_3D
; 
 368         // Drawing moving sash can cause problems on wxMac 
 370         splitterStyle 
|= wxSP_LIVE_UPDATE
; 
 372         m_Splitter 
= new wxSplitterWindow(this, wxID_ANY
, wxDefaultPosition
, wxDefaultSize
, splitterStyle
); 
 374         topWindowSizer
->Add(m_Splitter
, 1, wxEXPAND
); 
 376         m_HtmlWin 
= new wxHtmlHelpHtmlWindow(this, m_Splitter
, wxID_ANY
, wxDefaultPosition
, wxDefaultSize
, wxHW_DEFAULT_STYLE
|htmlWindowBorder
); 
 377         m_NavigPan 
= new wxPanel(m_Splitter
, wxID_ANY
); 
 378         m_NavigNotebook 
= new wxNotebook(m_NavigPan
, wxID_HTML_NOTEBOOK
, 
 379                                          wxDefaultPosition
, wxDefaultSize
); 
 381         m_NavigNotebook
->SetWindowVariant(wxWINDOW_VARIANT_SMALL
); 
 384         navigSizer 
= new wxBoxSizer(wxVERTICAL
); 
 385         navigSizer
->Add(m_NavigNotebook
, 1, wxEXPAND
); 
 387         m_NavigPan
->SetSizer(navigSizer
); 
 391         // only html window, no notebook with index,contents etc 
 392         m_HtmlWin 
= new wxHtmlWindow(this, wxID_ANY
, wxDefaultPosition
, wxDefaultSize
, wxHW_DEFAULT_STYLE
|htmlWindowBorder
); 
 393         topWindowSizer
->Add(m_HtmlWin
, 1, wxEXPAND
); 
 397         m_HtmlWin
->ReadCustomization(m_Config
, m_ConfigRoot
); 
 399     // contents tree panel? 
 400     if ( helpStyle 
& wxHF_CONTENTS 
) 
 402         wxWindow 
*dummy 
= new wxPanel(m_NavigNotebook
, wxID_HTML_INDEXPAGE
); 
 404         dummy
->SetWindowVariant(wxWINDOW_VARIANT_NORMAL
); 
 406         wxSizer 
*topsizer 
= new wxBoxSizer(wxVERTICAL
); 
 408         topsizer
->Add(0, 10); 
 410         dummy
->SetSizer(topsizer
); 
 412         if ( helpStyle 
& wxHF_BOOKMARKS 
) 
 414             m_Bookmarks 
= new wxComboBox(dummy
, wxID_HTML_BOOKMARKSLIST
, 
 416                                          wxDefaultPosition
, wxDefaultSize
, 
 417                                          0, NULL
, wxCB_READONLY 
| wxCB_SORT
); 
 418             m_Bookmarks
->Append(_("(bookmarks)")); 
 419             for (unsigned i 
= 0; i 
< m_BookmarksNames
.GetCount(); i
++) 
 420                 m_Bookmarks
->Append(m_BookmarksNames
[i
]); 
 421             m_Bookmarks
->SetSelection(0); 
 423             wxBitmapButton 
*bmpbt1
, *bmpbt2
; 
 424             bmpbt1 
= new wxBitmapButton(dummy
, wxID_HTML_BOOKMARKSADD
, 
 425                                  wxArtProvider::GetBitmap(wxART_ADD_BOOKMARK
, 
 427             bmpbt2 
= new wxBitmapButton(dummy
, wxID_HTML_BOOKMARKSREMOVE
, 
 428                                  wxArtProvider::GetBitmap(wxART_DEL_BOOKMARK
, 
 431             bmpbt1
->SetToolTip(_("Add current page to bookmarks")); 
 432             bmpbt2
->SetToolTip(_("Remove current page from bookmarks")); 
 433 #endif // wxUSE_TOOLTIPS 
 435             wxSizer 
*sizer 
= new wxBoxSizer(wxHORIZONTAL
); 
 437             sizer
->Add(m_Bookmarks
, 1, wxALIGN_CENTRE_VERTICAL 
| wxRIGHT
, 5); 
 438             sizer
->Add(bmpbt1
, 0, wxALIGN_CENTRE_VERTICAL 
| wxRIGHT
, 2); 
 439             sizer
->Add(bmpbt2
, 0, wxALIGN_CENTRE_VERTICAL
, 0); 
 441             topsizer
->Add(sizer
, 0, wxEXPAND 
| wxLEFT 
| wxBOTTOM 
| wxRIGHT
, 10); 
 444         m_ContentsBox 
= new wxTreeCtrl(dummy
, wxID_HTML_TREECTRL
, 
 445                                        wxDefaultPosition
, wxDefaultSize
, 
 446 #if defined(__WXGTK20__) || defined(__WXMAC__) 
 448                                        wxTR_HAS_BUTTONS 
| wxTR_HIDE_ROOT 
| 
 452                                        wxTR_HAS_BUTTONS 
| wxTR_HIDE_ROOT 
| 
 457         wxImageList 
*ContentsImageList 
= new wxImageList(16, 16); 
 458         ContentsImageList
->Add(wxArtProvider::GetIcon(wxART_HELP_BOOK
, 
 461         ContentsImageList
->Add(wxArtProvider::GetIcon(wxART_HELP_FOLDER
, 
 464         ContentsImageList
->Add(wxArtProvider::GetIcon(wxART_HELP_PAGE
, 
 468         m_ContentsBox
->AssignImageList(ContentsImageList
); 
 470         topsizer
->Add(m_ContentsBox
, 1, 
 471                       wxEXPAND 
| wxLEFT 
| wxBOTTOM 
| wxRIGHT
, 
 474         m_NavigNotebook
->AddPage(dummy
, _("Contents")); 
 475         m_ContentsPage 
= notebook_page
++; 
 478     // index listbox panel? 
 479     if ( helpStyle 
& wxHF_INDEX 
) 
 481         wxWindow 
*dummy 
= new wxPanel(m_NavigNotebook
, wxID_HTML_INDEXPAGE
); 
 483         dummy
->SetWindowVariant(wxWINDOW_VARIANT_NORMAL
); 
 485         wxSizer 
*topsizer 
= new wxBoxSizer(wxVERTICAL
); 
 487         dummy
->SetSizer(topsizer
); 
 489         m_IndexText 
= new wxTextCtrl(dummy
, wxID_HTML_INDEXTEXT
, wxEmptyString
, 
 490                                      wxDefaultPosition
, wxDefaultSize
, 
 492         m_IndexButton 
= new wxButton(dummy
, wxID_HTML_INDEXBUTTON
, _("Find")); 
 493         m_IndexButtonAll 
= new wxButton(dummy
, wxID_HTML_INDEXBUTTONALL
, 
 495         m_IndexCountInfo 
= new wxStaticText(dummy
, wxID_HTML_COUNTINFO
, 
 496                                             wxEmptyString
, wxDefaultPosition
, 
 498                                             wxALIGN_RIGHT 
| wxST_NO_AUTORESIZE
); 
 499         m_IndexList 
= new wxListBox(dummy
, wxID_HTML_INDEXLIST
, 
 500                                     wxDefaultPosition
, wxDefaultSize
, 
 501                                     0, NULL
, wxLB_SINGLE
); 
 504         m_IndexButton
->SetToolTip(_("Display all index items that contain given substring. Search is case insensitive.")); 
 505         m_IndexButtonAll
->SetToolTip(_("Show all items in index")); 
 506 #endif //wxUSE_TOOLTIPS 
 508         topsizer
->Add(m_IndexText
, 0, wxEXPAND 
| wxALL
, 10); 
 509         wxSizer 
*btsizer 
= new wxBoxSizer(wxHORIZONTAL
); 
 510         btsizer
->Add(m_IndexButton
, 0, wxRIGHT
, 2); 
 511         btsizer
->Add(m_IndexButtonAll
); 
 512         topsizer
->Add(btsizer
, 0, 
 513                       wxALIGN_RIGHT 
| wxLEFT 
| wxRIGHT 
| wxBOTTOM
, 10); 
 514         topsizer
->Add(m_IndexCountInfo
, 0, wxEXPAND 
| wxLEFT 
| wxRIGHT
, 2); 
 515         topsizer
->Add(m_IndexList
, 1, wxEXPAND 
| wxALL
, 2); 
 517         m_NavigNotebook
->AddPage(dummy
, _("Index")); 
 518         m_IndexPage 
= notebook_page
++; 
 521     // search list panel? 
 522     if ( helpStyle 
& wxHF_SEARCH 
) 
 524         wxWindow 
*dummy 
= new wxPanel(m_NavigNotebook
, wxID_HTML_INDEXPAGE
); 
 526         dummy
->SetWindowVariant(wxWINDOW_VARIANT_NORMAL
); 
 528         wxSizer 
*sizer 
= new wxBoxSizer(wxVERTICAL
); 
 530         dummy
->SetSizer(sizer
); 
 532         m_SearchText 
= new wxTextCtrl(dummy
, wxID_HTML_SEARCHTEXT
, 
 534                                       wxDefaultPosition
, wxDefaultSize
, 
 536         m_SearchChoice 
= new wxChoice(dummy
, wxID_HTML_SEARCHCHOICE
, 
 537                                       wxDefaultPosition
, wxSize(125,wxDefaultCoord
)); 
 538         m_SearchCaseSensitive 
= new wxCheckBox(dummy
, wxID_ANY
, _("Case sensitive")); 
 539         m_SearchWholeWords 
= new wxCheckBox(dummy
, wxID_ANY
, _("Whole words only")); 
 540         m_SearchButton 
= new wxButton(dummy
, wxID_HTML_SEARCHBUTTON
, _("Search")); 
 542         m_SearchButton
->SetToolTip(_("Search contents of help book(s) for all occurrences of the text you typed above")); 
 543 #endif //wxUSE_TOOLTIPS 
 544         m_SearchList 
= new wxListBox(dummy
, wxID_HTML_SEARCHLIST
, 
 545                                      wxDefaultPosition
, wxDefaultSize
, 
 546                                      0, NULL
, wxLB_SINGLE
); 
 548         sizer
->Add(m_SearchText
, 0, wxEXPAND 
| wxALL
, 10); 
 549         sizer
->Add(m_SearchChoice
, 0, wxEXPAND 
| wxLEFT 
| wxRIGHT 
| wxBOTTOM
, 10); 
 550         sizer
->Add(m_SearchCaseSensitive
, 0, wxLEFT 
| wxRIGHT
, 10); 
 551         sizer
->Add(m_SearchWholeWords
, 0, wxLEFT 
| wxRIGHT
, 10); 
 552         sizer
->Add(m_SearchButton
, 0, wxALL 
| wxALIGN_RIGHT
, 8); 
 553         sizer
->Add(m_SearchList
, 1, wxALL 
| wxEXPAND
, 2); 
 555         m_NavigNotebook
->AddPage(dummy
, _("Search")); 
 556         m_SearchPage 
= notebook_page
; 
 565         navigSizer
->SetSizeHints(m_NavigPan
); 
 566         m_NavigPan
->Layout(); 
 570     if ( m_NavigPan 
&& m_Splitter 
) 
 572         // The panel will have its own min size which the splitter 
 575         //    m_Splitter->SetMinimumPaneSize(m_NavigPan->GetBestSize().x); 
 577         m_Splitter
->SetMinimumPaneSize(20); 
 579         if ( m_Cfg
.navig_on 
) 
 582             m_Splitter
->SplitVertically(m_NavigPan
, m_HtmlWin
, m_Cfg
.sashpos
); 
 586             m_NavigPan
->Show(false); 
 587             m_Splitter
->Initialize(m_HtmlWin
); 
 591     // Reduce flicker by updating the splitter pane sizes before the 
 593     wxSizeEvent 
sizeEvent(GetSize(), GetId()); 
 594     GetEventHandler()->ProcessEvent(sizeEvent
); 
 597         m_Splitter
->UpdateSize(); 
 602 wxHtmlHelpWindow::~wxHtmlHelpWindow() 
 604     if ( m_helpController 
) 
 605         m_helpController
->SetHelpWindow(NULL
); 
 607     delete m_mergedIndex
; 
 609     // PopEventHandler(); // wxhtmlhelpcontroller (not any more!) 
 612     if (m_NormalFonts
) delete m_NormalFonts
; 
 613     if (m_FixedFonts
) delete m_FixedFonts
; 
 616         WX_CLEAR_HASH_TABLE(*m_PagesHash
); 
 619 #if wxUSE_PRINTING_ARCHITECTURE 
 620     if (m_Printer
) delete m_Printer
; 
 624 void wxHtmlHelpWindow::SetController(wxHtmlHelpController
* controller
) 
 628     m_helpController 
= controller
; 
 629     m_Data 
= controller
->GetHelpData(); 
 630     m_DataCreated 
= false; 
 634 void wxHtmlHelpWindow::AddToolbarButtons(wxToolBar 
*toolBar
, int style
) 
 636     wxBitmap wpanelBitmap 
= 
 637         wxArtProvider::GetBitmap(wxART_HELP_SIDE_PANEL
, wxART_TOOLBAR
); 
 638     wxBitmap wbackBitmap 
= 
 639         wxArtProvider::GetBitmap(wxART_GO_BACK
, wxART_TOOLBAR
); 
 640     wxBitmap wforwardBitmap 
= 
 641         wxArtProvider::GetBitmap(wxART_GO_FORWARD
, wxART_TOOLBAR
); 
 642     wxBitmap wupnodeBitmap 
= 
 643         wxArtProvider::GetBitmap(wxART_GO_TO_PARENT
, wxART_TOOLBAR
); 
 645         wxArtProvider::GetBitmap(wxART_GO_UP
, wxART_TOOLBAR
); 
 646     wxBitmap wdownBitmap 
= 
 647         wxArtProvider::GetBitmap(wxART_GO_DOWN
, wxART_TOOLBAR
); 
 648     wxBitmap wopenBitmap 
= 
 649         wxArtProvider::GetBitmap(wxART_FILE_OPEN
, wxART_TOOLBAR
); 
 650     wxBitmap wprintBitmap 
= 
 651         wxArtProvider::GetBitmap(wxART_PRINT
, wxART_TOOLBAR
); 
 652     wxBitmap woptionsBitmap 
= 
 653         wxArtProvider::GetBitmap(wxART_HELP_SETTINGS
, wxART_TOOLBAR
); 
 655     wxASSERT_MSG( (wpanelBitmap
.Ok() && wbackBitmap
.Ok() && 
 656                    wforwardBitmap
.Ok() && wupnodeBitmap
.Ok() && 
 657                    wupBitmap
.Ok() && wdownBitmap
.Ok() && 
 658                    wopenBitmap
.Ok() && wprintBitmap
.Ok() && 
 659                    woptionsBitmap
.Ok()), 
 660                   wxT("One or more HTML help frame toolbar bitmap could not be loaded.")) ; 
 663     toolBar
->AddTool(wxID_HTML_PANEL
, wxEmptyString
, wpanelBitmap
, _("Show/hide navigation panel")); 
 664     toolBar
->AddSeparator(); 
 665     toolBar
->AddTool(wxID_HTML_BACK
, wxEmptyString
, wbackBitmap
, _("Go back")); 
 666     toolBar
->AddTool(wxID_HTML_FORWARD
, wxEmptyString
, wforwardBitmap
, _("Go forward")); 
 667     toolBar
->AddSeparator(); 
 668     toolBar
->AddTool(wxID_HTML_UPNODE
, wxEmptyString
, wupnodeBitmap
, _("Go one level up in document hierarchy")); 
 669     toolBar
->AddTool(wxID_HTML_UP
, wxEmptyString
, wupBitmap
, _("Previous page")); 
 670     toolBar
->AddTool(wxID_HTML_DOWN
, wxEmptyString
, wdownBitmap
, _("Next page")); 
 672     if ((style 
& wxHF_PRINT
) || (style 
& wxHF_OPEN_FILES
)) 
 673         toolBar
->AddSeparator(); 
 675     if (style 
& wxHF_OPEN_FILES
) 
 676         toolBar
->AddTool(wxID_HTML_OPENFILE
, wxEmptyString
, wopenBitmap
, _("Open HTML document")); 
 678 #if wxUSE_PRINTING_ARCHITECTURE 
 679     if (style 
& wxHF_PRINT
) 
 680         toolBar
->AddTool(wxID_HTML_PRINT
, wxEmptyString
, wprintBitmap
, _("Print this page")); 
 683     toolBar
->AddSeparator(); 
 684     toolBar
->AddTool(wxID_HTML_OPTIONS
, wxEmptyString
, woptionsBitmap
, _("Display options dialog")); 
 686     // Allow application to add custom buttons 
 687     wxHtmlHelpFrame
* parentFrame 
= wxDynamicCast(GetParent(), wxHtmlHelpFrame
); 
 688     wxHtmlHelpDialog
* parentDialog 
= wxDynamicCast(GetParent(), wxHtmlHelpDialog
); 
 690         parentFrame
->AddToolbarButtons(toolBar
, style
); 
 692         parentDialog
->AddToolbarButtons(toolBar
, style
); 
 694 #endif //wxUSE_TOOLBAR 
 697 bool wxHtmlHelpWindow::Display(const wxString
& x
) 
 699     wxString url 
= m_Data
->FindPageByName(x
); 
 702         m_HtmlWin
->LoadPage(url
); 
 710 bool wxHtmlHelpWindow::Display(const int id
) 
 712     wxString url 
= m_Data
->FindPageById(id
); 
 715         m_HtmlWin
->LoadPage(url
); 
 723 bool wxHtmlHelpWindow::DisplayContents() 
 728     if (!m_Splitter
->IsSplit()) 
 732         m_Splitter
->SplitVertically(m_NavigPan
, m_HtmlWin
, m_Cfg
.sashpos
); 
 733         m_Cfg
.navig_on 
= true; 
 736     m_NavigNotebook
->SetSelection(m_ContentsPage
); 
 738     if (m_Data
->GetBookRecArray().GetCount() > 0) 
 740         wxHtmlBookRecord
& book 
= m_Data
->GetBookRecArray()[0]; 
 741         if (!book
.GetStart().empty()) 
 742             m_HtmlWin
->LoadPage(book
.GetFullPath(book
.GetStart())); 
 748 bool wxHtmlHelpWindow::DisplayIndex() 
 753     if (!m_Splitter
->IsSplit()) 
 757         m_Splitter
->SplitVertically(m_NavigPan
, m_HtmlWin
, m_Cfg
.sashpos
); 
 760     m_NavigNotebook
->SetSelection(m_IndexPage
); 
 762     if (m_Data
->GetBookRecArray().GetCount() > 0) 
 764         wxHtmlBookRecord
& book 
= m_Data
->GetBookRecArray()[0]; 
 765         if (!book
.GetStart().empty()) 
 766             m_HtmlWin
->LoadPage(book
.GetFullPath(book
.GetStart())); 
 772 void wxHtmlHelpWindow::DisplayIndexItem(const wxHtmlHelpMergedIndexItem 
*it
) 
 774     if (it
->items
.size() == 1) 
 776         if (!it
->items
[0]->page
.empty()) 
 778             m_HtmlWin
->LoadPage(it
->items
[0]->GetFullPath()); 
 784         wxBusyCursor busy_cursor
; 
 786         // more pages associated with this index item -- let the user choose 
 787         // which one she/he wants from a list: 
 789         size_t len 
= it
->items
.size(); 
 790         for (size_t i 
= 0; i 
< len
; i
++) 
 792             wxString page 
= it
->items
[i
]->page
; 
 793             // try to find page's title in contents: 
 794             const wxHtmlHelpDataItems
& contents 
= m_Data
->GetContentsArray(); 
 795             size_t clen 
= contents
.size(); 
 796             for (size_t j 
= 0; j 
< clen
; j
++) 
 798                 if (contents
[j
].page 
== page
) 
 800                     page 
= contents
[j
].name
; 
 807         wxSingleChoiceDialog 
dlg(this, 
 808                                  _("Please choose the page to display:"), 
 810                                  arr
, NULL
, wxCHOICEDLG_STYLE 
& ~wxCENTRE
); 
 811         if (dlg
.ShowModal() == wxID_OK
) 
 813             m_HtmlWin
->LoadPage(it
->items
[dlg
.GetSelection()]->GetFullPath()); 
 819 bool wxHtmlHelpWindow::KeywordSearch(const wxString
& keyword
, 
 820                                     wxHelpSearchMode mode
) 
 822     wxCHECK_MSG( !keyword
.empty(), false, "must have a non empty keyword" ); 
 824     if (mode 
== wxHELP_SEARCH_ALL
) 
 826         if ( !(m_SearchList 
&& 
 827                m_SearchButton 
&& m_SearchText 
&& m_SearchChoice
) ) 
 830     else if (mode 
== wxHELP_SEARCH_INDEX
) 
 832         if ( !(m_IndexList 
&& 
 833                m_IndexButton 
&& m_IndexButtonAll 
&& m_IndexText
) ) 
 839     wxString book 
= wxEmptyString
; 
 841     if (!m_Splitter
->IsSplit()) 
 845         m_Splitter
->SplitVertically(m_NavigPan
, m_HtmlWin
, m_Cfg
.sashpos
); 
 848     if (mode 
== wxHELP_SEARCH_ALL
) 
 850         m_NavigNotebook
->SetSelection(m_SearchPage
); 
 851         m_SearchList
->Clear(); 
 852         m_SearchText
->SetValue(keyword
); 
 853         m_SearchButton
->Disable(); 
 855         if (m_SearchChoice
->GetSelection() != 0) 
 856             book 
= m_SearchChoice
->GetStringSelection(); 
 858         wxHtmlSearchStatus 
status(m_Data
, keyword
, 
 859                                   m_SearchCaseSensitive
->GetValue(), 
 860                                   m_SearchWholeWords
->GetValue(), 
 863 #if wxUSE_PROGRESSDLG 
 864         wxProgressDialog 
progress(_("Searching..."), 
 865                                   _("No matching page found yet"), 
 866                                   status
.GetMaxIndex(), this, 
 867                                   wxPD_APP_MODAL 
| wxPD_CAN_ABORT 
| wxPD_AUTO_HIDE
); 
 871         while (status
.IsActive()) 
 873             curi 
= status
.GetCurIndex(); 
 875 #if wxUSE_PROGRESSDLG 
 876                 && !progress
.Update(curi
) 
 882                 foundstr
.Printf(_("Found %i matches"), ++foundcnt
); 
 883 #if wxUSE_PROGRESSDLG 
 884                 progress
.Update(status
.GetCurIndex(), foundstr
); 
 886                 m_SearchList
->Append(status
.GetName(), (void*)status
.GetCurItem()); 
 890         m_SearchButton
->Enable(); 
 891         m_SearchText
->SetSelection(0, keyword
.length()); 
 892         m_SearchText
->SetFocus(); 
 894     else if (mode 
== wxHELP_SEARCH_INDEX
) 
 896         m_NavigNotebook
->SetSelection(m_IndexPage
); 
 897         m_IndexList
->Clear(); 
 898         m_IndexButton
->Disable(); 
 899         m_IndexButtonAll
->Disable(); 
 900         m_IndexText
->SetValue(keyword
); 
 903         m_IndexButton
->Enable(); 
 904         m_IndexButtonAll
->Enable(); 
 905         foundcnt 
= m_IndexList
->GetCount(); 
 913                 wxFAIL_MSG( wxT("unknown help search mode") ); 
 916             case wxHELP_SEARCH_ALL
: 
 918                 wxHtmlHelpDataItem 
*it 
= 
 919                     (wxHtmlHelpDataItem
*) m_SearchList
->GetClientData(0); 
 922                     m_HtmlWin
->LoadPage(it
->GetFullPath()); 
 928             case wxHELP_SEARCH_INDEX
: 
 930                 wxHtmlHelpMergedIndexItem
* it 
= 
 931                     (wxHtmlHelpMergedIndexItem
*) m_IndexList
->GetClientData(0); 
 933                     DisplayIndexItem(it
); 
 943 void wxHtmlHelpWindow::CreateContents() 
 950         WX_CLEAR_HASH_TABLE(*m_PagesHash
); 
 954     const wxHtmlHelpDataItems
& contents 
= m_Data
->GetContentsArray(); 
 956     size_t cnt 
= contents
.size(); 
 958     m_PagesHash 
= new wxHashTable(wxKEY_STRING
, 2 * cnt
); 
 960     const int MAX_ROOTS 
= 64; 
 961     wxTreeItemId roots
[MAX_ROOTS
]; 
 962     // VS: this array holds information about whether we've set item icon at 
 963     //     given level. This is necessary because m_Data has a flat structure 
 964     //     and there's no way of recognizing if some item has subitems or not. 
 965     //     We set the icon later: when we find an item with level=n, we know 
 966     //     that the last item with level=n-1 was afolder with subitems, so we 
 967     //     set its icon accordingly 
 968     bool imaged
[MAX_ROOTS
]; 
 969     m_ContentsBox
->DeleteAllItems(); 
 971     roots
[0] = m_ContentsBox
->AddRoot(_("(Help)")); 
 974     for (size_t i 
= 0; i 
< cnt
; i
++) 
 976         wxHtmlHelpDataItem 
*it 
= &contents
[i
]; 
 980             if (m_hfStyle 
& wxHF_MERGE_BOOKS
) 
 981                 // VS: we don't want book nodes, books' content should 
 982                 //    appear under tree's root. This line will create a "fake" 
 983                 //    record about book node so that the rest of this look 
 984                 //    will believe there really _is_ a book node and will 
 989                 roots
[1] = m_ContentsBox
->AppendItem(roots
[0], 
 990                                          it
->name
, IMG_Book
, -1, 
 991                                          new wxHtmlHelpTreeItemData(i
)); 
 992                 m_ContentsBox
->SetItemBold(roots
[1], true); 
 996         // ...and their contents: 
 999             roots
[it
->level 
+ 1] = m_ContentsBox
->AppendItem( 
1000                                      roots
[it
->level
], it
->name
, IMG_Page
, 
1001                                      -1, new wxHtmlHelpTreeItemData(i
)); 
1002             imaged
[it
->level 
+ 1] = false; 
1005         m_PagesHash
->Put(it
->GetFullPath(), 
1006                          new wxHtmlHelpHashData(i
, roots
[it
->level 
+ 1])); 
1008         // Set the icon for the node one level up in the hierarchy, 
1009         // unless already done (see comment above imaged[] declaration) 
1010         if (!imaged
[it
->level
]) 
1012             int image 
= IMG_Folder
; 
1013             if (m_hfStyle 
& wxHF_ICONS_BOOK
) 
1015             else if (m_hfStyle 
& wxHF_ICONS_BOOK_CHAPTER
) 
1016                 image 
= (it
->level 
== 1) ? IMG_Book 
: IMG_Folder
; 
1017             m_ContentsBox
->SetItemImage(roots
[it
->level
], image
); 
1018             m_ContentsBox
->SetItemImage(roots
[it
->level
], image
, 
1019                                         wxTreeItemIcon_Selected
); 
1020             imaged
[it
->level
] = true; 
1025 void wxHtmlHelpWindow::CreateIndex() 
1030     m_IndexList
->Clear(); 
1032     size_t cnt 
= m_mergedIndex
->size(); 
1035     if (cnt 
> INDEX_IS_SMALL
) 
1036         cnttext
.Printf(_("%i of %i"), 0, cnt
); 
1038         cnttext
.Printf(_("%i of %i"), cnt
, cnt
); 
1039     m_IndexCountInfo
->SetLabel(cnttext
); 
1040     if (cnt 
> INDEX_IS_SMALL
) 
1043     for (size_t i 
= 0; i 
< cnt
; i
++) 
1044         m_IndexList
->Append((*m_mergedIndex
)[i
].name
, 
1045                             (char*)(&(*m_mergedIndex
)[i
])); 
1048 void wxHtmlHelpWindow::CreateSearch() 
1050     if (! (m_SearchList 
&& m_SearchChoice
)) 
1052     m_SearchList
->Clear(); 
1053     m_SearchChoice
->Clear(); 
1054     m_SearchChoice
->Append(_("Search in all books")); 
1055     const wxHtmlBookRecArray
& bookrec 
= m_Data
->GetBookRecArray(); 
1056     int i
, cnt 
= bookrec
.GetCount(); 
1057     for (i 
= 0; i 
< cnt
; i
++) 
1058         m_SearchChoice
->Append(bookrec
[i
].GetTitle()); 
1059     m_SearchChoice
->SetSelection(0); 
1062 void wxHtmlHelpWindow::RefreshLists() 
1064     // Update m_mergedIndex: 
1065     UpdateMergedIndex(); 
1066     // Update the controls 
1072 void wxHtmlHelpWindow::ReadCustomization(wxConfigBase 
*cfg
, const wxString
& path
) 
1077     if (path 
!= wxEmptyString
) 
1079         oldpath 
= cfg
->GetPath(); 
1080         cfg
->SetPath(wxT("/") + path
); 
1083     m_Cfg
.navig_on 
= cfg
->Read(wxT("hcNavigPanel"), m_Cfg
.navig_on
) != 0; 
1084     m_Cfg
.sashpos 
= cfg
->Read(wxT("hcSashPos"), m_Cfg
.sashpos
); 
1085     m_Cfg
.x 
= cfg
->Read(wxT("hcX"), m_Cfg
.x
); 
1086     m_Cfg
.y 
= cfg
->Read(wxT("hcY"), m_Cfg
.y
); 
1087     m_Cfg
.w 
= cfg
->Read(wxT("hcW"), m_Cfg
.w
); 
1088     m_Cfg
.h 
= cfg
->Read(wxT("hcH"), m_Cfg
.h
); 
1090     m_FixedFace 
= cfg
->Read(wxT("hcFixedFace"), m_FixedFace
); 
1091     m_NormalFace 
= cfg
->Read(wxT("hcNormalFace"), m_NormalFace
); 
1092     m_FontSize 
= cfg
->Read(wxT("hcBaseFontSize"), m_FontSize
); 
1099         cnt 
= cfg
->Read(wxT("hcBookmarksCnt"), 0L); 
1102             m_BookmarksNames
.Clear(); 
1103             m_BookmarksPages
.Clear(); 
1106                 m_Bookmarks
->Clear(); 
1107                 m_Bookmarks
->Append(_("(bookmarks)")); 
1110             for (i 
= 0; i 
< cnt
; i
++) 
1112                 val
.Printf(wxT("hcBookmark_%i"), i
); 
1114                 m_BookmarksNames
.Add(s
); 
1115                 if (m_Bookmarks
) m_Bookmarks
->Append(s
); 
1116                 val
.Printf(wxT("hcBookmark_%i_url"), i
); 
1118                 m_BookmarksPages
.Add(s
); 
1124         m_HtmlWin
->ReadCustomization(cfg
); 
1126     if (path 
!= wxEmptyString
) 
1127         cfg
->SetPath(oldpath
); 
1130 void wxHtmlHelpWindow::WriteCustomization(wxConfigBase 
*cfg
, const wxString
& path
) 
1135     if (path 
!= wxEmptyString
) 
1137         oldpath 
= cfg
->GetPath(); 
1138         cfg
->SetPath(wxT("/") + path
); 
1141     cfg
->Write(wxT("hcNavigPanel"), m_Cfg
.navig_on
); 
1142     cfg
->Write(wxT("hcSashPos"), (long)m_Cfg
.sashpos
); 
1144     //  Don't write if iconized as this would make the window 
1145     //  disappear next time it is shown! 
1146     cfg
->Write(wxT("hcX"), (long)m_Cfg
.x
); 
1147     cfg
->Write(wxT("hcY"), (long)m_Cfg
.y
); 
1148     cfg
->Write(wxT("hcW"), (long)m_Cfg
.w
); 
1149     cfg
->Write(wxT("hcH"), (long)m_Cfg
.h
); 
1151     cfg
->Write(wxT("hcFixedFace"), m_FixedFace
); 
1152     cfg
->Write(wxT("hcNormalFace"), m_NormalFace
); 
1153     cfg
->Write(wxT("hcBaseFontSize"), (long)m_FontSize
); 
1158         int cnt 
= m_BookmarksNames
.GetCount(); 
1161         cfg
->Write(wxT("hcBookmarksCnt"), (long)cnt
); 
1162         for (i 
= 0; i 
< cnt
; i
++) 
1164             val
.Printf(wxT("hcBookmark_%i"), i
); 
1165             cfg
->Write(val
, m_BookmarksNames
[i
]); 
1166             val
.Printf(wxT("hcBookmark_%i_url"), i
); 
1167             cfg
->Write(val
, m_BookmarksPages
[i
]); 
1172         m_HtmlWin
->WriteCustomization(cfg
); 
1174     if (path 
!= wxEmptyString
) 
1175         cfg
->SetPath(oldpath
); 
1178 static void SetFontsToHtmlWin(wxHtmlWindow 
*win
, const wxString
& scalf
, const wxString
& fixf
, int size
) 
1181     f_sizes
[0] = int(size 
* 0.6); 
1182     f_sizes
[1] = int(size 
* 0.8); 
1184     f_sizes
[3] = int(size 
* 1.2); 
1185     f_sizes
[4] = int(size 
* 1.4); 
1186     f_sizes
[5] = int(size 
* 1.6); 
1187     f_sizes
[6] = int(size 
* 1.8); 
1189     win
->SetFonts(scalf
, fixf
, f_sizes
); 
1192 class wxHtmlHelpWindowOptionsDialog 
: public wxDialog
 
1195     wxComboBox 
*NormalFont
, *FixedFont
; 
1196     wxSpinCtrl 
*FontSize
; 
1197     wxHtmlWindow 
*TestWin
; 
1199     wxHtmlHelpWindowOptionsDialog(wxWindow 
*parent
) 
1200         : wxDialog(parent
, wxID_ANY
, wxString(_("Help Browser Options"))) 
1202         wxBoxSizer 
*topsizer 
= new wxBoxSizer(wxVERTICAL
); 
1203         wxFlexGridSizer 
*sizer 
= new wxFlexGridSizer(2, 3, 2, 5); 
1205         sizer
->Add(new wxStaticText(this, wxID_ANY
, _("Normal font:"))); 
1206         sizer
->Add(new wxStaticText(this, wxID_ANY
, _("Fixed font:"))); 
1207         sizer
->Add(new wxStaticText(this, wxID_ANY
, _("Font size:"))); 
1209         sizer
->Add(NormalFont 
= new wxComboBox(this, wxID_ANY
, wxEmptyString
, wxDefaultPosition
, 
1210                       wxSize(200, wxDefaultCoord
), 
1211                       0, NULL
, wxCB_DROPDOWN 
| wxCB_READONLY
)); 
1213         sizer
->Add(FixedFont 
= new wxComboBox(this, wxID_ANY
, wxEmptyString
, wxDefaultPosition
, 
1214                       wxSize(200, wxDefaultCoord
), 
1215                       0, NULL
, wxCB_DROPDOWN 
| wxCB_READONLY
)); 
1217         sizer
->Add(FontSize 
= new wxSpinCtrl(this, wxID_ANY
, wxEmptyString
, wxDefaultPosition
, 
1218                       wxDefaultSize
, wxSP_ARROW_KEYS
, 2, 100, 2, wxT("wxSpinCtrl"))); 
1220         topsizer
->Add(sizer
, 0, wxLEFT
|wxRIGHT
|wxTOP
, 10); 
1222         topsizer
->Add(new wxStaticText(this, wxID_ANY
, _("Preview:")), 
1223                         0, wxLEFT 
| wxTOP
, 10); 
1225         topsizer
->AddSpacer(5); 
1227         topsizer
->Add(TestWin 
= new wxHtmlWindow(this, wxID_ANY
, wxDefaultPosition
, wxSize(20, 150), 
1228                                                  wxHW_SCROLLBAR_AUTO
|wxBORDER_THEME
), 
1229                         1, wxEXPAND 
| wxLEFT 
| wxRIGHT
, 10); 
1231         wxBoxSizer 
*sizer2 
= new wxBoxSizer(wxHORIZONTAL
); 
1233         sizer2
->Add(ok 
= new wxButton(this, wxID_OK
), 0, wxALL
, 10); 
1235         sizer2
->Add(new wxButton(this, wxID_CANCEL
), 0, wxALL
, 10); 
1236         topsizer
->Add(sizer2
, 0, wxALIGN_RIGHT
); 
1239         topsizer
->Fit(this); 
1244     void UpdateTestWin() 
1247         SetFontsToHtmlWin(TestWin
, 
1248                           NormalFont
->GetStringSelection(), 
1249                           FixedFont
->GetStringSelection(), 
1250                           FontSize
->GetValue()); 
1252         wxString 
content(_("font size")); 
1254         content 
= wxT("<font size=-2>") + content 
+ wxT(" -2</font><br>") 
1255                   wxT("<font size=-1>") + content 
+ wxT(" -1</font><br>") 
1256                   wxT("<font size=+0>") + content 
+ wxT(" +0</font><br>") 
1257                   wxT("<font size=+1>") + content 
+ wxT(" +1</font><br>") 
1258                   wxT("<font size=+2>") + content 
+ wxT(" +2</font><br>") 
1259                   wxT("<font size=+3>") + content 
+ wxT(" +3</font><br>") 
1260                   wxT("<font size=+4>") + content 
+ wxT(" +4</font><br>") ; 
1262         content 
= wxString( wxT("<html><body><table><tr><td>") ) + 
1263                   _("Normal face<br>and <u>underlined</u>. ") + 
1264                   _("<i>Italic face.</i> ") + 
1265                   _("<b>Bold face.</b> ") + 
1266                   _("<b><i>Bold italic face.</i></b><br>") + 
1268                   wxString( wxT("</td><td><tt>") ) + 
1269                   _("Fixed size face.<br> <b>bold</b> <i>italic</i> ") + 
1270                   _("<b><i>bold italic <u>underlined</u></i></b><br>") + 
1272                   wxT("</tt></td></tr></table></body></html>"); 
1274         TestWin
->SetPage( content 
); 
1277     void OnUpdate(wxCommandEvent
& WXUNUSED(event
)) 
1281     void OnUpdateSpin(wxSpinEvent
& WXUNUSED(event
)) 
1286     DECLARE_EVENT_TABLE() 
1287     wxDECLARE_NO_COPY_CLASS(wxHtmlHelpWindowOptionsDialog
); 
1290 BEGIN_EVENT_TABLE(wxHtmlHelpWindowOptionsDialog
, wxDialog
) 
1291     EVT_COMBOBOX(wxID_ANY
, wxHtmlHelpWindowOptionsDialog::OnUpdate
) 
1292     EVT_SPINCTRL(wxID_ANY
, wxHtmlHelpWindowOptionsDialog::OnUpdateSpin
) 
1295 void wxHtmlHelpWindow::OptionsDialog() 
1297     wxHtmlHelpWindowOptionsDialog 
dlg(this); 
1300     if (m_NormalFonts 
== NULL
) 
1302         m_NormalFonts 
= new wxArrayString(wxFontEnumerator::GetFacenames()); 
1303         m_NormalFonts
->Sort(); // ascending sort 
1305     if (m_FixedFonts 
== NULL
) 
1307         m_FixedFonts 
= new wxArrayString( 
1308                     wxFontEnumerator::GetFacenames(wxFONTENCODING_SYSTEM
, 
1309                     true /*enum fixed width only*/)); 
1310         m_FixedFonts
->Sort(); // ascending sort 
1313     // VS: We want to show the font that is actually used by wxHtmlWindow. 
1314     //     If customization dialog wasn't used yet, facenames are empty and 
1315     //     wxHtmlWindow uses default fonts -- let's find out what they 
1316     //     are so that we can pass them to the dialog: 
1317     if (m_NormalFace
.empty()) 
1319         wxFont 
fnt(m_FontSize
, wxSWISS
, wxNORMAL
, wxNORMAL
, false); 
1320         m_NormalFace 
= fnt
.GetFaceName(); 
1322     if (m_FixedFace
.empty()) 
1324         wxFont 
fnt(m_FontSize
, wxMODERN
, wxNORMAL
, wxNORMAL
, false); 
1325         m_FixedFace 
= fnt
.GetFaceName(); 
1328     for (i 
= 0; i 
< m_NormalFonts
->GetCount(); i
++) 
1329         dlg
.NormalFont
->Append((*m_NormalFonts
)[i
]); 
1330     for (i 
= 0; i 
< m_FixedFonts
->GetCount(); i
++) 
1331         dlg
.FixedFont
->Append((*m_FixedFonts
)[i
]); 
1332     if (!m_NormalFace
.empty()) 
1333         dlg
.NormalFont
->SetStringSelection(m_NormalFace
); 
1335         dlg
.NormalFont
->SetSelection(0); 
1336     if (!m_FixedFace
.empty()) 
1337         dlg
.FixedFont
->SetStringSelection(m_FixedFace
); 
1339         dlg
.FixedFont
->SetSelection(0); 
1340     dlg
.FontSize
->SetValue(m_FontSize
); 
1341     dlg
.UpdateTestWin(); 
1343     if (dlg
.ShowModal() == wxID_OK
) 
1345         m_NormalFace 
= dlg
.NormalFont
->GetStringSelection(); 
1346         m_FixedFace 
= dlg
.FixedFont
->GetStringSelection(); 
1347         m_FontSize 
= dlg
.FontSize
->GetValue(); 
1348         SetFontsToHtmlWin(m_HtmlWin
, m_NormalFace
, m_FixedFace
, m_FontSize
); 
1352 void wxHtmlHelpWindow::NotifyPageChanged() 
1354     if (m_UpdateContents 
&& m_PagesHash
) 
1356         wxString page 
= wxHtmlHelpHtmlWindow::GetOpenedPageWithAnchor(m_HtmlWin
); 
1357         wxHtmlHelpHashData 
*ha 
= NULL
; 
1359             ha 
= (wxHtmlHelpHashData
*) m_PagesHash
->Get(page
); 
1363             bool olduc 
= m_UpdateContents
; 
1364             m_UpdateContents 
= false; 
1365             m_ContentsBox
->SelectItem(ha
->m_Id
); 
1366             m_ContentsBox
->EnsureVisible(ha
->m_Id
); 
1367             m_UpdateContents 
= olduc
; 
1377 void wxHtmlHelpWindow::OnToolbar(wxCommandEvent
& event
) 
1379     switch (event
.GetId()) 
1381         case wxID_HTML_BACK 
: 
1382             m_HtmlWin
->HistoryBack(); 
1383             NotifyPageChanged(); 
1386         case wxID_HTML_FORWARD 
: 
1387             m_HtmlWin
->HistoryForward(); 
1388             NotifyPageChanged(); 
1394                 wxString page 
= wxHtmlHelpHtmlWindow::GetOpenedPageWithAnchor(m_HtmlWin
); 
1395                 wxHtmlHelpHashData 
*ha 
= NULL
; 
1397                     ha 
= (wxHtmlHelpHashData
*) m_PagesHash
->Get(page
); 
1398                 if (ha 
&& ha
->m_Index 
> 0) 
1400                     const wxHtmlHelpDataItem
& it 
= m_Data
->GetContentsArray()[ha
->m_Index 
- 1]; 
1401                     if (!it
.page
.empty()) 
1403                         m_HtmlWin
->LoadPage(it
.GetFullPath()); 
1404                         NotifyPageChanged(); 
1410         case wxID_HTML_UPNODE 
: 
1413                 wxString page 
= wxHtmlHelpHtmlWindow::GetOpenedPageWithAnchor(m_HtmlWin
); 
1414                 wxHtmlHelpHashData 
*ha 
= NULL
; 
1416                     ha 
= (wxHtmlHelpHashData
*) m_PagesHash
->Get(page
); 
1417                 if (ha 
&& ha
->m_Index 
> 0) 
1420                         m_Data
->GetContentsArray()[ha
->m_Index
].level 
- 1; 
1421                     int ind 
= ha
->m_Index 
- 1; 
1423                     const wxHtmlHelpDataItem 
*it 
= 
1424                         &m_Data
->GetContentsArray()[ind
]; 
1425                     while (ind 
>= 0 && it
->level 
!= level
) 
1428                         it 
= &m_Data
->GetContentsArray()[ind
]; 
1432                         if (!it
->page
.empty()) 
1434                             m_HtmlWin
->LoadPage(it
->GetFullPath()); 
1435                             NotifyPageChanged(); 
1442         case wxID_HTML_DOWN 
: 
1445                 wxString page 
= wxHtmlHelpHtmlWindow::GetOpenedPageWithAnchor(m_HtmlWin
); 
1446                 wxHtmlHelpHashData 
*ha 
= NULL
; 
1448                     ha 
= (wxHtmlHelpHashData
*) m_PagesHash
->Get(page
); 
1450                 const wxHtmlHelpDataItems
& contents 
= m_Data
->GetContentsArray(); 
1451                 if (ha 
&& ha
->m_Index 
< (int)contents
.size() - 1) 
1453                     size_t idx 
= ha
->m_Index 
+ 1; 
1455                     while (contents
[idx
].GetFullPath() == page
) idx
++; 
1457                     if (!contents
[idx
].page
.empty()) 
1459                         m_HtmlWin
->LoadPage(contents
[idx
].GetFullPath()); 
1460                         NotifyPageChanged(); 
1466         case wxID_HTML_PANEL 
: 
1468                 if (! (m_Splitter 
&& m_NavigPan
)) 
1470                 if (m_Splitter
->IsSplit()) 
1472                     m_Cfg
.sashpos 
= m_Splitter
->GetSashPosition(); 
1473                     m_Splitter
->Unsplit(m_NavigPan
); 
1474                     m_Cfg
.navig_on 
= false; 
1480                     m_Splitter
->SplitVertically(m_NavigPan
, m_HtmlWin
, m_Cfg
.sashpos
); 
1481                     m_Cfg
.navig_on 
= true; 
1486         case wxID_HTML_OPTIONS 
: 
1490         case wxID_HTML_BOOKMARKSADD 
: 
1495                 item 
= m_HtmlWin
->GetOpenedPageTitle(); 
1496                 url 
= m_HtmlWin
->GetOpenedPage(); 
1497                 if (item 
== wxEmptyString
) 
1498                     item 
= url
.AfterLast(wxT('/')); 
1499                 if (m_BookmarksPages
.Index(url
) == wxNOT_FOUND
) 
1501                     m_Bookmarks
->Append(item
); 
1502                     m_BookmarksNames
.Add(item
); 
1503                     m_BookmarksPages
.Add(url
); 
1508         case wxID_HTML_BOOKMARKSREMOVE 
: 
1513                 item 
= m_Bookmarks
->GetStringSelection(); 
1514                 pos 
= m_BookmarksNames
.Index(item
); 
1515                 if (pos 
!= wxNOT_FOUND
) 
1517                     m_BookmarksNames
.RemoveAt(pos
); 
1518                     m_BookmarksPages
.RemoveAt(pos
); 
1519                     pos 
= m_Bookmarks
->GetSelection(); 
1520                     wxASSERT_MSG( pos 
!= wxNOT_FOUND 
, wxT("Unknown bookmark position") ) ; 
1521                     m_Bookmarks
->Delete((unsigned int)pos
); 
1526 #if wxUSE_PRINTING_ARCHITECTURE 
1527         case wxID_HTML_PRINT 
: 
1529                 if (m_Printer 
== NULL
) 
1530                     m_Printer 
= new wxHtmlEasyPrinting(_("Help Printing"), this); 
1531                 if (!m_HtmlWin
->GetOpenedPage()) 
1533                     wxLogWarning(_("Cannot print empty page.")); 
1537                     m_Printer
->PrintFile(m_HtmlWin
->GetOpenedPage()); 
1543         case wxID_HTML_OPENFILE 
: 
1545                 wxString filemask 
= wxString( 
1546                     _("HTML files (*.html;*.htm)|*.html;*.htm|")) + 
1547                     _("Help books (*.htb)|*.htb|Help books (*.zip)|*.zip|") + 
1548                     _("HTML Help Project (*.hhp)|*.hhp|") + 
1550                     _("Compressed HTML Help file (*.chm)|*.chm|") + 
1552                     _("All files (*.*)|*"); 
1553                 wxString s 
= wxFileSelector(_("Open HTML document"), 
1558                                             wxFD_OPEN 
| wxFD_FILE_MUST_EXIST
, 
1562                     wxString ext 
= s
.Right(4).Lower(); 
1563                     if (ext 
== wxT(".zip") || ext 
== wxT(".htb") || 
1565                         ext 
== wxT(".chm") || 
1574                         m_HtmlWin
->LoadPage(s
); 
1581 void wxHtmlHelpWindow::OnContentsSel(wxTreeEvent
& event
) 
1583     wxHtmlHelpTreeItemData 
*pg
; 
1585     pg 
= (wxHtmlHelpTreeItemData
*) m_ContentsBox
->GetItemData(event
.GetItem()); 
1587     if (pg 
&& m_UpdateContents
) 
1589         const wxHtmlHelpDataItems
& contents 
= m_Data
->GetContentsArray(); 
1590         m_UpdateContents 
= false; 
1591         if (!contents
[pg
->m_Id
].page
.empty()) 
1592             m_HtmlWin
->LoadPage(contents
[pg
->m_Id
].GetFullPath()); 
1593         m_UpdateContents 
= true; 
1597 void wxHtmlHelpWindow::OnIndexSel(wxCommandEvent
& WXUNUSED(event
)) 
1599     wxHtmlHelpMergedIndexItem 
*it 
= (wxHtmlHelpMergedIndexItem
*) 
1600         m_IndexList
->GetClientData(m_IndexList
->GetSelection()); 
1602         DisplayIndexItem(it
); 
1605 void wxHtmlHelpWindow::OnIndexFind(wxCommandEvent
& WXUNUSED(event
)) 
1610 void wxHtmlHelpWindow::DoIndexFind() 
1612     wxString sr 
= m_IndexText
->GetLineText(0); 
1614     if (sr 
== wxEmptyString
) 
1622         m_IndexList
->Clear(); 
1623         const wxHtmlHelpMergedIndex
& index 
= *m_mergedIndex
; 
1624         size_t cnt 
= index
.size(); 
1627         for (size_t i 
= 0; i 
< cnt
; i
++) 
1629             if (index
[i
].name
.Lower().find(sr
) != wxString::npos
) 
1631                 int pos 
= m_IndexList
->Append(index
[i
].name
, 
1632                                               (char*)(&index
[i
])); 
1636                     // don't automatically show topic selector if this 
1637                     // item points to multiple pages: 
1638                     if (index
[i
].items
.size() == 1) 
1640                         m_IndexList
->SetSelection(0); 
1641                         DisplayIndexItem(&index
[i
]); 
1645                 // if this is nested item of the index, show its parent(s) 
1646                 // as well, otherwise it would not be clear what entry is 
1648                 wxHtmlHelpMergedIndexItem 
*parent 
= index
[i
].parent
; 
1652                         (index
.Index(*(wxHtmlHelpMergedIndexItem
*)m_IndexList
->GetClientData(pos
-1))) < index
.Index(*parent
)) 
1654                         m_IndexList
->Insert(parent
->name
, 
1655                                             pos
, (char*)parent
); 
1656                         parent 
= parent
->parent
; 
1661                 // finally, it the item we just added is itself a parent for 
1662                 // other items, show them as well, because they are refinements 
1663                 // of the displayed index entry (i.e. it is implicitly contained 
1664                 // in them: "foo" with parent "bar" reads as "bar, foo"): 
1665                 int level 
= index
[i
].items
[0]->level
; 
1667                 while (i 
< cnt 
&& index
[i
].items
[0]->level 
> level
) 
1669                     m_IndexList
->Append(index
[i
].name
, (char*)(&index
[i
])); 
1677         cnttext
.Printf(_("%i of %i"), displ
, cnt
); 
1678         m_IndexCountInfo
->SetLabel(cnttext
); 
1680         m_IndexText
->SetSelection(0, sr
.length()); 
1681         m_IndexText
->SetFocus(); 
1685 void wxHtmlHelpWindow::OnIndexAll(wxCommandEvent
& WXUNUSED(event
)) 
1690 void wxHtmlHelpWindow::DoIndexAll() 
1694     m_IndexList
->Clear(); 
1695     const wxHtmlHelpMergedIndex
& index 
= *m_mergedIndex
; 
1696     size_t cnt 
= index
.size(); 
1699     for (size_t i 
= 0; i 
< cnt
; i
++) 
1701         m_IndexList
->Append(index
[i
].name
, (char*)(&index
[i
])); 
1704             // don't automatically show topic selector if this 
1705             // item points to multiple pages: 
1706             if (index
[i
].items
.size() == 1) 
1708                 DisplayIndexItem(&index
[i
]); 
1715     cnttext
.Printf(_("%i of %i"), cnt
, cnt
); 
1716     m_IndexCountInfo
->SetLabel(cnttext
); 
1719 void wxHtmlHelpWindow::OnSearchSel(wxCommandEvent
& WXUNUSED(event
)) 
1721     wxHtmlHelpDataItem 
*it 
= (wxHtmlHelpDataItem
*) m_SearchList
->GetClientData(m_SearchList
->GetSelection()); 
1724         if (!it
->page
.empty()) 
1725             m_HtmlWin
->LoadPage(it
->GetFullPath()); 
1726         NotifyPageChanged(); 
1730 void wxHtmlHelpWindow::OnSearch(wxCommandEvent
& WXUNUSED(event
)) 
1732     wxString sr 
= m_SearchText
->GetLineText(0); 
1735         KeywordSearch(sr
, wxHELP_SEARCH_ALL
); 
1738 void wxHtmlHelpWindow::OnBookmarksSel(wxCommandEvent
& WXUNUSED(event
)) 
1740     wxString str 
= m_Bookmarks
->GetStringSelection(); 
1741     int idx 
= m_BookmarksNames
.Index(str
); 
1742     if (!str
.empty() && str 
!= _("(bookmarks)") && idx 
!= wxNOT_FOUND
) 
1744        m_HtmlWin
->LoadPage(m_BookmarksPages
[(size_t)idx
]); 
1745        NotifyPageChanged(); 
1749 void wxHtmlHelpWindow::OnSize(wxSizeEvent
& WXUNUSED(event
)) 
1754 #endif // wxUSE_WXHTML_HELP