mirror of
https://invent.kde.org/graphics/okular
synced 2024-09-28 20:24:09 +00:00
Keystroke, format, validate, calculate events support for combo boxes.
Added keystroke, format, validate, calculate events for combo boxes. Also did some refactoring for recalculateForms method.
This commit is contained in:
parent
1cad230102
commit
5b449e5fdf
|
@ -245,9 +245,9 @@ void FormatTest::testDateFormat()
|
|||
QFETCH(QString, text);
|
||||
QFETCH(QString, result);
|
||||
|
||||
Okular::FormFieldText *fft = reinterpret_cast<Okular::FormFieldText *>(m_fields[fieldName]);
|
||||
fft->setText(text);
|
||||
m_document->processFormatAction(fft->additionalAction(Okular::FormField::FormatField), fft);
|
||||
Okular::FormField *ff = m_fields[fieldName];
|
||||
ff->setValue(QVariant(text));
|
||||
m_document->processFormatAction(ff->additionalAction(Okular::FormField::FormatField), ff);
|
||||
|
||||
QCOMPARE(m_formattedText, result);
|
||||
}
|
||||
|
|
|
@ -423,11 +423,12 @@ void KeystrokeTest::testDateKeystrokeCommit()
|
|||
QFETCH(QString, text);
|
||||
QFETCH(QString, result);
|
||||
|
||||
Okular::FormFieldText *fft = reinterpret_cast<Okular::FormFieldText *>(m_AFMethodsTestsFields[fieldName]);
|
||||
fft->setText(text);
|
||||
m_AFMethodsTestsDocument->processKeystrokeCommitAction(fft->additionalAction(Okular::FormField::FieldModified), fft);
|
||||
Okular::FormField *ff = m_AFMethodsTestsFields[fieldName];
|
||||
ff->setValue(QVariant(text));
|
||||
bool returnCode = true;
|
||||
m_AFMethodsTestsDocument->processKeystrokeCommitAction(ff->additionalAction(Okular::FormField::FieldModified), ff, returnCode);
|
||||
|
||||
QCOMPARE(fft->text(), result);
|
||||
QCOMPARE(ff->value().toString(), result);
|
||||
}
|
||||
|
||||
void KeystrokeTest::testDateKeystrokeCommit_data()
|
||||
|
|
|
@ -1205,34 +1205,29 @@ void DocumentPrivate::recalculateForms()
|
|||
if (form->id() == formId) {
|
||||
const Action *action = form->additionalAction(FormField::CalculateField);
|
||||
if (action) {
|
||||
FormFieldText *fft = dynamic_cast<FormFieldText *>(form);
|
||||
std::shared_ptr<Event> event;
|
||||
QString oldVal;
|
||||
if (fft) {
|
||||
if (dynamic_cast<FormFieldText *>(form) || dynamic_cast<FormFieldChoice *>(form)) {
|
||||
// Prepare text calculate event
|
||||
event = Event::createFormCalculateEvent(fft, m_pagesVector[pageIdx]);
|
||||
if (!m_scripter) {
|
||||
m_scripter = new Scripter(this);
|
||||
}
|
||||
m_scripter->setEvent(event.get());
|
||||
event = Event::createFormCalculateEvent(form, m_pagesVector[pageIdx]);
|
||||
const ScriptAction *linkscript = static_cast<const ScriptAction *>(action);
|
||||
executeScriptEvent(event, linkscript);
|
||||
// The value maybe changed in javascript so save it first.
|
||||
oldVal = fft->text();
|
||||
}
|
||||
oldVal = form->value().toString();
|
||||
|
||||
m_parent->processAction(action);
|
||||
if (event && fft) {
|
||||
// Update text field from calculate
|
||||
m_scripter->setEvent(nullptr);
|
||||
const QString newVal = event->value().toString();
|
||||
if (newVal != oldVal) {
|
||||
fft->setText(newVal);
|
||||
fft->setAppearanceText(newVal);
|
||||
if (const Okular::Action *action = fft->additionalAction(Okular::FormField::FormatField)) {
|
||||
// The format action handles the refresh.
|
||||
m_parent->processFormatAction(action, form);
|
||||
} else {
|
||||
Q_EMIT m_parent->refreshFormWidget(fft);
|
||||
pageNeedsRefresh = true;
|
||||
if (event) {
|
||||
// Update text field from calculate
|
||||
const QString newVal = event->value().toString();
|
||||
if (newVal != oldVal) {
|
||||
form->setValue(QVariant(newVal));
|
||||
form->setAppearanceValue(QVariant(newVal));
|
||||
if (const Okular::Action *action = form->additionalAction(Okular::FormField::FormatField)) {
|
||||
// The format action handles the refresh.
|
||||
m_parent->processFormatAction(action, form);
|
||||
} else {
|
||||
Q_EMIT m_parent->refreshFormWidget(form);
|
||||
pageNeedsRefresh = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -378,6 +378,45 @@ QString FormFieldChoice::exportValueForChoice(const QString &choice) const
|
|||
return d->exportValues.value(choice, choice);
|
||||
}
|
||||
|
||||
void FormFieldChoice::setValue(const QVariant &value)
|
||||
{
|
||||
if (choiceType() == ComboBox) {
|
||||
const QStringList availableChoices = choices();
|
||||
const QString valueToSet = value.toString();
|
||||
for (int i = 0; i < availableChoices.size(); i++) {
|
||||
if (valueToSet == availableChoices[i]) {
|
||||
const QList oneChoiceList = {i};
|
||||
setCurrentChoices(oneChoiceList);
|
||||
return; // We expect to set only one element for a combo box
|
||||
}
|
||||
}
|
||||
// If the value to be set is not present in the available choices
|
||||
setEditChoice(valueToSet);
|
||||
} else {
|
||||
// TODO what to set for ListBox.
|
||||
}
|
||||
}
|
||||
|
||||
QVariant FormFieldChoice::value() const
|
||||
{
|
||||
if (choiceType() == ComboBox) {
|
||||
if (currentChoices().isEmpty()) {
|
||||
return QVariant(editChoice());
|
||||
}
|
||||
return QVariant(choices().at(currentChoices().constFirst()));
|
||||
} else {
|
||||
// TODO what to return for ListBox. Temporarily return empty string.
|
||||
return QVariant(QString());
|
||||
}
|
||||
}
|
||||
|
||||
void FormFieldChoice::setAppearanceValue(const QVariant &value)
|
||||
{
|
||||
if (choiceType() == ComboBox) {
|
||||
setAppearanceChoiceText(value.toString());
|
||||
}
|
||||
}
|
||||
|
||||
class Okular::FormFieldSignaturePrivate : public Okular::FormFieldPrivate
|
||||
{
|
||||
public:
|
||||
|
|
32
core/form.h
32
core/form.h
|
@ -502,6 +502,38 @@ public:
|
|||
*/
|
||||
QString exportValueForChoice(const QString &choice) const;
|
||||
|
||||
/**
|
||||
* Sets the @p text which should be rendered by the PDF in the position of choice FormField.
|
||||
*
|
||||
* @since 24.12
|
||||
*/
|
||||
virtual void setAppearanceChoiceText(const QString &text) = 0;
|
||||
|
||||
/**
|
||||
* Sets the @p value asssociated with the choice form field.
|
||||
* It does not set anything for ListBox for now, only for the ComboBox.
|
||||
*
|
||||
* Expected type of @p value is QString.
|
||||
* @since 24.12
|
||||
*/
|
||||
void setValue(const QVariant &value) override;
|
||||
|
||||
/**
|
||||
* Returns the value associated with the choice form field.
|
||||
* In case of ComboBox, if there is any selection, then the selected value is returned, else the value entered in editText of the comboBox.
|
||||
* Returns empty string for ListBox for now.
|
||||
*
|
||||
* @since 24.12
|
||||
*/
|
||||
QVariant value() const override;
|
||||
|
||||
/**
|
||||
* Sets the appearance @p value associated with the form field.
|
||||
*
|
||||
* @since 24.12
|
||||
*/
|
||||
void setAppearanceValue(const QVariant &value) override;
|
||||
|
||||
protected:
|
||||
FormFieldChoice();
|
||||
|
||||
|
|
|
@ -257,10 +257,7 @@ std::shared_ptr<Event> Event::createFormCalculateEvent(FormField *target, Page *
|
|||
ret->setTargetPage(targetPage);
|
||||
ret->setTargetName(targetName);
|
||||
|
||||
const FormFieldText *fft = dynamic_cast<FormFieldText *>(target);
|
||||
if (fft) {
|
||||
ret->setValue(QVariant(fft->text()));
|
||||
}
|
||||
ret->setValue(target->value());
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
|
@ -377,6 +377,15 @@ void PopplerFormFieldChoice::setEditChoice(const QString &text)
|
|||
m_field->setEditChoice(text);
|
||||
}
|
||||
|
||||
void PopplerFormFieldChoice::setAppearanceChoiceText(const QString &text)
|
||||
{
|
||||
#if POPPLER_VERSION_MACRO >= QT_VERSION_CHECK(24, 8, 0)
|
||||
m_field->setAppearanceChoiceText(text);
|
||||
#else
|
||||
Q_UNUSED(text);
|
||||
#endif
|
||||
}
|
||||
|
||||
Qt::Alignment PopplerFormFieldChoice::textAlignment() const
|
||||
{
|
||||
return Qt::AlignTop | m_field->textAlignment();
|
||||
|
|
|
@ -114,6 +114,7 @@ public:
|
|||
void setCurrentChoices(const QList<int> &choices) override;
|
||||
QString editChoice() const override;
|
||||
void setEditChoice(const QString &text) override;
|
||||
void setAppearanceChoiceText(const QString &text) override;
|
||||
Qt::Alignment textAlignment() const override;
|
||||
bool canBeSpellChecked() const override;
|
||||
|
||||
|
|
|
@ -85,7 +85,7 @@ void FormWidgetsController::signalMouseAction(Okular::Action *action, Okular::Fo
|
|||
void FormWidgetsController::processScriptAction(Okular::Action *a, Okular::FormField *field, Okular::Annotation::AdditionalActionType type)
|
||||
{
|
||||
// If it's not a Action Script or if the field is not a FormText, handle it normally
|
||||
if (a->actionType() != Okular::Action::Script || field->type() != Okular::FormField::FormText) {
|
||||
if (a->actionType() != Okular::Action::Script || field->type() != Okular::FormField::FormText || field->type() != Okular::FormField::FormChoice) {
|
||||
Q_EMIT action(a);
|
||||
return;
|
||||
}
|
||||
|
@ -1065,6 +1065,7 @@ ComboEdit::ComboEdit(Okular::FormFieldChoice *choice, PageView *pageView)
|
|||
connect(this, &QComboBox::editTextChanged, this, &ComboEdit::slotValueChanged);
|
||||
connect(lineEdit(), &QLineEdit::cursorPositionChanged, this, &ComboEdit::slotValueChanged);
|
||||
|
||||
m_editing = false;
|
||||
setVisible(choice->isVisible());
|
||||
setCursor(Qt::ArrowCursor);
|
||||
m_prevCursorPos = lineEdit()->cursorPosition();
|
||||
|
@ -1090,10 +1091,19 @@ void ComboEdit::slotValueChanged()
|
|||
prevText = form->choices().at(form->currentChoices().constFirst());
|
||||
}
|
||||
|
||||
int cursorPos = lineEdit()->cursorPosition();
|
||||
int cursorPos;
|
||||
if (text != prevText) {
|
||||
Q_EMIT m_controller->formComboChangedByWidget(pageItem()->pageNumber(), form, currentText(), cursorPos, m_prevCursorPos, m_prevAnchorPos);
|
||||
if (form->additionalAction(Okular::FormField::FieldModified) && m_editing && !form->isReadOnly()) {
|
||||
m_controller->document()->processKeystrokeAction(form->additionalAction(Okular::FormField::FieldModified), form, lineEdit()->text(), m_prevCursorPos, m_prevAnchorPos);
|
||||
}
|
||||
cursorPos = lineEdit()->cursorPosition();
|
||||
if (text == lineEdit()->text()) {
|
||||
Q_EMIT m_controller->formComboChangedByWidget(pageItem()->pageNumber(), form, currentText(), cursorPos, m_prevCursorPos, m_prevAnchorPos);
|
||||
}
|
||||
} else {
|
||||
cursorPos = lineEdit()->cursorPosition();
|
||||
}
|
||||
|
||||
m_prevCursorPos = cursorPos;
|
||||
m_prevAnchorPos = cursorPos;
|
||||
if (lineEdit()->hasSelectedText()) {
|
||||
|
@ -1176,6 +1186,40 @@ bool ComboEdit::event(QEvent *e)
|
|||
Q_EMIT m_controller->requestRedo();
|
||||
return true;
|
||||
}
|
||||
} else if (e->type() == QEvent::FocusIn) {
|
||||
const auto ffc = static_cast<Okular::FormFieldChoice *>(m_ff);
|
||||
|
||||
QString prevText;
|
||||
if (ffc->currentChoices().isEmpty()) {
|
||||
prevText = ffc->editChoice();
|
||||
} else {
|
||||
prevText = ffc->choices().at(ffc->currentChoices().constFirst());
|
||||
}
|
||||
if (lineEdit()->text() != prevText) {
|
||||
lineEdit()->setText(prevText);
|
||||
}
|
||||
QFocusEvent *focusEvent = static_cast<QFocusEvent *>(e);
|
||||
if (focusEvent->reason() != Qt::ActiveWindowFocusReason) {
|
||||
if (const Okular::Action *action = m_ff->additionalAction(Okular::Annotation::FocusIn)) {
|
||||
m_controller->document()->processFocusAction(action, m_ff);
|
||||
}
|
||||
}
|
||||
setFocus();
|
||||
m_editing = true;
|
||||
} else if (e->type() == QEvent::FocusOut) {
|
||||
m_editing = false;
|
||||
|
||||
// Don't worry about focus events from other sources than the user FocusEvent to edit the field
|
||||
QFocusEvent *focusEvent = static_cast<QFocusEvent *>(e);
|
||||
if (focusEvent->reason() == Qt::OtherFocusReason || focusEvent->reason() == Qt::ActiveWindowFocusReason) {
|
||||
return true;
|
||||
}
|
||||
|
||||
m_controller->document()->processKVCFActions(m_ff);
|
||||
|
||||
if (const Okular::Action *action = m_ff->additionalAction(Okular::Annotation::FocusOut)) {
|
||||
m_controller->document()->processFocusAction(action, m_ff);
|
||||
}
|
||||
}
|
||||
return QComboBox::event(e);
|
||||
}
|
||||
|
|
|
@ -317,6 +317,7 @@ private Q_SLOTS:
|
|||
private:
|
||||
int m_prevCursorPos;
|
||||
int m_prevAnchorPos;
|
||||
bool m_editing;
|
||||
DECLARE_ADDITIONAL_ACTIONS
|
||||
|
||||
protected:
|
||||
|
|
Loading…
Reference in a new issue