]> git.saurik.com Git - wxWidgets.git/blob - src/html/htmlhelp.cpp
New HTML help system. The old controller class has been split in
[wxWidgets.git] / src / html / htmlhelp.cpp
1 // Name: htmlhelp.cpp
2 // Purpose: Help controller
3 // Author: Vaclav Slavik
4 // Copyright: (c) 1999 Vaclav Slavik
5 // Licence: wxWindows Licence
6 /////////////////////////////////////////////////////////////////////////////
7
8 #error This file should not be compiled! Update your build system! \
9 (configure users, rerun configure to get a new Makefile) \
10 Instead of htmlhelp[_io], use helpdata, helpfrm and helpctrl. This \
11 file is only left to point out the problem and will be removed r.s.n.
12
13 #ifdef __GNUG__
14 #pragma implementation "htmlhelp.h"
15 #endif
16
17 #include "wx/wxprec.h"
18
19 #if wxUSE_HTML
20
21 #ifdef __BORDLANDC__
22 #pragma hdrstop
23 #endif
24
25 #ifndef WXPRECOMP
26 #include <wx/wx.h>
27 #endif
28
29
30 #include <wx/notebook.h>
31 #include <wx/imaglist.h>
32 #include <wx/treectrl.h>
33 #include <wx/tokenzr.h>
34 #include <wx/wfstream.h>
35 #include <wx/html/htmlwin.h>
36 #include <wx/html/htmlhelp.h>
37 #include <wx/busyinfo.h>
38
39 #if !((wxVERSION_NUMBER < 2100) || ((wxVERSION_NUMBER == 2100) && (wxBETA_NUMBER < 7)))
40 #include <wx/progdlg.h>
41 #endif
42
43
44 // Bitmaps:
45
46 #ifndef __WXMSW__
47 #include "bitmaps/panel.xpm"
48 #include "bitmaps/back.xpm"
49 #include "bitmaps/forward.xpm"
50 #include "bitmaps/book.xpm"
51 #include "bitmaps/folder.xpm"
52 #include "bitmaps/page.xpm"
53 #endif
54
55 #include "search.h"
56
57
58
59
60 #include <wx/arrimpl.cpp>
61 WX_DEFINE_OBJARRAY(HtmlBookRecArray)
62
63
64
65
66
67
68
69
70
71 //-----------------------------------------------------------------------------
72 // wxHtmlHelpController
73 //-----------------------------------------------------------------------------
74
75
76 IMPLEMENT_DYNAMIC_CLASS(wxHtmlHelpController, wxEvtHandler)
77
78
79 wxHtmlHelpController::wxHtmlHelpController() : wxEvtHandler()
80 {
81 m_Frame = NULL;
82 m_Config = NULL;
83 m_ConfigRoot = wxEmptyString;
84 m_TitleFormat = _("Help : %s");
85 m_TempPath = wxEmptyString;
86
87 m_Cfg.x = m_Cfg.y = 0;
88 m_Cfg.w = 700; m_Cfg.h = 480;
89 m_Cfg.sashpos = 240;
90 m_Cfg.navig_on = TRUE;
91
92 m_ContentsImageList = new wxImageList(12, 12);
93 m_ContentsImageList -> Add(wxICON(book));
94 m_ContentsImageList -> Add(wxICON(folder));
95 m_ContentsImageList -> Add(wxICON(page));
96
97 m_Contents = NULL;
98 m_ContentsCnt = 0;
99 m_Index = NULL;
100 m_IndexCnt = 0;
101
102 m_IndexBox = NULL;
103 m_ContentsBox = NULL;
104 m_SearchList = NULL;
105 m_SearchText = NULL;
106 m_SearchButton = NULL;
107 m_HtmlWin = NULL;
108 m_Splitter = NULL;
109 m_NavigPan = NULL;
110 }
111
112
113
114 wxHtmlHelpController::~wxHtmlHelpController()
115 {
116 int i;
117
118 m_BookRecords.Empty();
119 delete m_ContentsImageList;
120 if (m_Contents) {
121 for (i = 0; i < m_ContentsCnt; i++) {
122 delete[] m_Contents[i].m_Page;
123 delete[] m_Contents[i].m_Name;
124 }
125 free(m_Contents);
126 }
127 if (m_Index) {
128 for (i = 0; i < m_IndexCnt; i++) {
129 delete[] m_Index[i].m_Page;
130 delete[] m_Index[i].m_Name;
131 }
132 free(m_Index);
133 }
134 }
135
136
137
138 void wxHtmlHelpController::SetTempDir(const wxString& path)
139 {
140 if (path == wxEmptyString) m_TempPath = path;
141 else {
142 if (wxIsAbsolutePath(path)) m_TempPath = path;
143 else m_TempPath = wxGetCwd() + "/" + path;
144
145 if (m_TempPath[m_TempPath.Length() - 1] != '/')
146 m_TempPath << "/";
147 }
148 }
149
150
151
152
153 // Reads one line, stores it into buf and returns pointer to new line or NULL.
154 static char* ReadLine(char *line, char *buf)
155 {
156 char *writeptr = buf, *readptr = line;
157
158 while (*readptr != 0 && *readptr != '\r' && *readptr != '\n') *(writeptr++) = *(readptr++);
159 *writeptr = 0;
160 while (*readptr == '\r' || *readptr == '\n') readptr++;
161 if (*readptr == 0) return NULL;
162 else return readptr;
163 }
164
165
166 static wxString SafeFileName(const wxString& s)
167 {
168 wxString res = s;
169 res.Replace(":", "_", TRUE);
170 res.Replace(" ", "_", TRUE);
171 res.Replace("/", "_", TRUE);
172 res.Replace("\\", "_", TRUE);
173 res.Replace("#", "_", TRUE);
174 res.Replace(".", "_", TRUE);
175 return res;
176 }
177
178
179 static int IndexCompareFunc(const void *a, const void *b)
180 {
181 return strcmp(((HtmlContentsItem*)a) -> m_Name, ((HtmlContentsItem*)b) -> m_Name);
182 }
183
184
185
186 bool wxHtmlHelpController::AddBook(const wxString& book, bool show_wait_msg)
187 {
188 wxFSFile *fi;
189 wxFileSystem fsys;
190 wxInputStream *s;
191 HtmlBookRecord *bookr;
192 wxString bookFull;
193
194 int sz;
195 char *buff, *lineptr;
196 char linebuf[300];
197
198 wxString title = _("noname"),
199 safetitle,
200 start = wxEmptyString,
201 contents = wxEmptyString, index = wxEmptyString;
202
203 if (wxIsAbsolutePath(book)) bookFull = book;
204 else bookFull = wxGetCwd() + "/" + book;
205
206 fi = fsys.OpenFile(bookFull);
207 if (fi == NULL) return FALSE;
208 fsys.ChangePathTo(bookFull);
209 s = fi -> GetStream();
210 sz = s -> GetSize();
211 buff = new char[sz+1];
212 buff[sz] = 0;
213 s -> Read(buff, sz);
214 lineptr = buff;
215 delete fi;
216
217 while ((lineptr = ReadLine(lineptr, linebuf)) != NULL) {
218 if (strstr(linebuf, "Title=") == linebuf)
219 title = linebuf + strlen("Title=");
220 if (strstr(linebuf, "Default topic=") == linebuf)
221 start = linebuf + strlen("Default topic=");
222 if (strstr(linebuf, "Index file=") == linebuf)
223 index = linebuf + strlen("Index file=");
224 if (strstr(linebuf, "Contents file=") == linebuf)
225 contents = linebuf + strlen("Contents file=");
226 }
227 delete[] buff;
228
229 bookr = new HtmlBookRecord(fsys.GetPath(), title, start);
230
231 if (m_ContentsCnt % HTML_REALLOC_STEP == 0)
232 m_Contents = (HtmlContentsItem*) realloc(m_Contents, (m_ContentsCnt + HTML_REALLOC_STEP) * sizeof(HtmlContentsItem));
233 m_Contents[m_ContentsCnt].m_Level = 0;
234 m_Contents[m_ContentsCnt].m_ID = 0;
235 m_Contents[m_ContentsCnt].m_Page = new char[start.Length() + 1];
236 strcpy(m_Contents[m_ContentsCnt].m_Page, start.c_str());
237 m_Contents[m_ContentsCnt].m_Name = new char [title.Length() + 1];
238 strcpy(m_Contents[m_ContentsCnt].m_Name, title.c_str());
239 m_Contents[m_ContentsCnt].m_Book = bookr;
240 m_ContentsCnt++;
241
242 // Try to find cached binary versions:
243 safetitle = SafeFileName(title);
244 fi = fsys.OpenFile(safetitle + ".cached");
245 if (fi == NULL) fi = fsys.OpenFile(m_TempPath + safetitle + ".cached");
246 if ((fi == NULL) || (m_TempPath == wxEmptyString)) {
247 LoadMSProject(bookr, fsys, index, contents, show_wait_msg);
248 if (m_TempPath != wxEmptyString) {
249 wxFileOutputStream *outs = new wxFileOutputStream(m_TempPath + safetitle + ".cached");
250 SaveCachedBook(bookr, outs);
251 delete outs;
252 }
253 }
254 else {
255 LoadCachedBook(bookr, fi -> GetStream());
256 delete fi;
257 }
258
259 m_BookRecords.Add(bookr);
260 if (m_IndexCnt > 0)
261 qsort(m_Index, m_IndexCnt, sizeof(HtmlContentsItem), IndexCompareFunc);
262
263 return TRUE;
264 }
265
266
267
268
269 void wxHtmlHelpController::Display(const wxString& x)
270 {
271 int cnt;
272 int i;
273 wxFileSystem fsys;
274 wxFSFile *f;
275
276 CreateHelpWindow();
277
278 /* 1. try to open given file: */
279
280 cnt = m_BookRecords.GetCount();
281 for (i = 0; i < cnt; i++) {
282 f = fsys.OpenFile(m_BookRecords[i].GetBasePath() + x);
283 if (f) {
284 m_HtmlWin -> LoadPage(m_BookRecords[i].GetBasePath() + x);
285 delete f;
286 return;
287 }
288 }
289
290
291 /* 2. try to find a book: */
292
293 for (i = 0; i < cnt; i++) {
294 if (m_BookRecords[i].GetTitle() == x) {
295 m_HtmlWin -> LoadPage(m_BookRecords[i].GetBasePath() + m_BookRecords[i].GetStart());
296 return;
297 }
298 }
299
300 /* 3. try to find in contents: */
301
302 cnt = m_ContentsCnt;
303 for (i = 0; i < cnt; i++) {
304 if (strcmp(m_Contents[i].m_Name, x) == 0) {
305 m_HtmlWin -> LoadPage(m_Contents[i].m_Book -> GetBasePath() + m_Contents[i].m_Page);
306 return;
307 }
308 }
309
310
311 /* 4. try to find in index: */
312
313 cnt = m_IndexCnt;
314 for (i = 0; i < cnt; i++) {
315 if (strcmp(m_Index[i].m_Name, x) == 0) {
316 m_HtmlWin -> LoadPage(m_Index[i].m_Book -> GetBasePath() + m_Index[i].m_Page);
317 return;
318 }
319 }
320
321
322 /* 5. if everything failed, search the documents: */
323
324 KeywordSearch(x);
325 }
326
327
328
329 void wxHtmlHelpController::Display(const int id)
330 {
331 CreateHelpWindow();
332
333 for (int i = 0; i < m_ContentsCnt; i++) {
334 if (m_Contents[i].m_ID == id) {
335 m_HtmlWin -> LoadPage(m_Contents[i].m_Book -> GetBasePath() + m_Contents[i].m_Page);
336 return;
337 }
338 }
339 }
340
341
342
343 void wxHtmlHelpController::DisplayContents()
344 {
345 CreateHelpWindow();
346 m_Frame -> Raise();
347 if (!m_Splitter -> IsSplit()) {
348 m_NavigPan -> Show(TRUE);
349 m_HtmlWin -> Show(TRUE);
350 m_Splitter -> SplitVertically(m_NavigPan, m_HtmlWin, m_Cfg.sashpos);
351 }
352 m_NavigPan -> SetSelection(0);
353 }
354
355
356
357 void wxHtmlHelpController::DisplayIndex()
358 {
359 CreateHelpWindow();
360 m_Frame -> Raise();
361 if (!m_Splitter -> IsSplit()) {
362 m_NavigPan -> Show(TRUE);
363 m_HtmlWin -> Show(TRUE);
364 m_Splitter -> SplitVertically(m_NavigPan, m_HtmlWin, m_Cfg.sashpos);
365 }
366 m_NavigPan -> SetSelection(1);
367 }
368
369
370
371
372 #if (wxVERSION_NUMBER < 2100) || ((wxVERSION_NUMBER == 2100) && (wxBETA_NUMBER < 7))
373
374 class MyProgressDlg : public wxDialog
375 {
376 public:
377 bool m_Canceled;
378
379 MyProgressDlg(wxWindow *parent) : wxDialog(parent, -1,
380 _("Searching..."),
381 wxPoint(0, 0),
382 #ifdef __WXGTK__
383 wxSize(300, 110))
384 #else
385 wxSize(300, 130))
386 #endif
387 {m_Canceled = FALSE;}
388 void OnCancel(wxCommandEvent& event) {m_Canceled = TRUE;}
389 DECLARE_EVENT_TABLE()
390 };
391 BEGIN_EVENT_TABLE(MyProgressDlg, wxDialog)
392 EVT_BUTTON(wxID_CANCEL, MyProgressDlg::OnCancel)
393 END_EVENT_TABLE()
394
395 #endif
396
397
398 bool wxHtmlHelpController::KeywordSearch(const wxString& keyword)
399 {
400 int foundcnt = 0;
401 CreateHelpWindow();
402 // if these are not set, we can't continue
403 if (! (m_SearchList && m_HtmlWin))
404 return FALSE;
405 m_Frame -> Raise();
406 if (m_Splitter && m_NavigPan && m_SearchButton) {
407 if (!m_Splitter -> IsSplit()) {
408 m_NavigPan -> Show(TRUE);
409 m_HtmlWin -> Show(TRUE);
410 m_Splitter -> SplitVertically(m_NavigPan, m_HtmlWin, m_Cfg.sashpos);
411 }
412 m_NavigPan -> SetSelection(2);
413 m_SearchList -> Clear();
414 m_SearchText -> SetValue(keyword);
415 m_SearchButton -> Enable(FALSE);
416 }
417 {
418 int cnt = m_ContentsCnt;
419 wxSearchEngine engine;
420 wxFileSystem fsys;
421 wxFSFile *file;
422 wxString lastpage = wxEmptyString;
423 wxString foundstr;
424
425 #if (wxVERSION_NUMBER < 2100) || ((wxVERSION_NUMBER == 2100) && (wxBETA_NUMBER < 7))
426 MyProgressDlg progress(m_Frame);
427
428 wxStaticText *prompt = new wxStaticText(&progress, -1, "", wxPoint(20, 50), wxSize(260, 25), wxALIGN_CENTER);
429 wxGauge *gauge = new wxGauge(&progress, -1, cnt, wxPoint(20, 20), wxSize(260, 25));
430 wxButton *btn = new wxButton(&progress, wxID_CANCEL, _("Cancel"), wxPoint(110, 70), wxSize(80, 25));
431 btn = btn; /* fool compiler :-) */
432 prompt -> SetLabel(_("No matching page found yet"));
433
434 progress.Centre(wxBOTH);
435 progress.Show(TRUE);
436 #else
437 wxProgressDialog progress(_("Searching..."), _("No matching page found yet"), cnt, m_Frame, wxPD_APP_MODAL | wxPD_CAN_ABORT | wxPD_AUTO_HIDE);
438 #endif
439
440 engine.LookFor(keyword);
441
442 for (int i = 0; i < cnt; i++) {
443 #if (wxVERSION_NUMBER < 2100) || ((wxVERSION_NUMBER == 2100) && (wxBETA_NUMBER < 7))
444 gauge -> SetValue(i);
445 if (progress.m_Canceled) break;
446 #else
447 if (progress.Update(i) == FALSE) break;
448 #endif
449 wxYield();
450
451 file = fsys.OpenFile(m_Contents[i].m_Book -> GetBasePath() + m_Contents[i].m_Page);
452 if (file) {
453 if (lastpage != file -> GetLocation()) {
454 lastpage = file -> GetLocation();
455 if (engine.Scan(file -> GetStream())) {
456 foundstr.Printf(_("Found %i matches"), ++foundcnt);
457 #if (wxVERSION_NUMBER < 2100) || ((wxVERSION_NUMBER == 2100) && (wxBETA_NUMBER < 7))
458 prompt -> SetLabel(foundstr);
459 #else
460 progress.Update(i, foundstr);
461 #endif
462 wxYield();
463 m_SearchList -> Append(m_Contents[i].m_Name, (char*)(m_Contents + i));
464 }
465 }
466 delete file;
467 }
468 }
469
470 #if (wxVERSION_NUMBER < 2100) || ((wxVERSION_NUMBER == 2100) && (wxBETA_NUMBER < 7))
471 progress.Close(TRUE);
472 #endif
473 }
474 if (m_SearchButton)
475 m_SearchButton -> Enable(TRUE);
476 if (m_SearchText) {
477 m_SearchText -> SetSelection(0, keyword.Length());
478 m_SearchText -> SetFocus();
479 }
480 if (foundcnt) {
481 HtmlContentsItem *it = (HtmlContentsItem*) m_SearchList -> GetClientData(0);
482 if (it) m_HtmlWin -> LoadPage(it -> m_Book -> GetBasePath() + it -> m_Page);
483 }
484 return (foundcnt > 0);
485 }
486
487
488
489
490
491
492 void wxHtmlHelpController::CreateHelpWindow()
493 {
494 wxBusyCursor cur;
495 wxString oldpath;
496 wxStatusBar *sbar;
497
498 if (m_Frame) {
499 m_Frame -> Raise();
500 m_Frame -> Show(TRUE);
501 return;
502 }
503
504 #if wxUSE_BUSYINFO
505 wxBusyInfo busyinfo(_("Preparing help window..."));
506 #endif
507
508 if (m_Config) ReadCustomization(m_Config, m_ConfigRoot);
509
510 m_Frame = new wxFrame(NULL, -1, "", wxPoint(m_Cfg.x, m_Cfg.y), wxSize(m_Cfg.w, m_Cfg.h));
511 m_Frame -> PushEventHandler(this);
512 sbar = m_Frame -> CreateStatusBar();
513
514 {
515 wxToolBar *toolBar;
516 toolBar = m_Frame -> CreateToolBar(wxNO_BORDER | wxTB_HORIZONTAL | wxTB_FLAT | wxTB_DOCKABLE);
517 toolBar -> SetMargins(2, 2);
518 wxBitmap* toolBarBitmaps[3];
519
520 #ifdef __WXMSW__
521 toolBarBitmaps[0] = new wxBitmap("panel");
522 toolBarBitmaps[1] = new wxBitmap("back");
523 toolBarBitmaps[2] = new wxBitmap("forward");
524 int width = 24;
525 #else
526 toolBarBitmaps[0] = new wxBitmap(panel_xpm);
527 toolBarBitmaps[1] = new wxBitmap(back_xpm);
528 toolBarBitmaps[2] = new wxBitmap(forward_xpm);
529 int width = 16;
530 #endif
531
532 int currentX = 5;
533
534 toolBar -> AddTool(wxID_HTML_PANEL, *(toolBarBitmaps[0]), wxNullBitmap, FALSE, currentX, -1, (wxObject *) NULL, _("Show/hide navigation panel"));
535 currentX += width + 5;
536 toolBar -> AddSeparator();
537 toolBar -> AddTool(wxID_HTML_BACK, *(toolBarBitmaps[1]), wxNullBitmap, FALSE, currentX, -1, (wxObject *) NULL, _("Go back to the previous HTML page"));
538 currentX += width + 5;
539 toolBar -> AddTool(wxID_HTML_FORWARD, *(toolBarBitmaps[2]), wxNullBitmap, FALSE, currentX, -1, (wxObject *) NULL, _("Go forward to the next HTML page"));
540 currentX += width + 5;
541
542 toolBar -> Realize();
543
544 // Can delete the bitmaps since they're reference counted
545 for (int i = 0; i < 3; i++) delete toolBarBitmaps[i];
546 }
547
548
549 {
550 m_Splitter = new wxSplitterWindow(m_Frame);
551
552 m_HtmlWin = new wxHtmlWindow(m_Splitter);
553 m_HtmlWin -> SetRelatedFrame(m_Frame, m_TitleFormat);
554 m_HtmlWin -> SetRelatedStatusBar(0);
555 if (m_Config) m_HtmlWin -> ReadCustomization(m_Config, m_ConfigRoot);
556
557 m_NavigPan = new wxNotebook(m_Splitter, wxID_HTML_NOTEBOOK, wxDefaultPosition, wxDefaultSize);
558 {
559 m_ContentsBox = new wxTreeCtrl(m_NavigPan, wxID_HTML_TREECTRL, wxDefaultPosition, wxDefaultSize, wxTR_HAS_BUTTONS | wxSUNKEN_BORDER);
560 m_ContentsBox -> SetImageList(m_ContentsImageList);
561 m_NavigPan -> AddPage(m_ContentsBox, _("Contents"));
562 }
563
564 {
565 wxWindow *dummy = new wxPanel(m_NavigPan, wxID_HTML_INDEXPAGE);
566 wxLayoutConstraints *b1 = new wxLayoutConstraints;
567 b1 -> top.SameAs (dummy, wxTop, 0);
568 b1 -> left.SameAs (dummy, wxLeft, 0);
569 b1 -> width.PercentOf (dummy, wxWidth, 100);
570 b1 -> bottom.SameAs (dummy, wxBottom, 0);
571 m_IndexBox = new wxListBox(dummy, wxID_HTML_INDEXLIST, wxDefaultPosition, wxDefaultSize, 0);
572 m_IndexBox -> SetConstraints(b1);
573 dummy -> SetAutoLayout(TRUE);
574 m_NavigPan -> AddPage(dummy, _("Index"));
575 }
576
577 {
578 wxWindow *dummy = new wxPanel(m_NavigPan, wxID_HTML_SEARCHPAGE);
579
580 wxLayoutConstraints *b1 = new wxLayoutConstraints;
581 m_SearchText = new wxTextCtrl(dummy, wxID_HTML_SEARCHTEXT);
582 b1 -> top.SameAs (dummy, wxTop, 0);
583 b1 -> left.SameAs (dummy, wxLeft, 0);
584 b1 -> right.SameAs (dummy, wxRight, 0);
585 b1 -> height.AsIs();
586 m_SearchText -> SetConstraints(b1);
587
588 wxLayoutConstraints *b2 = new wxLayoutConstraints;
589 m_SearchButton = new wxButton(dummy, wxID_HTML_SEARCHBUTTON, _("Search!"));
590 b2 -> top.Below (m_SearchText, 10);
591 b2 -> right.SameAs (dummy, wxRight, 10);
592 b2 -> width.AsIs();
593 b2 -> height.AsIs();
594 m_SearchButton -> SetConstraints(b2);
595
596 wxLayoutConstraints *b3 = new wxLayoutConstraints;
597 m_SearchList = new wxListBox(dummy, wxID_HTML_SEARCHLIST, wxDefaultPosition, wxDefaultSize, 0);
598 b3 -> top.Below (m_SearchButton, 10);
599 b3 -> left.SameAs (dummy, wxLeft, 0);
600 b3 -> right.SameAs (dummy, wxRight, 0);
601 b3 -> bottom.SameAs (dummy, wxBottom, 0);
602 m_SearchList -> SetConstraints(b3);
603
604 dummy -> SetAutoLayout(TRUE);
605 dummy -> Layout();
606 m_NavigPan -> AddPage(dummy, _("Search"));
607 }
608
609 RefreshLists();
610 m_NavigPan -> Show(TRUE);
611 m_HtmlWin -> Show(TRUE);
612 m_Splitter -> SetMinimumPaneSize(20);
613 m_Splitter -> SplitVertically(m_NavigPan, m_HtmlWin, m_Cfg.sashpos);
614 if (!m_Cfg.navig_on) m_Splitter -> Unsplit(m_NavigPan);
615 wxYield();
616 }
617
618 m_Frame -> Show(TRUE);
619 wxYield();
620 }
621
622
623
624 #define MAX_ROOTS 64
625
626 void wxHtmlHelpController::CreateContents()
627 {
628 HtmlContentsItem *it;
629 wxTreeItemId roots[MAX_ROOTS];
630 bool imaged[MAX_ROOTS];
631 int count = m_ContentsCnt;
632
633 m_ContentsBox -> DeleteAllItems();
634 roots[0] = m_ContentsBox -> AddRoot(_("(Help)"));
635 imaged[0] = TRUE;
636
637 for (int i = 0; i < count; i++) {
638 it = m_Contents + i;
639 roots[it -> m_Level + 1] = m_ContentsBox -> AppendItem(roots[it -> m_Level], it -> m_Name, IMG_Page, -1, new wxHtmlHelpTreeItemData(it));
640 if (it -> m_Level == 0) {
641 m_ContentsBox -> SetItemBold(roots[1], TRUE);
642 m_ContentsBox -> SetItemImage(roots[1], IMG_Book);
643 m_ContentsBox -> SetItemSelectedImage(roots[1], IMG_Book);
644 imaged[1] = TRUE;
645 }
646 else imaged[it -> m_Level + 1] = FALSE;
647
648 if (!imaged[it -> m_Level]) {
649 m_ContentsBox -> SetItemImage(roots[it -> m_Level], IMG_Folder);
650 m_ContentsBox -> SetItemSelectedImage(roots[it -> m_Level], IMG_Folder);
651 imaged[it -> m_Level] = TRUE;
652 }
653 }
654
655 m_ContentsBox -> Expand(roots[0]);
656 }
657
658
659
660
661 void wxHtmlHelpController::CreateIndex()
662 {
663 m_IndexBox -> Clear();
664
665 for (int i = 0; i < m_IndexCnt; i++)
666 m_IndexBox -> Append(m_Index[i].m_Name, (char*)(m_Index + i));
667 }
668
669
670
671 void wxHtmlHelpController::RefreshLists()
672 {
673 if (m_Frame) {
674 CreateContents();
675 CreateIndex();
676 m_SearchList -> Clear();
677 }
678 }
679
680
681
682
683
684
685
686 void wxHtmlHelpController::ReadCustomization(wxConfigBase *cfg, wxString path)
687 {
688 wxString oldpath;
689 wxString tmp;
690
691 if (path != wxEmptyString) {
692 oldpath = cfg -> GetPath();
693 cfg -> SetPath(path);
694 }
695
696 m_Cfg.navig_on = cfg -> Read("hcNavigPanel", m_Cfg.navig_on) != 0;
697 m_Cfg.sashpos = cfg -> Read("hcSashPos", m_Cfg.sashpos);
698 m_Cfg.x = cfg -> Read("hcX", m_Cfg.x);
699 m_Cfg.y = cfg -> Read("hcY", m_Cfg.y);
700 m_Cfg.w = cfg -> Read("hcW", m_Cfg.w);
701 m_Cfg.h = cfg -> Read("hcH", m_Cfg.h);
702
703 if (path != wxEmptyString)
704 cfg -> SetPath(oldpath);
705 }
706
707
708
709 void wxHtmlHelpController::WriteCustomization(wxConfigBase *cfg, wxString path)
710 {
711 wxString oldpath;
712 wxString tmp;
713
714 if (path != wxEmptyString) {
715 oldpath = cfg -> GetPath();
716 cfg -> SetPath(path);
717 }
718
719 cfg -> Write("hcNavigPanel", m_Cfg.navig_on);
720 cfg -> Write("hcSashPos", (long)m_Cfg.sashpos);
721 cfg -> Write("hcX", (long)m_Cfg.x);
722 cfg -> Write("hcY", (long)m_Cfg.y);
723 cfg -> Write("hcW", (long)m_Cfg.w);
724 cfg -> Write("hcH", (long)m_Cfg.h);
725
726 if (path != wxEmptyString)
727 cfg -> SetPath(oldpath);
728 }
729
730
731
732
733
734 /*
735 EVENT HANDLING :
736 */
737
738
739 void wxHtmlHelpController::OnToolbar(wxCommandEvent& event)
740 {
741 switch (event.GetId()) {
742 case wxID_HTML_BACK :
743 m_HtmlWin -> HistoryBack();
744 break;
745 case wxID_HTML_FORWARD :
746 m_HtmlWin -> HistoryForward();
747 break;
748 case wxID_HTML_PANEL :
749 if (m_Splitter -> IsSplit()) {
750 m_Cfg.sashpos = m_Splitter -> GetSashPosition();
751 m_Splitter -> Unsplit(m_NavigPan);
752 }
753 else {
754 m_NavigPan -> Show(TRUE);
755 m_HtmlWin -> Show(TRUE);
756 m_Splitter -> SplitVertically(m_NavigPan, m_HtmlWin, m_Cfg.sashpos);
757 }
758 break;
759 }
760 }
761
762
763
764 void wxHtmlHelpController::OnContentsSel(wxTreeEvent& event)
765 {
766 wxHtmlHelpTreeItemData *pg;
767
768 pg = (wxHtmlHelpTreeItemData*) m_ContentsBox -> GetItemData(event.GetItem());
769 if (pg) m_HtmlWin -> LoadPage(pg -> GetPage());
770 }
771
772
773
774 void wxHtmlHelpController::OnIndexSel(wxCommandEvent& event)
775 {
776 HtmlContentsItem *it = (HtmlContentsItem*) m_IndexBox -> GetClientData(m_IndexBox -> GetSelection());
777 if (it) m_HtmlWin -> LoadPage(it -> m_Book -> GetBasePath() + it -> m_Page);
778 }
779
780
781
782 void wxHtmlHelpController::OnSearchSel(wxCommandEvent& event)
783 {
784 HtmlContentsItem *it = (HtmlContentsItem*) m_SearchList -> GetClientData(m_SearchList -> GetSelection());
785 if (it) m_HtmlWin -> LoadPage(it -> m_Book -> GetBasePath() + it -> m_Page);
786 }
787
788
789
790 void wxHtmlHelpController::OnCloseWindow(wxCloseEvent& event)
791 {
792 int a, b;
793
794 m_Cfg.navig_on = m_Splitter -> IsSplit();
795 if (m_Cfg.navig_on)
796 m_Cfg.sashpos = m_Splitter -> GetSashPosition();
797 m_Frame -> GetPosition(&a, &b);
798 m_Cfg.x = a, m_Cfg.y = b;
799 m_Frame -> GetSize(&a, &b);
800 m_Cfg.w = a, m_Cfg.h = b;
801
802 if (m_Config) {
803 WriteCustomization(m_Config, m_ConfigRoot);
804 m_HtmlWin -> WriteCustomization(m_Config, m_ConfigRoot);
805 }
806 m_Frame = NULL;
807
808 event.Skip();
809 }
810
811
812
813 void wxHtmlHelpController::OnSearch(wxCommandEvent& event)
814 {
815 wxString sr = m_SearchText -> GetLineText(0);
816
817 if (sr != wxEmptyString) KeywordSearch(sr);
818 }
819
820
821
822 BEGIN_EVENT_TABLE(wxHtmlHelpController, wxEvtHandler)
823 EVT_TOOL_RANGE(wxID_HTML_PANEL, wxID_HTML_FORWARD, wxHtmlHelpController::OnToolbar)
824 EVT_TREE_SEL_CHANGED(wxID_HTML_TREECTRL, wxHtmlHelpController::OnContentsSel)
825 EVT_LISTBOX(wxID_HTML_INDEXLIST, wxHtmlHelpController::OnIndexSel)
826 EVT_LISTBOX(wxID_HTML_SEARCHLIST, wxHtmlHelpController::OnSearchSel)
827 EVT_CLOSE(wxHtmlHelpController::OnCloseWindow)
828 EVT_BUTTON(wxID_HTML_SEARCHBUTTON, wxHtmlHelpController::OnSearch)
829 EVT_TEXT_ENTER(wxID_HTML_SEARCHTEXT, wxHtmlHelpController::OnSearch)
830 END_EVENT_TABLE()
831
832
833
834 #endif
835