File indexing completed on 2024-05-12 04:44:34

0001 // SPDX-FileCopyrightText: Lukas Sommer <sommerluk@gmail.com>
0002 // SPDX-License-Identifier: BSD-2-Clause OR MIT
0003 
0004 #ifndef MULTISPINBOX_P_H
0005 #define MULTISPINBOX_P_H
0006 
0007 // Include the header of the public class of this private implementation.
0008 // #include "multispinbox.h"
0009 
0010 #include "constpropagatingrawpointer.h"
0011 #include "helperqttypes.h"
0012 #include "multispinboxsection.h"
0013 #include <qaccessiblewidget.h>
0014 #include <qglobal.h>
0015 #include <qlist.h>
0016 #include <qobject.h>
0017 #include <qpointer.h>
0018 #include <qstring.h>
0019 class QAccessibleInterface;
0020 
0021 #if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
0022 #include <qtmetamacros.h>
0023 #else
0024 #include <qobjectdefs.h>
0025 #endif
0026 
0027 namespace PerceptualColor
0028 {
0029 class ExtendedDoubleValidator;
0030 class MultiSpinBox;
0031 
0032 /** @internal
0033  *
0034  *  @brief Private implementation within the <em>Pointer to
0035  *  implementation</em> idiom */
0036 class MultiSpinBoxPrivate final : public QObject
0037 {
0038     Q_OBJECT
0039 
0040 public:
0041     explicit MultiSpinBoxPrivate(MultiSpinBox *backLink);
0042     /** @brief Default destructor
0043      *
0044      * The destructor is non-<tt>virtual</tt> because
0045      * the class as a whole is <tt>final</tt>. */
0046     virtual ~MultiSpinBoxPrivate() noexcept override = default;
0047 
0048     /** @brief Only for unit tests. */
0049     friend class TestMultiSpinBox;
0050 
0051     // constexpr
0052     /** @brief Default value of a section */
0053     static constexpr double defaultSectionValue = 0;
0054 
0055     /** @brief Counter for all actions added
0056      * by @ref MultiSpinBox::addActionButton. */
0057     int m_actionButtonCount = 0;
0058     /** @brief Holds the index of the currently selected section.
0059      * @sa @ref setCurrentIndexAndUpdateTextAndSelectValue
0060      * @sa @ref setCurrentIndexWithoutUpdatingText */
0061     QListSizeType m_currentIndex = 0;
0062     /** @brief Holds the data for the sections.
0063      *
0064      * This list is guaranteed to contain at least <em>one</em> section.
0065      *
0066      * @sa @ref MultiSpinBox::sectionConfigurations()
0067      * @sa @ref MultiSpinBox::setSectionConfigurations() */
0068     QList<MultiSpinBoxSection> m_sectionConfigurations;
0069     /** @brief Internal storage for
0070      * property @ref MultiSpinBox::sectionValues. */
0071     QList<double> m_sectionValues = QList<double>{MultiSpinBoxPrivate::defaultSectionValue};
0072     /** @brief The string of everything <em>after</em> the value of the
0073      * current section.
0074      *
0075      * This includes the suffix of the current section and everything
0076      * (prefixes, values and suffixes) of all sections that come after
0077      * the current sections. */
0078     QString m_textAfterCurrentValue;
0079     /** @brief The string of everything <em>before</em> the value of the
0080      * current section.
0081      *
0082      * This includes everything (prefixes, values and suffixes) of all
0083      * sections that come before the current section, and the prefix
0084      * of the current section. */
0085     QString m_textBeforeCurrentValue;
0086     /** @brief The string of the value of the current section. */
0087     QString m_textOfCurrentValue;
0088     /** @brief The validator for the <tt>QLineEdit</tt>.
0089      *
0090      * This validator allows changes only to the <em>current</em> section.
0091      *
0092      * If the current section changes, also this validator’s configuration
0093      * will be adapted to cover the new current section.
0094      *
0095      * @note It is <em>not</em> possible to change various values at the
0096      * same time, for example by marking all the current text and use
0097      * Ctrl-V to past a complete new value from the clipboard. This would
0098      * be impossible to parse reliably, because the prefixes and suffixes
0099      * of each section might contain (localized) digits that would be
0100      * difficult to differentiate from the actual value. */
0101     QPointer<ExtendedDoubleValidator> m_validator;
0102 
0103     // Functions
0104     [[nodiscard]] QString formattedValue(QListSizeType index) const;
0105     [[nodiscard]] bool isCursorTouchingCurrentSectionValue() const;
0106     void setCurrentIndexAndUpdateTextAndSelectValue(QListSizeType newIndex);
0107     void setCurrentIndexToZeroAndUpdateTextAndSelectValue();
0108     void setCurrentIndexWithoutUpdatingText(QListSizeType newIndex);
0109     void setSectionValuesWithoutFurtherUpdating(const QList<double> &newSectionValues);
0110     void updatePrefixValueSuffixText();
0111 
0112 public Q_SLOTS:
0113     void reactOnCursorPositionChange(const int oldPos, const int newPos);
0114     void updateCurrentValueFromText(const QString &lineEditText);
0115 
0116 private:
0117     Q_DISABLE_COPY(MultiSpinBoxPrivate)
0118 
0119     /** @brief Pointer to the object from which <em>this</em> object
0120      *  is the private implementation. */
0121     ConstPropagatingRawPointer<MultiSpinBox> q_pointer;
0122 };
0123 
0124 /** @internal
0125  *
0126  * @brief Interface for accessible objects. */
0127 class AccessibleMultiSpinBox : public QAccessibleWidget
0128 {
0129 public:
0130     explicit AccessibleMultiSpinBox(MultiSpinBox *w);
0131     virtual ~AccessibleMultiSpinBox() override;
0132     [[nodiscard]] static QAccessibleInterface *factory(const QString &classname, QObject *object);
0133 };
0134 
0135 } // namespace PerceptualColor
0136 
0137 #endif // MULTISPINBOX_P_H