|
|
|
|
@ -13,6 +13,7 @@ |
|
|
|
|
#include <QtGui/QTextDocument> |
|
|
|
|
#include <QtGui/QTextFrame> |
|
|
|
|
#include <QTextDocumentFragment> |
|
|
|
|
#include <QFileInfo> |
|
|
|
|
|
|
|
|
|
#include <kdebug.h> |
|
|
|
|
#include <klocale.h> |
|
|
|
|
@ -62,9 +63,10 @@ void Converter::_emitData(Okular::DocumentInfo::Key key, |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Got over the blocks from start and add them to hashes use name as the
|
|
|
|
|
// Got over the blocks from start and add them to hashes use name as the
|
|
|
|
|
// prefix for local links
|
|
|
|
|
void Converter::_handle_anchors(const QTextBlock &start, const QString &name) { |
|
|
|
|
const QString curDir = QFileInfo(name).path(); |
|
|
|
|
|
|
|
|
|
for (QTextBlock bit = start; bit != mTextDocument->end(); bit = bit.next()) { |
|
|
|
|
for (QTextBlock::iterator fit = bit.begin(); !(fit.atEnd()); ++fit) { |
|
|
|
|
@ -72,14 +74,35 @@ void Converter::_handle_anchors(const QTextBlock &start, const QString &name) { |
|
|
|
|
QTextFragment frag = fit.fragment(); |
|
|
|
|
|
|
|
|
|
if (frag.isValid() && frag.charFormat().isAnchor()) { |
|
|
|
|
QUrl href(frag.charFormat().anchorHref()); |
|
|
|
|
QString hrefString = frag.charFormat().anchorHref(); |
|
|
|
|
|
|
|
|
|
// remove ./ or ../
|
|
|
|
|
// making it easier to compare, with links
|
|
|
|
|
while(!hrefString.isNull() && ( hrefString.at(0) == '.' || hrefString.at(0) == '/') ){ |
|
|
|
|
hrefString.remove(0,1); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
QUrl href(hrefString); |
|
|
|
|
if (href.isValid() && !href.isEmpty()) { |
|
|
|
|
if (href.isRelative()) { // Inside document link
|
|
|
|
|
mLocalLinks.insert(href.toString(), |
|
|
|
|
QPair<int, int>(frag.position(), |
|
|
|
|
frag.position()+frag.length())); |
|
|
|
|
} else { // Outside document link
|
|
|
|
|
if(!hrefString.indexOf('#')) |
|
|
|
|
hrefString = name + hrefString; |
|
|
|
|
else if(QFileInfo(hrefString).path() == "." && curDir != ".") |
|
|
|
|
hrefString = curDir + '/' + hrefString; |
|
|
|
|
|
|
|
|
|
// QTextCharFormat sometimes splits a link in two
|
|
|
|
|
// if there's no white space between words & the first one is an anchor
|
|
|
|
|
// consider whole word to be an anchor
|
|
|
|
|
++fit; |
|
|
|
|
int fragLen = frag.length(); |
|
|
|
|
if(!fit.atEnd() && ((fit.fragment().position() - frag.position()) == 1)) |
|
|
|
|
fragLen += fit.fragment().length(); |
|
|
|
|
--fit; |
|
|
|
|
|
|
|
|
|
_insert_local_links(hrefString, |
|
|
|
|
QPair<int, int>(frag.position(), |
|
|
|
|
frag.position()+fragLen)); |
|
|
|
|
} else { // Outside document link
|
|
|
|
|
Okular::BrowseAction *action = |
|
|
|
|
new Okular::BrowseAction(href.toString()); |
|
|
|
|
|
|
|
|
|
@ -101,6 +124,17 @@ void Converter::_handle_anchors(const QTextBlock &start, const QString &name) { |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void Converter::_insert_local_links(const QString &key, const QPair<int, int> &value) |
|
|
|
|
{ |
|
|
|
|
if(mLocalLinks.contains(key)){ |
|
|
|
|
mLocalLinks[key].append(value); |
|
|
|
|
} else { |
|
|
|
|
QVector< QPair<int, int> > vec; |
|
|
|
|
vec.append(value); |
|
|
|
|
mLocalLinks.insert(key,vec); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
QTextDocument* Converter::convert( const QString &fileName ) |
|
|
|
|
{ |
|
|
|
|
EpubDocument *newDocument = new EpubDocument(fileName); |
|
|
|
|
@ -142,6 +176,10 @@ QTextDocument* Converter::convert( const QString &fileName ) |
|
|
|
|
mTextDocument->setCurrentSubDocument(link); |
|
|
|
|
QString htmlContent = QString::fromUtf8(epub_it_get_curr(it)); |
|
|
|
|
|
|
|
|
|
// as QTextCharFormat::anchorNames() ignores sections, replace it with <p>
|
|
|
|
|
htmlContent.replace(QRegExp("< *section"),"<p"); |
|
|
|
|
htmlContent.replace(QRegExp("< */ *section"),"</p"); |
|
|
|
|
|
|
|
|
|
QTextBlock before; |
|
|
|
|
if(firstPage) { |
|
|
|
|
// preHtml & postHtml make it possible to have a margin around the content of the page
|
|
|
|
|
@ -243,20 +281,23 @@ QTextDocument* Converter::convert( const QString &fileName ) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// adding link actions
|
|
|
|
|
QHashIterator<QString, QPair<int, int> > hit(mLocalLinks); |
|
|
|
|
QHashIterator<QString, QVector< QPair<int, int> > > hit(mLocalLinks); |
|
|
|
|
while (hit.hasNext()) { |
|
|
|
|
hit.next(); |
|
|
|
|
|
|
|
|
|
const QTextBlock block = mSectionMap.value(hit.key()); |
|
|
|
|
if (block.isValid()) { // be sure we actually got a block
|
|
|
|
|
Okular::DocumentViewport viewport = |
|
|
|
|
calculateViewport(mTextDocument, block); |
|
|
|
|
|
|
|
|
|
Okular::GotoAction *action = new Okular::GotoAction(QString(), viewport); |
|
|
|
|
for (int i = 0; i < hit.value().size(); ++i) { |
|
|
|
|
if (block.isValid()) { // be sure we actually got a block
|
|
|
|
|
Okular::DocumentViewport viewport = |
|
|
|
|
calculateViewport(mTextDocument, block); |
|
|
|
|
|
|
|
|
|
Okular::GotoAction *action = new Okular::GotoAction(QString(), viewport); |
|
|
|
|
|
|
|
|
|
emit addAction(action, hit.value().first, hit.value().second); |
|
|
|
|
} else { |
|
|
|
|
kDebug() << "Error: no block found for "<< hit.key(); |
|
|
|
|
emit addAction(action, hit.value()[i].first, hit.value()[i].second); |
|
|
|
|
} else { |
|
|
|
|
kDebug() << "Error: no block found for "<< hit.key(); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|