Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qquickpdfdocument.cpp
Go to the documentation of this file.
1// Copyright (C) 2022 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
5#include <private/qpdffile_p.h>
6#include <QtCore/qmetatype.h>
7#include <QtCore/qstandardpaths.h>
8#include <QtQml/qqmlcontext.h>
9#include <QtQml/qqmlengine.h>
10#include <QtQml/qqmlinfo.h>
11#include <QtQuick/qquickitem.h>
12#include <QtQml/qqmlfile.h>
13#include <QThread>
14
16
17/*!
18 \qmltype PdfDocument
19//! \nativetype QQuickPdfDocument
20 \inqmlmodule QtQuick.Pdf
21 \ingroup pdf
22 \brief A representation of a PDF document.
23 \since 5.15
24
25 PdfDocument provides access to PDF document meta-information.
26 It is not necessary for rendering, as it is enough to use an
27 \l Image with source set to the URL of the PDF.
28*/
29
30/*
31 Constructs a PDF document.
32*/
33QQuickPdfDocument::QQuickPdfDocument(QObject *parent)
34 : QObject(parent)
35{
36}
37
38/*!
39 \internal
40*/
41QQuickPdfDocument::~QQuickPdfDocument()
42{
43 delete m_carrierFile;
44};
45
46void QQuickPdfDocument::classBegin()
47{
48 m_doc = static_cast<QPdfDocument *>(qmlExtendedObject(this));
49 Q_ASSERT(m_doc);
50 connect(m_doc, &QPdfDocument::passwordChanged, this, [this]() -> void {
51 if (resolvedSource().isValid())
52 m_doc->load(QQmlFile::urlToLocalFileOrQrc(resolvedSource()));
53 });
54 connect(m_doc, &QPdfDocument::statusChanged, this, [this] (QPdfDocument::Status status) {
55 emit errorChanged();
56 if (status == QPdfDocument::Status::Ready)
57 emit metaDataChanged();
58 });
59 if (m_doc->error() == QPdfDocument::Error::IncorrectPassword)
60 emit m_doc->passwordRequired();
61}
62
63/*!
64 \qmlproperty url PdfDocument::source
65
66 This property holds a URL pointing to the PDF file to be loaded.
67
68 \note At this time, only local filesystem and
69 \l {The Qt Resource System} {resource} URLs are supported. Nevertheless,
70 the \c source property is a \l {QUrl}{URL}, not merely a filesystem path.
71 PdfDocument resolves it via QQmlContext::resolvedUrl(). You should
72 typically ensure that the URL starts with a \c {file://} scheme, unless you
73 mean to load the PDF file from resources, or it comes from some component
74 (such as \l {QtQuick.Controls::}{FileDialog}) that resolves it in advance.
75*/
76void QQuickPdfDocument::setSource(QUrl source)
77{
78 if (m_source == source)
79 return;
80
81 m_source = source;
82 m_maxPageWidthHeight = QSizeF();
83 if (m_carrierFile) {
84 if (m_carrierFile->thread())
85 m_carrierFile->deleteLater(); // to be done in that thread
86 else
87 delete m_carrierFile; // avoid leaking if there's no thread affinity
88 }
89 m_carrierFile = nullptr;
90 emit sourceChanged();
91 const QQmlContext *context = qmlContext(this);
92 m_resolvedSource = context ? context->resolvedUrl(source) : source;
93 if (m_resolvedSource.isValid())
94 m_doc->load(QQmlFile::urlToLocalFileOrQrc(m_resolvedSource));
95 else
96 qmlWarning(this) << QQuickPdfDocument::tr("Cannot open: %1").arg(m_resolvedSource.toString());
97}
98
99/*!
100 \qmlproperty string PdfDocument::error
101
102 This property holds a translated string representation of the current
103 error, if any.
104
105 \sa status
106*/
107QString QQuickPdfDocument::error() const
108{
109 switch (m_doc->error()) {
110 case QPdfDocument::Error::None:
111 return tr("no error");
112 break;
113 case QPdfDocument::Error::Unknown:
114 break;
115 case QPdfDocument::Error::DataNotYetAvailable:
116 return tr("data not yet available");
117 break;
118 case QPdfDocument::Error::FileNotFound:
119 return tr("file not found");
120 break;
121 case QPdfDocument::Error::InvalidFileFormat:
122 return tr("invalid file format");
123 break;
124 case QPdfDocument::Error::IncorrectPassword:
125 return tr("incorrect password");
126 break;
127 case QPdfDocument::Error::UnsupportedSecurityScheme:
128 return tr("unsupported security scheme");
129 break;
130 }
131 return tr("unknown error");
132}
133
134/*!
135 \qmlproperty string PdfDocument::password
136
137 This property holds the document password. If the passwordRequired()
138 signal is emitted, the UI should prompt the user and then set this
139 property so that document opening can continue.
140*/
141
142/*!
143 \qmlproperty int PdfDocument::pageCount
144
145 This property holds the number of pages the PDF contains.
146*/
147
148/*!
149 \qmlsignal PdfDocument::passwordRequired()
150
151 This signal is emitted when the PDF requires a password in order to open.
152 The UI in a typical PDF viewer should prompt the user for the password
153 and then set the password property when the user has provided it.
154*/
155
156/*!
157 \qmlmethod size PdfDocument::pagePointSize(int page)
158
159 Returns the size of the given \a page in points.
160*/
161
162qreal QQuickPdfDocument::maxPageWidth() const
163{
164 updateMaxPageSize();
165 return m_maxPageWidthHeight.width();
166}
167
168qreal QQuickPdfDocument::maxPageHeight() const
169{
170 updateMaxPageSize();
171 return m_maxPageWidthHeight.height();
172}
173
174QPdfDocument *QQuickPdfDocument::document() const
175{
176 return m_doc;
177}
178
179/*!
180 \internal
181 Returns a QPdfFile instance that can carry this document down into
182 QPdfIOHandler::load(QIODevice *). It should not be used for other purposes.
183*/
184QPdfFile *QQuickPdfDocument::carrierFile()
185{
186 if (!m_carrierFile)
187 m_carrierFile = new QPdfFile(m_doc);
188 return m_carrierFile;
189}
190
191void QQuickPdfDocument::updateMaxPageSize() const
192{
193 if (m_maxPageWidthHeight.isValid())
194 return;
195 qreal w = 0;
196 qreal h = 0;
197 const int count = m_doc->pageCount();
198 for (int i = 0; i < count; ++i) {
199 auto size = m_doc->pagePointSize(i);
200 w = qMax(w, size.width());
201 h = qMax(w, size.height());
202 }
203 m_maxPageWidthHeight = QSizeF(w, h);
204}
205
206/*!
207 \qmlproperty real PdfDocument::maxPageWidth
208
209 This property holds the width of the widest page in the document, in points.
210*/
211
212/*!
213 \qmlproperty real PdfDocument::maxPageHeight
214
215 This property holds the height of the tallest page in the document, in points.
216*/
217
218/*!
219 \qmlproperty string PdfDocument::title
220
221 This property holds the document's title. A typical viewer UI can bind this
222 to the \c Window.title property.
223*/
224
225/*!
226 \qmlproperty string PdfDocument::author
227
228 This property holds the name of the person who created the document.
229*/
230
231/*!
232 \qmlproperty string PdfDocument::subject
233
234 This property holds the subject of the document.
235*/
236
237/*!
238 \qmlproperty string PdfDocument::keywords
239
240 This property holds the keywords associated with the document.
241*/
242
243/*!
244 \qmlproperty string PdfDocument::creator
245
246 If the document was converted to PDF from another format, this property
247 holds the name of the software that created the original document.
248*/
249
250/*!
251 \qmlproperty string PdfDocument::producer
252
253 If the document was converted to PDF from another format, this property
254 holds the name of the software that converted it to PDF.
255*/
256
257/*!
258 \qmlproperty date PdfDocument::creationDate
259
260 This property holds the date and time the document was created.
261*/
262
263/*!
264 \qmlproperty date PdfDocument::modificationDate
265
266 This property holds the date and time the document was most recently
267 modified.
268*/
269
270/*!
271 \qmlproperty enum PdfDocument::status
272
273 This property tells the current status of the document. The possible values are:
274
275 \value PdfDocument.Null The initial status after the document has been created or after it has been closed.
276 \value PdfDocument.Loading The status after load() has been called and before the document is fully loaded.
277 \value PdfDocument.Ready The status when the document is fully loaded and its data can be accessed.
278 \value PdfDocument.Unloading The status after close() has been called on an open document.
279 At this point the document is still valid and all its data can be accessed.
280 \value PdfDocument.Error The status after Loading, if loading has failed.
281*/
282
283QT_END_NAMESPACE
284
285#include "moc_qquickpdfdocument_p.cpp"