]> git.saurik.com Git - wxWidgets.git/blob - utils/wxPython/modules/html/helpsys.cpp
added wxHtmlHelpController and -System wrappers. See README for some remarks
[wxWidgets.git] / utils / wxPython / modules / html / helpsys.cpp
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
46 bool wxHtmlHelpSystem::AddBookParam(const wxString& title, const wxString& contfile,
47 const wxString& indexfile, const wxString& deftopic,
48 const wxString& path, bool show_wait_msg)
49 {
50 wxFileSystem fsys;
51 wxFSFile *fi;
52 HtmlBookRecord *bookr;
53 wxString safetitle;
54
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);
92
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 {
134 wxTreeCtrl* tree;
135 tree = new wxTreeCtrl(parent, wxID_HTML_TREECTRL, wxDefaultPosition,
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
146 void wxHtmlHelpSystem::SetControls(wxFrame* frame, wxHtmlWindow* htmlwin,
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