mirror of https://github.com/JakubMelka/PDF4QT.git
Issue #118: Refactoring of forms finished
This commit is contained in:
parent
b4d123baac
commit
0e1959b3aa
|
@ -1424,11 +1424,9 @@ bool PDFAnnotationManager::isAnnotationDrawnByEditor(const PageAnnotation& annot
|
|||
return false;
|
||||
}
|
||||
|
||||
const PDFFormFieldWidgetEditor* editor = nullptr;
|
||||
if (annotation.annotation->getType() == AnnotationType::Widget)
|
||||
{
|
||||
editor = m_formManager->getEditor(m_formManager->getFormFieldForWidget(annotation.annotation->getSelfReference()));
|
||||
return editor && editor->isEditorDrawEnabled();
|
||||
return m_formManager->isEditorDrawEnabled(annotation.annotation->getSelfReference());
|
||||
}
|
||||
|
||||
return false;
|
||||
|
@ -3105,10 +3103,9 @@ void PDFWidgetAnnotation::draw(AnnotationDrawParameters& parameters) const
|
|||
PDFPainterStateGuard guard(parameters.painter);
|
||||
parameters.painter->setCompositionMode(getCompositionMode());
|
||||
|
||||
const PDFFormFieldWidgetEditor* editor = parameters.formManager->getEditor(formField);
|
||||
if (editor && editor->isEditorDrawEnabled())
|
||||
if (parameters.formManager->isEditorDrawEnabled(formField))
|
||||
{
|
||||
editor->draw(parameters, true);
|
||||
parameters.formManager->drawFormField(formField, parameters, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -3117,7 +3114,7 @@ void PDFWidgetAnnotation::draw(AnnotationDrawParameters& parameters) const
|
|||
case PDFFormField::FieldType::Text:
|
||||
case PDFFormField::FieldType::Choice:
|
||||
{
|
||||
editor->draw(parameters, false);
|
||||
m_parameters.formManager->drawFormField(parameters, false);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -3146,8 +3143,6 @@ void PDFWidgetAnnotation::draw(AnnotationDrawParameters& parameters) const
|
|||
font.setPixelSize(qCeil(fontSize));
|
||||
font.setStyleStrategy(QFont::ForceOutline);
|
||||
|
||||
QFontMetrics fontMetrics(font);
|
||||
|
||||
QPainter* painter = parameters.painter;
|
||||
painter->translate(rectangle.bottomLeft());
|
||||
painter->scale(1.0, -1.0);
|
||||
|
|
|
@ -15,9 +15,7 @@
|
|||
// You should have received a copy of the GNU Lesser General Public License
|
||||
// along with PDF4QT. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
#include "pdfdrawspacecontroller.h"
|
||||
#include "pdfdrawwidget.h"
|
||||
#include "pdfrenderer.h"
|
||||
#include "pdfpainter.h"
|
||||
#include "pdfcompiler.h"
|
||||
|
|
|
@ -17,7 +17,6 @@
|
|||
|
||||
#include "pdfform.h"
|
||||
#include "pdfdocument.h"
|
||||
#include "pdftexteditpseudowidget.h"
|
||||
#include "pdfdrawspacecontroller.h"
|
||||
#include "pdfdocumentbuilder.h"
|
||||
#include "pdfpainterutils.h"
|
||||
|
@ -26,141 +25,6 @@
|
|||
namespace pdf
|
||||
{
|
||||
|
||||
/// "Pseudo" widget, which is emulating list box. It can contain scrollbar.
|
||||
class PDFListBoxPseudowidget
|
||||
{
|
||||
public:
|
||||
explicit PDFListBoxPseudowidget(PDFFormField::FieldFlags flags);
|
||||
|
||||
using Options = PDFFormFieldChoice::Options;
|
||||
|
||||
inline bool isReadonly() const { return m_flags.testFlag(PDFFormField::ReadOnly); }
|
||||
inline bool isMultiSelect() const { return m_flags.testFlag(PDFFormField::MultiSelect); }
|
||||
inline bool isCommitOnSelectionChange() const { return m_flags.testFlag(PDFFormField::CommitOnSelectionChange); }
|
||||
|
||||
void shortcutOverrideEvent(QWidget* widget, QKeyEvent* event);
|
||||
void keyPressEvent(QWidget* widget, QKeyEvent* event);
|
||||
|
||||
/// Sets widget appearance, such as font, font size, color, text alignment,
|
||||
/// and rectangle, in which widget resides on page (in page coordinates)
|
||||
/// \param appearance Appearance
|
||||
/// \param textAlignment Text alignment
|
||||
/// \param rect Widget rectangle in page coordinates
|
||||
/// \param options Options selectable by list box
|
||||
/// \param topIndex Index of first visible item
|
||||
void setAppearance(const PDFAnnotationDefaultAppearance& appearance,
|
||||
Qt::Alignment textAlignment,
|
||||
QRectF rect,
|
||||
const Options& options,
|
||||
int topIndex,
|
||||
std::set<int> selection);
|
||||
|
||||
/// Draw text edit using given parameters
|
||||
/// \param parameters Parameters
|
||||
void draw(AnnotationDrawParameters& parameters, bool edit) const;
|
||||
|
||||
/// Sets current selection. If commit on selection change flag
|
||||
/// is set, then contents of the widgets are commited. New selection
|
||||
/// is not set, if field is readonly and \p force is false
|
||||
/// \param selection New selection
|
||||
/// \param force Set selection even if readonly
|
||||
void setSelection(std::set<int> selection, bool force);
|
||||
|
||||
/// Returns active item selection
|
||||
const std::set<int>& getSelection() const { return m_selection; }
|
||||
|
||||
/// Returns top index
|
||||
int getTopItemIndex() const { return m_topIndex; }
|
||||
|
||||
/// Set top item index
|
||||
/// \param index Top item index
|
||||
void setTopItemIndex(int index);
|
||||
|
||||
/// Scrolls the list box in such a way, that index is visible
|
||||
/// \param index Index to scroll to
|
||||
void scrollTo(int index);
|
||||
|
||||
/// Returns valid index from index (i.e. index which ranges from first
|
||||
/// row to the last one). If index itself is valid, then it is returned.
|
||||
/// \param index Index, from which we want to get valid one
|
||||
int getValidIndex(int index) const;
|
||||
|
||||
/// Returns true, if index is valid
|
||||
bool isValidIndex(int index) const { return index == getValidIndex(index); }
|
||||
|
||||
/// Returns number of rows in the viewport
|
||||
int getViewportRowCount() const { return qFloor(m_widgetRect.height() / m_lineSpacing); }
|
||||
|
||||
/// Returns item index from widget position (i.e. transforms
|
||||
/// point in the widget to the index of item, which is under the point)
|
||||
/// \param point Widget point
|
||||
int getIndexFromWidgetPosition(const QPointF& point) const;
|
||||
|
||||
/// Sets current item and updates selection based on keyboard modifiers
|
||||
/// \param index New index
|
||||
/// \param modifiers Keyboard modifiers
|
||||
void setCurrentItem(int index, Qt::KeyboardModifiers modifiers);
|
||||
|
||||
/// Returns text of selected item text. If no item is selected,
|
||||
/// or multiple items are selected, then empty string is returned.
|
||||
/// \returns Selected text
|
||||
QString getSelectedItemText() const;
|
||||
|
||||
/// Returns true, if single item is selected
|
||||
bool isSingleItemSelected() const { return m_selection.size() == 1; }
|
||||
|
||||
/// Returns index of option, in the list box option list.
|
||||
/// If option is not found, then -1 is returned.
|
||||
/// \param option Option
|
||||
int findOption(const QString& option) const;
|
||||
|
||||
/// Sets widget appearance, such as font, font size, color, text alignment,
|
||||
/// and rectangle, in which widget resides on page (in page coordinates)
|
||||
/// \param font Font
|
||||
/// \param fontColor Font color
|
||||
/// \param textAlignment Text alignment
|
||||
/// \param rect Widget rectangle in page coordinates
|
||||
/// \param options Options selectable by list box
|
||||
/// \param topIndex Index of first visible item
|
||||
void initialize(QFont font, QColor fontColor, Qt::Alignment textAlignment, QRectF rect,
|
||||
const Options& options, int topIndex, std::set<int> selection);
|
||||
|
||||
private:
|
||||
int getStartItemIndex() const { return 0; }
|
||||
int getEndItemIndex() const { return m_options.empty() ? 0 : int(m_options.size() - 1); }
|
||||
|
||||
int getSingleStep() const { return 1; }
|
||||
int getPageStep() const { return qMax(getViewportRowCount() - 1, getSingleStep()); }
|
||||
|
||||
/// Returns true, if row with this index is visible in the widget
|
||||
/// (it is in viewport).
|
||||
/// \param index Index
|
||||
bool isVisible(int index) const;
|
||||
|
||||
/// Moves current item by offset (negative is up, positive is down)
|
||||
/// \param offset Offset
|
||||
/// \param modifiers Keyboard modifiers
|
||||
void moveCurrentItemIndexByOffset(int offset, Qt::KeyboardModifiers modifiers) { setCurrentItem(m_currentIndex + offset, modifiers); }
|
||||
|
||||
/// Returns true, if list box has continuous selection
|
||||
bool hasContinuousSelection() const;
|
||||
|
||||
/// Creates transformation matrix, which transforms widget coordinates to page coordinates
|
||||
QTransform createListBoxTransformMatrix() const;
|
||||
|
||||
PDFFormField::FieldFlags m_flags;
|
||||
|
||||
Options m_options;
|
||||
Qt::Alignment m_textAlignment = Qt::Alignment();
|
||||
int m_topIndex = 0;
|
||||
int m_currentIndex = 0;
|
||||
std::set<int> m_selection;
|
||||
QFont m_font;
|
||||
PDFReal m_lineSpacing = 0.0;
|
||||
QRectF m_widgetRect;
|
||||
QColor m_textColor;
|
||||
};
|
||||
|
||||
PDFForm PDFForm::parse(const PDFDocument* document, PDFObject object)
|
||||
{
|
||||
PDFForm form;
|
||||
|
@ -807,7 +671,7 @@ void PDFFormManager::setDocument(const PDFModifiedDocument& document)
|
|||
m_form = PDFForm();
|
||||
}
|
||||
|
||||
updateFormWidgetEditors();
|
||||
onDocumentReset();
|
||||
}
|
||||
else if (document.hasFlag(PDFModifiedDocument::FormField))
|
||||
{
|
||||
|
@ -1036,6 +900,18 @@ void PDFFormManager::performPaging()
|
|||
}
|
||||
}
|
||||
|
||||
bool PDFFormManager::isFocused(PDFObjectReference widget) const
|
||||
{
|
||||
Q_UNUSED(widget);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool PDFFormManager::isEditorDrawEnabled(const PDFObjectReference& reference) const
|
||||
{
|
||||
Q_UNUSED(reference);
|
||||
return false;
|
||||
}
|
||||
|
||||
void PDFFormManager::updateFieldValues()
|
||||
{
|
||||
if (m_document)
|
||||
|
|
|
@ -591,8 +591,25 @@ public:
|
|||
/// is emitted.
|
||||
void performPaging();
|
||||
|
||||
/// Returns true, if widget is focused.
|
||||
/// \param widget Widget annotation reference
|
||||
virtual bool isFocused(PDFObjectReference widget) const;
|
||||
|
||||
/// Is editor draw enabled?
|
||||
virtual bool isEditorDrawEnabled(const PDFObjectReference& reference) const;
|
||||
virtual bool isEditorDrawEnabled(const PDFFormField* formField) const;
|
||||
|
||||
/// Draw form field widget using given parameters. It is used, when
|
||||
/// we want to draw editor contents on the painter using parameters.
|
||||
/// Parameter \p edit decides, if editor is drawn, or static contents
|
||||
/// based on field value is drawn.
|
||||
/// \param parameters Parameters
|
||||
/// \param edit Draw editor or static contents
|
||||
virtual void drawFormField(const PDFFormField* formField, AnnotationDrawParameters& parameters, bool edit) const;
|
||||
|
||||
protected:
|
||||
virtual void updateFieldValues();
|
||||
virtual void onDocumentReset() { }
|
||||
|
||||
signals:
|
||||
void actionTriggered(const pdf::PDFAction* action);
|
||||
|
|
|
@ -27,6 +27,142 @@
|
|||
namespace pdf
|
||||
{
|
||||
|
||||
/// "Pseudo" widget, which is emulating list box. It can contain scrollbar.
|
||||
class PDFListBoxPseudowidget
|
||||
{
|
||||
public:
|
||||
explicit PDFListBoxPseudowidget(PDFFormField::FieldFlags flags);
|
||||
|
||||
using Options = PDFFormFieldChoice::Options;
|
||||
|
||||
inline bool isReadonly() const { return m_flags.testFlag(PDFFormField::ReadOnly); }
|
||||
inline bool isMultiSelect() const { return m_flags.testFlag(PDFFormField::MultiSelect); }
|
||||
inline bool isCommitOnSelectionChange() const { return m_flags.testFlag(PDFFormField::CommitOnSelectionChange); }
|
||||
|
||||
void shortcutOverrideEvent(QWidget* widget, QKeyEvent* event);
|
||||
void keyPressEvent(QWidget* widget, QKeyEvent* event);
|
||||
|
||||
/// Sets widget appearance, such as font, font size, color, text alignment,
|
||||
/// and rectangle, in which widget resides on page (in page coordinates)
|
||||
/// \param appearance Appearance
|
||||
/// \param textAlignment Text alignment
|
||||
/// \param rect Widget rectangle in page coordinates
|
||||
/// \param options Options selectable by list box
|
||||
/// \param topIndex Index of first visible item
|
||||
void setAppearance(const PDFAnnotationDefaultAppearance& appearance,
|
||||
Qt::Alignment textAlignment,
|
||||
QRectF rect,
|
||||
const Options& options,
|
||||
int topIndex,
|
||||
std::set<int> selection);
|
||||
|
||||
/// Draw text edit using given parameters
|
||||
/// \param parameters Parameters
|
||||
void draw(AnnotationDrawParameters& parameters, bool edit) const;
|
||||
|
||||
/// Sets current selection. If commit on selection change flag
|
||||
/// is set, then contents of the widgets are commited. New selection
|
||||
/// is not set, if field is readonly and \p force is false
|
||||
/// \param selection New selection
|
||||
/// \param force Set selection even if readonly
|
||||
void setSelection(std::set<int> selection, bool force);
|
||||
|
||||
/// Returns active item selection
|
||||
const std::set<int>& getSelection() const { return m_selection; }
|
||||
|
||||
/// Returns top index
|
||||
int getTopItemIndex() const { return m_topIndex; }
|
||||
|
||||
/// Set top item index
|
||||
/// \param index Top item index
|
||||
void setTopItemIndex(int index);
|
||||
|
||||
/// Scrolls the list box in such a way, that index is visible
|
||||
/// \param index Index to scroll to
|
||||
void scrollTo(int index);
|
||||
|
||||
/// Returns valid index from index (i.e. index which ranges from first
|
||||
/// row to the last one). If index itself is valid, then it is returned.
|
||||
/// \param index Index, from which we want to get valid one
|
||||
int getValidIndex(int index) const;
|
||||
|
||||
/// Returns true, if index is valid
|
||||
bool isValidIndex(int index) const { return index == getValidIndex(index); }
|
||||
|
||||
/// Returns number of rows in the viewport
|
||||
int getViewportRowCount() const { return qFloor(m_widgetRect.height() / m_lineSpacing); }
|
||||
|
||||
/// Returns item index from widget position (i.e. transforms
|
||||
/// point in the widget to the index of item, which is under the point)
|
||||
/// \param point Widget point
|
||||
int getIndexFromWidgetPosition(const QPointF& point) const;
|
||||
|
||||
/// Sets current item and updates selection based on keyboard modifiers
|
||||
/// \param index New index
|
||||
/// \param modifiers Keyboard modifiers
|
||||
void setCurrentItem(int index, Qt::KeyboardModifiers modifiers);
|
||||
|
||||
/// Returns text of selected item text. If no item is selected,
|
||||
/// or multiple items are selected, then empty string is returned.
|
||||
/// \returns Selected text
|
||||
QString getSelectedItemText() const;
|
||||
|
||||
/// Returns true, if single item is selected
|
||||
bool isSingleItemSelected() const { return m_selection.size() == 1; }
|
||||
|
||||
/// Returns index of option, in the list box option list.
|
||||
/// If option is not found, then -1 is returned.
|
||||
/// \param option Option
|
||||
int findOption(const QString& option) const;
|
||||
|
||||
/// Sets widget appearance, such as font, font size, color, text alignment,
|
||||
/// and rectangle, in which widget resides on page (in page coordinates)
|
||||
/// \param font Font
|
||||
/// \param fontColor Font color
|
||||
/// \param textAlignment Text alignment
|
||||
/// \param rect Widget rectangle in page coordinates
|
||||
/// \param options Options selectable by list box
|
||||
/// \param topIndex Index of first visible item
|
||||
void initialize(QFont font, QColor fontColor, Qt::Alignment textAlignment, QRectF rect,
|
||||
const Options& options, int topIndex, std::set<int> selection);
|
||||
|
||||
private:
|
||||
int getStartItemIndex() const { return 0; }
|
||||
int getEndItemIndex() const { return m_options.empty() ? 0 : int(m_options.size() - 1); }
|
||||
|
||||
int getSingleStep() const { return 1; }
|
||||
int getPageStep() const { return qMax(getViewportRowCount() - 1, getSingleStep()); }
|
||||
|
||||
/// Returns true, if row with this index is visible in the widget
|
||||
/// (it is in viewport).
|
||||
/// \param index Index
|
||||
bool isVisible(int index) const;
|
||||
|
||||
/// Moves current item by offset (negative is up, positive is down)
|
||||
/// \param offset Offset
|
||||
/// \param modifiers Keyboard modifiers
|
||||
void moveCurrentItemIndexByOffset(int offset, Qt::KeyboardModifiers modifiers) { setCurrentItem(m_currentIndex + offset, modifiers); }
|
||||
|
||||
/// Returns true, if list box has continuous selection
|
||||
bool hasContinuousSelection() const;
|
||||
|
||||
/// Creates transformation matrix, which transforms widget coordinates to page coordinates
|
||||
QTransform createListBoxTransformMatrix() const;
|
||||
|
||||
PDFFormField::FieldFlags m_flags;
|
||||
|
||||
Options m_options;
|
||||
Qt::Alignment m_textAlignment = Qt::Alignment();
|
||||
int m_topIndex = 0;
|
||||
int m_currentIndex = 0;
|
||||
std::set<int> m_selection;
|
||||
QFont m_font;
|
||||
PDFReal m_lineSpacing = 0.0;
|
||||
QRectF m_widgetRect;
|
||||
QColor m_textColor;
|
||||
};
|
||||
|
||||
|
||||
/// Editor for button-like editors
|
||||
class PDFFormFieldAbstractButtonEditor : public PDFFormFieldWidgetEditor
|
||||
{
|
||||
|
@ -2016,4 +2152,30 @@ void PDFFormFieldListBoxEditor::commit()
|
|||
}
|
||||
}
|
||||
|
||||
PDFWidgetFormManager::isEditorDrawEnabled(const PDFObjectReference& reference) const
|
||||
{
|
||||
const PDFFormFieldWidgetEditor* editor = getEditor(getFormFieldForWidget(reference));
|
||||
return editor && editor->isEditorDrawEnabled();
|
||||
}
|
||||
|
||||
void PDFWidgetFormManager::onDocumentReset()
|
||||
{
|
||||
updateFormWidgetEditors();
|
||||
}
|
||||
|
||||
bool PDFWidgetFormManager::isEditorDrawEnabled(const PDFFormField* formField) const
|
||||
{
|
||||
const PDFFormFieldWidgetEditor* editor = getEditor(formField);
|
||||
return editor && editor->isEditorDrawEnabled();
|
||||
}
|
||||
|
||||
void PDFWidgetFormManager::drawFormField(const PDFFormField* formField, AnnotationDrawParameters& parameters, bool edit) const
|
||||
{
|
||||
const PDFFormFieldWidgetEditor* editor = getEditor(formField);
|
||||
if (editor)
|
||||
{
|
||||
editor->draw(parameters, edit);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace pdf
|
||||
|
|
|
@ -53,7 +53,7 @@ public:
|
|||
/// based on field value is drawn.
|
||||
/// \param parameters Parameters
|
||||
/// \param edit Draw editor or static contents
|
||||
virtual void draw(AnnotationDrawParameters& parameters, bool edit) const;
|
||||
virtual void draw(AnnotationDrawParameters& parameters, bool edit) const override;
|
||||
|
||||
protected:
|
||||
/// This function is called every time, the focus state changes
|
||||
|
@ -104,7 +104,7 @@ public:
|
|||
|
||||
/// Returns true, if widget is focused.
|
||||
/// \param widget Widget annotation reference
|
||||
bool isFocused(PDFObjectReference widget) const;
|
||||
virtual bool isFocused(PDFObjectReference widget) const override;
|
||||
|
||||
/// Returns editor for form field
|
||||
PDFFormFieldWidgetEditor* getEditor(const PDFFormField* formField) const;
|
||||
|
@ -130,8 +130,13 @@ public:
|
|||
bool isValid() const { return editor != nullptr; }
|
||||
};
|
||||
|
||||
virtual bool isEditorDrawEnabled(const PDFObjectReference& reference) const override;
|
||||
virtual bool isEditorDrawEnabled(const PDFFormField* formField) const override;
|
||||
virtual void drawFormField(const PDFFormField* formField, AnnotationDrawParameters& parameters, bool edit) const override;
|
||||
|
||||
protected:
|
||||
virtual void updateFieldValues() override;
|
||||
virtual void onDocumentReset() override;
|
||||
|
||||
private:
|
||||
void updateFormWidgetEditors();
|
||||
|
|
Loading…
Reference in New Issue