• Skip to content
  • Skip to link menu
Trinity API Reference
  • Trinity API Reference
  • kdoctools
 

kdoctools

  • kdoctools
tdeio_help.cpp
1#include <config.h>
2
3#ifdef HAVE_SYS_TYPES_H
4# include <sys/types.h>
5#endif
6#ifdef HAVE_SYS_STAT_H
7# include <sys/stat.h>
8#endif
9
10#include <errno.h>
11#include <fcntl.h>
12#ifdef HAVE_STDIO_H
13# include <stdio.h>
14#endif
15#ifdef HAVE_STDLIB_H
16# include <stdlib.h>
17#endif
18
19#include <tqvaluelist.h>
20#include <tqfileinfo.h>
21#include <tqfile.h>
22#include <tqtextstream.h>
23#include <tqregexp.h>
24#include <tqtextcodec.h>
25
26#include <kdebug.h>
27#include <kurl.h>
28#include <tdeglobal.h>
29#include <tdelocale.h>
30#include <tdestandarddirs.h>
31#include <kinstance.h>
32
33#include "tdeio_help.h"
34#include <libxslt/xsltutils.h>
35#include <libxslt/transform.h>
36#include "xslt.h"
37
38using namespace TDEIO;
39
40TQString HelpProtocol::langLookup(const TQString &fname)
41{
42 TQStringList search;
43
44 // assemble the local search paths
45 const TQStringList localDoc = TDEGlobal::dirs()->resourceDirs("html") + TDEGlobal::dirs()->resourceDirs("html-bundle");
46
47 TQStringList langs = TDEGlobal::locale()->languageList();
48 langs.append( "en" );
49 langs.remove( "C" );
50
51 // this is kind of compat hack as we install our docs in en/ but the
52 // default language is en_US
53 for (TQStringList::Iterator it = langs.begin(); it != langs.end(); ++it)
54 if ( *it == "en_US" )
55 *it = "en";
56
57 // look up the different languages
58 int ldCount = localDoc.count();
59 for (int id=0; id < ldCount; id++)
60 {
61 TQStringList::ConstIterator lang;
62 for (lang = langs.begin(); lang != langs.end(); ++lang)
63 search.append(TQString("%1%2/%3").arg(localDoc[id], *lang, fname));
64 }
65
66 // try to locate the file
67 TQStringList::Iterator it;
68 for (it = search.begin(); it != search.end(); ++it)
69 {
70 kdDebug( 7119 ) << "Looking for help in: " << *it << endl;
71
72 TQFileInfo info(*it);
73 if (info.exists() && info.isFile() && info.isReadable())
74 return *it;
75
76 if ( ( *it ).right( 5 ) == ".html" )
77 {
78 TQString file = (*it).left((*it).findRev('/')) + "/index.docbook";
79 kdDebug( 7119 ) << "Looking for help in: " << file << endl;
80 info.setFile(file);
81 if (info.exists() && info.isFile() && info.isReadable())
82 return *it;
83 }
84 }
85
86
87 return TQString::null;
88}
89
90
91TQString HelpProtocol::lookupFile(const TQString &fname, const TQString &query, bool &redirect)
92{
93 redirect = false;
94 TQString result = langLookup(fname);
95 if (result.isEmpty())
96 {
97 result = langLookup(fname+"/index.html");
98 if (!result.isEmpty())
99 {
100 KURL red("help:/");
101 red.setPath( fname+"/index.html" );
102 red.setQuery( query );
103 redirection(red);
104 kdDebug( 7119 ) << "redirect to " << red.url() << endl;
105 redirect = true;
106 }
107 else
108 {
109 const TQString helpNotFound("khelpcenter/helpnotfound/index.html");
110 result = langLookup(helpNotFound);
111 if (!result.isEmpty())
112 {
113 KURL red("help:/");
114 red.setPath(helpNotFound);
115 red.setQuery(query);
116 redirection(red);
117 kdDebug( 7119 ) << "redirect to " << red.url() << endl;
118 redirect = true;
119 }
120 else
121 {
122 unicodeError(i18n("Sorry, there is no documentation available at all for %1." ).arg(fname));
123 finished();
124 return TQString::null;
125 }
126 }
127 } else
128 kdDebug( 7119 ) << "result " << result << endl;
129
130 return result;
131}
132
133
134void HelpProtocol::unicodeError( const TQString &t )
135{
136 data(fromUnicode( TQString(
137 "<html><head><meta http-equiv=\"Content-Type\" content=\"text/html; charset=%1\"></head>\n"
138 "%2</html>" ).arg( TQTextCodec::codecForLocale()->name() ).arg( t ) ) );
139}
140
141HelpProtocol *slave = 0;
142
143HelpProtocol::HelpProtocol( bool ghelp, const TQCString &pool, const TQCString &app )
144 : SlaveBase( ghelp ? "ghelp" : "help", pool, app ), mGhelp( ghelp )
145{
146 slave = this;
147}
148
149void HelpProtocol::get( const KURL& url )
150{
151 kdDebug( 7119 ) << "get: path=" << url.path()
152 << " query=" << url.query() << endl;
153
154 bool redirect;
155 TQString doc;
156 doc = url.path();
157
158 if ( !mGhelp ) {
159 if (doc.at(0) != '/')
160 doc = doc.prepend('/');
161
162 if (doc.at(doc.length() - 1) == '/')
163 doc += "index.html";
164 }
165
166 infoMessage(i18n("Looking up correct file"));
167
168 if ( !mGhelp ) {
169 doc = lookupFile(doc, url.query(), redirect);
170
171 if (redirect)
172 {
173 finished();
174 return;
175 }
176 }
177
178 if (doc.isEmpty())
179 {
180 error( TDEIO::ERR_DOES_NOT_EXIST, url.url() );
181 return;
182 }
183
184 mimeType("text/html");
185 KURL target;
186 target.setPath(doc);
187 if (url.hasHTMLRef())
188 target.setHTMLRef(url.htmlRef());
189
190 kdDebug( 7119 ) << "target " << target.url() << endl;
191
192 TQString file = target.path();
193
194 if ( mGhelp ) {
195 if ( file.right( 4 ) != ".xml" ) {
196 get_file( target );
197 return;
198 }
199 } else {
200 TQString docbook_file = file.left(file.findRev('/')) + "/index.docbook";
201 if (!TDEStandardDirs::exists(file)) {
202 file = docbook_file;
203 } else {
204 TQFileInfo fi(file);
205 if (fi.isDir()) {
206 file = file + "/index.docbook";
207 } else {
208 if ( file.right( 5 ) != ".html" || !compareTimeStamps( file, docbook_file ) ) {
209 get_file( target );
210 return;
211 } else
212 file = docbook_file;
213 }
214 }
215 }
216
217 infoMessage(i18n("Preparing document"));
218
219 if ( mGhelp ) {
220 TQString xsl = "customization/tde-nochunk.xsl";
221 mParsed = transform(file, locate("dtd", xsl));
222
223 kdDebug( 7119 ) << "parsed " << mParsed.length() << endl;
224
225 if (mParsed.isEmpty()) {
226 unicodeError( i18n( "The requested help file could not be parsed:<br>%1" ).arg( file ) );
227 } else {
228 int pos1 = mParsed.find( "charset=" );
229 if ( pos1 > 0 ) {
230 int pos2 = mParsed.find( '"', pos1 );
231 if ( pos2 > 0 ) {
232 mParsed.replace( pos1, pos2 - pos1, "charset=UTF-8" );
233 }
234 }
235 data( mParsed.utf8() );
236 }
237 } else {
238
239 kdDebug( 7119 ) << "look for cache for " << file << endl;
240
241 mParsed = lookForCache( file );
242
243 kdDebug( 7119 ) << "cached parsed " << mParsed.length() << endl;
244
245 if ( mParsed.isEmpty() ) {
246 mParsed = transform(file, locate("dtd", "customization/tde-chunk.xsl"));
247 if ( !mParsed.isEmpty() ) {
248 infoMessage( i18n( "Saving to cache" ) );
249 TQString cache = file.left( file.length() - 7 );
250 saveToCache( mParsed, locateLocal( "cache",
251 "tdeio_help" + cache +
252 "cache.bz2" ) );
253 }
254 } else infoMessage( i18n( "Using cached version" ) );
255
256 kdDebug( 7119 ) << "parsed " << mParsed.length() << endl;
257
258 if (mParsed.isEmpty()) {
259 unicodeError( i18n( "The requested help file could not be parsed:<br>%1" ).arg( file ) );
260 } else {
261 TQString query = url.query(), anchor;
262
263 // if we have a query, look if it contains an anchor
264 if (!query.isEmpty())
265 if (query.left(8) == "?anchor=") {
266 anchor = query.mid(8).lower();
267
268 KURL redirURL(url);
269
270 redirURL.setQuery(TQString::null);
271 redirURL.setHTMLRef(anchor);
272 redirection(redirURL);
273 finished();
274 return;
275 }
276 if (anchor.isEmpty() && url.hasHTMLRef())
277 anchor = url.htmlRef();
278
279 kdDebug( 7119 ) << "anchor: " << anchor << endl;
280
281 if ( !anchor.isEmpty() )
282 {
283 int index = 0;
284 while ( true ) {
285 index = mParsed.find( TQRegExp( "<a name=" ), index);
286 if ( index == -1 ) {
287 kdDebug( 7119 ) << "no anchor\n";
288 break; // use whatever is the target, most likely index.html
289 }
290
291 if ( mParsed.mid( index, 11 + anchor.length() ).lower() ==
292 TQString( "<a name=\"%1\">" ).arg( anchor ) )
293 {
294 index = mParsed.findRev( "<FILENAME filename=", index ) +
295 strlen( "<FILENAME filename=\"" );
296 TQString filename=mParsed.mid( index, 2000 );
297 filename = filename.left( filename.find( '\"' ) );
298 TQString path = target.path();
299 path = path.left( path.findRev( '/' ) + 1) + filename;
300 kdDebug( 7119 ) << "anchor found in " << path <<endl;
301 target.setPath( path );
302 break;
303 }
304 index++;
305 }
306 }
307 emitFile( target );
308 }
309 }
310
311 finished();
312}
313
314void HelpProtocol::emitFile( const KURL& url )
315{
316 infoMessage(i18n("Looking up section"));
317
318 TQString filename = url.path().mid(url.path().findRev('/') + 1);
319
320 int index = mParsed.find(TQString("<FILENAME filename=\"%1\"").arg(filename));
321 if (index == -1) {
322 if ( filename == "index.html" ) {
323 data( fromUnicode( mParsed ) );
324 return;
325 }
326
327 unicodeError( i18n("Could not find filename %1 in %2.").arg(filename).arg( url.url() ) );
328 return;
329 }
330
331 TQString filedata = splitOut(mParsed, index);
332 replaceCharsetHeader( filedata );
333
334 data( fromUnicode( filedata ) );
335 data( TQByteArray() );
336}
337
338void HelpProtocol::mimetype( const KURL &)
339{
340 mimeType("text/html");
341 finished();
342}
343
344// Copied from tdeio_file to avoid redirects
345
346#define MAX_IPC_SIZE (1024*32)
347
348void HelpProtocol::get_file( const KURL& url )
349{
350 kdDebug( 7119 ) << "get_file " << url.url() << endl;
351
352 TQCString _path( TQFile::encodeName(url.path()));
353 struct stat buff;
354 if ( ::stat( _path.data(), &buff ) == -1 ) {
355 if ( errno == EACCES )
356 error( TDEIO::ERR_ACCESS_DENIED, url.path() );
357 else
358 error( TDEIO::ERR_DOES_NOT_EXIST, url.path() );
359 return;
360 }
361
362 if ( S_ISDIR( buff.st_mode ) ) {
363 error( TDEIO::ERR_IS_DIRECTORY, url.path() );
364 return;
365 }
366 if ( S_ISFIFO( buff.st_mode ) || S_ISSOCK ( buff.st_mode ) ) {
367 error( TDEIO::ERR_CANNOT_OPEN_FOR_READING, url.path() );
368 return;
369 }
370
371 int fd = open( _path.data(), O_RDONLY);
372 if ( fd < 0 ) {
373 error( TDEIO::ERR_CANNOT_OPEN_FOR_READING, url.path() );
374 return;
375 }
376
377 totalSize( buff.st_size );
378 int processed_size = 0;
379
380 char buffer[ MAX_IPC_SIZE ];
381 TQByteArray array;
382
383 while( 1 )
384 {
385 int n = ::read( fd, buffer, MAX_IPC_SIZE );
386 if (n == -1)
387 {
388 if (errno == EINTR)
389 continue;
390 error( TDEIO::ERR_COULD_NOT_READ, url.path());
391 close(fd);
392 return;
393 }
394 if (n == 0)
395 break; // Finished
396
397 array.setRawData(buffer, n);
398 data( array );
399 array.resetRawData(buffer, n);
400
401 processed_size += n;
402 processedSize( processed_size );
403 }
404
405 data( TQByteArray() );
406
407 close( fd );
408
409 processedSize( buff.st_size );
410
411 finished();
412}

kdoctools

Skip menu "kdoctools"
  • Main Page
  • File List
  • Related Pages

kdoctools

Skip menu "kdoctools"
  • arts
  • dcop
  • dnssd
  • interfaces
  •   kspeech
  •     interface
  •     library
  •   tdetexteditor
  • kate
  • kded
  • kdoctools
  • kimgio
  • kjs
  • libtdemid
  • libtdescreensaver
  • tdeabc
  • tdecmshell
  • tdecore
  • tdefx
  • tdehtml
  • tdeinit
  • tdeio
  •   bookmarks
  •   httpfilter
  •   kpasswdserver
  •   kssl
  •   tdefile
  •   tdeio
  •   tdeioexec
  • tdeioslave
  •   http
  • tdemdi
  •   tdemdi
  • tdenewstuff
  • tdeparts
  • tdeprint
  • tderandr
  • tderesources
  • tdespell2
  • tdesu
  • tdeui
  • tdeunittest
  • tdeutils
  • tdewallet
Generated for kdoctools by doxygen 1.9.4
This website is maintained by Timothy Pearson.