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