2007-01-13 23:15:28 +00:00
|
|
|
/***************************************************************************
|
|
|
|
* Copyright (C) 2007 by Tobias Koenig <tokoe@kde.org> *
|
|
|
|
* *
|
|
|
|
* 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. *
|
|
|
|
***************************************************************************/
|
|
|
|
|
2007-04-19 18:30:20 +00:00
|
|
|
#include "textdocumentgenerator.h"
|
|
|
|
#include "textdocumentgenerator_p.h"
|
|
|
|
|
2018-08-31 09:23:45 +00:00
|
|
|
#include <QFile>
|
|
|
|
#include <QFontDatabase>
|
|
|
|
#include <QImage>
|
|
|
|
#include <QMutex>
|
|
|
|
#include <QPainter>
|
|
|
|
#include <QPrinter>
|
|
|
|
#include <QStack>
|
|
|
|
#include <QTextDocumentWriter>
|
|
|
|
#include <QTextStream>
|
|
|
|
#include <QVector>
|
2007-01-13 23:15:28 +00:00
|
|
|
|
2011-06-01 08:31:44 +00:00
|
|
|
#include "action.h"
|
|
|
|
#include "annotations.h"
|
2019-03-30 22:47:17 +00:00
|
|
|
#include "document_p.h"
|
2011-06-01 08:31:44 +00:00
|
|
|
#include "page.h"
|
|
|
|
#include "textpage.h"
|
2007-01-13 23:15:28 +00:00
|
|
|
|
2019-01-28 23:04:25 +00:00
|
|
|
#include <cmath>
|
|
|
|
|
2007-01-13 23:15:28 +00:00
|
|
|
using namespace Okular;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Generic Converter Implementation
|
|
|
|
*/
|
|
|
|
TextDocumentConverter::TextDocumentConverter()
|
2017-09-05 21:27:18 +00:00
|
|
|
: QObject(nullptr)
|
|
|
|
, d_ptr(new TextDocumentConverterPrivate)
|
2007-01-13 23:15:28 +00:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
TextDocumentConverter::~TextDocumentConverter()
|
|
|
|
{
|
2007-12-08 14:45:32 +00:00
|
|
|
delete d_ptr;
|
2007-01-13 23:15:28 +00:00
|
|
|
}
|
|
|
|
|
2014-05-10 13:31:59 +00:00
|
|
|
QTextDocument *TextDocumentConverter::convert(const QString &)
|
|
|
|
{
|
2017-09-05 21:27:18 +00:00
|
|
|
return nullptr;
|
2014-05-10 13:31:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
Document::OpenResult TextDocumentConverter::convertWithPassword(const QString &fileName, const QString &)
|
|
|
|
{
|
|
|
|
QTextDocument *doc = convert(fileName);
|
|
|
|
setDocument(doc);
|
2017-09-05 21:27:18 +00:00
|
|
|
return doc != nullptr ? Document::OpenSuccess : Document::OpenError;
|
2014-05-10 13:31:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
QTextDocument *TextDocumentConverter::document()
|
|
|
|
{
|
|
|
|
return d_ptr->mDocument;
|
|
|
|
}
|
|
|
|
|
|
|
|
void TextDocumentConverter::setDocument(QTextDocument *document)
|
|
|
|
{
|
|
|
|
d_ptr->mDocument = document;
|
|
|
|
}
|
|
|
|
|
2007-01-19 16:33:58 +00:00
|
|
|
DocumentViewport TextDocumentConverter::calculateViewport(QTextDocument *document, const QTextBlock &block)
|
|
|
|
{
|
2009-01-10 11:29:11 +00:00
|
|
|
return TextDocumentUtils::calculateViewport(document, block);
|
2007-01-19 16:33:58 +00:00
|
|
|
}
|
|
|
|
|
2008-02-14 23:19:24 +00:00
|
|
|
TextDocumentGenerator *TextDocumentConverter::generator() const
|
|
|
|
{
|
2017-09-05 21:27:18 +00:00
|
|
|
return d_ptr->mParent ? d_ptr->mParent->q_func() : nullptr;
|
2008-02-14 23:19:24 +00:00
|
|
|
}
|
|
|
|
|
2007-01-13 23:15:28 +00:00
|
|
|
/**
|
|
|
|
* Generic Generator Implementation
|
|
|
|
*/
|
2007-09-14 13:31:55 +00:00
|
|
|
Okular::TextPage *TextDocumentGeneratorPrivate::createTextPage(int pageNumber) const
|
2007-01-13 23:15:28 +00:00
|
|
|
{
|
2008-08-15 13:24:02 +00:00
|
|
|
#ifdef OKULAR_TEXTDOCUMENT_THREADED_RENDERING
|
2008-05-06 20:20:10 +00:00
|
|
|
Q_Q(const TextDocumentGenerator);
|
2008-08-15 13:24:02 +00:00
|
|
|
#endif
|
2008-05-06 20:20:10 +00:00
|
|
|
|
2007-01-13 23:15:28 +00:00
|
|
|
Okular::TextPage *textPage = new Okular::TextPage;
|
|
|
|
|
|
|
|
int start, end;
|
|
|
|
|
2008-05-06 20:20:10 +00:00
|
|
|
#ifdef OKULAR_TEXTDOCUMENT_THREADED_RENDERING
|
|
|
|
q->userMutex()->lock();
|
|
|
|
#endif
|
2009-01-10 11:29:11 +00:00
|
|
|
TextDocumentUtils::calculatePositions(mDocument, pageNumber, start, end);
|
2007-01-13 23:15:28 +00:00
|
|
|
|
2008-05-07 23:04:01 +00:00
|
|
|
{
|
2007-01-13 23:15:28 +00:00
|
|
|
QTextCursor cursor(mDocument);
|
|
|
|
for (int i = start; i < end - 1; ++i) {
|
|
|
|
cursor.setPosition(i);
|
|
|
|
cursor.setPosition(i + 1, QTextCursor::KeepAnchor);
|
2020-07-10 22:15:05 +00:00
|
|
|
|
2007-01-13 23:15:28 +00:00
|
|
|
QString text = cursor.selectedText();
|
2007-05-12 08:17:02 +00:00
|
|
|
if (text.length() == 1) {
|
2007-01-13 23:15:28 +00:00
|
|
|
QRectF rect;
|
2009-01-10 11:29:11 +00:00
|
|
|
TextDocumentUtils::calculateBoundingRect(mDocument, i, i + 1, rect, pageNumber);
|
2007-05-12 08:17:02 +00:00
|
|
|
if (pageNumber == -1)
|
2015-10-29 12:37:11 +00:00
|
|
|
text = QStringLiteral("\n");
|
2020-07-10 22:15:05 +00:00
|
|
|
|
2007-01-13 23:15:28 +00:00
|
|
|
textPage->append(text, new Okular::NormalizedRect(rect.left(), rect.top(), rect.right(), rect.bottom()));
|
2020-07-10 22:15:05 +00:00
|
|
|
}
|
2007-01-13 23:15:28 +00:00
|
|
|
}
|
|
|
|
}
|
2008-05-06 20:20:10 +00:00
|
|
|
#ifdef OKULAR_TEXTDOCUMENT_THREADED_RENDERING
|
|
|
|
q->userMutex()->unlock();
|
|
|
|
#endif
|
2007-01-13 23:15:28 +00:00
|
|
|
|
|
|
|
return textPage;
|
|
|
|
}
|
|
|
|
|
2007-09-14 13:31:55 +00:00
|
|
|
void TextDocumentGeneratorPrivate::addAction(Action *action, int cursorBegin, int cursorEnd)
|
2007-01-13 23:15:28 +00:00
|
|
|
{
|
2007-04-20 12:49:17 +00:00
|
|
|
if (!action)
|
2007-01-13 23:15:28 +00:00
|
|
|
return;
|
|
|
|
|
|
|
|
LinkPosition position;
|
2007-04-20 12:49:17 +00:00
|
|
|
position.link = action;
|
2007-01-13 23:15:28 +00:00
|
|
|
position.startPosition = cursorBegin;
|
|
|
|
position.endPosition = cursorEnd;
|
|
|
|
|
|
|
|
mLinkPositions.append(position);
|
|
|
|
}
|
|
|
|
|
2007-09-14 13:31:55 +00:00
|
|
|
void TextDocumentGeneratorPrivate::addAnnotation(Annotation *annotation, int cursorBegin, int cursorEnd)
|
2007-01-13 23:15:28 +00:00
|
|
|
{
|
|
|
|
if (!annotation)
|
|
|
|
return;
|
|
|
|
|
2007-12-08 13:45:06 +00:00
|
|
|
annotation->setFlags(annotation->flags() | Okular::Annotation::External);
|
|
|
|
|
2007-01-13 23:15:28 +00:00
|
|
|
AnnotationPosition position;
|
|
|
|
position.annotation = annotation;
|
|
|
|
position.startPosition = cursorBegin;
|
|
|
|
position.endPosition = cursorEnd;
|
|
|
|
|
|
|
|
mAnnotationPositions.append(position);
|
|
|
|
}
|
|
|
|
|
2007-09-14 13:31:55 +00:00
|
|
|
void TextDocumentGeneratorPrivate::addTitle(int level, const QString &title, const QTextBlock &block)
|
2007-01-13 23:15:28 +00:00
|
|
|
{
|
|
|
|
TitlePosition position;
|
|
|
|
position.level = level;
|
|
|
|
position.title = title;
|
|
|
|
position.block = block;
|
|
|
|
|
|
|
|
mTitlePositions.append(position);
|
|
|
|
}
|
|
|
|
|
2007-09-14 13:31:55 +00:00
|
|
|
void TextDocumentGeneratorPrivate::addMetaData(const QString &key, const QString &value, const QString &title)
|
2007-01-13 23:15:28 +00:00
|
|
|
{
|
|
|
|
mDocumentInfo.set(key, value, title);
|
|
|
|
}
|
|
|
|
|
2008-02-08 14:13:55 +00:00
|
|
|
void TextDocumentGeneratorPrivate::addMetaData(DocumentInfo::Key key, const QString &value)
|
|
|
|
{
|
|
|
|
mDocumentInfo.set(key, value);
|
|
|
|
}
|
|
|
|
|
2019-01-16 18:29:52 +00:00
|
|
|
QList<TextDocumentGeneratorPrivate::LinkInfo> TextDocumentGeneratorPrivate::generateLinkInfos() const
|
2007-01-13 23:15:28 +00:00
|
|
|
{
|
2019-01-16 18:29:52 +00:00
|
|
|
QList<LinkInfo> result;
|
|
|
|
|
2007-01-13 23:15:28 +00:00
|
|
|
for (int i = 0; i < mLinkPositions.count(); ++i) {
|
|
|
|
const LinkPosition &linkPosition = mLinkPositions[i];
|
|
|
|
|
2019-01-28 21:08:24 +00:00
|
|
|
const QVector<QRectF> rects = TextDocumentUtils::calculateBoundingRects(mDocument, linkPosition.startPosition, linkPosition.endPosition);
|
2007-01-13 23:15:28 +00:00
|
|
|
|
2019-01-28 21:08:24 +00:00
|
|
|
for (int i = 0; i < rects.count(); ++i) {
|
|
|
|
const QRectF &rect = rects[i];
|
2007-01-13 23:15:28 +00:00
|
|
|
|
2019-01-28 21:08:24 +00:00
|
|
|
LinkInfo info;
|
|
|
|
info.link = linkPosition.link;
|
|
|
|
info.ownsLink = i == 0;
|
|
|
|
info.page = std::floor(rect.y());
|
|
|
|
info.boundingRect = QRectF(rect.x(), rect.y() - info.page, rect.width(), rect.height());
|
2019-01-16 18:29:52 +00:00
|
|
|
result.append(info);
|
2019-01-28 21:08:24 +00:00
|
|
|
}
|
2007-01-13 23:15:28 +00:00
|
|
|
}
|
2019-01-16 18:29:52 +00:00
|
|
|
|
|
|
|
return result;
|
2007-01-13 23:15:28 +00:00
|
|
|
}
|
|
|
|
|
2019-01-16 18:29:52 +00:00
|
|
|
QList<TextDocumentGeneratorPrivate::AnnotationInfo> TextDocumentGeneratorPrivate::generateAnnotationInfos() const
|
2007-01-13 23:15:28 +00:00
|
|
|
{
|
2019-01-16 18:29:52 +00:00
|
|
|
QList<AnnotationInfo> result;
|
|
|
|
|
2007-01-13 23:15:28 +00:00
|
|
|
for (int i = 0; i < mAnnotationPositions.count(); ++i) {
|
|
|
|
const AnnotationPosition &annotationPosition = mAnnotationPositions[i];
|
|
|
|
|
|
|
|
AnnotationInfo info;
|
|
|
|
info.annotation = annotationPosition.annotation;
|
|
|
|
|
2009-01-10 11:29:11 +00:00
|
|
|
TextDocumentUtils::calculateBoundingRect(mDocument, annotationPosition.startPosition, annotationPosition.endPosition, info.boundingRect, info.page);
|
2007-01-13 23:15:28 +00:00
|
|
|
|
2007-12-10 22:39:48 +00:00
|
|
|
if (info.page >= 0)
|
2019-01-16 18:29:52 +00:00
|
|
|
result.append(info);
|
2007-01-13 23:15:28 +00:00
|
|
|
}
|
2019-01-16 18:29:52 +00:00
|
|
|
|
|
|
|
return result;
|
2007-01-13 23:15:28 +00:00
|
|
|
}
|
|
|
|
|
2007-09-14 13:31:55 +00:00
|
|
|
void TextDocumentGeneratorPrivate::generateTitleInfos()
|
2007-01-13 23:15:28 +00:00
|
|
|
{
|
2008-11-29 07:45:25 +00:00
|
|
|
QStack<QPair<int, QDomNode>> parentNodeStack;
|
2007-01-13 23:15:28 +00:00
|
|
|
|
|
|
|
QDomNode parentNode = mDocumentSynopsis;
|
|
|
|
|
2008-11-29 07:45:25 +00:00
|
|
|
parentNodeStack.push(qMakePair(0, parentNode));
|
2007-01-13 23:15:28 +00:00
|
|
|
|
|
|
|
for (int i = 0; i < mTitlePositions.count(); ++i) {
|
|
|
|
const TitlePosition &position = mTitlePositions[i];
|
|
|
|
|
2009-01-10 11:29:11 +00:00
|
|
|
Okular::DocumentViewport viewport = TextDocumentUtils::calculateViewport(mDocument, position.block);
|
2007-01-13 23:15:28 +00:00
|
|
|
|
|
|
|
QDomElement item = mDocumentSynopsis.createElement(position.title);
|
2015-10-29 12:37:11 +00:00
|
|
|
item.setAttribute(QStringLiteral("Viewport"), viewport.toString());
|
2007-01-13 23:15:28 +00:00
|
|
|
|
2008-11-29 07:45:25 +00:00
|
|
|
int headingLevel = position.level;
|
|
|
|
|
|
|
|
// we need a parent, which has to be at a higher heading level than this heading level
|
|
|
|
// so we just work through the stack
|
|
|
|
while (!parentNodeStack.isEmpty()) {
|
|
|
|
int parentLevel = parentNodeStack.top().first;
|
|
|
|
if (parentLevel < headingLevel) {
|
|
|
|
// this is OK as a parent
|
|
|
|
parentNode = parentNodeStack.top().second;
|
|
|
|
break;
|
|
|
|
} else {
|
|
|
|
// we'll need to be further into the stack
|
|
|
|
parentNodeStack.pop();
|
2007-01-13 23:15:28 +00:00
|
|
|
}
|
|
|
|
}
|
2008-11-29 07:45:25 +00:00
|
|
|
parentNode.appendChild(item);
|
|
|
|
parentNodeStack.push(qMakePair(headingLevel, QDomNode(item)));
|
2007-01-13 23:15:28 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-05-18 11:57:46 +00:00
|
|
|
void TextDocumentGeneratorPrivate::initializeGenerator()
|
2007-01-13 23:15:28 +00:00
|
|
|
{
|
2013-05-18 11:57:46 +00:00
|
|
|
Q_Q(TextDocumentGenerator);
|
|
|
|
|
|
|
|
mConverter->d_ptr->mParent = q->d_func();
|
|
|
|
|
|
|
|
if (mGeneralSettings) {
|
|
|
|
mFont = mGeneralSettings->font();
|
|
|
|
}
|
2008-02-14 23:19:24 +00:00
|
|
|
|
2013-05-18 11:57:46 +00:00
|
|
|
q->setFeature(Generator::TextExtraction);
|
|
|
|
q->setFeature(Generator::PrintNative);
|
|
|
|
q->setFeature(Generator::PrintToFile);
|
2008-05-06 20:20:10 +00:00
|
|
|
#ifdef OKULAR_TEXTDOCUMENT_THREADED_RENDERING
|
2019-07-03 22:09:04 +00:00
|
|
|
q->setFeature(Generator::Threaded);
|
2008-05-06 20:20:10 +00:00
|
|
|
#endif
|
2007-01-26 16:35:30 +00:00
|
|
|
|
2019-12-19 22:18:31 +00:00
|
|
|
QObject::connect(mConverter, &TextDocumentConverter::addAction, q, [this](Action *a, int cb, int ce) { addAction(a, cb, ce); });
|
|
|
|
QObject::connect(mConverter, &TextDocumentConverter::addAnnotation, q, [this](Annotation *a, int cb, int ce) { addAnnotation(a, cb, ce); });
|
|
|
|
QObject::connect(mConverter, &TextDocumentConverter::addTitle, q, [this](int l, const QString &t, const QTextBlock &b) { addTitle(l, t, b); });
|
|
|
|
QObject::connect(mConverter, QOverload<const QString &, const QString &, const QString &>::of(&TextDocumentConverter::addMetaData), q, [this](const QString &k, const QString &v, const QString &t) { addMetaData(k, v, t); });
|
|
|
|
QObject::connect(mConverter, QOverload<DocumentInfo::Key, const QString &>::of(&TextDocumentConverter::addMetaData), q, [this](DocumentInfo::Key k, const QString &v) { addMetaData(k, v); });
|
2013-05-18 11:57:46 +00:00
|
|
|
|
2015-10-29 12:37:11 +00:00
|
|
|
QObject::connect(mConverter, &TextDocumentConverter::error, q, &Generator::error);
|
|
|
|
QObject::connect(mConverter, &TextDocumentConverter::warning, q, &Generator::warning);
|
|
|
|
QObject::connect(mConverter, &TextDocumentConverter::notice, q, &Generator::notice);
|
2013-05-18 11:57:46 +00:00
|
|
|
}
|
|
|
|
|
2014-09-17 21:52:14 +00:00
|
|
|
TextDocumentGenerator::TextDocumentGenerator(TextDocumentConverter *converter, const QString &configName, QObject *parent, const QVariantList &args)
|
|
|
|
: Okular::Generator(*new TextDocumentGeneratorPrivate(converter), parent, args)
|
2013-05-18 11:57:46 +00:00
|
|
|
{
|
|
|
|
Q_D(TextDocumentGenerator);
|
|
|
|
d->mGeneralSettings = new TextDocumentSettings(configName, this);
|
|
|
|
|
|
|
|
d->initializeGenerator();
|
|
|
|
}
|
|
|
|
|
2007-01-13 23:15:28 +00:00
|
|
|
TextDocumentGenerator::~TextDocumentGenerator()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2014-05-10 13:31:59 +00:00
|
|
|
Document::OpenResult TextDocumentGenerator::loadDocumentWithPassword(const QString &fileName, QVector<Okular::Page *> &pagesVector, const QString &password)
|
2007-01-13 23:15:28 +00:00
|
|
|
{
|
2007-09-14 13:31:55 +00:00
|
|
|
Q_D(TextDocumentGenerator);
|
2014-05-10 13:31:59 +00:00
|
|
|
const Document::OpenResult openResult = d->mConverter->convertWithPassword(fileName, password);
|
2007-01-13 23:15:28 +00:00
|
|
|
|
2014-05-10 13:31:59 +00:00
|
|
|
if (openResult != Document::OpenSuccess) {
|
2017-09-05 21:27:18 +00:00
|
|
|
d->mDocument = nullptr;
|
2014-05-10 13:31:59 +00:00
|
|
|
|
2008-04-20 09:49:20 +00:00
|
|
|
// loading failed, cleanup all the stuff eventually gathered from the converter
|
|
|
|
d->mTitlePositions.clear();
|
2019-12-09 13:16:55 +00:00
|
|
|
for (const TextDocumentGeneratorPrivate::LinkPosition &linkPos : qAsConst(d->mLinkPositions)) {
|
2008-04-20 09:49:20 +00:00
|
|
|
delete linkPos.link;
|
|
|
|
}
|
|
|
|
d->mLinkPositions.clear();
|
2019-12-09 13:16:55 +00:00
|
|
|
for (const TextDocumentGeneratorPrivate::AnnotationPosition &annPos : qAsConst(d->mAnnotationPositions)) {
|
2008-04-20 09:49:20 +00:00
|
|
|
delete annPos.annotation;
|
|
|
|
}
|
|
|
|
d->mAnnotationPositions.clear();
|
|
|
|
|
2014-05-10 13:31:59 +00:00
|
|
|
return openResult;
|
2008-04-20 09:49:20 +00:00
|
|
|
}
|
2014-05-10 13:31:59 +00:00
|
|
|
d->mDocument = d->mConverter->document();
|
2007-01-13 23:15:28 +00:00
|
|
|
|
|
|
|
d->generateTitleInfos();
|
2019-01-16 18:29:52 +00:00
|
|
|
const QList<TextDocumentGeneratorPrivate::LinkInfo> linkInfos = d->generateLinkInfos();
|
|
|
|
const QList<TextDocumentGeneratorPrivate::AnnotationInfo> annotationInfos = d->generateAnnotationInfos();
|
2007-01-13 23:15:28 +00:00
|
|
|
|
|
|
|
pagesVector.resize(d->mDocument->pageCount());
|
|
|
|
|
|
|
|
const QSize size = d->mDocument->pageSize().toSize();
|
2007-05-03 21:45:14 +00:00
|
|
|
|
|
|
|
QVector<QLinkedList<Okular::ObjectRect *>> objects(d->mDocument->pageCount());
|
2019-01-16 18:29:52 +00:00
|
|
|
for (const TextDocumentGeneratorPrivate::LinkInfo &info : linkInfos) {
|
2010-04-11 17:54:54 +00:00
|
|
|
// in case that the converter report bogus link info data, do not assert here
|
2019-08-21 21:34:30 +00:00
|
|
|
if (info.page < 0 || info.page >= objects.count())
|
2010-04-11 17:54:54 +00:00
|
|
|
continue;
|
|
|
|
|
2007-05-03 21:45:14 +00:00
|
|
|
const QRectF rect = info.boundingRect;
|
2019-01-28 21:08:24 +00:00
|
|
|
if (info.ownsLink) {
|
|
|
|
objects[info.page].append(new Okular::ObjectRect(rect.left(), rect.top(), rect.right(), rect.bottom(), false, Okular::ObjectRect::Action, info.link));
|
|
|
|
} else {
|
|
|
|
objects[info.page].append(new Okular::NonOwningObjectRect(rect.left(), rect.top(), rect.right(), rect.bottom(), false, Okular::ObjectRect::Action, info.link));
|
|
|
|
}
|
2007-05-03 21:45:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
QVector<QLinkedList<Okular::Annotation *>> annots(d->mDocument->pageCount());
|
2019-01-16 18:29:52 +00:00
|
|
|
for (const TextDocumentGeneratorPrivate::AnnotationInfo &info : annotationInfos) {
|
2007-05-03 21:45:14 +00:00
|
|
|
annots[info.page].append(info.annotation);
|
|
|
|
}
|
|
|
|
|
2007-01-13 23:15:28 +00:00
|
|
|
for (int i = 0; i < d->mDocument->pageCount(); ++i) {
|
|
|
|
Okular::Page *page = new Okular::Page(i, size.width(), size.height(), Okular::Rotation0);
|
|
|
|
pagesVector[i] = page;
|
2007-05-03 21:45:14 +00:00
|
|
|
|
|
|
|
if (!objects.at(i).isEmpty()) {
|
|
|
|
page->setObjectRects(objects.at(i));
|
|
|
|
}
|
|
|
|
QLinkedList<Okular::Annotation *>::ConstIterator annIt = annots.at(i).begin(), annEnd = annots.at(i).end();
|
|
|
|
for (; annIt != annEnd; ++annIt) {
|
|
|
|
page->addAnnotation(*annIt);
|
|
|
|
}
|
2007-01-13 23:15:28 +00:00
|
|
|
}
|
|
|
|
|
2014-05-10 13:31:59 +00:00
|
|
|
return openResult;
|
2007-01-13 23:15:28 +00:00
|
|
|
}
|
|
|
|
|
2007-10-08 16:46:51 +00:00
|
|
|
bool TextDocumentGenerator::doCloseDocument()
|
2007-01-13 23:15:28 +00:00
|
|
|
{
|
2007-09-14 13:31:55 +00:00
|
|
|
Q_D(TextDocumentGenerator);
|
2007-01-13 23:15:28 +00:00
|
|
|
delete d->mDocument;
|
2017-09-05 21:27:18 +00:00
|
|
|
d->mDocument = nullptr;
|
2007-01-13 23:15:28 +00:00
|
|
|
|
2007-05-21 22:26:37 +00:00
|
|
|
d->mTitlePositions.clear();
|
|
|
|
d->mLinkPositions.clear();
|
2008-04-20 09:49:20 +00:00
|
|
|
d->mAnnotationPositions.clear();
|
2008-04-19 20:06:31 +00:00
|
|
|
// do not use clear() for the following two, otherwise they change type
|
|
|
|
d->mDocumentInfo = Okular::DocumentInfo();
|
|
|
|
d->mDocumentSynopsis = Okular::DocumentSynopsis();
|
2007-05-21 22:26:37 +00:00
|
|
|
|
2007-01-13 23:15:28 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2007-01-24 15:06:45 +00:00
|
|
|
bool TextDocumentGenerator::canGeneratePixmap() const
|
2007-01-13 23:15:28 +00:00
|
|
|
{
|
2008-05-06 20:20:10 +00:00
|
|
|
return Generator::canGeneratePixmap();
|
2007-01-13 23:15:28 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void TextDocumentGenerator::generatePixmap(Okular::PixmapRequest *request)
|
|
|
|
{
|
2008-05-06 20:20:10 +00:00
|
|
|
Generator::generatePixmap(request);
|
|
|
|
}
|
2007-01-13 23:15:28 +00:00
|
|
|
|
2008-05-06 20:20:10 +00:00
|
|
|
QImage TextDocumentGeneratorPrivate::image(PixmapRequest *request)
|
|
|
|
{
|
|
|
|
if (!mDocument)
|
|
|
|
return QImage();
|
|
|
|
|
2008-08-15 13:24:02 +00:00
|
|
|
#ifdef OKULAR_TEXTDOCUMENT_THREADED_RENDERING
|
2008-05-06 20:20:10 +00:00
|
|
|
Q_Q(TextDocumentGenerator);
|
2008-08-15 13:24:02 +00:00
|
|
|
#endif
|
2007-01-13 23:15:28 +00:00
|
|
|
|
2008-05-06 20:20:10 +00:00
|
|
|
QImage image(request->width(), request->height(), QImage::Format_ARGB32);
|
|
|
|
image.fill(Qt::white);
|
2007-01-13 23:15:28 +00:00
|
|
|
|
|
|
|
QPainter p;
|
2008-05-06 20:20:10 +00:00
|
|
|
p.begin(&image);
|
2007-01-13 23:15:28 +00:00
|
|
|
|
|
|
|
qreal width = request->width();
|
|
|
|
qreal height = request->height();
|
|
|
|
|
2008-05-06 20:20:10 +00:00
|
|
|
const QSize size = mDocument->pageSize().toSize();
|
|
|
|
|
2007-01-13 23:15:28 +00:00
|
|
|
p.scale(width / (qreal)size.width(), height / (qreal)size.height());
|
|
|
|
|
|
|
|
QRect rect;
|
|
|
|
rect = QRect(0, request->pageNumber() * size.height(), size.width(), size.height());
|
|
|
|
p.translate(QPoint(0, request->pageNumber() * size.height() * -1));
|
2014-03-12 22:01:42 +00:00
|
|
|
p.setClipRect(rect);
|
2008-05-06 20:20:10 +00:00
|
|
|
#ifdef OKULAR_TEXTDOCUMENT_THREADED_RENDERING
|
|
|
|
q->userMutex()->lock();
|
|
|
|
#endif
|
2014-03-12 22:01:42 +00:00
|
|
|
QAbstractTextDocumentLayout::PaintContext context;
|
|
|
|
context.palette.setColor(QPalette::Text, Qt::black);
|
|
|
|
// FIXME Fix Qt, this doesn't work, we have horrible hacks
|
|
|
|
// in the generators that return html, remove that code
|
|
|
|
// if Qt ever gets fixed
|
|
|
|
// context.palette.setColor( QPalette::Link, Qt::blue );
|
|
|
|
context.clip = rect;
|
2013-05-18 11:57:46 +00:00
|
|
|
mDocument->setDefaultFont(mFont);
|
2014-03-12 22:01:42 +00:00
|
|
|
mDocument->documentLayout()->draw(&p, context);
|
2008-05-06 20:20:10 +00:00
|
|
|
#ifdef OKULAR_TEXTDOCUMENT_THREADED_RENDERING
|
|
|
|
q->userMutex()->unlock();
|
|
|
|
#endif
|
2007-01-13 23:15:28 +00:00
|
|
|
p.end();
|
|
|
|
|
2008-05-06 20:20:10 +00:00
|
|
|
return image;
|
2007-01-13 23:15:28 +00:00
|
|
|
}
|
|
|
|
|
2018-02-01 18:42:37 +00:00
|
|
|
Okular::TextPage *TextDocumentGenerator::textPage(Okular::TextRequest *request)
|
2007-01-13 23:15:28 +00:00
|
|
|
{
|
2007-09-14 13:31:55 +00:00
|
|
|
Q_D(TextDocumentGenerator);
|
2018-02-01 18:42:37 +00:00
|
|
|
return d->createTextPage(request->page()->number());
|
2007-01-13 23:15:28 +00:00
|
|
|
}
|
|
|
|
|
2007-10-15 23:01:27 +00:00
|
|
|
bool TextDocumentGenerator::print(QPrinter &printer)
|
2007-01-13 23:15:28 +00:00
|
|
|
{
|
2007-09-14 13:31:55 +00:00
|
|
|
Q_D(TextDocumentGenerator);
|
2007-01-13 23:15:28 +00:00
|
|
|
if (!d->mDocument)
|
|
|
|
return false;
|
|
|
|
|
2007-11-27 16:29:50 +00:00
|
|
|
d->mDocument->print(&printer);
|
2007-01-13 23:15:28 +00:00
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2014-05-11 09:17:49 +00:00
|
|
|
Okular::DocumentInfo TextDocumentGenerator::generateDocumentInfo(const QSet<DocumentInfo::Key> & /*keys*/) const
|
2007-01-13 23:15:28 +00:00
|
|
|
{
|
2014-05-11 09:17:49 +00:00
|
|
|
Q_D(const TextDocumentGenerator);
|
|
|
|
return d->mDocumentInfo;
|
2007-01-13 23:15:28 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
const Okular::DocumentSynopsis *TextDocumentGenerator::generateDocumentSynopsis()
|
|
|
|
{
|
2007-09-14 13:31:55 +00:00
|
|
|
Q_D(TextDocumentGenerator);
|
2007-01-13 23:15:28 +00:00
|
|
|
if (!d->mDocumentSynopsis.hasChildNodes())
|
2017-09-05 21:27:18 +00:00
|
|
|
return nullptr;
|
2007-01-13 23:15:28 +00:00
|
|
|
else
|
|
|
|
return &d->mDocumentSynopsis;
|
|
|
|
}
|
|
|
|
|
2008-03-15 02:15:16 +00:00
|
|
|
QVariant TextDocumentGeneratorPrivate::metaData(const QString &key, const QVariant &option) const
|
|
|
|
{
|
|
|
|
Q_UNUSED(option)
|
2015-10-29 12:37:11 +00:00
|
|
|
if (key == QLatin1String("DocumentTitle")) {
|
2014-05-11 09:17:49 +00:00
|
|
|
return mDocumentInfo.get(DocumentInfo::Title);
|
2008-03-15 02:15:16 +00:00
|
|
|
}
|
|
|
|
return QVariant();
|
|
|
|
}
|
|
|
|
|
2007-01-13 23:15:28 +00:00
|
|
|
Okular::ExportFormat::List TextDocumentGenerator::exportFormats() const
|
|
|
|
{
|
|
|
|
static Okular::ExportFormat::List formats;
|
|
|
|
if (formats.isEmpty()) {
|
2007-04-21 11:09:41 +00:00
|
|
|
formats.append(Okular::ExportFormat::standardFormat(Okular::ExportFormat::PlainText));
|
|
|
|
formats.append(Okular::ExportFormat::standardFormat(Okular::ExportFormat::PDF));
|
2009-05-21 16:46:05 +00:00
|
|
|
if (QTextDocumentWriter::supportedDocumentFormats().contains("ODF")) {
|
|
|
|
formats.append(Okular::ExportFormat::standardFormat(Okular::ExportFormat::OpenDocumentText));
|
|
|
|
}
|
|
|
|
if (QTextDocumentWriter::supportedDocumentFormats().contains("HTML")) {
|
|
|
|
formats.append(Okular::ExportFormat::standardFormat(Okular::ExportFormat::HTML));
|
|
|
|
}
|
2007-01-13 23:15:28 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return formats;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool TextDocumentGenerator::exportTo(const QString &fileName, const Okular::ExportFormat &format)
|
|
|
|
{
|
2007-09-14 13:31:55 +00:00
|
|
|
Q_D(TextDocumentGenerator);
|
2007-01-13 23:15:28 +00:00
|
|
|
if (!d->mDocument)
|
|
|
|
return false;
|
|
|
|
|
2014-09-11 13:18:05 +00:00
|
|
|
if (format.mimeType().name() == QLatin1String("application/pdf")) {
|
2007-01-13 23:15:28 +00:00
|
|
|
QFile file(fileName);
|
|
|
|
if (!file.open(QIODevice::WriteOnly))
|
|
|
|
return false;
|
|
|
|
|
|
|
|
QPrinter printer(QPrinter::HighResolution);
|
|
|
|
printer.setOutputFormat(QPrinter::PdfFormat);
|
|
|
|
printer.setOutputFileName(fileName);
|
|
|
|
d->mDocument->print(&printer);
|
|
|
|
|
|
|
|
return true;
|
2014-09-11 13:18:05 +00:00
|
|
|
} else if (format.mimeType().name() == QLatin1String("text/plain")) {
|
2007-01-13 23:15:28 +00:00
|
|
|
QFile file(fileName);
|
|
|
|
if (!file.open(QIODevice::WriteOnly))
|
|
|
|
return false;
|
|
|
|
|
|
|
|
QTextStream out(&file);
|
|
|
|
out << d->mDocument->toPlainText();
|
|
|
|
|
|
|
|
return true;
|
2014-09-11 13:18:05 +00:00
|
|
|
} else if (format.mimeType().name() == QLatin1String("application/vnd.oasis.opendocument.text")) {
|
2009-05-21 16:46:05 +00:00
|
|
|
QTextDocumentWriter odfWriter(fileName, "odf");
|
2007-01-13 23:15:28 +00:00
|
|
|
|
2009-05-21 16:46:05 +00:00
|
|
|
return odfWriter.write(d->mDocument);
|
2014-09-11 13:18:05 +00:00
|
|
|
} else if (format.mimeType().name() == QLatin1String("text/html")) {
|
2009-05-21 16:46:05 +00:00
|
|
|
QTextDocumentWriter odfWriter(fileName, "html");
|
2008-09-01 12:00:50 +00:00
|
|
|
|
2009-05-21 16:46:05 +00:00
|
|
|
return odfWriter.write(d->mDocument);
|
2008-09-01 12:51:30 +00:00
|
|
|
}
|
2007-01-13 23:15:28 +00:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2013-05-18 11:57:46 +00:00
|
|
|
bool TextDocumentGenerator::reparseConfig()
|
|
|
|
{
|
|
|
|
Q_D(TextDocumentGenerator);
|
2013-06-06 21:50:09 +00:00
|
|
|
const QFont newFont = d->mGeneralSettings->font();
|
2013-05-18 11:57:46 +00:00
|
|
|
|
|
|
|
if (newFont != d->mFont) {
|
|
|
|
d->mFont = newFont;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
void TextDocumentGenerator::addPages(KConfigDialog * /*dlg*/)
|
|
|
|
{
|
2014-09-11 19:12:27 +00:00
|
|
|
qCWarning(OkularCoreDebug) << "You forgot to reimplement addPages in your TextDocumentGenerator";
|
2013-05-18 11:57:46 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
TextDocumentSettings *TextDocumentGenerator::generalSettings()
|
|
|
|
{
|
|
|
|
Q_D(TextDocumentGenerator);
|
|
|
|
|
|
|
|
return d->mGeneralSettings;
|
|
|
|
}
|
|
|
|
|
2019-03-30 22:47:17 +00:00
|
|
|
TextDocumentConverter *TextDocumentGenerator::converter()
|
|
|
|
{
|
|
|
|
Q_D(TextDocumentGenerator);
|
|
|
|
|
|
|
|
return d->mConverter;
|
|
|
|
}
|
|
|
|
|
|
|
|
void TextDocumentGenerator::setTextDocument(QTextDocument *textDocument)
|
|
|
|
{
|
|
|
|
Q_D(TextDocumentGenerator);
|
|
|
|
|
|
|
|
d->mDocument = textDocument;
|
|
|
|
|
2019-12-09 13:16:55 +00:00
|
|
|
for (Page *p : qAsConst(d->m_document->m_pagesVector)) {
|
2019-03-30 22:47:17 +00:00
|
|
|
p->setTextPage(nullptr);
|
|
|
|
}
|
|
|
|
}
|