]> git.saurik.com Git - wxWidgets.git/blame - src/generic/helphtml.cpp
moved patterns to static structures, added resouce loader struct where needed
[wxWidgets.git] / src / generic / helphtml.cpp
CommitLineData
f96b60aa
VZ
1/////////////////////////////////////////////////////////////////////////////
2// Name: helphtml.cpp
3// Purpose: base class for html help systems
4// Author: Karsten Ballueder
5// Modified by:
6// Created: 04/01/98
7// RCS-ID: $Id$
8// Copyright: (c) Karsten Ballueder
9// Licence: wxWindows licence
10/////////////////////////////////////////////////////////////////////////////
11
afcaf277
KB
12#ifdef __GNUG__
13# pragma implementation "helphtml.h"
14#endif
15
f96b60aa
VZ
16#include "wx/wxprec.h"
17
18#ifdef __BORLANDC__
19 #pragma hdrstop
20#endif
afcaf277 21
31528cd3
VZ
22#if wxUSE_HELP
23
f96b60aa
VZ
24#ifndef WX_PRECOMP
25 #include "wx/setup.h"
26 #include "wx/string.h"
27 #include "wx/utils.h"
28 #include "wx/list.h"
29 #include "wx/intl.h"
e179bd65
RR
30 #include "wx/msgdlg.h"
31 #include "wx/choicdlg.h"
f96b60aa 32#endif
afcaf277 33
f96b60aa
VZ
34#include "wx/helpbase.h"
35#include "wx/generic/helpext.h"
36
37#include <stdio.h>
38#include <ctype.h>
585ae8cb 39#ifndef __MWERKS__
f96b60aa 40#include <sys/stat.h>
585ae8cb 41#endif
f96b60aa 42
004fd0c8 43#if !defined(__WINDOWS__) && !defined(__OS2__)
f96b60aa
VZ
44 #include <unistd.h>
45#endif
afcaf277 46
8d184505
KB
47#define CONTENTS_ID 0
48
afcaf277
KB
49class wxExtHelpMapEntry : public wxObject
50{
51public:
52 int id;
53 wxString url;
54 wxString doc;
55 wxExtHelpMapEntry(int iid, wxString const &iurl, wxString const &idoc)
56 { id = iid; url = iurl; doc = idoc; }
57};
58
afcaf277 59IMPLEMENT_ABSTRACT_CLASS(wxHTMLHelpControllerBase, wxHelpControllerBase)
85833f5c 60
afcaf277
KB
61/**
62 This class implements help via an external browser.
63 It requires the name of a directory containing the documentation
64 and a file mapping numerical Section numbers to relative URLS.
65*/
66
85833f5c 67wxHTMLHelpControllerBase::wxHTMLHelpControllerBase()
afcaf277
KB
68{
69 m_MapList = (wxList*) NULL;
70 m_NumOfEntries = 0;
71}
72
73void
85833f5c 74wxHTMLHelpControllerBase::DeleteList()
afcaf277
KB
75{
76 if(m_MapList)
77 {
78 wxNode *node = m_MapList->First();
79 while (node)
80 {
81 delete (wxExtHelpMapEntry *)node->Data();
82 delete node;
83 node = m_MapList->First();
84 }
85 delete m_MapList;
86 m_MapList = (wxList*) NULL;
87 }
88}
89
85833f5c 90wxHTMLHelpControllerBase::~wxHTMLHelpControllerBase()
afcaf277
KB
91{
92 DeleteList();
93}
94
95/** This must be called to tell the controller where to find the
96 documentation.
97 @param file - NOT a filename, but a directory name.
98 @return true on success
99*/
100bool
101wxHTMLHelpControllerBase::Initialize(const wxString& file)
102{
103 return LoadFile(file);
104}
105
106
107// ifile is the name of the base help directory
108bool
109wxHTMLHelpControllerBase::LoadFile(const wxString& ifile)
110{
111 wxString mapFile, file, url, doc;
112 int id,i,len;
113 char buffer[WXEXTHELP_BUFLEN];
85833f5c 114
afcaf277
KB
115 wxBusyCursor b; // display a busy cursor
116
117 if(! ifile.IsEmpty())
118 {
119 file = ifile;
120 if(! wxIsAbsolutePath(file))
121 {
87138c52 122 wxChar* f = wxGetWorkingDirectory();
afcaf277
KB
123 file = f;
124 delete[] f; // wxGetWorkingDirectory returns new memory
125 file << WXEXTHELP_SEPARATOR << ifile;
126 }
127 else
128 file = ifile;
129
ce4169a4 130#if wxUSE_INTL
afcaf277
KB
131 // If a locale is set, look in file/localename, i.e.
132 // If passed "/usr/local/myapp/help" and the current wxLocale is
133 // set to be "de", then look in "/usr/local/myapp/help/de/"
134 // first and fall back to "/usr/local/myapp/help" if that
135 // doesn't exist.
136 if(wxGetLocale() && !wxGetLocale()->GetName().IsEmpty())
137 {
138 wxString newfile;
139 newfile << WXEXTHELP_SEPARATOR << wxGetLocale()->GetName();
140 if(wxDirExists(newfile))
141 file = newfile;
cfad3750
KB
142 else
143 {
144 newfile = WXEXTHELP_SEPARATOR;
87138c52 145 const wxChar *cptr = wxGetLocale()->GetName().c_str();
223d09f6 146 while(*cptr && *cptr != wxT('_'))
cfad3750
KB
147 newfile << *(cptr++);
148 if(wxDirExists(newfile))
149 file = newfile;
150 }
afcaf277 151 }
ce4169a4 152#endif
85833f5c 153
afcaf277
KB
154 if(! wxDirExists(file))
155 return FALSE;
85833f5c 156
afcaf277
KB
157 mapFile << file << WXEXTHELP_SEPARATOR << WXEXTHELP_MAPFILE;
158 }
159 else // try to reload old file
160 mapFile = m_MapFile;
161
162 if(! wxFileExists(mapFile))
163 return FALSE;
164
165 DeleteList();
166 m_MapList = new wxList;
167 m_NumOfEntries = 0;
85833f5c 168
63c8fa95 169 FILE *input = wxFopen(mapFile,wxT("rt"));
afcaf277
KB
170 if(! input)
171 return FALSE;
172 do
173 {
174 if(fgets(buffer,WXEXTHELP_BUFLEN,input) && *buffer != WXEXTHELP_COMMENTCHAR)
175 {
176 len = strlen(buffer);
177 if(buffer[len-1] == '\n')
178 buffer[len-1] = '\0'; // cut of trailing newline
179 if(sscanf(buffer,"%d", &id) != 1)
180 break; // error
181 for(i=0; isdigit(buffer[i])||isspace(buffer[i])||buffer[i]=='-'; i++)
182 ; // find begin of URL
183 url = "";
184 while(buffer[i] && ! isspace(buffer[i]) && buffer[i] !=
185 WXEXTHELP_COMMENTCHAR)
186 url << buffer[i++];
187 while(buffer[i] && buffer[i] != WXEXTHELP_COMMENTCHAR)
188 i++;
189 doc = "";
190 if(buffer[i])
191 doc = (buffer + i + 1); // skip the comment character
192 m_MapList->Append(new wxExtHelpMapEntry(id,url,doc));
193 m_NumOfEntries++;
194 }
195 }while(! feof(input));
196 fclose(input);
85833f5c 197
afcaf277
KB
198 m_MapFile = file; // now it's valid
199 return TRUE;
200}
201
202
203bool
85833f5c 204wxHTMLHelpControllerBase::DisplayContents()
afcaf277
KB
205{
206 if(! m_NumOfEntries)
207 return FALSE;
8dd71e2b 208
8d184505
KB
209 wxString contents;
210 wxNode *node = m_MapList->First();
211 wxExtHelpMapEntry *entry;
212 while(node)
213 {
214 entry = (wxExtHelpMapEntry *)node->Data();
215 if(entry->id == CONTENTS_ID)
216 {
217 contents = entry->url;
218 break;
219 }
220 node = node->Next();
221 }
222
223 bool rc = FALSE;
3bcf00ab
KB
224 wxString file;
225 file << m_MapFile << WXEXTHELP_SEPARATOR << contents;
223d09f6
KB
226 if(file.Contains(wxT('#')))
227 file = file.BeforeLast(wxT('#'));
3bcf00ab 228 if(contents.Length() && wxFileExists(file))
8d184505 229 rc = DisplaySection(CONTENTS_ID);
004fd0c8 230
8d184505 231 // if not found, open homemade toc:
223d09f6 232 return rc ? TRUE : KeywordSearch(wxT(""));
afcaf277 233}
85833f5c 234
afcaf277
KB
235bool
236wxHTMLHelpControllerBase::DisplaySection(int sectionNo)
237{
238 if(! m_NumOfEntries)
239 return FALSE;
240
241 wxBusyCursor b; // display a busy cursor
242 wxNode *node = m_MapList->First();
243 wxExtHelpMapEntry *entry;
244 while(node)
245 {
246 entry = (wxExtHelpMapEntry *)node->Data();
247 if(entry->id == sectionNo)
248 return DisplayHelp(entry->url);
249 node = node->Next();
250 }
251 return FALSE;
252}
253
f6bcfd97
BP
254bool wxHTMLHelpControllerBase::DisplaySection(const wxString& section)
255{
256 bool isFilename = (section.Find(wxT(".htm")) != -1);
257
258 if (isFilename)
259 return DisplayHelp(section);
260 else
261 return KeywordSearch(section);
262}
263
afcaf277
KB
264bool
265wxHTMLHelpControllerBase::DisplayBlock(long blockNo)
266{
267 return DisplaySection((int)blockNo);
268}
269
270bool
271wxHTMLHelpControllerBase::KeywordSearch(const wxString& k)
272{
273 if(! m_NumOfEntries)
274 return FALSE;
275
afcaf277
KB
276 wxString *choices = new wxString[m_NumOfEntries];
277 wxString *urls = new wxString[m_NumOfEntries];
278 wxString compA, compB;
85833f5c 279
afcaf277
KB
280 int idx = 0, j;
281 bool rc;
282 bool showAll = k.IsEmpty();
283 wxNode *node = m_MapList->First();
284 wxExtHelpMapEntry *entry;
85833f5c 285
afcaf277 286 {
0bcddc59
KB
287 wxBusyCursor b; // display a busy cursor
288 compA = k; compA.LowerCase(); // we compare case insensitive
289 while(node)
afcaf277 290 {
0bcddc59
KB
291 entry = (wxExtHelpMapEntry *)node->Data();
292 compB = entry->doc; compB.LowerCase();
293 if((showAll || compB.Contains(k)) && ! compB.IsEmpty())
294 {
295 urls[idx] = entry->url;
296 // doesn't work:
297 // choices[idx] = (**i).doc.Contains((**i).doc.Before(WXEXTHELP_COMMENTCHAR));
298 //if(choices[idx].IsEmpty()) // didn't contain the ';'
299 // choices[idx] = (**i).doc;
300 choices[idx] = "";
301 for(j=0;entry->doc.c_str()[j]
302 && entry->doc.c_str()[j] != WXEXTHELP_COMMENTCHAR; j++)
303 choices[idx] << entry->doc.c_str()[j];
304 idx++;
305 }
306 node = node->Next();
afcaf277 307 }
afcaf277 308 }
004fd0c8 309
afcaf277
KB
310 if(idx == 1)
311 rc = DisplayHelp(urls[0]);
312 else if(idx == 0)
313 {
314 wxMessageBox(_("No entries found."));
315 rc = FALSE;
316 }
317 else
318 {
319 idx = wxGetSingleChoiceIndex(showAll ? _("Help Index") : _("Relevant entries:"),
320 showAll ? _("Help Index") : _("Entries found"),
321 idx,choices);
322 if(idx != -1)
323 rc = DisplayHelp(urls[idx]);
324 else
325 rc = FALSE;
326 }
327 delete[] urls;
328 delete[] choices;
85833f5c 329
afcaf277
KB
330 return rc;
331}
332
333
334bool
85833f5c 335wxHTMLHelpControllerBase::Quit()
afcaf277
KB
336{
337 return TRUE;
338}
339
340void
85833f5c 341wxHTMLHelpControllerBase::OnQuit()
afcaf277
KB
342{
343}
344
31528cd3 345#endif // wxUSE_HELP