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

kdoctools

tdeio_help.cpp

00001 #include <config.h>
00002 
00003 #ifdef HAVE_SYS_TYPES_H
00004 # include <sys/types.h>
00005 #endif
00006 #ifdef HAVE_SYS_STAT_H
00007 # include <sys/stat.h>
00008 #endif
00009 
00010 #include <errno.h>
00011 #include <fcntl.h>
00012 #ifdef HAVE_STDIO_H
00013 # include <stdio.h>
00014 #endif
00015 #ifdef HAVE_STDLIB_H
00016 # include <stdlib.h>
00017 #endif
00018 
00019 #include <tqvaluelist.h>
00020 #include <tqfileinfo.h>
00021 #include <tqfile.h>
00022 #include <tqtextstream.h>
00023 #include <tqregexp.h>
00024 #include <tqtextcodec.h>
00025 
00026 #include <kdebug.h>
00027 #include <kurl.h>
00028 #include <tdeglobal.h>
00029 #include <tdelocale.h>
00030 #include <kstandarddirs.h>
00031 #include <kinstance.h>
00032 
00033 #include "tdeio_help.h"
00034 #include <libxslt/xsltutils.h>
00035 #include <libxslt/transform.h>
00036 #include "xslt.h"
00037 
00038 using namespace TDEIO;
00039 
00040 TQString HelpProtocol::langLookup(const TQString &fname)
00041 {
00042     TQStringList search;
00043 
00044     // assemble the local search paths
00045     const TQStringList localDoc = TDEGlobal::dirs()->resourceDirs("html") + TDEGlobal::dirs()->resourceDirs("html-bundle");
00046 
00047     TQStringList langs = TDEGlobal::locale()->languageList();
00048     langs.append( "en" );
00049     langs.remove( "C" );
00050 
00051     // this is kind of compat hack as we install our docs in en/ but the
00052     // default language is en_US
00053     for (TQStringList::Iterator it = langs.begin(); it != langs.end(); ++it)
00054         if ( *it == "en_US" )
00055             *it = "en";
00056 
00057     // look up the different languages
00058     int ldCount = localDoc.count();
00059     for (int id=0; id < ldCount; id++)
00060     {
00061         TQStringList::ConstIterator lang;
00062         for (lang = langs.begin(); lang != langs.end(); ++lang)
00063             search.append(TQString("%1%2/%3").arg(localDoc[id], *lang, fname));
00064     }
00065 
00066     // try to locate the file
00067     TQStringList::Iterator it;
00068     for (it = search.begin(); it != search.end(); ++it)
00069     {
00070         kdDebug( 7119 ) << "Looking for help in: " << *it << endl;
00071 
00072         TQFileInfo info(*it);
00073         if (info.exists() && info.isFile() && info.isReadable())
00074             return *it;
00075 
00076         if ( ( *it ).right( 5 ) == ".html" )
00077         {
00078             TQString file = (*it).left((*it).findRev('/')) + "/index.docbook";
00079             kdDebug( 7119 ) << "Looking for help in: " << file << endl;
00080             info.setFile(file);
00081             if (info.exists() && info.isFile() && info.isReadable())
00082                 return *it;
00083         }
00084     }
00085 
00086 
00087     return TQString::null;
00088 }
00089 
00090 
00091 TQString HelpProtocol::lookupFile(const TQString &fname, const TQString &query, bool &redirect)
00092 {
00093     redirect = false;
00094     TQString result = langLookup(fname);
00095     if (result.isEmpty())
00096     {
00097         result = langLookup(fname+"/index.html");
00098         if (!result.isEmpty())
00099         {
00100             KURL red("help:/");
00101             red.setPath( fname+"/index.html" );
00102             red.setQuery( query );
00103             redirection(red);
00104             kdDebug( 7119 ) << "redirect to " << red.url() << endl;
00105             redirect = true;
00106         }
00107         else
00108         {
00109             const TQString helpNotFound("khelpcenter/helpnotfound/index.html");
00110             result = langLookup(helpNotFound);
00111             if (!result.isEmpty())
00112             {
00113                 KURL red("help:/");
00114                 red.setPath(helpNotFound);
00115                 red.setQuery(query);
00116                 redirection(red);
00117                 kdDebug( 7119 ) << "redirect to " << red.url() << endl;
00118                 redirect = true;
00119             }
00120             else
00121             {
00122                 unicodeError(i18n("Sorry, there is no documentation available at all for %1." ).arg(fname));
00123                 finished();
00124                 return TQString::null;
00125             }
00126         }
00127     } else
00128         kdDebug( 7119 ) << "result " << result << endl;
00129 
00130     return result;
00131 }
00132 
00133 
00134 void HelpProtocol::unicodeError( const TQString &t )
00135 {
00136    data(fromUnicode( TQString(
00137         "<html><head><meta http-equiv=\"Content-Type\" content=\"text/html; charset=%1\"></head>\n"
00138         "%2</html>" ).arg( TQTextCodec::codecForLocale()->name() ).arg( t ) ) );
00139 }
00140 
00141 HelpProtocol *slave = 0;
00142 
00143 HelpProtocol::HelpProtocol( bool ghelp, const TQCString &pool, const TQCString &app )
00144   : SlaveBase( ghelp ? "ghelp" : "help", pool, app ), mGhelp( ghelp )
00145 {
00146     slave = this;
00147 }
00148 
00149 void HelpProtocol::get( const KURL& url )
00150 {
00151     kdDebug( 7119 ) << "get: path=" << url.path()
00152               << " query=" << url.query() << endl;
00153 
00154     bool redirect;
00155     TQString doc;
00156     doc = url.path();
00157 
00158     if ( !mGhelp ) {
00159         if (doc.at(0) != '/')
00160             doc = doc.prepend('/');
00161 
00162         if (doc.at(doc.length() - 1) == '/')
00163             doc += "index.html";
00164     }
00165 
00166     infoMessage(i18n("Looking up correct file"));
00167 
00168     if ( !mGhelp ) {
00169       doc = lookupFile(doc, url.query(), redirect);
00170 
00171       if (redirect)
00172       {
00173           finished();
00174           return;
00175       }
00176     }
00177 
00178     if (doc.isEmpty())
00179     {
00180         error( TDEIO::ERR_DOES_NOT_EXIST, url.url() );
00181         return;
00182     }
00183 
00184     mimeType("text/html");
00185     KURL target;
00186     target.setPath(doc);
00187     if (url.hasHTMLRef())
00188         target.setHTMLRef(url.htmlRef());
00189 
00190     kdDebug( 7119 ) << "target " << target.url() << endl;
00191 
00192     TQString file = target.path();
00193     
00194     if ( mGhelp ) {
00195       if ( file.right( 4 ) != ".xml" ) {
00196          get_file( target );
00197          return;
00198       }
00199     } else {
00200         TQString docbook_file = file.left(file.findRev('/')) + "/index.docbook";
00201         if (!TDEStandardDirs::exists(file)) {
00202             file = docbook_file;
00203         } else {
00204             TQFileInfo fi(file);
00205             if (fi.isDir()) {
00206                 file = file + "/index.docbook";
00207             } else {
00208                 if ( file.right( 5 ) != ".html" || !compareTimeStamps( file, docbook_file ) ) {
00209                     get_file( target );
00210                     return;
00211                 } else
00212                     file = docbook_file;
00213             }
00214         }
00215     }
00216 
00217     infoMessage(i18n("Preparing document"));
00218 
00219     if ( mGhelp ) {
00220         TQString xsl = "customization/tde-nochunk.xsl";
00221         mParsed = transform(file, locate("dtd", xsl));
00222 
00223         kdDebug( 7119 ) << "parsed " << mParsed.length() << endl;
00224 
00225         if (mParsed.isEmpty()) {
00226             unicodeError( i18n( "The requested help file could not be parsed:<br>%1" ).arg( file ) );
00227         } else {
00228             int pos1 = mParsed.find( "charset=" );
00229             if ( pos1 > 0 ) {
00230               int pos2 = mParsed.find( '"', pos1 );
00231               if ( pos2 > 0 ) {
00232                 mParsed.replace( pos1, pos2 - pos1, "charset=UTF-8" );
00233               }
00234             }
00235             data( mParsed.utf8() );
00236         }
00237     } else {
00238 
00239         kdDebug( 7119 ) << "look for cache for " << file << endl;
00240 
00241         mParsed = lookForCache( file );
00242 
00243         kdDebug( 7119 ) << "cached parsed " << mParsed.length() << endl;
00244 
00245         if ( mParsed.isEmpty() ) {
00246             mParsed = transform(file, locate("dtd", "customization/tde-chunk.xsl"));
00247             if ( !mParsed.isEmpty() ) {
00248                 infoMessage( i18n( "Saving to cache" ) );
00249                 TQString cache = file.left( file.length() - 7 );
00250                 saveToCache( mParsed, locateLocal( "cache",
00251                                                         "tdeio_help" + cache +
00252                                                         "cache.bz2" ) );
00253             }
00254         } else infoMessage( i18n( "Using cached version" ) );
00255 
00256         kdDebug( 7119 ) << "parsed " << mParsed.length() << endl;
00257 
00258         if (mParsed.isEmpty()) {
00259             unicodeError( i18n( "The requested help file could not be parsed:<br>%1" ).arg( file ) );
00260         } else {
00261             TQString query = url.query(), anchor;
00262 
00263             // if we have a query, look if it contains an anchor
00264             if (!query.isEmpty())
00265                 if (query.left(8) == "?anchor=") {
00266                     anchor = query.mid(8).lower();
00267 
00268                 KURL redirURL(url);
00269 
00270                 redirURL.setQuery(TQString::null);
00271                 redirURL.setHTMLRef(anchor);
00272                 redirection(redirURL);
00273                 finished();
00274                 return;
00275             }
00276             if (anchor.isEmpty() && url.hasHTMLRef())
00277             anchor = url.htmlRef();
00278 
00279             kdDebug( 7119 ) << "anchor: " << anchor << endl;
00280 
00281             if ( !anchor.isEmpty() )
00282             {
00283                 int index = 0;
00284                 while ( true ) {
00285                     index = mParsed.find( TQRegExp( "<a name=" ), index);
00286                     if ( index == -1 ) {
00287                         kdDebug( 7119 ) << "no anchor\n";
00288                         break; // use whatever is the target, most likely index.html
00289                     }
00290 
00291                     if ( mParsed.mid( index, 11 + anchor.length() ).lower() ==
00292                          TQString( "<a name=\"%1\">" ).arg( anchor ) )
00293                     {
00294                         index = mParsed.findRev( "<FILENAME filename=", index ) +
00295                                  strlen( "<FILENAME filename=\"" );
00296                         TQString filename=mParsed.mid( index, 2000 );
00297                         filename = filename.left( filename.find( '\"' ) );
00298                         TQString path = target.path();
00299                         path = path.left( path.findRev( '/' ) + 1) + filename;
00300                         kdDebug( 7119 ) << "anchor found in " << path <<endl;
00301                         target.setPath( path );
00302                         break;
00303                     }
00304                     index++;
00305                 }
00306             }
00307             emitFile( target );
00308         }
00309     }
00310 
00311     finished();
00312 }
00313 
00314 void HelpProtocol::emitFile( const KURL& url )
00315 {
00316     infoMessage(i18n("Looking up section"));
00317 
00318     TQString filename = url.path().mid(url.path().findRev('/') + 1);
00319 
00320     int index = mParsed.find(TQString("<FILENAME filename=\"%1\"").arg(filename));
00321     if (index == -1) {
00322         if ( filename == "index.html" ) {
00323             data( fromUnicode( mParsed ) );
00324             return;
00325         }
00326 
00327         unicodeError( i18n("Could not find filename %1 in %2.").arg(filename).arg( url.url() ) );
00328         return;
00329     }
00330 
00331     TQString filedata = splitOut(mParsed, index);
00332     replaceCharsetHeader( filedata );
00333 
00334     data( fromUnicode( filedata ) );
00335     data( TQByteArray() );
00336 }
00337 
00338 void HelpProtocol::mimetype( const KURL &)
00339 {
00340     mimeType("text/html");
00341     finished();
00342 }
00343 
00344 // Copied from tdeio_file to avoid redirects
00345 
00346 #define MAX_IPC_SIZE (1024*32)
00347 
00348 void HelpProtocol::get_file( const KURL& url )
00349 {
00350     kdDebug( 7119 ) << "get_file " << url.url() << endl;
00351 
00352     TQCString _path( TQFile::encodeName(url.path()));
00353     struct stat buff;
00354     if ( ::stat( _path.data(), &buff ) == -1 ) {
00355         if ( errno == EACCES )
00356            error( TDEIO::ERR_ACCESS_DENIED, url.path() );
00357         else
00358            error( TDEIO::ERR_DOES_NOT_EXIST, url.path() );
00359     return;
00360     }
00361 
00362     if ( S_ISDIR( buff.st_mode ) ) {
00363     error( TDEIO::ERR_IS_DIRECTORY, url.path() );
00364     return;
00365     }
00366     if ( S_ISFIFO( buff.st_mode ) || S_ISSOCK ( buff.st_mode ) ) {
00367     error( TDEIO::ERR_CANNOT_OPEN_FOR_READING, url.path() );
00368     return;
00369     }
00370 
00371     int fd = open( _path.data(), O_RDONLY);
00372     if ( fd < 0 ) {
00373     error( TDEIO::ERR_CANNOT_OPEN_FOR_READING, url.path() );
00374     return;
00375     }
00376 
00377     totalSize( buff.st_size );
00378     int processed_size = 0;
00379 
00380     char buffer[ MAX_IPC_SIZE ];
00381     TQByteArray array;
00382 
00383     while( 1 )
00384     {
00385        int n = ::read( fd, buffer, MAX_IPC_SIZE );
00386        if (n == -1)
00387        {
00388           if (errno == EINTR)
00389               continue;
00390           error( TDEIO::ERR_COULD_NOT_READ, url.path());
00391           close(fd);
00392           return;
00393        }
00394        if (n == 0)
00395           break; // Finished
00396 
00397        array.setRawData(buffer, n);
00398        data( array );
00399        array.resetRawData(buffer, n);
00400 
00401        processed_size += n;
00402        processedSize( processed_size );
00403     }
00404 
00405     data( TQByteArray() );
00406 
00407     close( fd );
00408 
00409     processedSize( buff.st_size );
00410 
00411     finished();
00412 }

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.7.1
This website is maintained by Timothy Pearson.