#include #ifdef HAVE_SYS_TYPES_H # include #endif #ifdef HAVE_SYS_STAT_H # include #endif #include #include #ifdef HAVE_STDIO_H # include #endif #ifdef HAVE_STDLIB_H # include #endif #include #include #include #include #include #include #include #include #include #include #include #include #include "tdeio_help.h" #include #include #include "xslt.h" using namespace TDEIO; TQString HelpProtocol::langLookup(const TQString &fname) { TQStringList search; // assemble the local search paths const TQStringList localDoc = TDEGlobal::dirs()->resourceDirs("html") + TDEGlobal::dirs()->resourceDirs("html-bundle"); TQStringList langs = TDEGlobal::locale()->languageList(); langs.append( "en" ); langs.remove( "C" ); // this is kind of compat hack as we install our docs in en/ but the // default language is en_US for (TQStringList::Iterator it = langs.begin(); it != langs.end(); ++it) if ( *it == "en_US" ) *it = "en"; // look up the different languages int ldCount = localDoc.count(); for (int id=0; id < ldCount; id++) { TQStringList::ConstIterator lang; for (lang = langs.begin(); lang != langs.end(); ++lang) search.append(TQString("%1%2/%3").arg(localDoc[id], *lang, fname)); } // try to locate the file TQStringList::Iterator it; for (it = search.begin(); it != search.end(); ++it) { kdDebug( 7119 ) << "Looking for help in: " << *it << endl; TQFileInfo info(*it); if (info.exists() && info.isFile() && info.isReadable()) return *it; if ( ( *it ).right( 5 ) == ".html" ) { TQString file = (*it).left((*it).findRev('/')) + "/index.docbook"; kdDebug( 7119 ) << "Looking for help in: " << file << endl; info.setFile(file); if (info.exists() && info.isFile() && info.isReadable()) return *it; } } return TQString::null; } TQString HelpProtocol::lookupFile(const TQString &fname, const TQString &query, bool &redirect) { redirect = false; TQString result = langLookup(fname); if (result.isEmpty()) { result = langLookup(fname+"/index.html"); if (!result.isEmpty()) { KURL red("help:/"); red.setPath( fname+"/index.html" ); red.setQuery( query ); redirection(red); kdDebug( 7119 ) << "redirect to " << red.url() << endl; redirect = true; } else { const TQString helpNotFound("khelpcenter/helpnotfound/index.html"); result = langLookup(helpNotFound); if (!result.isEmpty()) { KURL red("help:/"); red.setPath(helpNotFound); red.setQuery(query); redirection(red); kdDebug( 7119 ) << "redirect to " << red.url() << endl; redirect = true; } else { unicodeError(i18n("Sorry, there is no documentation available at all for %1." ).arg(fname)); finished(); return TQString::null; } } } else kdDebug( 7119 ) << "result " << result << endl; return result; } void HelpProtocol::unicodeError( const TQString &t ) { data(fromUnicode( TQString( "\n" "%2" ).arg( TQTextCodec::codecForLocale()->name() ).arg( t ) ) ); } HelpProtocol *slave = 0; HelpProtocol::HelpProtocol( bool ghelp, const TQCString &pool, const TQCString &app ) : SlaveBase( ghelp ? "ghelp" : "help", pool, app ), mGhelp( ghelp ) { slave = this; } void HelpProtocol::get( const KURL& url ) { kdDebug( 7119 ) << "get: path=" << url.path() << " query=" << url.query() << endl; bool redirect; TQString doc; doc = url.path(); if ( !mGhelp ) { if (doc.at(0) != '/') doc = doc.prepend('/'); if (doc.at(doc.length() - 1) == '/') doc += "index.html"; } infoMessage(i18n("Looking up correct file")); if ( !mGhelp ) { doc = lookupFile(doc, url.query(), redirect); if (redirect) { finished(); return; } } if (doc.isEmpty()) { error( TDEIO::ERR_DOES_NOT_EXIST, url.url() ); return; } mimeType("text/html"); KURL target; target.setPath(doc); if (url.hasHTMLRef()) target.setHTMLRef(url.htmlRef()); kdDebug( 7119 ) << "target " << target.url() << endl; TQString file = target.path(); if ( mGhelp ) { if ( file.right( 4 ) != ".xml" ) { get_file( target ); return; } } else { TQString docbook_file = file.left(file.findRev('/')) + "/index.docbook"; if (!TDEStandardDirs::exists(file)) { file = docbook_file; } else { TQFileInfo fi(file); if (fi.isDir()) { file = file + "/index.docbook"; } else { if ( file.right( 5 ) != ".html" || !compareTimeStamps( file, docbook_file ) ) { get_file( target ); return; } else file = docbook_file; } } } infoMessage(i18n("Preparing document")); if ( mGhelp ) { TQString xsl = "customization/tde-nochunk.xsl"; mParsed = transform(file, locate("dtd", xsl)); kdDebug( 7119 ) << "parsed " << mParsed.length() << endl; if (mParsed.isEmpty()) { unicodeError( i18n( "The requested help file could not be parsed:
%1" ).arg( file ) ); } else { int pos1 = mParsed.find( "charset=" ); if ( pos1 > 0 ) { int pos2 = mParsed.find( '"', pos1 ); if ( pos2 > 0 ) { mParsed.replace( pos1, pos2 - pos1, "charset=UTF-8" ); } } data( mParsed.utf8() ); } } else { kdDebug( 7119 ) << "look for cache for " << file << endl; mParsed = lookForCache( file ); kdDebug( 7119 ) << "cached parsed " << mParsed.length() << endl; if ( mParsed.isEmpty() ) { mParsed = transform(file, locate("dtd", "customization/tde-chunk.xsl")); if ( !mParsed.isEmpty() ) { infoMessage( i18n( "Saving to cache" ) ); TQString cache = file.left( file.length() - 7 ); saveToCache( mParsed, locateLocal( "cache", "tdeio_help" + cache + "cache.bz2" ) ); } } else infoMessage( i18n( "Using cached version" ) ); kdDebug( 7119 ) << "parsed " << mParsed.length() << endl; if (mParsed.isEmpty()) { unicodeError( i18n( "The requested help file could not be parsed:
%1" ).arg( file ) ); } else { TQString query = url.query(), anchor; // if we have a query, look if it contains an anchor if (!query.isEmpty()) if (query.left(8) == "?anchor=") { anchor = query.mid(8).lower(); KURL redirURL(url); redirURL.setQuery(TQString::null); redirURL.setHTMLRef(anchor); redirection(redirURL); finished(); return; } if (anchor.isEmpty() && url.hasHTMLRef()) anchor = url.htmlRef(); kdDebug( 7119 ) << "anchor: " << anchor << endl; if ( !anchor.isEmpty() ) { int index = 0; while ( true ) { index = mParsed.find( TQRegExp( "" ).arg( anchor ) ) { index = mParsed.findRev( "