9#include "formtextinput_p.h"
11#include "ui/errorlabel.h"
13#include <KLocalizedString>
23auto defaultValueRequiredErrorMessage()
25 return i18n(
"Error: Enter a value.");
28auto defaultInvalidEntryErrorMessage()
30 return i18n(
"Error: Enter a value in the correct format.");
37 name = iface->text(t);
43namespace Kleo::_detail
46class FormTextInputBase::Private
57 Private(FormTextInputBase *q)
59 , mValueRequiredErrorMessage{defaultValueRequiredErrorMessage()}
60 , mInvalidEntryErrorMessage{defaultInvalidEntryErrorMessage()}
66 void setLabelText(
const QString &text,
const QString &accessibleName);
67 void setHint(
const QString &text,
const QString &accessibleDescription);
68 QString errorMessage(Error error)
const;
69 QString accessibleErrorMessage(Error error)
const;
71 QString accessibleDescription()
const;
72 void updateAccessibleNameAndDescription();
78 std::shared_ptr<QValidator> mValidator;
81 QString mValueRequiredErrorMessage;
82 QString mAccessibleValueRequiredErrorMessage;
83 QString mInvalidEntryErrorMessage;
84 QString mAccessibleInvalidEntryErrorMessage;
85 Error mError = EntryOK;
86 bool mRequired =
false;
87 bool mEditingInProgress =
false;
90QString FormTextInputBase::Private::annotatedIfRequired(
const QString &text)
const
92 return mRequired ?
i18nc(
"@label label text (required)",
"%1 (required)", text)
96void FormTextInputBase::Private::updateLabel()
99 mLabel->setText(annotatedIfRequired(mLabelText));
103void FormTextInputBase::Private::setLabelText(
const QString &text,
const QString &accessibleName)
106 mAccessibleName = accessibleName.
isEmpty() ? text : accessibleName;
108 updateAccessibleNameAndDescription();
111void FormTextInputBase::Private::setHint(
const QString &text,
const QString &accessibleDescription)
116 mHintLabel->setVisible(!text.
isEmpty());
117 mHintLabel->setText(text);
118 mHintLabel->setAccessibleName(accessibleDescription.
isEmpty() ? text : accessibleDescription);
119 updateAccessibleNameAndDescription();
130QString FormTextInputBase::Private::errorMessage(Error error)
const
136 return mValueRequiredErrorMessage;
138 return mInvalidEntryErrorMessage;
143QString FormTextInputBase::Private::accessibleErrorMessage(Error error)
const
149 return mAccessibleValueRequiredErrorMessage;
151 return mAccessibleInvalidEntryErrorMessage;
156void FormTextInputBase::Private::updateError()
162 if (mRequired && !q->hasValue()) {
163 mError = EntryMissing;
164 }
else if (!q->hasAcceptableInput()) {
165 mError = InvalidEntry;
170 const auto currentErrorMessage = mErrorLabel->text();
171 const auto newErrorMessage = decoratedError(
errorMessage(mError));
172 if (newErrorMessage == currentErrorMessage) {
175 if (currentErrorMessage.isEmpty() && mEditingInProgress) {
184 mErrorLabel->setVisible(!newErrorMessage.isEmpty());
185 mErrorLabel->setText(newErrorMessage);
186 mErrorLabel->setAccessibleName(decoratedError(accessibleErrorMessage(mError)));
187 updateAccessibleNameAndDescription();
190QString FormTextInputBase::Private::accessibleDescription()
const
195 description = mHintLabel->accessibleName();
204void FormTextInputBase::Private::updateAccessibleNameAndDescription()
207 if (mAccessibleName.isEmpty()) {
210 const bool errorShown = mErrorLabel && mErrorLabel->isVisible();
215 const auto description = errorShown ? accessibleDescription() +
QLatin1StringView{
" "} + mErrorLabel->accessibleName()
216 : accessibleDescription();
217 if (mWidget && mWidget->accessibleDescription() != description) {
218 mWidget->setAccessibleDescription(description);
225 QString name = annotatedIfRequired(mAccessibleName);
228 +
i18nc(
"text for screen readers to indicate that the associated object, "
229 "such as a form field, has an error",
232 if (mLabel && mLabel->accessibleName() != name) {
233 mLabel->setAccessibleName(name);
235 if (mWidget && mWidget->accessibleName() != name) {
236 mWidget->setAccessibleName(name);
240FormTextInputBase::FormTextInputBase()
241 : d{new Private{this}}
245FormTextInputBase::~FormTextInputBase() =
default;
247QWidget *FormTextInputBase::widget()
const
252QLabel *FormTextInputBase::label()
const
257QLabel *FormTextInputBase::hintLabel()
const
259 return d->mHintLabel;
262ErrorLabel *FormTextInputBase::errorLabel()
const
264 return d->mErrorLabel;
267void FormTextInputBase::setLabelText(
const QString &text,
const QString &accessibleName)
269 d->setLabelText(text, accessibleName);
272void FormTextInputBase::setHint(
const QString &text,
const QString &accessibleDescription)
274 d->setHint(text, accessibleDescription);
277void FormTextInputBase::setIsRequired(
bool required)
279 d->mRequired = required;
281 d->updateAccessibleNameAndDescription();
284bool FormTextInputBase::isRequired()
const
289void FormTextInputBase::setValidator(
const std::shared_ptr<QValidator> &validator)
291 Q_ASSERT(!validator || !validator->parent());
293 d->mValidator = validator;
296void FormTextInputBase::setValueRequiredErrorMessage(
const QString &text,
const QString &accessibleText)
299 d->mValueRequiredErrorMessage = defaultValueRequiredErrorMessage();
301 d->mValueRequiredErrorMessage = text;
303 if (accessibleText.
isEmpty()) {
304 d->mAccessibleValueRequiredErrorMessage = d->mValueRequiredErrorMessage;
306 d->mAccessibleValueRequiredErrorMessage = accessibleText;
310void FormTextInputBase::setInvalidEntryErrorMessage(
const QString &text,
const QString &accessibleText)
313 d->mInvalidEntryErrorMessage = defaultInvalidEntryErrorMessage();
315 d->mInvalidEntryErrorMessage = text;
317 if (accessibleText.
isEmpty()) {
318 d->mAccessibleInvalidEntryErrorMessage = d->mInvalidEntryErrorMessage;
320 d->mAccessibleInvalidEntryErrorMessage = accessibleText;
324void FormTextInputBase::setToolTip(
const QString &toolTip)
327 d->mLabel->setToolTip(toolTip);
330 d->mWidget->setToolTip(toolTip);
334void FormTextInputBase::setWidget(
QWidget *widget)
336 auto parent = widget ? widget->
parentWidget() :
nullptr;
338 d->mLabel =
new QLabel{parent};
340 d->mLabel->setWordWrap(
true);
341 QFont font = d->mLabel->font();
343 d->mLabel->setFont(font);
344 d->mLabel->setBuddy(d->mWidget);
345 d->mHintLabel =
new QLabel{parent};
349 d->mHintLabel->setBuddy(d->mWidget);
350 d->mHintLabel->setVisible(
false);
351 d->mErrorLabel =
new ErrorLabel{parent};
352 d->mErrorLabel->setWordWrap(
true);
355 d->mErrorLabel->setBuddy(d->mWidget);
356 d->mErrorLabel->setVisible(
false);
360void FormTextInputBase::setEnabled(
bool enabled)
363 d->mLabel->setEnabled(enabled);
366 d->mWidget->setEnabled(enabled);
368 if (d->mErrorLabel) {
369 d->mErrorLabel->setVisible(enabled && !d->mErrorLabel->text().isEmpty());
373QString FormTextInputBase::currentError()
const
376 return d->errorMessage(d->mError);
381bool FormTextInputBase::validate(
const QString &text,
int pos)
const
390void FormTextInputBase::onTextChanged()
392 d->mEditingInProgress =
true;
396void FormTextInputBase::onEditingFinished()
398 d->mEditingInProgress =
false;
405bool Kleo::FormTextInput<QLineEdit>::hasValue()
const
407 const auto w = widget();
408 return w && !w->text().trimmed().isEmpty();
412bool Kleo::FormTextInput<QLineEdit>::hasAcceptableInput()
const
414 const auto w = widget();
415 return w && validate(w->text(), w->cursorPosition());
419void Kleo::FormTextInput<QLineEdit>::connectWidget()
421 const auto w = widget();
QString i18nc(const char *context, const char *text, const TYPE &arg...)
QString i18n(const char *text, const TYPE &arg...)
KCALUTILS_EXPORT QString errorMessage(const KCalendarCore::Exception &exception)
QAccessibleInterface * queryAccessibleInterface(QObject *object)
void setBold(bool enable)
void setTextFormat(Qt::TextFormat)
void setWordWrap(bool on)
void textChanged(const QString &text)
QMetaObject::Connection connect(const QObject *sender, PointerToMemberFunction signal, Functor functor)
bool isEmpty() const const