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()}
 
   64    QString annotatedIfRequired(
const QString &text) 
const;
 
   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();
 
   74    QPointer<QLabel> mLabel;
 
   75    QPointer<QLabel> mHintLabel;
 
   76    QPointer<QWidget> mWidget;
 
   77    QPointer<ErrorLabel> mErrorLabel;
 
   78    std::shared_ptr<QValidator> mValidator;
 
   80    QString mAccessibleName;
 
   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();
 
  124QString decoratedError(
const QString &text)
 
  126    return text.
isEmpty() ? QString() : 
i18nc(
"@info", 
"Error: %1", text);
 
  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);
 
  227        name += QLatin1StringView{
", "}
 
  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::widgetInternal()
 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