File indexing completed on 2024-05-12 04:33:32

0001 /*
0002     SPDX-FileCopyrightText: 2008 Pino Toscano <pino@kde.org>
0003     SPDX-FileCopyrightText: 2008 Harri Porten <porten@kde.org>
0004 
0005     SPDX-License-Identifier: GPL-2.0-or-later
0006 */
0007 
0008 #include "js_document_p.h"
0009 
0010 #include <qwidget.h>
0011 
0012 #include <QDebug>
0013 #include <QJSEngine>
0014 #include <assert.h>
0015 
0016 #include "../document_p.h"
0017 #include "../form.h"
0018 #include "../page.h"
0019 #include "js_data_p.h"
0020 #include "js_field_p.h"
0021 #include "js_ocg_p.h"
0022 
0023 using namespace Okular;
0024 
0025 // Document.numPages
0026 int JSDocument::numPages() const
0027 {
0028     return m_doc->m_pagesVector.count();
0029 }
0030 
0031 // Document.pageNum (getter)
0032 int JSDocument::pageNum() const
0033 {
0034     return m_doc->m_parent->currentPage();
0035 }
0036 
0037 // Document.pageNum (setter)
0038 void JSDocument::setPageNum(int page)
0039 {
0040     if (page == (int)m_doc->m_parent->currentPage()) {
0041         return;
0042     }
0043 
0044     m_doc->m_parent->setViewportPage(page);
0045 }
0046 
0047 // Document.documentFileName
0048 QString JSDocument::documentFileName() const
0049 {
0050     return m_doc->m_url.fileName();
0051 }
0052 
0053 // Document.filesize
0054 int JSDocument::filesize() const
0055 {
0056     return m_doc->m_docSize;
0057 }
0058 
0059 // Document.path
0060 QString JSDocument::path() const
0061 {
0062     return m_doc->m_url.toDisplayString(QUrl::PreferLocalFile);
0063 }
0064 
0065 // Document.URL
0066 QString JSDocument::URL() const
0067 {
0068     return m_doc->m_url.toDisplayString();
0069 }
0070 
0071 // Document.permStatusReady
0072 bool JSDocument::permStatusReady() const
0073 {
0074     return true;
0075 }
0076 
0077 // Document.dataObjects
0078 QJSValue JSDocument::dataObjects() const
0079 {
0080     const QList<EmbeddedFile *> *files = m_doc->m_generator->embeddedFiles();
0081 
0082     QJSValue dataObjects = qjsEngine(this)->newArray(files ? files->count() : 0);
0083     if (files) {
0084         QList<EmbeddedFile *>::ConstIterator it = files->begin(), itEnd = files->end();
0085         for (int i = 0; it != itEnd; ++it, ++i) {
0086             QJSValue newdata = qjsEngine(this)->newQObject(new JSData(*it));
0087             dataObjects.setProperty(i, newdata);
0088         }
0089     }
0090     return dataObjects;
0091 }
0092 
0093 // Document.external
0094 bool JSDocument::external() const
0095 {
0096     QWidget *widget = m_doc->m_widget;
0097 
0098     const bool isShell = (widget && widget->parentWidget() && widget->parentWidget()->objectName().startsWith(QLatin1String("okular::Shell")));
0099     return !isShell;
0100 }
0101 
0102 // Document.numFields
0103 int JSDocument::numFields() const
0104 {
0105     unsigned int numFields = 0;
0106 
0107     for (const Page *pIt : std::as_const(m_doc->m_pagesVector)) {
0108         numFields += pIt->formFields().size();
0109     }
0110 
0111     return numFields;
0112 }
0113 
0114 QJSValue JSDocument::info() const
0115 {
0116     QJSValue obj = qjsEngine(this)->newObject();
0117     QSet<DocumentInfo::Key> keys;
0118     keys << DocumentInfo::Title << DocumentInfo::Author << DocumentInfo::Subject << DocumentInfo::Keywords << DocumentInfo::Creator << DocumentInfo::Producer;
0119     const DocumentInfo docinfo = m_doc->m_parent->documentInfo(keys);
0120 #define KEY_GET(key, property)                                                                                                                                                                                                                 \
0121     do {                                                                                                                                                                                                                                       \
0122         const QString data = docinfo.get(key);                                                                                                                                                                                                 \
0123         if (!data.isEmpty()) {                                                                                                                                                                                                                 \
0124             obj.setProperty(QStringLiteral(property), data);                                                                                                                                                                                   \
0125             obj.setProperty(QStringLiteral(property).toLower(), data);                                                                                                                                                                         \
0126         }                                                                                                                                                                                                                                      \
0127     } while (0);
0128     KEY_GET(DocumentInfo::Title, "Title");
0129     KEY_GET(DocumentInfo::Author, "Author");
0130     KEY_GET(DocumentInfo::Subject, "Subject");
0131     KEY_GET(DocumentInfo::Keywords, "Keywords");
0132     KEY_GET(DocumentInfo::Creator, "Creator");
0133     KEY_GET(DocumentInfo::Producer, "Producer");
0134 #undef KEY_GET
0135     return obj;
0136 }
0137 
0138 #define DOCINFO_GET_METHOD(key, name)                                                                                                                                                                                                          \
0139     QString JSDocument::name() const                                                                                                                                                                                                           \
0140     {                                                                                                                                                                                                                                          \
0141         const DocumentInfo docinfo = m_doc->m_parent->documentInfo(QSet<DocumentInfo::Key>() << key);                                                                                                                                          \
0142         return docinfo.get(key);                                                                                                                                                                                                               \
0143     }
0144 
0145 DOCINFO_GET_METHOD(DocumentInfo::Author, author)
0146 DOCINFO_GET_METHOD(DocumentInfo::Creator, creator)
0147 DOCINFO_GET_METHOD(DocumentInfo::Keywords, keywords)
0148 DOCINFO_GET_METHOD(DocumentInfo::Producer, producer)
0149 DOCINFO_GET_METHOD(DocumentInfo::Title, title)
0150 DOCINFO_GET_METHOD(DocumentInfo::Subject, subject)
0151 
0152 #undef DOCINFO_GET_METHOD
0153 
0154 // Document.getField()
0155 QJSValue JSDocument::getField(const QString &cName) const
0156 {
0157     QVector<Page *>::const_iterator pIt = m_doc->m_pagesVector.constBegin(), pEnd = m_doc->m_pagesVector.constEnd();
0158     for (; pIt != pEnd; ++pIt) {
0159         const QList<Okular::FormField *> pageFields = (*pIt)->formFields();
0160         for (FormField *form : pageFields) {
0161             if (form->fullyQualifiedName() == cName) {
0162                 return JSField::wrapField(qjsEngine(this), form, *pIt);
0163             }
0164         }
0165     }
0166     return QJSValue(QJSValue::UndefinedValue);
0167 }
0168 
0169 // Document.getPageLabel()
0170 QString JSDocument::getPageLabel(int nPage) const
0171 {
0172     Page *p = m_doc->m_pagesVector.value(nPage);
0173     return p ? p->label() : QString();
0174 }
0175 
0176 // Document.getPageRotation()
0177 int JSDocument::getPageRotation(int nPage) const
0178 {
0179     Page *p = m_doc->m_pagesVector.value(nPage);
0180     return p ? p->orientation() * 90 : 0;
0181 }
0182 
0183 // Document.gotoNamedDest()
0184 void JSDocument::gotoNamedDest(const QString &cName) const
0185 {
0186     DocumentViewport viewport(m_doc->m_generator->metaData(QStringLiteral("NamedViewport"), cName).toString());
0187     if (viewport.isValid()) {
0188         m_doc->m_parent->setViewport(viewport);
0189     }
0190 }
0191 
0192 // Document.syncAnnotScan()
0193 void JSDocument::syncAnnotScan() const
0194 {
0195 }
0196 
0197 // Document.getNthFieldName
0198 QJSValue JSDocument::getNthFieldName(int nIndex) const
0199 {
0200     for (const Page *pIt : std::as_const(m_doc->m_pagesVector)) {
0201         const QList<Okular::FormField *> pageFields = pIt->formFields();
0202 
0203         if (nIndex < pageFields.size()) {
0204             const Okular::FormField *form = pageFields[nIndex];
0205 
0206             return form->fullyQualifiedName();
0207         }
0208 
0209         nIndex -= pageFields.size();
0210     }
0211 
0212     return QJSValue(QJSValue::UndefinedValue);
0213 }
0214 
0215 QJSValue JSDocument::getOCGs([[maybe_unused]] int nPage) const
0216 {
0217     QAbstractItemModel *model = m_doc->m_parent->layersModel();
0218 
0219     QJSValue array = qjsEngine(this)->newArray(model->rowCount());
0220 
0221     for (int i = 0; i < model->rowCount(); ++i) {
0222         for (int j = 0; j < model->columnCount(); ++j) {
0223             const QModelIndex index = model->index(i, j);
0224 
0225             QJSValue item = qjsEngine(this)->newQObject(new JSOCG(model, i, j));
0226             item.setProperty(QStringLiteral("name"), model->data(index, Qt::DisplayRole).toString());
0227             item.setProperty(QStringLiteral("initState"), model->data(index, Qt::CheckStateRole).toBool());
0228 
0229             array.setProperty(i, item);
0230         }
0231     }
0232 
0233     return array;
0234 }
0235 
0236 JSDocument::JSDocument(DocumentPrivate *doc, QObject *parent)
0237     : QObject(parent)
0238     , m_doc(doc)
0239 {
0240 }
0241 
0242 JSDocument::~JSDocument() = default;