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