Commit e82d5d88 authored by Aleksei Kanash's avatar Aleksei Kanash

Added the plugin "cffadaprot". It converts Sankore documents to IWB.

parent 468145e2
......@@ -35,6 +35,7 @@ QT += script
QT += xmlpatterns
INCLUDEPATH += src
INCLUDEPATH += plugins/cffadaptor/src
include($$THIRD_PARTY_PATH/libs.pri)
include(src/adaptors/adaptors.pri)
......@@ -109,6 +110,7 @@ RCC_DIR = $$BUILD_DIR/rcc
UI_DIR = $$BUILD_DIR/ui
win32 {
LIBS += "-Lplugins/cffadaptor/lib/win32" "-lCFF_Adaptor"
RC_FILE = resources/win/sankore.rc
CONFIG += qaxcontainer
exists(console):CONFIG += console
......@@ -129,6 +131,7 @@ win32 {
}
macx {
LIBS += "-Lplugins/cffadaptor/lib/mac" "-lCFF_Adaptor"
LIBS += -framework Foundation
LIBS += -lcrypto
LIBS += -framework AppKit
......@@ -326,6 +329,7 @@ macx {
}
linux-g++ {
LIBS += "-Lplugins/cffadaptor/lib/linux" "-lCFF_Adaptor"
LIBS += -lcrypto
QMAKE_CFLAGS += -fopenmp
QMAKE_CXXFLAGS += -fopenmp
......@@ -341,6 +345,7 @@ linux-g++ {
}
linux-g++-32 {
LIBS += "-Lplugins/cffadaptor/lib/linux" "-lCFF_Adaptor"
LIBS += -lcrypto
QMAKE_CFLAGS += -fopenmp
QMAKE_CXXFLAGS += -fopenmp
......@@ -356,6 +361,7 @@ linux-g++-32 {
}
linux-g++-64 {
LIBS += "-Lplugins/cffadaptor/lib/linux" "-lCFF_Adaptor"
LIBS += -lcrypto
QMAKE_CFLAGS += -fopenmp
QMAKE_CXXFLAGS += -fopenmp
......@@ -371,6 +377,7 @@ linux-g++-64 {
}
RESOURCES += resources/sankore.qrc
RESOURCES += plugins/cffadaptor/resources/resources.qrc
# When adding a translation here, also add it in the macx part
TRANSLATIONS = resources/i18n/sankore_en.ts \
......
#-------------------------------------------------
#
# Project created by QtCreator 2012-02-14T13:30:14
#
#-------------------------------------------------
win32: SUB_DIR = win32
macx: SUB_DIR = macx
linux-g++: SUB_DIR = linux
linux-g++-32: SUB_DIR = linux
linux-g++-64: SUB_DIR = linux
QUAZIP_DIR = "$$PWD/../../../Sankore-ThirdParty/quazip"
ZLIB_DIR = "$$PWD/../../../Sankore-ThirdParty/zlib"
INCLUDEPATH += src \
"$$QUAZIP_DIR/quazip-0.3" \
"$$ZLIB_DIR/1.2.3/include"
LIBS += "-L$$QUAZIP_DIR/lib/$$SUB_DIR" "-lquazip"
QT += xml xmlpatterns core
QT += gui
QT += svg
TARGET = CFF_Adaptor
TEMPLATE = lib
win32{
CONFIG += dll
}
DEFINES += UBCFFADAPTOR_LIBRARY
DEFINES += NO_THIRD_PARTY_WARNINGS
SOURCES += \
src/UBCFFAdaptor.cpp
HEADERS +=\
$$PWD/../../src/globals/UBGlobals.h \
src/UBCFFAdaptor.h \
src/UBCFFAdaptor_global.h \
src/UBCFFConstants.h
OBJECTS_DIR = $$PWD/objects
MOC_DIR = $$PWD/moc
DESTDIR = $$PWD/lib/$$SUB_DIR
RESOURCES += \
resources/resources.qrc
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 13.0.2, SVG Export Plug-In . SVG Version: 6.00 Build 14948) -->
<svg version="1.2" baseProfile="tiny" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
x="0px" y="0px" width="26px" height="26px" viewBox="0 0 26 26" xml:space="preserve">
<circle fill="#CCCCCC" cx="13" cy="13" r="13"/>
<circle fill="#999999" cx="13" cy="13" r="11"/>
<rect x="7" y="9" fill="#FFFFFF" width="6" height="8"/>
<polygon fill="#FFFFFF" points="10,11 10,15 17,21 17,5 "/>
</svg>
<RCC>
<qresource prefix="/">
<file>images/soundOn.svg</file>
</qresource>
</RCC>
#include "UBCFFAdaptor.h"
#include <QtCore>
#include <QtXml>
#include <QTransform>
#include <QGraphicsItem>
#include <QSvgRenderer>
#include <QPainter>
#include "UBGlobals.h"
#include "UBCFFConstants.h"
THIRD_PARTY_WARNINGS_DISABLE
#include "quazip.h"
#include "quazipfile.h"
#include "quazipfileinfo.h"
THIRD_PARTY_WARNINGS_ENABLE
UBCFFAdaptor::UBCFFAdaptor()
{}
bool UBCFFAdaptor::convertUBZToIWB(const QString &from, const QString &to)
{
qDebug() << "starting converion from" << from << "to" << to;
QString source = QString();
if (QFileInfo(from).isDir() && QFile::exists(from)) {
qDebug() << "File specified is dir, continuing convertion";
source = from;
} else {
source = uncompressZip(from);
if (!source.isNull()) qDebug() << "File specified is zip file. Uncompressed to tmp dir, continuing convertion";
}
if (source.isNull()) {
qDebug() << "File specified is not a dir or a zip file, stopping covretion";
return false;
}
QString tmpDestination = createNewTmpDir();
if (tmpDestination.isNull()) {
qDebug() << "can't create temp destination folder. Stopping parsing...";
return false;
}
UBToCFFConverter tmpConvertrer(source, tmpDestination);
if (!tmpConvertrer) {
qDebug() << "The convertrer class is invalid, stopping conversion. Error message" << tmpConvertrer.lastErrStr();
return false;
}
if (!tmpConvertrer.parse()) {
return false;
}
if (!compressZip(tmpDestination, to))
qDebug() << "error in compression";
//Cleanning tmp souces in filesystem
if (!QFileInfo(from).isDir())
if (!freeDir(source))
qDebug() << "can't delete tmp directory" << QDir(source).absolutePath() << "try to delete them manually";
if (!freeDir(tmpDestination))
qDebug() << "can't delete tmp directory" << QDir(tmpDestination).absolutePath() << "try to delete them manually";
return true;
}
QString UBCFFAdaptor::uncompressZip(const QString &zipFile)
{
QuaZip zip(zipFile);
if(!zip.open(QuaZip::mdUnzip)) {
qWarning() << "Import failed. Cause zip.open(): " << zip.getZipError();
return QString();
}
zip.setFileNameCodec("UTF-8");
QuaZipFileInfo info;
QuaZipFile file(&zip);
//create unique cff document root fodler
QString documentRootFolder = createNewTmpDir();
if (documentRootFolder.isNull()) {
qDebug() << "can't create tmp directory for zip file" << zipFile;
return QString();
}
QDir rootDir(documentRootFolder);
QFile out;
char c;
bool allOk = true;
for(bool more = zip.goToFirstFile(); more; more=zip.goToNextFile()) {
if(!zip.getCurrentFileInfo(&info)) {
qWarning() << "Import failed. Cause: getCurrentFileInfo(): " << zip.getZipError();
allOk = false;
break;
}
if(!file.open(QIODevice::ReadOnly)) {
allOk = false;
break;
}
if(file.getZipError()!= UNZ_OK) {
qWarning() << "Import failed. Cause: file.getFileName(): " << zip.getZipError();
allOk = false;
break;
}
QString newFileName = documentRootFolder + "/" + file.getActualFileName();
QFileInfo newFileInfo(newFileName);
rootDir.mkpath(newFileInfo.absolutePath());
out.setFileName(newFileName);
out.open(QIODevice::WriteOnly);
while(file.getChar(&c))
out.putChar(c);
out.close();
if(file.getZipError()!=UNZ_OK) {
qWarning() << "Import failed. Cause: " << zip.getZipError();
allOk = false;
break;
}
if(!file.atEnd()) {
qWarning() << "Import failed. Cause: read all but not EOF";
allOk = false;
break;
}
file.close();
if(file.getZipError()!=UNZ_OK) {
qWarning() << "Import failed. Cause: file.close(): " << file.getZipError();
allOk = false;
break;
}
}
if (!allOk) {
out.close();
file.close();
zip.close();
return QString();
}
if(zip.getZipError()!=UNZ_OK) {
qWarning() << "Import failed. Cause: zip.close(): " << zip.getZipError();
return QString();
}
return documentRootFolder;
}
bool UBCFFAdaptor::compressZip(const QString &source, const QString &destination)
{
QDir toDir = QFileInfo(destination).dir();
if (!toDir.exists())
if (!QDir().mkpath(toDir.absolutePath())) {
qDebug() << "can't create destination folder to uncompress file";
return false;
}
QuaZip zip(destination);
zip.setFileNameCodec("UTF-8");
if(!zip.open(QuaZip::mdCreate)) {
qDebug("Export failed. Cause: zip.open(): %d", zip.getZipError());
return false;
}
QuaZipFile outZip(&zip);
QFileInfo sourceInfo(source);
if (sourceInfo.isDir()) {
if (!compressDir(QFileInfo(source).absoluteFilePath(), "", &outZip))
return false;
} else if (sourceInfo.isFile()) {
if (!compressFile(QFileInfo(source).absoluteFilePath(), "", &outZip))
return false;
}
return true;
}
bool UBCFFAdaptor::compressDir(const QString &dirName, const QString &parentDir, QuaZipFile *outZip)
{
QFileInfoList dirFiles = QDir(dirName).entryInfoList(QDir::AllDirs | QDir::Files | QDir::NoDotAndDotDot);
QListIterator<QFileInfo> iter(dirFiles);
while (iter.hasNext()) {
QFileInfo curFile = iter.next();
if (curFile.isDir()) {
if (!compressDir(curFile.absoluteFilePath(), parentDir + curFile.fileName() + "/", outZip)) {
qDebug() << "error at compressing dir" << curFile.absoluteFilePath();
return false;
}
} else if (curFile.isFile()) {
if (!compressFile(curFile.absoluteFilePath(), parentDir, outZip)) {
return false;
}
}
}
return true;
}
bool UBCFFAdaptor::compressFile(const QString &fileName, const QString &parentDir, QuaZipFile *outZip)
{
QFile sourceFile(fileName);
if(!sourceFile.open(QIODevice::ReadOnly)) {
qDebug() << "Compression of file" << sourceFile.fileName() << " failed. Cause: inFile.open(): " << sourceFile.errorString();
return false;
}
if(!outZip->open(QIODevice::WriteOnly, QuaZipNewInfo(parentDir + QFileInfo(fileName).fileName(), sourceFile.fileName()))) {
qDebug() << "Compression of file" << sourceFile.fileName() << " failed. Cause: outFile.open(): " << outZip->getZipError();
sourceFile.close();
return false;
}
outZip->write(sourceFile.readAll());
if(outZip->getZipError() != UNZ_OK) {
qDebug() << "Compression of file" << sourceFile.fileName() << " failed. Cause: outFile.write(): " << outZip->getZipError();
sourceFile.close();
outZip->close();
return false;
}
if(outZip->getZipError() != UNZ_OK)
{
qWarning() << "Compression of file" << sourceFile.fileName() << " failed. Cause: outFile.close(): " << outZip->getZipError();
sourceFile.close();
outZip->close();
return false;
}
outZip->close();
sourceFile.close();
return true;
}
QString UBCFFAdaptor::createNewTmpDir()
{
int tmpNumber = 0;
QDir systemTmp = QDir::temp();
while (true) {
QString dirName = QString("CFF_adaptor_filedata_store%1.%2")
.arg(QDateTime::currentDateTime().toString("dd_MM_yyyy_HH-mm"))
.arg(tmpNumber++);
if (!systemTmp.exists(dirName)) {
if (systemTmp.mkdir(dirName)) {
QString result = systemTmp.absolutePath() + "/" + dirName;
tmpDirs.append(result);
return result;
} else {
qDebug() << "Can't create temporary dir maybe due to permissions";
return QString();
}
} else if (tmpNumber == 10) {
qWarning() << "Import failed. Failed to create temporary file ";
return QString();
}
tmpNumber++;
}
return QString();
}
bool UBCFFAdaptor::deleteDir(const QString& pDirPath) const
{
if (pDirPath == "" || pDirPath == "." || pDirPath == "..")
return false;
QDir dir(pDirPath);
if (dir.exists())
{
foreach(QFileInfo dirContent, dir.entryInfoList(QDir::Files | QDir::Dirs
| QDir::NoDotAndDotDot | QDir::Hidden | QDir::System, QDir::Name))
{
if (dirContent.isDir())
{
deleteDir(dirContent.absoluteFilePath());
}
else
{
if (!dirContent.dir().remove(dirContent.fileName()))
{
return false;
}
}
}
}
return dir.rmdir(pDirPath);
}
bool UBCFFAdaptor::freeDir(const QString &dir)
{
bool result = true;
if (!deleteDir(dir))
result = false;
tmpDirs.removeAll(QDir(dir).absolutePath());
return result;
}
void UBCFFAdaptor::freeTmpDirs()
{
foreach (QString dir, tmpDirs)
freeDir(dir);
}
UBCFFAdaptor::~UBCFFAdaptor()
{
freeTmpDirs();
}
UBCFFAdaptor::UBToCFFConverter::UBToCFFConverter(const QString &source, const QString &destination)
{
sourcePath = source;
destinationPath = destination;
errorStr = noErrorMsg;
mDataModel = new QDomDocument;
mDocumentToWrite = new QDomDocument;
mDocumentToWrite->setContent(QString("<doc></doc>"));
mIWBContentWriter = new QXmlStreamWriter;
mIWBContentWriter->setAutoFormatting(true);
iwbSVGItemsAttributes.insert(tIWBImage, iwbSVGImageAttributes);
iwbSVGItemsAttributes.insert(tIWBVideo, iwbSVGVideoAttributes);
iwbSVGItemsAttributes.insert(tIWBText, iwbSVGTextAttributes);
iwbSVGItemsAttributes.insert(tIWBTextArea, iwbSVGTextAreaAttributes);
iwbSVGItemsAttributes.insert(tIWBPolyLine, iwbSVGPolyLineAttributes);
iwbSVGItemsAttributes.insert(tIWBPolygon, iwbSVGPolygonAttributes);
iwbSVGItemsAttributes.insert(tIWBRect, iwbSVGRectAttributes);
iwbSVGItemsAttributes.insert(tIWBLine, iwbSVGLineAttributes);
iwbSVGItemsAttributes.insert(tIWBTspan, iwbSVGTspanAttributes);
}
bool UBCFFAdaptor::UBToCFFConverter::parse()
{
if(!isValid()) {
qDebug() << "document metadata is not valid. Can't parse";
return false;
}
qDebug() << "begin parsing ubz";
QFile outFile(contentIWBFileName());
if (!outFile.open(QIODevice::WriteOnly| QIODevice::Text)) {
qDebug() << "can't open output file for writing";
errorStr = "createXMLOutputPatternError";
return false;
}
mIWBContentWriter->setDevice(&outFile);
mIWBContentWriter->writeStartDocument();
mIWBContentWriter->writeStartElement(tIWBRoot);
fillNamespaces();
mIWBContentWriter->writeAttribute(aIWBVersion, avIWBVersionNo);
if (!parseMetadata()) {
if (errorStr == noErrorMsg)
errorStr = "MetadataParsingError";
outFile.close();
return false;
}
if (!parseContent()) {
if (errorStr == noErrorMsg)
errorStr = "ContentParsingError";
outFile.close();
return false;
}
mIWBContentWriter->writeEndElement();
mIWBContentWriter->writeEndDocument();
outFile.close();
qDebug() << "finished with success";
return true;
}
bool UBCFFAdaptor::UBToCFFConverter::parseMetadata()
{
int errorLine, errorColumn;
QFile metaDataFile(sourcePath + "/" + fMetadata);
if (!metaDataFile.open(QIODevice::ReadOnly | QIODevice::Text)) {
errorStr = "can't open" + QFileInfo(sourcePath + "/" + fMetadata).absoluteFilePath();
qDebug() << errorStr;
return false;
} else if (!mDataModel->setContent(metaDataFile.readAll(), true, &errorStr, &errorLine, &errorColumn)) {
qWarning() << "Error:Parseerroratline" << errorLine << ","
<< "column" << errorColumn << ":" << errorStr;
return false;
}
QDomElement nextInElement = mDataModel->documentElement();
nextInElement = nextInElement.firstChildElement(tDescription);
if (!nextInElement.isNull()) {
mIWBContentWriter->writeStartElement(iwbNS, tIWBMeta);
mIWBContentWriter->writeAttribute(aIWBName, aCreator);
mIWBContentWriter->writeAttribute(aIWBContent, avCreator);
mIWBContentWriter->writeEndElement();
mIWBContentWriter->writeStartElement(iwbNS, tIWBMeta);
mIWBContentWriter->writeAttribute(aIWBName, aOwner);
mIWBContentWriter->writeAttribute(aIWBContent, avOwner);
mIWBContentWriter->writeEndElement();
mIWBContentWriter->writeStartElement(iwbNS, tIWBMeta);
mIWBContentWriter->writeAttribute(aIWBName, aDescription);
mIWBContentWriter->writeAttribute(aIWBContent, avDescription);
mIWBContentWriter->writeEndElement();
mIWBContentWriter->writeStartElement(iwbNS, tIWBMeta);
mIWBContentWriter->writeAttribute(aIWBName, aAbout);
mIWBContentWriter->writeAttribute(aIWBContent, nextInElement.attribute(aAbout));
mIWBContentWriter->writeEndElement();
nextInElement = nextInElement.firstChildElement();
while (!nextInElement.isNull()) {
QString textContent = nextInElement.text();
if (!textContent.trimmed().isEmpty()) {
if (nextInElement.tagName() == tUBZSize) { //taking main viewbox rect since for CFF specificaton we have static viewbox
QSize tmpSize = getSVGDimentions(nextInElement.text());
if (!tmpSize.isNull()) {
mSVGSize = tmpSize;
mViewbox.setRect(0,0, tmpSize.width(), tmpSize.height());
} else {
qDebug() << "can't interpret svg section size";
errorStr = "InterpretSvgSizeError";
return false;
}
} else {
mIWBContentWriter->writeStartElement(iwbNS, tIWBMeta);
mIWBContentWriter->writeAttribute(aIWBName, nextInElement.tagName());
mIWBContentWriter->writeAttribute(aIWBContent, textContent);
mIWBContentWriter->writeEndElement();
}
}
nextInElement = nextInElement.nextSiblingElement();
}
}
metaDataFile.close();
return true;
}
bool UBCFFAdaptor::UBToCFFConverter::parseContent() {
QDir sourceDir(sourcePath);
QStringList fileFilters;
fileFilters << QString(pageAlias + "???." + pageFileExtentionUBZ);
QStringList pageList = sourceDir.entryList(fileFilters, QDir::Files, QDir::Name | QDir::IgnoreCase);
QDomElement svgDocumentSection = mDataModel->createElementNS(svgIWBNS, ":"+tSvg);
if (!pageList.count()) {
qDebug() << "can't find any content file";
errorStr = "ErrorContentFile";
return false;
} else
{
QDomElement pageset = parsePageset(pageList);
if (pageset.isNull())
return false;
else
svgDocumentSection.appendChild(pageset);
}
svgDocumentSection.setAttribute(aIWBViewBox, rectToIWBAttr(mViewbox));
svgDocumentSection.setAttribute(aWidth, QString("%1").arg(mViewbox.width()));
svgDocumentSection.setAttribute(aHeight, QString("%1").arg(mViewbox.height()));
writeQDomElementToXML(svgDocumentSection);
if (!writeExtendedIwbSection()) {
if (errorStr == noErrorMsg)
errorStr = "writeExtendedIwbSectionError";
return false;
}
return true;
}
QDomElement UBCFFAdaptor::UBToCFFConverter::parsePage(const QString &pageFileName)
{
qDebug() << "begin parsing page" + pageFileName;
mSvgElements.clear(); //clean Svg elements map before parsing new page
int errorLine, errorColumn;
QFile pageFile(sourcePath + "/" + pageFileName);
if (!pageFile.open(QIODevice::ReadOnly | QIODevice::Text)) {
qDebug() << "can't open file" << pageFileName << "for reading";
return QDomElement();
} else if (!mDataModel->setContent(pageFile.readAll(), true, &errorStr, &errorLine, &errorColumn)) {
qWarning() << "Error:Parseerroratline" << errorLine << ","
<< "column" << errorColumn << ":" << errorStr;
pageFile.close();
return QDomElement();
}
QDomElement page;
QDomElement group;
QDomElement nextTopElement = mDataModel->firstChildElement();
while (!nextTopElement.isNull()) {
QString tagname = nextTopElement.tagName();
if (tagname == tSvg) {
page = parseSvgPageSection(nextTopElement);
if (page.isNull()) {
qDebug() << "The page is empty.";
pageFile.close();
return QDomElement();
}
} else if (tagname == tUBZGroup) {
group = parseGroupPageSection(nextTopElement);
if (group.isNull()) {
qDebug() << "Page doesn't contains any groups.";
pageFile.close();
return QDomElement();
}
}
nextTopElement = nextTopElement.nextSiblingElement();
}
pageFile.close();
return page.hasChildNodes() ? page : QDomElement();
}
QDomElement UBCFFAdaptor::UBToCFFConverter::parsePageset(const QStringList &pageFileNames)
{
QMultiMap<int, QDomElement> pageList;
int iPageNo = 1;
QStringListIterator curPage(pageFileNames);
while (curPage.hasNext()) {
QString curPageFile = curPage.next();
QDomElement iterElement = parsePage(curPageFile);
if (!iterElement.isNull())
{
iterElement.setAttribute(tId, iPageNo);
addSVGElementToResultModel(iterElement, pageList, iPageNo);
iPageNo++;
}
else
return QDomElement();
}
if (!pageList.count())
return QDomElement();
QDomElement svgPagesetElement = mDocumentToWrite->createElementNS(svgIWBNS,":"+ tIWBPageSet);
QMapIterator<int, QDomElement> nextSVGElement(pageList);
nextSVGElement.toFront();
while (nextSVGElement.hasNext())
svgPagesetElement.appendChild(nextSVGElement.next().value());
return svgPagesetElement.hasChildNodes() ? svgPagesetElement : QDomElement();
}
QDomElement UBCFFAdaptor::UBToCFFConverter::parseSvgPageSection(const QDomElement &element)
{
//we don't know about page number, so return QDomElement.
//Parsing top level tag attributes
//getting current page viewbox to be able to convert coordinates to global viewbox parameter
if (element.hasAttribute(aUBZViewBox)) {
setViewBox(getViewboxRect(element.attribute(aUBZViewBox)));
}
QMultiMap<int, QDomElement> svgElements;
QDomElement svgElementPart = mDocumentToWrite->createElementNS(svgIWBNS,":"+ tIWBPage);
if (element.hasAttribute(aDarkBackground)) {
createBackground(element, svgElements);
}
//Parsing svg children attributes
// Elements can know about its layer, so it must add result QDomElements to ordrered list.
QDomElement nextElement = element.firstChildElement();
while (!nextElement.isNull()) {
QString tagName = nextElement.tagName();
if (tagName == tUBZG) parseSVGGGroup(nextElement, svgElements);
else if (tagName == tUBZImage) parseUBZImage(nextElement, svgElements);
else if (tagName == tUBZVideo) parseUBZVideo(nextElement, svgElements);
else if (tagName == tUBZAudio) parseUBZAudio(nextElement, svgElements);
else if (tagName == tUBZForeignObject) parseForeignObject(nextElement, svgElements);
else if (tagName == tUBZLine) parseUBZLine(nextElement, svgElements);
else if (tagName == tUBZPolygon) parseUBZPolygon(nextElement, svgElements);
else if (tagName == tUBZPolyline) parseUBZPolyline(nextElement, svgElements);
nextElement = nextElement.nextSiblingElement();
}
if (0 == svgElements.count())
return QDomElement();
// to do:
// there we must to sort elements (take elements from list and assign parent ordered like in parseSVGGGroup)
// we returns just element because we don't care about layer.
QMapIterator<int, QDomElement> nextSVGElement(svgElements);
nextSVGElement.toFront();
while (nextSVGElement.hasNext())
svgElementPart.appendChild(nextSVGElement.next().value());
return svgElementPart.hasChildNodes() ? svgElementPart : QDomElement();
}
void UBCFFAdaptor::UBToCFFConverter::writeQDomElementToXML(const QDomNode &node)
{
if (!node.isNull())
if (node.isText())
{
mIWBContentWriter->writeCharacters(node.nodeValue());
}
else
{
mIWBContentWriter->writeStartElement(node.namespaceURI(), node.toElement().tagName());
for (int i = 0; i < node.toElement().attributes().count(); i++)
{
QDomAttr attr = node.toElement().attributes().item(i).toAttr();
mIWBContentWriter->writeAttribute(attr.name(), attr.value());
}
QDomNode child = node.firstChild();
while(!child.isNull())
{
writeQDomElementToXML(child);
child = child.nextSibling();
}
mIWBContentWriter->writeEndElement();
}
}
bool UBCFFAdaptor::UBToCFFConverter::writeExtendedIwbSection()
{
if (!mExtendedElements.count()) {
qDebug() << "extended iwb content list is empty";
errorStr = "EmptyExtendedIwbSectionContentError";
return false;
}
QListIterator<QDomElement> nextExtendedIwbElement(mExtendedElements);
while (nextExtendedIwbElement.hasNext()) {
writeQDomElementToXML(nextExtendedIwbElement.next());
//TODO write iwb extended element to mIWBContentWriter
}
return true;
}
// extended element options
// editable, background, locked are supported for now
QDomElement UBCFFAdaptor::UBToCFFConverter::parseGroupPageSection(const QDomElement &element)
{
// First sankore side implementation needed. TODO in Sankore 1.5
Q_UNUSED(element)
qDebug() << "parsing ubz group section";
return QDomElement();
}
QString UBCFFAdaptor::UBToCFFConverter::getDstContentFolderName(const QString &elementType)
{
QString sRet;
QString sDstContentFolderName;
// widgets must be saved as .png images.
if ((tIWBImage == elementType) || (tUBZForeignObject == elementType))
sDstContentFolderName = cfImages;
else
if (tIWBVideo == elementType)
sDstContentFolderName = cfVideos;
else
if (tIWBAudio == elementType)
sDstContentFolderName = cfAudios;
sRet = sDstContentFolderName;
return sRet;
}
QString UBCFFAdaptor::UBToCFFConverter::getSrcContentFolderName(QString href)
{
QString sRet;
QStringList ls = href.split("/");
for (int i = 0; i < ls.count()-1; i++)
{
QString sPart = ls.at(i);
if (ubzContentFolders.contains(sPart))
{
sRet = sPart;
}
}
// if (0 < ls.count())
// sRet = ls.at(ls.count()-1);
//
// sRet = href.remove(sRet);
//
// if (sRet.endsWith("/"))
// sRet.remove("/");
return sRet;
}
QString UBCFFAdaptor::UBToCFFConverter::getFileNameFromPath(const QString sPath)
{
QString sRet;
QStringList sl = sPath.split("/",QString::SkipEmptyParts);
if (0 < sl.count())
{
QString name = sl.at(sl.count()-1);
QString extention = getExtentionFromFileName(name);
if (feWgt == extention)
{
name.remove("{");
name.remove("}");
}
name.remove(name.length()-extention.length(), extention.length());
name += convertExtention(extention);
sRet = name;
}
return sRet;
}
QString UBCFFAdaptor::UBToCFFConverter::getExtentionFromFileName(const QString &filename)
{
QStringList sl = filename.split("/",QString::SkipEmptyParts);
if (0 < sl.count())
{
QString name = sl.at(sl.count()-1);
QStringList tl = name.split(".");
return tl.at(tl.count()-1);
}
return QString();
}
QString UBCFFAdaptor::UBToCFFConverter::convertExtention(const QString &ext)
{
QString sRet;
if (feSvg == ext)
sRet = fePng;
else
if (feWgt == ext)
sRet = fePng;
else
sRet = ext;
return sRet;
}
QString UBCFFAdaptor::UBToCFFConverter::getElementTypeFromUBZ(const QDomElement &element)
{
QString sRet;
if (tUBZForeignObject == element.tagName())
{
QString sPath;
if (element.hasAttribute(aUBZType))
{
if (avUBZText == element.attribute(aUBZType))
sRet = tIWBTextArea;
else
sRet = element.attribute(aUBZType);
}
else
{
if (element.hasAttribute(aSrc))
sPath = element.attribute(aSrc);
else
if (element.hasAttribute(aUBZHref))
sPath = element.attribute(aUBZHref);
QStringList tsl = sPath.split(".", QString::SkipEmptyParts);
if (0 < tsl.count())
{
QString elementType = tsl.at(tsl.count()-1);
if (iwbElementImage.contains(elementType))
sRet = tIWBImage;
else
if (iwbElementAudio.contains(elementType))
sRet = tIWBAudio;
else
if (iwbElementVideo.contains(elementType))
sRet = tIWBVideo;
}
}
}
else
sRet = element.tagName();
return sRet;
}
int UBCFFAdaptor::UBToCFFConverter::getElementLayer(const QDomElement &element)
{
int iRetLayer = 0;
if (element.hasAttribute(aZLayer))
iRetLayer = (int)element.attribute(aZLayer).toDouble();
else
iRetLayer = DEFAULT_LAYER;
return iRetLayer;
}
bool UBCFFAdaptor::UBToCFFConverter::itIsSupportedFormat(const QString &format) const
{
bool bRet;
QStringList tsl = format.split(".", QString::SkipEmptyParts);
if (0 < tsl.count())
bRet = cffSupportedFileFormats.contains(tsl.at(tsl.count()-1));
else
bRet = false;
return bRet;
}
bool UBCFFAdaptor::UBToCFFConverter::itIsFormatToConvert(const QString &format) const
{
foreach (QString f, ubzFormatsToConvert.split(","))
{
if (format == f)
return true;
}
return false;
}
bool UBCFFAdaptor::UBToCFFConverter::itIsSVGElementAttribute(const QString ItemType, const QString &AttrName)
{
QString allowedElementAttributes = iwbSVGItemsAttributes[ItemType];
allowedElementAttributes.remove("/t");
allowedElementAttributes.remove(" ");
foreach(QString attr, allowedElementAttributes.split(","))
{
if (AttrName == attr.trimmed())
return true;
}
return false;
}
bool UBCFFAdaptor::UBToCFFConverter::itIsIWBAttribute(const QString &attribute) const
{
foreach (QString attr, iwbElementAttributes.split(","))
{
if (attribute == attr.trimmed())
return true;
}
return false;
}
bool UBCFFAdaptor::UBToCFFConverter::itIsUBZAttributeToConvert(const QString &attribute) const
{
foreach (QString attr, ubzElementAttributesToConvert.split(","))
{
if (attribute == attr.trimmed())
return true;
}
return false;
}
bool UBCFFAdaptor::UBToCFFConverter::ibwAddLine(int x1, int y1, int x2, int y2, QString color, int width, bool isBackground)
{
bool bRet = true;
QDomDocument doc;
QDomElement svgBackgroundCrossPart = doc.createElementNS(svgIWBNS,svgIWBNSPrefix + ":line");
QDomElement iwbBackgroundCrossPart = doc.createElementNS(iwbNS,iwbNsPrefix + ":" + tElement);
QString sUUID = QUuid::createUuid().toString().remove("{").remove("}");
svgBackgroundCrossPart.setTagName(tIWBLine);
svgBackgroundCrossPart.setAttribute(aX+"1", x1);
svgBackgroundCrossPart.setAttribute(aY+"1", y1);
svgBackgroundCrossPart.setAttribute(aX+"2", x2);
svgBackgroundCrossPart.setAttribute(aY+"2", y2);
svgBackgroundCrossPart.setAttribute(aStroke, color);
svgBackgroundCrossPart.setAttribute(aStrokeWidth, width);
svgBackgroundCrossPart.setAttribute(aID, sUUID);
if (isBackground)
{
iwbBackgroundCrossPart.setAttribute(aRef, sUUID);
iwbBackgroundCrossPart.setAttribute(aLocked, avTrue);
addIWBElementToResultModel(iwbBackgroundCrossPart);
}
addSVGElementToResultModel(svgBackgroundCrossPart, mSvgElements, DEFAULT_BACKGROUND_CROSS_LAYER);
if (!bRet)
{
qDebug() << "|error at creating crosses on background";
errorStr = "CreatingCrossedBackgroundParsingError.";
}
return bRet;
}
QTransform UBCFFAdaptor::UBToCFFConverter::getTransformFromUBZ(const QDomElement &ubzElement)
{
QTransform trRet;
QStringList transformParameters;
QString ubzTransform = ubzElement.attribute(aTransform);
ubzTransform.remove("matrix");
ubzTransform.remove("(");
ubzTransform.remove(")");
transformParameters = ubzTransform.split(",", QString::SkipEmptyParts);
if (6 <= transformParameters.count())
{
QTransform *tr = NULL;
tr = new QTransform(transformParameters.at(0).toDouble(),
transformParameters.at(1).toDouble(),
transformParameters.at(2).toDouble(),
transformParameters.at(3).toDouble(),
transformParameters.at(4).toDouble(),
transformParameters.at(5).toDouble());
trRet = *tr;
delete tr;
}
if (6 <= transformParameters.count())
{
QTransform *tr = NULL;
tr = new QTransform(transformParameters.at(0).toDouble(),
transformParameters.at(1).toDouble(),
transformParameters.at(2).toDouble(),
transformParameters.at(3).toDouble(),
transformParameters.at(4).toDouble(),
transformParameters.at(5).toDouble());
trRet = *tr;
delete tr;
}
return trRet;
}
qreal UBCFFAdaptor::UBToCFFConverter::getAngleFromTransform(const QTransform &tr)
{
qreal angle = -(atan(tr.m21()/tr.m11())*180/PI);
if (tr.m21() > 0 && tr.m11() < 0)
angle += 180;
else
if (tr.m21() < 0 && tr.m11() < 0)
angle += 180;
return angle;
}
void UBCFFAdaptor::UBToCFFConverter::setGeometryFromUBZ(const QDomElement &ubzElement, QDomElement &iwbElement)
{
setCoordinatesFromUBZ(ubzElement,iwbElement);
}
void UBCFFAdaptor::UBToCFFConverter::setCoordinatesFromUBZ(const QDomElement &ubzElement, QDomElement &iwbElement)
{
QTransform tr;
if (QString() != ubzElement.attribute(aTransform))
tr = getTransformFromUBZ(ubzElement);
qreal x = ubzElement.attribute(aX).toDouble();
qreal y = ubzElement.attribute(aY).toDouble();
qreal height = ubzElement.attribute(aHeight).toDouble();
qreal width = ubzElement.attribute(aWidth).toDouble();
qreal alpha = getAngleFromTransform(tr);
QRectF itemRect;
QGraphicsRectItem item;
item.setRect(0,0, width, height);
item.setTransform(tr);
item.setTransformOriginPoint(item.boundingRect().center());
item.setRotation(-alpha);
QMatrix sceneMatrix = item.sceneMatrix();
iwbElement.setAttribute(aX, x);
iwbElement.setAttribute(aY, y);
iwbElement.setAttribute(aHeight, height*sceneMatrix.m22());
iwbElement.setAttribute(aWidth, width*sceneMatrix.m11());
iwbElement.setAttribute(aTransform, QString("rotate(%1) translate(%2,%3)").arg(alpha)
.arg(sceneMatrix.dx())
.arg(sceneMatrix.dy()));
}
bool UBCFFAdaptor::UBToCFFConverter::setContentFromUBZ(const QDomElement &ubzElement, QDomElement &svgElement)
{
bool bRet = true;
QString srcPath;
if (tUBZForeignObject != ubzElement.tagName())
srcPath = ubzElement.attribute(aUBZHref);
else
srcPath = ubzElement.attribute(aSrc);
QString sSrcContentFolder = getSrcContentFolderName(srcPath);
QString sSrcFileName = sourcePath + "/" + srcPath ;
QString fileExtention = getExtentionFromFileName(sSrcFileName);
QString sDstContentFolder = getDstContentFolderName(ubzElement.tagName());
QString sDstFileName(QString(QUuid::createUuid().toString()+"."+convertExtention(fileExtention)).remove("{").remove("}"));
if (itIsSupportedFormat(fileExtention)) // format is supported and we can copy src. files without changing.
{
sSrcFileName = sourcePath + "/" + sSrcContentFolder + "/" + getFileNameFromPath(srcPath); // some elements must be exported as images, so we take hes existing thumbnails.
QFile srcFile;
srcFile.setFileName(sSrcFileName);
QDir dstDocFolder(destinationPath);
if (!dstDocFolder.exists(sDstContentFolder))
bRet &= dstDocFolder.mkdir(sDstContentFolder);
if (bRet)
{
QString dstFilePath = destinationPath+"/"+sDstContentFolder+"/"+sDstFileName;
bRet &= srcFile.copy(dstFilePath);
}
if (bRet)
{
svgElement.setAttribute(aSVGHref, sDstContentFolder+"/"+sDstFileName);
svgElement.setAttribute(aSVGRequiredExtension, svgRequiredExtensionPrefix+convertExtention(fileExtention));
}
}
else
if (itIsFormatToConvert(fileExtention)) // we cannot copy that source files. We need to create dst. file from src. file without copy.
{
if (feSvg == fileExtention)
{
QDir dstDocFolder(destinationPath);
if (!dstDocFolder.exists(sDstContentFolder))
bRet &= dstDocFolder.mkdir(sDstContentFolder);
if (bRet)
{
if (feSvg == fileExtention) // svg images must be converted to PNG.
{
QString dstFilePath = destinationPath+"/"+sDstContentFolder+"/"+sDstFileName;
bRet &= createPngFromSvg(sSrcFileName, dstFilePath, getTransformFromUBZ(ubzElement));
}
else
bRet = false;
}
if (bRet)
{
svgElement.setAttribute(aSVGHref, sDstContentFolder+"/"+sDstFileName);
svgElement.setAttribute(aSVGRequiredExtension, svgRequiredExtensionPrefix+fePng);
}
}
}
if (!bRet)
{
qDebug() << "format is not supported by CFF";
}
return bRet;
}
void UBCFFAdaptor::UBToCFFConverter::setCFFTextFromHTMLTextNode(const QDomElement htmlTextNode, QDomElement &iwbElement)
{
QDomDocument textDoc;
QDomElement textParentElement = iwbElement;
QString textString;
QDomNode htmlPNode = htmlTextNode.firstChild();
bool bTbreak = false;
// reads HTML text strings - each string placed in separate <p> section
while(!htmlPNode.isNull())
{
// add <tbreak> for split strings
if (bTbreak)
{
bTbreak = false;
QDomElement tbreakNode = textDoc.createElementNS(svgIWBNS, svgIWBNSPrefix+":"+tIWBTbreak);
textParentElement.appendChild(tbreakNode.cloneNode(true));
}
QDomNode spanNode = htmlPNode.firstChild();
while (!spanNode.isNull())
{
if (spanNode.isText())
{
QDomText nodeText = textDoc.createTextNode(spanNode.nodeValue());
textParentElement.appendChild(nodeText.cloneNode(true));
}
else
if (spanNode.isElement())
{
QDomElement spanElement = textDoc.createElementNS(svgIWBNS,svgIWBNSPrefix + ":" + tIWBTspan);
if (spanNode.hasAttributes())
{
int attrCount = spanNode.attributes().count();
if (0 < attrCount)
{
for (int i = 0; i < attrCount; i++)
{
// html attributes like: style="font-size:40pt; color:"red";".
QStringList cffAttributes = spanNode.attributes().item(i).nodeValue().split(";", QString::SkipEmptyParts);
{
for (int i = 0; i < cffAttributes.count(); i++)
{
QString attr = cffAttributes.at(i).trimmed();
QStringList AttrVal = attr.split(":", QString::SkipEmptyParts);
if(1 < AttrVal.count())
{
QString sAttr = ubzAttrNameToCFFAttrName(AttrVal.at(0));
if (itIsSVGElementAttribute(spanElement.tagName(), sAttr))
spanElement.setAttribute(sAttr, ubzAttrValueToCFFAttrName(AttrVal.at(1)));
}
}
}
}
}
}
QDomText nodeText = textDoc.createTextNode(spanNode.firstChild().nodeValue());
spanElement.appendChild(nodeText);
textParentElement.appendChild(spanElement.cloneNode(true));
}
spanNode = spanNode.nextSibling();
}
bTbreak = true;
htmlPNode = htmlPNode.nextSibling();
}
}
QString UBCFFAdaptor::UBToCFFConverter::ubzAttrNameToCFFAttrName(QString cffAttrName)
{
QString sRet = cffAttrName;
if (QString("color") == cffAttrName)
sRet = QString("fill");
return sRet;
}
QString UBCFFAdaptor::UBToCFFConverter::ubzAttrValueToCFFAttrName(QString cffValue)
{
QString sRet = cffValue;
if (QString("text") == cffValue)
sRet = QString("normal");
return sRet;
}
bool UBCFFAdaptor::UBToCFFConverter::setCFFAttribute(const QString &attributeName, const QString &attributeValue, const QDomElement &ubzElement, QDomElement &iwbElement, QDomElement &svgElement)
{
bool bRet = true;
bool bNeedsIWBSection = false;
if (itIsIWBAttribute(attributeName))
{
if (!((aBackground == attributeName) && (avFalse == attributeValue)))
{
iwbElement.setAttribute(attributeName, attributeValue);
bNeedsIWBSection = true;
}
}
else
if (itIsUBZAttributeToConvert(attributeName))
{
if (aTransform == attributeName)
{
setGeometryFromUBZ(ubzElement, svgElement);
}
else
if (attributeName.contains(aUBZHref)||attributeName.contains(aSrc))
{
bRet &= setContentFromUBZ(ubzElement, svgElement);
bNeedsIWBSection = bRet||bNeedsIWBSection;
}
}
else
if (itIsSVGElementAttribute(svgElement.tagName(),attributeName))
{
svgElement.setAttribute(attributeName, attributeValue);
}
if (bNeedsIWBSection)
{
if (0 < iwbElement.attributes().count())
{
QStringList tl = ubzElement.attribute(aSVGHref).split("/");
QString id = tl.at(tl.count()-1);
// if element already have an ID, we use it. Else we create new id for element.
if (QString() == id)
id = QUuid::createUuid().toString().remove("{").remove("}");
svgElement.setAttribute(aID, id);
iwbElement.setAttribute(aRef, id);
}
}
return bRet;
}
bool UBCFFAdaptor::UBToCFFConverter::setCommonAttributesFromUBZ(const QDomElement &ubzElement, QDomElement &iwbElement, QDomElement &svgElement)
{
bool bRet = true;
for (int i = 0; i < ubzElement.attributes().count(); i++)
{
QDomNode attribute = ubzElement.attributes().item(i);
QString attributeName = ubzAttrNameToCFFAttrName(attribute.nodeName().remove("ub:"));
bRet &= setCFFAttribute(attributeName, ubzAttrValueToCFFAttrName(attribute.nodeValue()), ubzElement, iwbElement, svgElement);
if (!bRet) break;
}
return bRet;
}
void UBCFFAdaptor::UBToCFFConverter::setViewBox(QRect viewbox)
{
mViewbox |= viewbox;
}
QDomNode UBCFFAdaptor::UBToCFFConverter::findTextNode(const QDomNode &node)
{
QDomNode iterNode = node;
while (!iterNode.isNull())
{
if (iterNode.isText())
{
if (!iterNode.isNull())
return iterNode;
}
else
{
if (!iterNode.firstChild().isNull())
{
QDomNode foundNode = findTextNode(iterNode.firstChild());
if (!foundNode.isNull())
if (foundNode.isText())
return foundNode;
}
}
if (!iterNode.nextSibling().isNull())
iterNode = iterNode.nextSibling();
else
break;
}
return iterNode;
}
QDomNode UBCFFAdaptor::UBToCFFConverter::findNodeByTagName(const QDomNode &node, QString tagName)
{
QDomNode iterNode = node;
while (!iterNode.isNull())
{
QString t = iterNode.toElement().tagName();
if (tagName == t)
return iterNode;
else
{
if (!iterNode.firstChildElement().isNull())
{
QDomNode foundNode = findNodeByTagName(iterNode.firstChildElement(), tagName);
if (!foundNode.isNull())
if (foundNode.isElement())
{
if (tagName == foundNode.toElement().tagName())
return foundNode;
}
else
break;
}
}
if (!iterNode.nextSibling().isNull())
iterNode = iterNode.nextSibling();
else
break;
}
return QDomNode();
}
bool UBCFFAdaptor::UBToCFFConverter::createBackground(const QDomElement &element, QMultiMap<int, QDomElement> &dstSvgList)
{
qDebug() << "|creating element background";
QDomDocument doc;
//QDomElement svgBackgroundElementPart = doc.createElementNS(svgIWBNS,svgIWBNSPrefix + ":" + tUBZImage);
QDomElement svgBackgroundElementPart = doc.createElementNS(svgIWBNS,svgIWBNSPrefix + ":" + tIWBRect);
QDomElement iwbBackgroundElementPart = doc.createElementNS(iwbNS,iwbNsPrefix + ":" + tElement);
QRect bckRect(mViewbox);
if (0 <= mViewbox.topLeft().x())
bckRect.topLeft().setX(0);
if (0 <= mViewbox.topLeft().y())
bckRect.topLeft().setY(0);
// QString backgroundImagePath = createBackgroundImage(element, QSize(bckRect.width(), bckRect.height()));
// if (QString() != backgroundImagePath)
if (QRect() != bckRect)
{
QString sElementID = QUuid::createUuid().toString().remove("{").remove("}");
bool darkBackground = (avTrue == element.attribute(aDarkBackground));
svgBackgroundElementPart.setAttribute(aFill, darkBackground ? "black" : "white");
svgBackgroundElementPart.setAttribute(aID, sElementID);
svgBackgroundElementPart.setAttribute(aX, bckRect.x());
svgBackgroundElementPart.setAttribute(aY, bckRect.y());
svgBackgroundElementPart.setAttribute(aHeight, bckRect.height());
svgBackgroundElementPart.setAttribute(aWidth, bckRect.width());
//svgBackgroundElementPart.setAttribute(aSVGHref, backgroundImagePath);
iwbBackgroundElementPart.setAttribute(aRef, sElementID);
iwbBackgroundElementPart.setAttribute(aBackground, avTrue);
//iwbBackgroundElementPart.setAttribute(aLocked, avTrue);
addSVGElementToResultModel(svgBackgroundElementPart, dstSvgList, DEFAULT_BACKGROUND_LAYER);
addIWBElementToResultModel(iwbBackgroundElementPart);
return true;
}
else
{
qDebug() << "|error at creating element background";
errorStr = "CreatingElementBackgroundParsingError.";
return false;
}
}
QString UBCFFAdaptor::UBToCFFConverter::createBackgroundImage(const QDomElement &element, QSize size)
{
QString sRet;
QString sDstFileName(fIWBBackground);
bool bDirExists = true;
QDir dstDocFolder(destinationPath);
if (!dstDocFolder.exists(cfImages))
bDirExists &= dstDocFolder.mkdir(cfImages);
QString dstFilePath;
if (bDirExists)
dstFilePath = destinationPath+"/"+cfImages+"/"+sDstFileName;
if (!QFile().exists(dstFilePath))
{
QRect rect(0,0, size.width(), size.height());
QImage *bckImage = new QImage(size, QImage::Format_RGB888);
QPainter *painter = new QPainter(bckImage);
bool darkBackground = (avTrue == element.attribute(aDarkBackground));
QColor bCrossColor;
bCrossColor = darkBackground?QColor(Qt::white):QColor(Qt::blue);
int penAlpha = (int)(255/2); // default Sankore value for transform.m11 < 1
bCrossColor.setAlpha(penAlpha);
painter->setPen(bCrossColor);
painter->setBrush(darkBackground?QColor(Qt::black):QColor(Qt::white));
painter->drawRect(rect);
if (avTrue == element.attribute(aCrossedBackground))
{
qreal firstY = ((int) (rect.y () / iCrossSize)) * iCrossSize;
for (qreal yPos = firstY; yPos <= rect.y () + rect.height (); yPos += iCrossSize)
{
painter->drawLine (rect.x (), yPos, rect.x () + rect.width (), yPos);
}
qreal firstX = ((int) (rect.x () / iCrossSize)) * iCrossSize;
for (qreal xPos = firstX; xPos <= rect.x () + rect.width (); xPos += iCrossSize)
{
painter->drawLine (xPos, rect.y (), xPos, rect.y () + rect.height ());
}
}
painter->end();
painter->save();
if (QString() != dstFilePath)
if (bckImage->save(dstFilePath))
sRet = cfImages+"/"+sDstFileName;
delete bckImage;
delete painter;
}
else
sRet = cfImages+"/"+sDstFileName;
return sRet;
}
bool UBCFFAdaptor::UBToCFFConverter::createPngFromSvg(QString &svgPath, QString &dstPath, QTransform transformation, QSize size)
{
if (QFile().exists(svgPath))
{
QImage i(svgPath);
QSize iSize = (QSize() == size)?QSize(i.size().width()*transformation.m11(), i.size().height()*transformation.m22()):size;
QImage image(iSize, QImage::Format_ARGB32_Premultiplied);
image.fill(0);
QPainter imagePainter(&image);
QSvgRenderer renderer(svgPath);
renderer.render(&imagePainter);
return image.save(dstPath);
}
else
return false;
}
bool UBCFFAdaptor::UBToCFFConverter::parseSVGGGroup(const QDomElement &element, QMultiMap<int, QDomElement> &dstSvgList)
{
qDebug() << "|parsing g section";
QDomElement nextElement = element.firstChildElement();
if (nextElement.isNull()) {
qDebug() << "Empty g element";
errorStr = "EmptyGSection";
return false;
}
QMultiMap<int, QDomElement> svgElements;
QDomDocument doc;
QDomElement svgElementPart = doc.createElementNS(svgIWBNS,svgIWBNSPrefix + ":" + tIWBG);
QDomElement iwbElementPart = doc.createElementNS(iwbNS,iwbNsPrefix + ":" + tElement);
// Elements can know about its layer, so it must add result QDomElements to ordrered list.
while (!nextElement.isNull()) {
QString tagName = nextElement.tagName();
if (tagName == tUBZLine) parseUBZLine(nextElement, svgElements);
else if (tagName == tUBZPolygon) parseUBZPolygon(nextElement, svgElements);
else if (tagName == tUBZPolyline) parseUBZPolyline(nextElement, svgElements);
nextElement = nextElement.nextSiblingElement();
}
QList<int> layers;
QMapIterator<int, QDomElement> nextSVGElement(svgElements);
while (nextSVGElement.hasNext())
layers << nextSVGElement.next().key();
qSort(layers);
int layer = layers.at(0);
nextSVGElement.toFront();
while (nextSVGElement.hasNext())
svgElementPart.appendChild(nextSVGElement.next().value());
addSVGElementToResultModel(svgElementPart, dstSvgList, layer);
return true;
}
bool UBCFFAdaptor::UBToCFFConverter::parseUBZImage(const QDomElement &element, QMultiMap<int, QDomElement> &dstSvgList)
{
qDebug() << "|parsing image";
QDomDocument doc;
QDomElement svgElementPart = doc.createElementNS(svgIWBNS,svgIWBNSPrefix + ":" + getElementTypeFromUBZ(element));
QDomElement iwbElementPart = doc.createElementNS(iwbNS,iwbNsPrefix + ":" + tElement);
if (setCommonAttributesFromUBZ(element, iwbElementPart, svgElementPart))
{
addSVGElementToResultModel(svgElementPart, dstSvgList, getElementLayer(element));
if (0 < iwbElementPart.attributes().count())
addIWBElementToResultModel(iwbElementPart);
return true;
}
else
{
qDebug() << "|error at image parsing";
errorStr = "ImageParsingError";
return false;
}
}
bool UBCFFAdaptor::UBToCFFConverter::parseUBZVideo(const QDomElement &element, QMultiMap<int, QDomElement> &dstSvgList)
{
qDebug() << "|parsing video";
QDomDocument doc;
QDomElement svgElementPart = doc.createElementNS(svgIWBNS,svgIWBNSPrefix + ":" + getElementTypeFromUBZ(element));
QDomElement iwbElementPart = doc.createElementNS(iwbNS,iwbNsPrefix + ":" + tElement);
if (setCommonAttributesFromUBZ(element, iwbElementPart, svgElementPart))
{
QDomElement svgSwitchSection = doc.createElementNS(svgIWBNS,svgIWBNSPrefix + ":" + tIWBSwitch);
svgSwitchSection.appendChild(svgElementPart);
// if viewer cannot open that content - it must use that:
QDomElement svgText = doc.createElementNS(svgIWBNS,svgIWBNSPrefix + ":" + tIWBTextArea);
svgText.setAttribute(aX, svgElementPart.attribute(aX));
svgText.setAttribute(aY, svgElementPart.attribute(aY));
svgText.setAttribute(aWidth, svgElementPart.attribute(aWidth));
svgText.setAttribute(aHeight, svgElementPart.attribute(aHeight));
svgText.setAttribute(aTransform, svgElementPart.attribute(aTransform));
QDomText text = doc.createTextNode("Cannot Open Content");
svgText.appendChild(text);
svgSwitchSection.appendChild(svgText);
addSVGElementToResultModel(svgSwitchSection, dstSvgList, getElementLayer(element));
if (0 < iwbElementPart.attributes().count())
addIWBElementToResultModel(iwbElementPart);
return true;
}
else
{
qDebug() << "|error at video parsing";
errorStr = "VideoParsingError";
return false;
}
}
bool UBCFFAdaptor::UBToCFFConverter::parseUBZAudio(const QDomElement &element, QMultiMap<int, QDomElement> &dstSvgList)
{
qDebug() << "|parsing audio";
// audio file must be linked to cff item excluding video.
// to do:
// 1 add image for audio element.
// 2 set id for this element
// 3 add <svg:a> section with xlink:href to audio file
// 4 add shild to a section with id of the image
QDomDocument doc;
QDomElement svgElementPart = doc.createElementNS(svgIWBNS,svgIWBNSPrefix + ":" + getElementTypeFromUBZ(element));
QDomElement iwbElementPart = doc.createElementNS(iwbNS,iwbNsPrefix + ":" + tElement);
if (setCommonAttributesFromUBZ(element, iwbElementPart, svgElementPart))
{
//we must create image-containers for audio files
int audioImageDimention = qMin(svgElementPart.attribute(aWidth).toInt(), svgElementPart.attribute(aHeight).toInt());
QString srcAudioImageFile(sAudioElementImage);
QString elementId = QString(QUuid::createUuid().toString()).remove("{").remove("}");
QString sDstAudioImageFileName = elementId+"."+fePng;
QString dstAudioImageFilePath = destinationPath+"/"+cfImages+"/"+sDstAudioImageFileName;
QString dstAudioImageRelativePath = cfImages+"/"+sDstAudioImageFileName;
QFile srcFile(srcAudioImageFile);
//creating folder for audioImage
QDir dstDocFolder(destinationPath);
bool bRes = true;
if (!dstDocFolder.exists(cfImages))
bRes &= dstDocFolder.mkdir(cfImages);
// CFF cannot show SVG images, so we need to convert it to png.
if (bRes && createPngFromSvg(srcAudioImageFile, dstAudioImageFilePath, getTransformFromUBZ(element), QSize(audioImageDimention, audioImageDimention)))
{
QDomElement svgSwitchSection = doc.createElementNS(svgIWBNS,svgIWBNSPrefix + ":" + tIWBSwitch);
// first we place content
QDomElement svgASection = doc.createElementNS(svgIWBNS,svgIWBNSPrefix + ":" + tIWBA);
svgASection.setAttribute(aSVGHref, svgElementPart.attribute(aSVGHref));
svgElementPart.setTagName(tIWBImage);
svgElementPart.setAttribute(aSVGHref, dstAudioImageRelativePath);
svgElementPart.setAttribute(aHeight, audioImageDimention);
svgElementPart.setAttribute(aWidth, audioImageDimention);
svgASection.appendChild(svgElementPart);
svgSwitchSection.appendChild(svgASection);
// if viewer cannot open that content - it must use that:
QDomElement svgText = doc.createElementNS(svgIWBNS,svgIWBNSPrefix + ":" + tIWBTextArea);
svgText.setAttribute(aX, svgElementPart.attribute(aX));
svgText.setAttribute(aY, svgElementPart.attribute(aY));
svgText.setAttribute(aWidth, svgElementPart.attribute(aWidth));
svgText.setAttribute(aHeight, svgElementPart.attribute(aHeight));
svgText.setAttribute(aTransform, svgElementPart.attribute(aTransform));
QDomText text = doc.createTextNode("Cannot Open Content");
svgText.appendChild(text);
svgSwitchSection.appendChild(svgText);
addSVGElementToResultModel(svgSwitchSection, dstSvgList, getElementLayer(element));
if (0 < iwbElementPart.attributes().count())
addIWBElementToResultModel(iwbElementPart);
return true;
}
return false;
}
else
{
qDebug() << "|error at audio parsing";
errorStr = "AudioParsingError";
return false;
}
}
bool UBCFFAdaptor::UBToCFFConverter::parseForeignObject(const QDomElement &element, QMultiMap<int, QDomElement> &dstSvgList)
{
if (element.attribute(aUBZType) == avUBZText) {
return parseUBZText(element, dstSvgList);
}
qDebug() << "|parsing foreign object";
QDomDocument doc;
QDomElement svgElementPart = doc.createElementNS(svgIWBNS,svgIWBNSPrefix + ":" + getElementTypeFromUBZ(element));
QDomElement iwbElementPart = doc.createElementNS(iwbNS,iwbNsPrefix + ":" + tElement);
if (setCommonAttributesFromUBZ(element, iwbElementPart, svgElementPart))
{
addSVGElementToResultModel(svgElementPart, dstSvgList, getElementLayer(element));
if (0 < iwbElementPart.attributes().count())
addIWBElementToResultModel(iwbElementPart);
return true;
}
else
{
qDebug() << "|error at parsing foreign object";
errorStr = "ForeignObjectParsingError";
return false;
}
}
bool UBCFFAdaptor::UBToCFFConverter::parseUBZText(const QDomElement &element, QMultiMap<int, QDomElement> &dstSvgList)
{
qDebug() << "|parsing text";
QDomDocument doc;
QDomElement svgElementPart = doc.createElementNS(svgIWBNS,svgIWBNSPrefix + ":" + getElementTypeFromUBZ(element));
QDomElement iwbElementPart = doc.createElementNS(iwbNS,iwbNsPrefix + ":" + tElement);
if (element.hasChildNodes())
{
QDomDocument htmlDoc;
htmlDoc.setContent(findTextNode(element).nodeValue());
QDomNode bodyNode = findNodeByTagName(htmlDoc.firstChildElement(), "body");
setCFFTextFromHTMLTextNode(bodyNode.toElement(), svgElementPart);
if (setCommonAttributesFromUBZ(element, iwbElementPart, svgElementPart))
{
QString commonParams;
for (int i = 0; i < bodyNode.attributes().count(); i++)
{
commonParams += " " + bodyNode.attributes().item(i).nodeValue();
}
commonParams.remove(" ");
commonParams.remove("'");
QStringList commonAttributes = commonParams.split(";", QString::SkipEmptyParts);
for (int i = 0; i < commonAttributes.count(); i++)
{
QStringList AttrVal = commonAttributes.at(i).split(":", QString::SkipEmptyParts);
if (1 < AttrVal.count())
{
QString sAttr = ubzAttrNameToCFFAttrName(AttrVal.at(0));
QString sVal = ubzAttrValueToCFFAttrName(AttrVal.at(1));
setCFFAttribute(sAttr, sVal, element, iwbElementPart, svgElementPart);
}
}
addSVGElementToResultModel(svgElementPart, dstSvgList, getElementLayer(element));
if (0 < iwbElementPart.attributes().count())
addIWBElementToResultModel(iwbElementPart);
return true;
}
return false;
}
else
{
qDebug() << "|error at text parsing";
errorStr = "TextParsingError";
return false;
}
}
bool UBCFFAdaptor::UBToCFFConverter::parseUBZPolygon(const QDomElement &element, QMultiMap<int, QDomElement> &dstSvgList)
{
qDebug() << "||parsing polygon";
QDomDocument doc;
QDomElement svgElementPart = doc.createElementNS(svgIWBNS,svgIWBNSPrefix + ":" + getElementTypeFromUBZ(element));
QDomElement iwbElementPart = doc.createElementNS(iwbNS,iwbNsPrefix + ":" + tElement);
if (setCommonAttributesFromUBZ(element, iwbElementPart, svgElementPart))
{
addSVGElementToResultModel(svgElementPart, dstSvgList, getElementLayer(element));
if (0 < iwbElementPart.attributes().count())
{
QString id = QUuid::createUuid().toString().remove("{").remove("}");
svgElementPart.setAttribute(aID, id);
iwbElementPart.setAttribute(aRef, id);
addIWBElementToResultModel(iwbElementPart);
}
return true;
}
else
{
qDebug() << "||error at parsing polygon";
errorStr = "PolygonParsingError";
return false;
}
}
bool UBCFFAdaptor::UBToCFFConverter::parseUBZPolyline(const QDomElement &element, QMultiMap<int, QDomElement> &dstSvgList)
{
qDebug() << "||parsing polyline";
QDomElement resElement;
QDomDocument doc;
QDomElement svgElementPart = doc.createElementNS(svgIWBNS,svgIWBNSPrefix + ":" + getElementTypeFromUBZ(element));
QDomElement iwbElementPart = doc.createElementNS(iwbNS,iwbNsPrefix + ":" + tElement);
if (setCommonAttributesFromUBZ(element, iwbElementPart, svgElementPart))
{
addSVGElementToResultModel(svgElementPart, dstSvgList, getElementLayer(element));
if (0 < iwbElementPart.attributes().count())
{
QString id = QUuid::createUuid().toString().remove("{").remove("}");
svgElementPart.setAttribute(aID, id);
iwbElementPart.setAttribute(aRef, id);
addIWBElementToResultModel(iwbElementPart);
}
return true;
}
else
{
qDebug() << "||error at parsing polygon";
errorStr = "PolylineParsingError";
return false;
}
}
bool UBCFFAdaptor::UBToCFFConverter::parseUBZLine(const QDomElement &element, QMultiMap<int, QDomElement> &dstSvgList)
{
qDebug() << "||parsing line";
QDomElement resElement;
QDomDocument doc;
QDomElement svgElementPart = doc.createElementNS(svgIWBNS,svgIWBNSPrefix + ":" + getElementTypeFromUBZ(element));
QDomElement iwbElementPart = doc.createElementNS(iwbNS,iwbNsPrefix + ":" + tElement);
if (setCommonAttributesFromUBZ(element, iwbElementPart, svgElementPart))
{
addSVGElementToResultModel(svgElementPart, dstSvgList, getElementLayer(element));
if (0 < iwbElementPart.attributes().count())
{
QString id = QUuid::createUuid().toString().remove("{").remove("}");
svgElementPart.setAttribute(aID, id);
iwbElementPart.setAttribute(aRef, id);
addIWBElementToResultModel(iwbElementPart);
}
}
else
{
qDebug() << "||error at parsing polygon";
errorStr = "LineParsingError";
return false;
}
return true;
}
void UBCFFAdaptor::UBToCFFConverter::addSVGElementToResultModel(const QDomElement &element, QMultiMap<int, QDomElement> &dstList, int layer)
{
int elementLayer = (DEFAULT_LAYER == layer) ? DEFAULT_LAYER : layer;
dstList.setInsertInOrder(true);
QDomElement rootElement = element.cloneNode(true).toElement();
mDocumentToWrite->firstChildElement().appendChild(rootElement);
dstList.insert(elementLayer, rootElement);
}
void UBCFFAdaptor::UBToCFFConverter::addIWBElementToResultModel(const QDomElement &element)
{
QDomElement rootElement = element.cloneNode(true).toElement();
mDocumentToWrite->firstChildElement().appendChild(rootElement);
mExtendedElements.append(rootElement);
}
UBCFFAdaptor::UBToCFFConverter::~UBToCFFConverter()
{
if (mDataModel)
delete mDataModel;
if (mIWBContentWriter)
delete mIWBContentWriter;
}
bool UBCFFAdaptor::UBToCFFConverter::isValid() const
{
bool result = QFileInfo(sourcePath).exists()
&& QFileInfo(sourcePath).isDir()
&& errorStr == noErrorMsg;
if (!result) {
qDebug() << "specified data is not valid";
errorStr = "ValidateDataError";
}
return result;
}
void UBCFFAdaptor::UBToCFFConverter::fillNamespaces()
{
mIWBContentWriter->writeDefaultNamespace(svgUBZNS);
mIWBContentWriter->writeNamespace(iwbNS, iwbNsPrefix);
mIWBContentWriter->writeNamespace(svgIWBNS, svgIWBNSPrefix);
mIWBContentWriter->writeNamespace(xlinkNS, xlinkNSPrefix);
}
QString UBCFFAdaptor::UBToCFFConverter::digitFileFormat(int digit) const
{
return QString("%1").arg(digit, 3, 10, QLatin1Char('0'));
}
QString UBCFFAdaptor::UBToCFFConverter::contentIWBFileName() const
{
return destinationPath + "/" + fIWBContent;
}
//setting SVG dimenitons
QSize UBCFFAdaptor::UBToCFFConverter::getSVGDimentions(const QString &element)
{
QStringList dimList;
dimList = element.split(dimensionsDelimiter1, QString::KeepEmptyParts);
if (dimList.count() != 2) // row unlike 0x0
return QSize();
bool ok;
int width = dimList.takeFirst().toInt(&ok);
if (!ok || !width)
return QSize();
int height = dimList.takeFirst().toInt(&ok);
if (!ok || !height)
return QSize();
return QSize(width, height);
}
//Setting viewbox rectangle
QRect UBCFFAdaptor::UBToCFFConverter::getViewboxRect(const QString &element) const
{
QStringList dimList;
dimList = element.split(dimensionsDelimiter2, QString::KeepEmptyParts);
if (dimList.count() != 4) // row unlike 0 0 0 0
return QRect();
bool ok = false;
int x = dimList.takeFirst().toInt(&ok);
if (!ok || !x)
return QRect();
int y = dimList.takeFirst().toInt(&ok);
if (!ok || !y)
return QRect();
int width = dimList.takeFirst().toInt(&ok);
if (!ok || !width)
return QRect();
int height = dimList.takeFirst().toInt(&ok);
if (!ok || !height)
return QRect();
return QRect(x, y, width, height);
}
QString UBCFFAdaptor::UBToCFFConverter::rectToIWBAttr(const QRect &rect) const
{
if (rect.isNull()) return QString();
return QString("%1 %2 %3 %4").arg(rect.topLeft().x())
.arg(rect.topLeft().y())
.arg(rect.width())
.arg(rect.height());
}
UBCFFAdaptor::UBToUBZConverter::UBToUBZConverter()
{
}
#ifndef UBCFFADAPTOR_H
#define UBCFFADAPTOR_H
#include "UBCFFAdaptor_global.h"
#include <QtCore>
class QTransform;
class QDomDocument;
class QDomElement;
class QDomNode;
class QuaZipFile;
class UBCFFADAPTORSHARED_EXPORT UBCFFAdaptor {
class UBToCFFConverter;
public:
UBCFFAdaptor();
~UBCFFAdaptor();
bool convertUBZToIWB(const QString &from, const QString &to);
bool deleteDir(const QString& pDirPath) const;
private:
QString uncompressZip(const QString &zipFile);
bool compressZip(const QString &source, const QString &destination);
bool compressDir(const QString &dirName, const QString &parentDir, QuaZipFile *outZip);
bool compressFile(const QString &fileName, const QString &parentDir, QuaZipFile *outZip);
QString createNewTmpDir();
bool freeDir(const QString &dir);
void freeTmpDirs();
private:
QStringList tmpDirs;
private:
class UBToCFFConverter {
static const int DEFAULT_LAYER = -100000;
public:
UBToCFFConverter(const QString &source, const QString &destination);
~UBToCFFConverter();
bool isValid() const;
QString lastErrStr() const {return errorStr;}
bool parse();
private:
void fillNamespaces();
bool parseMetadata();
bool parseContent();
QDomElement parsePageset(const QStringList &pageFileNames);
QDomElement parsePage(const QString &pageFileName);
QDomElement parseSvgPageSection(const QDomElement &element);
void writeQDomElementToXML(const QDomNode &node);
bool writeExtendedIwbSection();
QDomElement parseGroupPageSection(const QDomElement &element);
bool createBackground(const QDomElement &element, QMultiMap<int, QDomElement> &dstSvgList);
QString createBackgroundImage(const QDomElement &element, QSize size);
bool createPngFromSvg(QString &svgPath, QString &dstPath, QTransform transformation, QSize size = QSize());
bool parseSVGGGroup(const QDomElement &element, QMultiMap<int, QDomElement> &dstSvgList);
bool parseUBZImage(const QDomElement &element, QMultiMap<int, QDomElement> &dstSvgList);
bool parseUBZVideo(const QDomElement &element, QMultiMap<int, QDomElement> &dstSvgList);
bool parseUBZAudio(const QDomElement &element, QMultiMap<int, QDomElement> &dstSvgList);
bool parseForeignObject(const QDomElement &element, QMultiMap<int, QDomElement> &dstSvgList);
bool parseUBZText(const QDomElement &element, QMultiMap<int, QDomElement> &dstSvgList);
bool parseUBZPolygon(const QDomElement &element, QMultiMap<int, QDomElement> &dstSvgList);
bool parseUBZPolyline(const QDomElement &element, QMultiMap<int, QDomElement> &dstSvgList);
bool parseUBZLine(const QDomElement &element, QMultiMap<int, QDomElement> &dstSvgList);
void addSVGElementToResultModel(const QDomElement &element, QMultiMap<int, QDomElement> &dstList, int layer = DEFAULT_LAYER);
void addIWBElementToResultModel(const QDomElement &element);
qreal getAngleFromTransform(const QTransform &tr);
QString getDstContentFolderName(const QString &elementType);
QString getSrcContentFolderName(QString href);
QString getFileNameFromPath(QString sPath);
QString getExtentionFromFileName(const QString &filename);
QString convertExtention(const QString &ext);
QString getElementTypeFromUBZ(const QDomElement &element);
int getElementLayer(const QDomElement &element);
bool itIsSupportedFormat(const QString &format) const;
bool itIsFormatToConvert(const QString &format) const;
bool itIsSVGElementAttribute(const QString ItemType, const QString &AttrName);
bool itIsIWBAttribute(const QString &attribute) const;
bool itIsUBZAttributeToConvert(const QString &attribute) const;
bool ibwAddLine(int x1, int y1, int x2, int y2, QString color=QString(), int width=1, bool isBackground=false);
QTransform getTransformFromUBZ(const QDomElement &ubzElement);
void setGeometryFromUBZ(const QDomElement &ubzElement, QDomElement &iwbElement);
void setCoordinatesFromUBZ(const QDomElement &ubzElement, QDomElement &iwbElement);
bool setContentFromUBZ(const QDomElement &ubzElement, QDomElement &svgElement);
void setCFFTextFromUBZ(const QDomElement &ubzElement, QDomElement &iwbElement, QDomElement &svgElement);
void setCFFTextFromHTMLTextNode(const QDomElement htmlTextNode, QDomElement &iwbElement);
QString ubzAttrNameToCFFAttrName(QString cffAttrName);
QString ubzAttrValueToCFFAttrName(QString cffAttrValue);
bool setCFFAttribute(const QString &attributeName, const QString &attributeValue, const QDomElement &ubzElement, QDomElement &iwbElement, QDomElement &svgElement);
bool setCommonAttributesFromUBZ(const QDomElement &ubzElement, QDomElement &iwbElement, QDomElement &svgElement);
void setViewBox(QRect viewbox);
QDomNode findTextNode(const QDomNode &node);
QDomNode findNodeByTagName(const QDomNode &node, QString tagName);
QSize getSVGDimentions(const QString &element);
inline QRect getViewboxRect(const QString &element) const;
inline QString rectToIWBAttr(const QRect &rect) const;
inline QString digitFileFormat(int num) const;
inline bool strToBool(const QString &in) const {return in == "true";}
QString contentIWBFileName() const;
private:
QMap<QString, QString> iwbSVGItemsAttributes;
QDomDocument *mDataModel; //model for reading indata
QXmlStreamWriter *mIWBContentWriter; //stream to write outdata
QSize mSVGSize; //svg page size
QRect mViewbox; //Main viewbox parameter for CFF
QString sourcePath; // dir with unpacked source data (ubz)
QString destinationPath; //dir with unpacked destination data (iwb)
QDomDocument *mDocumentToWrite; //document for saved QDomElements from mSvgElements and mExtendedElements
QMultiMap<int, QDomElement> mSvgElements; //Saving svg elements to have a sorted by z order list of elements to write;
QList<QDomElement> mExtendedElements; //Saving extended options of elements to be able to add them to the end of result iwb document;
mutable QString errorStr; // last error string message
public:
operator bool() const {return isValid();}
};
class UBToUBZConverter {
public:
UBToUBZConverter();
};
};
#endif // UBCFFADAPTOR_H
#ifndef UBCFFADAPTOR_GLOBAL_H
#define UBCFFADAPTOR_GLOBAL_H
#include <QtCore/qglobal.h>
#if defined(UBCFFADAPTOR_LIBRARY)
# define UBCFFADAPTORSHARED_EXPORT Q_DECL_EXPORT
#else
# define UBCFFADAPTORSHARED_EXPORT Q_DECL_IMPORT
#endif
#endif // UBCFFADAPTOR_GLOBAL_H
#ifndef UBCFFCONSTANTS_H
#define UBCFFCONSTANTS_H
#define PI 3.1415926535
const int DEFAULT_BACKGROUND_LAYER = -20000002;
const int DEFAULT_BACKGROUND_CROSS_LAYER = -20000001;
// Constant names. Use only them instead const char* in each function
// Constant fileNames;
const QString fMetadata = "metadata.rdf";
const QString fIWBContent = "content.xml";
const QString fIWBBackground = "background.png";
const QString sAudioElementImage = ":images/soundOn.svg";
// Constant messages;
const QString noErrorMsg = "NoError";
// Tag names
const QString tDescription = "Description";
const QString tIWBRoot = "iwb";
const QString tIWBMeta = "meta";
const QString tUBZSize = "size";
const QString tSvg = "svg";
const QString tIWBPage = "page";
const QString tIWBPageSet = "pageset";
const QString tId = "id";
const QString tElement = "element";
const QString tUBZGroup = "group";
const QString tUBZG = "g";
const QString tUBZPolygon = "polygon";
const QString tUBZPolyline = "polyline";
const QString tUBZLine = "line";
const QString tUBZAudio = "audio";
const QString tUBZVideo = "video";
const QString tUBZImage = "image";
const QString tUBZForeignObject = "foreignObject";
const QString tUBZTextContent = "itemTextContent";
const QString tIWBA = "a";
const QString tIWBG = "g";
const QString tIWBSwitch = "switch";
const QString tIWBImage = "image";
const QString tIWBVideo = "video";
const QString tIWBAudio = "audio";
const QString tIWBText = "text";
const QString tIWBTextArea = "textarea";
const QString tIWBPolyLine = "polyline";
const QString tIWBPolygon = "polygon";
const QString tIWBFlash = "video";
const QString tIWBRect = "rect";
const QString tIWBLine = "line";
const QString tIWBTbreak = "tbreak";
const QString tIWBTspan = "tspan";
// Attributes names
const QString aIWBVersion = "version";
const QString aOwner = "owner";
const QString aDescription = "description";
const QString aCreator = "creator";
const QString aAbout = "about";
const QString aIWBViewBox = "viewbox";
const QString aUBZViewBox = "viewBox";
const QString aDarkBackground = "dark-background";
const QString aBackground = "background";
const QString aCrossedBackground = "crossed-background";
const QString aUBZType = "type";
const QString aUBZUuid = "uuid";
const QString aFill = "fill"; // IWB attribute contans color to fill
const QString aID = "id"; // ID of any svg element can be placed in to iwb section
const QString aRef = "ref"; // as reference for applying additional attributes
const QString aSVGHref = "xlink:href"; // reference to file
const QString aIWBHref = "ref"; // reference to element ID
const QString aUBZHref = "href";
const QString aSrc = "src";
const QString aSVGRequiredExtension = "requiredExtensions";
const QString aX = "x";
const QString aY = "y";
const QString aWidth = "width";
const QString aHeight = "height";
const QString aStroke = "stroke";
const QString aStrokeWidth = "stroke-width";
const QString aPoints = "points";
const QString aZLayer = "z-value";
const QString aLayer = "layer";
const QString aTransform = "transform";
const QString aLocked = "locked";
const QString aIWBName = "name";
const QString aIWBContent = "content";
// Attribute values
const QString avIWBVersionNo = "1.0";
const QString avUBZText = "text";
const QString avFalse = "false";
const QString avTrue = "true";
// Namespaces and prefixes
const QString svgRequiredExtensionPrefix = "http://www.imsglobal.org/iwb/";
const QString dcNS = "http://purl.org/dc/elements/1.1/";
const QString ubNS = "http://uniboard.mnemis.com/document";
const QString svgUBZNS = "http://www.imsglobal.org/xsd/iwb_v1p0";
const QString svgIWBNS = "http://www.w3.org/2000/svg";
const QString xlinkNS = "http://www.w3.org/1999/xlink";
const QString iwbNS = "http://www.becta.org.uk/iwb";
const QString xsiNS = "http://www.w3.org/2001/XMLSchema-instance";
const QString xsiShemaLocation = "\
http://www.imsglobal.org/xsd/iwb_v1p0 \
http://www.imsglobal.org/profile/iwb/iwbv1p0_v1p0.xsd \
http://www.w3.org/2000/svg http://www.imsglobal.org/profile/iwb/svgsubsetv1p0_v1p0.xsd \
http://www.w3.org/1999/xlink http://www.imsglobal.org/xsd/w3/1999/xlink.xsd";
const QString dcNSPrefix = "dc";
const QString ubNSPrefix = "ub";
const QString svgIWBNSPrefix = "svg";
const QString xlinkNSPrefix = "xlink";
const QString iwbNsPrefix = "iwb";
const QString xsiPrefix = "xsi";
const QString xsiSchemaLocationPrefix = "schemaLocation";
const QString avOwner = "";
const QString avCreator = "";
const QString avDescription = "";
//constant symbols and words etc
const QString dimensionsDelimiter1 = "x";
const QString dimensionsDelimiter2 = " ";
const QString pageAlias = "page";
const QString pageFileExtentionUBZ = "svg";
//content folder names
const QString cfImages = "images";
const QString cfVideos = "video";
const QString cfAudios = "audio";
const QString cfFlash = "flash";
//known file extentions
const QString feSvg = "svg";
const QString feWgt = "wgt";
const QString fePng = "png";
const int iCrossSize = 32;
const int iCrossWidth = 1;
// Image formats supported by CFF exclude wgt. Wgt is Sankore widget, which is considered as a .png preview.
const QString iwbElementImage(" \
wgt, \
jpeg, \
jpg, \
bmp, \
gif, \
wmf, \
emf, \
png, \
tif, \
tiff \
");
// Video formats supported by CFF
const QString iwbElementVideo(" \
mpg, \
mpeg, \
swf, \
");
// Audio formats supported by CFF
const QString iwbElementAudio(" \
mp3, \
wav \
");
const QString cffSupportedFileFormats(iwbElementImage + iwbElementVideo + iwbElementAudio);
const QString ubzFormatsToConvert("svg");
const QString iwbSVGImageAttributes(" \
id, \
xlink:href, \
x, \
y, \
height, \
width, \
fill-opacity, \
requiredExtentions, \
transform \
");
const QString iwbSVGAudioAttributes(" \
id, \
xlink:href, \
x, \
y, \
height, \
width, \
fill-opacity, \
requiredExtentions, \
transform \
");
const QString iwbSVGVideoAttributes(" \
id, \
xlink:href, \
x, \
y, \
height, \
width, \
fill-opacity, \
requiredExtentions, \
transform \
");
const QString iwbSVGRectAttributes(" \
id, \
x, \
y, \
height, \
width, \
fill, \
fill-opacity, \
stroke, \
stroke-dasharray, \
stroke-linecap, \
stroke-linejoin, \
stroke-opacity, \
stroke-width, \
transform \
");
const QString iwbSVGTextAttributes(" \
id, \
x, \
y, \
fill, \
font-family, \
font-size, \
font-style, \
font-weight, \
font-stretch, \
transform \
");
const QString iwbSVGTextAreaAttributes(" \
id, \
x, \
y, \
height, \
width, \
fill, \
font-family, \
font-size, \
font-style, \
font-weight, \
font-stretch, \
text-align, \
transform \
");
const QString iwbSVGTspanAttributes(" \
id, \
fill, \
font-family, \
font-size, \
font-style, \
font-weight, \
font-stretch, \
text-align, \
");
const QString iwbSVGLineAttributes(" \
id, \
x1, \
y1, \
x2, \
y2, \
stroke, \
stroke-dasharray, \
stroke-width, \
stroke-opacity, \
stroke-linecap, \
transform \
");
const QString iwbSVGPolyLineAttributes(" \
id, \
points, \
stroke, \
stroke-width, \
stroke-dasharray, \
stroke-opacity, \
stroke-linecap, \
transform \
");
const QString iwbSVGPolygonAttributes(" \
id, \
points, \
fill, \
fill-opacity, \
stroke, \
stroke-dasharray, \
stroke-width, \
stroke-linecap, \
stroke-linejoin, \
stroke-opacity, \
stroke-width, \
transform \
");
// 1 to 1 copy to SVG section
const QString iwbElementAttributes(" \
background, \
background-fill, \
background-posture, \
flip, \
freehand, \
highlight, \
highlight-fill, \
list-style-type, \
list-style-type-fill, \
locked, \
replicate, \
revealer, \
stroke-lineshape-start, \
stroke-lineshape-end \
");
// cannot be copied 1 to 1 to SVG section
const QString ubzElementAttributesToConvert(" \
xlink:href, \
src, \
transform \
");
// additional attributes. Have references in SVG section.
const QString svgElementAttributes(" \
points, \
fill, \
fill-opacity, \
stroke, \
stroke-dasharray, \
stroke-linecap, \
stroke-opacity, \
stroke-width, \
stroke_linejoin, \
requiredExtensions, \
viewbox, \
x, \
y, \
x1, \
y1, \
x2, \
y2, \
height, \
width, \
font-family, \
font-size, \
font-style, \
font-weight, \
font-stretch, \
text-align \
");
const QString ubzContentFolders("audios,videos,images,widgets");
struct UBItemLayerType
{
enum Enum
{
FixedBackground = -2000, Object = -1000, Graphic = 0, Tool = 1000, Control = 2000
};
};
#endif // UBCFFCONSTANTS_H
\ No newline at end of file
#ifndef UBGLOBALS_H
#define UBGLOBALS_H
#define DELETEPTR(ptr) if(NULL != ptr){ \
delete ptr; \
ptr = NULL; \
}
#ifdef Q_WS_WIN
#define WARNINGS_DISABLE __pragma(warning(push, 0));
#define WARNINGS_ENABLE __pragma(warning(pop));
#ifdef NO_THIRD_PARTY_WARNINGS
// disabling warning level to 0 and save old state
#define THIRD_PARTY_WARNINGS_DISABLE WARNINGS_DISABLE
#else
// just save old state (needs for not empty define)
#define THIRD_PARTY_WARNINGS_DISABLE __pragma(warning(push));
#endif //#ifdef NO_THIRD_PARTY_WARNINGS
// anyway on WIN
#define THIRD_PARTY_WARNINGS_ENABLE WARNINGS_ENABLE
#else //#ifdef Q_WS_WIN
#define WARNINGS_DISABLE _Pragma("GCC diagnostic push"); \
_Pragma("GCC diagnostic ignored \"-Wunused-parameter\""); \
_Pragma("GCC diagnostic ignored \"-Wunused-variable\""); \
_Pragma("GCC diagnostic ignored \"-Wsign-compare\"");
#define WARNINGS_ENABLE _Pragma("GCC diagnostic pop");
#ifdef NO_THIRD_PARTY_WARNINGS
//disabling some warnings
#define THIRD_PARTY_WARNINGS_DISABLE WARNINGS_DISABLE
#define THIRD_PARTY_WARNINGS_ENABLE WARNINGS_ENABLE
#else
// just save old state (needs for not empty define)
#define THIRD_PARTY_WARNINGS_ENABLE WARNINGS_ENABLE
#endif //#ifdef NO_THIRD_PARTY_WARNINGS
#endif //#ifdef Q_WS_WIN
#endif // UBGLOBALS_H
#include "UBExportCFF.h"
#include "UBCFFAdaptor.h"
#include "document/UBDocumentProxy.h"
#include "core/UBDocumentManager.h"
#include "core/UBApplication.h"
UBExportCFF::UBExportCFF(QObject *parent)
: UBExportAdaptor(parent)
{
}
UBExportCFF::~UBExportCFF()
{
}
QString UBExportCFF::exportName()
{
return tr("Export to IWB");
}
QString UBExportCFF::exportExtention()
{
return QString(".iwb");
}
void UBExportCFF::persist(UBDocumentProxy* pDocument)
{
QString src = pDocument->persistencePath();
if (!pDocument)
return;
QString filename = askForFileName(pDocument, tr("Export as IWB File"));
if (filename.length() > 0)
{
QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
if (mIsVerbose)
UBApplication::showMessage(tr("Exporting document..."));
UBCFFAdaptor toIWBExporter;
if (toIWBExporter.convertUBZToIWB(src, filename))
{
if (mIsVerbose)
UBApplication::showMessage(tr("Export successful."));
}
else
if (mIsVerbose)
UBApplication::showMessage(tr("Export failed."));
QApplication::restoreOverrideCursor();
}
}
\ No newline at end of file
/*
* 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 3 of the License, or
* (at your option) any later version.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef UBExportCFF_H_
#define UBExportCFF_H_
#include <QtCore>
#include "UBExportAdaptor.h"
#include "frameworks/UBFileSystemUtils.h"
class UBDocumentProxy;
class UBExportCFF : public UBExportAdaptor
{
Q_OBJECT;
public:
UBExportCFF(QObject *parent = 0);
virtual ~UBExportCFF();
virtual QString exportName();
virtual QString exportExtention();
virtual void persist(UBDocumentProxy* pDocument);
};
#endif /* UBExportCFF_H_ */
\ No newline at end of file
......@@ -14,6 +14,7 @@ HEADERS += src/adaptors/UBExportAdaptor.h\
src/adaptors/UBExportWeb.h \
src/adaptors/UBWebPublisher.h \
src/adaptors/UBImportCFF.h \
src/adaptors/UBExportCFF.h \
src/adaptors/UBCFFSubsetAdaptor.h
HEADERS += src/adaptors/publishing/UBDocumentPublisher.h \
......@@ -36,6 +37,7 @@ SOURCES += src/adaptors/UBExportAdaptor.cpp\
src/adaptors/UBExportWeb.cpp \
src/adaptors/UBWebPublisher.cpp \
src/adaptors/UBImportCFF.cpp \
src/adaptors/UBExportCFF.cpp \
src/adaptors/UBCFFSubsetAdaptor.cpp \
src/adaptors/publishing/UBDocumentPublisher.cpp
......
......@@ -21,6 +21,7 @@
#include "adaptors/UBExportFullPDF.h"
#include "adaptors/UBExportDocument.h"
#include "adaptors/UBExportWeb.h"
#include "adaptors/UBExportCFF.h"
#include "adaptors/UBWebPublisher.h"
#include "adaptors/UBImportDocument.h"
#include "adaptors/UBImportPDF.h"
......@@ -62,6 +63,8 @@ UBDocumentManager::UBDocumentManager(QObject *parent)
QString dummyObjects = tr("objects");
QString dummyWidgets = tr("widgets");
UBExportCFF* cffExporter = new UBExportCFF(this);
mExportAdaptors.append(cffExporter);
UBExportFullPDF* exportFullPdf = new UBExportFullPDF(this);
mExportAdaptors.append(exportFullPdf);
UBExportDocument* exportDocument = new UBExportDocument(this);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment