]>
Commit | Line | Data |
---|---|---|
5ca24bf4 HH |
1 | /* htmlsys.h : wxHtmlHelpSystem is an extension of the wxHtmlHelpController. |
2 | * mainly does two things: | |
3 | * - extend the interface somewhat so the programmer can dictate most of the | |
4 | * look and feel of the htmlhelp frame. | |
5 | * - make some protected functions public (adding _ to the function name) so | |
6 | * that SWIG can wrap them. | |
7 | * | |
8 | * Harm van der Heijden 32aug1999 | |
9 | */ | |
10 | #include "helpsys.h" | |
11 | #include <wx/wx.h> | |
12 | #include <wx/wfstream.h> | |
13 | #include <wx/busyinfo.h> | |
14 | ||
15 | // Bitmaps: | |
16 | #ifndef __WXMSW__ | |
17 | #include "bitmaps/panel.xpm" | |
18 | #include "bitmaps/back.xpm" | |
19 | #include "bitmaps/forward.xpm" | |
20 | #include "bitmaps/book.xpm" | |
21 | #include "bitmaps/folder.xpm" | |
22 | #include "bitmaps/page.xpm" | |
23 | #endif | |
24 | ||
25 | IMPLEMENT_DYNAMIC_CLASS(wxHtmlHelpSystem, wxHtmlHelpController) | |
26 | ||
27 | // The two static funtions below are also defined in htmlhelp.cpp | |
28 | // maybe they should be protected class functions. | |
29 | static wxString SafeFileName(const wxString& s) | |
30 | { | |
31 | wxString res = s; | |
32 | res.Replace(":", "_", TRUE); | |
33 | res.Replace(" ", "_", TRUE); | |
34 | res.Replace("/", "_", TRUE); | |
35 | res.Replace("\\", "_", TRUE); | |
36 | res.Replace("#", "_", TRUE); | |
37 | res.Replace(".", "_", TRUE); | |
38 | return res; | |
39 | } | |
40 | ||
41 | static int IndexCompareFunc(const void *a, const void *b) | |
42 | { | |
43 | return strcmp(((HtmlContentsItem*)a) -> m_Name, ((HtmlContentsItem*)b) -> m_Name); | |
44 | } | |
45 | ||
0f66a9f3 RD |
46 | bool wxHtmlHelpSystem::AddBookParam(const wxString& title, const wxString& contfile, |
47 | const wxString& indexfile, const wxString& deftopic, | |
5ca24bf4 HH |
48 | const wxString& path, bool show_wait_msg) |
49 | { | |
50 | wxFileSystem fsys; | |
51 | wxFSFile *fi; | |
52 | HtmlBookRecord *bookr; | |
53 | wxString safetitle; | |
0f66a9f3 | 54 | |
5ca24bf4 HH |
55 | if (! path.IsEmpty()) |
56 | // workaround for bug in ChangePathTo(name, TRUE) | |
57 | fsys.ChangePathTo(path+"/gaga"); | |
58 | ||
59 | bookr = new HtmlBookRecord(path+'/', title, deftopic); | |
60 | ||
61 | if (m_ContentsCnt % HTML_REALLOC_STEP == 0) | |
62 | m_Contents = (HtmlContentsItem*) realloc(m_Contents, (m_ContentsCnt + HTML_REALLOC_STEP) * sizeof(HtmlContentsItem)); | |
63 | m_Contents[m_ContentsCnt].m_Level = 0; | |
64 | m_Contents[m_ContentsCnt].m_ID = 0; | |
65 | m_Contents[m_ContentsCnt].m_Page = new char[deftopic.Length() + 1]; | |
66 | strcpy(m_Contents[m_ContentsCnt].m_Page, deftopic.c_str()); | |
67 | m_Contents[m_ContentsCnt].m_Name = new char [title.Length() + 1]; | |
68 | strcpy(m_Contents[m_ContentsCnt].m_Name, title.c_str()); | |
69 | m_Contents[m_ContentsCnt].m_Book = bookr; | |
70 | m_ContentsCnt++; | |
71 | ||
72 | // Try to find cached binary versions: | |
73 | safetitle = SafeFileName(title); | |
74 | fi = fsys.OpenFile(safetitle + ".cached"); | |
75 | if (fi == NULL) fi = fsys.OpenFile(m_TempPath + safetitle + ".cached"); | |
76 | if ((fi == NULL) || (m_TempPath == wxEmptyString)) { | |
77 | LoadMSProject(bookr, fsys, indexfile, contfile, show_wait_msg); | |
78 | if (m_TempPath != wxEmptyString) { | |
79 | wxFileOutputStream *outs = new wxFileOutputStream(m_TempPath + safetitle + ".cached"); | |
80 | SaveCachedBook(bookr, outs); | |
81 | delete outs; | |
82 | } | |
83 | } | |
84 | else { | |
85 | LoadCachedBook(bookr, fi -> GetStream()); | |
86 | delete fi; | |
87 | } | |
88 | ||
89 | m_BookRecords.Add(bookr); | |
90 | if (m_IndexCnt > 0) | |
91 | qsort(m_Index, m_IndexCnt, sizeof(HtmlContentsItem), IndexCompareFunc); | |
0f66a9f3 | 92 | |
5ca24bf4 HH |
93 | return TRUE; |
94 | } | |
95 | ||
96 | wxToolBar* wxHtmlHelpSystem::CreateToolBar(wxFrame* frame) | |
97 | { | |
98 | wxToolBar *toolBar; | |
99 | toolBar = frame -> CreateToolBar(wxNO_BORDER | wxTB_HORIZONTAL | wxTB_FLAT | wxTB_DOCKABLE); | |
100 | toolBar -> SetMargins(2, 2); | |
101 | wxBitmap* toolBarBitmaps[3]; | |
102 | ||
103 | #ifdef __WXMSW__ | |
104 | toolBarBitmaps[0] = new wxBitmap("panel"); | |
105 | toolBarBitmaps[1] = new wxBitmap("back"); | |
106 | toolBarBitmaps[2] = new wxBitmap("forward"); | |
107 | int width = 24; | |
108 | #else | |
109 | toolBarBitmaps[0] = new wxBitmap(panel_xpm); | |
110 | toolBarBitmaps[1] = new wxBitmap(back_xpm); | |
111 | toolBarBitmaps[2] = new wxBitmap(forward_xpm); | |
112 | int width = 16; | |
113 | #endif | |
114 | ||
115 | int currentX = 5; | |
116 | ||
117 | toolBar -> AddTool(wxID_HTML_PANEL, *(toolBarBitmaps[0]), wxNullBitmap, FALSE, currentX, -1, (wxObject *) NULL, _("Show/hide navigation panel")); | |
118 | currentX += width + 5; | |
119 | toolBar -> AddSeparator(); | |
120 | toolBar -> AddTool(wxID_HTML_BACK, *(toolBarBitmaps[1]), wxNullBitmap, FALSE, currentX, -1, (wxObject *) NULL, _("Go back to the previous HTML page")); | |
121 | currentX += width + 5; | |
122 | toolBar -> AddTool(wxID_HTML_FORWARD, *(toolBarBitmaps[2]), wxNullBitmap, FALSE, currentX, -1, (wxObject *) NULL, _("Go forward to the next HTML page")); | |
123 | currentX += width + 5; | |
124 | ||
125 | toolBar -> Realize(); | |
126 | ||
127 | // Can delete the bitmaps since they're reference counted | |
128 | for (int i = 0; i < 3; i++) delete toolBarBitmaps[i]; | |
129 | return toolBar; | |
130 | } | |
131 | ||
132 | wxTreeCtrl* wxHtmlHelpSystem::CreateContentsTree(wxWindow* parent) | |
133 | { | |
0f66a9f3 RD |
134 | wxTreeCtrl* tree; |
135 | tree = new wxTreeCtrl(parent, wxID_HTML_TREECTRL, wxDefaultPosition, | |
5ca24bf4 HH |
136 | wxDefaultSize, wxTR_HAS_BUTTONS | wxSUNKEN_BORDER); |
137 | tree -> SetImageList(m_ContentsImageList); | |
138 | return tree; | |
139 | } | |
140 | ||
141 | wxListBox* wxHtmlHelpSystem::CreateIndexList(wxWindow* parent) | |
142 | { | |
143 | return new wxListBox(parent, wxID_HTML_INDEXLIST, wxDefaultPosition, wxDefaultSize, 0); | |
144 | } | |
145 | ||
0f66a9f3 | 146 | void wxHtmlHelpSystem::SetControls(wxFrame* frame, wxHtmlWindow* htmlwin, |
5ca24bf4 HH |
147 | wxTreeCtrl* contents, wxListBox* index, |
148 | wxListBox* searchlist) | |
149 | { | |
150 | m_Frame = frame; | |
151 | m_HtmlWin = htmlwin; | |
152 | m_ContentsBox = contents; | |
153 | m_IndexBox = index; | |
154 | m_SearchList = searchlist; | |
155 | m_SearchText = NULL; // provide your own input box | |
156 | /* if you're setting your own controls, you and your event handlers are | |
157 | * responsible for any splitter and notebook adjustments, not the | |
158 | * htmlhelp framework */ | |
159 | m_Splitter = NULL; | |
160 | m_NavigPan = NULL; | |
161 | RefreshLists(); | |
162 | } | |
163 | ||
164 | void wxHtmlHelpSystem::CreateHelpWindow() | |
165 | { | |
166 | wxBusyCursor cur; | |
167 | wxString oldpath; | |
168 | wxStatusBar *sbar; | |
169 | ||
170 | if (m_Frame) { | |
171 | m_Frame -> Raise(); | |
172 | m_Frame -> Show(TRUE); | |
173 | return; | |
174 | } | |
175 | ||
176 | #if wxUSE_BUSYINFO | |
177 | wxBusyInfo busyinfo(_("Preparing help window...")); | |
178 | #endif | |
179 | ||
180 | if (m_Config) ReadCustomization(m_Config, m_ConfigRoot); | |
181 | ||
182 | m_Frame = new wxFrame(NULL, -1, "", wxPoint(m_Cfg.x, m_Cfg.y), wxSize(m_Cfg.w, m_Cfg.h)); | |
183 | m_Frame -> PushEventHandler(this); | |
184 | sbar = m_Frame -> CreateStatusBar(); | |
185 | ||
186 | CreateToolBar(m_Frame); | |
187 | ||
188 | { | |
189 | m_Splitter = new wxSplitterWindow(m_Frame); | |
190 | ||
191 | m_HtmlWin = new wxHtmlWindow(m_Splitter); | |
192 | m_HtmlWin -> SetRelatedFrame(m_Frame, m_TitleFormat); | |
193 | m_HtmlWin -> SetRelatedStatusBar(0); | |
194 | if (m_Config) m_HtmlWin -> ReadCustomization(m_Config, m_ConfigRoot); | |
195 | ||
196 | m_NavigPan = new wxNotebook(m_Splitter, wxID_HTML_NOTEBOOK, wxDefaultPosition, wxDefaultSize); | |
197 | if (m_ContentsCnt) { | |
198 | m_ContentsBox = CreateContentsTree(m_NavigPan); | |
199 | m_NavigPan -> AddPage(m_ContentsBox, _("Contents")); | |
200 | } | |
201 | ||
202 | if (m_IndexCnt) { | |
203 | wxWindow *dummy = new wxPanel(m_NavigPan, wxID_HTML_INDEXPAGE); | |
204 | wxLayoutConstraints *b1 = new wxLayoutConstraints; | |
205 | b1 -> top.SameAs (dummy, wxTop, 0); | |
206 | b1 -> left.SameAs (dummy, wxLeft, 0); | |
207 | b1 -> width.PercentOf (dummy, wxWidth, 100); | |
208 | b1 -> bottom.SameAs (dummy, wxBottom, 0); | |
209 | m_IndexBox = CreateIndexList(dummy); | |
210 | m_IndexBox -> SetConstraints(b1); | |
211 | ||
212 | dummy -> SetAutoLayout(TRUE); | |
213 | m_NavigPan -> AddPage(dummy, _("Index")); | |
214 | } | |
215 | ||
216 | { | |
217 | wxWindow *dummy = new wxPanel(m_NavigPan, wxID_HTML_SEARCHPAGE); | |
218 | ||
219 | wxLayoutConstraints *b1 = new wxLayoutConstraints; | |
220 | m_SearchText = new wxTextCtrl(dummy, wxID_HTML_SEARCHTEXT); | |
221 | b1 -> top.SameAs (dummy, wxTop, 0); | |
222 | b1 -> left.SameAs (dummy, wxLeft, 0); | |
223 | b1 -> right.SameAs (dummy, wxRight, 0); | |
224 | b1 -> height.AsIs(); | |
225 | m_SearchText -> SetConstraints(b1); | |
226 | ||
227 | wxLayoutConstraints *b2 = new wxLayoutConstraints; | |
228 | m_SearchButton = new wxButton(dummy, wxID_HTML_SEARCHBUTTON, _("Search!")); | |
229 | b2 -> top.Below (m_SearchText, 10); | |
230 | b2 -> right.SameAs (dummy, wxRight, 10); | |
231 | b2 -> width.AsIs(); | |
232 | b2 -> height.AsIs(); | |
233 | m_SearchButton -> SetConstraints(b2); | |
234 | ||
235 | wxLayoutConstraints *b3 = new wxLayoutConstraints; | |
236 | m_SearchList = new wxListBox(dummy, wxID_HTML_SEARCHLIST, wxDefaultPosition, wxDefaultSize, 0); | |
237 | b3 -> top.Below (m_SearchButton, 10); | |
238 | b3 -> left.SameAs (dummy, wxLeft, 0); | |
239 | b3 -> right.SameAs (dummy, wxRight, 0); | |
240 | b3 -> bottom.SameAs (dummy, wxBottom, 0); | |
241 | m_SearchList -> SetConstraints(b3); | |
242 | ||
243 | dummy -> SetAutoLayout(TRUE); | |
244 | dummy -> Layout(); | |
245 | m_NavigPan -> AddPage(dummy, _("Search")); | |
246 | } | |
247 | ||
248 | RefreshLists(); | |
249 | m_NavigPan -> Show(TRUE); | |
250 | m_HtmlWin -> Show(TRUE); | |
251 | m_Splitter -> SetMinimumPaneSize(20); | |
252 | m_Splitter -> SplitVertically(m_NavigPan, m_HtmlWin, m_Cfg.sashpos); | |
253 | if (!m_Cfg.navig_on) m_Splitter -> Unsplit(m_NavigPan); | |
254 | wxYield(); | |
255 | } | |
256 | ||
257 | m_Frame -> Show(TRUE); | |
258 | wxYield(); | |
259 | } | |
260 | ||
261 | void wxHtmlHelpSystem::RefreshLists() | |
262 | { | |
263 | if (m_Frame) { | |
264 | CreateContents(); | |
265 | CreateIndex(); | |
266 | if (m_SearchList) | |
267 | m_SearchList -> Clear(); | |
268 | } | |
269 | } | |
270 | ||
271 | void wxHtmlHelpSystem::OnToolbar(wxCommandEvent& event) | |
272 | { | |
273 | switch (event.GetId()) { | |
274 | case wxID_HTML_BACK : | |
275 | if (m_HtmlWin) m_HtmlWin -> HistoryBack(); | |
276 | break; | |
277 | case wxID_HTML_FORWARD : | |
278 | if (m_HtmlWin) m_HtmlWin -> HistoryForward(); | |
279 | break; | |
280 | case wxID_HTML_PANEL : | |
281 | if (! (m_Splitter && m_NavigPan)) | |
282 | return; | |
283 | if (m_Splitter -> IsSplit()) { | |
284 | m_Cfg.sashpos = m_Splitter -> GetSashPosition(); | |
285 | m_Splitter -> Unsplit(m_NavigPan); | |
286 | } | |
287 | else { | |
288 | m_NavigPan -> Show(TRUE); | |
289 | m_HtmlWin -> Show(TRUE); | |
290 | m_Splitter -> SplitVertically(m_NavigPan, m_HtmlWin, m_Cfg.sashpos); | |
291 | } | |
292 | break; | |
293 | } | |
294 | } | |
295 | ||
296 | void wxHtmlHelpSystem::OnCloseWindow(wxCloseEvent& event) | |
297 | { | |
298 | int a, b; | |
299 | ||
300 | if (m_Splitter && m_NavigPan) { | |
301 | m_Cfg.navig_on = m_Splitter -> IsSplit(); | |
302 | if (m_Cfg.navig_on) | |
303 | m_Cfg.sashpos = m_Splitter -> GetSashPosition(); | |
304 | m_Frame -> GetPosition(&a, &b); | |
305 | m_Cfg.x = a, m_Cfg.y = b; | |
306 | m_Frame -> GetSize(&a, &b); | |
307 | m_Cfg.w = a, m_Cfg.h = b; | |
308 | } | |
309 | if (m_Config) { | |
310 | WriteCustomization(m_Config, m_ConfigRoot); | |
311 | m_HtmlWin -> WriteCustomization(m_Config, m_ConfigRoot); | |
312 | } | |
313 | m_Frame = NULL; | |
314 | ||
315 | //event.Skip(); | |
316 | } | |
317 | ||
318 | BEGIN_EVENT_TABLE(wxHtmlHelpSystem, wxHtmlHelpController) | |
319 | EVT_TOOL_RANGE(wxID_HTML_PANEL, wxID_HTML_FORWARD, wxHtmlHelpSystem::OnToolbar) | |
320 | EVT_CLOSE(wxHtmlHelpSystem::OnCloseWindow) | |
321 | END_EVENT_TABLE() | |
322 |