textdocumentgenerator.cpp 17.8 KB
Newer Older
1
2
3
4
5
6
7
8
9
/***************************************************************************
 *   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.                                   *
 ***************************************************************************/

Albert Astals Cid's avatar
Albert Astals Cid committed
10
11
12
#include "textdocumentgenerator.h"
#include "textdocumentgenerator_p.h"

Yuri Chornoivan's avatar
Yuri Chornoivan committed
13
14
15
#include <QFile>
#include <QFontDatabase>
#include <QImage>
Albert Astals Cid's avatar
Albert Astals Cid committed
16
#include <QMutex>
Yuri Chornoivan's avatar
Yuri Chornoivan committed
17
18
#include <QPainter>
#include <QPrinter>
Albert Astals Cid's avatar
Albert Astals Cid committed
19
#include <QStack>
Yuri Chornoivan's avatar
Yuri Chornoivan committed
20
#include <QTextDocumentWriter>
Albert Astals Cid's avatar
Albert Astals Cid committed
21
22
#include <QTextStream>
#include <QVector>
23

24
25
#include "action.h"
#include "annotations.h"
26
#include "document_p.h"
27
28
#include "page.h"
#include "textpage.h"
29

30
31
#include <cmath>

32
33
34
35
36
37
using namespace Okular;

/**
 * Generic Converter Implementation
 */
TextDocumentConverter::TextDocumentConverter()
Albert Astals Cid's avatar
Albert Astals Cid committed
38
39
    : QObject(nullptr)
    , d_ptr(new TextDocumentConverterPrivate)
40
41
42
43
44
{
}

TextDocumentConverter::~TextDocumentConverter()
{
45
    delete d_ptr;
46
47
}

Albert Astals Cid's avatar
Albert Astals Cid committed
48
QTextDocument *TextDocumentConverter::convert(const QString &)
49
{
50
    return nullptr;
51
52
}

Albert Astals Cid's avatar
Albert Astals Cid committed
53
Document::OpenResult TextDocumentConverter::convertWithPassword(const QString &fileName, const QString &)
54
{
Albert Astals Cid's avatar
Albert Astals Cid committed
55
56
    QTextDocument *doc = convert(fileName);
    setDocument(doc);
57
    return doc != nullptr ? Document::OpenSuccess : Document::OpenError;
58
59
60
61
62
63
64
}

QTextDocument *TextDocumentConverter::document()
{
    return d_ptr->mDocument;
}

Albert Astals Cid's avatar
Albert Astals Cid committed
65
void TextDocumentConverter::setDocument(QTextDocument *document)
66
67
68
69
{
    d_ptr->mDocument = document;
}

Albert Astals Cid's avatar
Albert Astals Cid committed
70
DocumentViewport TextDocumentConverter::calculateViewport(QTextDocument *document, const QTextBlock &block)
71
{
Albert Astals Cid's avatar
Albert Astals Cid committed
72
    return TextDocumentUtils::calculateViewport(document, block);
73
74
}

Albert Astals Cid's avatar
Albert Astals Cid committed
75
TextDocumentGenerator *TextDocumentConverter::generator() const
76
{
77
    return d_ptr->mParent ? d_ptr->mParent->q_func() : nullptr;
78
79
}

80
81
82
/**
 * Generic Generator Implementation
 */
Albert Astals Cid's avatar
Albert Astals Cid committed
83
Okular::TextPage *TextDocumentGeneratorPrivate::createTextPage(int pageNumber) const
84
{
85
#ifdef OKULAR_TEXTDOCUMENT_THREADED_RENDERING
Albert Astals Cid's avatar
Albert Astals Cid committed
86
    Q_Q(const TextDocumentGenerator);
87
#endif
88

89
90
91
92
    Okular::TextPage *textPage = new Okular::TextPage;

    int start, end;

93
94
95
#ifdef OKULAR_TEXTDOCUMENT_THREADED_RENDERING
    q->userMutex()->lock();
#endif
Albert Astals Cid's avatar
Albert Astals Cid committed
96
    TextDocumentUtils::calculatePositions(mDocument, pageNumber, start, end);
97

98
    {
Albert Astals Cid's avatar
Albert Astals Cid committed
99
100
101
102
103
104
105
106
107
108
109
110
111
112
        QTextCursor cursor(mDocument);
        for (int i = start; i < end - 1; ++i) {
            cursor.setPosition(i);
            cursor.setPosition(i + 1, QTextCursor::KeepAnchor);

            QString text = cursor.selectedText();
            if (text.length() == 1) {
                QRectF rect;
                TextDocumentUtils::calculateBoundingRect(mDocument, i, i + 1, rect, pageNumber);
                if (pageNumber == -1)
                    text = QStringLiteral("\n");

                textPage->append(text, new Okular::NormalizedRect(rect.left(), rect.top(), rect.right(), rect.bottom()));
            }
113
114
        }
    }
115
116
117
#ifdef OKULAR_TEXTDOCUMENT_THREADED_RENDERING
    q->userMutex()->unlock();
#endif
118
119
120
121

    return textPage;
}

Albert Astals Cid's avatar
Albert Astals Cid committed
122
void TextDocumentGeneratorPrivate::addAction(Action *action, int cursorBegin, int cursorEnd)
123
{
Albert Astals Cid's avatar
Albert Astals Cid committed
124
    if (!action)
125
126
127
        return;

    LinkPosition position;
Pino Toscano's avatar
Pino Toscano committed
128
    position.link = action;
129
130
131
    position.startPosition = cursorBegin;
    position.endPosition = cursorEnd;

Albert Astals Cid's avatar
Albert Astals Cid committed
132
    mLinkPositions.append(position);
133
134
}

Albert Astals Cid's avatar
Albert Astals Cid committed
135
void TextDocumentGeneratorPrivate::addAnnotation(Annotation *annotation, int cursorBegin, int cursorEnd)
136
{
Albert Astals Cid's avatar
Albert Astals Cid committed
137
    if (!annotation)
138
139
        return;

Albert Astals Cid's avatar
Albert Astals Cid committed
140
    annotation->setFlags(annotation->flags() | Okular::Annotation::External);
141

142
143
144
145
146
    AnnotationPosition position;
    position.annotation = annotation;
    position.startPosition = cursorBegin;
    position.endPosition = cursorEnd;

Albert Astals Cid's avatar
Albert Astals Cid committed
147
    mAnnotationPositions.append(position);
148
149
}

Albert Astals Cid's avatar
Albert Astals Cid committed
150
void TextDocumentGeneratorPrivate::addTitle(int level, const QString &title, const QTextBlock &block)
151
152
153
154
155
156
{
    TitlePosition position;
    position.level = level;
    position.title = title;
    position.block = block;

Albert Astals Cid's avatar
Albert Astals Cid committed
157
    mTitlePositions.append(position);
158
159
}

Albert Astals Cid's avatar
Albert Astals Cid committed
160
void TextDocumentGeneratorPrivate::addMetaData(const QString &key, const QString &value, const QString &title)
161
{
Albert Astals Cid's avatar
Albert Astals Cid committed
162
    mDocumentInfo.set(key, value, title);
163
164
}

Albert Astals Cid's avatar
Albert Astals Cid committed
165
void TextDocumentGeneratorPrivate::addMetaData(DocumentInfo::Key key, const QString &value)
166
{
Albert Astals Cid's avatar
Albert Astals Cid committed
167
    mDocumentInfo.set(key, value);
168
169
}

170
QList<TextDocumentGeneratorPrivate::LinkInfo> TextDocumentGeneratorPrivate::generateLinkInfos() const
171
{
172
173
    QList<LinkInfo> result;

Albert Astals Cid's avatar
Albert Astals Cid committed
174
175
    for (int i = 0; i < mLinkPositions.count(); ++i) {
        const LinkPosition &linkPosition = mLinkPositions[i];
176

Albert Astals Cid's avatar
Albert Astals Cid committed
177
        const QVector<QRectF> rects = TextDocumentUtils::calculateBoundingRects(mDocument, linkPosition.startPosition, linkPosition.endPosition);
178

Albert Astals Cid's avatar
Albert Astals Cid committed
179
180
        for (int i = 0; i < rects.count(); ++i) {
            const QRectF &rect = rects[i];
181

182
183
184
            LinkInfo info;
            info.link = linkPosition.link;
            info.ownsLink = i == 0;
Albert Astals Cid's avatar
Albert Astals Cid committed
185
186
187
            info.page = std::floor(rect.y());
            info.boundingRect = QRectF(rect.x(), rect.y() - info.page, rect.width(), rect.height());
            result.append(info);
188
        }
189
    }
190
191

    return result;
192
193
}

194
QList<TextDocumentGeneratorPrivate::AnnotationInfo> TextDocumentGeneratorPrivate::generateAnnotationInfos() const
195
{
196
197
    QList<AnnotationInfo> result;

Albert Astals Cid's avatar
Albert Astals Cid committed
198
199
    for (int i = 0; i < mAnnotationPositions.count(); ++i) {
        const AnnotationPosition &annotationPosition = mAnnotationPositions[i];
200
201
202
203

        AnnotationInfo info;
        info.annotation = annotationPosition.annotation;

Albert Astals Cid's avatar
Albert Astals Cid committed
204
        TextDocumentUtils::calculateBoundingRect(mDocument, annotationPosition.startPosition, annotationPosition.endPosition, info.boundingRect, info.page);
205

Albert Astals Cid's avatar
Albert Astals Cid committed
206
207
        if (info.page >= 0)
            result.append(info);
208
    }
209
210

    return result;
211
212
}

213
void TextDocumentGeneratorPrivate::generateTitleInfos()
214
{
Albert Astals Cid's avatar
Albert Astals Cid committed
215
    QStack<QPair<int, QDomNode>> parentNodeStack;
216
217
218

    QDomNode parentNode = mDocumentSynopsis;

Albert Astals Cid's avatar
Albert Astals Cid committed
219
    parentNodeStack.push(qMakePair(0, parentNode));
220

Albert Astals Cid's avatar
Albert Astals Cid committed
221
222
    for (int i = 0; i < mTitlePositions.count(); ++i) {
        const TitlePosition &position = mTitlePositions[i];
223

Albert Astals Cid's avatar
Albert Astals Cid committed
224
        Okular::DocumentViewport viewport = TextDocumentUtils::calculateViewport(mDocument, position.block);
225

Albert Astals Cid's avatar
Albert Astals Cid committed
226
227
        QDomElement item = mDocumentSynopsis.createElement(position.title);
        item.setAttribute(QStringLiteral("Viewport"), viewport.toString());
228

229
230
231
232
        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
Albert Astals Cid's avatar
Albert Astals Cid committed
233
        while (!parentNodeStack.isEmpty()) {
234
            int parentLevel = parentNodeStack.top().first;
Albert Astals Cid's avatar
Albert Astals Cid committed
235
            if (parentLevel < headingLevel) {
236
237
238
239
240
241
                // this is OK as a parent
                parentNode = parentNodeStack.top().second;
                break;
            } else {
                // we'll need to be further into the stack
                parentNodeStack.pop();
242
243
            }
        }
Albert Astals Cid's avatar
Albert Astals Cid committed
244
245
        parentNode.appendChild(item);
        parentNodeStack.push(qMakePair(headingLevel, QDomNode(item)));
246
247
248
    }
}

249
void TextDocumentGeneratorPrivate::initializeGenerator()
250
{
Albert Astals Cid's avatar
Albert Astals Cid committed
251
    Q_Q(TextDocumentGenerator);
252
253
254

    mConverter->d_ptr->mParent = q->d_func();

Albert Astals Cid's avatar
Albert Astals Cid committed
255
    if (mGeneralSettings) {
256
257
        mFont = mGeneralSettings->font();
    }
258

Albert Astals Cid's avatar
Albert Astals Cid committed
259
260
261
    q->setFeature(Generator::TextExtraction);
    q->setFeature(Generator::PrintNative);
    q->setFeature(Generator::PrintToFile);
262
#ifdef OKULAR_TEXTDOCUMENT_THREADED_RENDERING
Albert Astals Cid's avatar
Albert Astals Cid committed
263
    q->setFeature(Generator::Threaded);
264
#endif
265

Albert Astals Cid's avatar
Albert Astals Cid committed
266
267
268
269
270
    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); });
271

Albert Astals Cid's avatar
Albert Astals Cid committed
272
273
274
    QObject::connect(mConverter, &TextDocumentConverter::error, q, &Generator::error);
    QObject::connect(mConverter, &TextDocumentConverter::warning, q, &Generator::warning);
    QObject::connect(mConverter, &TextDocumentConverter::notice, q, &Generator::notice);
275
276
}

Albert Astals Cid's avatar
Albert Astals Cid committed
277
278
TextDocumentGenerator::TextDocumentGenerator(TextDocumentConverter *converter, const QString &configName, QObject *parent, const QVariantList &args)
    : Okular::Generator(*new TextDocumentGeneratorPrivate(converter), parent, args)
279
{
Albert Astals Cid's avatar
Albert Astals Cid committed
280
281
    Q_D(TextDocumentGenerator);
    d->mGeneralSettings = new TextDocumentSettings(configName, this);
282
283
284
285

    d->initializeGenerator();
}

286
287
288
289
TextDocumentGenerator::~TextDocumentGenerator()
{
}

Albert Astals Cid's avatar
Albert Astals Cid committed
290
Document::OpenResult TextDocumentGenerator::loadDocumentWithPassword(const QString &fileName, QVector<Okular::Page *> &pagesVector, const QString &password)
291
{
Albert Astals Cid's avatar
Albert Astals Cid committed
292
293
    Q_D(TextDocumentGenerator);
    const Document::OpenResult openResult = d->mConverter->convertWithPassword(fileName, password);
294

Albert Astals Cid's avatar
Albert Astals Cid committed
295
    if (openResult != Document::OpenSuccess) {
296
        d->mDocument = nullptr;
297

298
299
        // loading failed, cleanup all the stuff eventually gathered from the converter
        d->mTitlePositions.clear();
Albert Astals Cid's avatar
Albert Astals Cid committed
300
        for (const TextDocumentGeneratorPrivate::LinkPosition &linkPos : qAsConst(d->mLinkPositions)) {
301
302
303
            delete linkPos.link;
        }
        d->mLinkPositions.clear();
Albert Astals Cid's avatar
Albert Astals Cid committed
304
        for (const TextDocumentGeneratorPrivate::AnnotationPosition &annPos : qAsConst(d->mAnnotationPositions)) {
305
306
307
308
            delete annPos.annotation;
        }
        d->mAnnotationPositions.clear();

309
        return openResult;
310
    }
311
    d->mDocument = d->mConverter->document();
312
313

    d->generateTitleInfos();
314
315
    const QList<TextDocumentGeneratorPrivate::LinkInfo> linkInfos = d->generateLinkInfos();
    const QList<TextDocumentGeneratorPrivate::AnnotationInfo> annotationInfos = d->generateAnnotationInfos();
316

Albert Astals Cid's avatar
Albert Astals Cid committed
317
    pagesVector.resize(d->mDocument->pageCount());
318
319

    const QSize size = d->mDocument->pageSize().toSize();
320

Albert Astals Cid's avatar
Albert Astals Cid committed
321
322
    QVector<QLinkedList<Okular::ObjectRect *>> objects(d->mDocument->pageCount());
    for (const TextDocumentGeneratorPrivate::LinkInfo &info : linkInfos) {
323
        // in case that the converter report bogus link info data, do not assert here
Albert Astals Cid's avatar
Albert Astals Cid committed
324
325
        if (info.page < 0 || info.page >= objects.count())
            continue;
326

327
        const QRectF rect = info.boundingRect;
Albert Astals Cid's avatar
Albert Astals Cid committed
328
329
        if (info.ownsLink) {
            objects[info.page].append(new Okular::ObjectRect(rect.left(), rect.top(), rect.right(), rect.bottom(), false, Okular::ObjectRect::Action, info.link));
330
        } else {
Albert Astals Cid's avatar
Albert Astals Cid committed
331
            objects[info.page].append(new Okular::NonOwningObjectRect(rect.left(), rect.top(), rect.right(), rect.bottom(), false, Okular::ObjectRect::Action, info.link));
332
        }
333
334
    }

Albert Astals Cid's avatar
Albert Astals Cid committed
335
336
337
    QVector<QLinkedList<Okular::Annotation *>> annots(d->mDocument->pageCount());
    for (const TextDocumentGeneratorPrivate::AnnotationInfo &info : annotationInfos) {
        annots[info.page].append(info.annotation);
338
339
    }

Albert Astals Cid's avatar
Albert Astals Cid committed
340
341
342
    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;
343

Albert Astals Cid's avatar
Albert Astals Cid committed
344
345
        if (!objects.at(i).isEmpty()) {
            page->setObjectRects(objects.at(i));
346
        }
Albert Astals Cid's avatar
Albert Astals Cid committed
347
348
349
        QLinkedList<Okular::Annotation *>::ConstIterator annIt = annots.at(i).begin(), annEnd = annots.at(i).end();
        for (; annIt != annEnd; ++annIt) {
            page->addAnnotation(*annIt);
350
        }
351
352
    }

353
    return openResult;
354
355
}

356
bool TextDocumentGenerator::doCloseDocument()
357
{
Albert Astals Cid's avatar
Albert Astals Cid committed
358
    Q_D(TextDocumentGenerator);
359
    delete d->mDocument;
360
    d->mDocument = nullptr;
361

362
363
    d->mTitlePositions.clear();
    d->mLinkPositions.clear();
364
    d->mAnnotationPositions.clear();
365
366
367
    // do not use clear() for the following two, otherwise they change type
    d->mDocumentInfo = Okular::DocumentInfo();
    d->mDocumentSynopsis = Okular::DocumentSynopsis();
368

369
370
371
    return true;
}

372
bool TextDocumentGenerator::canGeneratePixmap() const
373
{
374
    return Generator::canGeneratePixmap();
375
376
}

Albert Astals Cid's avatar
Albert Astals Cid committed
377
void TextDocumentGenerator::generatePixmap(Okular::PixmapRequest *request)
378
{
Albert Astals Cid's avatar
Albert Astals Cid committed
379
    Generator::generatePixmap(request);
380
}
381

Albert Astals Cid's avatar
Albert Astals Cid committed
382
QImage TextDocumentGeneratorPrivate::image(PixmapRequest *request)
383
{
Albert Astals Cid's avatar
Albert Astals Cid committed
384
    if (!mDocument)
385
386
        return QImage();

387
#ifdef OKULAR_TEXTDOCUMENT_THREADED_RENDERING
Albert Astals Cid's avatar
Albert Astals Cid committed
388
    Q_Q(TextDocumentGenerator);
389
#endif
390

Albert Astals Cid's avatar
Albert Astals Cid committed
391
392
    QImage image(request->width(), request->height(), QImage::Format_ARGB32);
    image.fill(Qt::white);
393
394

    QPainter p;
Albert Astals Cid's avatar
Albert Astals Cid committed
395
    p.begin(&image);
396
397
398
399

    qreal width = request->width();
    qreal height = request->height();

400
401
    const QSize size = mDocument->pageSize().toSize();

Albert Astals Cid's avatar
Albert Astals Cid committed
402
    p.scale(width / (qreal)size.width(), height / (qreal)size.height());
403
404

    QRect rect;
Albert Astals Cid's avatar
Albert Astals Cid committed
405
406
407
    rect = QRect(0, request->pageNumber() * size.height(), size.width(), size.height());
    p.translate(QPoint(0, request->pageNumber() * size.height() * -1));
    p.setClipRect(rect);
408
409
410
#ifdef OKULAR_TEXTDOCUMENT_THREADED_RENDERING
    q->userMutex()->lock();
#endif
411
    QAbstractTextDocumentLayout::PaintContext context;
Albert Astals Cid's avatar
Albert Astals Cid committed
412
413
414
415
416
    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 );
417
    context.clip = rect;
Albert Astals Cid's avatar
Albert Astals Cid committed
418
419
    mDocument->setDefaultFont(mFont);
    mDocument->documentLayout()->draw(&p, context);
420
421
422
#ifdef OKULAR_TEXTDOCUMENT_THREADED_RENDERING
    q->userMutex()->unlock();
#endif
423
424
    p.end();

425
    return image;
426
427
}

Albert Astals Cid's avatar
Albert Astals Cid committed
428
Okular::TextPage *TextDocumentGenerator::textPage(Okular::TextRequest *request)
429
{
Albert Astals Cid's avatar
Albert Astals Cid committed
430
431
    Q_D(TextDocumentGenerator);
    return d->createTextPage(request->page()->number());
432
433
}

Albert Astals Cid's avatar
Albert Astals Cid committed
434
bool TextDocumentGenerator::print(QPrinter &printer)
435
{
Albert Astals Cid's avatar
Albert Astals Cid committed
436
437
    Q_D(TextDocumentGenerator);
    if (!d->mDocument)
438
439
        return false;

Albert Astals Cid's avatar
Albert Astals Cid committed
440
    d->mDocument->print(&printer);
441
442
443
444

    return true;
}

Albert Astals Cid's avatar
Albert Astals Cid committed
445
Okular::DocumentInfo TextDocumentGenerator::generateDocumentInfo(const QSet<DocumentInfo::Key> & /*keys*/) const
446
{
Albert Astals Cid's avatar
Albert Astals Cid committed
447
    Q_D(const TextDocumentGenerator);
448
    return d->mDocumentInfo;
449
450
}

Albert Astals Cid's avatar
Albert Astals Cid committed
451
const Okular::DocumentSynopsis *TextDocumentGenerator::generateDocumentSynopsis()
452
{
Albert Astals Cid's avatar
Albert Astals Cid committed
453
454
    Q_D(TextDocumentGenerator);
    if (!d->mDocumentSynopsis.hasChildNodes())
455
        return nullptr;
456
457
458
459
    else
        return &d->mDocumentSynopsis;
}

Albert Astals Cid's avatar
Albert Astals Cid committed
460
QVariant TextDocumentGeneratorPrivate::metaData(const QString &key, const QVariant &option) const
461
{
Albert Astals Cid's avatar
Albert Astals Cid committed
462
463
464
    Q_UNUSED(option)
    if (key == QLatin1String("DocumentTitle")) {
        return mDocumentInfo.get(DocumentInfo::Title);
465
466
467
468
    }
    return QVariant();
}

Albert Astals Cid's avatar
Albert Astals Cid committed
469
Okular::ExportFormat::List TextDocumentGenerator::exportFormats() const
470
471
{
    static Okular::ExportFormat::List formats;
Albert Astals Cid's avatar
Albert Astals Cid committed
472
473
474
475
476
    if (formats.isEmpty()) {
        formats.append(Okular::ExportFormat::standardFormat(Okular::ExportFormat::PlainText));
        formats.append(Okular::ExportFormat::standardFormat(Okular::ExportFormat::PDF));
        if (QTextDocumentWriter::supportedDocumentFormats().contains("ODF")) {
            formats.append(Okular::ExportFormat::standardFormat(Okular::ExportFormat::OpenDocumentText));
Tobias Koenig's avatar
Tobias Koenig committed
477
        }
Albert Astals Cid's avatar
Albert Astals Cid committed
478
479
        if (QTextDocumentWriter::supportedDocumentFormats().contains("HTML")) {
            formats.append(Okular::ExportFormat::standardFormat(Okular::ExportFormat::HTML));
Tobias Koenig's avatar
Tobias Koenig committed
480
        }
481
482
483
484
485
    }

    return formats;
}

Albert Astals Cid's avatar
Albert Astals Cid committed
486
bool TextDocumentGenerator::exportTo(const QString &fileName, const Okular::ExportFormat &format)
487
{
Albert Astals Cid's avatar
Albert Astals Cid committed
488
489
    Q_D(TextDocumentGenerator);
    if (!d->mDocument)
490
491
        return false;

Albert Astals Cid's avatar
Albert Astals Cid committed
492
493
494
    if (format.mimeType().name() == QLatin1String("application/pdf")) {
        QFile file(fileName);
        if (!file.open(QIODevice::WriteOnly))
495
496
            return false;

Albert Astals Cid's avatar
Albert Astals Cid committed
497
498
499
500
        QPrinter printer(QPrinter::HighResolution);
        printer.setOutputFormat(QPrinter::PdfFormat);
        printer.setOutputFileName(fileName);
        d->mDocument->print(&printer);
501
502

        return true;
Albert Astals Cid's avatar
Albert Astals Cid committed
503
504
505
    } else if (format.mimeType().name() == QLatin1String("text/plain")) {
        QFile file(fileName);
        if (!file.open(QIODevice::WriteOnly))
506
507
            return false;

Albert Astals Cid's avatar
Albert Astals Cid committed
508
        QTextStream out(&file);
509
510
511
        out << d->mDocument->toPlainText();

        return true;
Albert Astals Cid's avatar
Albert Astals Cid committed
512
513
    } else if (format.mimeType().name() == QLatin1String("application/vnd.oasis.opendocument.text")) {
        QTextDocumentWriter odfWriter(fileName, "odf");
514

Albert Astals Cid's avatar
Albert Astals Cid committed
515
516
517
        return odfWriter.write(d->mDocument);
    } else if (format.mimeType().name() == QLatin1String("text/html")) {
        QTextDocumentWriter odfWriter(fileName, "html");
518

Albert Astals Cid's avatar
Albert Astals Cid committed
519
        return odfWriter.write(d->mDocument);
520
    }
521
522
523
    return false;
}

524
525
bool TextDocumentGenerator::reparseConfig()
{
Albert Astals Cid's avatar
Albert Astals Cid committed
526
    Q_D(TextDocumentGenerator);
527
    const QFont newFont = d->mGeneralSettings->font();
528

Albert Astals Cid's avatar
Albert Astals Cid committed
529
    if (newFont != d->mFont) {
530
531
532
533
534
535
536
        d->mFont = newFont;
        return true;
    }

    return false;
}

Albert Astals Cid's avatar
Albert Astals Cid committed
537
void TextDocumentGenerator::addPages(KConfigDialog * /*dlg*/)
538
{
539
    qCWarning(OkularCoreDebug) << "You forgot to reimplement addPages in your TextDocumentGenerator";
540
541
542
    return;
}

Albert Astals Cid's avatar
Albert Astals Cid committed
543
TextDocumentSettings *TextDocumentGenerator::generalSettings()
544
{
Albert Astals Cid's avatar
Albert Astals Cid committed
545
    Q_D(TextDocumentGenerator);
546
547
548
549

    return d->mGeneralSettings;
}

Albert Astals Cid's avatar
Albert Astals Cid committed
550
TextDocumentConverter *TextDocumentGenerator::converter()
551
{
Albert Astals Cid's avatar
Albert Astals Cid committed
552
    Q_D(TextDocumentGenerator);
553
554
555
556

    return d->mConverter;
}

Albert Astals Cid's avatar
Albert Astals Cid committed
557
void TextDocumentGenerator::setTextDocument(QTextDocument *textDocument)
558
{
Albert Astals Cid's avatar
Albert Astals Cid committed
559
    Q_D(TextDocumentGenerator);
560
561
562

    d->mDocument = textDocument;

Albert Astals Cid's avatar
Albert Astals Cid committed
563
564
    for (Page *p : qAsConst(d->m_document->m_pagesVector)) {
        p->setTextPage(nullptr);
565
566
    }
}