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