| /* poppler-form.h: qt4 interface to poppler |
| * Copyright (C) 2007, 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, or (at your option) |
| * any later version. |
| * |
| * This program is distributed in the hope that it will be useful, |
| * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| * GNU General Public License for more details. |
| * |
| * You should have received a copy of the GNU General Public License |
| * along with this program; if not, write to the Free Software |
| * Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. |
| */ |
| |
| #include "poppler-qt4.h" |
| |
| #include <QtCore/QSizeF> |
| |
| #include <Form.h> |
| #include <Object.h> |
| |
| #include "poppler-form.h" |
| #include "poppler-private.h" |
| #include "poppler-annotation-helper.h" |
| |
| #include <math.h> |
| |
| namespace Poppler { |
| |
| FormField::FormField(FormFieldData &dd) |
| : m_formData(&dd) |
| { |
| // reading the coords |
| double left, top, right, bottom; |
| m_formData->fm->getRect(&left, &bottom, &right, &top); |
| // build a normalized transform matrix for this page at 100% scale |
| GfxState gfxState( 72.0, 72.0, m_formData->page->getMediaBox(), m_formData->page->getRotate(), gTrue ); |
| double * gfxCTM = gfxState.getCTM(); |
| double MTX[6]; |
| for ( int i = 0; i < 6; i+=2 ) |
| { |
| MTX[i] = gfxCTM[i] / m_formData->page->getCropWidth(); |
| MTX[i+1] = gfxCTM[i+1] / m_formData->page->getCropHeight(); |
| } |
| QPointF topLeft; |
| XPDFReader::transform( MTX, qMin( left, right ), qMax( top, bottom ), topLeft ); |
| QPointF bottomRight; |
| XPDFReader::transform( MTX, qMax( left, right ), qMin( top, bottom ), bottomRight ); |
| m_formData->box = QRectF(topLeft, QSizeF(bottomRight.x() - topLeft.x(), bottomRight.y() - topLeft.y())); |
| |
| Object *obj = m_formData->fm->getObj(); |
| Object tmp; |
| |
| // reading the flags |
| if (obj->isDict() && obj->dictLookup("Ff", &tmp)->isInt()) |
| { |
| m_formData->flags = tmp.getInt(); |
| } |
| tmp.free(); |
| // reading the widget annotation flags |
| if (obj->isDict() && obj->dictLookup("F", &tmp)->isInt()) |
| { |
| m_formData->annoflags = tmp.getInt(); |
| } |
| tmp.free(); |
| } |
| |
| FormField::~FormField() |
| { |
| delete m_formData; |
| m_formData = 0; |
| } |
| |
| QRectF FormField::rect() const |
| { |
| return m_formData->box; |
| } |
| |
| int FormField::id() const |
| { |
| return m_formData->fm->getID(); |
| } |
| |
| QString FormField::name() const |
| { |
| Object tmp; |
| Object *obj = m_formData->fm->getObj(); |
| QString name; |
| if (obj->dictLookup("T", &tmp)->isString()) |
| { |
| GooString *goo = tmp.getString(); |
| if (goo) |
| name = goo->getCString(); |
| } |
| tmp.free(); |
| return name; |
| } |
| |
| QString FormField::uiName() const |
| { |
| Object tmp; |
| Object *obj = m_formData->fm->getObj(); |
| QString name; |
| if (obj->dictLookup("TU", &tmp)->isString()) |
| { |
| GooString *goo = tmp.getString(); |
| if (goo) |
| name = goo->getCString(); |
| } |
| tmp.free(); |
| return name; |
| } |
| |
| bool FormField::isReadOnly() const |
| { |
| return m_formData->fm->isReadOnly(); |
| } |
| |
| bool FormField::isVisible() const |
| { |
| return !(m_formData->annoflags & (1 << 1)); |
| } |
| |
| |
| FormFieldButton::FormFieldButton(DocumentData *doc, ::Page *p, ::FormWidgetButton *w) |
| : FormField(*new FormFieldData(doc, p, w)) |
| { |
| } |
| |
| FormFieldButton::~FormFieldButton() |
| { |
| } |
| |
| FormFieldButton::FormType FormFieldButton::type() const |
| { |
| return FormField::FormButton; |
| } |
| |
| FormFieldButton::ButtonType FormFieldButton::buttonType() const |
| { |
| FormWidgetButton* fwb = static_cast<FormWidgetButton*>(m_formData->fm); |
| switch (fwb->getButtonType()) |
| { |
| case formButtonCheck: |
| return FormFieldButton::CheckBox; |
| break; |
| case formButtonPush: |
| return FormFieldButton::Push; |
| break; |
| case formButtonRadio: |
| return FormFieldButton::Radio; |
| break; |
| } |
| return FormFieldButton::CheckBox; |
| } |
| |
| QString FormFieldButton::caption() const |
| { |
| FormWidgetButton* fwb = static_cast<FormWidgetButton*>(m_formData->fm); |
| // HACK push buttons seems to have a null GooString for the caption |
| if (fwb->getButtonType() == formButtonPush) |
| return QString(); |
| |
| return fwb->getOnStr() ? QString::fromUtf8(fwb->getOnStr()) : QString(); |
| } |
| |
| bool FormFieldButton::state() const |
| { |
| FormWidgetButton* fwb = static_cast<FormWidgetButton*>(m_formData->fm); |
| return fwb->getState(); |
| } |
| |
| void FormFieldButton::setState( bool state ) |
| { |
| FormWidgetButton* fwb = static_cast<FormWidgetButton*>(m_formData->fm); |
| fwb->setState((GBool)state); |
| } |
| |
| QList<int> FormFieldButton::siblings() const |
| { |
| FormWidgetButton* fwb = static_cast<FormWidgetButton*>(m_formData->fm); |
| if (fwb->getButtonType() == formButtonPush) |
| return QList<int>(); |
| |
| QList<int> ret; |
| unsigned *sibls = fwb->getSiblingsID(); |
| for (int i = 0; i < fwb->getNumSiblingsID(); ++i) |
| ret.append(sibls[i]); |
| |
| return ret; |
| } |
| |
| |
| FormFieldText::FormFieldText(DocumentData *doc, ::Page *p, ::FormWidgetText *w) |
| : FormField(*new FormFieldData(doc, p, w)) |
| { |
| } |
| |
| FormFieldText::~FormFieldText() |
| { |
| } |
| |
| FormField::FormType FormFieldText::type() const |
| { |
| return FormField::FormText; |
| } |
| |
| FormFieldText::TextType FormFieldText::textType() const |
| { |
| FormWidgetText* fwt = static_cast<FormWidgetText*>(m_formData->fm); |
| if (fwt->isFileSelect()) |
| return FormFieldText::FileSelect; |
| else if (fwt->isMultiline()) |
| return FormFieldText::Multiline; |
| return FormFieldText::Normal; |
| } |
| |
| QString FormFieldText::text() const |
| { |
| GooString *goo = static_cast<FormWidgetText*>(m_formData->fm)->getContent(); |
| return UnicodeParsedString(goo); |
| } |
| |
| void FormFieldText::setText( const QString& text ) |
| { |
| FormWidgetText* fwt = static_cast<FormWidgetText*>(m_formData->fm); |
| GooString * goo = QStringToUnicodeGooString( text ); |
| fwt->setContent( goo ); |
| } |
| |
| bool FormFieldText::isPassword() const |
| { |
| FormWidgetText* fwt = static_cast<FormWidgetText*>(m_formData->fm); |
| return fwt->isPassword(); |
| } |
| |
| bool FormFieldText::isRichText() const |
| { |
| FormWidgetText* fwt = static_cast<FormWidgetText*>(m_formData->fm); |
| return fwt->isRichText(); |
| } |
| |
| int FormFieldText::maximumLength() const |
| { |
| FormWidgetText* fwt = static_cast<FormWidgetText*>(m_formData->fm); |
| const int maxlen = fwt->getMaxLen(); |
| return maxlen > 0 ? maxlen : -1; |
| } |
| |
| Qt::Alignment FormFieldText::textAlignment() const |
| { |
| return m_formData->textAlignment(m_formData->fm->getObj()); |
| } |
| |
| bool FormFieldText::canBeSpellChecked() const |
| { |
| FormWidgetText* fwt = static_cast<FormWidgetText*>(m_formData->fm); |
| return !fwt->noSpellCheck(); |
| } |
| |
| |
| FormFieldChoice::FormFieldChoice(DocumentData *doc, ::Page *p, ::FormWidgetChoice *w) |
| : FormField(*new FormFieldData(doc, p, w)) |
| { |
| } |
| |
| FormFieldChoice::~FormFieldChoice() |
| { |
| } |
| |
| FormFieldChoice::FormType FormFieldChoice::type() const |
| { |
| return FormField::FormChoice; |
| } |
| |
| FormFieldChoice::ChoiceType FormFieldChoice::choiceType() const |
| { |
| FormWidgetChoice* fwc = static_cast<FormWidgetChoice*>(m_formData->fm); |
| if (fwc->isCombo()) |
| return FormFieldChoice::ComboBox; |
| return FormFieldChoice::ListBox; |
| } |
| |
| QStringList FormFieldChoice::choices() const |
| { |
| FormWidgetChoice* fwc = static_cast<FormWidgetChoice*>(m_formData->fm); |
| QStringList ret; |
| int num = fwc->getNumChoices(); |
| for (int i = 0; i < num; ++i) |
| { |
| ret.append(UnicodeParsedString(fwc->getChoice(i))); |
| } |
| return ret; |
| } |
| |
| bool FormFieldChoice::isEditable() const |
| { |
| FormWidgetChoice* fwc = static_cast<FormWidgetChoice*>(m_formData->fm); |
| return fwc->isCombo() ? fwc->hasEdit() : false; |
| } |
| |
| bool FormFieldChoice::multiSelect() const |
| { |
| // return m_formData->flags & (1 << 21); |
| FormWidgetChoice* fwc = static_cast<FormWidgetChoice*>(m_formData->fm); |
| return !fwc->isCombo() ? fwc->isMultiSelect() : false; |
| } |
| |
| QList<int> FormFieldChoice::currentChoices() const |
| { |
| FormWidgetChoice* fwc = static_cast<FormWidgetChoice*>(m_formData->fm); |
| int num = fwc->getNumChoices(); |
| QList<int> choices; |
| for ( int i = 0; i < num; ++i ) |
| if ( fwc->isSelected( i ) ) |
| choices.append( i ); |
| return choices; |
| } |
| |
| void FormFieldChoice::setCurrentChoices( const QList<int> &choice ) |
| { |
| FormWidgetChoice* fwc = static_cast<FormWidgetChoice*>(m_formData->fm); |
| fwc->deselectAll(); |
| for ( int i = 0; i < choice.count(); ++i ) |
| fwc->select( choice.at( i ) ); |
| } |
| |
| Qt::Alignment FormFieldChoice::textAlignment() const |
| { |
| return m_formData->textAlignment(m_formData->fm->getObj()); |
| } |
| |
| bool FormFieldChoice::canBeSpellChecked() const |
| { |
| FormWidgetChoice* fwc = static_cast<FormWidgetChoice*>(m_formData->fm); |
| return !fwc->noSpellCheck(); |
| } |
| |
| } |