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