File indexing completed on 2024-05-19 04:29:53

0001 /*
0002  * SPDX-FileCopyrightText: 2021-2023 Alvin Wong <alvin@alvinhc.com>
0003  *
0004  * SPDX-License-Identifier: GPL-3.0-or-later
0005  */
0006 
0007 #include "KisSpinBoxI18nHelper.h"
0008 
0009 #include <QDebug>
0010 #include <QSpinBox>
0011 
0012 namespace KisSpinBoxI18nHelper
0013 {
0014     namespace
0015     {
0016         const char *const HANDLER_PROPERTY_NAME = "_kis_KisSpinBoxI18nHelper_handler";
0017 
0018         struct HandlerWrapper
0019         {
0020             std::function<void(int)> m_handler;
0021 
0022             HandlerWrapper() {}
0023 
0024             explicit HandlerWrapper(std::function<void(int)> handler)
0025                 : m_handler(handler)
0026             {}
0027         };
0028 
0029     } /* namespace */
0030 
0031 } /* namespace KisSpinBoxI18nHelper */
0032 
0033 Q_DECLARE_METATYPE(KisSpinBoxI18nHelper::HandlerWrapper)
0034 
0035 namespace KisSpinBoxI18nHelper
0036 {
0037     void install(QSpinBox *spinBox, std::function<QString(int)> messageFn)
0038     {
0039         const auto changeHandler = [messageFn, spinBox](int value) {
0040             setText(spinBox, messageFn(value));
0041         };
0042         // Apply prefix/suffix with existing value immediately.
0043         changeHandler(spinBox->value());
0044         QObject::connect(spinBox, QOverload<int>::of(&QSpinBox::valueChanged), changeHandler);
0045         spinBox->setProperty(HANDLER_PROPERTY_NAME, QVariant::fromValue(HandlerWrapper(changeHandler)));
0046     }
0047 
0048     bool update(QSpinBox *spinBox)
0049     {
0050         const QVariant handlerVariant = spinBox->property(HANDLER_PROPERTY_NAME);
0051         if (!handlerVariant.isValid()) {
0052             qWarning() << "KisSpinBoxI18nHelper::update called with" << spinBox
0053                        << "but it does not have the property" << HANDLER_PROPERTY_NAME;
0054             return false;
0055         }
0056         if (!handlerVariant.canConvert<HandlerWrapper>()) {
0057             qWarning() << "KisSpinBoxI18nHelper::update called with" << spinBox
0058                        << "but its property" << HANDLER_PROPERTY_NAME << "is invalid";
0059             return false;
0060         }
0061         const HandlerWrapper handler = handlerVariant.value<HandlerWrapper>();
0062         handler.m_handler(spinBox->value());
0063         return true;
0064     }
0065 
0066     template<typename TSpinBox>
0067     static void setTextGeneric(TSpinBox *spinBox, const QStringView textTemplate)
0068     {
0069         const QLatin1String placeholder{"{n}"};
0070         const qsizetype idx = textTemplate.indexOf(placeholder);
0071         if (idx >= 0) {
0072             spinBox->setPrefix(textTemplate.left(idx).toString());
0073             spinBox->setSuffix(textTemplate.mid(idx + placeholder.size()).toString());
0074         } else {
0075             spinBox->setPrefix(QString());
0076             spinBox->setSuffix(textTemplate.toString());
0077         }
0078     }
0079 
0080     void setText(QSpinBox *spinBox, const QStringView textTemplate)
0081     {
0082         setTextGeneric(spinBox, textTemplate);
0083     }
0084 
0085     void setText(QDoubleSpinBox *spinBox, const QStringView textTemplate)
0086     {
0087         setTextGeneric(spinBox, textTemplate);
0088     }
0089 
0090 } /* namespace KisSpinBoxI18nHelper */