File indexing completed on 2024-04-28 15:51:45

0001 /*
0002     SPDX-FileCopyrightText: 2007 Pino Toscano <pino@kde.org>
0003 
0004     Work sponsored by the LiMux project of the city of Munich:
0005     SPDX-FileCopyrightText: 2017 Klarälvdalens Datakonsult AB a KDAB Group company <info@kdab.com>
0006 
0007     SPDX-License-Identifier: GPL-2.0-or-later
0008 */
0009 
0010 #ifndef _OKULAR_FORMWIDGETS_H_
0011 #define _OKULAR_FORMWIDGETS_H_
0012 
0013 #include "core/area.h"
0014 #include "core/form.h"
0015 
0016 #include <KTextEdit>
0017 #include <KUrlRequester>
0018 #include <QCheckBox>
0019 #include <QComboBox>
0020 #include <QLineEdit>
0021 #include <QListWidget>
0022 #include <QPushButton>
0023 #include <QRadioButton>
0024 
0025 class ComboEdit;
0026 class QMenu;
0027 class QButtonGroup;
0028 class FormWidgetIface;
0029 class PageView;
0030 class PageViewItem;
0031 class RadioButtonEdit;
0032 class QEvent;
0033 
0034 namespace Okular
0035 {
0036 class Action;
0037 class FormField;
0038 class FormFieldButton;
0039 class FormFieldChoice;
0040 class FormFieldText;
0041 class FormFieldSignature;
0042 class Document;
0043 }
0044 
0045 struct RadioData {
0046     RadioData()
0047     {
0048     }
0049 
0050     QList<int> ids;
0051     QButtonGroup *group;
0052 };
0053 
0054 class FormWidgetsController : public QObject
0055 {
0056     Q_OBJECT
0057 
0058 public:
0059     explicit FormWidgetsController(Okular::Document *doc);
0060     ~FormWidgetsController() override;
0061 
0062     void signalAction(Okular::Action *action);
0063     void signalMouseUpAction(Okular::Action *action, Okular::FormField *form);
0064 
0065     void processScriptAction(Okular::Action *a, Okular::FormField *field, Okular::Annotation::AdditionalActionType type);
0066 
0067     void registerRadioButton(FormWidgetIface *fwButton, Okular::FormFieldButton *formButton);
0068     void dropRadioButtons();
0069     bool canUndo();
0070     bool canRedo();
0071 
0072     Okular::Document *document() const;
0073 
0074     static bool shouldFormWidgetBeShown(Okular::FormField *form);
0075 
0076 Q_SIGNALS:
0077     void changed(int pageNumber);
0078     void requestUndo();
0079     void requestRedo();
0080     void canUndoChanged(bool undoAvailable);
0081     void canRedoChanged(bool redoAvailable);
0082     void formTextChangedByWidget(int pageNumber, Okular::FormFieldText *form, const QString &newContents, int newCursorPos, int prevCursorPos, int prevAnchorPos);
0083 
0084     void formTextChangedByUndoRedo(int pageNumber, Okular::FormFieldText *form, const QString &contents, int cursorPos, int anchorPos);
0085 
0086     void formListChangedByWidget(int pageNumber, Okular::FormFieldChoice *form, const QList<int> &newChoices);
0087 
0088     void formListChangedByUndoRedo(int pageNumber, Okular::FormFieldChoice *form, const QList<int> &choices);
0089 
0090     void formComboChangedByWidget(int pageNumber, Okular::FormFieldChoice *form, const QString &newText, int newCursorPos, int prevCursorPos, int prevAnchorPos);
0091 
0092     void formComboChangedByUndoRedo(int pageNumber, Okular::FormFieldChoice *form, const QString &text, int cursorPos, int anchorPos);
0093 
0094     void formButtonsChangedByWidget(int pageNumber, const QList<Okular::FormFieldButton *> &formButtons, const QList<bool> &newButtonStates);
0095 
0096     void action(Okular::Action *action);
0097 
0098     void mouseUpAction(Okular::Action *action, Okular::FormField *form);
0099 
0100     void refreshFormWidget(Okular::FormField *form);
0101 
0102 private Q_SLOTS:
0103     void slotButtonClicked(QAbstractButton *button);
0104     void slotFormButtonsChangedByUndoRedo(int pageNumber, const QList<Okular::FormFieldButton *> &formButtons);
0105 
0106 private:
0107     friend class TextAreaEdit;
0108     friend class FormLineEdit;
0109     friend class FileEdit;
0110     friend class ListEdit;
0111     friend class ComboEdit;
0112     friend class SignatureEdit;
0113 
0114     QList<RadioData> m_radios;
0115     QHash<int, QAbstractButton *> m_buttons;
0116     Okular::Document *m_doc;
0117 };
0118 
0119 class FormWidgetFactory
0120 {
0121 public:
0122     static FormWidgetIface *createWidget(Okular::FormField *ff, PageView *pageView);
0123 };
0124 
0125 class FormWidgetIface
0126 {
0127 public:
0128     FormWidgetIface(QWidget *w, Okular::FormField *ff);
0129     virtual ~FormWidgetIface();
0130 
0131     FormWidgetIface(const FormWidgetIface &) = delete;
0132     FormWidgetIface &operator=(const FormWidgetIface &) = delete;
0133 
0134     Okular::NormalizedRect rect() const;
0135     void setWidthHeight(int w, int h);
0136     void moveTo(int x, int y);
0137     bool setVisibility(bool visible);
0138     void setCanBeFilled(bool fill);
0139 
0140     void setPageItem(PageViewItem *pageItem);
0141     PageViewItem *pageItem() const;
0142     void setFormField(Okular::FormField *field);
0143     Okular::FormField *formField() const;
0144 
0145     virtual void setFormWidgetsController(FormWidgetsController *controller);
0146 
0147 protected:
0148     virtual void slotRefresh(Okular::FormField *form);
0149 
0150     FormWidgetsController *m_controller;
0151     Okular::FormField *m_ff;
0152 
0153 private:
0154     QWidget *m_widget;
0155     PageViewItem *m_pageItem;
0156 };
0157 
0158 #define DECLARE_ADDITIONAL_ACTIONS                                                                                                                                                                                                             \
0159 protected:                                                                                                                                                                                                                                     \
0160     virtual void mousePressEvent(QMouseEvent *event) override;                                                                                                                                                                                 \
0161     virtual void mouseReleaseEvent(QMouseEvent *event) override;                                                                                                                                                                               \
0162     virtual void focusInEvent(QFocusEvent *event) override;                                                                                                                                                                                    \
0163     virtual void focusOutEvent(QFocusEvent *event) override;                                                                                                                                                                                   \
0164     virtual void leaveEvent(QEvent *event) override;                                                                                                                                                                                           \
0165     virtual void enterEvent(QEnterEvent *event) override;
0166 
0167 class PushButtonEdit : public QPushButton, public FormWidgetIface
0168 {
0169     Q_OBJECT
0170 
0171 public:
0172     explicit PushButtonEdit(Okular::FormFieldButton *button, PageView *pageView);
0173 
0174     DECLARE_ADDITIONAL_ACTIONS
0175 };
0176 
0177 class CheckBoxEdit : public QCheckBox, public FormWidgetIface
0178 {
0179     Q_OBJECT
0180 
0181 public:
0182     explicit CheckBoxEdit(Okular::FormFieldButton *button, PageView *pageView);
0183 
0184     // reimplemented from FormWidgetIface
0185     void setFormWidgetsController(FormWidgetsController *controller) override;
0186 
0187     void doActivateAction();
0188 
0189 protected:
0190     void slotRefresh(Okular::FormField *form) override;
0191     DECLARE_ADDITIONAL_ACTIONS
0192 };
0193 
0194 class RadioButtonEdit : public QRadioButton, public FormWidgetIface
0195 {
0196     Q_OBJECT
0197 
0198 public:
0199     explicit RadioButtonEdit(Okular::FormFieldButton *button, PageView *pageView);
0200 
0201     // reimplemented from FormWidgetIface
0202     void setFormWidgetsController(FormWidgetsController *controller) override;
0203     DECLARE_ADDITIONAL_ACTIONS
0204 };
0205 
0206 class FormLineEdit : public QLineEdit, public FormWidgetIface
0207 {
0208     Q_OBJECT
0209 
0210 public:
0211     explicit FormLineEdit(Okular::FormFieldText *text, PageView *pageView);
0212     void setFormWidgetsController(FormWidgetsController *controller) override;
0213     bool event(QEvent *e) override;
0214     void contextMenuEvent(QContextMenuEvent *event) override;
0215 
0216 public Q_SLOTS:
0217     void slotHandleTextChangedByUndoRedo(int pageNumber, Okular::FormFieldText *textForm, const QString &contents, int cursorPos, int anchorPos);
0218 private Q_SLOTS:
0219     void slotChanged();
0220 
0221 protected:
0222     void slotRefresh(Okular::FormField *form) override;
0223 
0224 private:
0225     int m_prevCursorPos;
0226     int m_prevAnchorPos;
0227     bool m_editing;
0228     DECLARE_ADDITIONAL_ACTIONS
0229 };
0230 
0231 class TextAreaEdit : public KTextEdit, public FormWidgetIface
0232 {
0233     Q_OBJECT
0234 
0235 public:
0236     explicit TextAreaEdit(Okular::FormFieldText *text, PageView *pageView);
0237     ~TextAreaEdit() override;
0238     void setFormWidgetsController(FormWidgetsController *controller) override;
0239     bool event(QEvent *e) override;
0240 
0241 public Q_SLOTS:
0242     void slotHandleTextChangedByUndoRedo(int pageNumber, Okular::FormFieldText *textForm, const QString &contents, int cursorPos, int anchorPos);
0243     void slotUpdateUndoAndRedoInContextMenu(QMenu *menu);
0244 
0245 private Q_SLOTS:
0246     void slotChanged();
0247 
0248 protected:
0249     void slotRefresh(Okular::FormField *form) override;
0250 
0251 private:
0252     int m_prevCursorPos;
0253     int m_prevAnchorPos;
0254     bool m_editing;
0255     DECLARE_ADDITIONAL_ACTIONS
0256 };
0257 
0258 class FileEdit : public KUrlRequester, public FormWidgetIface
0259 {
0260     Q_OBJECT
0261 
0262 public:
0263     explicit FileEdit(Okular::FormFieldText *text, PageView *pageView);
0264     void setFormWidgetsController(FormWidgetsController *controller) override;
0265 
0266 protected:
0267     bool eventFilter(QObject *obj, QEvent *event) override;
0268 
0269 private Q_SLOTS:
0270     void slotChanged();
0271     void slotHandleFileChangedByUndoRedo(int pageNumber, Okular::FormFieldText *form, const QString &contents, int cursorPos, int anchorPos);
0272 
0273 private:
0274     int m_prevCursorPos;
0275     int m_prevAnchorPos;
0276     DECLARE_ADDITIONAL_ACTIONS
0277 };
0278 
0279 class ListEdit : public QListWidget, public FormWidgetIface
0280 {
0281     Q_OBJECT
0282 
0283 public:
0284     explicit ListEdit(Okular::FormFieldChoice *choice, PageView *pageView);
0285     void setFormWidgetsController(FormWidgetsController *controller) override;
0286 
0287 private Q_SLOTS:
0288     void slotSelectionChanged();
0289     void slotHandleFormListChangedByUndoRedo(int pageNumber, Okular::FormFieldChoice *listForm, const QList<int> &choices);
0290     DECLARE_ADDITIONAL_ACTIONS
0291 };
0292 
0293 class ComboEdit : public QComboBox, public FormWidgetIface
0294 {
0295     Q_OBJECT
0296 
0297 public:
0298     explicit ComboEdit(Okular::FormFieldChoice *choice, PageView *pageView);
0299     void setFormWidgetsController(FormWidgetsController *controller) override;
0300     bool event(QEvent *e) override;
0301     void contextMenuEvent(QContextMenuEvent *event) override;
0302 
0303 private Q_SLOTS:
0304     void slotValueChanged();
0305     void slotHandleFormComboChangedByUndoRedo(int pageNumber, Okular::FormFieldChoice *comboForm, const QString &text, int cursorPos, int anchorPos);
0306 
0307 private:
0308     int m_prevCursorPos;
0309     int m_prevAnchorPos;
0310     DECLARE_ADDITIONAL_ACTIONS
0311 };
0312 
0313 class SignatureEdit : public QAbstractButton, public FormWidgetIface
0314 {
0315     Q_OBJECT
0316 
0317 public:
0318     explicit SignatureEdit(Okular::FormFieldSignature *signature, PageView *pageView);
0319 
0320     // This will be called when an item in signature panel is clicked. Calling it changes the
0321     // widget state. If this widget was visible prior to calling this then background
0322     // color will change and borders will remain otherwise visibility of this widget will change.
0323     // During the change all interactions will be disabled.
0324     void setDummyMode(bool set);
0325 
0326 protected:
0327     bool event(QEvent *e) override;
0328     void contextMenuEvent(QContextMenuEvent *event) override;
0329     void paintEvent(QPaintEvent *event) override;
0330 
0331 private Q_SLOTS:
0332     void slotViewProperties();
0333     void signUnsignedSignature();
0334 
0335 private:
0336     bool m_widgetPressed;
0337     bool m_dummyMode;
0338     bool m_wasVisible; // this will help in deciding whether or not to paint border for this widget
0339 
0340     DECLARE_ADDITIONAL_ACTIONS
0341 };
0342 
0343 #undef DECLARE_ADDITIONAL_ACTIONS
0344 
0345 #endif