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 ///////////////////////////////////////////////////////////////////////////// 
  13 #pragma implementation 
  16 // For compilers that support precompilation, includes "wx.h" 
  18 #include "wx/wxprec.h" 
  31 #include "wx/html/helpfrm.h" 
  32 #include "wx/notebook.h" 
  33 #include "wx/imaglist.h" 
  34 #include "wx/treectrl.h" 
  35 #include "wx/tokenzr.h" 
  36 #include "wx/wfstream.h" 
  37 #include "wx/html/htmlwin.h" 
  38 #include "wx/busyinfo.h" 
  39 #include "wx/progdlg.h" 
  40 #include "wx/toolbar.h" 
  41 #include "wx/fontenum.h" 
  46 #include "bitmaps/wpanel.xpm" 
  47 #include "bitmaps/wback.xpm" 
  48 #include "bitmaps/wforward.xpm" 
  49 #include "bitmaps/wbook.xpm" 
  50 #include "bitmaps/woptions.xpm" 
  51 #include "bitmaps/wfolder.xpm" 
  52 #include "bitmaps/wpage.xpm" 
  53 #include "bitmaps/whelp.xpm" 
  54 #include "bitmaps/whlproot.xpm" 
  55 #include "bitmaps/wbkadd.xpm" 
  56 #include "bitmaps/wbkdel.xpm" 
  59 #include "wx/stream.h" 
  61 // number of times that the contents/index creation progress dialog 
  63 #define PROGRESS_STEP 40 
  65 // what is considered "small index"? 
  66 #define INDEX_IS_SMALL 100 
  69 //-------------------------------------------------------------------------- 
  70 // wxHtmlHelpTreeItemData (private) 
  71 //-------------------------------------------------------------------------- 
  73 class wxHtmlHelpTreeItemData 
: public wxTreeItemData
 
  79         wxHtmlHelpTreeItemData(wxHtmlContentsItem 
*it
) : wxTreeItemData() 
  81                 m_Page 
= it 
-> m_Book 
-> GetBasePath() + it 
-> m_Page
; 
  83         const wxString
& GetPage() { return m_Page
; } 
  89 //--------------------------------------------------------------------------- 
  91 //--------------------------------------------------------------------------- 
  93 IMPLEMENT_DYNAMIC_CLASS(wxHtmlHelpFrame
, wxFrame
) 
  95 wxHtmlHelpFrame::wxHtmlHelpFrame(wxWindow
* parent
, wxWindowID id
, const wxString
& title
, 
  96                                  int style
, wxHtmlHelpData
* data
) 
  99     Create(parent
, id
, title
, style
); 
 102 void wxHtmlHelpFrame::Init(wxHtmlHelpData
* data
) 
 106         m_DataCreated 
= FALSE
; 
 108         m_Data 
= new wxHtmlHelpData(); 
 109         m_DataCreated 
= TRUE
; 
 112     m_ContentsImageList 
= new wxImageList(16, 16); 
 113     m_ContentsImageList 
-> Add(wxICON(wbook
)); 
 114     m_ContentsImageList 
-> Add(wxICON(wfolder
)); 
 115     m_ContentsImageList 
-> Add(wxICON(wpage
)); 
 116     m_ContentsImageList 
-> Add(wxICON(whlproot
)); 
 118     m_ContentsBox 
= NULL
; 
 120     m_IndexButton 
= NULL
; 
 121     m_IndexButtonAll 
= NULL
; 
 124     m_SearchButton 
= NULL
; 
 126     m_SearchChoice 
= NULL
; 
 127     m_IndexCountInfo 
= NULL
; 
 133     m_ConfigRoot 
= wxEmptyString
; 
 135     m_Cfg
.x 
= m_Cfg
.y 
= 0; 
 139     m_Cfg
.navig_on 
= TRUE
; 
 141     m_NormalFonts 
= m_FixedFonts 
= NULL
; 
 143     m_NormalFace 
= m_FixedFace 
= wxEmptyString
; 
 146 // Create: builds the GUI components. 
 147 // with the style flag it's possible to toggle the toolbar, contents, index and search 
 149 // m_HtmlWin will *always* be created, but it's important to realize that 
 150 // m_ContentsBox, m_IndexList, m_SearchList, m_SearchButton, m_SearchText and 
 151 // m_SearchButton may be NULL. 
 152 // moreover, if no contents, index or searchpage is needed, m_Splitter and 
 153 // m_NavigPan will be NULL too (with m_HtmlWin directly connected to the frame) 
 155 bool wxHtmlHelpFrame::Create(wxWindow
* parent
, wxWindowID id
, const wxString
& title
, 
 158     // Do the config in two steps. We read the HtmlWindow customization after we 
 159     // create the window. 
 161         ReadCustomization(m_Config
, m_ConfigRoot
); 
 163     wxFrame::Create(parent
, id
, _("Help"), wxPoint(m_Cfg
.x
, m_Cfg
.y
), wxSize(m_Cfg
.w
, m_Cfg
.h
), wxDEFAULT_FRAME_STYLE
, "wxHtmlHelp"); 
 165     GetPosition(&m_Cfg
.x
, &m_Cfg
.y
); 
 167     SetIcon(wxICON(whelp
)); 
 169     int notebook_page 
= 0; 
 174     if (style 
& wxHF_TOOLBAR
) { 
 175         wxToolBar 
*toolBar 
= CreateToolBar(wxNO_BORDER 
| wxTB_HORIZONTAL 
| wxTB_DOCKABLE
); 
 176         toolBar
->SetMargins( 2, 2 ); 
 178         toolBar 
-> AddTool(wxID_HTML_PANEL
, wxBITMAP(wpanel
), wxNullBitmap
, 
 179                            FALSE
, -1, -1, (wxObject 
*) NULL
, 
 180                            _("Show/hide navigation panel")); 
 181         toolBar 
-> AddSeparator(); 
 182         toolBar 
-> AddTool(wxID_HTML_BACK
, wxBITMAP(wback
), wxNullBitmap
, 
 183                            FALSE
, -1, -1, (wxObject 
*) NULL
, 
 184                            _("Go back to the previous HTML page")); 
 185         toolBar 
-> AddTool(wxID_HTML_FORWARD
, wxBITMAP(wforward
), wxNullBitmap
, 
 186                            FALSE
, -1, -1, (wxObject 
*) NULL
, 
 187                            _("Go forward to the next HTML page")); 
 188         toolBar 
-> AddSeparator(); 
 190         if (style 
& wxHF_BOOKMARKS
) { 
 191             m_Bookmarks 
= new wxComboBox(toolBar
, wxID_HTML_BOOKMARKSLIST
, wxEmptyString
,  
 192                                          wxDefaultPosition
, wxSize(300,-1), 0, NULL
, wxCB_READONLY 
| wxCB_SORT
); 
 193             m_Bookmarks 
-> Append(_("<bookmarks>")); 
 194             for (unsigned i 
= 0; i 
< m_BookmarksNames
.GetCount(); i
++) 
 195                 m_Bookmarks 
-> Append(m_BookmarksNames
[i
]); 
 196             m_Bookmarks 
-> SetSelection(0); 
 197             toolBar 
-> AddControl(m_Bookmarks
); 
 199             toolBar 
-> AddSeparator(); 
 201             toolBar 
-> AddTool(wxID_HTML_BOOKMARKSADD
, wxBITMAP(wbkadd
), wxNullBitmap
, 
 202                                FALSE
, -1, -1, (wxObject 
*) NULL
, 
 203                                _("Add current page to bookmarks")); 
 204             toolBar 
-> AddTool(wxID_HTML_BOOKMARKSREMOVE
, wxBITMAP(wbkdel
), wxNullBitmap
, 
 205                                FALSE
, -1, -1, (wxObject 
*) NULL
, 
 206                                _("Remove current page from bookmarks")); 
 209         toolBar 
-> AddSeparator(); 
 210         toolBar 
-> AddTool(wxID_HTML_OPTIONS
, wxBITMAP(woptions
), wxNullBitmap
, 
 211                            FALSE
, -1, -1, (wxObject 
*) NULL
, 
 212                            _("Display options dialog")); 
 214         toolBar 
-> Realize(); 
 217     if (style 
& (wxHF_CONTENTS 
| wxHF_INDEX 
| wxHF_SEARCH
)) { 
 218         // traditional help controller; splitter window with html page on the 
 219         // right and a notebook containing various pages on the left 
 220         m_Splitter 
= new wxSplitterWindow(this); 
 222         m_HtmlWin 
= new wxHtmlWindow(m_Splitter
); 
 223         m_NavigPan 
= new wxNotebook(m_Splitter
, wxID_HTML_NOTEBOOK
, 
 224                                     wxDefaultPosition
, wxDefaultSize
); 
 225     } else { // only html window, no notebook with index,contents etc 
 226         m_HtmlWin 
= new wxHtmlWindow(this); 
 229     m_HtmlWin 
-> SetRelatedFrame(this, m_TitleFormat
); 
 230     m_HtmlWin 
-> SetRelatedStatusBar(0); 
 232         m_HtmlWin 
-> ReadCustomization(m_Config
, m_ConfigRoot
); 
 234     // contents tree panel? 
 235     if (style 
& wxHF_CONTENTS
) { 
 236         m_ContentsBox 
= new wxTreeCtrl(m_NavigPan
, wxID_HTML_TREECTRL
, 
 237                                        wxDefaultPosition
, wxDefaultSize
, 
 238                                        wxTR_HAS_BUTTONS 
| wxSUNKEN_BORDER
); 
 239         m_ContentsBox 
-> SetImageList(m_ContentsImageList
); 
 240         m_NavigPan 
-> AddPage(m_ContentsBox
, _("Contents")); 
 241         m_ContentsPage 
= notebook_page
++; 
 244     // index listbox panel? 
 245     if (style 
& wxHF_INDEX
) { 
 246         wxWindow 
*dummy 
= new wxPanel(m_NavigPan
, wxID_HTML_INDEXPAGE
); 
 248         wxLayoutConstraints 
*b1 
= new wxLayoutConstraints
; 
 249         m_IndexText 
= new wxTextCtrl(dummy
, wxID_HTML_INDEXTEXT
, wxEmptyString
, wxDefaultPosition
, wxDefaultSize
, wxTE_PROCESS_ENTER
); 
 250         b1 
-> top
.SameAs (dummy
, wxTop
, 10); 
 251         b1 
-> left
.SameAs (dummy
, wxLeft
, 10); 
 252         b1 
-> right
.SameAs (dummy
, wxRight
, 10); 
 254         m_IndexText 
-> SetConstraints(b1
); 
 256         wxLayoutConstraints 
*b4 
= new wxLayoutConstraints
; 
 257         m_IndexButtonAll 
= new wxButton(dummy
, wxID_HTML_INDEXBUTTONALL
, _("Show all")); 
 259         b4 
-> top
.Below (m_IndexText
, 10); 
 260         b4 
-> right
.SameAs (dummy
, wxRight
, 10); 
 263         m_IndexButtonAll 
-> SetConstraints(b4
); 
 265         wxLayoutConstraints 
*b2 
= new wxLayoutConstraints
; 
 266         m_IndexButton 
= new wxButton(dummy
, wxID_HTML_INDEXBUTTON
, _("Find")); 
 267         b2 
-> top
.Below (m_IndexText
, 10); 
 268         b2 
-> right
.LeftOf (m_IndexButtonAll
, 10); 
 271         m_IndexButton 
-> SetConstraints(b2
); 
 273         wxLayoutConstraints 
*b5 
= new wxLayoutConstraints
; 
 274         m_IndexCountInfo 
= new wxStaticText(dummy
, wxID_HTML_COUNTINFO
, wxEmptyString
, wxDefaultPosition
, wxDefaultSize
, wxALIGN_RIGHT 
| wxST_NO_AUTORESIZE
); 
 276         b5 
-> top
.Below (m_IndexButton
, 5); 
 277         b5 
-> right
.SameAs (dummy
, wxRight
, 10); 
 278         b5 
-> left
.SameAs (dummy
, wxLeft
, 10); 
 280         m_IndexCountInfo 
-> SetConstraints(b5
); 
 282         wxLayoutConstraints 
*b3 
= new wxLayoutConstraints
; 
 283         m_IndexList 
= new wxListBox(dummy
, wxID_HTML_INDEXLIST
, wxDefaultPosition
, wxDefaultSize
, 0, NULL
, wxLB_SINGLE 
| wxLB_ALWAYS_SB
); 
 284         b3 
-> top
.Below (m_IndexCountInfo
, 5); 
 285         b3 
-> left
.SameAs (dummy
, wxLeft
, 0); 
 286         b3 
-> right
.SameAs (dummy
, wxRight
, 0); 
 287         b3 
-> bottom
.SameAs (dummy
, wxBottom
, 0); 
 288         m_IndexList 
-> SetConstraints(b3
); 
 291         m_IndexButtonAll 
-> SetToolTip(_("Show all items in index")); 
 292         m_IndexButton 
-> SetToolTip(_("Display all index items that contain given substring. Search is case insensitive.")); 
 293 #endif //wxUSE_TOOLTIPS 
 295         dummy 
-> SetAutoLayout(TRUE
); 
 298         m_NavigPan 
-> AddPage(dummy
, _("Index")); 
 299         m_IndexPage 
= notebook_page
++; 
 302     // search list panel? 
 303     if (style 
& wxHF_SEARCH
) { 
 304         wxWindow 
*dummy 
= new wxPanel(m_NavigPan
, wxID_HTML_SEARCHPAGE
); 
 306         wxLayoutConstraints 
*b1 
= new wxLayoutConstraints
; 
 307         m_SearchText 
= new wxTextCtrl(dummy
, wxID_HTML_SEARCHTEXT
, wxEmptyString
, wxDefaultPosition
, wxDefaultSize
, wxTE_PROCESS_ENTER
); 
 308         b1 
-> top
.SameAs (dummy
, wxTop
, 10); 
 309         b1 
-> left
.SameAs (dummy
, wxLeft
, 10); 
 310         b1 
-> right
.SameAs (dummy
, wxRight
, 10); 
 312         m_SearchText 
-> SetConstraints(b1
); 
 314         wxLayoutConstraints 
*b2 
= new wxLayoutConstraints
; 
 315         m_SearchButton 
= new wxButton(dummy
, wxID_HTML_SEARCHBUTTON
, _("Search")); 
 317         m_SearchButton 
-> SetToolTip(_("Search contents of help book(s) for all occurences of the text you typed above")); 
 318 #endif //wxUSE_TOOLTIPS 
 319         b2 
-> top
.Below (m_SearchText
, 10); 
 320         b2 
-> left
.SameAs (dummy
, wxLeft
, 10); 
 323         m_SearchButton 
-> SetConstraints(b2
); 
 325         wxLayoutConstraints 
*b4 
= new wxLayoutConstraints
; 
 326         m_SearchChoice 
= new wxChoice(dummy
, wxID_HTML_SEARCHCHOICE
, wxDefaultPosition
, 
 328         b4 
-> top
.Below (m_SearchText
, 10); 
 329         b4 
-> left
.SameAs (m_SearchButton
, wxRight
, 10); 
 330         b4 
-> right
.SameAs (dummy
, wxRight
, 10); 
 332         m_SearchChoice 
-> SetConstraints(b4
); 
 334         wxLayoutConstraints 
*b3 
= new wxLayoutConstraints
; 
 335         m_SearchList 
= new wxListBox(dummy
, wxID_HTML_SEARCHLIST
, wxDefaultPosition
, wxDefaultSize
, 0, NULL
, wxLB_SINGLE 
| wxLB_ALWAYS_SB
); 
 336         b3 
-> top
.Below (m_SearchButton
, 10); 
 337         b3 
-> left
.SameAs (dummy
, wxLeft
, 0); 
 338         b3 
-> right
.SameAs (dummy
, wxRight
, 0); 
 339         b3 
-> bottom
.SameAs (dummy
, wxBottom
, 0); 
 340         m_SearchList 
-> SetConstraints(b3
); 
 342         dummy 
-> SetAutoLayout(TRUE
); 
 344         m_NavigPan 
-> AddPage(dummy
, _("Search")); 
 345         m_SearchPage 
= notebook_page
++; 
 347     m_HtmlWin 
-> Show(TRUE
); 
 352     if (m_NavigPan 
&& m_Splitter
) { 
 353         m_Splitter 
-> SetMinimumPaneSize(20); 
 355             m_Splitter 
-> SplitVertically(m_NavigPan
, m_HtmlWin
, m_Cfg
.sashpos
); 
 357             m_Splitter 
-> SplitVertically(m_NavigPan
, m_HtmlWin
, m_Cfg
.sashpos
); 
 358             m_Splitter 
-> Unsplit(); 
 360         if (m_Cfg
.navig_on
) { 
 361             m_NavigPan 
-> Show(TRUE
); 
 362             m_Splitter 
-> SplitVertically(m_NavigPan
, m_HtmlWin
, m_Cfg
.sashpos
); 
 365             m_NavigPan 
-> Show(FALSE
); 
 366             m_Splitter 
-> Initialize(m_HtmlWin
); 
 372 wxHtmlHelpFrame::~wxHtmlHelpFrame() 
 374     delete m_ContentsImageList
; 
 377     if (m_NormalFonts
) delete m_NormalFonts
; 
 378     if (m_FixedFonts
) delete m_FixedFonts
; 
 381 bool wxHtmlHelpFrame::Display(const wxString
& x
) 
 383     wxString url 
= m_Data
->FindPageByName(x
); 
 384     if (! url
.IsEmpty()) { 
 385         m_HtmlWin
->LoadPage(url
); 
 391 bool wxHtmlHelpFrame::Display(const int id
) 
 393     wxString url 
= m_Data
->FindPageById(id
); 
 394     if (! url
.IsEmpty()) { 
 395         m_HtmlWin
->LoadPage(url
); 
 403 bool wxHtmlHelpFrame::DisplayContents() 
 407     if (!m_Splitter 
-> IsSplit()) { 
 408         m_NavigPan 
-> Show(TRUE
); 
 409         m_HtmlWin 
-> Show(TRUE
); 
 410         m_Splitter 
-> SplitVertically(m_NavigPan
, m_HtmlWin
, m_Cfg
.sashpos
); 
 411         m_Cfg
.navig_on 
= TRUE
; 
 413     m_NavigPan 
-> SetSelection(0); 
 419 bool wxHtmlHelpFrame::DisplayIndex() 
 423     if (!m_Splitter 
-> IsSplit()) { 
 424         m_NavigPan 
-> Show(TRUE
); 
 425         m_HtmlWin 
-> Show(TRUE
); 
 426         m_Splitter 
-> SplitVertically(m_NavigPan
, m_HtmlWin
, m_Cfg
.sashpos
); 
 428     m_NavigPan 
-> SetSelection(1); 
 432 bool wxHtmlHelpFrame::KeywordSearch(const wxString
& keyword
) 
 434     if (! (m_SearchList 
&& m_SearchButton 
&& m_SearchText 
&& m_SearchChoice
)) 
 439     wxString book 
= wxEmptyString
; 
 441     if (!m_Splitter 
-> IsSplit()) { 
 442         m_NavigPan 
-> Show(TRUE
); 
 443         m_HtmlWin 
-> Show(TRUE
); 
 444         m_Splitter 
-> SplitVertically(m_NavigPan
, m_HtmlWin
, m_Cfg
.sashpos
); 
 446     m_NavigPan 
-> SetSelection(m_SearchPage
); 
 447     m_SearchList 
-> Clear(); 
 448     m_SearchText 
-> SetValue(keyword
); 
 449     m_SearchButton 
-> Enable(FALSE
); 
 451     if (m_SearchChoice
->GetSelection() != 0) 
 452         book 
= m_SearchChoice
->GetStringSelection(); 
 454     wxHtmlSearchStatus 
status(m_Data
, keyword
, book
); 
 456     wxProgressDialog 
progress(_("Searching..."), _("No matching page found yet"), 
 457                               status
.GetMaxIndex(), this, 
 458                               wxPD_APP_MODAL 
| wxPD_CAN_ABORT 
| wxPD_AUTO_HIDE
); 
 460     while (status
.IsActive()) { 
 461         if (progress
.Update(status
.GetCurIndex()) == FALSE
) 
 463         if (status
.Search()) { 
 464             foundstr
.Printf(_("Found %i matches"), ++foundcnt
); 
 465             progress
.Update(status
.GetCurIndex(), foundstr
); 
 466             m_SearchList 
-> Append(status
.GetName(), status
.GetContentsItem()); 
 471     m_SearchButton 
-> Enable(TRUE
); 
 472     m_SearchText 
-> SetSelection(0, keyword
.Length()); 
 473     m_SearchText 
-> SetFocus(); 
 475         wxHtmlContentsItem 
*it 
= (wxHtmlContentsItem
*) m_SearchList 
-> GetClientData(0); 
 476         if (it
) m_HtmlWin 
-> LoadPage(it 
-> m_Book 
-> GetBasePath() + it 
-> m_Page
); 
 478     return (foundcnt 
> 0); 
 483 void wxHtmlHelpFrame::CreateContents(bool show_progress
) 
 488     wxProgressDialog 
*progress 
= NULL
; 
 491     m_ContentsBox
->Clear(); 
 493     int cnt 
= m_Data
->GetContentsCnt(); 
 494     int div 
= (cnt 
/ PROGRESS_STEP
) + 1; 
 497     wxHtmlContentsItem 
*it
; 
 500         progress 
= new wxProgressDialog(_("Building contents tree..."), wxEmptyString
, 
 501                                         cnt
, this, wxPD_APP_MODAL 
| wxPD_CAN_ABORT 
| 
 504     wxTreeItemId roots
[MAX_ROOTS
]; 
 505     bool imaged
[MAX_ROOTS
]; 
 507     m_ContentsBox 
-> DeleteAllItems(); 
 508     roots
[0] = m_ContentsBox 
-> AddRoot(_("(Help)")); 
 509     m_ContentsBox 
-> SetItemImage(roots
[0], IMG_RootFolder
); 
 510     m_ContentsBox 
-> SetItemSelectedImage(roots
[0], IMG_RootFolder
); 
 513     for (it 
= m_Data
->GetContents(), i 
= 0; i 
< cnt
; i
++, it
++) { 
 514         if (show_progress 
&& ((i 
% div
) == 0)) { 
 515             proginfo
.Printf(_("Added %d/%d items"), i
, cnt
); 
 516             if (! progress
->Update(i
, proginfo
)) 
 520         roots
[it 
-> m_Level 
+ 1] =  m_ContentsBox 
-> AppendItem( 
 521                                        roots
[it 
-> m_Level
], it 
-> m_Name
, IMG_Page
, -1, 
 522                                        new wxHtmlHelpTreeItemData(it
)); 
 524         if (it 
-> m_Level 
== 0) { 
 525             m_ContentsBox 
-> SetItemBold(roots
[1], TRUE
); 
 526             m_ContentsBox 
-> SetItemImage(roots
[1], IMG_Book
); 
 527             m_ContentsBox 
-> SetItemSelectedImage(roots
[1], IMG_Book
); 
 529         } else imaged
[it 
-> m_Level 
+ 1] = FALSE
; 
 531         if (!imaged
[it 
-> m_Level
]) { 
 532             m_ContentsBox 
-> SetItemImage(roots
[it 
-> m_Level
], IMG_Folder
); 
 533             m_ContentsBox 
-> SetItemSelectedImage(roots
[it 
-> m_Level
], IMG_Folder
); 
 534             imaged
[it 
-> m_Level
] = TRUE
; 
 539     m_ContentsBox 
-> Expand(roots
[0]); 
 543 void wxHtmlHelpFrame::CreateIndex(bool show_progress
) 
 548     wxProgressDialog 
*progress 
= NULL
; 
 551     m_IndexList
->Clear(); 
 553     int cnt 
= m_Data
->GetIndexCnt(); 
 556     if (cnt 
> INDEX_IS_SMALL
) cnttext
.Printf(_("%i of %i"), 0, cnt
); 
 557     else cnttext
.Printf(_("%i of %i"), cnt
, cnt
); 
 558     m_IndexCountInfo 
-> SetLabel(cnttext
); 
 559     if (cnt 
> INDEX_IS_SMALL
) return; 
 561     int div 
= (cnt 
/ PROGRESS_STEP
) + 1; 
 563     wxHtmlContentsItem
* index 
= m_Data
->GetIndex(); 
 566         progress 
= new wxProgressDialog(_("Building index list..."), wxEmptyString
, 
 567                                         cnt
, this, wxPD_APP_MODAL 
| wxPD_CAN_ABORT 
| 
 569     for (int i 
= 0; i 
< cnt
; i
++) { 
 570         if (show_progress 
&& ((i 
% div
) == 0)) { 
 571             proginfo
.Printf(_("Added %d/%d items"), i
, cnt
); 
 572             if (! progress
->Update(i
, proginfo
)) 
 576         m_IndexList 
-> Append(index
[i
].m_Name
, (char*)(index 
+ i
)); 
 583 void wxHtmlHelpFrame::CreateSearch() 
 585     if (! (m_SearchList 
&& m_SearchChoice
)) 
 587     m_SearchList 
-> Clear(); 
 588     m_SearchChoice 
-> Clear(); 
 589     m_SearchChoice 
-> Append(_("all books")); 
 590     const wxHtmlBookRecArray
& bookrec 
= m_Data
->GetBookRecArray(); 
 591     int i
, cnt 
= bookrec
.GetCount(); 
 592     for (i 
= 0; i 
< cnt
; i
++) 
 593         m_SearchChoice
->Append(bookrec
[i
].GetTitle()); 
 594     m_SearchChoice
->SetSelection(0); 
 598 void wxHtmlHelpFrame::RefreshLists(bool show_progress
) 
 600     CreateContents(show_progress
); 
 601     CreateIndex(show_progress
); 
 605 void wxHtmlHelpFrame::ReadCustomization(wxConfigBase 
*cfg
, const wxString
& path
) 
 610     if (path 
!= wxEmptyString
) { 
 611         oldpath 
= cfg 
-> GetPath(); 
 612         cfg 
-> SetPath(path
); 
 615     m_Cfg
.navig_on 
= cfg 
-> Read("hcNavigPanel", m_Cfg
.navig_on
) != 0; 
 616     m_Cfg
.sashpos 
= cfg 
-> Read("hcSashPos", m_Cfg
.sashpos
); 
 617     m_Cfg
.x 
= cfg 
-> Read("hcX", m_Cfg
.x
); 
 618     m_Cfg
.y 
= cfg 
-> Read("hcY", m_Cfg
.y
); 
 619     m_Cfg
.w 
= cfg 
-> Read("hcW", m_Cfg
.w
); 
 620     m_Cfg
.h 
= cfg 
-> Read("hcH", m_Cfg
.h
); 
 622     m_FixedFace 
= cfg 
-> Read("hcFixedFace", m_FixedFace
); 
 623     m_NormalFace 
= cfg 
-> Read("hcNormalFace", m_NormalFace
); 
 624     m_FontSize 
= cfg 
-> Read("hcFontSize", m_FontSize
); 
 631         cnt 
= cfg 
-> Read("hcBookmarksCnt", 0L); 
 633             m_BookmarksNames
.Clear(); 
 634             m_BookmarksPages
.Clear(); 
 636                 m_Bookmarks 
-> Clear(); 
 637                 m_Bookmarks 
-> Append(_("<bookmarks>")); 
 640             for (i 
= 0; i 
< cnt
; i
++) { 
 641                 val
.Printf(wxT("hcBookmark_%i"), i
); 
 642                 s 
= cfg 
-> Read(val
); 
 643                 m_BookmarksNames
.Add(s
); 
 644                 if (m_Bookmarks
) m_Bookmarks 
-> Append(s
); 
 645                 val
.Printf(wxT("hcBookmark_%i_url"), i
); 
 646                 s 
= cfg 
-> Read(val
); 
 647                 m_BookmarksPages
.Add(s
); 
 653         m_HtmlWin
->ReadCustomization(cfg
, path
); 
 655     if (path 
!= wxEmptyString
) 
 656         cfg 
-> SetPath(oldpath
); 
 659 void wxHtmlHelpFrame::WriteCustomization(wxConfigBase 
*cfg
, const wxString
& path
) 
 664     if (path 
!= wxEmptyString
) { 
 665         oldpath 
= cfg 
-> GetPath(); 
 666         cfg 
-> SetPath(path
); 
 669     cfg 
-> Write("hcNavigPanel", m_Cfg
.navig_on
); 
 670     cfg 
-> Write("hcSashPos", (long)m_Cfg
.sashpos
); 
 671     cfg 
-> Write("hcX", (long)m_Cfg
.x
); 
 672     cfg 
-> Write("hcY", (long)m_Cfg
.y
); 
 673     cfg 
-> Write("hcW", (long)m_Cfg
.w
); 
 674     cfg 
-> Write("hcH", (long)m_Cfg
.h
); 
 675     cfg 
-> Write("hcFixedFace", m_FixedFace
); 
 676     cfg 
-> Write("hcNormalFace", m_NormalFace
); 
 677     cfg 
-> Write("hcFontSize", (long)m_FontSize
); 
 681         int cnt 
= m_BookmarksNames
.GetCount(); 
 684         cfg 
-> Write("hcBookmarksCnt", (long)cnt
); 
 685         for (i 
= 0; i 
< cnt
; i
++) { 
 686             val
.Printf(wxT("hcBookmark_%i"), i
); 
 687             cfg 
-> Write(val
, m_BookmarksNames
[i
]); 
 688             val
.Printf(wxT("hcBookmark_%i_url"), i
); 
 689             cfg 
-> Write(val
, m_BookmarksPages
[i
]); 
 694         m_HtmlWin
->WriteCustomization(cfg
, path
); 
 696     if (path 
!= wxEmptyString
) 
 697         cfg 
-> SetPath(oldpath
); 
 704 static void SetFontsToHtmlWin(wxHtmlWindow 
*win
, wxString scalf
, wxString fixf
, int size
) 
 706     static int f_sizes
[3][7] =  
 708             { 8,  9, 12, 14, 16, 19, 22}, 
 709             {10, 12, 14, 16, 19, 24, 32}, 
 710             {14, 16, 18, 24, 32, 38, 45} 
 713     win 
-> SetFonts(scalf
, fixf
, f_sizes
[size
]); 
 717 class wxHtmlHelpFrameOptionsDialog 
: public wxDialog
 
 720         wxComboBox 
*NormalFont
, *FixedFont
; 
 721         wxRadioBox 
*RadioBox
; 
 722         wxHtmlWindow 
*TestWin
; 
 724         wxHtmlHelpFrameOptionsDialog(wxWindow 
*parent
) : wxDialog(parent
, -1, wxString(_("Help Browser Options"))) 
 726                 wxString choices
[3] = {_("small"), _("medium"), _("large")}; 
 727                 wxBoxSizer 
*topsizer
, *sizer
, *sizer2
; 
 729                 topsizer 
= new wxBoxSizer(wxVERTICAL
); 
 731                 sizer 
= new wxBoxSizer(wxHORIZONTAL
); 
 733                 sizer2 
= new wxStaticBoxSizer( new wxStaticBox(this, -1, _("Normal font:")), wxVERTICAL
); 
 734                 sizer2 
-> Add(NormalFont 
= new wxComboBox(this, -1, wxEmptyString
, wxDefaultPosition
,  
 736                               0, NULL
, wxCB_DROPDOWN 
| wxCB_READONLY
), 
 737                               1, wxEXPAND 
| wxLEFT 
| wxRIGHT
, 10); 
 739                 sizer 
-> Add(sizer2
, 0, wxEXPAND 
| wxLEFT
|wxRIGHT
|wxTOP
, 10); 
 741                 sizer2 
= new wxStaticBoxSizer( new wxStaticBox(this, -1, _("Fixed font:")), wxVERTICAL
); 
 742                 sizer2 
-> Add(FixedFont 
= new wxComboBox(this, -1, wxEmptyString
, wxDefaultPosition
,  
 744                               0, NULL
, wxCB_DROPDOWN 
| wxCB_READONLY
),  
 745                               1, wxEXPAND 
| wxLEFT 
| wxRIGHT
, 10); 
 747                 sizer 
-> Add(sizer2
, 0, wxEXPAND 
| wxLEFT
|wxRIGHT
|wxTOP
, 10); 
 749                 topsizer 
-> Add(sizer
); 
 751                 topsizer 
-> Add(RadioBox 
= new wxRadioBox(this, -1, _("Font size:"),  
 752                                                           wxDefaultPosition
, wxDefaultSize
, 3, choices
, 3),  
 753                                 0, wxEXPAND 
| wxLEFT
|wxRIGHT
|wxTOP
, 10); 
 755                 topsizer 
-> Add(new wxStaticText(this, -1, _("Preview:")),  
 756                                 0, wxLEFT 
| wxTOP
, 10); 
 757                 topsizer 
-> Add(TestWin 
= new wxHtmlWindow(this, -1, wxDefaultPosition
, wxSize(-1, 150)),  
 758                                 1, wxEXPAND 
| wxLEFT
|wxTOP
|wxRIGHT
, 10); 
 760                 sizer 
= new wxBoxSizer(wxHORIZONTAL
); 
 761                 sizer 
-> Add(new wxButton(this, wxID_OK
, _("OK")), 0, wxALL
, 10); 
 762                 sizer 
-> Add(new wxButton(this, wxID_CANCEL
, _("Cancel")), 0, wxALL
, 10); 
 763                 topsizer 
-> Add(sizer
, 0, wxALIGN_RIGHT
); 
 767                 topsizer 
-> Fit(this); 
 775                 SetFontsToHtmlWin(TestWin
,  
 776                                   NormalFont 
-> GetStringSelection(), 
 777                                   FixedFont 
-> GetStringSelection(), 
 778                                   RadioBox 
-> GetSelection()); 
 779                 TestWin 
-> SetPage(_("<html><body>" 
 780                                    "Normal face<br>(and <u>underlined</u>. <i>Italic face.</i> " 
 781                                    "<b>Bold face.</b> <b><i>Bold italic face.</i></b><br>" 
 782                                    "<font size=-2>font size -2</font><br>" 
 783                                    "<font size=-1>font size -1</font><br>" 
 784                                    "<font size=+0>font size +0</font><br>" 
 785                                    "<font size=+1>font size +1</font><br>" 
 786                                    "<font size=+2>font size +2</font><br>" 
 787                                    "<font size=+3>font size +3</font><br>" 
 788                                    "<font size=+4>font size +4</font><br>" 
 790                                    "<p><tt>Fixed size face.<br> <b>bold</b> <i>italic</i> " 
 791                                    "<b><i>bold italic <u>underlined</u></i></b><br>" 
 792                                    "<font size=-2>font size -2</font><br>" 
 793                                    "<font size=-1>font size -1</font><br>" 
 794                                    "<font size=+0>font size +0</font><br>" 
 795                                    "<font size=+1>font size +1</font><br>" 
 796                                    "<font size=+2>font size +2</font><br>" 
 797                                    "<font size=+3>font size +3</font><br>" 
 798                                    "<font size=+4>font size +4</font></tt>" 
 802         void OnUpdate(wxCloseEvent
& event
) 
 807         DECLARE_EVENT_TABLE() 
 810 BEGIN_EVENT_TABLE(wxHtmlHelpFrameOptionsDialog
, wxDialog
) 
 811     EVT_COMBOBOX(-1, wxHtmlHelpFrameOptionsDialog::OnUpdate
) 
 812     EVT_RADIOBOX(-1, wxHtmlHelpFrameOptionsDialog::OnUpdate
) 
 816 void wxHtmlHelpFrame::OptionsDialog() 
 818     wxHtmlHelpFrameOptionsDialog 
dlg(this); 
 821     if (m_NormalFonts 
== NULL
) { 
 822         wxFontEnumerator enu
; 
 823         enu
.EnumerateFacenames(); 
 824         m_NormalFonts 
= new wxArrayString
; 
 825         *m_NormalFonts 
= *enu
.GetFacenames(); 
 826         m_NormalFonts 
-> Sort(); 
 828     if (m_FixedFonts 
== NULL
) { 
 829         wxFontEnumerator enu
; 
 830         enu
.EnumerateFacenames(wxFONTENCODING_SYSTEM
, TRUE
); 
 831         m_FixedFonts 
= new wxArrayString
; 
 832         *m_FixedFonts 
= *enu
.GetFacenames(); 
 833         m_FixedFonts 
-> Sort(); 
 836     for (i 
= 0; i 
< m_NormalFonts 
-> GetCount(); i
++) 
 837         dlg
.NormalFont 
-> Append((*m_NormalFonts
)[i
]); 
 838     for (i 
= 0; i 
< m_FixedFonts 
-> GetCount(); i
++) 
 839         dlg
.FixedFont 
-> Append((*m_FixedFonts
)[i
]); 
 840     if (!m_NormalFace
.IsEmpty()) dlg
.NormalFont 
-> SetStringSelection(m_NormalFace
); 
 841     else dlg
.NormalFont 
-> SetSelection(0); 
 842     if (!m_FixedFace
.IsEmpty()) dlg
.FixedFont 
-> SetStringSelection(m_FixedFace
); 
 843     else dlg
.FixedFont 
-> SetSelection(0); 
 844     dlg
.RadioBox 
-> SetSelection(m_FontSize
); 
 847     if (dlg
.ShowModal() == wxID_OK
) { 
 848         m_NormalFace 
= dlg
.NormalFont 
-> GetStringSelection(); 
 849         m_FixedFace 
= dlg
.FixedFont 
-> GetStringSelection(); 
 850         m_FontSize 
= dlg
.RadioBox 
-> GetSelection(); 
 851         SetFontsToHtmlWin(m_HtmlWin
, m_NormalFace
, m_FixedFace
, m_FontSize
); 
 864 void wxHtmlHelpFrame::OnToolbar(wxCommandEvent
& event
) 
 866     switch (event
.GetId()) { 
 868         case wxID_HTML_BACK 
: 
 869             m_HtmlWin 
-> HistoryBack(); 
 872         case wxID_HTML_FORWARD 
: 
 873             m_HtmlWin 
-> HistoryForward(); 
 876         case wxID_HTML_PANEL 
: 
 877             if (! (m_Splitter 
&& m_NavigPan
)) 
 879             if (m_Splitter 
-> IsSplit()) { 
 880                 m_Cfg
.sashpos 
= m_Splitter 
-> GetSashPosition(); 
 881                 m_Splitter 
-> Unsplit(m_NavigPan
); 
 882                 m_Cfg
.navig_on 
= FALSE
; 
 884                 m_NavigPan 
-> Show(TRUE
); 
 885                 m_HtmlWin 
-> Show(TRUE
); 
 886                 m_Splitter 
-> SplitVertically(m_NavigPan
, m_HtmlWin
, m_Cfg
.sashpos
); 
 887                 m_Cfg
.navig_on 
= TRUE
; 
 891         case wxID_HTML_OPTIONS 
: 
 895         case wxID_HTML_BOOKMARKSADD 
:  
 900                 item 
= m_HtmlWin 
-> GetOpenedPageTitle(); 
 901                 url 
= m_HtmlWin 
-> GetOpenedPage(); 
 902                 if (item 
== wxEmptyString
) item 
= url
.AfterLast(wxT('/')); 
 903                 if (m_BookmarksPages
.Index(url
) == wxNOT_FOUND
) { 
 904                     m_Bookmarks 
-> Append(item
); 
 905                     m_BookmarksNames
.Add(item
); 
 906                     m_BookmarksPages
.Add(url
); 
 911         case wxID_HTML_BOOKMARKSREMOVE 
:  
 916                 item 
= m_Bookmarks 
-> GetStringSelection(); 
 917                 pos 
= m_BookmarksNames
.Index(item
); 
 918                 if (pos 
!= wxNOT_FOUND
) { 
 919                     m_BookmarksNames
.Remove(pos
); 
 920                     m_BookmarksPages
.Remove(pos
); 
 921                     m_Bookmarks 
-> Delete(m_Bookmarks 
-> GetSelection()); 
 930 void wxHtmlHelpFrame::OnContentsSel(wxTreeEvent
& event
) 
 932     wxHtmlHelpTreeItemData 
*pg
; 
 934     pg 
= (wxHtmlHelpTreeItemData
*) m_ContentsBox 
-> GetItemData(event
.GetItem()); 
 935     if (pg
) m_HtmlWin 
-> LoadPage(pg 
-> GetPage()); 
 940 void wxHtmlHelpFrame::OnIndexSel(wxCommandEvent
& WXUNUSED(event
)) 
 942     wxHtmlContentsItem 
*it 
= (wxHtmlContentsItem
*) m_IndexList 
-> GetClientData(m_IndexList 
-> GetSelection()); 
 943     m_HtmlWin 
-> LoadPage(it 
-> m_Book 
-> GetBasePath() + it 
-> m_Page
); 
 947 void wxHtmlHelpFrame::OnIndexFind(wxCommandEvent
& event
) 
 949     wxString sr 
= m_IndexText 
-> GetLineText(0); 
 951     if (sr 
== wxEmptyString
)  
 956         const wxChar 
*cstr 
= sr
.c_str(); 
 957         wxChar mybuff
[512], *ptr
; 
 960         m_IndexList
->Clear(); 
 961         int cnt 
= m_Data
->GetIndexCnt(); 
 962         wxHtmlContentsItem
* index 
= m_Data
->GetIndex(); 
 965         for (int i 
= 0; i 
< cnt
; i
++) 
 967             wxStrncpy(mybuff
, index
[i
].m_Name
, 512); 
 969             for (ptr 
= mybuff
; *ptr 
!= 0; ptr
++)  
 970                 if (*ptr 
>= 'A' && *ptr 
<= 'Z') *ptr 
-= 'A' - 'a'; 
 971             if (wxStrstr(mybuff
, cstr
) != NULL
) { 
 972                 m_IndexList 
-> Append(index
[i
].m_Name
, (char*)(index 
+ i
)); 
 975                     m_HtmlWin 
-> LoadPage(index
[i
].m_Book 
-> GetBasePath() + index
[i
].m_Page
); 
 982         cnttext
.Printf(_("%i of %i"), displ
, cnt
); 
 983         m_IndexCountInfo 
-> SetLabel(cnttext
); 
 985         m_IndexText 
-> SetSelection(0, sr
.Length()); 
 986         m_IndexText 
-> SetFocus(); 
 990 void wxHtmlHelpFrame::OnIndexAll(wxCommandEvent
& WXUNUSED(event
)) 
 994     m_IndexList
->Clear(); 
 995     int cnt 
= m_Data
->GetIndexCnt(); 
 997     wxHtmlContentsItem
* index 
= m_Data
->GetIndex(); 
 999     for (int i 
= 0; i 
< cnt
; i
++) { 
1000         m_IndexList 
-> Append(index
[i
].m_Name
, (char*)(index 
+ i
)); 
1002             m_HtmlWin 
-> LoadPage(index
[i
].m_Book 
-> GetBasePath() + index
[i
].m_Page
); 
1008     cnttext
.Printf(_("%i of %i"), cnt
, cnt
); 
1009     m_IndexCountInfo 
-> SetLabel(cnttext
); 
1013 void wxHtmlHelpFrame::OnSearchSel(wxCommandEvent
& WXUNUSED(event
)) 
1015     wxHtmlContentsItem 
*it 
= (wxHtmlContentsItem
*) m_SearchList 
-> GetClientData(m_SearchList 
-> GetSelection()); 
1016     if (it
) m_HtmlWin 
-> LoadPage(it 
-> m_Book 
-> GetBasePath() + it 
-> m_Page
); 
1019 void wxHtmlHelpFrame::OnSearch(wxCommandEvent
& WXUNUSED(event
)) 
1021     wxString sr 
= m_SearchText 
-> GetLineText(0); 
1023     if (sr 
!= wxEmptyString
) KeywordSearch(sr
); 
1026 void wxHtmlHelpFrame::OnBookmarksSel(wxCommandEvent
& WXUNUSED(event
)) 
1028     wxString sr 
= m_Bookmarks 
-> GetStringSelection(); 
1030     if (sr 
!= wxEmptyString 
&& sr 
!= _("<bookmarks>")) 
1031         m_HtmlWin 
-> LoadPage(m_BookmarksPages
[m_BookmarksNames
.Index(sr
)]); 
1034 void wxHtmlHelpFrame::OnCloseWindow(wxCloseEvent
& evt
) 
1036     GetSize(&m_Cfg
.w
, &m_Cfg
.h
); 
1037     GetPosition(&m_Cfg
.x
, &m_Cfg
.y
); 
1039     if (m_Splitter 
&& m_Cfg
.navig_on
) m_Cfg
.sashpos 
= m_Splitter 
-> GetSashPosition(); 
1042         WriteCustomization(m_Config
, m_ConfigRoot
); 
1047 BEGIN_EVENT_TABLE(wxHtmlHelpFrame
, wxFrame
) 
1048     EVT_TOOL_RANGE(wxID_HTML_PANEL
, wxID_HTML_BOOKMARKSREMOVE
, wxHtmlHelpFrame::OnToolbar
) 
1049     EVT_TREE_SEL_CHANGED(wxID_HTML_TREECTRL
, wxHtmlHelpFrame::OnContentsSel
) 
1050     EVT_LISTBOX(wxID_HTML_INDEXLIST
, wxHtmlHelpFrame::OnIndexSel
) 
1051     EVT_LISTBOX(wxID_HTML_SEARCHLIST
, wxHtmlHelpFrame::OnSearchSel
) 
1052     EVT_BUTTON(wxID_HTML_SEARCHBUTTON
, wxHtmlHelpFrame::OnSearch
) 
1053     EVT_TEXT_ENTER(wxID_HTML_SEARCHTEXT
, wxHtmlHelpFrame::OnSearch
) 
1054     EVT_BUTTON(wxID_HTML_INDEXBUTTON
, wxHtmlHelpFrame::OnIndexFind
) 
1055     EVT_TEXT_ENTER(wxID_HTML_INDEXTEXT
, wxHtmlHelpFrame::OnIndexFind
) 
1056     EVT_BUTTON(wxID_HTML_INDEXBUTTONALL
, wxHtmlHelpFrame::OnIndexAll
) 
1057     EVT_COMBOBOX(wxID_HTML_BOOKMARKSLIST
, wxHtmlHelpFrame::OnBookmarksSel
) 
1058     EVT_CLOSE(wxHtmlHelpFrame::OnCloseWindow
)