2013-11-04 19:29:33 +00:00
|
|
|
/***************************************************************************
|
|
|
|
* Copyright (C) 2008 by Jakub Stachowski <qbast@go2.pl> *
|
|
|
|
* *
|
|
|
|
* 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. *
|
|
|
|
***************************************************************************/
|
|
|
|
#include "mobidocument.h"
|
2013-11-04 20:38:52 +00:00
|
|
|
#include <qmobipocket/mobipocket.h>
|
|
|
|
#include <qmobipocket/qfilestream.h>
|
2018-08-31 09:23:45 +00:00
|
|
|
#include <QColor>
|
|
|
|
#include <QFile>
|
|
|
|
#include <QRegExp>
|
|
|
|
#include <QDebug>
|
2014-03-12 22:07:31 +00:00
|
|
|
#include <QApplication> // Because of the HACK
|
|
|
|
#include <QPalette> // Because of the HACK
|
2013-11-04 19:29:33 +00:00
|
|
|
|
|
|
|
using namespace Mobi;
|
|
|
|
|
|
|
|
MobiDocument::MobiDocument(const QString &fileName) : QTextDocument()
|
|
|
|
{
|
|
|
|
file = new Mobipocket::QFileStream(fileName);
|
|
|
|
doc = new Mobipocket::Document(file);
|
|
|
|
if (doc->isValid()) {
|
|
|
|
QString text=doc->text();
|
|
|
|
QString header=text.left(1024);
|
2016-07-11 19:59:14 +00:00
|
|
|
if (header.contains(QStringLiteral("<html>")) || header.contains(QStringLiteral("<HTML>"))) {
|
2014-03-12 22:07:31 +00:00
|
|
|
// HACK BEGIN Get the links without CSS to be blue
|
|
|
|
// Remove if Qt ever gets fixed and the code in textdocumentgenerator.cpp works
|
|
|
|
const QPalette orig = qApp->palette();
|
|
|
|
QPalette p = orig;
|
|
|
|
p.setColor(QPalette::Link, Qt::blue);
|
|
|
|
qApp->setPalette(p);
|
|
|
|
// HACK END
|
|
|
|
|
|
|
|
setHtml(fixMobiMarkup(text));
|
|
|
|
|
|
|
|
// HACK BEGIN
|
|
|
|
qApp->setPalette(orig);
|
|
|
|
// HACK END
|
|
|
|
} else {
|
|
|
|
setPlainText(text);
|
|
|
|
}
|
2013-11-04 19:29:33 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
MobiDocument::~MobiDocument()
|
|
|
|
{
|
|
|
|
delete doc;
|
|
|
|
delete file;
|
|
|
|
}
|
|
|
|
|
|
|
|
QVariant MobiDocument::loadResource(int type, const QUrl &name)
|
|
|
|
{
|
2016-07-11 19:59:14 +00:00
|
|
|
if (type!=QTextDocument::ImageResource || name.scheme()!=QString(QStringLiteral("pdbrec"))) return QVariant();
|
2013-11-04 19:29:33 +00:00
|
|
|
bool ok;
|
2019-04-25 21:10:48 +00:00
|
|
|
quint16 recnum=name.path().midRef(1).toUShort(&ok);
|
2013-11-04 19:29:33 +00:00
|
|
|
if (!ok || recnum>=doc->imageCount()) return QVariant();
|
|
|
|
|
|
|
|
QVariant resource;
|
|
|
|
resource.setValue(doc->getImage(recnum-1));
|
|
|
|
addResource(type, name, resource);
|
|
|
|
|
|
|
|
return resource;
|
|
|
|
}
|
|
|
|
|
|
|
|
// starting from 'pos', find position in the string that is not inside a tag
|
|
|
|
int outsideTag(const QString& data, int pos)
|
|
|
|
{
|
|
|
|
for (int i=pos-1;i>=0;i--) {
|
2016-07-11 19:59:14 +00:00
|
|
|
if (data[i]==QLatin1Char('>')) return pos;
|
|
|
|
if (data[i]==QLatin1Char('<')) return i;
|
2013-11-04 19:29:33 +00:00
|
|
|
}
|
|
|
|
return pos;
|
|
|
|
}
|
|
|
|
|
|
|
|
QString MobiDocument::fixMobiMarkup(const QString& data)
|
|
|
|
{
|
|
|
|
QString ret=data;
|
|
|
|
QMap<int,QString> anchorPositions;
|
2016-07-11 19:59:14 +00:00
|
|
|
static QRegExp anchors(QStringLiteral("<a(?: href=\"[^\"]*\"){0,1}[\\s]+filepos=['\"]{0,1}([\\d]+)[\"']{0,1}"), Qt::CaseInsensitive);
|
2013-11-04 19:29:33 +00:00
|
|
|
int pos=0;
|
|
|
|
|
|
|
|
// find all link destinations
|
|
|
|
while ( (pos=anchors.indexIn( data, pos ))!=-1) {
|
|
|
|
int filepos=anchors.cap( 1 ).toUInt( );
|
|
|
|
if (filepos) anchorPositions[filepos]=anchors.cap(1);
|
|
|
|
pos+=anchors.matchedLength();
|
|
|
|
}
|
|
|
|
|
|
|
|
// put HTML anchors in all link destinations
|
|
|
|
int offset=0;
|
|
|
|
QMapIterator<int,QString> it(anchorPositions);
|
|
|
|
while (it.hasNext()) {
|
|
|
|
it.next();
|
|
|
|
// link pointing outside the document, ignore
|
|
|
|
if ( (it.key()+offset) >= ret.size()) continue;
|
|
|
|
int fixedpos=outsideTag(ret, it.key()+offset);
|
2016-07-11 19:59:14 +00:00
|
|
|
ret.insert(fixedpos,QStringLiteral("<a name=\"")+it.value()+QStringLiteral("\"> </a>"));
|
2013-11-04 19:29:33 +00:00
|
|
|
// inserting anchor shifts all offsets after the anchor
|
|
|
|
offset+=21+it.value().size();
|
|
|
|
}
|
|
|
|
|
|
|
|
// replace links referencing filepos with normal internal links
|
2016-07-11 19:59:14 +00:00
|
|
|
ret.replace(anchors, QStringLiteral("<a href=\"#\\1\""));
|
2013-11-04 19:29:33 +00:00
|
|
|
// Mobipocket uses strange variang of IMG tags: <img recindex="3232"> where recindex is number of
|
|
|
|
// record containing image
|
2016-07-11 19:59:14 +00:00
|
|
|
static QRegExp imgs(QStringLiteral("<img.*recindex=\"([\\d]*)\".*>"), Qt::CaseInsensitive);
|
2013-11-04 19:29:33 +00:00
|
|
|
|
|
|
|
imgs.setMinimal(true);
|
2016-07-11 19:59:14 +00:00
|
|
|
ret.replace(imgs, QStringLiteral("<img src=\"pdbrec:/\\1\">"));
|
|
|
|
ret.replace(QStringLiteral("<mbp:pagebreak/>"), QStringLiteral("<p style=\"page-break-after:always\"></p>"));
|
2013-11-04 19:29:33 +00:00
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|