diff --git a/umbrello/docgenerators/docbookgeneratorjob.cpp b/umbrello/docgenerators/docbookgeneratorjob.cpp index e752cbdcd..aa161bb85 100644 --- a/umbrello/docgenerators/docbookgeneratorjob.cpp +++ b/umbrello/docgenerators/docbookgeneratorjob.cpp @@ -1,204 +1,204 @@ /*************************************************************************** * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * copyright (C) 2008-2014 * * Umbrello UML Modeller Authors * ***************************************************************************/ #include "docbookgeneratorjob.h" #include "debug_utils.h" #include "uml.h" #include "umldoc.h" #include #include #include #include #include #include #include #include #include #include // kde includes #if QT_VERSION < 0x050000 #include #include #endif #include // qt includes #include #if QT_VERSION >= 0x050000 #include #include #endif extern int xmlLoadExtDtdDefaultValue; #define MAX_PATHS 64 xmlExternalEntityLoader defaultEntityLoader = NULL; static xmlChar *paths[MAX_PATHS + 1]; static int nbpaths = 0; static QHash replaceURLList; /* * Entity loading control and customization. * taken from kdelibs/kdoctools/xslt.cpp */ static xmlParserInputPtr xsltprocExternalEntityLoader(const char *_URL, const char *ID,xmlParserCtxtPtr ctxt) { xmlParserInputPtr ret; warningSAXFunc warning = NULL; // use local available dtd versions instead of fetching it everytime from the internet QString url = QLatin1String(_URL); QHash::const_iterator i; for(i = replaceURLList.constBegin(); i != replaceURLList.constEnd(); i++) { if (url.startsWith(i.key())) { url.replace(i.key(),i.value()); qDebug() << "converted" << _URL << "to" << url; } } char URL[1024]; strcpy(URL,url.toLatin1().constData()); const char *lastsegment = URL; const char *iter = URL; if (nbpaths > 0) { while (*iter != 0) { if (*iter == '/') lastsegment = iter + 1; iter++; } } if ((ctxt != NULL) && (ctxt->sax != NULL)) { warning = ctxt->sax->warning; ctxt->sax->warning = NULL; } if (defaultEntityLoader != NULL) { ret = defaultEntityLoader(URL, ID, ctxt); if (ret != NULL) { if (warning != NULL) ctxt->sax->warning = warning; qDebug() << "Loaded URL=\"" << URL << "\" ID=\"" << ID << "\""; return(ret); } } for (int i = 0;i < nbpaths;i++) { xmlChar *newURL; newURL = xmlStrdup((const xmlChar *) paths[i]); newURL = xmlStrcat(newURL, (const xmlChar *) "/"); newURL = xmlStrcat(newURL, (const xmlChar *) lastsegment); if (newURL != NULL) { ret = defaultEntityLoader((const char *)newURL, ID, ctxt); if (ret != NULL) { if (warning != NULL) ctxt->sax->warning = warning; qDebug() << "Loaded URL=\"" << newURL << "\" ID=\"" << ID << "\""; xmlFree(newURL); return(ret); } xmlFree(newURL); } } if (warning != NULL) { ctxt->sax->warning = warning; if (URL != NULL) warning(ctxt, "failed to load external entity \"%s\"\n", URL); else if (ID != NULL) warning(ctxt, "failed to load external entity \"%s\"\n", ID); } return(NULL); } DocbookGeneratorJob::DocbookGeneratorJob(QObject* parent): QThread(parent) { } void DocbookGeneratorJob::run() { UMLApp* app = UMLApp::app(); UMLDoc* umlDoc = app->document(); //write the XMI model in an in-memory char* string QString xmi; QTextStream xmiStream(&xmi, QIODevice::WriteOnly); #if QT_VERSION >= 0x050000 QTemporaryFile file; // we need this tmp file if we are writing to a remote file #else KTemporaryFile file; // we need this tmp file if we are writing to a remote file #endif file.setAutoRemove(false); // lets open the file for writing if (!file.open()) { uError() << "There was a problem saving file" << file.fileName(); return; } umlDoc->saveToXMI1(file); // save the xmi stuff to it xsltStylesheetPtr cur = 0; xmlDocPtr doc, res; const char *params[16 + 1]; int nbparams = 0; params[nbparams] = 0; QString xslBaseName = QLatin1String("xmi2docbook.xsl"); #if QT_VERSION >= 0x050000 - QString xsltFile(QStandardPaths::locate(QStandardPaths::DataLocation, xslBaseName)); + QString xsltFile(QStandardPaths::locate(QStandardPaths::GenericDataLocation, QLatin1String("umbrello5/") + xslBaseName)); #else - QString xsltFile(KGlobal::dirs()->findResource("appdata", xslBaseName)); + QString xsltFile(KGlobal::dirs()->findResource("data", QLatin1String("umbrello/") + xslBaseName)); #endif if (xsltFile.isEmpty()) xsltFile = QLatin1String(DOCGENERATORS_DIR) + QLatin1Char('/') + xslBaseName; if (!defaultEntityLoader) { defaultEntityLoader = xmlGetExternalEntityLoader(); xmlSetExternalEntityLoader(xsltprocExternalEntityLoader); QFileInfo xsltFilePath(xsltFile); replaceURLList[QLatin1String("http://www.oasis-open.org/docbook/xml/simple/4.1.2.5/sdocbook.dtd")] = QString(QLatin1String("file:///%1/simple4125/sdocbook.dtd")).arg(xsltFilePath.absolutePath()); } xmlSubstituteEntitiesDefault(1); xmlLoadExtDtdDefaultValue = 1; cur = xsltParseStylesheetFile((const xmlChar *)xsltFile.toLatin1().constData()); doc = xmlParseFile((const char*)(file.fileName().toUtf8())); res = xsltApplyStylesheet(cur, doc, params); #if QT_VERSION >= 0x050000 QTemporaryFile tmpDocBook; #else KTemporaryFile tmpDocBook; #endif tmpDocBook.setAutoRemove(false); tmpDocBook.open(); umlDoc->writeToStatusBar(i18n("Exporting to DocBook...")); xsltSaveResultToFd(tmpDocBook.handle(), res, cur); xsltFreeStylesheet(cur); xmlFreeDoc(res); xmlFreeDoc(doc); xsltCleanupGlobals(); xmlCleanupParser(); emit docbookGenerated(tmpDocBook.fileName()); } diff --git a/umbrello/docgenerators/xhtmlgenerator.cpp b/umbrello/docgenerators/xhtmlgenerator.cpp index f150cc122..975475a0e 100644 --- a/umbrello/docgenerators/xhtmlgenerator.cpp +++ b/umbrello/docgenerators/xhtmlgenerator.cpp @@ -1,269 +1,269 @@ /*************************************************************************** * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * copyright (C) 2006 Gael de Chalendar (aka Kleag) kleag@free.fr * * copyright (C) 2006-2014 * * Umbrello UML Modeller Authors * ***************************************************************************/ #include "xhtmlgenerator.h" #include "debug_utils.h" #include "docbook2xhtmlgeneratorjob.h" #include "uml.h" #include "umldoc.h" #include "umlviewimageexportermodel.h" #include "docbookgenerator.h" #if QT_VERSION >= 0x050000 #include #endif #include #include #if QT_VERSION < 0x050000 #include #include #endif #include #include #include #include #if QT_VERSION >= 0x050000 #include #endif #include /** * Constructor. */ XhtmlGenerator::XhtmlGenerator() { m_umlDoc = UMLApp::app()->document(); m_pStatus = true; m_pThreadFinished = false; m_d2xg = 0; } /** * Destructor. */ XhtmlGenerator::~XhtmlGenerator() { } /** * Exports the current model to XHTML in a directory named as the model * with the .xmi suffix removed. The XHTML file will have the same name * with the .html suffix. Figures will be named as the corresponding * diagrams in the GUI * @todo change file naming to avoid paths with spaces or non-ASCII chars * @todo better handling of error conditions * @return true if saving is successful and false otherwise. */ bool XhtmlGenerator::generateXhtmlForProject() { #if QT_VERSION >= 0x050000 QUrl url = m_umlDoc->url(); #else KUrl url = m_umlDoc->url(); #endif QString fileName = url.fileName(); fileName.remove(QRegExp(QLatin1String(".xmi$"))); #if QT_VERSION >= 0x050000 url.setPath(fileName); #else url.setFileName(fileName); #endif uDebug() << "Exporting to directory: " << url; return generateXhtmlForProjectInto(url); } /** * Exports the current model to XHTML in the given directory * @param destDir the directory where the XHTML file and the figures will * be written * @todo better handling of error conditions * @return true if saving is successful and false otherwise. */ #if QT_VERSION >= 0x050000 bool XhtmlGenerator::generateXhtmlForProjectInto(const QUrl& destDir) #else bool XhtmlGenerator::generateXhtmlForProjectInto(const KUrl& destDir) #endif { uDebug() << "First convert to docbook"; m_destDir = destDir; // KUrl url(QString("file://")+m_tmpDir.name()); DocbookGenerator* docbookGenerator = new DocbookGenerator; docbookGenerator->generateDocbookForProjectInto(destDir); uDebug() << "Connecting..."; connect(docbookGenerator, SIGNAL(finished(bool)), this, SLOT(slotDocbookToXhtml(bool))); return true; } /** * This slot is triggerd when the first part, xmi to docbook, is finished * @param status status to continue with converting */ void XhtmlGenerator::slotDocbookToXhtml(bool status) { uDebug() << "Now convert docbook to html..."; if (!status) { uDebug() << "Error in converting to docbook"; m_pStatus = false; return; } else { #if QT_VERSION >= 0x050000 QUrl url = m_umlDoc->url(); #else KUrl url = m_umlDoc->url(); #endif QString fileName = url.fileName(); fileName.replace(QRegExp(QLatin1String(".xmi$")), QLatin1String(".docbook")); #if QT_VERSION >= 0x050000 url.setPath(m_destDir.path() + QLatin1Char('/') + fileName); #else url.setPath(m_destDir.path()); url.addPath(fileName); #endif m_umlDoc->writeToStatusBar(i18n("Generating XHTML...")); m_d2xg = new Docbook2XhtmlGeneratorJob(url, this); connect(m_d2xg, SIGNAL(xhtmlGenerated(QString)), this, SLOT(slotHtmlGenerated(QString))); connect(m_d2xg, SIGNAL(finished()), this, SLOT(threadFinished())); uDebug() << "Threading"; m_d2xg->start(); } } /** * Triggered when the copying of the HTML result file is finished. * Emits the signal finished(). * @param tmpFileName temporary file name */ void XhtmlGenerator::slotHtmlGenerated(const QString& tmpFileName) { uDebug() << "HTML Generated " << tmpFileName; #if QT_VERSION >= 0x050000 QUrl url = m_umlDoc->url(); #else KUrl url = m_umlDoc->url(); #endif QString fileName = url.fileName(); fileName.replace(QRegExp(QLatin1String(".xmi$")), QLatin1String(".html")); #if QT_VERSION >= 0x050000 url.setPath(m_destDir.path() + QLatin1Char('/') + fileName); #else url.setPath(m_destDir.path()); url.addPath(fileName); #endif #if QT_VERSION >= 0x050000 KIO::Job* htmlCopyJob = KIO::file_copy(QUrl::fromLocalFile(tmpFileName), url, -1, KIO::Overwrite | KIO::HideProgressInfo); KJobWidgets::setWindow(htmlCopyJob, (QWidget*)UMLApp::app()); htmlCopyJob->exec(); if (!htmlCopyJob->error()) { #else KIO::Job* htmlCopyJob = KIO::file_copy(KUrl::fromPath(tmpFileName), url, -1, KIO::Overwrite | KIO::HideProgressInfo); if (KIO::NetAccess::synchronousRun(htmlCopyJob, (QWidget*)UMLApp::app())) { #endif m_umlDoc->writeToStatusBar(i18n("XHTML Generation Complete...")); } else { m_pStatus = false; return; } m_umlDoc->writeToStatusBar(i18n("Copying CSS...")); QString cssBaseName = QLatin1String("xmi.css"); #if QT_VERSION >= 0x050000 - QString cssFileName(QStandardPaths::locate(QStandardPaths::GenericDataLocation, cssBaseName)); + QString cssFileName(QStandardPaths::locate(QStandardPaths::GenericDataLocation, QLatin1String("umbrello5/") + cssBaseName)); #else - QString cssFileName(KGlobal::dirs()->findResource("appdata", cssBaseName)); + QString cssFileName(KGlobal::dirs()->findResource("data", QLatin1String("umbrello/") + cssBaseName)); #endif if (cssFileName.isEmpty()) cssFileName = QLatin1String(DOCGENERATORS_DIR) + QLatin1Char('/') + cssBaseName; #if QT_VERSION >= 0x050000 QUrl cssUrl = m_destDir; cssUrl.setPath(cssUrl.path() + QLatin1Char('/') + cssBaseName); #else KUrl cssUrl = m_destDir; cssUrl.addPath(cssBaseName); #endif #if QT_VERSION >= 0x050000 KIO::Job* cssJob = KIO::file_copy(QUrl::fromLocalFile(cssFileName), cssUrl, -1, KIO::Overwrite | KIO::HideProgressInfo); KJobWidgets::setWindow(cssJob, (QWidget*)UMLApp::app()); cssJob->exec(); if (!cssJob->error()) { #else KIO::Job* cssJob = KIO::file_copy(cssFileName, cssUrl, -1, KIO::Overwrite | KIO::HideProgressInfo); if (KIO::NetAccess::synchronousRun(cssJob, (QWidget*)UMLApp::app())) { #endif m_umlDoc->writeToStatusBar(i18n("Finished Copying CSS...")); m_pStatus = true; } else { m_umlDoc->writeToStatusBar(i18n("Failed Copying CSS...")); m_pStatus = false; } while (m_pThreadFinished == false) { // wait for thread to finish qApp->processEvents(); } emit finished(m_pStatus); } /** * Invoked when a thread is finished */ void XhtmlGenerator::threadFinished() { m_pThreadFinished = true; delete m_d2xg; m_d2xg = 0; } /** * return local dookbool xsl file for generating html * * @return filename if present */ QString XhtmlGenerator::localDocbookXslFile() { - QString xslFileName = QLatin1String("../../xml/docbook/stylesheet/nwalsh/current/html/docbook.xsl"); + QString xslFileName = QLatin1String("xml/docbook/stylesheet/nwalsh/current/html/docbook.xsl"); #if QT_VERSION >= 0x050000 QString localXsl = QStandardPaths::locate(QStandardPaths::GenericDataLocation, xslFileName); #else - QString localXsl = KGlobal::dirs()->findResource("data", xslFileName); + QString localXsl = KGlobal::dirs()->findResource("data", QLatin1String("../../") + xslFileName); #endif QFileInfo fi(localXsl); return fi.canonicalFilePath(); } /** * return custom xsl file for generating html * * @return filename */ QString XhtmlGenerator::customXslFile() { QString xslBaseName = QLatin1String("docbook2xhtml.xsl"); #if QT_VERSION >= 0x050000 - QString xsltFileName(QStandardPaths::locate(QStandardPaths::DataLocation, QLatin1String("umbrello5/") + xslBaseName)); + QString xsltFileName(QStandardPaths::locate(QStandardPaths::GenericDataLocation, QLatin1String("umbrello5/") + xslBaseName)); #else - QString xsltFileName(KGlobal::dirs()->findResource("appdata", xslBaseName)); + QString xsltFileName(KGlobal::dirs()->findResource("data", QLatin1String("umbrello/") + xslBaseName)); #endif if (xsltFileName.isEmpty()) xsltFileName = QLatin1String(DOCGENERATORS_DIR) + QLatin1Char('/') + xslBaseName; return xsltFileName; }