1. fixed wxGTK notebook which was completely broken by the merge
[wxWidgets.git] / src / html / helpfrm.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: helpfrm.cpp
3 // Purpose: wxHtmlHelpFrame
4 // Notes: Based on htmlhelp.cpp, implementing a monolithic
5 // HTML Help controller class, by Vaclav Slavik
6 // Author: Harm van der Heijden and Vaclav Slavik
7 // RCS-ID: $Id$
8 // Copyright: (c) Harm van der Heijden and Vaclav Slavik
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
11
12 #ifdef __GNUG__
13 #pragma implementation
14 #endif
15
16 // For compilers that support precompilation, includes "wx.h"
17
18 #include "wx/wxprec.h"
19
20 #ifdef __BORLANDC__
21 #pragma hdrstop
22 #endif
23
24 #if wxUSE_HTML && wxUSE_STREAMS
25
26 #ifndef WXPRECOMP
27 #include "wx/intl.h"
28 #include "wx/log.h"
29
30 #include "wx/object.h"
31 #include "wx/layout.h"
32 #include "wx/sizer.h"
33
34 #include "wx/bmpbuttn.h"
35 #include "wx/statbox.h"
36 #include "wx/radiobox.h"
37 #endif // WXPRECOMP
38
39 #include "wx/html/helpfrm.h"
40 #include "wx/html/helpctrl.h"
41 #include "wx/notebook.h"
42 #include "wx/imaglist.h"
43 #include "wx/treectrl.h"
44 #include "wx/tokenzr.h"
45 #include "wx/wfstream.h"
46 #include "wx/html/htmlwin.h"
47 #include "wx/busyinfo.h"
48 #include "wx/progdlg.h"
49 #include "wx/toolbar.h"
50 #include "wx/fontenum.h"
51 #include "wx/stream.h"
52 #include "wx/filedlg.h"
53
54 // Bitmaps:
55
56 #ifndef __WXMSW__
57 #include "bitmaps/wpanel.xpm"
58 #include "bitmaps/wback.xpm"
59 #include "bitmaps/wforward.xpm"
60 #include "bitmaps/wbook.xpm"
61 #include "bitmaps/woptions.xpm"
62 #include "bitmaps/wfolder.xpm"
63 #include "bitmaps/wpage.xpm"
64 #include "bitmaps/whelp.xpm"
65 #include "bitmaps/whlproot.xpm"
66 #include "bitmaps/wbkadd.xpm"
67 #include "bitmaps/wbkdel.xpm"
68 #include "bitmaps/wup.xpm"
69 #include "bitmaps/wupnode.xpm"
70 #include "bitmaps/wdown.xpm"
71 #include "bitmaps/wopen.xpm"
72 #include "bitmaps/wprint.xpm"
73 #endif
74
75
76 // what is considered "small index"?
77 #define INDEX_IS_SMALL 100
78
79
80 //--------------------------------------------------------------------------
81 // wxHtmlHelpTreeItemData (private)
82 //--------------------------------------------------------------------------
83
84 class wxHtmlHelpTreeItemData : public wxTreeItemData
85 {
86 public:
87 #if defined(__VISAGECPP__)
88 // VA needs a default ctor for some reason....
89 wxHtmlHelpTreeItemData() : wxTreeItemData()
90 { m_Id = 0; }
91 #endif
92 wxHtmlHelpTreeItemData(int id) : wxTreeItemData()
93 { m_Id = id;}
94
95 int m_Id;
96 };
97
98
99 //--------------------------------------------------------------------------
100 // wxHtmlHelpHashData (private)
101 //--------------------------------------------------------------------------
102
103 class wxHtmlHelpHashData : public wxObject
104 {
105 public:
106 wxHtmlHelpHashData(int index, wxTreeItemId id) : wxObject()
107 { m_Index = index; m_Id = id;}
108 ~wxHtmlHelpHashData() {}
109
110 int m_Index;
111 wxTreeItemId m_Id;
112 };
113
114
115 //--------------------------------------------------------------------------
116 // wxHtmlHelpHtmlWindow (private)
117 //--------------------------------------------------------------------------
118
119 class wxHtmlHelpHtmlWindow : public wxHtmlWindow
120 {
121 public:
122 wxHtmlHelpHtmlWindow(wxHtmlHelpFrame *fr, wxWindow *parent) : wxHtmlWindow(parent), m_Frame(fr) {}
123
124 virtual void OnLinkClicked(const wxHtmlLinkInfo& link)
125 {
126 wxHtmlWindow::OnLinkClicked(link);
127 m_Frame->NotifyPageChanged();
128 }
129
130 private:
131 wxHtmlHelpFrame *m_Frame;
132 };
133
134
135
136 //---------------------------------------------------------------------------
137 // wxHtmlHelpFrame
138 //---------------------------------------------------------------------------
139
140 // Command IDs :
141 enum
142 {
143 //wxID_HTML_HELPFRAME = wxID_HIGHEST + 1,
144 wxID_HTML_PANEL = wxID_HIGHEST + 2,
145 wxID_HTML_BACK,
146 wxID_HTML_FORWARD,
147 wxID_HTML_UPNODE,
148 wxID_HTML_UP,
149 wxID_HTML_DOWN,
150 wxID_HTML_PRINT,
151 wxID_HTML_OPENFILE,
152 wxID_HTML_OPTIONS,
153 wxID_HTML_BOOKMARKSLIST,
154 wxID_HTML_BOOKMARKSADD,
155 wxID_HTML_BOOKMARKSREMOVE,
156 wxID_HTML_TREECTRL,
157 wxID_HTML_INDEXPAGE,
158 wxID_HTML_INDEXLIST,
159 wxID_HTML_INDEXTEXT,
160 wxID_HTML_INDEXBUTTON,
161 wxID_HTML_INDEXBUTTONALL,
162 wxID_HTML_NOTEBOOK,
163 wxID_HTML_SEARCHPAGE,
164 wxID_HTML_SEARCHTEXT,
165 wxID_HTML_SEARCHLIST,
166 wxID_HTML_SEARCHBUTTON,
167 wxID_HTML_SEARCHCHOICE,
168 wxID_HTML_COUNTINFO
169 };
170
171
172 IMPLEMENT_DYNAMIC_CLASS(wxHtmlHelpFrame, wxFrame)
173
174 wxHtmlHelpFrame::wxHtmlHelpFrame(wxWindow* parent, wxWindowID id, const wxString& title,
175 int style, wxHtmlHelpData* data)
176 {
177 Init(data);
178 Create(parent, id, title, style);
179 }
180
181 void wxHtmlHelpFrame::Init(wxHtmlHelpData* data)
182 {
183 if (data)
184 {
185 m_Data = data;
186 m_DataCreated = FALSE;
187 } else
188 {
189 m_Data = new wxHtmlHelpData();
190 m_DataCreated = TRUE;
191 }
192
193 m_ContentsBox = NULL;
194 m_IndexList = NULL;
195 m_IndexButton = NULL;
196 m_IndexButtonAll = NULL;
197 m_IndexText = NULL;
198 m_SearchList = NULL;
199 m_SearchButton = NULL;
200 m_SearchText = NULL;
201 m_SearchChoice = NULL;
202 m_IndexCountInfo = NULL;
203 m_Splitter = NULL;
204 m_NavigPan = NULL;
205 m_HtmlWin = NULL;
206 m_Bookmarks = NULL;
207 m_SearchCaseSensitive = NULL;
208 m_SearchWholeWords = NULL;
209
210 m_Config = NULL;
211 m_ConfigRoot = wxEmptyString;
212
213 m_Cfg.x = m_Cfg.y = 0;
214 m_Cfg.w = 700;
215 m_Cfg.h = 480;
216 m_Cfg.sashpos = 240;
217 m_Cfg.navig_on = TRUE;
218
219 m_NormalFonts = m_FixedFonts = NULL;
220 m_NormalFace = m_FixedFace = wxEmptyString;
221 m_FontSize = 1;
222
223 #if wxUSE_PRINTING_ARCHITECTURE
224 m_Printer = NULL;
225 #endif
226
227 m_PagesHash = NULL;
228 m_UpdateContents = TRUE;
229 m_helpController = (wxHelpControllerBase*) NULL;
230 }
231
232 // Create: builds the GUI components.
233 // with the style flag it's possible to toggle the toolbar, contents, index and search
234 // controls.
235 // m_HtmlWin will *always* be created, but it's important to realize that
236 // m_ContentsBox, m_IndexList, m_SearchList, m_SearchButton, m_SearchText and
237 // m_SearchButton may be NULL.
238 // moreover, if no contents, index or searchpage is needed, m_Splitter and
239 // m_NavigPan will be NULL too (with m_HtmlWin directly connected to the frame)
240
241 bool wxHtmlHelpFrame::Create(wxWindow* parent, wxWindowID id,
242 const wxString& WXUNUSED(title), int style)
243 {
244 m_hfStyle = style;
245
246 wxImageList *ContentsImageList = new wxImageList(16, 16);
247 ContentsImageList->Add(wxICON(wbook));
248 ContentsImageList->Add(wxICON(wfolder));
249 ContentsImageList->Add(wxICON(wpage));
250 ContentsImageList->Add(wxICON(whlproot));
251
252 // Do the config in two steps. We read the HtmlWindow customization after we
253 // create the window.
254 if (m_Config)
255 ReadCustomization(m_Config, m_ConfigRoot);
256
257 wxFrame::Create(parent, id, _("Help"), wxPoint(m_Cfg.x, m_Cfg.y), wxSize(m_Cfg.w, m_Cfg.h), wxDEFAULT_FRAME_STYLE, "wxHtmlHelp");
258
259 GetPosition(&m_Cfg.x, &m_Cfg.y);
260
261 SetIcon(wxICON(whelp));
262
263 int notebook_page = 0;
264
265 CreateStatusBar();
266
267 // toolbar?
268 if (style & (wxHF_TOOLBAR | wxHF_FLAT_TOOLBAR))
269 {
270 wxToolBar *toolBar = CreateToolBar(wxNO_BORDER | wxTB_HORIZONTAL |
271 wxTB_DOCKABLE |
272 (style & wxHF_FLAT_TOOLBAR ? wxTB_FLAT : 0));
273 toolBar->SetMargins( 2, 2 );
274 AddToolbarButtons(toolBar, style);
275 toolBar->Realize();
276 }
277
278 if (style & (wxHF_CONTENTS | wxHF_INDEX | wxHF_SEARCH))
279 {
280 // traditional help controller; splitter window with html page on the
281 // right and a notebook containing various pages on the left
282 m_Splitter = new wxSplitterWindow(this);
283
284 m_HtmlWin = new wxHtmlHelpHtmlWindow(this, m_Splitter);
285 m_NavigPan = new wxNotebook(m_Splitter, wxID_HTML_NOTEBOOK,
286 wxDefaultPosition, wxDefaultSize);
287 }
288 else
289 { // only html window, no notebook with index,contents etc
290 m_HtmlWin = new wxHtmlWindow(this);
291 }
292
293 m_HtmlWin->SetRelatedFrame(this, m_TitleFormat);
294 m_HtmlWin->SetRelatedStatusBar(0);
295 if (m_Config)
296 m_HtmlWin->ReadCustomization(m_Config, m_ConfigRoot);
297
298 // contents tree panel?
299 if (style & wxHF_CONTENTS)
300 {
301 wxWindow *dummy = new wxPanel(m_NavigPan, wxID_HTML_INDEXPAGE);
302
303 if (style & wxHF_BOOKMARKS)
304 {
305 wxLayoutConstraints *b1 = new wxLayoutConstraints;
306 wxBitmapButton *bmpbt = new wxBitmapButton(dummy, wxID_HTML_BOOKMARKSREMOVE, wxBITMAP(wbkdel), wxDefaultPosition, wxSize(20,20));
307
308 b1->top.SameAs (dummy, wxTop, 10);
309 b1->right.SameAs (dummy, wxRight, 10);
310 b1->height.AsIs();
311 b1->width.AsIs();
312 bmpbt->SetConstraints(b1);
313
314 wxLayoutConstraints *b2 = new wxLayoutConstraints;
315 wxBitmapButton *bmpbt2 = new wxBitmapButton(dummy, wxID_HTML_BOOKMARKSADD, wxBITMAP(wbkadd), wxDefaultPosition, wxSize(20,20));
316
317 b2->top.SameAs (dummy, wxTop, 10);
318 b2->right.LeftOf (bmpbt, 2);
319 b2->height.AsIs();
320 b2->width.AsIs();
321 bmpbt2->SetConstraints(b2);
322
323 #if wxUSE_TOOLTIPS
324 bmpbt->SetToolTip(_("Remove current page from bookmarks"));
325 bmpbt2->SetToolTip(_("Add current page to bookmarks"));
326 #endif //wxUSE_TOOLTIPS
327
328 wxLayoutConstraints *b3 = new wxLayoutConstraints;
329 m_Bookmarks = new wxComboBox(dummy, wxID_HTML_BOOKMARKSLIST, wxEmptyString,
330 wxDefaultPosition, wxDefaultSize, 0, NULL, wxCB_READONLY | wxCB_SORT);
331 m_Bookmarks->Append(_("(bookmarks)"));
332 for (unsigned i = 0; i < m_BookmarksNames.GetCount(); i++)
333 m_Bookmarks->Append(m_BookmarksNames[i]);
334 m_Bookmarks->SetSelection(0);
335
336 b3->centreY.SameAs (bmpbt2, wxCentreY);
337 b3->left.SameAs (dummy, wxLeft, 10);
338 b3->right.LeftOf (bmpbt2, 5);
339 b3->height.AsIs();
340 m_Bookmarks->SetConstraints(b3);
341
342
343 wxLayoutConstraints *b4 = new wxLayoutConstraints;
344 m_ContentsBox = new wxTreeCtrl(dummy, wxID_HTML_TREECTRL,
345 wxDefaultPosition, wxDefaultSize,
346 wxTR_HAS_BUTTONS | wxSUNKEN_BORDER);
347 m_ContentsBox->AssignImageList(ContentsImageList);
348
349 b4->top.Below (m_Bookmarks, 10);
350 b4->left.SameAs (dummy, wxLeft, 0);
351 b4->right.SameAs (dummy, wxRight, 0);
352 b4->bottom.SameAs (dummy, wxBottom, 0);
353 m_ContentsBox->SetConstraints(b4);
354
355 dummy->SetAutoLayout(TRUE);
356 dummy->Layout();
357
358 m_NavigPan->AddPage(dummy, _("Contents"));
359 }
360
361 else
362 {
363 m_ContentsBox = new wxTreeCtrl(m_NavigPan, wxID_HTML_TREECTRL,
364 wxDefaultPosition, wxDefaultSize,
365 wxTR_HAS_BUTTONS | wxSUNKEN_BORDER);
366 m_ContentsBox->AssignImageList(ContentsImageList);
367 m_NavigPan->AddPage(m_ContentsBox, _("Contents"));
368 }
369
370 m_ContentsPage = notebook_page++;
371 }
372
373 // index listbox panel?
374 if (style & wxHF_INDEX)
375 {
376 wxWindow *dummy = new wxPanel(m_NavigPan, wxID_HTML_INDEXPAGE);
377
378 wxLayoutConstraints *b1 = new wxLayoutConstraints;
379 m_IndexText = new wxTextCtrl(dummy, wxID_HTML_INDEXTEXT, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_PROCESS_ENTER);
380 b1->top.SameAs (dummy, wxTop, 10);
381 b1->left.SameAs (dummy, wxLeft, 10);
382 b1->right.SameAs (dummy, wxRight, 10);
383 b1->height.AsIs();
384 m_IndexText->SetConstraints(b1);
385
386 wxLayoutConstraints *b4 = new wxLayoutConstraints;
387 m_IndexButtonAll = new wxButton(dummy, wxID_HTML_INDEXBUTTONALL, _("Show all"));
388
389 b4->top.Below (m_IndexText, 10);
390 b4->right.SameAs (dummy, wxRight, 10);
391 b4->width.AsIs();
392 b4->height.AsIs();
393 m_IndexButtonAll->SetConstraints(b4);
394
395 wxLayoutConstraints *b2 = new wxLayoutConstraints;
396 m_IndexButton = new wxButton(dummy, wxID_HTML_INDEXBUTTON, _("Find"));
397 b2->top.Below (m_IndexText, 10);
398 b2->right.LeftOf (m_IndexButtonAll, 10);
399 b2->width.AsIs();
400 b2->height.AsIs();
401 m_IndexButton->SetConstraints(b2);
402
403 wxLayoutConstraints *b5 = new wxLayoutConstraints;
404 m_IndexCountInfo = new wxStaticText(dummy, wxID_HTML_COUNTINFO, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxALIGN_RIGHT | wxST_NO_AUTORESIZE);
405
406 b5->top.Below (m_IndexButton, 5);
407 b5->right.SameAs (dummy, wxRight, 10);
408 b5->left.SameAs (dummy, wxLeft, 10);
409 b5->height.AsIs();
410 m_IndexCountInfo->SetConstraints(b5);
411
412 wxLayoutConstraints *b3 = new wxLayoutConstraints;
413 m_IndexList = new wxListBox(dummy, wxID_HTML_INDEXLIST, wxDefaultPosition, wxDefaultSize, 0, NULL, wxLB_SINGLE);
414 b3->top.Below (m_IndexCountInfo, 5);
415 b3->left.SameAs (dummy, wxLeft, 0);
416 b3->right.SameAs (dummy, wxRight, 0);
417 b3->bottom.SameAs (dummy, wxBottom, 0);
418 m_IndexList->SetConstraints(b3);
419
420 #if wxUSE_TOOLTIPS
421 m_IndexButtonAll->SetToolTip(_("Show all items in index"));
422 m_IndexButton->SetToolTip(_("Display all index items that contain given substring. Search is case insensitive."));
423 #endif //wxUSE_TOOLTIPS
424
425 dummy->SetAutoLayout(TRUE);
426 dummy->Layout();
427
428 m_NavigPan->AddPage(dummy, _("Index"));
429 m_IndexPage = notebook_page++;
430 }
431
432 // search list panel?
433 if (style & wxHF_SEARCH)
434 {
435 wxWindow *dummy = new wxPanel(m_NavigPan, wxID_HTML_SEARCHPAGE);
436
437 wxLayoutConstraints *b1 = new wxLayoutConstraints;
438 m_SearchText = new wxTextCtrl(dummy, wxID_HTML_SEARCHTEXT, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_PROCESS_ENTER);
439 b1->top.SameAs (dummy, wxTop, 10);
440 b1->left.SameAs (dummy, wxLeft, 10);
441 b1->right.SameAs (dummy, wxRight, 10);
442 b1->height.AsIs();
443 m_SearchText->SetConstraints(b1);
444
445 wxLayoutConstraints *b4 = new wxLayoutConstraints;
446 m_SearchChoice = new wxChoice(dummy, wxID_HTML_SEARCHCHOICE, wxDefaultPosition,
447 wxDefaultSize);
448 b4->top.Below (m_SearchText, 10);
449 b4->left.SameAs (dummy, wxLeft, 10);
450 b4->right.SameAs (dummy, wxRight, 10);
451 b4->height.AsIs();
452 m_SearchChoice->SetConstraints(b4);
453
454 wxLayoutConstraints *b5 = new wxLayoutConstraints;
455 m_SearchCaseSensitive = new wxCheckBox(dummy, -1, _("Case sensitive"));
456 b5->top.Below (m_SearchChoice, 10);
457 b5->left.SameAs (dummy, wxLeft, 10);
458 b5->width.AsIs();
459 b5->height.AsIs ();
460 m_SearchCaseSensitive->SetConstraints(b5);
461
462 wxLayoutConstraints *b6 = new wxLayoutConstraints;
463 m_SearchWholeWords = new wxCheckBox(dummy, -1, _("Whole words only"));
464 b6->top.Below (m_SearchCaseSensitive, 0);
465 b6->left.SameAs (dummy, wxLeft, 10);
466 b6->width.AsIs();
467 b6->height.AsIs ();
468 m_SearchWholeWords->SetConstraints(b6);
469
470 wxLayoutConstraints *b2 = new wxLayoutConstraints;
471 m_SearchButton = new wxButton(dummy, wxID_HTML_SEARCHBUTTON, _("Search"));
472 #if wxUSE_TOOLTIPS
473 m_SearchButton->SetToolTip(_("Search contents of help book(s) for all occurences of the text you typed above"));
474 #endif //wxUSE_TOOLTIPS
475 b2->top.Below (m_SearchWholeWords, 0);
476 b2->right.SameAs (dummy, wxRight, 10);
477 b2->width.AsIs();
478 b2->height.AsIs();
479 m_SearchButton->SetConstraints(b2);
480
481 wxLayoutConstraints *b3 = new wxLayoutConstraints;
482 m_SearchList = new wxListBox(dummy, wxID_HTML_SEARCHLIST, wxDefaultPosition, wxDefaultSize, 0, NULL, wxLB_SINGLE);
483 b3->top.Below (m_SearchButton, 10);
484 b3->left.SameAs (dummy, wxLeft, 0);
485 b3->right.SameAs (dummy, wxRight, 0);
486 b3->bottom.SameAs (dummy, wxBottom, 0);
487 m_SearchList->SetConstraints(b3);
488
489 dummy->SetAutoLayout(TRUE);
490 dummy->Layout();
491 m_NavigPan->AddPage(dummy, _("Search"));
492 m_SearchPage = notebook_page++;
493 }
494 m_HtmlWin->Show(TRUE);
495
496 RefreshLists();
497
498 // showtime
499 if (m_NavigPan && m_Splitter)
500 {
501 m_Splitter->SetMinimumPaneSize(20);
502 if (m_Cfg.navig_on)
503 m_Splitter->SplitVertically(m_NavigPan, m_HtmlWin, m_Cfg.sashpos);
504 else
505 {
506 m_Splitter->SplitVertically(m_NavigPan, m_HtmlWin, m_Cfg.sashpos);
507 m_Splitter->Unsplit();
508 }
509
510 if (m_Cfg.navig_on)
511 {
512 m_NavigPan->Show(TRUE);
513 m_Splitter->SplitVertically(m_NavigPan, m_HtmlWin, m_Cfg.sashpos);
514 }
515 else
516 {
517 m_NavigPan->Show(FALSE);
518 m_Splitter->Initialize(m_HtmlWin);
519 }
520 }
521 return TRUE;
522 }
523
524 wxHtmlHelpFrame::~wxHtmlHelpFrame()
525 {
526 // PopEventHandler(); // wxhtmlhelpcontroller (not any more!)
527 if (m_DataCreated)
528 delete m_Data;
529 if (m_NormalFonts) delete m_NormalFonts;
530 if (m_FixedFonts) delete m_FixedFonts;
531 if (m_PagesHash) delete m_PagesHash;
532 }
533
534
535 void wxHtmlHelpFrame::AddToolbarButtons(wxToolBar *toolBar, int style)
536 {
537 wxBitmap wpanelBitmap = wxBITMAP(wpanel);
538 wxBitmap wbackBitmap = wxBITMAP(wback);
539 wxBitmap wforwardBitmap = wxBITMAP(wforward);
540 wxBitmap wupnodeBitmap = wxBITMAP(wupnode);
541 wxBitmap wupBitmap = wxBITMAP(wup);
542 wxBitmap wdownBitmap = wxBITMAP(wdown);
543 wxBitmap wopenBitmap = wxBITMAP(wopen);
544 wxBitmap wprintBitmap = wxBITMAP(wprint);
545 wxBitmap woptionsBitmap = wxBITMAP(woptions);
546
547 wxASSERT_MSG( (wpanelBitmap.Ok() && wbackBitmap.Ok() &&
548 wforwardBitmap.Ok() && wupnodeBitmap.Ok() &&
549 wupBitmap.Ok() && wdownBitmap.Ok() &&
550 wopenBitmap.Ok() && wprintBitmap.Ok() &&
551 woptionsBitmap.Ok()),
552 wxT("One or more HTML help frame toolbar bitmap could not be loaded.")) ;
553
554
555 toolBar->AddTool(wxID_HTML_PANEL, wpanelBitmap, wxNullBitmap,
556 FALSE, -1, -1, (wxObject *) NULL,
557 _("Show/hide navigation panel"));
558
559 toolBar->AddSeparator();
560 toolBar->AddTool(wxID_HTML_BACK, wbackBitmap, wxNullBitmap,
561 FALSE, -1, -1, (wxObject *) NULL,
562 _("Go back"));
563 toolBar->AddTool(wxID_HTML_FORWARD, wforwardBitmap, wxNullBitmap,
564 FALSE, -1, -1, (wxObject *) NULL,
565 _("Go forward"));
566 toolBar->AddSeparator();
567
568 toolBar->AddTool(wxID_HTML_UPNODE, wupnodeBitmap, wxNullBitmap,
569 FALSE, -1, -1, (wxObject *) NULL,
570 _("Go one level up in document hierarchy"));
571 toolBar->AddTool(wxID_HTML_UP, wupBitmap, wxNullBitmap,
572 FALSE, -1, -1, (wxObject *) NULL,
573 _("Previous page"));
574 toolBar->AddTool(wxID_HTML_DOWN, wdownBitmap, wxNullBitmap,
575 FALSE, -1, -1, (wxObject *) NULL,
576 _("Next page"));
577
578 if ((style & wxHF_PRINT) || (style & wxHF_OPEN_FILES))
579 toolBar->AddSeparator();
580
581 if (style & wxHF_OPEN_FILES)
582 toolBar->AddTool(wxID_HTML_OPENFILE, wopenBitmap, wxNullBitmap,
583 FALSE, -1, -1, (wxObject *) NULL,
584 _("Open HTML document"));
585
586 #if wxUSE_PRINTING_ARCHITECTURE
587 if (style & wxHF_PRINT)
588 toolBar->AddTool(wxID_HTML_PRINT, wprintBitmap, wxNullBitmap,
589 FALSE, -1, -1, (wxObject *) NULL,
590 _("Print this page"));
591 #endif
592
593 toolBar->AddSeparator();
594 toolBar->AddTool(wxID_HTML_OPTIONS, woptionsBitmap, wxNullBitmap,
595 FALSE, -1, -1, (wxObject *) NULL,
596 _("Display options dialog"));
597 }
598
599
600 void wxHtmlHelpFrame::SetTitleFormat(const wxString& format)
601 {
602 if (m_HtmlWin)
603 m_HtmlWin->SetRelatedFrame(this, format);
604 m_TitleFormat = format;
605 }
606
607
608 bool wxHtmlHelpFrame::Display(const wxString& x)
609 {
610 wxString url = m_Data->FindPageByName(x);
611 if (!url.IsEmpty())
612 {
613 m_HtmlWin->LoadPage(url);
614 NotifyPageChanged();
615 return TRUE;
616 }
617 return FALSE;
618 }
619
620 bool wxHtmlHelpFrame::Display(const int id)
621 {
622 wxString url = m_Data->FindPageById(id);
623 if (!url.IsEmpty())
624 {
625 m_HtmlWin->LoadPage(url);
626 NotifyPageChanged();
627 return TRUE;
628 }
629 return FALSE;
630 }
631
632
633
634 bool wxHtmlHelpFrame::DisplayContents()
635 {
636 if (! m_ContentsBox)
637 return FALSE;
638 if (!m_Splitter->IsSplit())
639 {
640 m_NavigPan->Show(TRUE);
641 m_HtmlWin->Show(TRUE);
642 m_Splitter->SplitVertically(m_NavigPan, m_HtmlWin, m_Cfg.sashpos);
643 m_Cfg.navig_on = TRUE;
644 }
645 m_NavigPan->SetSelection(0);
646 if (m_Data->GetBookRecArray().GetCount() > 0)
647 {
648 wxHtmlBookRecord& book = m_Data->GetBookRecArray()[0];
649 if (!book.GetStart().IsEmpty())
650 m_HtmlWin->LoadPage(book.GetFullPath(book.GetStart()));
651 }
652 return TRUE;
653 }
654
655
656
657 bool wxHtmlHelpFrame::DisplayIndex()
658 {
659 if (! m_IndexList)
660 return FALSE;
661 if (!m_Splitter->IsSplit())
662 {
663 m_NavigPan->Show(TRUE);
664 m_HtmlWin->Show(TRUE);
665 m_Splitter->SplitVertically(m_NavigPan, m_HtmlWin, m_Cfg.sashpos);
666 }
667 m_NavigPan->SetSelection(1);
668 if (m_Data->GetBookRecArray().GetCount() > 0)
669 {
670 wxHtmlBookRecord& book = m_Data->GetBookRecArray()[0];
671 if (!book.GetStart().IsEmpty())
672 m_HtmlWin->LoadPage(book.GetFullPath(book.GetStart()));
673 }
674 return TRUE;
675 }
676
677
678
679 bool wxHtmlHelpFrame::KeywordSearch(const wxString& keyword)
680 {
681 if (! (m_SearchList && m_SearchButton && m_SearchText && m_SearchChoice))
682 return FALSE;
683
684 int foundcnt = 0, curi;
685 wxString foundstr;
686 wxString book = wxEmptyString;
687
688 if (!m_Splitter->IsSplit())
689 {
690 m_NavigPan->Show(TRUE);
691 m_HtmlWin->Show(TRUE);
692 m_Splitter->SplitVertically(m_NavigPan, m_HtmlWin, m_Cfg.sashpos);
693 }
694 m_NavigPan->SetSelection(m_SearchPage);
695 m_SearchList->Clear();
696 m_SearchText->SetValue(keyword);
697 m_SearchButton->Enable(FALSE);
698
699 if (m_SearchChoice->GetSelection() != 0)
700 book = m_SearchChoice->GetStringSelection();
701
702 wxHtmlSearchStatus status(m_Data, keyword,
703 m_SearchCaseSensitive->GetValue(), m_SearchWholeWords->GetValue(),
704 book);
705
706 wxProgressDialog progress(_("Searching..."), _("No matching page found yet"),
707 status.GetMaxIndex(), this,
708 wxPD_APP_MODAL | wxPD_CAN_ABORT | wxPD_AUTO_HIDE);
709
710 while (status.IsActive())
711 {
712 curi = status.GetCurIndex();
713 if (curi % 32 == 0 && progress.Update(curi) == FALSE)
714 break;
715 if (status.Search())
716 {
717 foundstr.Printf(_("Found %i matches"), ++foundcnt);
718 progress.Update(status.GetCurIndex(), foundstr);
719 m_SearchList->Append(status.GetName(), status.GetContentsItem());
720 }
721 }
722
723 m_SearchButton->Enable(TRUE);
724 m_SearchText->SetSelection(0, keyword.Length());
725 m_SearchText->SetFocus();
726 if (foundcnt)
727 {
728 wxHtmlContentsItem *it = (wxHtmlContentsItem*) m_SearchList->GetClientData(0);
729 if (it)
730 {
731 m_HtmlWin->LoadPage(it->GetFullPath());
732 NotifyPageChanged();
733 }
734 }
735 return (foundcnt > 0);
736 }
737
738 void wxHtmlHelpFrame::CreateContents()
739 {
740 if (! m_ContentsBox)
741 return ;
742
743 m_ContentsBox->Clear();
744
745 if (m_PagesHash) delete m_PagesHash;
746 m_PagesHash = new wxHashTable(wxKEY_STRING, 2 * m_Data->GetContentsCnt());
747 m_PagesHash->DeleteContents(TRUE);
748
749 int cnt = m_Data->GetContentsCnt();
750 int i;
751 size_t booksCnt = m_Data->GetBookRecArray().GetCount();
752
753 wxHtmlContentsItem *it;
754
755 const int MAX_ROOTS = 64;
756 wxTreeItemId roots[MAX_ROOTS];
757 // VS: this array holds information about whether we've set item icon at
758 // given level. This is neccessary because m_Data has flat structure
759 // and there's no way of recognizing if some item has subitems or not.
760 // We set the icon later: when we find an item with level=n, we know
761 // that the last item with level=n-1 was folder with subitems, so we
762 // set its icon accordingly
763 bool imaged[MAX_ROOTS];
764 m_ContentsBox->DeleteAllItems();
765
766 // Don't show (Help) root if there's only one boook
767 if (booksCnt > 1)
768 {
769 roots[0] = m_ContentsBox->AddRoot(_("(Help)"));
770 m_ContentsBox->SetItemImage(roots[0], IMG_RootFolder);
771 m_ContentsBox->SetItemSelectedImage(roots[0], IMG_RootFolder);
772 imaged[0] = TRUE;
773 }
774
775 for (it = m_Data->GetContents(), i = 0; i < cnt; i++, it++)
776 {
777 // Handle books:
778 if (it->m_Level == 0)
779 {
780 // special case, only one book, make it tree's root:
781 if (booksCnt == 1)
782 {
783 roots[0] = roots[1] = m_ContentsBox->AddRoot(
784 it->m_Name, IMG_Book, -1,
785 new wxHtmlHelpTreeItemData(i));
786 imaged[0] = imaged[1] = TRUE;
787 m_ContentsBox->SetItemBold(roots[1], TRUE);
788 }
789 // multiple books:
790 else
791 {
792 if (m_hfStyle & wxHF_MERGE_BOOKS)
793 // VS: we don't want book nodes, books' content should
794 // appear under tree's root. This line will create "fake"
795 // record about book node so that the rest of this look
796 // will believe there really _is_ book node and will
797 // behave correctly.
798 roots[1] = roots[0];
799 else
800 {
801 roots[1] = m_ContentsBox->AppendItem(roots[0],
802 it->m_Name, IMG_Book, -1,
803 new wxHtmlHelpTreeItemData(i));
804 m_ContentsBox->SetItemBold(roots[1], TRUE);
805 }
806 imaged[1] = TRUE;
807 }
808 }
809 // ...and their contents:
810 else
811 {
812 roots[it->m_Level + 1] = m_ContentsBox->AppendItem(
813 roots[it->m_Level], it->m_Name, IMG_Page,
814 -1, new wxHtmlHelpTreeItemData(i));
815 imaged[it->m_Level + 1] = FALSE;
816 }
817
818 m_PagesHash->Put(it->GetFullPath(),
819 new wxHtmlHelpHashData(i, roots[it->m_Level + 1]));
820
821 // Set the icon for the node one level up in the hiearachy,
822 // unless already done (see comment above imaged[] declaration)
823 if (!imaged[it->m_Level])
824 {
825 int image = IMG_Folder;
826 if (m_hfStyle & wxHF_ICONS_BOOK)
827 image = IMG_Book;
828 else if (m_hfStyle & wxHF_ICONS_BOOK_CHAPTER)
829 image = (it->m_Level == 1) ? IMG_Book : IMG_Folder;
830 m_ContentsBox->SetItemImage(roots[it->m_Level], image);
831 m_ContentsBox->SetItemSelectedImage(roots[it->m_Level], image);
832 imaged[it->m_Level] = TRUE;
833 }
834 }
835
836 m_ContentsBox->Expand(roots[0]);
837 }
838
839
840 void wxHtmlHelpFrame::CreateIndex()
841 {
842 if (! m_IndexList)
843 return ;
844
845 m_IndexList->Clear();
846
847 int cnt = m_Data->GetIndexCnt();
848
849 wxString cnttext;
850 if (cnt > INDEX_IS_SMALL) cnttext.Printf(_("%i of %i"), 0, cnt);
851 else cnttext.Printf(_("%i of %i"), cnt, cnt);
852 m_IndexCountInfo->SetLabel(cnttext);
853 if (cnt > INDEX_IS_SMALL) return;
854
855 wxHtmlContentsItem* index = m_Data->GetIndex();
856
857 for (int i = 0; i < cnt; i++)
858 m_IndexList->Append(index[i].m_Name, (char*)(index + i));
859 }
860
861 void wxHtmlHelpFrame::CreateSearch()
862 {
863 if (! (m_SearchList && m_SearchChoice))
864 return ;
865 m_SearchList->Clear();
866 m_SearchChoice->Clear();
867 m_SearchChoice->Append(_("Search in all books"));
868 const wxHtmlBookRecArray& bookrec = m_Data->GetBookRecArray();
869 int i, cnt = bookrec.GetCount();
870 for (i = 0; i < cnt; i++)
871 m_SearchChoice->Append(bookrec[i].GetTitle());
872 m_SearchChoice->SetSelection(0);
873 }
874
875
876 void wxHtmlHelpFrame::RefreshLists()
877 {
878 CreateContents();
879 CreateIndex();
880 CreateSearch();
881 }
882
883 void wxHtmlHelpFrame::ReadCustomization(wxConfigBase *cfg, const wxString& path)
884 {
885 wxString oldpath;
886 wxString tmp;
887
888 if (path != wxEmptyString)
889 {
890 oldpath = cfg->GetPath();
891 cfg->SetPath(_T("/") + path);
892 }
893
894 m_Cfg.navig_on = cfg->Read(wxT("hcNavigPanel"), m_Cfg.navig_on) != 0;
895 m_Cfg.sashpos = cfg->Read(wxT("hcSashPos"), m_Cfg.sashpos);
896 m_Cfg.x = cfg->Read(wxT("hcX"), m_Cfg.x);
897 m_Cfg.y = cfg->Read(wxT("hcY"), m_Cfg.y);
898 m_Cfg.w = cfg->Read(wxT("hcW"), m_Cfg.w);
899 m_Cfg.h = cfg->Read(wxT("hcH"), m_Cfg.h);
900
901 m_FixedFace = cfg->Read(wxT("hcFixedFace"), m_FixedFace);
902 m_NormalFace = cfg->Read(wxT("hcNormalFace"), m_NormalFace);
903 m_FontSize = cfg->Read(wxT("hcFontSize"), m_FontSize);
904
905 {
906 int i;
907 int cnt;
908 wxString val, s;
909
910 cnt = cfg->Read(wxT("hcBookmarksCnt"), 0L);
911 if (cnt != 0)
912 {
913 m_BookmarksNames.Clear();
914 m_BookmarksPages.Clear();
915 if (m_Bookmarks)
916 {
917 m_Bookmarks->Clear();
918 m_Bookmarks->Append(_("(bookmarks)"));
919 }
920
921 for (i = 0; i < cnt; i++)
922 {
923 val.Printf(wxT("hcBookmark_%i"), i);
924 s = cfg->Read(val);
925 m_BookmarksNames.Add(s);
926 if (m_Bookmarks) m_Bookmarks->Append(s);
927 val.Printf(wxT("hcBookmark_%i_url"), i);
928 s = cfg->Read(val);
929 m_BookmarksPages.Add(s);
930 }
931 }
932 }
933
934 if (m_HtmlWin)
935 m_HtmlWin->ReadCustomization(cfg);
936
937 if (path != wxEmptyString)
938 cfg->SetPath(oldpath);
939 }
940
941 void wxHtmlHelpFrame::WriteCustomization(wxConfigBase *cfg, const wxString& path)
942 {
943 wxString oldpath;
944 wxString tmp;
945
946 if (path != wxEmptyString)
947 {
948 oldpath = cfg->GetPath();
949 cfg->SetPath(_T("/") + path);
950 }
951
952 cfg->Write(wxT("hcNavigPanel"), m_Cfg.navig_on);
953 cfg->Write(wxT("hcSashPos"), (long)m_Cfg.sashpos);
954 cfg->Write(wxT("hcX"), (long)m_Cfg.x);
955 cfg->Write(wxT("hcY"), (long)m_Cfg.y);
956 cfg->Write(wxT("hcW"), (long)m_Cfg.w);
957 cfg->Write(wxT("hcH"), (long)m_Cfg.h);
958 cfg->Write(wxT("hcFixedFace"), m_FixedFace);
959 cfg->Write(wxT("hcNormalFace"), m_NormalFace);
960 cfg->Write(wxT("hcFontSize"), (long)m_FontSize);
961
962 if (m_Bookmarks)
963 {
964 int i;
965 int cnt = m_BookmarksNames.GetCount();
966 wxString val;
967
968 cfg->Write(wxT("hcBookmarksCnt"), (long)cnt);
969 for (i = 0; i < cnt; i++)
970 {
971 val.Printf(wxT("hcBookmark_%i"), i);
972 cfg->Write(val, m_BookmarksNames[i]);
973 val.Printf(wxT("hcBookmark_%i_url"), i);
974 cfg->Write(val, m_BookmarksPages[i]);
975 }
976 }
977
978 if (m_HtmlWin)
979 m_HtmlWin->WriteCustomization(cfg);
980
981 if (path != wxEmptyString)
982 cfg->SetPath(oldpath);
983 }
984
985
986
987
988
989 static void SetFontsToHtmlWin(wxHtmlWindow *win, wxString scalf, wxString fixf, int size)
990 {
991 static int f_sizes[5][7] =
992 {
993 { 6, 7, 9, 12, 14, 16, 19},
994 { 8, 9, 12, 14, 16, 19, 22},
995 {10, 12, 14, 16, 19, 24, 32},
996 {14, 16, 18, 24, 32, 38, 45},
997 {16, 20, 24, 32, 38, 45, 50}
998 };
999
1000 win->SetFonts(scalf, fixf, f_sizes[size]);
1001 }
1002
1003
1004 class wxHtmlHelpFrameOptionsDialog : public wxDialog
1005 {
1006 public:
1007 wxComboBox *NormalFont, *FixedFont;
1008 wxRadioBox *RadioBox;
1009 wxHtmlWindow *TestWin;
1010
1011 wxHtmlHelpFrameOptionsDialog(wxWindow *parent) : wxDialog(parent, -1, wxString(_("Help Browser Options")))
1012 {
1013 wxString choices[5] = {_("very small"), _("small"), _("medium"), _("large"), _("very large")};
1014 wxBoxSizer *topsizer, *sizer, *sizer2;
1015
1016 topsizer = new wxBoxSizer(wxVERTICAL);
1017
1018 sizer = new wxBoxSizer(wxHORIZONTAL);
1019
1020 sizer2 = new wxStaticBoxSizer( new wxStaticBox(this, -1, _("Normal font:")), wxVERTICAL);
1021 sizer2->Add(NormalFont = new wxComboBox(this, -1, wxEmptyString, wxDefaultPosition,
1022 wxSize(200, 200),
1023 0, NULL, wxCB_DROPDOWN | wxCB_READONLY),
1024 1, wxEXPAND | wxLEFT | wxRIGHT, 10);
1025
1026 sizer->Add(sizer2, 0, wxEXPAND | wxLEFT|wxRIGHT|wxTOP, 10);
1027
1028 sizer2 = new wxStaticBoxSizer( new wxStaticBox(this, -1, _("Fixed font:")), wxVERTICAL);
1029 sizer2->Add(FixedFont = new wxComboBox(this, -1, wxEmptyString, wxDefaultPosition,
1030 wxSize(200, 200),
1031 0, NULL, wxCB_DROPDOWN | wxCB_READONLY),
1032 1, wxEXPAND | wxLEFT | wxRIGHT, 10);
1033
1034 sizer->Add(sizer2, 0, wxEXPAND | wxLEFT|wxRIGHT|wxTOP, 10);
1035
1036 topsizer->Add(sizer);
1037
1038 topsizer->Add(RadioBox = new wxRadioBox(this, -1, _("Font size:"),
1039 wxDefaultPosition, wxDefaultSize, 5, choices, 5),
1040 0, wxEXPAND | wxLEFT|wxRIGHT|wxTOP, 10);
1041
1042 topsizer->Add(new wxStaticText(this, -1, _("Preview:")),
1043 0, wxLEFT | wxTOP, 10);
1044 topsizer->Add(TestWin = new wxHtmlWindow(this, -1, wxDefaultPosition, wxSize(-1, 150)),
1045 1, wxEXPAND | wxLEFT|wxTOP|wxRIGHT, 10);
1046
1047 sizer = new wxBoxSizer(wxHORIZONTAL);
1048 sizer->Add(new wxButton(this, wxID_OK, _("OK")), 0, wxALL, 10);
1049 sizer->Add(new wxButton(this, wxID_CANCEL, _("Cancel")), 0, wxALL, 10);
1050 topsizer->Add(sizer, 0, wxALIGN_RIGHT);
1051
1052 SetAutoLayout(TRUE);
1053 SetSizer(topsizer);
1054 topsizer->Fit(this);
1055 Centre(wxBOTH);
1056 }
1057
1058
1059 void UpdateTestWin()
1060 {
1061 wxBusyCursor bcur;
1062 SetFontsToHtmlWin(TestWin,
1063 NormalFont->GetStringSelection(),
1064 FixedFont->GetStringSelection(),
1065 RadioBox->GetSelection());
1066 TestWin->SetPage(_(
1067 "<html><body>\
1068 Normal face<br>(and <u>underlined</u>. <i>Italic face.</i> \
1069 <b>Bold face.</b> <b><i>Bold italic face.</i></b><br>\
1070 <font size=-2>font size -2</font><br>\
1071 <font size=-1>font size -1</font><br>\
1072 <font size=+0>font size +0</font><br>\
1073 <font size=+1>font size +1</font><br>\
1074 <font size=+2>font size +2</font><br>\
1075 <font size=+3>font size +3</font><br>\
1076 <font size=+4>font size +4</font><br>\
1077 \
1078 <p><tt>Fixed size face.<br> <b>bold</b> <i>italic</i> \
1079 <b><i>bold italic <u>underlined</u></i></b><br>\
1080 <font size=-2>font size -2</font><br>\
1081 <font size=-1>font size -1</font><br>\
1082 <font size=+0>font size +0</font><br>\
1083 <font size=+1>font size +1</font><br>\
1084 <font size=+2>font size +2</font><br>\
1085 <font size=+3>font size +3</font><br>\
1086 <font size=+4>font size +4</font></tt>\
1087 </body></html>"
1088 ));
1089 }
1090
1091 void OnUpdate(wxCommandEvent& WXUNUSED(event))
1092 {
1093 UpdateTestWin();
1094 }
1095
1096 DECLARE_EVENT_TABLE()
1097 };
1098
1099 BEGIN_EVENT_TABLE(wxHtmlHelpFrameOptionsDialog, wxDialog)
1100 EVT_COMBOBOX(-1, wxHtmlHelpFrameOptionsDialog::OnUpdate)
1101 EVT_RADIOBOX(-1, wxHtmlHelpFrameOptionsDialog::OnUpdate)
1102 END_EVENT_TABLE()
1103
1104
1105 void wxHtmlHelpFrame::OptionsDialog()
1106 {
1107 wxHtmlHelpFrameOptionsDialog dlg(this);
1108 unsigned i;
1109
1110 if (m_NormalFonts == NULL)
1111 {
1112 wxFontEnumerator enu;
1113 enu.EnumerateFacenames();
1114 m_NormalFonts = new wxArrayString;
1115 *m_NormalFonts = *enu.GetFacenames();
1116 m_NormalFonts->Sort();
1117 }
1118 if (m_FixedFonts == NULL)
1119 {
1120 wxFontEnumerator enu;
1121 enu.EnumerateFacenames(wxFONTENCODING_SYSTEM, TRUE);
1122 m_FixedFonts = new wxArrayString;
1123 *m_FixedFonts = *enu.GetFacenames();
1124 m_FixedFonts->Sort();
1125 }
1126
1127 for (i = 0; i < m_NormalFonts->GetCount(); i++)
1128 dlg.NormalFont->Append((*m_NormalFonts)[i]);
1129 for (i = 0; i < m_FixedFonts->GetCount(); i++)
1130 dlg.FixedFont->Append((*m_FixedFonts)[i]);
1131 if (!m_NormalFace.IsEmpty()) dlg.NormalFont->SetStringSelection(m_NormalFace);
1132 else dlg.NormalFont->SetSelection(0);
1133 if (!m_FixedFace.IsEmpty()) dlg.FixedFont->SetStringSelection(m_FixedFace);
1134 else dlg.FixedFont->SetSelection(0);
1135 dlg.RadioBox->SetSelection(m_FontSize);
1136 dlg.UpdateTestWin();
1137
1138 if (dlg.ShowModal() == wxID_OK)
1139 {
1140 m_NormalFace = dlg.NormalFont->GetStringSelection();
1141 m_FixedFace = dlg.FixedFont->GetStringSelection();
1142 m_FontSize = dlg.RadioBox->GetSelection();
1143 SetFontsToHtmlWin(m_HtmlWin, m_NormalFace, m_FixedFace, m_FontSize);
1144 }
1145 }
1146
1147
1148
1149 void wxHtmlHelpFrame::NotifyPageChanged()
1150 {
1151 if (m_UpdateContents && m_PagesHash)
1152 {
1153 wxString an = m_HtmlWin->GetOpenedAnchor();
1154 wxHtmlHelpHashData *ha;
1155 if (an.IsEmpty())
1156 ha = (wxHtmlHelpHashData*) m_PagesHash->Get(m_HtmlWin->GetOpenedPage());
1157 else
1158 ha = (wxHtmlHelpHashData*) m_PagesHash->Get(m_HtmlWin->GetOpenedPage() + wxT("#") + an);
1159 if (ha)
1160 {
1161 bool olduc = m_UpdateContents;
1162 m_UpdateContents = FALSE;
1163 m_ContentsBox->SelectItem(ha->m_Id);
1164 m_ContentsBox->EnsureVisible(ha->m_Id);
1165 m_UpdateContents = olduc;
1166 }
1167 }
1168 }
1169
1170
1171
1172 /*
1173 EVENT HANDLING :
1174 */
1175
1176
1177 void wxHtmlHelpFrame::OnToolbar(wxCommandEvent& event)
1178 {
1179 switch (event.GetId())
1180 {
1181 case wxID_HTML_BACK :
1182 m_HtmlWin->HistoryBack();
1183 NotifyPageChanged();
1184 break;
1185
1186 case wxID_HTML_FORWARD :
1187 m_HtmlWin->HistoryForward();
1188 NotifyPageChanged();
1189 break;
1190
1191 case wxID_HTML_UP :
1192 if (m_PagesHash)
1193 {
1194 wxString an = m_HtmlWin->GetOpenedAnchor();
1195 wxHtmlHelpHashData *ha;
1196 if (an.IsEmpty())
1197 ha = (wxHtmlHelpHashData*) m_PagesHash->Get(m_HtmlWin->GetOpenedPage());
1198 else
1199 ha = (wxHtmlHelpHashData*) m_PagesHash->Get(m_HtmlWin->GetOpenedPage() + wxT("#") + an);
1200 if (ha && ha->m_Index > 0)
1201 {
1202 wxHtmlContentsItem *it = m_Data->GetContents() + (ha->m_Index - 1);
1203 if (it->m_Page[0] != 0)
1204 {
1205 m_HtmlWin->LoadPage(it->GetFullPath());
1206 NotifyPageChanged();
1207 }
1208 }
1209 }
1210 break;
1211
1212 case wxID_HTML_UPNODE :
1213 if (m_PagesHash)
1214 {
1215 wxString an = m_HtmlWin->GetOpenedAnchor();
1216 wxHtmlHelpHashData *ha;
1217 if (an.IsEmpty())
1218 ha = (wxHtmlHelpHashData*) m_PagesHash->Get(m_HtmlWin->GetOpenedPage());
1219 else
1220 ha = (wxHtmlHelpHashData*) m_PagesHash->Get(m_HtmlWin->GetOpenedPage() + wxT("#") + an);
1221 if (ha && ha->m_Index > 0)
1222 {
1223 int level = m_Data->GetContents()[ha->m_Index].m_Level - 1;
1224 wxHtmlContentsItem *it;
1225 int ind = ha->m_Index - 1;
1226
1227 it = m_Data->GetContents() + ind;
1228 while (ind >= 0 && it->m_Level != level) ind--, it--;
1229 if (ind >= 0)
1230 {
1231 if (it->m_Page[0] != 0)
1232 {
1233 m_HtmlWin->LoadPage(it->GetFullPath());
1234 NotifyPageChanged();
1235 }
1236 }
1237 }
1238 }
1239 break;
1240
1241 case wxID_HTML_DOWN :
1242 if (m_PagesHash)
1243 {
1244 wxString an = m_HtmlWin->GetOpenedAnchor();
1245 wxString adr;
1246 wxHtmlHelpHashData *ha;
1247
1248 if (an.IsEmpty()) adr = m_HtmlWin->GetOpenedPage();
1249 else adr = m_HtmlWin->GetOpenedPage() + wxT("#") + an;
1250
1251 ha = (wxHtmlHelpHashData*) m_PagesHash->Get(adr);
1252
1253 if (ha && ha->m_Index < m_Data->GetContentsCnt() - 1)
1254 {
1255 wxHtmlContentsItem *it = m_Data->GetContents() + (ha->m_Index + 1);
1256
1257 while (it->GetFullPath() == adr) it++;
1258
1259 if (it->m_Page[0] != 0)
1260 {
1261 m_HtmlWin->LoadPage(it->GetFullPath());
1262 NotifyPageChanged();
1263 }
1264 }
1265 }
1266 break;
1267
1268 case wxID_HTML_PANEL :
1269 {
1270 if (! (m_Splitter && m_NavigPan))
1271 return ;
1272 if (m_Splitter->IsSplit())
1273 {
1274 m_Cfg.sashpos = m_Splitter->GetSashPosition();
1275 m_Splitter->Unsplit(m_NavigPan);
1276 m_Cfg.navig_on = FALSE;
1277 }
1278 else
1279 {
1280 m_NavigPan->Show(TRUE);
1281 m_HtmlWin->Show(TRUE);
1282 m_Splitter->SplitVertically(m_NavigPan, m_HtmlWin, m_Cfg.sashpos);
1283 m_Cfg.navig_on = TRUE;
1284 }
1285 }
1286 break;
1287
1288 case wxID_HTML_OPTIONS :
1289 OptionsDialog();
1290 break;
1291
1292 case wxID_HTML_BOOKMARKSADD :
1293 {
1294 wxString item;
1295 wxString url;
1296
1297 item = m_HtmlWin->GetOpenedPageTitle();
1298 url = m_HtmlWin->GetOpenedPage();
1299 if (item == wxEmptyString)
1300 item = url.AfterLast(wxT('/'));
1301 if (m_BookmarksPages.Index(url) == wxNOT_FOUND)
1302 {
1303 m_Bookmarks->Append(item);
1304 m_BookmarksNames.Add(item);
1305 m_BookmarksPages.Add(url);
1306 }
1307 }
1308 break;
1309
1310 case wxID_HTML_BOOKMARKSREMOVE :
1311 {
1312 wxString item;
1313 int pos;
1314
1315 item = m_Bookmarks->GetStringSelection();
1316 pos = m_BookmarksNames.Index(item);
1317 if (pos != wxNOT_FOUND)
1318 {
1319 m_BookmarksNames.Remove(pos);
1320 m_BookmarksPages.Remove(pos);
1321 m_Bookmarks->Delete(m_Bookmarks->GetSelection());
1322 }
1323 }
1324 break;
1325
1326 #if wxUSE_PRINTING_ARCHITECTURE
1327 case wxID_HTML_PRINT :
1328 {
1329 if (m_Printer == NULL)
1330 m_Printer = new wxHtmlEasyPrinting(_("Help Printing"), this);
1331 if (!m_HtmlWin->GetOpenedPage())
1332 wxLogWarning(_("Cannot print empty page."));
1333 else
1334 m_Printer->PrintFile(m_HtmlWin->GetOpenedPage());
1335 }
1336 break;
1337 #endif
1338
1339 case wxID_HTML_OPENFILE :
1340 {
1341 wxString s = wxFileSelector(_("Open HTML document"),
1342 wxEmptyString,
1343 wxEmptyString,
1344 wxEmptyString,
1345 _(
1346 "HTML files (*.htm)|*.htm|HTML files (*.html)|*.html|\
1347 Help books (*.htb)|*.htb|Help books (*.zip)|*.zip|\
1348 HTML Help Project (*.hhp)|*.hhp|\
1349 All files (*.*)|*"
1350 ),
1351 wxOPEN | wxFILE_MUST_EXIST,
1352 this);
1353 if (!s.IsEmpty())
1354 {
1355 wxString ext = s.Right(4).Lower();
1356 if (ext == _T(".zip") || ext == _T(".htb") || ext == _T(".hhp"))
1357 {
1358 wxBusyCursor bcur;
1359 m_Data->AddBook(s);
1360 RefreshLists();
1361 }
1362 else
1363 m_HtmlWin->LoadPage(s);
1364 }
1365 }
1366 break;
1367 }
1368 }
1369
1370
1371
1372 void wxHtmlHelpFrame::OnContentsSel(wxTreeEvent& event)
1373 {
1374 wxHtmlHelpTreeItemData *pg;
1375 wxHtmlContentsItem *it;
1376
1377 pg = (wxHtmlHelpTreeItemData*) m_ContentsBox->GetItemData(event.GetItem());
1378
1379 if (pg && m_UpdateContents)
1380 {
1381 it = m_Data->GetContents() + (pg->m_Id);
1382 m_UpdateContents = FALSE;
1383 if (it->m_Page[0] != 0)
1384 m_HtmlWin->LoadPage(it->GetFullPath());
1385 m_UpdateContents = TRUE;
1386 }
1387 }
1388
1389
1390
1391 void wxHtmlHelpFrame::OnIndexSel(wxCommandEvent& WXUNUSED(event))
1392 {
1393 wxHtmlContentsItem *it = (wxHtmlContentsItem*) m_IndexList->GetClientData(m_IndexList->GetSelection());
1394 if (it->m_Page[0] != 0)
1395 m_HtmlWin->LoadPage(it->GetFullPath());
1396 NotifyPageChanged();
1397 }
1398
1399
1400 void wxHtmlHelpFrame::OnIndexFind(wxCommandEvent& event)
1401 {
1402 wxString sr = m_IndexText->GetLineText(0);
1403 sr.MakeLower();
1404 if (sr == wxEmptyString)
1405 {
1406 OnIndexAll(event);
1407 }
1408 else
1409 {
1410 wxBusyCursor bcur;
1411 const wxChar *cstr = sr.c_str();
1412 wxChar mybuff[512];
1413 wxChar *ptr;
1414 bool first = TRUE;
1415
1416 m_IndexList->Clear();
1417 int cnt = m_Data->GetIndexCnt();
1418 wxHtmlContentsItem* index = m_Data->GetIndex();
1419
1420 int displ = 0;
1421 for (int i = 0; i < cnt; i++)
1422 {
1423 wxStrncpy(mybuff, index[i].m_Name, 512);
1424 mybuff[511] = _T('\0');
1425 for (ptr = mybuff; *ptr != 0; ptr++)
1426 if (*ptr >= _T('A') && *ptr <= _T('Z'))
1427 *ptr -= (wxChar)(_T('A') - _T('a'));
1428 if (wxStrstr(mybuff, cstr) != NULL)
1429 {
1430 m_IndexList->Append(index[i].m_Name, (char*)(index + i));
1431 displ++;
1432 if (first)
1433 {
1434 if (index[i].m_Page[0] != 0)
1435 m_HtmlWin->LoadPage(index[i].GetFullPath());
1436 NotifyPageChanged();
1437 first = FALSE;
1438 }
1439 }
1440 }
1441
1442 wxString cnttext;
1443 cnttext.Printf(_("%i of %i"), displ, cnt);
1444 m_IndexCountInfo->SetLabel(cnttext);
1445
1446 m_IndexText->SetSelection(0, sr.Length());
1447 m_IndexText->SetFocus();
1448 }
1449 }
1450
1451 void wxHtmlHelpFrame::OnIndexAll(wxCommandEvent& WXUNUSED(event))
1452 {
1453 wxBusyCursor bcur;
1454
1455 m_IndexList->Clear();
1456 int cnt = m_Data->GetIndexCnt();
1457 bool first = TRUE;
1458 wxHtmlContentsItem* index = m_Data->GetIndex();
1459
1460 for (int i = 0; i < cnt; i++)
1461 {
1462 m_IndexList->Append(index[i].m_Name, (char*)(index + i));
1463 if (first)
1464 {
1465 if (index[i].m_Page[0] != 0)
1466 m_HtmlWin->LoadPage(index[i].GetFullPath());
1467 NotifyPageChanged();
1468 first = FALSE;
1469 }
1470 }
1471
1472 wxString cnttext;
1473 cnttext.Printf(_("%i of %i"), cnt, cnt);
1474 m_IndexCountInfo->SetLabel(cnttext);
1475 }
1476
1477
1478 void wxHtmlHelpFrame::OnSearchSel(wxCommandEvent& WXUNUSED(event))
1479 {
1480 wxHtmlContentsItem *it = (wxHtmlContentsItem*) m_SearchList->GetClientData(m_SearchList->GetSelection());
1481 if (it)
1482 {
1483 if (it->m_Page[0] != 0)
1484 m_HtmlWin->LoadPage(it->GetFullPath());
1485 NotifyPageChanged();
1486 }
1487 }
1488
1489 void wxHtmlHelpFrame::OnSearch(wxCommandEvent& WXUNUSED(event))
1490 {
1491 wxString sr = m_SearchText->GetLineText(0);
1492
1493 if (sr != wxEmptyString) KeywordSearch(sr);
1494 }
1495
1496 void wxHtmlHelpFrame::OnBookmarksSel(wxCommandEvent& WXUNUSED(event))
1497 {
1498 wxString sr = m_Bookmarks->GetStringSelection();
1499
1500 if (sr != wxEmptyString && sr != _("(bookmarks)"))
1501 {
1502 m_HtmlWin->LoadPage(m_BookmarksPages[m_BookmarksNames.Index(sr)]);
1503 NotifyPageChanged();
1504 }
1505 }
1506
1507 void wxHtmlHelpFrame::OnCloseWindow(wxCloseEvent& evt)
1508 {
1509 GetSize(&m_Cfg.w, &m_Cfg.h);
1510 GetPosition(&m_Cfg.x, &m_Cfg.y);
1511
1512 if (m_Splitter && m_Cfg.navig_on) m_Cfg.sashpos = m_Splitter->GetSashPosition();
1513
1514 if (m_Config)
1515 WriteCustomization(m_Config, m_ConfigRoot);
1516
1517 if (m_helpController && m_helpController->IsKindOf(CLASSINFO(wxHtmlHelpController)))
1518 {
1519 ((wxHtmlHelpController*) m_helpController)->OnCloseFrame(evt);
1520 }
1521
1522 evt.Skip();
1523 }
1524
1525 BEGIN_EVENT_TABLE(wxHtmlHelpFrame, wxFrame)
1526 EVT_TOOL_RANGE(wxID_HTML_PANEL, wxID_HTML_OPTIONS, wxHtmlHelpFrame::OnToolbar)
1527 EVT_BUTTON(wxID_HTML_BOOKMARKSREMOVE, wxHtmlHelpFrame::OnToolbar)
1528 EVT_BUTTON(wxID_HTML_BOOKMARKSADD, wxHtmlHelpFrame::OnToolbar)
1529 EVT_TREE_SEL_CHANGED(wxID_HTML_TREECTRL, wxHtmlHelpFrame::OnContentsSel)
1530 EVT_LISTBOX(wxID_HTML_INDEXLIST, wxHtmlHelpFrame::OnIndexSel)
1531 EVT_LISTBOX(wxID_HTML_SEARCHLIST, wxHtmlHelpFrame::OnSearchSel)
1532 EVT_BUTTON(wxID_HTML_SEARCHBUTTON, wxHtmlHelpFrame::OnSearch)
1533 EVT_TEXT_ENTER(wxID_HTML_SEARCHTEXT, wxHtmlHelpFrame::OnSearch)
1534 EVT_BUTTON(wxID_HTML_INDEXBUTTON, wxHtmlHelpFrame::OnIndexFind)
1535 EVT_TEXT_ENTER(wxID_HTML_INDEXTEXT, wxHtmlHelpFrame::OnIndexFind)
1536 EVT_BUTTON(wxID_HTML_INDEXBUTTONALL, wxHtmlHelpFrame::OnIndexAll)
1537 EVT_COMBOBOX(wxID_HTML_BOOKMARKSLIST, wxHtmlHelpFrame::OnBookmarksSel)
1538 EVT_CLOSE(wxHtmlHelpFrame::OnCloseWindow)
1539 END_EVENT_TABLE()
1540
1541 #endif