/* poppler-form-field.cc: glib interface to poppler * * Copyright (C) 2007 Carlos Garcia Campos * Copyright (C) 2006 Julien Rebetez * * 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.h" #include "poppler-private.h" /** * SECTION:poppler-form-field * @short_description: Form Field * @title: PopplerFormField */ typedef struct _PopplerFormFieldClass PopplerFormFieldClass; struct _PopplerFormFieldClass { GObjectClass parent_class; }; G_DEFINE_TYPE (PopplerFormField, poppler_form_field, G_TYPE_OBJECT) static void poppler_form_field_finalize (GObject *object) { PopplerFormField *field = POPPLER_FORM_FIELD (object); if (field->document) { g_object_unref (field->document); field->document = nullptr; } if (field->action) { poppler_action_free (field->action); field->action = nullptr; } field->widget = nullptr; G_OBJECT_CLASS (poppler_form_field_parent_class)->finalize (object); } static void poppler_form_field_init (PopplerFormField *field) { } static void poppler_form_field_class_init (PopplerFormFieldClass *klass) { GObjectClass *gobject_class = G_OBJECT_CLASS (klass); gobject_class->finalize = poppler_form_field_finalize; } PopplerFormField * _poppler_form_field_new (PopplerDocument *document, FormWidget *field) { PopplerFormField *poppler_field; g_return_val_if_fail (POPPLER_IS_DOCUMENT (document), NULL); g_return_val_if_fail (field != nullptr, NULL); poppler_field = POPPLER_FORM_FIELD (g_object_new (POPPLER_TYPE_FORM_FIELD, nullptr)); poppler_field->document = (PopplerDocument *)g_object_ref (document); poppler_field->widget = field; return poppler_field; } /* Public methods */ /** * poppler_form_field_get_field_type: * @field: a #PopplerFormField * * Gets the type of @field * * Return value: #PopplerFormFieldType of @field **/ PopplerFormFieldType poppler_form_field_get_field_type (PopplerFormField *field) { g_return_val_if_fail (POPPLER_IS_FORM_FIELD (field), POPPLER_FORM_FIELD_UNKNOWN); switch (field->widget->getType ()) { case formButton: return POPPLER_FORM_FIELD_BUTTON; case formText: return POPPLER_FORM_FIELD_TEXT; case formChoice: return POPPLER_FORM_FIELD_CHOICE; case formSignature: return POPPLER_FORM_FIELD_SIGNATURE; default: g_warning ("Unsupported Form Field Type"); } return POPPLER_FORM_FIELD_UNKNOWN; } /** * poppler_form_field_get_id: * @field: a #PopplerFormField * * Gets the id of @field * * Return value: the id of @field **/ gint poppler_form_field_get_id (PopplerFormField *field) { g_return_val_if_fail (POPPLER_IS_FORM_FIELD (field), -1); return field->widget->getID (); } /** * poppler_form_field_get_font_size: * @field: a #PopplerFormField * * Gets the font size of @field * * WARNING: This function always returns 0. Contact the poppler * mailing list if you're interested in implementing it properly * * Return value: the font size of @field **/ gdouble poppler_form_field_get_font_size (PopplerFormField *field) { g_return_val_if_fail (POPPLER_IS_FORM_FIELD (field), 0); return 0; } /** * poppler_form_field_is_read_only: * @field: a #PopplerFormField * * Checks whether @field is read only * * Return value: %TRUE if @field is read only **/ gboolean poppler_form_field_is_read_only (PopplerFormField *field) { g_return_val_if_fail (POPPLER_IS_FORM_FIELD (field), FALSE); return field->widget->isReadOnly (); } /** * poppler_form_field_get_action: * @field: a #PopplerFormField * * Retrieves the action (#PopplerAction) that shall be * performed when @field is activated, or %NULL * * Return value: (transfer none): the action to perform. The returned * object is owned by @field and should not be freed * * Since: 0.18 */ PopplerAction * poppler_form_field_get_action (PopplerFormField *field) { LinkAction *action; if (field->action) return field->action; action = field->widget->getActivationAction(); if (!action) return nullptr; field->action = _poppler_action_new (field->document, action, nullptr); return field->action; } /** * poppler_form_field_get_additional_action: * @field: a #PopplerFormField * @type: the type of additional action * * Retrieves the action (#PopplerAction) that shall be performed when * an additional action is triggered on @field, or %NULL. * * Return value: (transfer none): the action to perform. The returned * object is owned by @field and should not be freed. * * * Since: 0.72 */ PopplerAction * poppler_form_field_get_additional_action (PopplerFormField *field, PopplerAdditionalActionType type) { Annot::FormAdditionalActionsType form_action; LinkAction *link_action; PopplerAction **action; switch (type) { case POPPLER_ADDITIONAL_ACTION_FIELD_MODIFIED: form_action = Annot::actionFieldModified; action = &field->field_modified_action; break; case POPPLER_ADDITIONAL_ACTION_FORMAT_FIELD: form_action = Annot::actionFormatField; action = &field->format_field_action; break; case POPPLER_ADDITIONAL_ACTION_VALIDATE_FIELD: form_action = Annot::actionValidateField; action = &field->validate_field_action; break; case POPPLER_ADDITIONAL_ACTION_CALCULATE_FIELD: form_action = Annot::actionCalculateField; action = &field->calculate_field_action; break; default: g_return_val_if_reached (nullptr); return nullptr; } if (*action) return *action; link_action = field->widget->getAdditionalAction (form_action); if (!link_action) return nullptr; *action = _poppler_action_new (nullptr, link_action, nullptr); return *action; } /* Button Field */ /** * poppler_form_field_button_get_button_type: * @field: a #PopplerFormField * * Gets the button type of @field * * Return value: #PopplerFormButtonType of @field **/ PopplerFormButtonType poppler_form_field_button_get_button_type (PopplerFormField *field) { g_return_val_if_fail (field->widget->getType () == formButton, POPPLER_FORM_BUTTON_PUSH); switch (static_cast(field->widget)->getButtonType ()) { case formButtonPush: return POPPLER_FORM_BUTTON_PUSH; case formButtonCheck: return POPPLER_FORM_BUTTON_CHECK; case formButtonRadio: return POPPLER_FORM_BUTTON_RADIO; default: g_assert_not_reached (); } } /** * poppler_form_field_button_get_state: * @field: a #PopplerFormField * * Queries a #PopplerFormField and returns its current state. Returns %TRUE if * @field is pressed in and %FALSE if it is raised. * * Return value: current state of @field **/ gboolean poppler_form_field_button_get_state (PopplerFormField *field) { g_return_val_if_fail (field->widget->getType () == formButton, FALSE); return static_cast(field->widget)->getState (); } /** * poppler_form_field_button_set_state: * @field: a #PopplerFormField * @state: %TRUE or %FALSE * * Sets the status of @field. Set to %TRUE if you want the #PopplerFormField * to be 'pressed in', and %FALSE to raise it. **/ void poppler_form_field_button_set_state (PopplerFormField *field, gboolean state) { g_return_if_fail (field->widget->getType () == formButton); static_cast(field->widget)->setState ((bool)state); } /** * poppler_form_field_get_partial_name: * @field: a #PopplerFormField * * Gets the partial name of @field. * * Return value: a new allocated string. It must be freed with g_free() when done. * * Since: 0.16 **/ gchar* poppler_form_field_get_partial_name (PopplerFormField *field) { const GooString *tmp; g_return_val_if_fail (POPPLER_IS_FORM_FIELD (field), NULL); tmp = field->widget->getPartialName(); return tmp ? _poppler_goo_string_to_utf8 (tmp) : nullptr; } /** * poppler_form_field_get_mapping_name: * @field: a #PopplerFormField * * Gets the mapping name of @field that is used when * exporting interactive form field data from the document * * Return value: a new allocated string. It must be freed with g_free() when done. * * Since: 0.16 **/ gchar* poppler_form_field_get_mapping_name (PopplerFormField *field) { const GooString *tmp; g_return_val_if_fail (POPPLER_IS_FORM_FIELD (field), NULL); tmp = field->widget->getMappingName(); return tmp ? _poppler_goo_string_to_utf8 (tmp) : nullptr; } /** * poppler_form_field_get_name: * @field: a #PopplerFormField * * Gets the fully qualified name of @field. It's constructed by concatenating * the partial field names of the field and all of its ancestors. * * Return value: a new allocated string. It must be freed with g_free() when done. * * Since: 0.16 **/ gchar* poppler_form_field_get_name (PopplerFormField *field) { GooString *tmp; g_return_val_if_fail (POPPLER_IS_FORM_FIELD (field), NULL); tmp = field->widget->getFullyQualifiedName(); return tmp ? _poppler_goo_string_to_utf8 (tmp) : nullptr; } /* Text Field */ /** * poppler_form_field_text_get_text_type: * @field: a #PopplerFormField * * Gets the text type of @field. * * Return value: #PopplerFormTextType of @field **/ PopplerFormTextType poppler_form_field_text_get_text_type (PopplerFormField *field) { FormWidgetText *text_field; g_return_val_if_fail (field->widget->getType () == formText, POPPLER_FORM_TEXT_NORMAL); text_field = static_cast(field->widget); if (text_field->isMultiline ()) return POPPLER_FORM_TEXT_MULTILINE; else if (text_field->isFileSelect ()) return POPPLER_FORM_TEXT_FILE_SELECT; return POPPLER_FORM_TEXT_NORMAL; } /** * poppler_form_field_text_get_text: * @field: a #PopplerFormField * * Retrieves the contents of @field. * * Return value: a new allocated string. It must be freed with g_free() when done. **/ gchar * poppler_form_field_text_get_text (PopplerFormField *field) { FormWidgetText *text_field; const GooString *tmp; g_return_val_if_fail (field->widget->getType () == formText, NULL); text_field = static_cast(field->widget); tmp = text_field->getContent (); return tmp ? _poppler_goo_string_to_utf8 (tmp) : nullptr; } /** * poppler_form_field_text_set_text: * @field: a #PopplerFormField * @text: the new text * * Sets the text in @field to the given value, replacing the current contents. **/ void poppler_form_field_text_set_text (PopplerFormField *field, const gchar *text) { GooString *goo_tmp; gchar *tmp; gsize length = 0; g_return_if_fail (field->widget->getType () == formText); tmp = text ? g_convert (text, -1, "UTF-16BE", "UTF-8", nullptr, &length, nullptr) : nullptr; goo_tmp = new GooString (tmp, length); g_free (tmp); static_cast(field->widget)->setContent (goo_tmp); delete goo_tmp; } /** * poppler_form_field_text_get_max_len: * @field: a #PopplerFormField * * Retrieves the maximum allowed length of the text in @field * * Return value: the maximum allowed number of characters in @field, or -1 if there is no maximum. **/ gint poppler_form_field_text_get_max_len (PopplerFormField *field) { g_return_val_if_fail (field->widget->getType () == formText, 0); return static_cast(field->widget)->getMaxLen (); } /** * poppler_form_field_text_do_spell_check: * @field: a #PopplerFormField * * Checks whether spell checking should be done for the contents of @field * * Return value: %TRUE if spell checking should be done for @field **/ gboolean poppler_form_field_text_do_spell_check (PopplerFormField *field) { g_return_val_if_fail (field->widget->getType () == formText, FALSE); return !static_cast(field->widget)->noSpellCheck (); } gboolean poppler_form_field_text_do_scroll (PopplerFormField *field) { g_return_val_if_fail (field->widget->getType () == formText, FALSE); return !static_cast(field->widget)->noScroll (); } /** * poppler_form_field_text_is_rich_text: * @field: a #PopplerFormField * * Checks whether the contents of @field are rich text * * Return value: %TRUE if the contents of @field are rich text **/ gboolean poppler_form_field_text_is_rich_text (PopplerFormField *field) { g_return_val_if_fail (field->widget->getType () == formText, FALSE); return static_cast(field->widget)->isRichText (); } /** * poppler_form_field_text_is_password: * @field: a #PopplerFormField * * Checks whether content of @field is a password and it must be hidden * * Return value: %TRUE if the content of @field is a password **/ gboolean poppler_form_field_text_is_password (PopplerFormField *field) { g_return_val_if_fail (field->widget->getType () == formText, FALSE); return static_cast(field->widget)->isPassword (); } /* Choice Field */ /** * poppler_form_field_choice_get_choice_type: * @field: a #PopplerFormField * * Gets the choice type of @field * * Return value: #PopplerFormChoiceType of @field **/ PopplerFormChoiceType poppler_form_field_choice_get_choice_type (PopplerFormField *field) { g_return_val_if_fail (field->widget->getType () == formChoice, POPPLER_FORM_CHOICE_COMBO); if (static_cast(field->widget)->isCombo ()) return POPPLER_FORM_CHOICE_COMBO; else return POPPLER_FORM_CHOICE_LIST; } /** * poppler_form_field_choice_is_editable: * @field: a #PopplerFormField * * Checks whether @field is editable * * Return value: %TRUE if @field is editable **/ gboolean poppler_form_field_choice_is_editable (PopplerFormField *field) { g_return_val_if_fail (field->widget->getType () == formChoice, FALSE); return static_cast(field->widget)->hasEdit (); } /** * poppler_form_field_choice_can_select_multiple: * @field: a #PopplerFormField * * Checks whether @field allows multiple choices to be selected * * Return value: %TRUE if @field allows multiple choices to be selected **/ gboolean poppler_form_field_choice_can_select_multiple (PopplerFormField *field) { g_return_val_if_fail (field->widget->getType () == formChoice, FALSE); return static_cast(field->widget)->isMultiSelect (); } /** * poppler_form_field_choice_do_spell_check: * @field: a #PopplerFormField * * Checks whether spell checking should be done for the contents of @field * * Return value: %TRUE if spell checking should be done for @field **/ gboolean poppler_form_field_choice_do_spell_check (PopplerFormField *field) { g_return_val_if_fail (field->widget->getType () == formChoice, FALSE); return !static_cast(field->widget)->noSpellCheck (); } gboolean poppler_form_field_choice_commit_on_change (PopplerFormField *field) { g_return_val_if_fail (field->widget->getType () == formChoice, FALSE); return static_cast(field->widget)->commitOnSelChange (); } /** * poppler_form_field_choice_get_n_items: * @field: a #PopplerFormField * * Returns the number of items on @field * * Return value: the number of items on @field **/ gint poppler_form_field_choice_get_n_items (PopplerFormField *field) { g_return_val_if_fail (field->widget->getType () == formChoice, -1); return static_cast(field->widget)->getNumChoices (); } /** * poppler_form_field_choice_get_item: * @field: a #PopplerFormField * @index: the index of the item * * Returns the contents of the item on @field at the given index * * Return value: a new allocated string. It must be freed with g_free() when done. **/ gchar * poppler_form_field_choice_get_item (PopplerFormField *field, gint index) { const GooString *tmp; g_return_val_if_fail (field->widget->getType () == formChoice, NULL); g_return_val_if_fail (index >= 0 && index < poppler_form_field_choice_get_n_items (field), NULL); tmp = static_cast(field->widget)->getChoice (index); return tmp ? _poppler_goo_string_to_utf8 (tmp) : nullptr; } /** * poppler_form_field_choice_is_item_selected: * @field: a #PopplerFormField * @index: the index of the item * * Checks whether the item at the given index on @field is currently selected * * Return value: %TRUE if item at @index is currently selected **/ gboolean poppler_form_field_choice_is_item_selected (PopplerFormField *field, gint index) { g_return_val_if_fail (field->widget->getType () == formChoice, FALSE); g_return_val_if_fail (index >= 0 && index < poppler_form_field_choice_get_n_items (field), FALSE); return static_cast(field->widget)->isSelected (index); } /** * poppler_form_field_choice_select_item: * @field: a #PopplerFormField * @index: the index of the item * * Selects the item at the given index on @field **/ void poppler_form_field_choice_select_item (PopplerFormField *field, gint index) { g_return_if_fail (field->widget->getType () == formChoice); g_return_if_fail (index >= 0 && index < poppler_form_field_choice_get_n_items (field)); static_cast(field->widget)->select (index); } /** * poppler_form_field_choice_unselect_all: * @field: a #PopplerFormField * * Unselects all the items on @field **/ void poppler_form_field_choice_unselect_all (PopplerFormField *field) { g_return_if_fail (field->widget->getType () == formChoice); static_cast(field->widget)->deselectAll (); } /** * poppler_form_field_choice_toggle_item: * @field: a #PopplerFormField * @index: the index of the item * * Changes the state of the item at the given index **/ void poppler_form_field_choice_toggle_item (PopplerFormField *field, gint index) { g_return_if_fail (field->widget->getType () == formChoice); g_return_if_fail (index >= 0 && index < poppler_form_field_choice_get_n_items (field)); static_cast(field->widget)->toggle (index); } /** * poppler_form_field_choice_set_text: * @field: a #PopplerFormField * @text: the new text * * Sets the text in @field to the given value, replacing the current contents **/ void poppler_form_field_choice_set_text (PopplerFormField *field, const gchar *text) { GooString *goo_tmp; gchar *tmp; gsize length = 0; g_return_if_fail (field->widget->getType () == formChoice); tmp = text ? g_convert (text, -1, "UTF-16BE", "UTF-8", nullptr, &length, nullptr) : nullptr; goo_tmp = new GooString (tmp, length); g_free (tmp); static_cast(field->widget)->setEditChoice (goo_tmp); delete goo_tmp; } /** * poppler_form_field_choice_get_text: * @field: a #PopplerFormField * * Retrieves the contents of @field. * * Return value: a new allocated string. It must be freed with g_free() when done. **/ gchar * poppler_form_field_choice_get_text (PopplerFormField *field) { const GooString *tmp; g_return_val_if_fail (field->widget->getType () == formChoice, NULL); tmp = static_cast(field->widget)->getEditChoice (); return tmp ? _poppler_goo_string_to_utf8 (tmp) : nullptr; }