Implemented support for setIcon by changing appearance

Added test for setIcon

Made changes to be more inline with API.
diff --git a/poppler/Annot.cc b/poppler/Annot.cc
index 0bf9864..005fa96 100644
--- a/poppler/Annot.cc
+++ b/poppler/Annot.cc
@@ -3819,6 +3819,17 @@
   return true;
 }
 
+void AnnotWidget::setNewAppearance(Object &&newAppearance)
+{
+  if (!newAppearance.isNull()) {
+    appearStreams = std::make_unique<AnnotAppearance>(doc, &newAppearance);
+    update("AP", std::move(newAppearance));
+  }
+
+  if (appearStreams)
+    appearance = appearStreams->getAppearanceStream(AnnotAppearance::appearNormal, appearState->c_str());
+}
+
 // Grand unified handler for preparing text strings to be drawn into form
 // fields.  Takes as input a text string (in PDFDocEncoding or UTF-16).
 // Converts some or all of this string to the appropriate encoding for the
@@ -4980,7 +4991,7 @@
 void AnnotWidget::draw(Gfx *gfx, bool printing) {
   if (!isVisible (printing))
     return;
-
+  
   annotLocker();
   bool addDingbatsResource = false;
 
diff --git a/poppler/Annot.h b/poppler/Annot.h
index 88c165f..7b37464 100644
--- a/poppler/Annot.h
+++ b/poppler/Annot.h
@@ -1409,6 +1409,7 @@
   LinkAction *getAdditionalAction(AdditionalActionsType type); // The caller should delete the result
   LinkAction *getFormAdditionalAction(FormAdditionalActionsType type); // The caller should delete the result
   Dict *getParent() { return parent; }
+  void setNewAppearance(Object &&newAppearance);
 
   bool setFormAdditionalAction(FormAdditionalActionsType type, const GooString &js);
 
diff --git a/qt5/src/poppler-form.cc b/qt5/src/poppler-form.cc
index ef13e58..fa9c331 100644
--- a/qt5/src/poppler-form.cc
+++ b/qt5/src/poppler-form.cc
@@ -70,6 +70,36 @@
 
 namespace Poppler {
 
+FormFieldIcon::FormFieldIcon(FormFieldIconData *data)
+  : d_ptr(data)
+{
+}
+
+FormFieldIcon::FormFieldIcon(const FormFieldIcon &ffIcon)
+{
+  d_ptr = new FormFieldIconData;
+  d_ptr->icon = ffIcon.d_ptr->icon;
+}
+
+FormFieldIcon& FormFieldIcon::operator=(const FormFieldIcon &ffIcon)
+{
+  if(this != &ffIcon)
+  {  
+    delete d_ptr;
+    d_ptr = nullptr;
+
+    d_ptr = new FormFieldIconData;
+    *d_ptr = *ffIcon.d_ptr;
+  }
+  
+  return *this;
+}
+
+FormFieldIcon::~FormFieldIcon()
+{
+  delete d_ptr;
+}
+
 FormField::FormField(FormFieldData &dd)
   : m_formData(&dd)
 {
@@ -284,6 +314,34 @@
   return ret;
 }
 
+FormFieldIcon FormFieldButton::icon() const
+{
+  FormWidgetButton* fwb = static_cast<FormWidgetButton*>(m_formData->fm);
+  if (fwb->getButtonType() == formButtonPush)
+  {
+    Dict *dict = m_formData->fm->getObj()->getDict();
+    FormFieldIconData *data = new FormFieldIconData;
+    data->icon = dict;
+    return FormFieldIcon(data);
+  }
+  return FormFieldIcon(nullptr);
+}
+
+void FormFieldButton::setIcon(const FormFieldIcon &icon)
+{
+  if(FormFieldIconData::getData( icon ) == nullptr)
+    return;
+
+  FormWidgetButton* fwb = static_cast<FormWidgetButton*>(m_formData->fm);
+  if (fwb->getButtonType() == formButtonPush)
+  {
+    ::AnnotWidget *w = m_formData->fm->getWidgetAnnotation(); 
+    FormFieldIconData *data = FormFieldIconData::getData( icon );
+    if(data->icon != nullptr)
+      w->setNewAppearance(data->icon->lookup("AP"));
+  }
+}
+
 bool FormFieldButton::state() const
 {
   FormWidgetButton* fwb = static_cast<FormWidgetButton*>(m_formData->fm);
diff --git a/qt5/src/poppler-form.h b/qt5/src/poppler-form.h
index a102762..f4c6458 100644
--- a/qt5/src/poppler-form.h
+++ b/qt5/src/poppler-form.h
@@ -49,6 +49,30 @@
     class Link;
 
     class FormFieldData;
+    class FormFieldIconData;
+
+    /**
+	 The class containing the appearance information
+
+	 \since 0.78
+     */
+
+    class POPPLER_QT5_EXPORT FormFieldIcon {
+    
+    friend class FormFieldIconData;
+    
+    public:
+
+    	FormFieldIcon(FormFieldIconData *data);
+    	FormFieldIcon(const FormFieldIcon &ffIcon);
+    	~FormFieldIcon();
+
+    	FormFieldIcon& operator=(const FormFieldIcon &ffIcon);
+
+    private:
+
+    	FormFieldIconData *d_ptr;
+    };
     /**
       The base class representing a form field.
 
@@ -210,6 +234,21 @@
 	QString caption() const;
 
 	/**
+	 * Gets the icon used by the button
+	 *
+	 * \since 0.78
+	 */
+	FormFieldIcon icon() const;
+
+	/**
+	 * Sets a new icon for the button, it has to be a icon 
+	 * returned by FormFieldButton::icon.
+	 *
+	 * \since 0.78
+	 */ 
+	void setIcon(const FormFieldIcon &icon);
+
+	/**
 	  The state of the button.
 	 */
 	bool state() const;
diff --git a/qt5/src/poppler-private.cc b/qt5/src/poppler-private.cc
index e847ed5..5a8b6e7 100644
--- a/qt5/src/poppler-private.cc
+++ b/qt5/src/poppler-private.cc
@@ -28,6 +28,7 @@
  */
 
 #include "poppler-private.h"
+#include "poppler-form.h"
 
 #include <QtCore/QByteArray>
 #include <QtCore/QDebug>
@@ -302,4 +303,9 @@
         }
     }
 
-}
+    FormFieldIconData POPPLER_QT5_EXPORT *FormFieldIconData::getData( const FormFieldIcon &f )
+    {
+        return f.d_ptr;
+    }
+
+}
\ No newline at end of file
diff --git a/qt5/src/poppler-private.h b/qt5/src/poppler-private.h
index 8795634..4bcd263 100644
--- a/qt5/src/poppler-private.h
+++ b/qt5/src/poppler-private.h
@@ -237,6 +237,14 @@
 		::FormWidget *fm;
 		QRectF box;
     };
+    
+    class FormFieldIcon;
+    class FormFieldIconData
+    {
+    public:
+    	static FormFieldIconData *getData( const FormFieldIcon &f );
+    	Dict *icon;
+    };
 
 }
 
diff --git a/qt5/tests/check_forms.cpp b/qt5/tests/check_forms.cpp
index 6c6482d..ec48ce9 100644
--- a/qt5/tests/check_forms.cpp
+++ b/qt5/tests/check_forms.cpp
@@ -2,6 +2,7 @@
 
 #include <poppler-qt5.h>
 #include <poppler-form.h>
+#include <poppler-private.h>
 #include <Form.h>
 
 class TestForms: public QObject
@@ -12,6 +13,7 @@
 private slots:
     void testCheckbox();// Test for issue #655
     void testCheckboxIssue159();// Test for issue #159
+    void testSetIcon();// Test that setIcon will always be valid.
 };
 
 void TestForms::testCheckbox()
@@ -88,5 +90,63 @@
     QCOMPARE( beerFieldButton->state() , false );
 }
 
+void TestForms::testSetIcon()
+{
+    QScopedPointer< Poppler::Document > document(Poppler::Document::load(TESTDATADIR "/unittestcases/form_set_icon.pdf"));
+    QVERIFY( document );
+
+    QScopedPointer< Poppler::Page > page(document->page(0));
+    QVERIFY( page );
+
+    QList<Poppler::FormField*> forms = page->formFields();
+
+    Poppler::FormFieldButton *anmButton = nullptr;
+
+    // First we are finding the field which will have its icon changed
+    Q_FOREACH (Poppler::FormField *field, forms) {
+
+        if (field->type() != Poppler::FormField::FormButton)
+            continue;
+
+        Poppler::FormFieldButton *fieldButton = static_cast<Poppler::FormFieldButton *>(field);
+        if (field->name() == QStringLiteral("anm0"))
+            anmButton = fieldButton;
+
+    }
+
+    QVERIFY( anmButton );
+
+    // Then we set the Icon on this field, for every other field
+    // And verify if it has a valid icon
+    Q_FOREACH (Poppler::FormField *field, forms) {
+
+        if (field->type() != Poppler::FormField::FormButton)
+            continue;
+
+        Poppler::FormFieldButton *fieldButton = static_cast<Poppler::FormFieldButton *>(field);
+        if (field->name() == QStringLiteral("anm0"))
+            continue;
+
+        Poppler::FormFieldIcon newIcon = fieldButton->icon();
+
+        anmButton->setIcon( newIcon );
+
+        Poppler::FormFieldIcon anmIcon = anmButton->icon();
+
+        QVERIFY( Poppler::FormFieldIconData::getData( anmIcon ) );
+        QVERIFY( Poppler::FormFieldIconData::getData( anmIcon )->icon );
+
+        QCOMPARE( Poppler::FormFieldIconData::getData( anmIcon )->icon->lookupNF("AP").dictLookupNF("N").getRef().num,
+                  Poppler::FormFieldIconData::getData( newIcon )->icon->lookupNF("AP").dictLookupNF("N").getRef().num);
+    }
+
+    // Just making sure that setting a invalid icon will still produce a valid icon.
+    anmButton->setIcon( nullptr );
+    Poppler::FormFieldIcon anmIcon = anmButton->icon();
+
+    QVERIFY( Poppler::FormFieldIconData::getData( anmIcon ) );
+    QVERIFY( Poppler::FormFieldIconData::getData( anmIcon )->icon );
+}
+
 QTEST_GUILESS_MAIN(TestForms)
 #include "check_forms.moc"