]> git.saurik.com Git - wxWidgets.git/blame - src/html/helpfrm.cpp
correcting CGImage handling to be always correctly initialized and freed on OSX build...
[wxWidgets.git] / src / html / helpfrm.cpp
CommitLineData
8ec2b484
HH
1/////////////////////////////////////////////////////////////////////////////
2// Name: helpfrm.cpp
3// Purpose: wxHtmlHelpFrame
d5bb85a0 4// Notes: Based on htmlhelp.cpp, implementing a monolithic
8ec2b484
HH
5// HTML Help controller class, by Vaclav Slavik
6// Author: Harm van der Heijden and Vaclav Slavik
69941f05 7// RCS-ID: $Id$
8ec2b484 8// Copyright: (c) Harm van der Heijden and Vaclav Slavik
65571936 9// Licence: wxWindows licence
8ec2b484
HH
10/////////////////////////////////////////////////////////////////////////////
11
c32bfc10
VS
12// For compilers that support precompilation, includes "wx.h"
13
8ec2b484
HH
14#include "wx/wxprec.h"
15
16#ifdef __BORLANDC__
17#pragma hdrstop
18#endif
19
3379ed37 20#if wxUSE_WXHTML_HELP
07b8d7ec 21
8ec2b484 22#ifndef WXPRECOMP
07b8d7ec
VZ
23 #include "wx/intl.h"
24 #include "wx/log.h"
25
26 #include "wx/object.h"
07b8d7ec
VZ
27 #include "wx/sizer.h"
28
29 #include "wx/bmpbuttn.h"
30 #include "wx/statbox.h"
31 #include "wx/radiobox.h"
32#endif // WXPRECOMP
8ec2b484 33
c718e0b3
SC
34#ifdef __WXMAC__
35 #include "wx/menu.h"
36 #include "wx/msgdlg.h"
37#endif
38
8ec2b484 39#include "wx/html/helpfrm.h"
b4414c1f 40#include "wx/html/helpctrl.h"
618a5e38 41#include "wx/textctrl.h"
8ec2b484
HH
42#include "wx/notebook.h"
43#include "wx/imaglist.h"
44#include "wx/treectrl.h"
45#include "wx/tokenzr.h"
46#include "wx/wfstream.h"
47#include "wx/html/htmlwin.h"
48#include "wx/busyinfo.h"
49#include "wx/progdlg.h"
2bd5bbc9 50#include "wx/toolbar.h"
83efdf33 51#include "wx/fontenum.h"
0646614d
VS
52#include "wx/stream.h"
53#include "wx/filedlg.h"
f435c1f0 54#include "wx/artprov.h"
c269cf62 55#include "wx/spinctrl.h"
91fa114d
VS
56#include "wx/dynarray.h"
57#include "wx/choicdlg.h"
bfa7fb52 58#include "wx/settings.h"
8ec2b484 59
f0b6a33f
VS
60// what is considered "small index"?
61#define INDEX_IS_SMALL 100
62
9806a47c
JS
63/* Motif defines this as a macro */
64#ifdef Below
65#undef Below
66#endif
f0b6a33f 67
8ec2b484 68//--------------------------------------------------------------------------
382e6efe 69// wxHtmlHelpTreeItemData (private)
8ec2b484
HH
70//--------------------------------------------------------------------------
71
72class wxHtmlHelpTreeItemData : public wxTreeItemData
73{
0646614d 74 public:
da4cc40c
DW
75#if defined(__VISAGECPP__)
76// VA needs a default ctor for some reason....
77 wxHtmlHelpTreeItemData() : wxTreeItemData()
78 { m_Id = 0; }
79#endif
0646614d
VS
80 wxHtmlHelpTreeItemData(int id) : wxTreeItemData()
81 { m_Id = id;}
82
83 int m_Id;
84};
8ec2b484 85
0646614d
VS
86
87//--------------------------------------------------------------------------
88// wxHtmlHelpHashData (private)
89//--------------------------------------------------------------------------
90
91class wxHtmlHelpHashData : public wxObject
92{
8ec2b484 93 public:
0646614d
VS
94 wxHtmlHelpHashData(int index, wxTreeItemId id) : wxObject()
95 { m_Index = index; m_Id = id;}
f5ba273e 96 ~wxHtmlHelpHashData() {}
f6bcfd97 97
0646614d
VS
98 int m_Index;
99 wxTreeItemId m_Id;
8ec2b484
HH
100};
101
382e6efe 102
0646614d
VS
103//--------------------------------------------------------------------------
104// wxHtmlHelpHtmlWindow (private)
105//--------------------------------------------------------------------------
106
107class wxHtmlHelpHtmlWindow : public wxHtmlWindow
108{
109 public:
bfa7fb52
VS
110 wxHtmlHelpHtmlWindow(wxHtmlHelpFrame *fr, wxWindow *parent)
111 : wxHtmlWindow(parent), m_Frame(fr)
112 {
113 SetStandardFonts();
114 }
0646614d
VS
115
116 virtual void OnLinkClicked(const wxHtmlLinkInfo& link)
117 {
118 wxHtmlWindow::OnLinkClicked(link);
adf2eb2d
VS
119 const wxMouseEvent *e = link.GetEvent();
120 if (e == NULL || e->LeftUp())
121 m_Frame->NotifyPageChanged();
0646614d
VS
122 }
123
baa17710
WS
124 // Returns full location with anchor (helper)
125 static wxString GetOpenedPageWithAnchor(wxHtmlWindow *win)
126 {
127 if(!win)
128 return wxEmptyString;
129
130 wxString an = win->GetOpenedAnchor();
131 wxString pg = win->GetOpenedPage();
132 if(!an.empty())
133 {
134 pg << wxT("#");
135 pg << an;
136 }
137 return pg;
138 }
139
f6bcfd97 140 private:
0646614d 141 wxHtmlHelpFrame *m_Frame;
22f3361e
VZ
142
143 DECLARE_NO_COPY_CLASS(wxHtmlHelpHtmlWindow)
0646614d
VS
144};
145
382e6efe 146
91fa114d
VS
147//---------------------------------------------------------------------------
148// wxHtmlHelpFrame::m_mergedIndex
149//---------------------------------------------------------------------------
150
69b69d5a 151WX_DEFINE_ARRAY_PTR(const wxHtmlHelpDataItem*, wxHtmlHelpDataItemPtrArray);
91fa114d
VS
152
153struct wxHtmlHelpMergedIndexItem
154{
155 wxHtmlHelpMergedIndexItem *parent;
156 wxString name;
157 wxHtmlHelpDataItemPtrArray items;
158};
159
160WX_DECLARE_OBJARRAY(wxHtmlHelpMergedIndexItem, wxHtmlHelpMergedIndex);
161#include "wx/arrimpl.cpp"
162WX_DEFINE_OBJARRAY(wxHtmlHelpMergedIndex)
163
164void wxHtmlHelpFrame::UpdateMergedIndex()
165{
166 delete m_mergedIndex;
167 m_mergedIndex = new wxHtmlHelpMergedIndex;
168 wxHtmlHelpMergedIndex& merged = *m_mergedIndex;
169
170 const wxHtmlHelpDataItems& items = m_Data->GetIndexArray();
171 size_t len = items.size();
172
173 wxHtmlHelpMergedIndexItem *history[128] = {NULL};
d1da8872 174
91fa114d
VS
175 for (size_t i = 0; i < len; i++)
176 {
177 const wxHtmlHelpDataItem& item = items[i];
178 wxASSERT_MSG( item.level < 128, _T("nested index entries too deep") );
d1da8872 179
91fa114d
VS
180 if (history[item.level] &&
181 history[item.level]->items[0]->name == item.name)
182 {
183 // same index entry as previous one, update list of items
184 history[item.level]->items.Add(&item);
185 }
186 else
187 {
188 // new index entry
189 wxHtmlHelpMergedIndexItem *mi = new wxHtmlHelpMergedIndexItem();
190 mi->name = item.GetIndentedName();
191 mi->items.Add(&item);
192 mi->parent = (item.level == 0) ? NULL : history[item.level - 1];
193 history[item.level] = mi;
194 merged.Add(mi);
d1da8872 195 }
91fa114d
VS
196 }
197}
d1da8872 198
382e6efe 199
8ec2b484
HH
200//---------------------------------------------------------------------------
201// wxHtmlHelpFrame
202//---------------------------------------------------------------------------
203
576507e2
VS
204// Command IDs :
205enum
206{
207 //wxID_HTML_HELPFRAME = wxID_HIGHEST + 1,
208 wxID_HTML_PANEL = wxID_HIGHEST + 2,
209 wxID_HTML_BACK,
210 wxID_HTML_FORWARD,
211 wxID_HTML_UPNODE,
212 wxID_HTML_UP,
213 wxID_HTML_DOWN,
214 wxID_HTML_PRINT,
215 wxID_HTML_OPENFILE,
216 wxID_HTML_OPTIONS,
217 wxID_HTML_BOOKMARKSLIST,
218 wxID_HTML_BOOKMARKSADD,
219 wxID_HTML_BOOKMARKSREMOVE,
220 wxID_HTML_TREECTRL,
221 wxID_HTML_INDEXPAGE,
222 wxID_HTML_INDEXLIST,
223 wxID_HTML_INDEXTEXT,
224 wxID_HTML_INDEXBUTTON,
225 wxID_HTML_INDEXBUTTONALL,
226 wxID_HTML_NOTEBOOK,
227 wxID_HTML_SEARCHPAGE,
228 wxID_HTML_SEARCHTEXT,
229 wxID_HTML_SEARCHLIST,
230 wxID_HTML_SEARCHBUTTON,
231 wxID_HTML_SEARCHCHOICE,
232 wxID_HTML_COUNTINFO
233};
234
235
8ec2b484
HH
236IMPLEMENT_DYNAMIC_CLASS(wxHtmlHelpFrame, wxFrame)
237
238wxHtmlHelpFrame::wxHtmlHelpFrame(wxWindow* parent, wxWindowID id, const wxString& title,
d5bb85a0 239 int style, wxHtmlHelpData* data)
8ec2b484
HH
240{
241 Init(data);
242 Create(parent, id, title, style);
243}
d5bb85a0 244
8ec2b484
HH
245void wxHtmlHelpFrame::Init(wxHtmlHelpData* data)
246{
da4cc40c 247 if (data)
4f9297b0 248 {
d5bb85a0 249 m_Data = data;
dabbc6a5 250 m_DataCreated = false;
da4cc40c 251 } else
4f9297b0 252 {
d5bb85a0 253 m_Data = new wxHtmlHelpData();
dabbc6a5 254 m_DataCreated = true;
8ec2b484
HH
255 }
256
1afce1a8
WS
257 m_ContentsPage = 0;
258 m_IndexPage = 0;
259 m_SearchPage = 0;
260
8ec2b484 261 m_ContentsBox = NULL;
f0b6a33f
VS
262 m_IndexList = NULL;
263 m_IndexButton = NULL;
264 m_IndexButtonAll = NULL;
265 m_IndexText = NULL;
8ec2b484
HH
266 m_SearchList = NULL;
267 m_SearchButton = NULL;
268 m_SearchText = NULL;
269 m_SearchChoice = NULL;
240c2873 270 m_IndexCountInfo = NULL;
8ec2b484
HH
271 m_Splitter = NULL;
272 m_NavigPan = NULL;
5229b11d 273 m_NavigNotebook = NULL;
8ec2b484 274 m_HtmlWin = NULL;
382e6efe 275 m_Bookmarks = NULL;
c4971147
VS
276 m_SearchCaseSensitive = NULL;
277 m_SearchWholeWords = NULL;
278
91fa114d
VS
279 m_mergedIndex = NULL;
280
8ec2b484
HH
281 m_Config = NULL;
282 m_ConfigRoot = wxEmptyString;
283
1afce1a8 284 m_Cfg.x = m_Cfg.y = wxDefaultCoord;
d5bb85a0
VS
285 m_Cfg.w = 700;
286 m_Cfg.h = 480;
8ec2b484 287 m_Cfg.sashpos = 240;
dabbc6a5 288 m_Cfg.navig_on = true;
83efdf33
VS
289
290 m_NormalFonts = m_FixedFonts = NULL;
83efdf33 291 m_NormalFace = m_FixedFace = wxEmptyString;
c269cf62
VS
292#ifdef __WXMSW__
293 m_FontSize = 10;
294#else
295 m_FontSize = 14;
296#endif
f6bcfd97 297
0646614d
VS
298#if wxUSE_PRINTING_ARCHITECTURE
299 m_Printer = NULL;
300#endif
301
302 m_PagesHash = NULL;
dabbc6a5 303 m_UpdateContents = true;
b4414c1f 304 m_helpController = (wxHelpControllerBase*) NULL;
8ec2b484
HH
305}
306
d5bb85a0
VS
307// Create: builds the GUI components.
308// with the style flag it's possible to toggle the toolbar, contents, index and search
309// controls.
310// m_HtmlWin will *always* be created, but it's important to realize that
f0b6a33f 311// m_ContentsBox, m_IndexList, m_SearchList, m_SearchButton, m_SearchText and
d5bb85a0
VS
312// m_SearchButton may be NULL.
313// moreover, if no contents, index or searchpage is needed, m_Splitter and
314// m_NavigPan will be NULL too (with m_HtmlWin directly connected to the frame)
315
3379ed37 316bool wxHtmlHelpFrame::Create(wxWindow* parent, wxWindowID id,
576507e2 317 const wxString& WXUNUSED(title), int style)
8ec2b484 318{
576507e2
VS
319 m_hfStyle = style;
320
8fd2b35c 321 wxImageList *ContentsImageList = new wxImageList(16, 16);
1dfab6bb
VS
322 ContentsImageList->Add(wxArtProvider::GetIcon(wxART_HELP_BOOK,
323 wxART_HELP_BROWSER,
324 wxSize(16, 16)));
325 ContentsImageList->Add(wxArtProvider::GetIcon(wxART_HELP_FOLDER,
326 wxART_HELP_BROWSER,
327 wxSize(16, 16)));
328 ContentsImageList->Add(wxArtProvider::GetIcon(wxART_HELP_PAGE,
329 wxART_HELP_BROWSER,
330 wxSize(16, 16)));
8fd2b35c 331
8ec2b484
HH
332 // Do the config in two steps. We read the HtmlWindow customization after we
333 // create the window.
d5bb85a0
VS
334 if (m_Config)
335 ReadCustomization(m_Config, m_ConfigRoot);
8ec2b484 336
dabbc6a5
DS
337 wxFrame::Create(parent, id, _("Help"),
338 wxPoint(m_Cfg.x, m_Cfg.y), wxSize(m_Cfg.w, m_Cfg.h),
5229b11d 339 wxDEFAULT_FRAME_STYLE, wxT("wxHtmlHelp"));
8ec2b484 340
5c172c17
VS
341 GetPosition(&m_Cfg.x, &m_Cfg.y);
342
79683a13 343 SetIcon(wxArtProvider::GetIcon(wxART_HELP, wxART_HELP_BROWSER));
9ffdee80 344
d9b21c9f
JS
345 // On the Mac, each modeless frame must have a menubar.
346 // TODO: add more menu items, and perhaps add a style to show
347 // the menubar: compulsory on the Mac, optional elsewhere.
348#ifdef __WXMAC__
349 wxMenuBar* menuBar = new wxMenuBar;
350
351 wxMenu* fileMenu = new wxMenu;
352 fileMenu->Append(wxID_HTML_OPENFILE, _("&Open..."));
d9b21c9f
JS
353 fileMenu->AppendSeparator();
354 fileMenu->Append(wxID_CLOSE, _("&Close"));
355
b05206c9
JS
356 wxMenu* helpMenu = new wxMenu;
357 helpMenu->Append(wxID_ABOUT, _("&About..."));
322a5b45
JS
358 // Ensures we don't get an empty help menu
359 helpMenu->Append(wxID_HELP_CONTENTS, _("&About..."));
d9b21c9f 360
c3eeb758
RD
361 menuBar->Append(fileMenu,_("&File"));
362 menuBar->Append(helpMenu,_("&Help"));
d9b21c9f
JS
363 SetMenuBar(menuBar);
364#endif
365
8ec2b484
HH
366 int notebook_page = 0;
367
67a99992 368#if wxUSE_STATUSBAR
8ec2b484 369 CreateStatusBar();
67a99992 370#endif // wxUSE_STATUSBAR
8ec2b484 371
ee2f6a93 372#if wxUSE_TOOLBAR
8ec2b484 373 // toolbar?
576507e2 374 if (style & (wxHF_TOOLBAR | wxHF_FLAT_TOOLBAR))
4f9297b0 375 {
f6bcfd97
BP
376 wxToolBar *toolBar = CreateToolBar(wxNO_BORDER | wxTB_HORIZONTAL |
377 wxTB_DOCKABLE |
576507e2 378 (style & wxHF_FLAT_TOOLBAR ? wxTB_FLAT : 0));
00655497 379 toolBar->SetMargins( 2, 2 );
b854b7b8 380 AddToolbarButtons(toolBar, style);
4f9297b0 381 toolBar->Realize();
8ec2b484 382 }
ee2f6a93 383#endif //wxUSE_TOOLBAR
d5bb85a0 384
5229b11d
VS
385 wxSizer *navigSizer = NULL;
386
da4cc40c 387 if (style & (wxHF_CONTENTS | wxHF_INDEX | wxHF_SEARCH))
4f9297b0 388 {
d5bb85a0
VS
389 // traditional help controller; splitter window with html page on the
390 // right and a notebook containing various pages on the left
391 m_Splitter = new wxSplitterWindow(this);
392
0646614d 393 m_HtmlWin = new wxHtmlHelpHtmlWindow(this, m_Splitter);
dabbc6a5 394 m_NavigPan = new wxPanel(m_Splitter, wxID_ANY);
5229b11d
VS
395 m_NavigNotebook = new wxNotebook(m_NavigPan, wxID_HTML_NOTEBOOK,
396 wxDefaultPosition, wxDefaultSize);
dabbc6a5 397
5229b11d 398 navigSizer = new wxBoxSizer(wxVERTICAL);
adbf2d73 399 navigSizer->Add(m_NavigNotebook, 1, wxEXPAND);
5229b11d 400
5229b11d 401 m_NavigPan->SetSizer(navigSizer);
da4cc40c
DW
402 }
403 else
4f9297b0 404 { // only html window, no notebook with index,contents etc
d5bb85a0 405 m_HtmlWin = new wxHtmlWindow(this);
8ec2b484
HH
406 }
407
4f9297b0 408 m_HtmlWin->SetRelatedFrame(this, m_TitleFormat);
67a99992 409#if wxUSE_STATUSBAR
4f9297b0 410 m_HtmlWin->SetRelatedStatusBar(0);
67a99992 411#endif // wxUSE_STATUSBAR
5229b11d 412 if ( m_Config )
4f9297b0 413 m_HtmlWin->ReadCustomization(m_Config, m_ConfigRoot);
8ec2b484
HH
414
415 // contents tree panel?
5229b11d 416 if ( style & wxHF_CONTENTS )
4f9297b0 417 {
5229b11d
VS
418 wxWindow *dummy = new wxPanel(m_NavigNotebook, wxID_HTML_INDEXPAGE);
419 wxSizer *topsizer = new wxBoxSizer(wxVERTICAL);
dabbc6a5 420
5229b11d 421 topsizer->Add(0, 10);
dabbc6a5 422
5229b11d
VS
423 dummy->SetSizer(topsizer);
424
5229b11d 425 if ( style & wxHF_BOOKMARKS )
3379ed37 426 {
dabbc6a5 427 m_Bookmarks = new wxComboBox(dummy, wxID_HTML_BOOKMARKSLIST,
5229b11d 428 wxEmptyString,
dabbc6a5 429 wxDefaultPosition, wxDefaultSize,
5229b11d 430 0, NULL, wxCB_READONLY | wxCB_SORT);
4f9297b0 431 m_Bookmarks->Append(_("(bookmarks)"));
ae80f837 432 for (unsigned i = 0; i < m_BookmarksNames.GetCount(); i++)
4f9297b0
VS
433 m_Bookmarks->Append(m_BookmarksNames[i]);
434 m_Bookmarks->SetSelection(0);
ae80f837 435
5229b11d 436 wxBitmapButton *bmpbt1, *bmpbt2;
dabbc6a5
DS
437 bmpbt1 = new wxBitmapButton(dummy, wxID_HTML_BOOKMARKSADD,
438 wxArtProvider::GetBitmap(wxART_ADD_BOOKMARK,
61ba12f0 439 wxART_BUTTON));
dabbc6a5
DS
440 bmpbt2 = new wxBitmapButton(dummy, wxID_HTML_BOOKMARKSREMOVE,
441 wxArtProvider::GetBitmap(wxART_DEL_BOOKMARK,
61ba12f0 442 wxART_BUTTON));
5229b11d
VS
443#if wxUSE_TOOLTIPS
444 bmpbt1->SetToolTip(_("Add current page to bookmarks"));
445 bmpbt2->SetToolTip(_("Remove current page from bookmarks"));
446#endif // wxUSE_TOOLTIPS
447
448 wxSizer *sizer = new wxBoxSizer(wxHORIZONTAL);
dabbc6a5 449
f435c1f0
VS
450 sizer->Add(m_Bookmarks, 1, wxALIGN_CENTRE_VERTICAL | wxRIGHT, 5);
451 sizer->Add(bmpbt1, 0, wxALIGN_CENTRE_VERTICAL | wxRIGHT, 2);
452 sizer->Add(bmpbt2, 0, wxALIGN_CENTRE_VERTICAL, 0);
dabbc6a5 453
5229b11d 454 topsizer->Add(sizer, 0, wxEXPAND | wxLEFT | wxBOTTOM | wxRIGHT, 10);
ae80f837
VS
455 }
456
5229b11d
VS
457 m_ContentsBox = new wxTreeCtrl(dummy, wxID_HTML_TREECTRL,
458 wxDefaultPosition, wxDefaultSize,
8fbc9912 459#ifdef __WXGTK20__
dabbc6a5 460 wxSUNKEN_BORDER |
e0952648 461 wxTR_HAS_BUTTONS | wxTR_HIDE_ROOT |
8fbc9912
RR
462 wxTR_NO_LINES
463#else
464 wxSUNKEN_BORDER |
465 wxTR_HAS_BUTTONS | wxTR_HIDE_ROOT |
466 wxTR_LINES_AT_ROOT
467#endif
468 );
e0952648 469
5229b11d 470 m_ContentsBox->AssignImageList(ContentsImageList);
dabbc6a5 471
d49520c3 472 topsizer->Add(m_ContentsBox, 1,
395a82b1 473 wxEXPAND | wxLEFT | wxBOTTOM | wxRIGHT,
d49520c3 474 2);
ae80f837 475
5229b11d 476 m_NavigNotebook->AddPage(dummy, _("Contents"));
d5bb85a0 477 m_ContentsPage = notebook_page++;
8ec2b484
HH
478 }
479
480 // index listbox panel?
5229b11d 481 if ( style & wxHF_INDEX )
4f9297b0 482 {
dabbc6a5 483 wxWindow *dummy = new wxPanel(m_NavigNotebook, wxID_HTML_INDEXPAGE);
5229b11d
VS
484 wxSizer *topsizer = new wxBoxSizer(wxVERTICAL);
485
5229b11d
VS
486 dummy->SetSizer(topsizer);
487
dabbc6a5
DS
488 m_IndexText = new wxTextCtrl(dummy, wxID_HTML_INDEXTEXT, wxEmptyString,
489 wxDefaultPosition, wxDefaultSize,
5229b11d 490 wxTE_PROCESS_ENTER);
f0b6a33f 491 m_IndexButton = new wxButton(dummy, wxID_HTML_INDEXBUTTON, _("Find"));
dabbc6a5 492 m_IndexButtonAll = new wxButton(dummy, wxID_HTML_INDEXBUTTONALL,
5229b11d 493 _("Show all"));
dabbc6a5 494 m_IndexCountInfo = new wxStaticText(dummy, wxID_HTML_COUNTINFO,
5229b11d 495 wxEmptyString, wxDefaultPosition,
dabbc6a5 496 wxDefaultSize,
5229b11d 497 wxALIGN_RIGHT | wxST_NO_AUTORESIZE);
dabbc6a5
DS
498 m_IndexList = new wxListBox(dummy, wxID_HTML_INDEXLIST,
499 wxDefaultPosition, wxDefaultSize,
5229b11d 500 0, NULL, wxLB_SINGLE);
f0b6a33f 501
7618e374 502#if wxUSE_TOOLTIPS
4f9297b0 503 m_IndexButton->SetToolTip(_("Display all index items that contain given substring. Search is case insensitive."));
5229b11d 504 m_IndexButtonAll->SetToolTip(_("Show all items in index"));
7618e374
VS
505#endif //wxUSE_TOOLTIPS
506
5229b11d
VS
507 topsizer->Add(m_IndexText, 0, wxEXPAND | wxALL, 10);
508 wxSizer *btsizer = new wxBoxSizer(wxHORIZONTAL);
509 btsizer->Add(m_IndexButton, 0, wxRIGHT, 2);
510 btsizer->Add(m_IndexButtonAll);
dabbc6a5 511 topsizer->Add(btsizer, 0,
5229b11d
VS
512 wxALIGN_RIGHT | wxLEFT | wxRIGHT | wxBOTTOM, 10);
513 topsizer->Add(m_IndexCountInfo, 0, wxEXPAND | wxLEFT | wxRIGHT, 2);
395a82b1 514 topsizer->Add(m_IndexList, 1, wxEXPAND | wxALL, 2);
f0b6a33f 515
5229b11d 516 m_NavigNotebook->AddPage(dummy, _("Index"));
d5bb85a0 517 m_IndexPage = notebook_page++;
8ec2b484
HH
518 }
519
520 // search list panel?
5229b11d 521 if ( style & wxHF_SEARCH )
4f9297b0 522 {
dabbc6a5 523 wxWindow *dummy = new wxPanel(m_NavigNotebook, wxID_HTML_INDEXPAGE);
5229b11d 524 wxSizer *sizer = new wxBoxSizer(wxVERTICAL);
c4971147 525
5229b11d
VS
526 dummy->SetSizer(sizer);
527
dabbc6a5
DS
528 m_SearchText = new wxTextCtrl(dummy, wxID_HTML_SEARCHTEXT,
529 wxEmptyString,
530 wxDefaultPosition, wxDefaultSize,
5229b11d 531 wxTE_PROCESS_ENTER);
dabbc6a5 532 m_SearchChoice = new wxChoice(dummy, wxID_HTML_SEARCHCHOICE,
1afce1a8 533 wxDefaultPosition, wxSize(125,wxDefaultCoord));
dabbc6a5
DS
534 m_SearchCaseSensitive = new wxCheckBox(dummy, wxID_ANY, _("Case sensitive"));
535 m_SearchWholeWords = new wxCheckBox(dummy, wxID_ANY, _("Whole words only"));
ae80f837
VS
536 m_SearchButton = new wxButton(dummy, wxID_HTML_SEARCHBUTTON, _("Search"));
537#if wxUSE_TOOLTIPS
4f9297b0 538 m_SearchButton->SetToolTip(_("Search contents of help book(s) for all occurences of the text you typed above"));
ae80f837 539#endif //wxUSE_TOOLTIPS
dabbc6a5
DS
540 m_SearchList = new wxListBox(dummy, wxID_HTML_SEARCHLIST,
541 wxDefaultPosition, wxDefaultSize,
5229b11d 542 0, NULL, wxLB_SINGLE);
dabbc6a5 543
5229b11d
VS
544 sizer->Add(m_SearchText, 0, wxEXPAND | wxALL, 10);
545 sizer->Add(m_SearchChoice, 0, wxEXPAND | wxLEFT | wxRIGHT | wxBOTTOM, 10);
546 sizer->Add(m_SearchCaseSensitive, 0, wxLEFT | wxRIGHT, 10);
547 sizer->Add(m_SearchWholeWords, 0, wxLEFT | wxRIGHT, 10);
548 sizer->Add(m_SearchButton, 0, wxALL | wxALIGN_RIGHT, 8);
395a82b1 549 sizer->Add(m_SearchList, 1, wxALL | wxEXPAND, 2);
5229b11d
VS
550
551 m_NavigNotebook->AddPage(dummy, _("Search"));
999836aa 552 m_SearchPage = notebook_page;
8ec2b484 553 }
5229b11d 554
dabbc6a5 555 m_HtmlWin->Show();
f6bcfd97 556
b5a7b000 557 RefreshLists();
8ec2b484 558
5229b11d
VS
559 if ( navigSizer )
560 {
d49520c3 561 navigSizer->SetSizeHints(m_NavigPan);
5229b11d
VS
562 m_NavigPan->Layout();
563 }
564
8ec2b484 565 // showtime
5229b11d 566 if ( m_NavigPan && m_Splitter )
4f9297b0
VS
567 {
568 m_Splitter->SetMinimumPaneSize(20);
5229b11d 569 if ( m_Cfg.navig_on )
4f9297b0 570 m_Splitter->SplitVertically(m_NavigPan, m_HtmlWin, m_Cfg.sashpos);
4f9297b0 571
5229b11d 572 if ( m_Cfg.navig_on )
3379ed37 573 {
dabbc6a5 574 m_NavigPan->Show();
4f9297b0 575 m_Splitter->SplitVertically(m_NavigPan, m_HtmlWin, m_Cfg.sashpos);
c32bfc10 576 }
da4cc40c 577 else
3379ed37 578 {
dabbc6a5 579 m_NavigPan->Show(false);
4f9297b0 580 m_Splitter->Initialize(m_HtmlWin);
68364659 581 }
8ec2b484 582 }
dabbc6a5 583
7e521b01
JS
584 // Reduce flicker by updating the splitter pane sizes before the
585 // frame is shown
586 wxSizeEvent sizeEvent(GetSize(), GetId());
587 ProcessEvent(sizeEvent);
dabbc6a5 588
7e521b01 589 m_Splitter->UpdateSize();
dabbc6a5
DS
590
591 return true;
8ec2b484
HH
592}
593
594wxHtmlHelpFrame::~wxHtmlHelpFrame()
595{
418b7d6b 596 delete m_mergedIndex;
d1da8872 597
b4414c1f 598 // PopEventHandler(); // wxhtmlhelpcontroller (not any more!)
8ec2b484 599 if (m_DataCreated)
d5bb85a0 600 delete m_Data;
83efdf33
VS
601 if (m_NormalFonts) delete m_NormalFonts;
602 if (m_FixedFonts) delete m_FixedFonts;
dabbc6a5 603 if (m_PagesHash)
ba8c1601
MB
604 {
605 WX_CLEAR_HASH_TABLE(*m_PagesHash);
606 delete m_PagesHash;
607 }
6c24d95c
VS
608#if wxUSE_PRINTING_ARCHITECTURE
609 if (m_Printer) delete m_Printer;
610#endif
8ec2b484
HH
611}
612
b854b7b8 613
ee2f6a93 614#if wxUSE_TOOLBAR
b854b7b8
VS
615void wxHtmlHelpFrame::AddToolbarButtons(wxToolBar *toolBar, int style)
616{
dabbc6a5 617 wxBitmap wpanelBitmap =
61ba12f0 618 wxArtProvider::GetBitmap(wxART_HELP_SIDE_PANEL, wxART_TOOLBAR);
dabbc6a5 619 wxBitmap wbackBitmap =
61ba12f0 620 wxArtProvider::GetBitmap(wxART_GO_BACK, wxART_TOOLBAR);
dabbc6a5 621 wxBitmap wforwardBitmap =
61ba12f0 622 wxArtProvider::GetBitmap(wxART_GO_FORWARD, wxART_TOOLBAR);
dabbc6a5 623 wxBitmap wupnodeBitmap =
61ba12f0 624 wxArtProvider::GetBitmap(wxART_GO_TO_PARENT, wxART_TOOLBAR);
dabbc6a5 625 wxBitmap wupBitmap =
61ba12f0 626 wxArtProvider::GetBitmap(wxART_GO_UP, wxART_TOOLBAR);
dabbc6a5 627 wxBitmap wdownBitmap =
61ba12f0 628 wxArtProvider::GetBitmap(wxART_GO_DOWN, wxART_TOOLBAR);
dabbc6a5 629 wxBitmap wopenBitmap =
61ba12f0 630 wxArtProvider::GetBitmap(wxART_FILE_OPEN, wxART_TOOLBAR);
dabbc6a5 631 wxBitmap wprintBitmap =
61ba12f0 632 wxArtProvider::GetBitmap(wxART_PRINT, wxART_TOOLBAR);
dabbc6a5 633 wxBitmap woptionsBitmap =
61ba12f0 634 wxArtProvider::GetBitmap(wxART_HELP_SETTINGS, wxART_TOOLBAR);
f6bcfd97
BP
635
636 wxASSERT_MSG( (wpanelBitmap.Ok() && wbackBitmap.Ok() &&
637 wforwardBitmap.Ok() && wupnodeBitmap.Ok() &&
638 wupBitmap.Ok() && wdownBitmap.Ok() &&
639 wopenBitmap.Ok() && wprintBitmap.Ok() &&
640 woptionsBitmap.Ok()),
641 wxT("One or more HTML help frame toolbar bitmap could not be loaded.")) ;
642
643
4f9297b0 644 toolBar->AddTool(wxID_HTML_PANEL, wpanelBitmap, wxNullBitmap,
d1da8872 645 false, wxDefaultCoord, wxDefaultCoord, (wxObject *) NULL,
b854b7b8 646 _("Show/hide navigation panel"));
0646614d 647
4f9297b0
VS
648 toolBar->AddSeparator();
649 toolBar->AddTool(wxID_HTML_BACK, wbackBitmap, wxNullBitmap,
d1da8872 650 false, wxDefaultCoord, wxDefaultCoord, (wxObject *) NULL,
0646614d 651 _("Go back"));
4f9297b0 652 toolBar->AddTool(wxID_HTML_FORWARD, wforwardBitmap, wxNullBitmap,
d1da8872 653 false, wxDefaultCoord, wxDefaultCoord, (wxObject *) NULL,
0646614d 654 _("Go forward"));
4f9297b0 655 toolBar->AddSeparator();
b854b7b8 656
4f9297b0 657 toolBar->AddTool(wxID_HTML_UPNODE, wupnodeBitmap, wxNullBitmap,
d1da8872 658 false, wxDefaultCoord, wxDefaultCoord, (wxObject *) NULL,
0646614d 659 _("Go one level up in document hierarchy"));
4f9297b0 660 toolBar->AddTool(wxID_HTML_UP, wupBitmap, wxNullBitmap,
d1da8872 661 false, wxDefaultCoord, wxDefaultCoord, (wxObject *) NULL,
0646614d 662 _("Previous page"));
4f9297b0 663 toolBar->AddTool(wxID_HTML_DOWN, wdownBitmap, wxNullBitmap,
d1da8872 664 false, wxDefaultCoord, wxDefaultCoord, (wxObject *) NULL,
0646614d
VS
665 _("Next page"));
666
576507e2 667 if ((style & wxHF_PRINT) || (style & wxHF_OPEN_FILES))
4f9297b0 668 toolBar->AddSeparator();
f6bcfd97 669
576507e2 670 if (style & wxHF_OPEN_FILES)
4f9297b0 671 toolBar->AddTool(wxID_HTML_OPENFILE, wopenBitmap, wxNullBitmap,
d1da8872 672 false, wxDefaultCoord, wxDefaultCoord, (wxObject *) NULL,
0646614d
VS
673 _("Open HTML document"));
674
675#if wxUSE_PRINTING_ARCHITECTURE
676 if (style & wxHF_PRINT)
4f9297b0 677 toolBar->AddTool(wxID_HTML_PRINT, wprintBitmap, wxNullBitmap,
d1da8872 678 false, wxDefaultCoord, wxDefaultCoord, (wxObject *) NULL,
0646614d
VS
679 _("Print this page"));
680#endif
681
4f9297b0
VS
682 toolBar->AddSeparator();
683 toolBar->AddTool(wxID_HTML_OPTIONS, woptionsBitmap, wxNullBitmap,
d1da8872 684 false, wxDefaultCoord, wxDefaultCoord, (wxObject *) NULL,
b854b7b8
VS
685 _("Display options dialog"));
686}
ee2f6a93 687#endif //wxUSE_TOOLBAR
b854b7b8
VS
688
689
721ab905
VS
690void wxHtmlHelpFrame::SetTitleFormat(const wxString& format)
691{
692 if (m_HtmlWin)
693 m_HtmlWin->SetRelatedFrame(this, format);
694 m_TitleFormat = format;
695}
696
b854b7b8 697
8ec2b484
HH
698bool wxHtmlHelpFrame::Display(const wxString& x)
699{
700 wxString url = m_Data->FindPageByName(x);
baa17710 701 if (!url.empty())
4f9297b0 702 {
d5bb85a0 703 m_HtmlWin->LoadPage(url);
0646614d 704 NotifyPageChanged();
dabbc6a5 705 return true;
8ec2b484 706 }
dabbc6a5
DS
707
708 return false;
8ec2b484
HH
709}
710
711bool wxHtmlHelpFrame::Display(const int id)
712{
713 wxString url = m_Data->FindPageById(id);
baa17710 714 if (!url.empty())
4f9297b0 715 {
d5bb85a0 716 m_HtmlWin->LoadPage(url);
0646614d 717 NotifyPageChanged();
dabbc6a5 718 return true;
8ec2b484 719 }
dabbc6a5
DS
720
721 return false;
8ec2b484
HH
722}
723
724
725
726bool wxHtmlHelpFrame::DisplayContents()
727{
728 if (! m_ContentsBox)
dabbc6a5
DS
729 return false;
730
da4cc40c 731 if (!m_Splitter->IsSplit())
4f9297b0 732 {
dabbc6a5
DS
733 m_NavigPan->Show();
734 m_HtmlWin->Show();
4f9297b0 735 m_Splitter->SplitVertically(m_NavigPan, m_HtmlWin, m_Cfg.sashpos);
dabbc6a5 736 m_Cfg.navig_on = true;
8ec2b484 737 }
dabbc6a5 738
1afce1a8 739 m_NavigNotebook->SetSelection(m_ContentsPage);
dabbc6a5 740
71d04f7f
JS
741 if (m_Data->GetBookRecArray().GetCount() > 0)
742 {
743 wxHtmlBookRecord& book = m_Data->GetBookRecArray()[0];
baa17710 744 if (!book.GetStart().empty())
468ae730 745 m_HtmlWin->LoadPage(book.GetFullPath(book.GetStart()));
71d04f7f 746 }
dabbc6a5
DS
747
748 return true;
8ec2b484
HH
749}
750
751
752
753bool wxHtmlHelpFrame::DisplayIndex()
754{
f0b6a33f 755 if (! m_IndexList)
dabbc6a5
DS
756 return false;
757
da4cc40c 758 if (!m_Splitter->IsSplit())
4f9297b0 759 {
dabbc6a5
DS
760 m_NavigPan->Show();
761 m_HtmlWin->Show();
4f9297b0 762 m_Splitter->SplitVertically(m_NavigPan, m_HtmlWin, m_Cfg.sashpos);
8ec2b484 763 }
dabbc6a5 764
1afce1a8 765 m_NavigNotebook->SetSelection(m_IndexPage);
dabbc6a5 766
71d04f7f
JS
767 if (m_Data->GetBookRecArray().GetCount() > 0)
768 {
769 wxHtmlBookRecord& book = m_Data->GetBookRecArray()[0];
baa17710 770 if (!book.GetStart().empty())
468ae730 771 m_HtmlWin->LoadPage(book.GetFullPath(book.GetStart()));
71d04f7f 772 }
dabbc6a5
DS
773
774 return true;
8ec2b484 775}
020707bb 776
91fa114d
VS
777void wxHtmlHelpFrame::DisplayIndexItem(const wxHtmlHelpMergedIndexItem *it)
778{
779 if (it->items.size() == 1)
780 {
781 if (!it->items[0]->page.empty())
782 {
783 m_HtmlWin->LoadPage(it->items[0]->GetFullPath());
784 NotifyPageChanged();
785 }
786 }
787 else
788 {
789 wxBusyCursor busy_cursor;
8ec2b484 790
91fa114d
VS
791 // more pages associated with this index item -- let the user choose
792 // which one she/he wants from a list:
793 wxArrayString arr;
794 size_t len = it->items.size();
795 for (size_t i = 0; i < len; i++)
796 {
797 wxString page = it->items[i]->page;
798 // try to find page's title in contents:
799 const wxHtmlHelpDataItems& contents = m_Data->GetContentsArray();
800 size_t clen = contents.size();
801 for (size_t j = 0; j < clen; j++)
802 {
803 if (contents[j].page == page)
804 {
805 page = contents[j].name;
806 break;
807 }
808 }
809 arr.push_back(page);
810 }
811
812 wxSingleChoiceDialog dlg(this,
813 _("Please choose the page to display:"),
814 _("Help Topics"),
815 arr, NULL, wxCHOICEDLG_STYLE & ~wxCENTRE);
816 if (dlg.ShowModal() == wxID_OK)
817 {
818 m_HtmlWin->LoadPage(it->items[dlg.GetSelection()]->GetFullPath());
819 NotifyPageChanged();
820 }
821 }
822}
b854b7b8
VS
823
824
69b5cec2
VS
825bool wxHtmlHelpFrame::KeywordSearch(const wxString& keyword,
826 wxHelpSearchMode mode)
8ec2b484 827{
69b5cec2
VS
828 if (mode == wxHELP_SEARCH_ALL)
829 {
830 if ( !(m_SearchList &&
831 m_SearchButton && m_SearchText && m_SearchChoice) )
832 return false;
833 }
834 else if (mode == wxHELP_SEARCH_INDEX)
835 {
836 if ( !(m_IndexList &&
837 m_IndexButton && m_IndexButtonAll && m_IndexText) )
838 return false;
839 }
8ec2b484 840
69b5cec2 841 int foundcnt = 0;
8ec2b484
HH
842 wxString foundstr;
843 wxString book = wxEmptyString;
844
da4cc40c 845 if (!m_Splitter->IsSplit())
4f9297b0 846 {
dabbc6a5
DS
847 m_NavigPan->Show();
848 m_HtmlWin->Show();
4f9297b0 849 m_Splitter->SplitVertically(m_NavigPan, m_HtmlWin, m_Cfg.sashpos);
8ec2b484 850 }
8ec2b484 851
69b5cec2 852 if (mode == wxHELP_SEARCH_ALL)
4f9297b0 853 {
69b5cec2
VS
854 m_NavigNotebook->SetSelection(m_SearchPage);
855 m_SearchList->Clear();
856 m_SearchText->SetValue(keyword);
dabbc6a5 857 m_SearchButton->Disable();
69b5cec2
VS
858
859 if (m_SearchChoice->GetSelection() != 0)
860 book = m_SearchChoice->GetStringSelection();
861
862 wxHtmlSearchStatus status(m_Data, keyword,
863 m_SearchCaseSensitive->GetValue(),
864 m_SearchWholeWords->GetValue(),
865 book);
866
3511e024 867#if wxUSE_PROGRESSDLG
69b5cec2
VS
868 wxProgressDialog progress(_("Searching..."),
869 _("No matching page found yet"),
870 status.GetMaxIndex(), this,
871 wxPD_APP_MODAL | wxPD_CAN_ABORT | wxPD_AUTO_HIDE);
3511e024 872#endif
69b5cec2
VS
873
874 int curi;
875 while (status.IsActive())
3379ed37 876 {
69b5cec2 877 curi = status.GetCurIndex();
dabbc6a5 878 if (curi % 32 == 0
3511e024 879#if wxUSE_PROGRESSDLG
dabbc6a5 880 && !progress.Update(curi)
3511e024
WS
881#endif
882 )
69b5cec2
VS
883 break;
884 if (status.Search())
885 {
886 foundstr.Printf(_("Found %i matches"), ++foundcnt);
3511e024 887#if wxUSE_PROGRESSDLG
69b5cec2 888 progress.Update(status.GetCurIndex(), foundstr);
3511e024 889#endif
91fa114d 890 m_SearchList->Append(status.GetName(), (void*)status.GetCurItem());
69b5cec2 891 }
d5bb85a0 892 }
69b5cec2 893
dabbc6a5 894 m_SearchButton->Enable();
69b5cec2
VS
895 m_SearchText->SetSelection(0, keyword.Length());
896 m_SearchText->SetFocus();
897 }
898 else if (mode == wxHELP_SEARCH_INDEX)
899 {
900 m_NavigNotebook->SetSelection(m_IndexPage);
901 m_IndexList->Clear();
dabbc6a5
DS
902 m_IndexButton->Disable();
903 m_IndexButtonAll->Disable();
69b5cec2
VS
904 m_IndexText->SetValue(keyword);
905
906 wxCommandEvent dummy;
907 OnIndexFind(dummy); // what a hack...
dabbc6a5
DS
908 m_IndexButton->Enable();
909 m_IndexButtonAll->Enable();
69b5cec2 910 foundcnt = m_IndexList->GetCount();
8ec2b484
HH
911 }
912
da4cc40c 913 if (foundcnt)
4f9297b0 914 {
75d07c0a 915 switch ( mode )
69b5cec2 916 {
75d07c0a
VZ
917 default:
918 wxFAIL_MSG( _T("unknown help search mode") );
919 // fall back
920
921 case wxHELP_SEARCH_ALL:
91fa114d
VS
922 {
923 wxHtmlHelpDataItem *it =
924 (wxHtmlHelpDataItem*) m_SearchList->GetClientData(0);
925 if (it)
926 {
927 m_HtmlWin->LoadPage(it->GetFullPath());
928 NotifyPageChanged();
929 }
75d07c0a 930 break;
91fa114d 931 }
75d07c0a
VZ
932
933 case wxHELP_SEARCH_INDEX:
91fa114d 934 {
d1da8872 935 wxHtmlHelpMergedIndexItem* it =
91fa114d
VS
936 (wxHtmlHelpMergedIndexItem*) m_IndexList->GetClientData(0);
937 if (it)
938 DisplayIndexItem(it);
75d07c0a 939 break;
91fa114d 940 }
69b5cec2 941 }
75d07c0a 942
8ec2b484 943 }
75d07c0a
VZ
944
945 return foundcnt > 0;
8ec2b484
HH
946}
947
b5a7b000 948void wxHtmlHelpFrame::CreateContents()
8ec2b484
HH
949{
950 if (! m_ContentsBox)
d5bb85a0 951 return ;
8ec2b484 952
ba8c1601
MB
953 if (m_PagesHash)
954 {
955 WX_CLEAR_HASH_TABLE(*m_PagesHash);
956 delete m_PagesHash;
957 }
d1da8872 958
91fa114d 959 const wxHtmlHelpDataItems& contents = m_Data->GetContentsArray();
d1da8872 960
91fa114d 961 size_t cnt = contents.size();
8ec2b484 962
91fa114d 963 m_PagesHash = new wxHashTable(wxKEY_STRING, 2 * cnt);
d5bb85a0 964
576507e2 965 const int MAX_ROOTS = 64;
8ec2b484 966 wxTreeItemId roots[MAX_ROOTS];
576507e2 967 // VS: this array holds information about whether we've set item icon at
3103e8a9 968 // given level. This is necessary because m_Data has a flat structure
576507e2
VS
969 // and there's no way of recognizing if some item has subitems or not.
970 // We set the icon later: when we find an item with level=n, we know
3103e8a9 971 // that the last item with level=n-1 was afolder with subitems, so we
576507e2 972 // set its icon accordingly
3379ed37 973 bool imaged[MAX_ROOTS];
4f9297b0 974 m_ContentsBox->DeleteAllItems();
dabbc6a5 975
e0952648 976 roots[0] = m_ContentsBox->AddRoot(_("(Help)"));
dabbc6a5 977 imaged[0] = true;
8ec2b484 978
91fa114d 979 for (size_t i = 0; i < cnt; i++)
4f9297b0 980 {
91fa114d 981 wxHtmlHelpDataItem *it = &contents[i];
576507e2 982 // Handle books:
91fa114d 983 if (it->level == 0)
576507e2 984 {
e0952648
VS
985 if (m_hfStyle & wxHF_MERGE_BOOKS)
986 // VS: we don't want book nodes, books' content should
3103e8a9 987 // appear under tree's root. This line will create a "fake"
e0952648 988 // record about book node so that the rest of this look
3103e8a9 989 // will believe there really _is_ a book node and will
e0952648
VS
990 // behave correctly.
991 roots[1] = roots[0];
992 else
576507e2 993 {
e0952648 994 roots[1] = m_ContentsBox->AppendItem(roots[0],
91fa114d 995 it->name, IMG_Book, -1,
576507e2 996 new wxHtmlHelpTreeItemData(i));
dabbc6a5 997 m_ContentsBox->SetItemBold(roots[1], true);
576507e2 998 }
dabbc6a5 999 imaged[1] = true;
4f9297b0 1000 }
576507e2 1001 // ...and their contents:
3379ed37 1002 else
576507e2 1003 {
91fa114d
VS
1004 roots[it->level + 1] = m_ContentsBox->AppendItem(
1005 roots[it->level], it->name, IMG_Page,
576507e2 1006 -1, new wxHtmlHelpTreeItemData(i));
91fa114d 1007 imaged[it->level + 1] = false;
576507e2 1008 }
4f9297b0 1009
576507e2 1010 m_PagesHash->Put(it->GetFullPath(),
91fa114d 1011 new wxHtmlHelpHashData(i, roots[it->level + 1]));
576507e2 1012
3103e8a9 1013 // Set the icon for the node one level up in the hierarchy,
576507e2 1014 // unless already done (see comment above imaged[] declaration)
91fa114d 1015 if (!imaged[it->level])
3379ed37 1016 {
576507e2
VS
1017 int image = IMG_Folder;
1018 if (m_hfStyle & wxHF_ICONS_BOOK)
1019 image = IMG_Book;
1020 else if (m_hfStyle & wxHF_ICONS_BOOK_CHAPTER)
91fa114d
VS
1021 image = (it->level == 1) ? IMG_Book : IMG_Folder;
1022 m_ContentsBox->SetItemImage(roots[it->level], image);
1023 m_ContentsBox->SetItemImage(roots[it->level], image,
b5f6b52a 1024 wxTreeItemIcon_Selected);
91fa114d 1025 imaged[it->level] = true;
8ec2b484
HH
1026 }
1027 }
8ec2b484
HH
1028}
1029
1030
b5a7b000 1031void wxHtmlHelpFrame::CreateIndex()
8ec2b484 1032{
f0b6a33f 1033 if (! m_IndexList)
d5bb85a0 1034 return ;
8ec2b484 1035
f0b6a33f 1036 m_IndexList->Clear();
8ec2b484 1037
91fa114d 1038 size_t cnt = m_mergedIndex->size();
f6bcfd97 1039
240c2873 1040 wxString cnttext;
91fa114d
VS
1041 if (cnt > INDEX_IS_SMALL)
1042 cnttext.Printf(_("%i of %i"), 0, cnt);
1043 else
1044 cnttext.Printf(_("%i of %i"), cnt, cnt);
4f9297b0 1045 m_IndexCountInfo->SetLabel(cnttext);
91fa114d
VS
1046 if (cnt > INDEX_IS_SMALL)
1047 return;
8ec2b484 1048
91fa114d
VS
1049 for (size_t i = 0; i < cnt; i++)
1050 m_IndexList->Append((*m_mergedIndex)[i].name,
1051 (char*)(&(*m_mergedIndex)[i]));
8ec2b484
HH
1052}
1053
1054void wxHtmlHelpFrame::CreateSearch()
1055{
1056 if (! (m_SearchList && m_SearchChoice))
d5bb85a0 1057 return ;
4f9297b0
VS
1058 m_SearchList->Clear();
1059 m_SearchChoice->Clear();
1060 m_SearchChoice->Append(_("Search in all books"));
8ec2b484
HH
1061 const wxHtmlBookRecArray& bookrec = m_Data->GetBookRecArray();
1062 int i, cnt = bookrec.GetCount();
d5bb85a0
VS
1063 for (i = 0; i < cnt; i++)
1064 m_SearchChoice->Append(bookrec[i].GetTitle());
8ec2b484
HH
1065 m_SearchChoice->SetSelection(0);
1066}
1067
1068
b5a7b000 1069void wxHtmlHelpFrame::RefreshLists()
8ec2b484 1070{
91fa114d
VS
1071 // Update m_mergedIndex:
1072 UpdateMergedIndex();
1073 // Update the controls
b5a7b000
VS
1074 CreateContents();
1075 CreateIndex();
8ec2b484
HH
1076 CreateSearch();
1077}
1078
1079void wxHtmlHelpFrame::ReadCustomization(wxConfigBase *cfg, const wxString& path)
1080{
1081 wxString oldpath;
1082 wxString tmp;
1083
da4cc40c 1084 if (path != wxEmptyString)
4f9297b0
VS
1085 {
1086 oldpath = cfg->GetPath();
1087 cfg->SetPath(_T("/") + path);
8ec2b484
HH
1088 }
1089
4f9297b0
VS
1090 m_Cfg.navig_on = cfg->Read(wxT("hcNavigPanel"), m_Cfg.navig_on) != 0;
1091 m_Cfg.sashpos = cfg->Read(wxT("hcSashPos"), m_Cfg.sashpos);
1092 m_Cfg.x = cfg->Read(wxT("hcX"), m_Cfg.x);
1093 m_Cfg.y = cfg->Read(wxT("hcY"), m_Cfg.y);
1094 m_Cfg.w = cfg->Read(wxT("hcW"), m_Cfg.w);
1095 m_Cfg.h = cfg->Read(wxT("hcH"), m_Cfg.h);
8ec2b484 1096
4f9297b0
VS
1097 m_FixedFace = cfg->Read(wxT("hcFixedFace"), m_FixedFace);
1098 m_NormalFace = cfg->Read(wxT("hcNormalFace"), m_NormalFace);
c269cf62 1099 m_FontSize = cfg->Read(wxT("hcBaseFontSize"), m_FontSize);
83efdf33 1100
382e6efe
VS
1101 {
1102 int i;
1103 int cnt;
1104 wxString val, s;
f6bcfd97 1105
4f9297b0 1106 cnt = cfg->Read(wxT("hcBookmarksCnt"), 0L);
da4cc40c 1107 if (cnt != 0)
3379ed37 1108 {
382e6efe
VS
1109 m_BookmarksNames.Clear();
1110 m_BookmarksPages.Clear();
da4cc40c 1111 if (m_Bookmarks)
3379ed37 1112 {
4f9297b0
VS
1113 m_Bookmarks->Clear();
1114 m_Bookmarks->Append(_("(bookmarks)"));
382e6efe 1115 }
f6bcfd97 1116
da4cc40c 1117 for (i = 0; i < cnt; i++)
3379ed37 1118 {
0413cec5 1119 val.Printf(wxT("hcBookmark_%i"), i);
4f9297b0 1120 s = cfg->Read(val);
382e6efe 1121 m_BookmarksNames.Add(s);
4f9297b0 1122 if (m_Bookmarks) m_Bookmarks->Append(s);
0413cec5 1123 val.Printf(wxT("hcBookmark_%i_url"), i);
4f9297b0 1124 s = cfg->Read(val);
382e6efe
VS
1125 m_BookmarksPages.Add(s);
1126 }
1127 }
1128 }
1129
8ec2b484 1130 if (m_HtmlWin)
3e5296e7 1131 m_HtmlWin->ReadCustomization(cfg);
8ec2b484
HH
1132
1133 if (path != wxEmptyString)
4f9297b0 1134 cfg->SetPath(oldpath);
8ec2b484
HH
1135}
1136
1137void wxHtmlHelpFrame::WriteCustomization(wxConfigBase *cfg, const wxString& path)
1138{
1139 wxString oldpath;
1140 wxString tmp;
8ec2b484 1141
da4cc40c 1142 if (path != wxEmptyString)
4f9297b0
VS
1143 {
1144 oldpath = cfg->GetPath();
1145 cfg->SetPath(_T("/") + path);
8ec2b484
HH
1146 }
1147
4f9297b0
VS
1148 cfg->Write(wxT("hcNavigPanel"), m_Cfg.navig_on);
1149 cfg->Write(wxT("hcSashPos"), (long)m_Cfg.sashpos);
2b5f62a0
VZ
1150 if ( !IsIconized() )
1151 {
1152 // Don't write if iconized as this would make the window
1153 // disappear next time it is shown!
1154 cfg->Write(wxT("hcX"), (long)m_Cfg.x);
1155 cfg->Write(wxT("hcY"), (long)m_Cfg.y);
1156 cfg->Write(wxT("hcW"), (long)m_Cfg.w);
1157 cfg->Write(wxT("hcH"), (long)m_Cfg.h);
1158 }
4f9297b0
VS
1159 cfg->Write(wxT("hcFixedFace"), m_FixedFace);
1160 cfg->Write(wxT("hcNormalFace"), m_NormalFace);
c269cf62 1161 cfg->Write(wxT("hcBaseFontSize"), (long)m_FontSize);
4f9297b0 1162
da4cc40c 1163 if (m_Bookmarks)
4f9297b0 1164 {
382e6efe
VS
1165 int i;
1166 int cnt = m_BookmarksNames.GetCount();
1167 wxString val;
f6bcfd97 1168
4f9297b0 1169 cfg->Write(wxT("hcBookmarksCnt"), (long)cnt);
da4cc40c 1170 for (i = 0; i < cnt; i++)
3379ed37 1171 {
0413cec5 1172 val.Printf(wxT("hcBookmark_%i"), i);
4f9297b0 1173 cfg->Write(val, m_BookmarksNames[i]);
0413cec5 1174 val.Printf(wxT("hcBookmark_%i_url"), i);
4f9297b0 1175 cfg->Write(val, m_BookmarksPages[i]);
382e6efe
VS
1176 }
1177 }
8ec2b484
HH
1178
1179 if (m_HtmlWin)
3e5296e7 1180 m_HtmlWin->WriteCustomization(cfg);
8ec2b484
HH
1181
1182 if (path != wxEmptyString)
4f9297b0 1183 cfg->SetPath(oldpath);
8ec2b484
HH
1184}
1185
1186
83efdf33
VS
1187
1188
1189
fbfb8bcc 1190static void SetFontsToHtmlWin(wxHtmlWindow *win, const wxString& scalf, const wxString& fixf, int size)
83efdf33 1191{
c269cf62
VS
1192 int f_sizes[7];
1193 f_sizes[0] = int(size * 0.6);
1194 f_sizes[1] = int(size * 0.8);
1195 f_sizes[2] = size;
1196 f_sizes[3] = int(size * 1.2);
1197 f_sizes[4] = int(size * 1.4);
1198 f_sizes[5] = int(size * 1.6);
1199 f_sizes[6] = int(size * 1.8);
1200
1201 win->SetFonts(scalf, fixf, f_sizes);
83efdf33
VS
1202}
1203
1204
1205class wxHtmlHelpFrameOptionsDialog : public wxDialog
1206{
c269cf62
VS
1207public:
1208 wxComboBox *NormalFont, *FixedFont;
1209 wxSpinCtrl *FontSize;
1210 wxHtmlWindow *TestWin;
83efdf33 1211
dabbc6a5
DS
1212 wxHtmlHelpFrameOptionsDialog(wxWindow *parent)
1213 : wxDialog(parent, wxID_ANY, wxString(_("Help Browser Options")))
c269cf62
VS
1214 {
1215 wxBoxSizer *topsizer = new wxBoxSizer(wxVERTICAL);
1216 wxFlexGridSizer *sizer = new wxFlexGridSizer(2, 3, 2, 5);
1217
dabbc6a5
DS
1218 sizer->Add(new wxStaticText(this, wxID_ANY, _("Normal font:")));
1219 sizer->Add(new wxStaticText(this, wxID_ANY, _("Fixed font:")));
1220 sizer->Add(new wxStaticText(this, wxID_ANY, _("Font size:")));
c269cf62 1221
dabbc6a5 1222 sizer->Add(NormalFont = new wxComboBox(this, wxID_ANY, wxEmptyString, wxDefaultPosition,
d1da8872 1223 wxSize(200, wxDefaultCoord),
c269cf62
VS
1224 0, NULL, wxCB_DROPDOWN | wxCB_READONLY));
1225
dabbc6a5 1226 sizer->Add(FixedFont = new wxComboBox(this, wxID_ANY, wxEmptyString, wxDefaultPosition,
d1da8872 1227 wxSize(200, wxDefaultCoord),
c269cf62
VS
1228 0, NULL, wxCB_DROPDOWN | wxCB_READONLY));
1229
dabbc6a5 1230 sizer->Add(FontSize = new wxSpinCtrl(this, wxID_ANY));
c269cf62
VS
1231 FontSize->SetRange(2, 100);
1232
1233 topsizer->Add(sizer, 0, wxLEFT|wxRIGHT|wxTOP, 10);
1234
dabbc6a5 1235 topsizer->Add(new wxStaticText(this, wxID_ANY, _("Preview:")),
c269cf62 1236 0, wxLEFT | wxTOP, 10);
dabbc6a5 1237 topsizer->Add(TestWin = new wxHtmlWindow(this, wxID_ANY, wxDefaultPosition, wxSize(20, 150),
c269cf62
VS
1238 wxHW_SCROLLBAR_AUTO | wxSUNKEN_BORDER),
1239 1, wxEXPAND | wxLEFT|wxTOP|wxRIGHT, 10);
1240
1241 wxBoxSizer *sizer2 = new wxBoxSizer(wxHORIZONTAL);
1242 wxButton *ok;
5f7bcb48 1243 sizer2->Add(ok = new wxButton(this, wxID_OK), 0, wxALL, 10);
c269cf62 1244 ok->SetDefault();
5f7bcb48 1245 sizer2->Add(new wxButton(this, wxID_CANCEL), 0, wxALL, 10);
c269cf62
VS
1246 topsizer->Add(sizer2, 0, wxALIGN_RIGHT);
1247
c269cf62
VS
1248 SetSizer(topsizer);
1249 topsizer->Fit(this);
1250 Centre(wxBOTH);
1251 }
f6bcfd97 1252
83efdf33 1253
c269cf62
VS
1254 void UpdateTestWin()
1255 {
1256 wxBusyCursor bcur;
1257 SetFontsToHtmlWin(TestWin,
1258 NormalFont->GetStringSelection(),
1259 FixedFont->GetStringSelection(),
1260 FontSize->GetValue());
311ccb86
VZ
1261
1262 wxString content(_("font size"));
1263
1264 content = _T("<font size=-2>") + content + _T(" -2</font><br>")
1265 _T("<font size=-1>") + content + _T(" -1</font><br>")
1266 _T("<font size=+0>") + content + _T(" +0</font><br>")
1267 _T("<font size=+1>") + content + _T(" +1</font><br>")
1268 _T("<font size=+2>") + content + _T(" +2</font><br>")
1269 _T("<font size=+3>") + content + _T(" +3</font><br>")
1270 _T("<font size=+4>") + content + _T(" +4</font><br>") ;
1271
1272 content = wxString( _T("<html><body><table><tr><td>") ) +
1273 _("Normal face<br>and <u>underlined</u>. ") +
1274 _("<i>Italic face.</i> ") +
1275 _("<b>Bold face.</b> ") +
1276 _("<b><i>Bold italic face.</i></b><br>") +
1277 content +
1278 wxString( _T("</td><td><tt>") ) +
1279 _("Fixed size face.<br> <b>bold</b> <i>italic</i> ") +
1280 _("<b><i>bold italic <u>underlined</u></i></b><br>") +
1281 content +
1282 _T("</tt></td></tr></table></body></html>");
1283
1284 TestWin->SetPage( content );
c269cf62 1285 }
83efdf33 1286
c269cf62
VS
1287 void OnUpdate(wxCommandEvent& WXUNUSED(event))
1288 {
1289 UpdateTestWin();
1290 }
aab49a0b
JS
1291 void OnUpdateSpin(wxSpinEvent& WXUNUSED(event))
1292 {
1293 UpdateTestWin();
1294 }
83efdf33 1295
c269cf62 1296 DECLARE_EVENT_TABLE()
22f3361e 1297 DECLARE_NO_COPY_CLASS(wxHtmlHelpFrameOptionsDialog)
83efdf33
VS
1298};
1299
1300BEGIN_EVENT_TABLE(wxHtmlHelpFrameOptionsDialog, wxDialog)
dabbc6a5
DS
1301 EVT_COMBOBOX(wxID_ANY, wxHtmlHelpFrameOptionsDialog::OnUpdate)
1302 EVT_SPINCTRL(wxID_ANY, wxHtmlHelpFrameOptionsDialog::OnUpdateSpin)
83efdf33
VS
1303END_EVENT_TABLE()
1304
83efdf33
VS
1305void wxHtmlHelpFrame::OptionsDialog()
1306{
1307 wxHtmlHelpFrameOptionsDialog dlg(this);
1308 unsigned i;
f6bcfd97 1309
da4cc40c 1310 if (m_NormalFonts == NULL)
4f9297b0 1311 {
83efdf33
VS
1312 wxFontEnumerator enu;
1313 enu.EnumerateFacenames();
1314 m_NormalFonts = new wxArrayString;
1315 *m_NormalFonts = *enu.GetFacenames();
a2a03d78 1316 m_NormalFonts->Sort(); // ascending sort
83efdf33 1317 }
da4cc40c 1318 if (m_FixedFonts == NULL)
4f9297b0 1319 {
83efdf33 1320 wxFontEnumerator enu;
dabbc6a5 1321 enu.EnumerateFacenames(wxFONTENCODING_SYSTEM, true /*enum fixed width only*/);
83efdf33
VS
1322 m_FixedFonts = new wxArrayString;
1323 *m_FixedFonts = *enu.GetFacenames();
a2a03d78 1324 m_FixedFonts->Sort(); // ascending sort
83efdf33 1325 }
dabbc6a5 1326
c269cf62
VS
1327 // VS: We want to show the font that is actually used by wxHtmlWindow.
1328 // If customization dialog wasn't used yet, facenames are empty and
1329 // wxHtmlWindow uses default fonts -- let's find out what they
1330 // are so that we can pass them to the dialog:
1331 if (m_NormalFace.empty())
1332 {
dabbc6a5 1333 wxFont fnt(m_FontSize, wxSWISS, wxNORMAL, wxNORMAL, false);
c269cf62
VS
1334 m_NormalFace = fnt.GetFaceName();
1335 }
1336 if (m_FixedFace.empty())
1337 {
dabbc6a5 1338 wxFont fnt(m_FontSize, wxMODERN, wxNORMAL, wxNORMAL, false);
c269cf62
VS
1339 m_FixedFace = fnt.GetFaceName();
1340 }
f6bcfd97 1341
4f9297b0
VS
1342 for (i = 0; i < m_NormalFonts->GetCount(); i++)
1343 dlg.NormalFont->Append((*m_NormalFonts)[i]);
1344 for (i = 0; i < m_FixedFonts->GetCount(); i++)
1345 dlg.FixedFont->Append((*m_FixedFonts)[i]);
c269cf62
VS
1346 if (!m_NormalFace.empty())
1347 dlg.NormalFont->SetStringSelection(m_NormalFace);
1348 else
1affde0a 1349 dlg.NormalFont->SetSelection(0);
c269cf62
VS
1350 if (!m_FixedFace.empty())
1351 dlg.FixedFont->SetStringSelection(m_FixedFace);
1352 else
1353 dlg.FixedFont->SetSelection(0);
1354 dlg.FontSize->SetValue(m_FontSize);
83efdf33 1355 dlg.UpdateTestWin();
f6bcfd97 1356
da4cc40c 1357 if (dlg.ShowModal() == wxID_OK)
4f9297b0
VS
1358 {
1359 m_NormalFace = dlg.NormalFont->GetStringSelection();
1360 m_FixedFace = dlg.FixedFont->GetStringSelection();
c269cf62 1361 m_FontSize = dlg.FontSize->GetValue();
8eb2940f 1362 SetFontsToHtmlWin(m_HtmlWin, m_NormalFace, m_FixedFace, m_FontSize);
83efdf33
VS
1363 }
1364}
1365
1366
1367
0646614d
VS
1368void wxHtmlHelpFrame::NotifyPageChanged()
1369{
1370 if (m_UpdateContents && m_PagesHash)
1371 {
baa17710
WS
1372 wxString page = wxHtmlHelpHtmlWindow::GetOpenedPageWithAnchor(m_HtmlWin);
1373 wxHtmlHelpHashData *ha = NULL;
1374 if (!page.empty())
1375 ha = (wxHtmlHelpHashData*) m_PagesHash->Get(page);
1376
0646614d
VS
1377 if (ha)
1378 {
1379 bool olduc = m_UpdateContents;
dabbc6a5 1380 m_UpdateContents = false;
4f9297b0
VS
1381 m_ContentsBox->SelectItem(ha->m_Id);
1382 m_ContentsBox->EnsureVisible(ha->m_Id);
0646614d
VS
1383 m_UpdateContents = olduc;
1384 }
1385 }
1386}
1387
83efdf33
VS
1388
1389
8ec2b484
HH
1390/*
1391EVENT HANDLING :
1392*/
1393
1394
d45bc436
RR
1395void wxHtmlHelpFrame::OnActivate(wxActivateEvent& event)
1396{
1397 // This saves one mouse click when using the
1398 // wxHTML for context sensitive help systems
2b5f62a0
VZ
1399#ifndef __WXGTK__
1400 // NB: wxActivateEvent is a bit broken in wxGTK
1401 // and is sometimes sent when it should not be
d45bc436
RR
1402 if (event.GetActive() && m_HtmlWin)
1403 m_HtmlWin->SetFocus();
2b5f62a0 1404#endif
fbd90401
VS
1405
1406 event.Skip();
d45bc436
RR
1407}
1408
8ec2b484
HH
1409void wxHtmlHelpFrame::OnToolbar(wxCommandEvent& event)
1410{
da4cc40c 1411 switch (event.GetId())
4f9297b0 1412 {
8ec2b484 1413 case wxID_HTML_BACK :
4f9297b0 1414 m_HtmlWin->HistoryBack();
0646614d 1415 NotifyPageChanged();
8ec2b484 1416 break;
382e6efe 1417
8ec2b484 1418 case wxID_HTML_FORWARD :
4f9297b0 1419 m_HtmlWin->HistoryForward();
0646614d
VS
1420 NotifyPageChanged();
1421 break;
f6bcfd97
BP
1422
1423 case wxID_HTML_UP :
1424 if (m_PagesHash)
0646614d 1425 {
baa17710
WS
1426 wxString page = wxHtmlHelpHtmlWindow::GetOpenedPageWithAnchor(m_HtmlWin);
1427 wxHtmlHelpHashData *ha = NULL;
1428 if (!page.empty())
1429 ha = (wxHtmlHelpHashData*) m_PagesHash->Get(page);
4f9297b0 1430 if (ha && ha->m_Index > 0)
0646614d 1431 {
91fa114d
VS
1432 const wxHtmlHelpDataItem& it = m_Data->GetContentsArray()[ha->m_Index - 1];
1433 if (!it.page.empty())
7df9fbc3 1434 {
91fa114d 1435 m_HtmlWin->LoadPage(it.GetFullPath());
7df9fbc3
JS
1436 NotifyPageChanged();
1437 }
0646614d
VS
1438 }
1439 }
1440 break;
1441
f6bcfd97
BP
1442 case wxID_HTML_UPNODE :
1443 if (m_PagesHash)
0646614d 1444 {
baa17710
WS
1445 wxString page = wxHtmlHelpHtmlWindow::GetOpenedPageWithAnchor(m_HtmlWin);
1446 wxHtmlHelpHashData *ha = NULL;
1447 if (!page.empty())
1448 ha = (wxHtmlHelpHashData*) m_PagesHash->Get(page);
4f9297b0 1449 if (ha && ha->m_Index > 0)
0646614d 1450 {
d1da8872 1451 int level =
91fa114d 1452 m_Data->GetContentsArray()[ha->m_Index].level - 1;
4f9297b0 1453 int ind = ha->m_Index - 1;
f6bcfd97 1454
d1da8872 1455 const wxHtmlHelpDataItem *it =
91fa114d
VS
1456 &m_Data->GetContentsArray()[ind];
1457 while (ind >= 0 && it->level != level)
1458 {
e123fe41 1459 ind--;
91fa114d
VS
1460 it = &m_Data->GetContentsArray()[ind];
1461 }
0646614d
VS
1462 if (ind >= 0)
1463 {
91fa114d 1464 if (!it->page.empty())
7df9fbc3 1465 {
468ae730 1466 m_HtmlWin->LoadPage(it->GetFullPath());
7df9fbc3
JS
1467 NotifyPageChanged();
1468 }
0646614d
VS
1469 }
1470 }
1471 }
1472 break;
1473
f6bcfd97
BP
1474 case wxID_HTML_DOWN :
1475 if (m_PagesHash)
0646614d 1476 {
baa17710
WS
1477 wxString page = wxHtmlHelpHtmlWindow::GetOpenedPageWithAnchor(m_HtmlWin);
1478 wxHtmlHelpHashData *ha = NULL;
1479 if (!page.empty())
1480 ha = (wxHtmlHelpHashData*) m_PagesHash->Get(page);
0646614d 1481
91fa114d
VS
1482 const wxHtmlHelpDataItems& contents = m_Data->GetContentsArray();
1483 if (ha && ha->m_Index < (int)contents.size() - 1)
0646614d 1484 {
91fa114d 1485 size_t idx = ha->m_Index + 1;
f6bcfd97 1486
baa17710 1487 while (contents[idx].GetFullPath() == page) idx++;
7df9fbc3 1488
91fa114d 1489 if (!contents[idx].page.empty())
7df9fbc3 1490 {
91fa114d 1491 m_HtmlWin->LoadPage(contents[idx].GetFullPath());
7df9fbc3
JS
1492 NotifyPageChanged();
1493 }
0646614d
VS
1494 }
1495 }
8ec2b484 1496 break;
382e6efe 1497
8ec2b484 1498 case wxID_HTML_PANEL :
0646614d
VS
1499 {
1500 if (! (m_Splitter && m_NavigPan))
1501 return ;
da4cc40c 1502 if (m_Splitter->IsSplit())
3379ed37 1503 {
4f9297b0
VS
1504 m_Cfg.sashpos = m_Splitter->GetSashPosition();
1505 m_Splitter->Unsplit(m_NavigPan);
dabbc6a5 1506 m_Cfg.navig_on = false;
da4cc40c 1507 }
3379ed37
VZ
1508 else
1509 {
dabbc6a5
DS
1510 m_NavigPan->Show();
1511 m_HtmlWin->Show();
4f9297b0 1512 m_Splitter->SplitVertically(m_NavigPan, m_HtmlWin, m_Cfg.sashpos);
dabbc6a5 1513 m_Cfg.navig_on = true;
0646614d 1514 }
8ec2b484
HH
1515 }
1516 break;
382e6efe 1517
83efdf33
VS
1518 case wxID_HTML_OPTIONS :
1519 OptionsDialog();
1520 break;
f6bcfd97
BP
1521
1522 case wxID_HTML_BOOKMARKSADD :
382e6efe
VS
1523 {
1524 wxString item;
1525 wxString url;
f6bcfd97 1526
4f9297b0
VS
1527 item = m_HtmlWin->GetOpenedPageTitle();
1528 url = m_HtmlWin->GetOpenedPage();
da4cc40c 1529 if (item == wxEmptyString)
3379ed37 1530 item = url.AfterLast(wxT('/'));
da4cc40c 1531 if (m_BookmarksPages.Index(url) == wxNOT_FOUND)
3379ed37 1532 {
4f9297b0 1533 m_Bookmarks->Append(item);
382e6efe
VS
1534 m_BookmarksNames.Add(item);
1535 m_BookmarksPages.Add(url);
1536 }
1537 }
1538 break;
f6bcfd97
BP
1539
1540 case wxID_HTML_BOOKMARKSREMOVE :
382e6efe
VS
1541 {
1542 wxString item;
1543 int pos;
f6bcfd97 1544
4f9297b0 1545 item = m_Bookmarks->GetStringSelection();
382e6efe 1546 pos = m_BookmarksNames.Index(item);
da4cc40c 1547 if (pos != wxNOT_FOUND)
3379ed37 1548 {
ba8c1601
MB
1549 m_BookmarksNames.RemoveAt(pos);
1550 m_BookmarksPages.RemoveAt(pos);
4f9297b0 1551 m_Bookmarks->Delete(m_Bookmarks->GetSelection());
382e6efe
VS
1552 }
1553 }
1554 break;
0646614d
VS
1555
1556#if wxUSE_PRINTING_ARCHITECTURE
1557 case wxID_HTML_PRINT :
1558 {
f6bcfd97 1559 if (m_Printer == NULL)
0646614d 1560 m_Printer = new wxHtmlEasyPrinting(_("Help Printing"), this);
4f9297b0 1561 if (!m_HtmlWin->GetOpenedPage())
f5ba273e
VS
1562 wxLogWarning(_("Cannot print empty page."));
1563 else
4f9297b0 1564 m_Printer->PrintFile(m_HtmlWin->GetOpenedPage());
0646614d
VS
1565 }
1566 break;
1567#endif
1568
1569 case wxID_HTML_OPENFILE :
1570 {
3527f29c
VS
1571 wxString filemask = wxString(
1572 _("HTML files (*.html;*.htm)|*.html;*.htm|")) +
1573 _("Help books (*.htb)|*.htb|Help books (*.zip)|*.zip|") +
1574 _("HTML Help Project (*.hhp)|*.hhp|") +
1575#if wxUSE_LIBMSPACK
1576 _("Compressed HTML Help file (*.chm)|*.chm|") +
1577#endif
1578 _("All files (*.*)|*");
f6bcfd97
BP
1579 wxString s = wxFileSelector(_("Open HTML document"),
1580 wxEmptyString,
1581 wxEmptyString,
1582 wxEmptyString,
3527f29c 1583 filemask,
f6bcfd97
BP
1584 wxOPEN | wxFILE_MUST_EXIST,
1585 this);
baa17710 1586 if (!s.empty())
0646614d
VS
1587 {
1588 wxString ext = s.Right(4).Lower();
3527f29c
VS
1589 if (ext == _T(".zip") || ext == _T(".htb") ||
1590#if wxUSE_LIBMSPACK
1591 ext == _T(".chm") ||
1592#endif
1593 ext == _T(".hhp"))
0646614d
VS
1594 {
1595 wxBusyCursor bcur;
4f9297b0 1596 m_Data->AddBook(s);
0646614d
VS
1597 RefreshLists();
1598 }
1599 else
4f9297b0 1600 m_HtmlWin->LoadPage(s);
0646614d
VS
1601 }
1602 }
1603 break;
8ec2b484
HH
1604 }
1605}
1606
1607
1608
1609void wxHtmlHelpFrame::OnContentsSel(wxTreeEvent& event)
1610{
1611 wxHtmlHelpTreeItemData *pg;
1612
4f9297b0 1613 pg = (wxHtmlHelpTreeItemData*) m_ContentsBox->GetItemData(event.GetItem());
f6bcfd97
BP
1614
1615 if (pg && m_UpdateContents)
0646614d 1616 {
91fa114d 1617 const wxHtmlHelpDataItems& contents = m_Data->GetContentsArray();
dabbc6a5 1618 m_UpdateContents = false;
91fa114d
VS
1619 if (!contents[pg->m_Id].page.empty())
1620 m_HtmlWin->LoadPage(contents[pg->m_Id].GetFullPath());
dabbc6a5 1621 m_UpdateContents = true;
0646614d 1622 }
8ec2b484
HH
1623}
1624
1625
1626
a4c97004 1627void wxHtmlHelpFrame::OnIndexSel(wxCommandEvent& WXUNUSED(event))
8ec2b484 1628{
d1da8872 1629 wxHtmlHelpMergedIndexItem *it = (wxHtmlHelpMergedIndexItem*)
91fa114d
VS
1630 m_IndexList->GetClientData(m_IndexList->GetSelection());
1631 if (it)
1632 DisplayIndexItem(it);
8ec2b484
HH
1633}
1634
1635
f0b6a33f
VS
1636void wxHtmlHelpFrame::OnIndexFind(wxCommandEvent& event)
1637{
4f9297b0 1638 wxString sr = m_IndexText->GetLineText(0);
240c2873 1639 sr.MakeLower();
f6bcfd97 1640 if (sr == wxEmptyString)
4f9297b0 1641 {
f0b6a33f 1642 OnIndexAll(event);
4f9297b0 1643 }
da4cc40c 1644 else
4f9297b0 1645 {
f0b6a33f 1646 wxBusyCursor bcur;
f6bcfd97 1647
f0b6a33f 1648 m_IndexList->Clear();
91fa114d
VS
1649 const wxHtmlHelpMergedIndex& index = *m_mergedIndex;
1650 size_t cnt = index.size();
f0b6a33f 1651
240c2873 1652 int displ = 0;
91fa114d 1653 for (size_t i = 0; i < cnt; i++)
240c2873 1654 {
91fa114d 1655 if (index[i].name.Lower().find(sr) != wxString::npos)
3379ed37 1656 {
91fa114d
VS
1657 int pos = m_IndexList->Append(index[i].name,
1658 (char*)(&index[i]));
1659
1660 if (displ++ == 0)
3379ed37 1661 {
d8b5a517
VS
1662 // don't automatically show topic selector if this
1663 // item points to multiple pages:
1664 if (index[i].items.size() == 1)
1665 {
1666 m_IndexList->SetSelection(0);
1667 DisplayIndexItem(&index[i]);
1668 }
91fa114d
VS
1669 }
1670
1671 // if this is nested item of the index, show its parent(s)
1672 // as well, otherwise it would not be clear what entry is
1673 // shown:
1674 wxHtmlHelpMergedIndexItem *parent = index[i].parent;
1675 while (parent)
1676 {
d1da8872 1677 if (pos == 0 ||
91fa114d
VS
1678 (index.Index(*(wxHtmlHelpMergedIndexItem*)m_IndexList->GetClientData(pos-1))) < index.Index(*parent))
1679 {
1680 m_IndexList->Insert(parent->name,
1681 pos, (char*)parent);
1682 parent = parent->parent;
1683 }
1684 else break;
f0b6a33f 1685 }
1dfab6bb
VS
1686
1687 // finally, it the item we just added is itself a parent for
1688 // other items, show them as well, because they are refinements
1689 // of the displayed index entry (i.e. it is implicitly contained
1690 // in them: "foo" with parent "bar" reads as "bar, foo"):
42841dfc 1691 int level = index[i].items[0]->level;
1dfab6bb
VS
1692 i++;
1693 while (i < cnt && index[i].items[0]->level > level)
1694 {
1695 m_IndexList->Append(index[i].name, (char*)(&index[i]));
1696 i++;
1697 }
1698 i--;
f0b6a33f 1699 }
240c2873
VS
1700 }
1701
1702 wxString cnttext;
1703 cnttext.Printf(_("%i of %i"), displ, cnt);
4f9297b0 1704 m_IndexCountInfo->SetLabel(cnttext);
f0b6a33f 1705
4f9297b0
VS
1706 m_IndexText->SetSelection(0, sr.Length());
1707 m_IndexText->SetFocus();
f0b6a33f
VS
1708 }
1709}
1710
1711void wxHtmlHelpFrame::OnIndexAll(wxCommandEvent& WXUNUSED(event))
1712{
1713 wxBusyCursor bcur;
f6bcfd97 1714
f0b6a33f 1715 m_IndexList->Clear();
91fa114d
VS
1716 const wxHtmlHelpMergedIndex& index = *m_mergedIndex;
1717 size_t cnt = index.size();
dabbc6a5 1718 bool first = true;
f0b6a33f 1719
91fa114d 1720 for (size_t i = 0; i < cnt; i++)
4f9297b0 1721 {
91fa114d 1722 m_IndexList->Append(index[i].name, (char*)(&index[i]));
da4cc40c 1723 if (first)
3379ed37 1724 {
d8b5a517
VS
1725 // don't automatically show topic selector if this
1726 // item points to multiple pages:
1727 if (index[i].items.size() == 1)
1728 {
1729 DisplayIndexItem(&index[i]);
1730 }
dabbc6a5 1731 first = false;
f0b6a33f
VS
1732 }
1733 }
240c2873
VS
1734
1735 wxString cnttext;
1736 cnttext.Printf(_("%i of %i"), cnt, cnt);
4f9297b0 1737 m_IndexCountInfo->SetLabel(cnttext);
f0b6a33f
VS
1738}
1739
8ec2b484 1740
a4c97004 1741void wxHtmlHelpFrame::OnSearchSel(wxCommandEvent& WXUNUSED(event))
8ec2b484 1742{
91fa114d 1743 wxHtmlHelpDataItem *it = (wxHtmlHelpDataItem*) m_SearchList->GetClientData(m_SearchList->GetSelection());
f6bcfd97 1744 if (it)
0646614d 1745 {
91fa114d 1746 if (!it->page.empty())
468ae730 1747 m_HtmlWin->LoadPage(it->GetFullPath());
0646614d
VS
1748 NotifyPageChanged();
1749 }
8ec2b484
HH
1750}
1751
a4c97004 1752void wxHtmlHelpFrame::OnSearch(wxCommandEvent& WXUNUSED(event))
8ec2b484 1753{
4f9297b0 1754 wxString sr = m_SearchText->GetLineText(0);
8ec2b484 1755
69b5cec2
VS
1756 if (!sr.empty())
1757 KeywordSearch(sr, wxHELP_SEARCH_ALL);
8ec2b484
HH
1758}
1759
382e6efe
VS
1760void wxHtmlHelpFrame::OnBookmarksSel(wxCommandEvent& WXUNUSED(event))
1761{
4f9297b0 1762 wxString sr = m_Bookmarks->GetStringSelection();
382e6efe 1763
ae80f837 1764 if (sr != wxEmptyString && sr != _("(bookmarks)"))
0646614d 1765 {
4f9297b0 1766 m_HtmlWin->LoadPage(m_BookmarksPages[m_BookmarksNames.Index(sr)]);
0646614d
VS
1767 NotifyPageChanged();
1768 }
382e6efe
VS
1769}
1770
8ec2b484
HH
1771void wxHtmlHelpFrame::OnCloseWindow(wxCloseEvent& evt)
1772{
68364659
VS
1773 GetSize(&m_Cfg.w, &m_Cfg.h);
1774 GetPosition(&m_Cfg.x, &m_Cfg.y);
5c172c17 1775
5152b0e5
JS
1776#ifdef __WXGTK__
1777 if (IsGrabbed())
1778 {
1779 RemoveGrab();
1780 }
1781#endif
dabbc6a5 1782
4f9297b0 1783 if (m_Splitter && m_Cfg.navig_on) m_Cfg.sashpos = m_Splitter->GetSashPosition();
68364659 1784
d5bb85a0
VS
1785 if (m_Config)
1786 WriteCustomization(m_Config, m_ConfigRoot);
68364659 1787
b4414c1f
JS
1788 if (m_helpController && m_helpController->IsKindOf(CLASSINFO(wxHtmlHelpController)))
1789 {
1790 ((wxHtmlHelpController*) m_helpController)->OnCloseFrame(evt);
1791 }
1792
8ec2b484
HH
1793 evt.Skip();
1794}
1795
d9b21c9f 1796#ifdef __WXMAC__
4aa31786 1797void wxHtmlHelpFrame::OnClose(wxCommandEvent& event)
d9b21c9f 1798{
dabbc6a5 1799 Close(true);
d9b21c9f
JS
1800}
1801
1802void wxHtmlHelpFrame::OnAbout(wxCommandEvent& event)
1803{
91fa114d 1804 wxMessageBox(wxT("wxWidgets HTML Help Viewer (c) 1998-2004, Vaclav Slavik et al"), wxT("HelpView"),
d9b21c9f
JS
1805 wxICON_INFORMATION|wxOK, this);
1806}
1807#endif
1808
8ec2b484 1809BEGIN_EVENT_TABLE(wxHtmlHelpFrame, wxFrame)
d45bc436 1810 EVT_ACTIVATE(wxHtmlHelpFrame::OnActivate)
ae80f837
VS
1811 EVT_TOOL_RANGE(wxID_HTML_PANEL, wxID_HTML_OPTIONS, wxHtmlHelpFrame::OnToolbar)
1812 EVT_BUTTON(wxID_HTML_BOOKMARKSREMOVE, wxHtmlHelpFrame::OnToolbar)
1813 EVT_BUTTON(wxID_HTML_BOOKMARKSADD, wxHtmlHelpFrame::OnToolbar)
8ec2b484
HH
1814 EVT_TREE_SEL_CHANGED(wxID_HTML_TREECTRL, wxHtmlHelpFrame::OnContentsSel)
1815 EVT_LISTBOX(wxID_HTML_INDEXLIST, wxHtmlHelpFrame::OnIndexSel)
1816 EVT_LISTBOX(wxID_HTML_SEARCHLIST, wxHtmlHelpFrame::OnSearchSel)
1817 EVT_BUTTON(wxID_HTML_SEARCHBUTTON, wxHtmlHelpFrame::OnSearch)
1818 EVT_TEXT_ENTER(wxID_HTML_SEARCHTEXT, wxHtmlHelpFrame::OnSearch)
f0b6a33f
VS
1819 EVT_BUTTON(wxID_HTML_INDEXBUTTON, wxHtmlHelpFrame::OnIndexFind)
1820 EVT_TEXT_ENTER(wxID_HTML_INDEXTEXT, wxHtmlHelpFrame::OnIndexFind)
1821 EVT_BUTTON(wxID_HTML_INDEXBUTTONALL, wxHtmlHelpFrame::OnIndexAll)
382e6efe 1822 EVT_COMBOBOX(wxID_HTML_BOOKMARKSLIST, wxHtmlHelpFrame::OnBookmarksSel)
f6bcfd97 1823 EVT_CLOSE(wxHtmlHelpFrame::OnCloseWindow)
d9b21c9f 1824#ifdef __WXMAC__
4aa31786 1825 EVT_MENU(wxID_CLOSE, wxHtmlHelpFrame::OnClose)
d9b21c9f 1826 EVT_MENU(wxID_ABOUT, wxHtmlHelpFrame::OnAbout)
322a5b45 1827 EVT_MENU(wxID_HELP_CONTENTS, wxHtmlHelpFrame::OnAbout)
d9b21c9f
JS
1828#endif
1829
8ec2b484
HH
1830END_EVENT_TABLE()
1831
3379ed37 1832#endif // wxUSE_WXHTML_HELP