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