diff --git a/khelpcenter/slave/help.protocol b/khelpcenter/slave/help.protocol new file mode 100644 index 00000000..1bb5801e --- /dev/null +++ b/khelpcenter/slave/help.protocol @@ -0,0 +1,10 @@ +[Protocol] +exec=kio_help +protocol=help +input=none +output=filesystem +reading=true +defaultMimetype=text/html +Icon=help-browser +Class=:local +X-DocPath=kioslave/help/index.html diff --git a/khelpcenter/slave/kio_help.cpp b/khelpcenter/slave/kio_help.cpp new file mode 100644 index 00000000..73feb679 --- /dev/null +++ b/khelpcenter/slave/kio_help.cpp @@ -0,0 +1,495 @@ +/* This file is part of the KDE libraries + Copyright (C) 2000 Matthias Hoelzer-Kluepfel + Copyright (C) 2001 Stephan Kulow + Copyright (C) 2003 Cornelius Schumacher + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later versio + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + + +#include "kio_help.h" +#include "xslt.h" +#include "xslt_help.h" + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#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 + +using namespace KIO; + +QString HelpProtocol::langLookup(const QString &fname) +{ + QStringList search; + + // assemble the local search paths + const QStringList localDoc = KGlobal::dirs()->resourceDirs("html"); + + QStringList langs = KGlobal::locale()->languageList(); + langs.append( "en" ); + langs.removeAll( "C" ); + + // this is kind of compat hack as we install our docs in en/ but the + // default language is en_US + for (QStringList::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++) + { + QStringList::ConstIterator lang; + for (lang = langs.constBegin(); lang != langs.constEnd(); ++lang) + search.append(QString("%1%2/%3").arg(localDoc[id], *lang, fname)); + } + + // try to locate the file + for (QStringList::ConstIterator it = search.constBegin(); it != search.constEnd(); ++it) + { + kDebug( 7119 ) << "Looking for help in: " << *it; + + QFileInfo info(*it); + if (info.exists() && info.isFile() && info.isReadable()) + return *it; + + if ( ( *it ).endsWith( QLatin1String(".html") ) ) + { + QString file = (*it).left((*it).lastIndexOf('/')) + "/index.docbook"; + kDebug( 7119 ) << "Looking for help in: " << file; + info.setFile(file); + if (info.exists() && info.isFile() && info.isReadable()) + return *it; + } + } + + + return QString(); +} + + +QString HelpProtocol::lookupFile(const QString &fname, + const QString &query, bool &redirect) +{ + redirect = false; + + const QString path = fname; + + QString result = langLookup(path); + if (result.isEmpty()) + { + result = langLookup(path+"/index.html"); + if (!result.isEmpty()) + { + KUrl red( "help:/" ); + red.setPath( path + "/index.html" ); + red.setQuery( query ); + redirection(red); + kDebug( 7119 ) << "redirect to " << red.url(); + redirect = true; + } + else + { + const QString documentationNotFound = "khelpcenter/documentationnotfound/index.html"; + if (!langLookup(documentationNotFound).isEmpty()) + { + KUrl red; + red.setProtocol("help"); + red.setPath(documentationNotFound); + red.setQuery(query); + redirection(red); + redirect = true; + } + else + { + unicodeError( i18n("There is no documentation available for %1." , Qt::escape(path)) ); + return QString(); + } + } + } else + kDebug( 7119 ) << "result " << result; + + return result; +} + + +void HelpProtocol::unicodeError( const QString &t ) +{ +#ifdef Q_WS_WIN + QString encoding = "UTF-8"; +#else + QString encoding = QTextCodec::codecForLocale()->name(); +#endif + data(fromUnicode( QString( + "\n" + "%2" ).arg( encoding, Qt::escape(t) ) ) ); + +} + +HelpProtocol *slave = 0; + +HelpProtocol::HelpProtocol( bool ghelp, const QByteArray &pool, const QByteArray &app ) + : SlaveBase( ghelp ? "ghelp" : "help", pool, app ), mGhelp( ghelp ) +{ + slave = this; +} + +void HelpProtocol::get( const KUrl& url ) +{ + kDebug( 7119 ) << "path=" << url.path() + << "query=" << url.query(); + + bool redirect; + QString doc = QDir::cleanPath(url.path()); + if (doc.contains("..")) { + error( KIO::ERR_DOES_NOT_EXIST, url.url() ); + return; + } + + if ( !mGhelp ) { + if (!doc.startsWith('/')) + doc = doc.prepend(QLatin1Char('/')); + + if (doc.endsWith('/')) + 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( KIO::ERR_DOES_NOT_EXIST, url.url() ); + return; + } + + mimeType("text/html"); + KUrl target; + target.setPath(doc); + if (url.hasHTMLRef()) + target.setHTMLRef(url.htmlRef()); + + kDebug( 7119 ) << "target " << target.url(); + + QString file = target.scheme() == "file" ? target.toLocalFile() : target.path(); + + if ( mGhelp ) { + if ( !file.endsWith( QLatin1String( ".xml" ) ) ) { + get_file( target ); + return; + } + } else { + QString docbook_file = file.left(file.lastIndexOf('/')) + "/index.docbook"; + if (!KStandardDirs::exists(file)) { + file = docbook_file; + } else { + QFileInfo fi(file); + if (fi.isDir()) { + file = file + "/index.docbook"; + } else { + if ( !file.endsWith( QLatin1String( ".html" ) ) || !compareTimeStamps( file, docbook_file ) ) { + get_file( target ); + return; + } else + file = docbook_file; + } + } + } + + infoMessage(i18n("Preparing document")); + + if ( mGhelp ) { + QString xsl = "customization/kde-nochunk.xsl"; + mParsed = transform(file, KStandardDirs::locate("dtd", xsl)); + + kDebug( 7119 ) << "parsed " << mParsed.length(); + + if (mParsed.isEmpty()) { + unicodeError( i18n( "The requested help file could not be parsed:
%1" , file ) ); + } else { + int pos1 = mParsed.indexOf( "charset=" ); + if ( pos1 > 0 ) { + int pos2 = mParsed.indexOf( '"', pos1 ); + if ( pos2 > 0 ) { + mParsed.replace( pos1, pos2 - pos1, "charset=UTF-8" ); + } + } + data( mParsed.toUtf8() ); + } + } else { + + kDebug( 7119 ) << "look for cache for " << file; + + mParsed = lookForCache( file ); + + kDebug( 7119 ) << "cached parsed " << mParsed.length(); + + if ( mParsed.isEmpty() ) { + mParsed = transform(file, KStandardDirs::locate("dtd", "customization/kde-chunk.xsl")); + if ( !mParsed.isEmpty() ) { + infoMessage( i18n( "Saving to cache" ) ); +#ifdef Q_WS_WIN + QFileInfo fi(file); + // make sure filenames do not contain the base path, otherwise + // accessing user data from another location invalids cached files + // Accessing user data under a different path is possible + // when using usb sticks - this may affect unix/mac systems also + QString cache = '/' + fi.absolutePath().remove(KStandardDirs::installPath("html"),Qt::CaseInsensitive).replace('/','_') + '_' + fi.baseName() + '.'; +#else + QString cache = file.left( file.length() - 7 ); +#endif + saveToCache( mParsed, KStandardDirs::locateLocal( "cache", + "kio_help" + cache + + "cache.bz2" ) ); + } + } else infoMessage( i18n( "Using cached version" ) ); + + kDebug( 7119 ) << "parsed " << mParsed.length(); + + if (mParsed.isEmpty()) { + unicodeError( i18n( "The requested help file could not be parsed:
%1" , file ) ); + } else { + QString query = url.query(), anchor; + + // if we have a query, look if it contains an anchor + if (!query.isEmpty()) + if (query.startsWith(QLatin1String("?anchor="))) { + anchor = query.mid(8).toLower(); + + KUrl redirURL(url); + + redirURL.setQuery(QString()); + redirURL.setHTMLRef(anchor); + redirection(redirURL); + finished(); + return; + } + if (anchor.isEmpty() && url.hasHTMLRef()) + anchor = url.htmlRef(); + + kDebug( 7119 ) << "anchor: " << anchor; + + if ( !anchor.isEmpty() ) + { + int index = 0; + while ( true ) { + index = mParsed.indexOf( QRegExp( "" ).arg( anchor ) ) + { + index = mParsed.lastIndexOf( " + Copyright (C) 2001 Stephan Kulow + Copyright (C) 2003 Cornelius Schumacher + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include +#include + +#include + +#include +#include + +#include +#include + +class HelpProtocol : public KIO::SlaveBase +{ +public: + + HelpProtocol( bool ghelp, const QByteArray &pool, const QByteArray &app); + virtual ~HelpProtocol() { } + + virtual void get( const KUrl& url ); + + virtual void mimetype( const KUrl& url ); + +private: + + QString langLookup(const QString &fname); + void emitFile( const KUrl &url ); + void get_file( const KUrl& url ); + QString lookupFile(const QString &fname, const QString &query, + bool &redirect); + + void unicodeError( const QString &t ); + + QString mParsed; + bool mGhelp; +}; + + +#endif diff --git a/khelpcenter/slave/main.cpp b/khelpcenter/slave/main.cpp new file mode 100644 index 00000000..142c1a6c --- /dev/null +++ b/khelpcenter/slave/main.cpp @@ -0,0 +1,65 @@ +#ifdef _WIN32 +#define LIBXML_DLL_IMPORT __declspec(dllimport) +#else +extern "C" int xmlLoadExtDtdDefaultValue; +#endif + +#include "kio_help.h" +#include "xslt.h" + +#include +#include +#include + +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +extern "C" +{ + KDE_EXPORT int kdemain( int argc, char **argv ) + { + Q_ASSERT(!KGlobal::hasMainComponent()); // kdeinit is messed up if this is the case. + KComponentData componentData( "kio_help", "kio_help4" ); + fillInstance(componentData); + (void)componentData.config(); // we need this one to make sure system globals are read + + kDebug(7101) << "Starting " << getpid(); + + if (argc != 4) + { + fprintf(stderr, "Usage: kio_help protocol domain-socket1 domain-socket2\n"); + exit(-1); + } + + LIBXML_TEST_VERSION + xmlSubstituteEntitiesDefault(1); + xmlLoadExtDtdDefaultValue = 1; + exsltRegisterAll(); + + HelpProtocol slave(false, argv[2], argv[3]); + slave.dispatchLoop(); + + kDebug(7101) << "Done"; + return 0; + } +} + + + diff --git a/khelpcenter/slave/xslt.cpp b/khelpcenter/slave/xslt.cpp new file mode 100644 index 00000000..23fc4129 --- /dev/null +++ b/khelpcenter/slave/xslt.cpp @@ -0,0 +1,236 @@ +#include "xslt.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define INFO( x ) + +int writeToQString(void * context, const char * buffer, int len) +{ + QString *t = (QString*)context; + *t += QString::fromUtf8(buffer, len); + return len; +} + +int closeQString(void * context) { + QString *t = (QString*)context; + *t += '\n'; + return 0; +} + +QString transform( const QString &pat, const QString& tss, + const QVector ¶ms ) +{ + QString parsed; + + INFO(i18n("Parsing stylesheet")); + xsltStylesheetPtr style_sheet = + xsltParseStylesheetFile((const xmlChar *)QFile::encodeName(tss).constData()); + + if ( !style_sheet ) { + return parsed; + } + if (style_sheet->indent == 1) + xmlIndentTreeOutput = 1; + else + xmlIndentTreeOutput = 0; + + INFO(i18n("Parsing document")); + + xmlParserCtxtPtr pctxt; + + pctxt = xmlNewParserCtxt(); + if ( pctxt == NULL ) { + return parsed; + } + + xmlDocPtr doc = xmlCtxtReadFile(pctxt, QFile::encodeName(pat), NULL, + XML_PARSE_NOENT|XML_PARSE_DTDLOAD|XML_PARSE_NONET); + /* Check both the returned doc (for parsing errors) and the context + (for validation errors) */ + if (doc == NULL) { + return parsed; + } else { + if (pctxt->valid == 0) { + xmlFreeDoc(doc); + return parsed; + } + } + + xsltTransformContextPtr ctxt; + + ctxt = xsltNewTransformContext(style_sheet, doc); + if (ctxt == NULL) + return parsed; + + INFO(i18n("Applying stylesheet")); + QVector p = params; + p.append( NULL ); + xmlDocPtr res = xsltApplyStylesheet(style_sheet, doc, const_cast(&p[0])); + xmlFreeDoc(doc); + if (res != NULL) { + xmlOutputBufferPtr outp = xmlOutputBufferCreateIO(writeToQString, (xmlOutputCloseCallback)closeQString, &parsed, 0); + outp->written = 0; + INFO(i18n("Writing document")); + xsltSaveResultTo ( outp, res, style_sheet ); + xmlOutputBufferFlush(outp); + xmlFreeDoc(res); + } + xsltFreeStylesheet(style_sheet); + + if (parsed.isEmpty()) + parsed = ' '; // avoid error message + return parsed; +} + +/* +xmlParserInputPtr meinExternalEntityLoader(const char *URL, const char *ID, + xmlParserCtxtPtr ctxt) { + xmlParserInputPtr ret = NULL; + + // fprintf(stderr, "loading %s %s %s\n", URL, ID, ctxt->directory); + + if (URL == NULL) { + if ((ctxt->sax != NULL) && (ctxt->sax->warning != NULL)) + ctxt->sax->warning(ctxt, + "failed to load external entity \"%s\"\n", ID); + return(NULL); + } + if (!qstrcmp(ID, "-//OASIS//DTD DocBook XML V4.1.2//EN")) + URL = "docbook/xml-dtd-4.1.2/docbookx.dtd"; + if (!qstrcmp(ID, "-//OASIS//DTD XML DocBook V4.1.2//EN")) + URL = "docbook/xml-dtd-4.1.2/docbookx.dtd"; + + QString file; + if (KStandardDirs::exists( QDir::currentPath() + "/" + URL ) ) + file = QDir::currentPath() + "/" + URL; + else + file = locate("dtd", URL); + + ret = xmlNewInputFromFile(ctxt, file.toLatin1().constData()); + if (ret == NULL) { + if ((ctxt->sax != NULL) && (ctxt->sax->warning != NULL)) + ctxt->sax->warning(ctxt, + + "failed to load external entity \"%s\"\n", URL); + } + return(ret); +} +*/ + +QString splitOut(const QString &parsed, int index) +{ + int start_index = index + 1; + while (parsed.at(start_index - 1) != '>') start_index++; + + int inside = 0; + + QString filedata; + + while (true) { + int endindex = parsed.indexOf("", index); + int startindex = parsed.indexOf(" 0) { + if (startindex < endindex) { + // kDebug() << "finding another"; + index = startindex + 8; + inside++; + } else { + index = endindex + 8; + inside--; + } + } else { + inside--; + index = endindex + 1; + } + + if (inside == 0) { + filedata = parsed.mid(start_index, endindex - start_index); + break; + } + + } + + index = filedata.indexOf(" 0) { + int endindex = filedata.lastIndexOf(""); + while (filedata.at(endindex) != '>') endindex++; + endindex++; + filedata = filedata.left(index) + filedata.mid(endindex); + } + + // filedata.replace(QRegExp(">"), "\n>"); + return filedata; +} + +QByteArray fromUnicode( const QString &data ) +{ + QTextCodec *locale = QTextCodec::codecForLocale(); + QByteArray result; + char buffer[30000]; + uint buffer_len = 0; + uint len = 0; + int offset = 0; + const int part_len = 5000; + + QString part; + + while ( offset < data.length() ) + { + part = data.mid( offset, part_len ); + QByteArray test = locale->fromUnicode( part ); + if ( locale->toUnicode( test ) == part ) { + result += test; + offset += part_len; + continue; + } + len = part.length(); + buffer_len = 0; + for ( uint i = 0; i < len; i++ ) { + QByteArray test = locale->fromUnicode( part.mid( i, 1 ) ); + if ( locale->toUnicode( test ) == part.mid( i, 1 ) ) { + if (buffer_len + test.length() + 1 > sizeof(buffer)) + break; + strcpy( buffer + buffer_len, test.data() ); + buffer_len += test.length(); + } else { + QString res; + res.sprintf( "&#%d;", part.at( i ).unicode() ); + test = locale->fromUnicode( res ); + if (buffer_len + test.length() + 1 > sizeof(buffer)) + break; + strcpy( buffer + buffer_len, test.data() ); + buffer_len += test.length(); + } + } + result += QByteArray( buffer, buffer_len + 1); + offset += part_len; + } + return result; +} + +void replaceCharsetHeader( QString &output ) +{ + QString name; + name = QTextCodec::codecForLocale()->name(); + name.replace( QString( "ISO " ), "iso-" ); + output.replace( QString( "" ), + QString( "" ).arg( name ) ); +} diff --git a/khelpcenter/slave/xslt.h b/khelpcenter/slave/xslt.h new file mode 100644 index 00000000..22d9a502 --- /dev/null +++ b/khelpcenter/slave/xslt.h @@ -0,0 +1,24 @@ +#ifndef _MEIN_XSLT_H_ +#define _MEIN_XSLT_H_ + +#include +#include +#include + +class QByteArray; +class QIODevice; +class KComponentData; + +QString transform(const QString &file, const QString& stylesheet, + const QVector ¶ms = QVector()); +QString splitOut(const QString &parsed, int index); +void fillInstance(KComponentData &ins, const QString &srcdir = QString() ); +bool saveToCache( const QString &contents, const QString &filename ); +QByteArray fromUnicode( const QString &data ); +void replaceCharsetHeader( QString &output ); +QIODevice *getBZip2device(const QString &fileName ); + +extern bool warnings_exist; +extern QString *SRCDIR; + +#endif diff --git a/khelpcenter/slave/xslt_help.cpp b/khelpcenter/slave/xslt_help.cpp new file mode 100644 index 00000000..9c732fa5 --- /dev/null +++ b/khelpcenter/slave/xslt_help.cpp @@ -0,0 +1,109 @@ +#include "xslt_help.h" +#include "xslt.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +static bool readCache( const QString &filename, + const QString &cache, QString &output) +{ + kDebug( 7119 ) << filename << " " << cache; + KGlobal::dirs()->addResourceType("dtd", "data", "ksgmltools2/"); + if ( !compareTimeStamps( filename, cache ) ) + return false; + if ( !compareTimeStamps( KStandardDirs::locate( "dtd", "customization/kde-chunk.xsl"), cache ) ) + return false; + + kDebug( 7119 ) << "create filter"; + QIODevice *fd = ::getBZip2device(cache); + if ( !fd ) + return false; + + if (!fd->open(QIODevice::ReadOnly)) + { + delete fd; + QFile::remove(cache); + return false; + } + + kDebug( 7119 ) << "reading"; + + char buffer[32000]; + int n; + QByteArray text; + // Also end loop in case of error, when -1 is returned + while ( ( n = fd->read(buffer, 31900) ) > 0) + { + buffer[n] = 0; + text += buffer; + } + kDebug( 7119 ) << "read " << text.length(); + fd->close(); + + output = QString::fromUtf8( text ); + delete fd; + + if (n == -1) + return false; + + kDebug( 7119 ) << "finished "; + + return true; +} + +QString lookForCache( const QString &filename ) +{ + kDebug() << "lookForCache " << filename; + assert( filename.endsWith( QLatin1String(".docbook") ) ); + assert( QDir::isAbsolutePath(filename)); + QString cache = filename.left( filename.length() - 7 ); + QString output; + if ( readCache( filename, cache + "cache.bz2", output) ) + return output; +#ifdef Q_WS_WIN + QFileInfo fi(filename); + // make sure filenames do not contain the base path, otherwise + // accessing user data from another location invalids cached files. + // Accessing user data under a different path is possible + // when using usb sticks - this may affect unix/mac systems also + cache = '/' + fi.absolutePath().remove(KStandardDirs::installPath("html"),Qt::CaseInsensitive).replace('/','_') + '_' + fi.baseName() + '.'; +#endif + if ( readCache( filename, + KStandardDirs::locateLocal( "cache", + "kio_help" + cache + + "cache.bz2" ), output ) ) + return output; + + return QString(); +} + +bool compareTimeStamps( const QString &older, const QString &newer ) +{ + QFileInfo _older( older ); + QFileInfo _newer( newer ); + assert( _older.exists() ); + if ( !_newer.exists() ) + return false; + return ( _newer.lastModified() > _older.lastModified() ); +} diff --git a/khelpcenter/slave/xslt_help.h b/khelpcenter/slave/xslt_help.h new file mode 100644 index 00000000..ddaee590 --- /dev/null +++ b/khelpcenter/slave/xslt_help.h @@ -0,0 +1,14 @@ +#ifndef _MEIN_XSLT_HELP_H_ +#define _MEIN_XSLT_HELP_H_ + +#include + +QString lookForCache( const QString &filename ); + +/** + * Compares two files and returns true if @param newer exists and is newer than + * @param older + **/ +bool compareTimeStamps( const QString &older, const QString &newer ); + +#endif diff --git a/khelpcenter/slave/xslt_kde.cpp b/khelpcenter/slave/xslt_kde.cpp new file mode 100644 index 00000000..2c3f2c0d --- /dev/null +++ b/khelpcenter/slave/xslt_kde.cpp @@ -0,0 +1,63 @@ +#include "xslt.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +void fillInstance(KComponentData &ins, const QString &srcdir) +{ + QByteArray catalogs; + + if ( srcdir.isEmpty() ) { + catalogs += KUrl::fromLocalFile( ins.dirs()->findResource("data", "ksgmltools2/customization/catalog.xml") ).toEncoded(); + ins.dirs()->addResourceType("dtd", "data", "ksgmltools2/"); + } else { + catalogs += KUrl::fromLocalFile( srcdir +"/customization/catalog.xml" ).toEncoded(); + ins.dirs()->addResourceDir("dtd", srcdir); + } + + setenv( "XML_CATALOG_FILES", catalogs.constData(), 1 ); + xmlInitializeCatalog(); +} + +QIODevice *getBZip2device(const QString &fileName ) +{ + return KFilterDev::deviceForFile(fileName); +} + +bool saveToCache( const QString &contents, const QString &filename ) +{ + QIODevice *fd = ::getBZip2device(filename); + if ( !fd ) + return false; + + if (!fd->open(QIODevice::WriteOnly)) + { + delete fd; + return false; + } + + fd->write( contents.toUtf8() ); + fd->close(); + delete fd; + return true; +} diff --git a/khelpcenter/slave/xslt_kde.h b/khelpcenter/slave/xslt_kde.h new file mode 100644 index 00000000..ab7e5f94 --- /dev/null +++ b/khelpcenter/slave/xslt_kde.h @@ -0,0 +1,15 @@ +#ifndef _MEIN_XSLT_KDE_H_ +#define _MEIN_XSLT_KDE_H_ + +#include +#include + +class QByteArray; +class QIODevice; +class KComponentData; + +void fillInstance(KComponentData &ins, const QString &srcdir = QString() ); +bool saveToCache( const QString &contents, const QString &filename ); +QIODevice *getBZip2device(const QString &fileName ); + +#endif