File indexing completed on 2024-05-12 04:44:32
0001 // SPDX-FileCopyrightText: Lukas Sommer <sommerluk@gmail.com> 0002 // SPDX-License-Identifier: BSD-2-Clause OR MIT 0003 0004 // Own headers 0005 // First the interface, which forces the header to be self-contained. 0006 #include "extendeddoublevalidator.h" 0007 // Second, the private implementation. 0008 #include "extendeddoublevalidator_p.h" // IWYU pragma: associated 0009 0010 #include "constpropagatinguniquepointer.h" 0011 #include <qstringbuilder.h> 0012 class QObject; 0013 0014 namespace PerceptualColor 0015 { 0016 /** @brief Default constructor 0017 * @param parent pointer to the parent widget, if any */ 0018 ExtendedDoubleValidator::ExtendedDoubleValidator(QObject *parent) 0019 : QDoubleValidator(parent) 0020 , d_pointer(new ExtendedDoubleValidatorPrivate) 0021 { 0022 } 0023 0024 /** @brief Destructor */ 0025 ExtendedDoubleValidator::~ExtendedDoubleValidator() noexcept 0026 { 0027 } 0028 0029 // No documentation here (documentation of properties 0030 // and its getters are in the header) 0031 QString ExtendedDoubleValidator::prefix() const 0032 { 0033 return d_pointer->m_prefix; 0034 } 0035 0036 /** @brief Set the @ref prefix property. */ 0037 void ExtendedDoubleValidator::setPrefix(const QString &prefix) 0038 { 0039 if (prefix != d_pointer->m_prefix) { 0040 d_pointer->m_prefix = prefix; 0041 Q_EMIT prefixChanged(prefix); 0042 } 0043 } 0044 0045 /** @brief Set the @ref suffix property. */ 0046 void ExtendedDoubleValidator::setSuffix(const QString &suffix) 0047 { 0048 if (suffix != d_pointer->m_suffix) { 0049 d_pointer->m_suffix = suffix; 0050 Q_EMIT suffixChanged(suffix); 0051 } 0052 } 0053 0054 // No documentation here (documentation of properties 0055 // and its getters are in the header) 0056 QString ExtendedDoubleValidator::suffix() const 0057 { 0058 return d_pointer->m_suffix; 0059 } 0060 0061 QValidator::State ExtendedDoubleValidator::validate(QString &input, int &pos) const 0062 { 0063 QString myInput = input; 0064 int myPos = pos; 0065 0066 // IF (m_prefix.isEmpty && !m_prefix.isNull) 0067 // THEN input.startsWith(m_prefix) 0068 // → will be true IF !input.isEmpty 0069 // → will be false IF input.isEmpty 0070 // This is inconsistent. Therefore, we test is m_prefix is empty. 0071 // If not, we do nothing. 0072 // The same also applies to suffix. 0073 // TODO Bug report, because Qt documentation says at 0074 // https://doc.qt.io/qt-6/qstring.html#distinction-between-null-and-empty-strings 0075 // (and at its Qt-5-counterpart): 0076 // “All functions except isNull() treat null strings the same 0077 // as empty strings.” 0078 // This is apparently wrong (at least for Qt 5). 0079 if (!d_pointer->m_prefix.isEmpty()) { 0080 if (myInput.startsWith(d_pointer->m_prefix)) { 0081 myInput.remove(0, d_pointer->m_prefix.size()); 0082 // In Qt6, QString::size() returns a qsizetype aka “long long int”. 0083 // HACK We do a simple static_cast because a so long QString isn’t 0084 // useful anyway. 0085 myPos -= static_cast<int>(d_pointer->m_prefix.size()); 0086 } else { 0087 return QValidator::State::Invalid; 0088 } 0089 } 0090 if (!d_pointer->m_suffix.isEmpty()) { 0091 if (myInput.endsWith(d_pointer->m_suffix)) { 0092 myInput.chop(d_pointer->m_suffix.size()); 0093 } else { 0094 return QValidator::State::Invalid; 0095 } 0096 } 0097 0098 QValidator::State result = QDoubleValidator::validate(myInput, myPos); 0099 // Following the Qt documentation, QValidator::validate() is allowed 0100 // and indented to make changes to the arguments passed by reference 0101 // (“input” and “pos”). However, we use its child class QDoubleValidator. 0102 // The documentation of QDoubleValidator states that the “pos” argument 0103 // is not used. Therefore, write back only the “input” argument. 0104 input = d_pointer->m_prefix + myInput + d_pointer->m_suffix; 0105 0106 return result; 0107 } 0108 0109 } // namespace PerceptualColor