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