You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
807 lines
19 KiB
807 lines
19 KiB
/* |
|
SPDX-FileCopyrightText: 2005 Piotr Szymanski <niedakh@gmail.com> |
|
SPDX-FileCopyrightText: 2008 Albert Astals Cid <aacid@kde.org> |
|
|
|
Work sponsored by the LiMux project of the city of Munich: |
|
SPDX-FileCopyrightText: 2017 Klarälvdalens Datakonsult AB a KDAB Group company <info@kdab.com> |
|
|
|
SPDX-License-Identifier: GPL-2.0-or-later |
|
*/ |
|
|
|
#include "generator.h" |
|
#include "generator_p.h" |
|
#include "observer.h" |
|
|
|
#include <QApplication> |
|
#include <QEventLoop> |
|
#include <QPrinter> |
|
|
|
#include <KLocalizedString> |
|
#include <QDebug> |
|
#include <QIcon> |
|
#include <QMimeDatabase> |
|
#include <QTimer> |
|
|
|
#ifdef WITH_KWALLET |
|
#include <KWallet> |
|
#endif |
|
|
|
#include "document_p.h" |
|
#include "page.h" |
|
#include "page_p.h" |
|
#include "textpage.h" |
|
#include "utils.h" |
|
|
|
using namespace Okular; |
|
|
|
GeneratorPrivate::GeneratorPrivate() |
|
: m_document(nullptr) |
|
, mPixmapGenerationThread(nullptr) |
|
, mTextPageGenerationThread(nullptr) |
|
, mPixmapReady(true) |
|
, mTextPageReady(true) |
|
, m_closing(false) |
|
, m_closingLoop(nullptr) |
|
, m_dpi(72.0, 72.0) |
|
{ |
|
qRegisterMetaType<Okular::Page *>(); |
|
} |
|
|
|
GeneratorPrivate::~GeneratorPrivate() |
|
{ |
|
if (mPixmapGenerationThread) { |
|
mPixmapGenerationThread->wait(); |
|
} |
|
|
|
delete mPixmapGenerationThread; |
|
|
|
if (mTextPageGenerationThread) { |
|
mTextPageGenerationThread->wait(); |
|
} |
|
|
|
delete mTextPageGenerationThread; |
|
} |
|
|
|
PixmapGenerationThread *GeneratorPrivate::pixmapGenerationThread() |
|
{ |
|
if (mPixmapGenerationThread) { |
|
return mPixmapGenerationThread; |
|
} |
|
|
|
Q_Q(Generator); |
|
mPixmapGenerationThread = new PixmapGenerationThread(q); |
|
QObject::connect( |
|
mPixmapGenerationThread, &PixmapGenerationThread::finished, q, [this] { pixmapGenerationFinished(); }, Qt::QueuedConnection); |
|
|
|
return mPixmapGenerationThread; |
|
} |
|
|
|
TextPageGenerationThread *GeneratorPrivate::textPageGenerationThread() |
|
{ |
|
if (mTextPageGenerationThread) { |
|
return mTextPageGenerationThread; |
|
} |
|
|
|
Q_Q(Generator); |
|
mTextPageGenerationThread = new TextPageGenerationThread(q); |
|
QObject::connect( |
|
mTextPageGenerationThread, &TextPageGenerationThread::finished, q, [this] { textpageGenerationFinished(); }, Qt::QueuedConnection); |
|
|
|
return mTextPageGenerationThread; |
|
} |
|
|
|
void GeneratorPrivate::pixmapGenerationFinished() |
|
{ |
|
Q_Q(Generator); |
|
PixmapRequest *request = mPixmapGenerationThread->request(); |
|
const QImage &img = mPixmapGenerationThread->image(); |
|
mPixmapGenerationThread->endGeneration(); |
|
|
|
QMutexLocker locker(threadsLock()); |
|
|
|
if (m_closing) { |
|
mPixmapReady = true; |
|
delete request; |
|
if (mTextPageReady) { |
|
locker.unlock(); |
|
m_closingLoop->quit(); |
|
} |
|
return; |
|
} |
|
|
|
if (!request->shouldAbortRender()) { |
|
request->page()->setPixmap(request->observer(), new QPixmap(QPixmap::fromImage(img)), request->normalizedRect()); |
|
const int pageNumber = request->page()->number(); |
|
|
|
if (mPixmapGenerationThread->calcBoundingBox()) { |
|
q->updatePageBoundingBox(pageNumber, mPixmapGenerationThread->boundingBox()); |
|
} |
|
} else { |
|
// Cancel the text page generation too if it's still running |
|
if (mTextPageGenerationThread && mTextPageGenerationThread->isRunning()) { |
|
mTextPageGenerationThread->abortExtraction(); |
|
mTextPageGenerationThread->wait(); |
|
} |
|
} |
|
|
|
mPixmapReady = true; |
|
q->signalPixmapRequestDone(request); |
|
} |
|
|
|
void GeneratorPrivate::textpageGenerationFinished() |
|
{ |
|
Q_Q(Generator); |
|
Page *page = mTextPageGenerationThread->page(); |
|
mTextPageGenerationThread->endGeneration(); |
|
|
|
QMutexLocker locker(threadsLock()); |
|
mTextPageReady = true; |
|
|
|
if (m_closing) { |
|
delete mTextPageGenerationThread->textPage(); |
|
if (mPixmapReady) { |
|
locker.unlock(); |
|
m_closingLoop->quit(); |
|
} |
|
return; |
|
} |
|
|
|
if (mTextPageGenerationThread->textPage()) { |
|
TextPage *tp = mTextPageGenerationThread->textPage(); |
|
page->setTextPage(tp); |
|
q->signalTextGenerationDone(page, tp); |
|
} |
|
} |
|
|
|
QMutex *GeneratorPrivate::threadsLock() |
|
{ |
|
return &m_threadsMutex; |
|
} |
|
|
|
QVariant GeneratorPrivate::metaData(const QString &, const QVariant &) const |
|
{ |
|
return QVariant(); |
|
} |
|
|
|
QImage GeneratorPrivate::image(PixmapRequest *) |
|
{ |
|
return QImage(); |
|
} |
|
|
|
Generator::Generator(QObject *parent, const QVariantList &args) |
|
: Generator(*new GeneratorPrivate(), parent, args) |
|
{ |
|
// the delegated constructor does it all |
|
} |
|
|
|
Generator::Generator(GeneratorPrivate &dd, QObject *parent, const QVariantList &args) |
|
: QObject(parent) |
|
, d_ptr(&dd) |
|
{ |
|
d_ptr->q_ptr = this; |
|
Q_UNUSED(args) |
|
} |
|
|
|
Generator::~Generator() |
|
{ |
|
delete d_ptr; |
|
} |
|
|
|
bool Generator::loadDocument(const QString &fileName, QVector<Page *> &pagesVector) |
|
{ |
|
Q_UNUSED(fileName); |
|
Q_UNUSED(pagesVector); |
|
|
|
return false; |
|
} |
|
|
|
bool Generator::loadDocumentFromData(const QByteArray &, QVector<Page *> &) |
|
{ |
|
return false; |
|
} |
|
|
|
Document::OpenResult Generator::loadDocumentWithPassword(const QString &fileName, QVector<Page *> &pagesVector, const QString &) |
|
{ |
|
return loadDocument(fileName, pagesVector) ? Document::OpenSuccess : Document::OpenError; |
|
} |
|
|
|
Document::OpenResult Generator::loadDocumentFromDataWithPassword(const QByteArray &fileData, QVector<Page *> &pagesVector, const QString &) |
|
{ |
|
return loadDocumentFromData(fileData, pagesVector) ? Document::OpenSuccess : Document::OpenError; |
|
} |
|
|
|
Generator::SwapBackingFileResult Generator::swapBackingFile(QString const & /*newFileName */, QVector<Okular::Page *> & /*newPagesVector*/) |
|
{ |
|
return SwapBackingFileError; |
|
} |
|
|
|
bool Generator::closeDocument() |
|
{ |
|
Q_D(Generator); |
|
|
|
d->m_closing = true; |
|
|
|
d->threadsLock()->lock(); |
|
if (!(d->mPixmapReady && d->mTextPageReady)) { |
|
QEventLoop loop; |
|
d->m_closingLoop = &loop; |
|
|
|
d->threadsLock()->unlock(); |
|
|
|
loop.exec(); |
|
|
|
d->m_closingLoop = nullptr; |
|
} else { |
|
d->threadsLock()->unlock(); |
|
} |
|
|
|
bool ret = doCloseDocument(); |
|
|
|
d->m_closing = false; |
|
|
|
return ret; |
|
} |
|
|
|
bool Generator::canGeneratePixmap() const |
|
{ |
|
Q_D(const Generator); |
|
return d->mPixmapReady; |
|
} |
|
|
|
bool Generator::canSign() const |
|
{ |
|
return false; |
|
} |
|
|
|
bool Generator::sign(const NewSignatureData &, const QString &) |
|
{ |
|
return false; |
|
} |
|
|
|
CertificateStore *Generator::certificateStore() const |
|
{ |
|
return nullptr; |
|
} |
|
|
|
void Generator::generatePixmap(PixmapRequest *request) |
|
{ |
|
Q_D(Generator); |
|
d->mPixmapReady = false; |
|
|
|
const bool calcBoundingBox = !request->isTile() && !request->page()->isBoundingBoxKnown(); |
|
|
|
if (request->asynchronous() && hasFeature(Threaded)) { |
|
if (d->textPageGenerationThread()->isFinished() && !canGenerateTextPage()) { |
|
// It can happen that the text generation has already finished but |
|
// mTextPageReady is still false because textpageGenerationFinished |
|
// didn't have time to run, if so queue ourselves |
|
QTimer::singleShot(0, this, [this, request] { generatePixmap(request); }); |
|
return; |
|
} |
|
|
|
/** |
|
* We create the text page for every page that is visible to the |
|
* user, so he can use the text extraction tools without a delay. |
|
*/ |
|
if (hasFeature(TextExtraction) && !request->page()->hasTextPage() && canGenerateTextPage() && !d->m_closing) { |
|
d->mTextPageReady = false; |
|
d->textPageGenerationThread()->setPage(request->page()); |
|
|
|
// dummy is used as a way to make sure the lambda gets disconnected each time it is executed |
|
// since not all the times the pixmap generation thread starts we want the text generation thread to also start |
|
QObject *dummy = new QObject(); |
|
connect(d_ptr->pixmapGenerationThread(), &QThread::started, dummy, [this, dummy] { |
|
delete dummy; |
|
d_ptr->textPageGenerationThread()->startGeneration(); |
|
}); |
|
} |
|
// pixmap generation thread must be started *after* connect(), else we may miss the start signal and get lock-ups (see bug 396137) |
|
d->pixmapGenerationThread()->startGeneration(request, calcBoundingBox); |
|
|
|
return; |
|
} |
|
|
|
const QImage &img = image(request); |
|
request->page()->setPixmap(request->observer(), new QPixmap(QPixmap::fromImage(img)), request->normalizedRect()); |
|
const int pageNumber = request->page()->number(); |
|
|
|
d->mPixmapReady = true; |
|
|
|
signalPixmapRequestDone(request); |
|
if (calcBoundingBox) { |
|
updatePageBoundingBox(pageNumber, Utils::imageBoundingBox(&img)); |
|
} |
|
} |
|
|
|
bool Generator::canGenerateTextPage() const |
|
{ |
|
Q_D(const Generator); |
|
return d->mTextPageReady; |
|
} |
|
|
|
void Generator::generateTextPage(Page *page) |
|
{ |
|
TextRequest treq(page); |
|
TextPage *tp = textPage(&treq); |
|
page->setTextPage(tp); |
|
signalTextGenerationDone(page, tp); |
|
} |
|
|
|
QImage Generator::image(PixmapRequest *request) |
|
{ |
|
Q_D(Generator); |
|
return d->image(request); |
|
} |
|
|
|
TextPage *Generator::textPage(TextRequest *) |
|
{ |
|
return nullptr; |
|
} |
|
|
|
DocumentInfo Generator::generateDocumentInfo(const QSet<DocumentInfo::Key> &keys) const |
|
{ |
|
Q_UNUSED(keys); |
|
|
|
return DocumentInfo(); |
|
} |
|
|
|
const DocumentSynopsis *Generator::generateDocumentSynopsis() |
|
{ |
|
return nullptr; |
|
} |
|
|
|
FontInfo::List Generator::fontsForPage(int) |
|
{ |
|
return FontInfo::List(); |
|
} |
|
|
|
const QList<EmbeddedFile *> *Generator::embeddedFiles() const |
|
{ |
|
return nullptr; |
|
} |
|
|
|
Generator::PageSizeMetric Generator::pagesSizeMetric() const |
|
{ |
|
return None; |
|
} |
|
|
|
bool Generator::isAllowed(Permission) const |
|
{ |
|
return true; |
|
} |
|
|
|
void Generator::rotationChanged(Rotation, Rotation) |
|
{ |
|
} |
|
|
|
PageSize::List Generator::pageSizes() const |
|
{ |
|
return PageSize::List(); |
|
} |
|
|
|
void Generator::pageSizeChanged(const PageSize &, const PageSize &) |
|
{ |
|
} |
|
|
|
Document::PrintError Generator::print(QPrinter &) |
|
{ |
|
return Document::UnknownPrintError; |
|
} |
|
|
|
void Generator::opaqueAction(const BackendOpaqueAction * /*action*/) |
|
{ |
|
} |
|
|
|
void Generator::freeOpaqueActionContents(const BackendOpaqueAction & /*action*/) |
|
{ |
|
} |
|
|
|
QVariant Generator::metaData(const QString &key, const QVariant &option) const |
|
{ |
|
Q_D(const Generator); |
|
return d->metaData(key, option); |
|
} |
|
|
|
ExportFormat::List Generator::exportFormats() const |
|
{ |
|
return ExportFormat::List(); |
|
} |
|
|
|
bool Generator::exportTo(const QString &, const ExportFormat &) |
|
{ |
|
return false; |
|
} |
|
|
|
void Generator::walletDataForFile(const QString &fileName, QString *walletName, QString *walletFolder, QString *walletKey) const |
|
{ |
|
#ifdef WITH_KWALLET |
|
*walletKey = fileName.section(QLatin1Char('/'), -1, -1); |
|
*walletName = KWallet::Wallet::NetworkWallet(); |
|
*walletFolder = QStringLiteral("KPdf"); |
|
#endif |
|
} |
|
|
|
bool Generator::hasFeature(GeneratorFeature feature) const |
|
{ |
|
Q_D(const Generator); |
|
return d->m_features.contains(feature); |
|
} |
|
|
|
void Generator::signalPixmapRequestDone(PixmapRequest *request) |
|
{ |
|
Q_D(Generator); |
|
if (d->m_document) { |
|
d->m_document->requestDone(request); |
|
} else { |
|
delete request; |
|
} |
|
} |
|
|
|
void Generator::signalTextGenerationDone(Page *page, TextPage *textPage) |
|
{ |
|
Q_D(Generator); |
|
if (d->m_document) { |
|
d->m_document->textGenerationDone(page); |
|
} else { |
|
delete textPage; |
|
} |
|
} |
|
|
|
void Generator::signalPartialPixmapRequest(PixmapRequest *request, const QImage &image) |
|
{ |
|
if (request->shouldAbortRender()) { |
|
return; |
|
} |
|
|
|
PagePrivate *pagePrivate = PagePrivate::get(request->page()); |
|
pagePrivate->setPixmap(request->observer(), new QPixmap(QPixmap::fromImage(image)), request->normalizedRect(), true /* isPartialPixmap */); |
|
|
|
const int pageNumber = request->page()->number(); |
|
request->observer()->notifyPageChanged(pageNumber, Okular::DocumentObserver::Pixmap); |
|
} |
|
|
|
const Document *Generator::document() const |
|
{ |
|
Q_D(const Generator); |
|
if (d->m_document) { |
|
return d->m_document->m_parent; |
|
} |
|
return nullptr; |
|
} |
|
|
|
void Generator::setFeature(GeneratorFeature feature, bool on) |
|
{ |
|
Q_D(Generator); |
|
if (on) { |
|
d->m_features.insert(feature); |
|
} else { |
|
d->m_features.remove(feature); |
|
} |
|
} |
|
|
|
QVariant Generator::documentMetaData(const DocumentMetaDataKey key, const QVariant &option) const |
|
{ |
|
Q_D(const Generator); |
|
if (!d->m_document) { |
|
return QVariant(); |
|
} |
|
|
|
return d->m_document->documentMetaData(key, option); |
|
} |
|
|
|
QMutex *Generator::userMutex() const |
|
{ |
|
Q_D(const Generator); |
|
return &d->m_mutex; |
|
} |
|
|
|
void Generator::updatePageBoundingBox(int page, const NormalizedRect &boundingBox) |
|
{ |
|
Q_D(Generator); |
|
if (d->m_document) { // still connected to document? |
|
d->m_document->setPageBoundingBox(page, boundingBox); |
|
} |
|
} |
|
|
|
QByteArray Generator::requestFontData(const Okular::FontInfo & /*font*/) |
|
{ |
|
return {}; |
|
} |
|
|
|
void Generator::setDPI(const QSizeF dpi) |
|
{ |
|
Q_D(Generator); |
|
d->m_dpi = dpi; |
|
} |
|
|
|
QSizeF Generator::dpi() const |
|
{ |
|
Q_D(const Generator); |
|
return d->m_dpi; |
|
} |
|
|
|
QAbstractItemModel *Generator::layersModel() const |
|
{ |
|
return nullptr; |
|
} |
|
|
|
TextRequest::TextRequest() |
|
: d(new TextRequestPrivate) |
|
{ |
|
d->mPage = nullptr; |
|
d->mShouldAbortExtraction = 0; |
|
} |
|
|
|
TextRequest::TextRequest(Page *page) |
|
: d(new TextRequestPrivate) |
|
{ |
|
d->mPage = page; |
|
d->mShouldAbortExtraction = 0; |
|
} |
|
|
|
TextRequest::~TextRequest() |
|
{ |
|
delete d; |
|
} |
|
|
|
Page *TextRequest::page() const |
|
{ |
|
return d->mPage; |
|
} |
|
|
|
bool TextRequest::shouldAbortExtraction() const |
|
{ |
|
return d->mShouldAbortExtraction != 0; |
|
} |
|
|
|
TextRequestPrivate *TextRequestPrivate::get(const TextRequest *req) |
|
{ |
|
return req->d; |
|
} |
|
|
|
PixmapRequest::PixmapRequest(DocumentObserver *observer, int pageNumber, int width, int height, int priority, PixmapRequestFeatures features) |
|
: PixmapRequest(observer, pageNumber, width, height, qApp->devicePixelRatio(), priority, features) |
|
{ |
|
} |
|
|
|
PixmapRequest::PixmapRequest(DocumentObserver *observer, int pageNumber, int width, int height, qreal dpr, int priority, PixmapRequestFeatures features) |
|
: d(new PixmapRequestPrivate) |
|
{ |
|
d->mObserver = observer; |
|
d->mPageNumber = pageNumber; |
|
d->mWidth = ceil(width * dpr); |
|
d->mHeight = ceil(height * dpr); |
|
d->mPriority = priority; |
|
d->mFeatures = features; |
|
d->mForce = false; |
|
d->mTile = false; |
|
d->mNormalizedRect = NormalizedRect(); |
|
d->mPartialUpdatesWanted = false; |
|
d->mShouldAbortRender = 0; |
|
} |
|
|
|
PixmapRequest::~PixmapRequest() |
|
{ |
|
delete d; |
|
} |
|
|
|
DocumentObserver *PixmapRequest::observer() const |
|
{ |
|
return d->mObserver; |
|
} |
|
|
|
int PixmapRequest::pageNumber() const |
|
{ |
|
return d->mPageNumber; |
|
} |
|
|
|
int PixmapRequest::width() const |
|
{ |
|
return d->mWidth; |
|
} |
|
|
|
int PixmapRequest::height() const |
|
{ |
|
return d->mHeight; |
|
} |
|
|
|
int PixmapRequest::priority() const |
|
{ |
|
return d->mPriority; |
|
} |
|
|
|
bool PixmapRequest::asynchronous() const |
|
{ |
|
return d->mFeatures & Asynchronous; |
|
} |
|
|
|
bool PixmapRequest::preload() const |
|
{ |
|
return d->mFeatures & Preload; |
|
} |
|
|
|
Page *PixmapRequest::page() const |
|
{ |
|
return d->mPage; |
|
} |
|
|
|
void PixmapRequest::setTile(bool tile) |
|
{ |
|
d->mTile = tile; |
|
} |
|
|
|
bool PixmapRequest::isTile() const |
|
{ |
|
return d->mTile; |
|
} |
|
|
|
void PixmapRequest::setNormalizedRect(const NormalizedRect &rect) |
|
{ |
|
if (d->mNormalizedRect == rect) { |
|
return; |
|
} |
|
|
|
d->mNormalizedRect = rect; |
|
} |
|
|
|
const NormalizedRect &PixmapRequest::normalizedRect() const |
|
{ |
|
return d->mNormalizedRect; |
|
} |
|
|
|
void PixmapRequest::setPartialUpdatesWanted(bool partialUpdatesWanted) |
|
{ |
|
d->mPartialUpdatesWanted = partialUpdatesWanted; |
|
} |
|
|
|
bool PixmapRequest::partialUpdatesWanted() const |
|
{ |
|
return d->mPartialUpdatesWanted; |
|
} |
|
|
|
bool PixmapRequest::shouldAbortRender() const |
|
{ |
|
return d->mShouldAbortRender != 0; |
|
} |
|
|
|
Okular::TilesManager *PixmapRequestPrivate::tilesManager() const |
|
{ |
|
return mPage->d->tilesManager(mObserver); |
|
} |
|
|
|
PixmapRequestPrivate *PixmapRequestPrivate::get(const PixmapRequest *req) |
|
{ |
|
return req->d; |
|
} |
|
|
|
void PixmapRequestPrivate::swap() |
|
{ |
|
std::swap(mWidth, mHeight); |
|
} |
|
|
|
class Okular::ExportFormatPrivate : public QSharedData |
|
{ |
|
public: |
|
ExportFormatPrivate(const QString &description, const QMimeType &mimeType, const QIcon &icon = QIcon()) |
|
: QSharedData() |
|
, mDescription(description) |
|
, mMimeType(mimeType) |
|
, mIcon(icon) |
|
{ |
|
} |
|
~ExportFormatPrivate() |
|
{ |
|
} |
|
|
|
QString mDescription; |
|
QMimeType mMimeType; |
|
QIcon mIcon; |
|
}; |
|
|
|
ExportFormat::ExportFormat() |
|
: d(new ExportFormatPrivate(QString(), QMimeType())) |
|
{ |
|
} |
|
|
|
ExportFormat::ExportFormat(const QString &description, const QMimeType &mimeType) |
|
: d(new ExportFormatPrivate(description, mimeType)) |
|
{ |
|
} |
|
|
|
ExportFormat::ExportFormat(const QIcon &icon, const QString &description, const QMimeType &mimeType) |
|
: d(new ExportFormatPrivate(description, mimeType, icon)) |
|
{ |
|
} |
|
|
|
ExportFormat::~ExportFormat() |
|
{ |
|
} |
|
|
|
ExportFormat::ExportFormat(const ExportFormat &other) |
|
: d(other.d) |
|
{ |
|
} |
|
|
|
ExportFormat &ExportFormat::operator=(const ExportFormat &other) |
|
{ |
|
if (this == &other) { |
|
return *this; |
|
} |
|
|
|
d = other.d; |
|
|
|
return *this; |
|
} |
|
|
|
QString ExportFormat::description() const |
|
{ |
|
return d->mDescription; |
|
} |
|
|
|
QMimeType ExportFormat::mimeType() const |
|
{ |
|
return d->mMimeType; |
|
} |
|
|
|
QIcon ExportFormat::icon() const |
|
{ |
|
return d->mIcon; |
|
} |
|
|
|
bool ExportFormat::isNull() const |
|
{ |
|
return !d->mMimeType.isValid() || d->mDescription.isNull(); |
|
} |
|
|
|
ExportFormat ExportFormat::standardFormat(StandardExportFormat type) |
|
{ |
|
QMimeDatabase db; |
|
switch (type) { |
|
case PlainText: |
|
return ExportFormat(QIcon::fromTheme(QStringLiteral("text-x-generic")), i18n("Plain &Text..."), db.mimeTypeForName(QStringLiteral("text/plain"))); |
|
break; |
|
case PDF: |
|
return ExportFormat(QIcon::fromTheme(QStringLiteral("application-pdf")), i18n("PDF"), db.mimeTypeForName(QStringLiteral("application/pdf"))); |
|
break; |
|
case OpenDocumentText: |
|
return ExportFormat( |
|
QIcon::fromTheme(QStringLiteral("application-vnd.oasis.opendocument.text")), i18nc("This is the document format", "OpenDocument Text"), db.mimeTypeForName(QStringLiteral("application/vnd.oasis.opendocument.text"))); |
|
break; |
|
case HTML: |
|
return ExportFormat(QIcon::fromTheme(QStringLiteral("text-html")), i18nc("This is the document format", "HTML"), db.mimeTypeForName(QStringLiteral("text/html"))); |
|
break; |
|
} |
|
return ExportFormat(); |
|
} |
|
|
|
bool ExportFormat::operator==(const ExportFormat &other) const |
|
{ |
|
return d == other.d; |
|
} |
|
|
|
bool ExportFormat::operator!=(const ExportFormat &other) const |
|
{ |
|
return d != other.d; |
|
} |
|
|
|
QDebug operator<<(QDebug str, const Okular::PixmapRequest &req) |
|
{ |
|
PixmapRequestPrivate *reqPriv = PixmapRequestPrivate::get(&req); |
|
|
|
str << "PixmapRequest:" << &req; |
|
str << "- observer:" << (qulonglong)req.observer(); |
|
str << "- page:" << req.pageNumber(); |
|
str << "- width:" << req.width(); |
|
str << "- height:" << req.height(); |
|
str << "- priority:" << req.priority(); |
|
str << "- async:" << (req.asynchronous() ? "true" : "false"); |
|
str << "- tile:" << (req.isTile() ? "true" : "false"); |
|
str << "- rect:" << req.normalizedRect(); |
|
str << "- preload:" << (req.preload() ? "true" : "false"); |
|
str << "- partialUpdates:" << (req.partialUpdatesWanted() ? "true" : "false"); |
|
str << "- shouldAbort:" << (req.shouldAbortRender() ? "true" : "false"); |
|
str << "- force:" << (reqPriv->mForce ? "true" : "false"); |
|
return str; |
|
} |
|
|
|
/* kate: replace-tabs on; indent-width 4; */
|
|
|