okular/core/script/kjs_document.cpp

359 lines
12 KiB
C++

/***************************************************************************
* Copyright (C) 2008 by Pino Toscano <pino@kde.org> *
* Copyright (C) 2008 by Harri Porten <porten@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. *
***************************************************************************/
#include "kjs_document_p.h"
#include <qwidget.h>
#include <kjs/kjsobject.h>
#include <kjs/kjsprototype.h>
#include <kjs/kjsarguments.h>
#include <QDebug>
#include <assert.h>
#include "../document_p.h"
#include "../page.h"
#include "../form.h"
#include "kjs_data_p.h"
#include "kjs_field_p.h"
#include "kjs_ocg_p.h"
using namespace Okular;
static KJSPrototype *g_docProto;
// Document.numPages
static KJSObject docGetNumPages( KJSContext *, void *object )
{
DocumentPrivate *doc = reinterpret_cast< DocumentPrivate* >( object );
return KJSNumber( doc->m_pagesVector.count() );
}
// Document.pageNum (getter)
static KJSObject docGetPageNum( KJSContext *, void *object )
{
DocumentPrivate *doc = reinterpret_cast< DocumentPrivate* >( object );
return KJSNumber( doc->m_parent->currentPage() );
}
// Document.pageNum (setter)
static void docSetPageNum( KJSContext* ctx, void* object,
KJSObject value )
{
DocumentPrivate *doc = reinterpret_cast< DocumentPrivate* >( object );
int page = value.toInt32( ctx );
if ( page == (int)doc->m_parent->currentPage() )
return;
doc->m_parent->setViewportPage( page );
}
// Document.documentFileName
static KJSObject docGetDocumentFileName( KJSContext *, void *object )
{
DocumentPrivate *doc = reinterpret_cast< DocumentPrivate* >( object );
return KJSString( doc->m_url.fileName() );
}
// Document.filesize
static KJSObject docGetFilesize( KJSContext *, void *object )
{
DocumentPrivate *doc = reinterpret_cast< DocumentPrivate* >( object );
return KJSNumber( doc->m_docSize );
}
// Document.path
static KJSObject docGetPath( KJSContext *, void *object )
{
DocumentPrivate *doc = reinterpret_cast< DocumentPrivate* >( object );
return KJSString( doc->m_url.toDisplayString(QUrl::PreferLocalFile) );
}
// Document.URL
static KJSObject docGetURL( KJSContext *, void *object )
{
DocumentPrivate *doc = reinterpret_cast< DocumentPrivate* >( object );
return KJSString( doc->m_url.toDisplayString() );
}
// Document.permStatusReady
static KJSObject docGetPermStatusReady( KJSContext *, void * )
{
return KJSBoolean( true );
}
// Document.dataObjects
static KJSObject docGetDataObjects( KJSContext *ctx, void *object )
{
DocumentPrivate *doc = reinterpret_cast< DocumentPrivate* >( object );
const QList< EmbeddedFile * > *files = doc->m_generator->embeddedFiles();
KJSArray dataObjects( ctx, files ? files->count() : 0 );
if ( files )
{
QList< EmbeddedFile * >::ConstIterator it = files->begin(), itEnd = files->end();
for ( int i = 0; it != itEnd; ++it, ++i )
{
KJSObject newdata = JSData::wrapFile( ctx, *it );
dataObjects.setProperty( ctx, QString::number( i ), newdata );
}
}
return dataObjects;
}
// Document.external
static KJSObject docGetExternal( KJSContext *, void *object )
{
DocumentPrivate *doc = reinterpret_cast< DocumentPrivate* >( object );
QWidget *widget = doc->m_widget;
const bool isShell = ( widget
&& widget->parentWidget()
&& widget->parentWidget()->objectName().startsWith( QLatin1String( "okular::Shell" ) ) );
return KJSBoolean( !isShell );
}
// Document.numFields
static KJSObject docGetNumFields( KJSContext *, void *object )
{
const DocumentPrivate *doc = reinterpret_cast< DocumentPrivate* >( object );
unsigned int numFields = 0;
for ( const Page * pIt : qAsConst(doc->m_pagesVector) )
{
numFields += pIt->formFields().size();
}
return KJSNumber( numFields );
}
static KJSObject docGetInfo( KJSContext *ctx, void *object )
{
DocumentPrivate *doc = reinterpret_cast< DocumentPrivate* >( object );
KJSObject obj;
QSet<DocumentInfo::Key> keys;
keys << DocumentInfo::Title
<< DocumentInfo::Author
<< DocumentInfo::Subject
<< DocumentInfo::Keywords
<< DocumentInfo::Creator
<< DocumentInfo::Producer;
const DocumentInfo docinfo = doc->m_parent->documentInfo( keys );
#define KEY_GET( key, property ) \
do { \
const QString data = docinfo.get( key ); \
if ( !data.isEmpty() ) \
{ \
const KJSString newval( data ); \
obj.setProperty( ctx, QStringLiteral(property), newval ); \
obj.setProperty( ctx, QStringLiteral( property ).toLower(), newval ); \
} \
} while ( 0 );
KEY_GET( DocumentInfo::Title, "Title" );
KEY_GET( DocumentInfo::Author, "Author" );
KEY_GET( DocumentInfo::Subject, "Subject" );
KEY_GET( DocumentInfo::Keywords, "Keywords" );
KEY_GET( DocumentInfo::Creator, "Creator" );
KEY_GET( DocumentInfo::Producer, "Producer" );
#undef KEY_GET
return obj;
}
#define DOCINFO_GET_METHOD( key, name ) \
static KJSObject docGet ## name( KJSContext *, void *object ) \
{ \
DocumentPrivate *doc = reinterpret_cast< DocumentPrivate* >( object ); \
const DocumentInfo docinfo = doc->m_parent->documentInfo(QSet<DocumentInfo::Key>() << key ); \
return KJSString( docinfo.get( key ) ); \
}
DOCINFO_GET_METHOD( DocumentInfo::Author, Author )
DOCINFO_GET_METHOD( DocumentInfo::Creator, Creator )
DOCINFO_GET_METHOD( DocumentInfo::Keywords, Keywords )
DOCINFO_GET_METHOD( DocumentInfo::Producer, Producer )
DOCINFO_GET_METHOD( DocumentInfo::Title, Title )
DOCINFO_GET_METHOD( DocumentInfo::Subject, Subject )
#undef DOCINFO_GET_METHOD
// Document.getField()
static KJSObject docGetField( KJSContext *context, void *object,
const KJSArguments &arguments )
{
DocumentPrivate *doc = reinterpret_cast< DocumentPrivate* >( object );
QString cName = arguments.at( 0 ).toString( context );
QVector< Page * >::const_iterator pIt = doc->m_pagesVector.constBegin(), pEnd = doc->m_pagesVector.constEnd();
for ( ; pIt != pEnd; ++pIt )
{
const QLinkedList< Okular::FormField * > pageFields = (*pIt)->formFields();
QLinkedList< Okular::FormField * >::const_iterator ffIt = pageFields.constBegin(), ffEnd = pageFields.constEnd();
for ( ; ffIt != ffEnd; ++ffIt )
{
if ( (*ffIt)->fullyQualifiedName() == cName )
{
return JSField::wrapField( context, *ffIt, *pIt );
}
}
}
return KJSUndefined();
}
// Document.getPageLabel()
static KJSObject docGetPageLabel( KJSContext *ctx,void *object,
const KJSArguments &arguments )
{
DocumentPrivate *doc = reinterpret_cast< DocumentPrivate* >( object );
int nPage = arguments.at( 0 ).toInt32( ctx );
Page *p = doc->m_pagesVector.value( nPage );
return KJSString( p ? p->label() : QString() );
}
// Document.getPageRotation()
static KJSObject docGetPageRotation( KJSContext *ctx, void *object,
const KJSArguments &arguments )
{
DocumentPrivate *doc = reinterpret_cast< DocumentPrivate* >( object );
int nPage = arguments.at( 0 ).toInt32( ctx );
Page *p = doc->m_pagesVector.value( nPage );
return KJSNumber( p ? p->orientation() * 90 : 0 );
}
// Document.gotoNamedDest()
static KJSObject docGotoNamedDest( KJSContext *ctx, void *object,
const KJSArguments &arguments )
{
DocumentPrivate *doc = reinterpret_cast< DocumentPrivate* >( object );
QString dest = arguments.at( 0 ).toString( ctx );
DocumentViewport viewport( doc->m_generator->metaData( QStringLiteral("NamedViewport"), dest ).toString() );
if ( !viewport.isValid() )
return KJSUndefined();
doc->m_parent->setViewport( viewport );
return KJSUndefined();
}
// Document.syncAnnotScan()
static KJSObject docSyncAnnotScan( KJSContext *, void *,
const KJSArguments & )
{
return KJSUndefined();
}
// Document.getNthFieldName
static KJSObject docGetNthFieldName( KJSContext *ctx, void *object,
const KJSArguments &arguments )
{
const DocumentPrivate *doc = reinterpret_cast< DocumentPrivate* >( object );
int numField = arguments.at( 0 ).toInt32( ctx );
for ( const Page * pIt : qAsConst(doc->m_pagesVector) )
{
const QLinkedList< Okular::FormField * > pageFields = pIt->formFields();
if(numField < pageFields.size())
{
const auto ffIt = pageFields.begin() + numField;
return KJSString( (*ffIt)->fullyQualifiedName() );
}
numField -= pageFields.size();
}
return KJSUndefined();
}
static KJSObject docGetOCGs( KJSContext *ctx, void *object,
const KJSArguments & )
{
const DocumentPrivate *doc = reinterpret_cast< DocumentPrivate* >( object );
QAbstractItemModel * model = doc->m_parent->layersModel();
KJSArray array( ctx, model->rowCount() );
for(int i = 0;i < model->rowCount();++i){
for(int j = 0;j < model->columnCount();++j){
const QModelIndex index = model->index( i, j );
KJSObject item = JSOCG::wrapOCGObject( ctx, model, i, j );
item.setProperty( ctx, QStringLiteral("name"), model->data( index , Qt::DisplayRole ).toString() );
item.setProperty( ctx, QStringLiteral("initState"), model->data( index , Qt::CheckStateRole ).toBool() );
array.setProperty( ctx, QString::number( i ), item );
}
}
return array;
}
void JSDocument::initType( KJSContext *ctx )
{
assert( g_docProto );
static bool initialized = false;
if ( initialized )
return;
initialized = true;
g_docProto->defineProperty( ctx, QStringLiteral("numPages"), docGetNumPages );
g_docProto->defineProperty( ctx, QStringLiteral("pageNum"), docGetPageNum, docSetPageNum );
g_docProto->defineProperty( ctx, QStringLiteral("documentFileName"), docGetDocumentFileName );
g_docProto->defineProperty( ctx, QStringLiteral("filesize"), docGetFilesize );
g_docProto->defineProperty( ctx, QStringLiteral("path"), docGetPath );
g_docProto->defineProperty( ctx, QStringLiteral("URL"), docGetURL );
g_docProto->defineProperty( ctx, QStringLiteral("permStatusReady"), docGetPermStatusReady );
g_docProto->defineProperty( ctx, QStringLiteral("dataObjects"), docGetDataObjects );
g_docProto->defineProperty( ctx, QStringLiteral("external"), docGetExternal );
g_docProto->defineProperty( ctx, QStringLiteral("numFields"), docGetNumFields );
// info properties
g_docProto->defineProperty( ctx, QStringLiteral("info"), docGetInfo );
g_docProto->defineProperty( ctx, QStringLiteral("author"), docGetAuthor );
g_docProto->defineProperty( ctx, QStringLiteral("creator"), docGetCreator );
g_docProto->defineProperty( ctx, QStringLiteral("keywords"), docGetKeywords );
g_docProto->defineProperty( ctx, QStringLiteral("producer"), docGetProducer );
g_docProto->defineProperty( ctx, QStringLiteral("title"), docGetTitle );
g_docProto->defineProperty( ctx, QStringLiteral("subject"), docGetSubject );
g_docProto->defineFunction( ctx, QStringLiteral("getField"), docGetField );
g_docProto->defineFunction( ctx, QStringLiteral("getPageLabel"), docGetPageLabel );
g_docProto->defineFunction( ctx, QStringLiteral("getPageRotation"), docGetPageRotation );
g_docProto->defineFunction( ctx, QStringLiteral("gotoNamedDest"), docGotoNamedDest );
g_docProto->defineFunction( ctx, QStringLiteral("syncAnnotScan"), docSyncAnnotScan );
g_docProto->defineFunction( ctx, QStringLiteral("getNthFieldName"), docGetNthFieldName );
g_docProto->defineFunction( ctx, QStringLiteral("getOCGs"), docGetOCGs );
}
KJSGlobalObject JSDocument::wrapDocument( DocumentPrivate *doc )
{
if ( !g_docProto )
g_docProto = new KJSPrototype();
return g_docProto->constructGlobalObject( doc );
}