mirror of
https://invent.kde.org/graphics/okular
synced 2024-08-24 18:35:37 +00:00
![Albert Astals Cid](/assets/img/avatar_default.png)
find . \( -name "*.cpp" -or -name "*.h" -or -name "*.c" -or -name "*.cc" \) -exec clang-format -i {} \; If you reached this file doing a git blame, please see README.clang-format (added 2 commits in the future of this one)
320 lines
9.9 KiB
C++
320 lines
9.9 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_field_p.h"
|
|
|
|
#include <kjs/kjsarguments.h>
|
|
#include <kjs/kjsinterpreter.h>
|
|
#include <kjs/kjsprototype.h>
|
|
|
|
#include <QHash>
|
|
|
|
#include <QDebug>
|
|
#include <QTimer>
|
|
|
|
#include "../debug_p.h"
|
|
#include "../document_p.h"
|
|
#include "../form.h"
|
|
#include "../page.h"
|
|
#include "../page_p.h"
|
|
#include "kjs_display_p.h"
|
|
|
|
using namespace Okular;
|
|
|
|
#define OKULAR_NAME QStringLiteral("okular_name")
|
|
|
|
static KJSPrototype *g_fieldProto;
|
|
|
|
typedef QHash<FormField *, Page *> FormCache;
|
|
Q_GLOBAL_STATIC(FormCache, g_fieldCache)
|
|
typedef QHash<QString, FormField *> ButtonCache;
|
|
Q_GLOBAL_STATIC(ButtonCache, g_buttonCache)
|
|
|
|
// Helper for modified fields
|
|
static void updateField(FormField *field)
|
|
{
|
|
Page *page = g_fieldCache->value(field);
|
|
if (page) {
|
|
Document *doc = PagePrivate::get(page)->m_doc->m_parent;
|
|
const int pageNumber = page->number();
|
|
QTimer::singleShot(0, doc, [doc, pageNumber] { doc->refreshPixmaps(pageNumber); });
|
|
emit doc->refreshFormWidget(field);
|
|
} else {
|
|
qWarning() << "Could not get page of field" << field;
|
|
}
|
|
}
|
|
|
|
// 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->fullyQualifiedName());
|
|
}
|
|
|
|
// 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)
|
|
{
|
|
FormField *field = reinterpret_cast<FormField *>(object);
|
|
bool b = value.toBoolean(context);
|
|
field->setReadOnly(b);
|
|
|
|
updateField(field);
|
|
}
|
|
|
|
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 QStringLiteral("button");
|
|
case FormFieldButton::CheckBox:
|
|
return QStringLiteral("checkbox");
|
|
case FormFieldButton::Radio:
|
|
return QStringLiteral("radiobutton");
|
|
}
|
|
break;
|
|
}
|
|
case FormField::FormText:
|
|
return QStringLiteral("text");
|
|
case FormField::FormChoice: {
|
|
const FormFieldChoice *choice = static_cast<const FormFieldChoice *>(field);
|
|
switch (choice->choiceType()) {
|
|
case FormFieldChoice::ComboBox:
|
|
return QStringLiteral("combobox");
|
|
case FormFieldChoice::ListBox:
|
|
return QStringLiteral("listbox");
|
|
}
|
|
break;
|
|
}
|
|
case FormField::FormSignature:
|
|
return QStringLiteral("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);
|
|
|
|
switch (field->type()) {
|
|
case FormField::FormButton: {
|
|
const FormFieldButton *button = static_cast<const FormFieldButton *>(field);
|
|
if (button->state()) {
|
|
return KJSString(QStringLiteral("Yes"));
|
|
}
|
|
return KJSString(QStringLiteral("Off"));
|
|
}
|
|
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);
|
|
const QList<int> currentChoices = choice->currentChoices();
|
|
if (currentChoices.count() == 1) {
|
|
return KJSString(choice->exportValueForChoice(choice->choices().at(currentChoices[0])));
|
|
}
|
|
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);
|
|
|
|
switch (field->type()) {
|
|
case FormField::FormButton: {
|
|
FormFieldButton *button = static_cast<FormFieldButton *>(field);
|
|
const QString text = value.toString(context);
|
|
if (text == QStringLiteral("Yes")) {
|
|
button->setState(true);
|
|
updateField(field);
|
|
} else if (text == QStringLiteral("Off")) {
|
|
button->setState(false);
|
|
updateField(field);
|
|
}
|
|
break;
|
|
}
|
|
case FormField::FormText: {
|
|
FormFieldText *textField = static_cast<FormFieldText *>(field);
|
|
const QString text = value.toString(context);
|
|
if (text != textField->text()) {
|
|
textField->setText(text);
|
|
updateField(field);
|
|
}
|
|
break;
|
|
}
|
|
case FormField::FormChoice: {
|
|
FormFieldChoice *choice = static_cast<FormFieldChoice *>(field);
|
|
Q_UNUSED(choice); // ###
|
|
break;
|
|
}
|
|
case FormField::FormSignature: {
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Field.hidden (getter)
|
|
static KJSObject fieldGetHidden(KJSContext *, void *object)
|
|
{
|
|
const FormField *field = reinterpret_cast<FormField *>(object);
|
|
return KJSBoolean(!field->isVisible());
|
|
}
|
|
|
|
// Field.hidden (setter)
|
|
static void fieldSetHidden(KJSContext *context, void *object, KJSObject value)
|
|
{
|
|
FormField *field = reinterpret_cast<FormField *>(object);
|
|
bool b = value.toBoolean(context);
|
|
field->setVisible(!b);
|
|
|
|
updateField(field);
|
|
}
|
|
|
|
// Field.display (getter)
|
|
static KJSObject fieldGetDisplay(KJSContext *, void *object)
|
|
{
|
|
const FormField *field = reinterpret_cast<FormField *>(object);
|
|
bool visible = field->isVisible();
|
|
if (visible) {
|
|
return KJSNumber(field->isPrintable() ? FormDisplay::FormVisible : FormDisplay::FormNoPrint);
|
|
}
|
|
return KJSNumber(field->isPrintable() ? FormDisplay::FormNoView : FormDisplay::FormHidden);
|
|
}
|
|
|
|
// Field.display (setter)
|
|
static void fieldSetDisplay(KJSContext *context, void *object, KJSObject value)
|
|
{
|
|
FormField *field = reinterpret_cast<FormField *>(object);
|
|
const unsigned int b = value.toInt32(context);
|
|
switch (b) {
|
|
case FormDisplay::FormVisible:
|
|
field->setVisible(true);
|
|
field->setPrintable(true);
|
|
break;
|
|
case FormDisplay::FormHidden:
|
|
field->setVisible(false);
|
|
field->setPrintable(false);
|
|
break;
|
|
case FormDisplay::FormNoPrint:
|
|
field->setVisible(true);
|
|
field->setPrintable(false);
|
|
break;
|
|
case FormDisplay::FormNoView:
|
|
field->setVisible(false);
|
|
field->setPrintable(true);
|
|
break;
|
|
}
|
|
updateField(field);
|
|
}
|
|
|
|
// Instead of getting the Icon, we pick the field.
|
|
static KJSObject fieldButtonGetIcon(KJSContext *ctx, void *object, const KJSArguments &)
|
|
{
|
|
FormField *field = reinterpret_cast<FormField *>(object);
|
|
|
|
KJSObject fieldObject;
|
|
fieldObject.setProperty(ctx, OKULAR_NAME, field->fullyQualifiedName());
|
|
g_buttonCache->insert(field->fullyQualifiedName(), field);
|
|
|
|
return fieldObject;
|
|
}
|
|
|
|
/*
|
|
* Now we send to the button what Icon should be drawn on it
|
|
*/
|
|
static KJSObject fieldButtonSetIcon(KJSContext *ctx, void *object, const KJSArguments &arguments)
|
|
{
|
|
FormField *field = reinterpret_cast<FormField *>(object);
|
|
|
|
const QString fieldName = arguments.at(0).property(ctx, OKULAR_NAME).toString(ctx);
|
|
|
|
if (field->type() == Okular::FormField::FormButton) {
|
|
FormFieldButton *button = static_cast<FormFieldButton *>(field);
|
|
button->setIcon(g_buttonCache->value(fieldName));
|
|
}
|
|
|
|
updateField(field);
|
|
|
|
return KJSUndefined();
|
|
}
|
|
|
|
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, QStringLiteral("doc"), fieldGetDoc);
|
|
g_fieldProto->defineProperty(ctx, QStringLiteral("name"), fieldGetName);
|
|
g_fieldProto->defineProperty(ctx, QStringLiteral("readonly"), fieldGetReadOnly, fieldSetReadOnly);
|
|
g_fieldProto->defineProperty(ctx, QStringLiteral("type"), fieldGetType);
|
|
g_fieldProto->defineProperty(ctx, QStringLiteral("value"), fieldGetValue, fieldSetValue);
|
|
g_fieldProto->defineProperty(ctx, QStringLiteral("hidden"), fieldGetHidden, fieldSetHidden);
|
|
g_fieldProto->defineProperty(ctx, QStringLiteral("display"), fieldGetDisplay, fieldSetDisplay);
|
|
|
|
g_fieldProto->defineFunction(ctx, QStringLiteral("buttonGetIcon"), fieldButtonGetIcon);
|
|
g_fieldProto->defineFunction(ctx, QStringLiteral("buttonSetIcon"), fieldButtonSetIcon);
|
|
}
|
|
|
|
KJSObject JSField::wrapField(KJSContext *ctx, FormField *field, Page *page)
|
|
{
|
|
// ### cache unique wrapper
|
|
KJSObject f = g_fieldProto->constructObject(ctx, field);
|
|
f.setProperty(ctx, QStringLiteral("page"), page->number());
|
|
g_fieldCache->insert(field, page);
|
|
return f;
|
|
}
|
|
|
|
void JSField::clearCachedFields()
|
|
{
|
|
if (g_fieldCache.exists())
|
|
g_fieldCache->clear();
|
|
|
|
if (g_buttonCache.exists())
|
|
g_buttonCache->clear();
|
|
}
|