mirror of
https://invent.kde.org/graphics/okular
synced 2024-08-27 11:40:07 +00:00
fix internal links
This commit is contained in:
parent
c0cc3af9be
commit
6b3ac2e1b0
|
@ -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);
|
||||
|
||||
emit addAction(action, hit.value().first, hit.value().second);
|
||||
} else {
|
||||
kDebug() << "Error: no block found for "<< hit.key();
|
||||
Okular::GotoAction *action = new Okular::GotoAction(QString(), viewport);
|
||||
|
||||
emit addAction(action, hit.value()[i].first, hit.value()[i].second);
|
||||
} else {
|
||||
kDebug() << "Error: no block found for "<< hit.key();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -30,10 +30,11 @@ namespace Epub {
|
|||
|
||||
void _emitData(Okular::DocumentInfo::Key key, enum epub_metadata type);
|
||||
void _handle_anchors(const QTextBlock &start, const QString &name);
|
||||
void _insert_local_links(const QString &key, const QPair<int, int> &value);
|
||||
EpubDocument *mTextDocument;
|
||||
|
||||
QHash<QString, QTextBlock> mSectionMap;
|
||||
QHash<QString, QPair<int, int> > mLocalLinks;
|
||||
QHash<QString, QVector< QPair<int, int> > > mLocalLinks;
|
||||
};
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue