Start implementing the JavaScript scripting API for PDF documents,

thanks to Harri and Maksim and the brand-new public KJS API.

This starts the implementation of some of the API objects needed,
like App, Console, Data, Document, Field, FullScreen, Spell, Util.
Also, workaround the fact that we cannot change the read-only status for form fields.

svn path=/trunk/KDE/kdegraphics/okular/; revision=809259
This commit is contained in:
Pino Toscano 2008-05-18 16:37:07 +00:00
parent 5ef72af455
commit 19585b87f6
18 changed files with 1235 additions and 2 deletions

View file

@ -46,6 +46,14 @@ set(okularcore_SRCS
core/utils.cpp
core/view.cpp
core/fileprinter.cpp
core/script/executor_kjs.cpp
core/script/kjs_console.cpp
core/script/kjs_data.cpp
core/script/kjs_document.cpp
core/script/kjs_fullscreen.cpp
core/script/kjs_field.cpp
core/script/kjs_spell.cpp
core/script/kjs_util.cpp
)
install( FILES
@ -90,7 +98,7 @@ IF(APPLE)
SET(OKULAR_IOKIT "-framework IOKit" CACHE STRING "Apple IOKit framework")
ENDIF(APPLE)
target_link_libraries(okularcore ${OKULAR_IOKIT} ${KDE4_KIO_LIBS} ${KDE4_PHONON_LIBRARY} ${MATH_LIB} ${KDE4_THREADWEAVER_LIBRARY} )
target_link_libraries(okularcore ${OKULAR_IOKIT} ${KDE4_KIO_LIBS} ${KDE4_PHONON_LIBRARY} ${KDE4_KJSAPI_LIBRARY} ${MATH_LIB} ${KDE4_THREADWEAVER_LIBRARY} )
set_target_properties(okularcore PROPERTIES VERSION 1.1.0 SOVERSION 1 )

View file

@ -0,0 +1,110 @@
/***************************************************************************
* 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 "executor_kjs_p.h"
#include <kjs/kjsinterpreter.h>
#include <kjs/kjsobject.h>
#include <kjs/kjsprototype.h>
#include <kjs/kjsarguments.h>
#include <kdebug.h>
#include "../debug_p.h"
#include "../document_p.h"
#include "kjs_console_p.h"
#include "kjs_data_p.h"
#include "kjs_document_p.h"
#include "kjs_field_p.h"
#include "kjs_fullscreen_p.h"
#include "kjs_spell_p.h"
#include "kjs_util_p.h"
using namespace Okular;
class Okular::ExecutorKJSPrivate
{
public:
ExecutorKJSPrivate( DocumentPrivate *doc )
: m_doc( doc )
{
initTypes();
}
~ExecutorKJSPrivate()
{
JSField::clearCachedFields();
delete m_interpreter;
}
void initTypes();
DocumentPrivate *m_doc;
KJSInterpreter *m_interpreter;
KJSObject m_docObject;
};
void ExecutorKJSPrivate::initTypes()
{
m_docObject = JSDocument::wrapDocument( m_doc );
m_interpreter = new KJSInterpreter( m_docObject );
KJSContext *ctx = m_interpreter->globalContext();
JSFullscreen::initType( ctx );
JSConsole::initType( ctx );
JSData::initType( ctx );
JSDocument::initType( ctx );
JSField::initType( ctx );
JSSpell::initType( ctx );
JSUtil::initType( ctx );
m_docObject.setProperty( ctx, "console", JSConsole::object( ctx ) );
m_docObject.setProperty( ctx, "Doc", m_docObject );
m_docObject.setProperty( ctx, "spell", JSSpell::object( ctx ) );
m_docObject.setProperty( ctx, "util", JSUtil::object( ctx ) );
}
ExecutorKJS::ExecutorKJS( DocumentPrivate *doc )
: d( new ExecutorKJSPrivate( doc ) )
{
}
ExecutorKJS::~ExecutorKJS()
{
delete d;
}
void ExecutorKJS::execute( const QString &script )
{
#if 0
QString script2;
QString errMsg;
int errLine;
if ( !KJSInterpreter::normalizeCode( script, &script2, &errLine, &errMsg ) )
{
kWarning(OkularDebug) << "Parse error during normalization!";
script2 = script;
}
#endif
KJSResult result = d->m_interpreter->evaluate( "okular.js", 1,
script, &d->m_docObject );
KJSContext* ctx = d->m_interpreter->globalContext();
if ( result.isException() || ctx->hasException() )
{
kDebug(OkularDebug) << "JS exception" << result.errorMessage();
}
else
{
kDebug(OkularDebug) << "result:" << result.value().toString( ctx );
}
}

View file

@ -0,0 +1,35 @@
/***************************************************************************
* Copyright (C) 2008 by Pino Toscano <pino@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. *
***************************************************************************/
#ifndef OKULAR_SCRIPT_EXECUTOR_KJS_P_H
#define OKULAR_SCRIPT_EXECUTOR_KJS_P_H
class QString;
namespace Okular {
class DocumentPrivate;
class ExecutorKJSPrivate;
class ExecutorKJS
{
public:
ExecutorKJS( DocumentPrivate *doc );
~ExecutorKJS();
void execute( const QString &script );
private:
friend class ExecutorKJSPrivate;
ExecutorKJSPrivate* d;
};
}
#endif

View file

@ -0,0 +1,67 @@
/***************************************************************************
* 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_console_p.h"
#include <kjs/kjsobject.h>
#include <kjs/kjsprototype.h>
#include <kjs/kjsarguments.h>
#include <kdebug.h>
#include "../debug_p.h"
using namespace Okular;
static KJSPrototype *g_consoleProto;
static KJSObject consoleClear( KJSContext *, void *, const KJSArguments & )
{
return KJSUndefined();
}
static KJSObject consoleHide( KJSContext *, void *, const KJSArguments & )
{
return KJSUndefined();
}
static KJSObject consolePrintln( KJSContext *ctx, void *,
const KJSArguments &arguments )
{
QString cMessage = arguments.at( 0 ).toString( ctx );
kDebug(OkularDebug) << "CONSOLE:" << cMessage;
return KJSUndefined();
}
static KJSObject consoleShow( KJSContext *, void *, const KJSArguments & )
{
return KJSUndefined();
}
void JSConsole::initType( KJSContext *ctx )
{
static bool initialized = false;
if ( initialized )
return;
initialized = true;
g_consoleProto = new KJSPrototype();
g_consoleProto->defineFunction( ctx, "clear", consoleClear );
g_consoleProto->defineFunction( ctx, "hide", consoleHide );
g_consoleProto->defineFunction( ctx, "println", consolePrintln );
g_consoleProto->defineFunction( ctx, "hide", consoleShow );
}
KJSObject JSConsole::object( KJSContext *ctx )
{
return g_consoleProto->constructObject( ctx, 0 );
}

View file

@ -0,0 +1,28 @@
/***************************************************************************
* 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. *
***************************************************************************/
#ifndef OKULAR_SCRIPT_KJS_CONSOLE_P_H
#define OKULAR_SCRIPT_KJS_CONSOLE_P_H
class KJSContext;
class KJSObject;
namespace Okular {
class JSConsole
{
public:
static void initType( KJSContext *ctx );
static KJSObject object( KJSContext *ctx );
};
}
#endif

90
core/script/kjs_data.cpp Normal file
View file

@ -0,0 +1,90 @@
/***************************************************************************
* 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_data_p.h"
#include <kjs/kjsobject.h>
#include <kjs/kjsprototype.h>
#include <qdatetime.h>
#include "../document.h"
using namespace Okular;
static KJSPrototype *g_dataProto;
static KJSObject dataGetCreationDate( KJSContext *ctx, void *object )
{
const EmbeddedFile *file = reinterpret_cast< EmbeddedFile * >( object );
return KJSDate( ctx, file->creationDate() );
}
static KJSObject dataGetDescription( KJSContext *, void *object )
{
const EmbeddedFile *file = reinterpret_cast< EmbeddedFile * >( object );
return KJSString( file->description() );
}
static KJSObject dataGetMIMEType( KJSContext *, void *object )
{
return KJSString( "" );
}
static KJSObject dataGetModDate( KJSContext *ctx, void *object )
{
const EmbeddedFile *file = reinterpret_cast< EmbeddedFile * >( object );
return KJSDate( ctx, file->modificationDate() );
}
static KJSObject dataGetName( KJSContext *, void *object )
{
const EmbeddedFile *file = reinterpret_cast< EmbeddedFile * >( object );
return KJSString( file->name() );
}
static KJSObject dataGetPath( KJSContext *, void *object )
{
return KJSString( "" );
}
static KJSObject dataGetSize( KJSContext *, void *object )
{
const EmbeddedFile *file = reinterpret_cast< EmbeddedFile * >( object );
return KJSNumber( file->size() );
}
void JSData::initType( KJSContext *ctx )
{
static bool initialized = false;
if ( initialized )
return;
initialized = true;
if ( !g_dataProto )
g_dataProto = new KJSPrototype();
g_dataProto->defineProperty( ctx, "creationDate", dataGetCreationDate );
g_dataProto->defineProperty( ctx, "description", dataGetDescription );
g_dataProto->defineProperty( ctx, "MIMEType", dataGetMIMEType );
g_dataProto->defineProperty( ctx, "modDate", dataGetModDate );
g_dataProto->defineProperty( ctx, "name", dataGetName );
g_dataProto->defineProperty( ctx, "path", dataGetPath );
g_dataProto->defineProperty( ctx, "size", dataGetSize );
}
KJSObject JSData::wrapFile( KJSContext *ctx, EmbeddedFile *f )
{
return g_dataProto->constructObject( ctx, f );
}

30
core/script/kjs_data_p.h Normal file
View file

@ -0,0 +1,30 @@
/***************************************************************************
* 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. *
***************************************************************************/
#ifndef OKULAR_SCRIPT_KJS_DATA_P_H
#define OKULAR_SCRIPT_KJS_DATA_P_H
class KJSContext;
class KJSObject;
namespace Okular {
class EmbeddedFile;
class JSData
{
public:
static void initType( KJSContext *ctx );
static KJSObject wrapFile( KJSContext *ctx, EmbeddedFile *f );
};
}
#endif

View file

@ -0,0 +1,287 @@
/***************************************************************************
* 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 <kdebug.h>
#include <assert.h>
#include "../document_p.h"
#include "../page.h"
#include "../form.h"
#include "kjs_data_p.h"
#include "kjs_field_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.pathOrUrl() );
}
// Document.URL
static KJSObject docGetURL( KJSContext *, void *object )
{
DocumentPrivate *doc = reinterpret_cast< DocumentPrivate* >( object );
return KJSString( doc->m_url.prettyUrl() );
}
// 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_parent->widget();
const bool isShell = ( widget
&& widget->parentWidget()
&& widget->parentWidget()->objectName() == QLatin1String( "okular::Shell" ) );
return KJSBoolean( !isShell );
}
static KJSObject docGetInfo( KJSContext *ctx, void *object )
{
DocumentPrivate *doc = reinterpret_cast< DocumentPrivate* >( object );
KJSObject obj;
const DocumentInfo *docinfo = doc->m_generator->generateDocumentInfo();
if ( docinfo )
{
#define KEY_GET( key, property ) \
do { \
const QString data = docinfo->get( key ); \
if ( !data.isEmpty() ) \
{ \
const KJSString newval( data ); \
obj.setProperty( ctx, property, newval ); \
obj.setProperty( ctx, QString( property ).toLower(), newval ); \
} \
} while ( 0 );
KEY_GET( "title", "Title" );
KEY_GET( "author", "Author" );
KEY_GET( "subject", "Subject" );
KEY_GET( "keywords", "Keywords" );
KEY_GET( "creator", "Creator" );
KEY_GET( "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_generator->generateDocumentInfo(); \
return KJSString( docinfo->get( key ) ); \
}
DOCINFO_GET_METHOD( "author", Author )
DOCINFO_GET_METHOD( "creator", Creator )
DOCINFO_GET_METHOD( "keywords", Keywords )
DOCINFO_GET_METHOD( "producer", Producer )
DOCINFO_GET_METHOD( "title", Title )
DOCINFO_GET_METHOD( "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.begin(), pEnd = doc->m_pagesVector.end();
for ( ; pIt != pEnd; ++pIt )
{
const QLinkedList< Okular::FormField * > pageFields = (*pIt)->formFields();
QLinkedList< Okular::FormField * >::const_iterator ffIt = pageFields.begin(), ffEnd = pageFields.end();
for ( ; ffIt != ffEnd; ++ffIt )
{
if ( (*ffIt)->name() == 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( "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();
}
void JSDocument::initType( KJSContext *ctx )
{
assert( g_docProto );
static bool initialized = false;
if ( initialized )
return;
initialized = true;
g_docProto->defineProperty( ctx, "numPages", docGetNumPages );
g_docProto->defineProperty( ctx, "pageNum", docGetPageNum, docSetPageNum );
g_docProto->defineProperty( ctx, "documentFileName", docGetDocumentFileName );
g_docProto->defineProperty( ctx, "filesize", docGetFilesize );
g_docProto->defineProperty( ctx, "path", docGetPath );
g_docProto->defineProperty( ctx, "URL", docGetURL );
g_docProto->defineProperty( ctx, "permStatusReady", docGetPermStatusReady );
g_docProto->defineProperty( ctx, "dataObjects", docGetDataObjects );
g_docProto->defineProperty( ctx, "external", docGetExternal );
// info properties
g_docProto->defineProperty( ctx, "info", docGetInfo );
g_docProto->defineProperty( ctx, "author", docGetAuthor );
g_docProto->defineProperty( ctx, "creator", docGetCreator );
g_docProto->defineProperty( ctx, "keywords", docGetKeywords );
g_docProto->defineProperty( ctx, "producer", docGetProducer );
g_docProto->defineProperty( ctx, "title", docGetTitle );
g_docProto->defineProperty( ctx, "subject", docGetSubject );
g_docProto->defineFunction( ctx, "getField", docGetField );
g_docProto->defineFunction( ctx, "getPageLabel", docGetPageLabel );
g_docProto->defineFunction( ctx, "getPageRotation", docGetPageRotation );
g_docProto->defineFunction( ctx, "gotoNamedDest", docGotoNamedDest );
g_docProto->defineFunction( ctx, "syncAnnotScan", docSyncAnnotScan );
}
KJSObject JSDocument::wrapDocument( DocumentPrivate *doc )
{
if ( !g_docProto )
g_docProto = new KJSPrototype();
return g_docProto->constructObject( 0, doc );
}

View file

@ -0,0 +1,30 @@
/***************************************************************************
* 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. *
***************************************************************************/
#ifndef OKULAR_SCRIPT_KJS_DOCUMENT_P_H
#define OKULAR_SCRIPT_KJS_DOCUMENT_P_H
class KJSContext;
class KJSObject;
namespace Okular {
class DocumentPrivate;
class JSDocument
{
public:
static void initType( KJSContext *ctx );
static KJSObject wrapDocument( DocumentPrivate *doc );
};
}
#endif

230
core/script/kjs_field.cpp Normal file
View file

@ -0,0 +1,230 @@
/***************************************************************************
* 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_field_p.h"
#include <kjs/kjsinterpreter.h>
#include <kjs/kjsprototype.h>
#include <kjs/kjsarguments.h>
#include <qhash.h>
#include <kdebug.h>
#include <kglobal.h>
#include "../debug_p.h"
#include "../document_p.h"
#include "../form.h"
#include "../page.h"
using namespace Okular;
static KJSPrototype *g_fieldProto;
typedef QHash< FormField *, KJSObject > FormCache;
K_GLOBAL_STATIC( FormCache, g_fieldCache )
// Field.doc
static KJSObject fieldGetDoc( KJSContext *context, void * )
{
return context->interpreter().globalObject();
}
// Field.name
static KJSObject fieldGetName( KJSContext *, void *object )
{
const FormField *field = reinterpret_cast< FormField * >( object );
return KJSString( field->name() );
}
// Field.readonly (getter)
static KJSObject fieldGetReadOnly( KJSContext *, void *object )
{
const FormField *field = reinterpret_cast< FormField * >( object );
return KJSBoolean( field->isReadOnly() );
}
// Field.readonly (setter)
static void fieldSetReadOnly( KJSContext *context, void *object, KJSObject value )
{
#if 0
FormField *field = reinterpret_cast< FormField * >( object );
bool b = value.toBoolean( context );
field->setReadOnly( b );
#else
Q_UNUSED( context );
Q_UNUSED( object );
Q_UNUSED( value );
kDebug(OkularDebug) << "Not implemented: setting readonly property";
#endif
}
static QString fieldGetTypeHelper( const FormField *field )
{
switch ( field->type() )
{
case FormField::FormButton:
{
const FormFieldButton *button = static_cast< const FormFieldButton * >( field );
switch ( button->buttonType() )
{
case FormFieldButton::Push:
return "button";
case FormFieldButton::CheckBox:
return "checkbox";
case FormFieldButton::Radio:
return "radiobutton";
}
break;
}
case FormField::FormText:
return "text";
case FormField::FormChoice:
{
const FormFieldChoice *choice = static_cast< const FormFieldChoice * >( field );
switch ( choice->choiceType() )
{
case FormFieldChoice::ComboBox:
return "combobox";
case FormFieldChoice::ListBox:
return "listbox";
}
break;
}
case FormField::FormSignature:
return "signature";
}
return QString();
}
// Field.type
static KJSObject fieldGetType( KJSContext *, void *object )
{
const FormField *field = reinterpret_cast< FormField * >( object );
return KJSString( fieldGetTypeHelper( field ) );
}
// Field.value (getter)
static KJSObject fieldGetValue( KJSContext *context, void *object )
{
FormField *field = reinterpret_cast< FormField * >( object );
if ( field->isReadOnly() )
{
KJSObject value = g_fieldCache->value( field );
if ( g_fieldCache.exists() && g_fieldCache->contains( field ) )
value = g_fieldCache->value( field );
else
value = KJSString("");
kDebug(OkularDebug) << "Getting the value of a readonly field" << field->name() << ":" << value.toString( context );
return value;
}
switch ( field->type() )
{
case FormField::FormButton:
{
const FormFieldButton *button = static_cast< const FormFieldButton * >( field );
Q_UNUSED( button ); // ###
break;
}
case FormField::FormText:
{
const FormFieldText *text = static_cast< const FormFieldText * >( field );
return KJSString( text->text() );
}
case FormField::FormChoice:
{
const FormFieldChoice *choice = static_cast< const FormFieldChoice * >( field );
Q_UNUSED( choice ); // ###
break;
}
case FormField::FormSignature:
{
break;
}
}
return KJSUndefined();
}
// Field.value (setter)
static void fieldSetValue( KJSContext *context, void *object, KJSObject value )
{
FormField *field = reinterpret_cast< FormField * >( object );
if ( field->isReadOnly() )
{
// ### throw exception?
kDebug(OkularDebug) << "Trying to change the readonly field" << field->name() << "to" << value.toString( context );
g_fieldCache->insert( field, value );
return;
}
switch ( field->type() )
{
case FormField::FormButton:
{
FormFieldButton *button = static_cast< FormFieldButton * >( field );
Q_UNUSED( button ); // ###
break;
}
case FormField::FormText:
{
FormFieldText *text = static_cast< FormFieldText * >( field );
text->setText( value.toString( context ) );
break;
}
case FormField::FormChoice:
{
FormFieldChoice *choice = static_cast< FormFieldChoice * >( field );
Q_UNUSED( choice ); // ###
break;
}
case FormField::FormSignature:
{
break;
}
}
}
void JSField::initType( KJSContext *ctx )
{
static bool initialized = false;
if ( initialized )
return;
initialized = true;
if ( !g_fieldProto )
g_fieldProto = new KJSPrototype();
g_fieldProto->defineProperty( ctx, "doc", fieldGetDoc );
g_fieldProto->defineProperty( ctx, "name", fieldGetName );
g_fieldProto->defineProperty( ctx, "readonly",
fieldGetReadOnly, fieldSetReadOnly );
g_fieldProto->defineProperty( ctx, "type", fieldGetType );
g_fieldProto->defineProperty( ctx, "value", fieldGetValue, fieldSetValue );
}
KJSObject JSField::wrapField( KJSContext *ctx, FormField *field, Page *page )
{
// ### cache unique wrapper
KJSObject f = g_fieldProto->constructObject( ctx, field );
f.setProperty( ctx, "page", page->number() );
return f;
}
void JSField::clearCachedFields()
{
if ( g_fieldCache.exists() )
{
g_fieldCache->clear();
}
}

32
core/script/kjs_field_p.h Normal file
View file

@ -0,0 +1,32 @@
/***************************************************************************
* 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. *
***************************************************************************/
#ifndef OKULAR_SCRIPT_KJS_FIELD_P_H
#define OKULAR_SCRIPT_KJS_FIELD_P_H
class KJSContext;
class KJSObject;
namespace Okular {
class FormField;
class Page;
class JSField
{
public:
static void initType( KJSContext *ctx );
static KJSObject wrapField( KJSContext *ctx, FormField *field, Page *page );
static void clearCachedFields();
};
}
#endif

View file

@ -0,0 +1,78 @@
/***************************************************************************
* 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_fullscreen_p.h"
#include <assert.h>
#include <kjs/kjsobject.h>
#include <kjs/kjsprototype.h>
#include "settings.h"
using namespace Okular;
static KJSPrototype *g_fsProto;
static KJSObject fsGetLoop( KJSContext *, void * )
{
return KJSBoolean( Settings::slidesLoop() );
}
static void fsSetLoop( KJSContext *ctx, void *, KJSObject value )
{
bool loop = value.toBoolean( ctx );
Settings::setSlidesLoop( loop );
}
static KJSObject fsGetUseTimer( KJSContext *, void * )
{
return KJSBoolean( Settings::slidesAdvance() );
}
static void fsSetUseTimer( KJSContext *ctx, void *, KJSObject value )
{
bool use = value.toBoolean( ctx );
Settings::setSlidesAdvance( use );
}
static KJSObject fsGetTimeDelay( KJSContext *, void * )
{
return KJSNumber( Settings::slidesAdvanceTime() );
}
static void fsSetTimeDelay( KJSContext *ctx, void *, KJSObject value )
{
int time = static_cast<int>( value.toNumber( ctx ) );
Settings::setSlidesAdvanceTime( time );
}
void JSFullscreen::initType( KJSContext *ctx )
{
static bool initialized = false;
if ( initialized )
return;
initialized = true;
if ( !g_fsProto )
g_fsProto = new KJSPrototype();
g_fsProto->defineProperty( ctx, "loop", fsGetLoop, fsSetLoop );
g_fsProto->defineProperty( ctx, "useTimer",
fsGetUseTimer, fsSetUseTimer );
g_fsProto->defineProperty( ctx, "timeDelay",
fsGetTimeDelay, fsSetTimeDelay );
}
KJSObject JSFullscreen::object( KJSContext *ctx )
{
assert( g_fsProto );
return g_fsProto->constructObject( ctx );
}

View file

@ -0,0 +1,28 @@
/***************************************************************************
* 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. *
***************************************************************************/
#ifndef OKULAR_SCRIPT_KJS_FULLSCREEN_P_H
#define OKULAR_SCRIPT_KJS_FULLSCREEN_P_H
class KJSContext;
class KJSObject;
namespace Okular {
class JSFullscreen
{
public:
static void initType( KJSContext *ctx );
static KJSObject object( KJSContext *ctx );
};
}
#endif

42
core/script/kjs_spell.cpp Normal file
View file

@ -0,0 +1,42 @@
/***************************************************************************
* 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_spell_p.h"
#include <kjs/kjsobject.h>
#include <kjs/kjsprototype.h>
#include <QtCore/QString>
using namespace Okular;
static KJSPrototype *g_spellProto;
// Spell.available
static KJSObject spellGetAvailable( KJSContext *, void * )
{
return KJSBoolean( false );
}
void JSSpell::initType( KJSContext *ctx )
{
static bool initialized = false;
if ( initialized )
return;
initialized = true;
g_spellProto = new KJSPrototype();
g_spellProto->defineProperty( ctx, QString( "available" ), spellGetAvailable );
}
KJSObject JSSpell::object( KJSContext *ctx )
{
return g_spellProto->constructObject( ctx, 0 );
}

28
core/script/kjs_spell_p.h Normal file
View file

@ -0,0 +1,28 @@
/***************************************************************************
* 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. *
***************************************************************************/
#ifndef OKULAR_SCRIPT_KJS_SPELL_P_H
#define OKULAR_SCRIPT_KJS_SPELL_P_H
class KJSContext;
class KJSObject;
namespace Okular {
class JSSpell
{
public:
static void initType( KJSContext *ctx );
static KJSObject object( KJSContext *ctx );
};
}
#endif

74
core/script/kjs_util.cpp Normal file
View file

@ -0,0 +1,74 @@
/***************************************************************************
* 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_util_p.h"
#include <kjs/kjsobject.h>
#include <kjs/kjsprototype.h>
#include <kjs/kjsarguments.h>
#include <kurl.h>
using namespace Okular;
static KJSPrototype *g_utilProto;
static KJSObject crackURL( KJSContext *context, void *,
const KJSArguments &arguments )
{
if ( arguments.count() < 1 )
{
return context->throwException( "Missing URL argument" );
}
QString cURL = arguments.at( 0 ).toString( context );
KUrl url( cURL );
if ( !url.isValid() )
{
return context->throwException( "Invalid URL" );
}
if ( url.protocol() != QLatin1String( "file" )
|| url.protocol() != QLatin1String( "http" )
|| url.protocol() != QLatin1String( "https" ) )
{
return context->throwException( "Protocol not valid: '" + url.protocol() + '\'' );
}
KJSObject obj;
obj.setProperty( context, "cScheme", url.protocol() );
if ( url.hasUser() )
obj.setProperty( context, "cUser", url.user() );
if ( url.hasPass() )
obj.setProperty( context, "cPassword", url.password() );
obj.setProperty( context, "cHost", url.host() );
obj.setProperty( context, "nPort", url.port( 80 ) );
// TODO cPath (Optional) The path portion of the URL.
// TODO cParameters (Optional) The parameter string portion of the URL.
if ( url.hasRef() )
obj.setProperty( context, "cFragments", url.ref() );
return obj;
}
void JSUtil::initType( KJSContext *ctx )
{
static bool initialized = false;
if ( initialized )
return;
initialized = true;
g_utilProto = new KJSPrototype();
g_utilProto->defineFunction( ctx, "crackURL", crackURL );
}
KJSObject JSUtil::object( KJSContext *ctx )
{
return g_utilProto->constructObject( ctx, 0 );
}

28
core/script/kjs_util_p.h Normal file
View file

@ -0,0 +1,28 @@
/***************************************************************************
* 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. *
***************************************************************************/
#ifndef OKULAR_SCRIPT_KJS_UTIL_P_H
#define OKULAR_SCRIPT_KJS_UTIL_P_H
class KJSContext;
class KJSObject;
namespace Okular {
class JSUtil
{
public:
static void initType( KJSContext *ctx );
static KJSObject object( KJSContext *ctx );
};
}
#endif

View file

@ -12,6 +12,7 @@
#include <kdebug.h>
#include "debug_p.h"
#include "script/executor_kjs_p.h"
using namespace Okular;
@ -19,15 +20,17 @@ class Okular::ScripterPrivate
{
public:
ScripterPrivate( DocumentPrivate *doc )
: m_doc( doc )
: m_doc( doc ), m_kjs( 0 )
{
}
~ScripterPrivate()
{
delete m_kjs;
}
DocumentPrivate *m_doc;
ExecutorKJS *m_kjs;
};
Scripter::Scripter( DocumentPrivate *doc )
@ -52,6 +55,11 @@ QString Scripter::execute( ScriptType type, const QString &script )
switch ( type )
{
case JavaScript:
if ( !d->m_kjs )
{
d->m_kjs = new ExecutorKJS( d->m_doc );
}
d->m_kjs->execute( script );
break;
}
return QString();