]>
Commit | Line | Data |
---|---|---|
5526e819 VS |
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__ | |
4dcaf11a | 10 | #pragma implementation "htmlhelp.h" |
5526e819 VS |
11 | #endif |
12 | ||
4dcaf11a | 13 | #include "wx/wxprec.h" |
5526e819 | 14 | |
5526e819 VS |
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++) { | |
2776d7c3 VS |
157 | delete[] m_Contents[i].m_Page; |
158 | delete[] m_Contents[i].m_Name; | |
5526e819 VS |
159 | } |
160 | free(m_Contents); | |
161 | } | |
162 | if (m_Index) { | |
163 | for (i = 0; i < m_IndexCnt; i++) { | |
2776d7c3 VS |
164 | delete[] m_Index[i].m_Page; |
165 | delete[] m_Index[i].m_Name; | |
5526e819 VS |
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 | ||
602e68af | 221 | bool wxHtmlHelpController::AddBook(const wxString& book, bool show_wait_msg) |
5526e819 VS |
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(); | |
259d1674 | 245 | sz = s -> GetSize(); |
2776d7c3 | 246 | buff = new char[sz+1]; |
5526e819 VS |
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 | } | |
2776d7c3 | 262 | delete[] buff; |
5526e819 VS |
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; | |
2776d7c3 | 270 | m_Contents[m_ContentsCnt].m_Page = new char[start.Length() + 1]; |
5526e819 | 271 | strcpy(m_Contents[m_ContentsCnt].m_Page, start.c_str()); |
2776d7c3 | 272 | m_Contents[m_ContentsCnt].m_Name = new char [title.Length() + 1]; |
5526e819 VS |
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(); | |
2776d7c3 | 530 | m_Frame -> Show(TRUE); |
5526e819 VS |
531 | return; |
532 | } | |
533 | ||
602e68af | 534 | #if wxUSE_BUSYINFO |
5526e819 | 535 | wxBusyInfo busyinfo(_("Preparing help window...")); |
602e68af | 536 | #endif |
5526e819 VS |
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 | ||
259d1674 | 726 | m_Cfg.navig_on = cfg -> Read("hcNavigPanel", m_Cfg.navig_on) != 0; |
5526e819 VS |
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 |