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