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