37 #include <QtCore/QDir>
38 #include <QtCore/QFileInfo>
39 #include <QtCore/QFile>
40 #include <QtCore/QRegExp>
41 #include <QtCore/QTextCodec>
42 #include <QtGui/QTextDocument>
45 #ifdef HAVE_SYS_TYPES_H
46 # include <sys/types.h>
48 #ifdef HAVE_SYS_STAT_H
49 # include <sys/stat.h>
61 #include <libxslt/xsltutils.h>
62 #include <libxslt/transform.h>
75 langs.removeAll(
"C" );
79 for (QStringList::Iterator it = langs.begin(); it != langs.end(); ++it)
84 int ldCount = localDoc.count();
85 for (
int id=0;
id < ldCount;
id++)
87 QStringList::ConstIterator lang;
88 for (lang = langs.constBegin(); lang != langs.constEnd(); ++lang)
89 search.append(
QString(
"%1%2/%3").arg(localDoc[
id], *lang, fname));
93 for (QStringList::ConstIterator it = search.constBegin(); it != search.constEnd(); ++it)
95 kDebug( 7119 ) <<
"Looking for help in: " << *it;
98 if (info.exists() && info.isFile() && info.isReadable())
101 if ( ( *it ).endsWith( QLatin1String(
".html") ) )
103 QString file = (*it).left((*it).lastIndexOf(
'/')) +
"/index.docbook";
104 kDebug( 7119 ) <<
"Looking for help in: " << file;
106 if (info.exists() && info.isFile() && info.isReadable())
117 const QString &query,
bool &redirect)
123 QString result = langLookup(path);
124 if (result.isEmpty())
126 result = langLookup(path+
"/index.html");
127 if (!result.isEmpty())
129 KUrl red(
"help:/" );
130 red.setPath( path +
"/index.html" );
131 red.setQuery( query );
133 kDebug( 7119 ) <<
"redirect to " << red.url();
138 const QString documentationNotFound =
"khelpcenter/documentationnotfound/index.html";
139 if (!langLookup(documentationNotFound).isEmpty())
143 red.
setPath(documentationNotFound);
150 unicodeError(
i18n(
"There is no documentation available for %1." , Qt::escape(path)) );
155 kDebug( 7119 ) <<
"result " << result;
161 void HelpProtocol::unicodeError(
const QString &t )
166 QString encoding = QTextCodec::codecForLocale()->name();
169 "<html><head><meta http-equiv=\"Content-Type\" content=\"text/html; charset=%1\"></head>\n"
170 "%2</html>" ).arg( encoding, Qt::escape(t) ) ) );
177 :
SlaveBase( ghelp ?
"ghelp" :
"help", pool, app ), mGhelp( ghelp )
185 <<
"query=" << url.
query();
189 if (doc.contains(
"..")) {
195 if (!doc.startsWith(
'/'))
196 doc = doc.prepend(QLatin1Char(
'/'));
198 if (doc.endsWith(
'/'))
202 infoMessage(
i18n(
"Looking up correct file"));
205 doc = lookupFile(doc, url.
query(), redirect);
220 mimeType(
"text/html");
226 kDebug( 7119 ) <<
"target " << target.
url();
231 if ( !file.endsWith( QLatin1String(
".xml" ) ) ) {
236 QString docbook_file = file.left(file.lastIndexOf(
'/')) +
"/index.docbook";
242 file = file +
"/index.docbook";
244 if ( !file.endsWith( QLatin1String(
".html" ) ) || !
compareTimeStamps( file, docbook_file ) ) {
253 infoMessage(
i18n(
"Preparing document"));
256 QString xsl =
"customization/kde-nochunk.xsl";
259 kDebug( 7119 ) <<
"parsed " << mParsed.length();
261 if (mParsed.isEmpty()) {
262 unicodeError(
i18n(
"The requested help file could not be parsed:<br />%1" , file ) );
264 int pos1 = mParsed.indexOf(
"charset=" );
266 int pos2 = mParsed.indexOf(
'"', pos1 );
268 mParsed.replace( pos1, pos2 - pos1,
"charset=UTF-8" );
271 data( mParsed.toUtf8() );
275 kDebug( 7119 ) <<
"look for cache for " << file;
279 kDebug( 7119 ) <<
"cached parsed " << mParsed.length();
281 if ( mParsed.isEmpty() ) {
283 if ( !mParsed.isEmpty() ) {
284 infoMessage(
i18n(
"Saving to cache" ) );
293 QString cache = file.left( file.length() - 7 );
299 }
else infoMessage(
i18n(
"Using cached version" ) );
301 kDebug( 7119 ) <<
"parsed " << mParsed.length();
303 if (mParsed.isEmpty()) {
304 unicodeError(
i18n(
"The requested help file could not be parsed:<br />%1" , file ) );
309 if (!query.isEmpty())
310 if (query.startsWith(QLatin1String(
"?anchor="))) {
311 anchor = query.mid(8).toLower();
317 redirection(redirURL);
324 kDebug( 7119 ) <<
"anchor: " << anchor;
326 if ( !anchor.isEmpty() )
330 index = mParsed.indexOf( QRegExp(
"<a name=" ), index);
332 kDebug( 7119 ) <<
"no anchor\n";
336 if ( mParsed.mid( index, 11 + anchor.length() ).toLower() ==
337 QString(
"<a name=\"%1\">" ).arg( anchor ) )
339 index = mParsed.lastIndexOf(
"<FILENAME filename=", index ) +
340 strlen(
"<FILENAME filename=\"" );
341 QString filename=mParsed.mid( index, 2000 );
342 filename = filename.left( filename.indexOf(
'\"' ) );
344 path = path.left( path.lastIndexOf(
'/' ) + 1) + filename;
346 kDebug( 7119 ) <<
"anchor found in " << target.
url();
359 void HelpProtocol::emitFile(
const KUrl& url )
361 infoMessage(
i18n(
"Looking up section"));
365 int index = mParsed.indexOf(
QString(
"<FILENAME filename=\"%1\"").arg(filename));
367 if ( filename ==
"index.html" ) {
372 unicodeError(
i18n(
"Could not find filename %1 in %2.", filename, url.
url() ) );
380 data( QByteArray() );
385 mimeType(
"text/html");
391 #define MAX_IPC_SIZE (1024*32)
393 void HelpProtocol::get_file(
const KUrl& url )
395 kDebug( 7119 ) <<
"get_file " << url.
url();
403 if ( !f.open(QIODevice::ReadOnly) ) {
407 int processed_size = 0;
408 totalSize( f.size() );
415 qint64 n = f.read(array.data(),array.size());
427 processedSize( processed_size );
430 data( QByteArray() );
433 processedSize( f.size() );
436 QByteArray _path( QFile::encodeName(url.
path()));
437 KDE_struct_stat buff;
438 if ( KDE_stat( _path.data(), &buff ) == -1 ) {
439 if ( errno == EACCES )
446 if ( S_ISDIR( buff.st_mode ) ) {
450 if ( S_ISFIFO( buff.st_mode ) || S_ISSOCK ( buff.st_mode ) ) {
455 int fd = KDE_open( _path.data(), O_RDONLY);
461 totalSize( buff.st_size );
462 int processed_size = 0;
481 array = array.fromRawData(buffer, n);
483 array = array.fromRawData(buffer, n);
486 processedSize( processed_size );
489 data( QByteArray() );
493 processedSize( buff.st_size );
QString transform(const QString &pat, const QString &tss, const QVector< const char * > ¶ms)
QString i18n(const char *text)
bool compareTimeStamps(const QString &older, const QString &newer)
Compares two files and returns true if.
void replaceCharsetHeader(QString &output)
static QString locate(const char *type, const QString &filename, const KComponentData &cData=KGlobal::mainComponent())
QString toLocalFile(AdjustPathOption trailing=LeaveTrailingSlash) const
static QDebug kDebug(bool cond, int area=KDE_DEFAULT_DEBUG_AREA)
static bool exists(const QString &fullPath)
void setQuery(const QString &query)
void setPath(const QString &path)
void setProtocol(const QString &proto)
QString splitOut(const QString &parsed, int index)
bool saveToCache(const QString &contents, const QString &filename)
HelpProtocol(bool ghelp, const QByteArray &pool, const QByteArray &app)
QString path(AdjustPathOption trailing=LeaveTrailingSlash) const
void setHTMLRef(const QString &_ref)
QByteArray fromUnicode(const QString &data)
static QString installPath(const char *type)
QStringList resourceDirs(const char *type) const
virtual void mimetype(const KUrl &url)
QStringList languageList() const
static QString locateLocal(const char *type, const QString &filename, const KComponentData &cData=KGlobal::mainComponent())
virtual void get(const KUrl &url)
QString url(AdjustPathOption trailing=LeaveTrailingSlash) const
QString lookForCache(const QString &filename)