File indexing completed on 2024-05-12 16:02:28
0001 /* 0002 * SPDX-FileCopyrightText: 2017 Laurent Valentin Jospin <laurent.valentin@famillejospin.ch> 0003 * 0004 * SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 0007 #ifndef KISSPINBOXUNITMANAGER_H 0008 #define KISSPINBOXUNITMANAGER_H 0009 0010 #include <QObject> 0011 #include <QStringList> 0012 #include <QAbstractListModel> 0013 0014 #include "kritawidgetutils_export.h" 0015 0016 class KisSpinBoxUnitManager; 0017 class KisSpinBoxUnitManagerBuilder; 0018 class KisSpinBoxUnitManagerFactory; 0019 0020 /*! 0021 * \brief The KisSpinBoxUnitManagerFactory class is a factory that is used to build a default KisSpinBoxUnitManager. 0022 * \see KisSpinBoxUnitManagerBuilder 0023 */ 0024 class KRITAWIDGETUTILS_EXPORT KisSpinBoxUnitManagerFactory 0025 { 0026 public: 0027 0028 static KisSpinBoxUnitManager* buildDefaultUnitManager(QObject* parent); 0029 //! \brief set a builder the factory can use. The factory should take on the lifecycle of the builder, so to delete it call clearUnitManagerBuilder(); 0030 static void setDefaultUnitManagerBuilder(KisSpinBoxUnitManagerBuilder* pBuilder); 0031 static void clearUnitManagerBuilder(); 0032 0033 private: 0034 0035 static KisSpinBoxUnitManagerBuilder* builder; 0036 0037 }; 0038 0039 /*! 0040 * \brief The KisSpinBoxUnitManagerBuilder class is the base class, used in the strategy pattern of KisSpinBoxUnitManagerFactory. 0041 * \see KisSpinBoxUnitManagerFactory. 0042 */ 0043 class KRITAWIDGETUTILS_EXPORT KisSpinBoxUnitManagerBuilder 0044 { 0045 0046 public: 0047 0048 virtual ~KisSpinBoxUnitManagerBuilder() {} 0049 0050 virtual KisSpinBoxUnitManager* buildUnitManager(QObject* parent) = 0; //this pure virtual function is used to build a unitmanager, it will be used by the unitManagerFactory. 0051 }; 0052 0053 /** 0054 * @brief The KisSpinBoxUnitManager class is an abstract interface for the unitspinboxes classes to manage different type of units. 0055 * 0056 * The class differentiates between unit dimension (distance, angle, time). 0057 * 0058 * The class allows to convert values between reference unit and apparent unit, but also to get other information like possible units symbols. 0059 * 0060 * This class doesn't allow to use relative units (units whose conversion factor is dependent of the context), even if it's private data is prepared to manage it. 0061 * The reason for this is that from the library of this class it is very hard to easily access the information needed. So all will be managed by subclasses in other libs. 0062 * 0063 * The class is a subclass of QAbstractListModel, so that available list of units is easily accessed by other Qt standard components, like QComboBoxes. 0064 * 0065 */ 0066 class KRITAWIDGETUTILS_EXPORT KisSpinBoxUnitManager : public QAbstractListModel 0067 { 0068 Q_OBJECT 0069 0070 public: 0071 0072 enum UnitDimension{ 0073 LENGTH = 0, //length, print size, reference is point 0074 IMLENGTH = 1, //length, image size, reference is pixel. This dimension is used when the printing units must be avoided 0075 ANGLE = 2, 0076 TIME = 3 0077 }; 0078 0079 static inline bool isUnitId(int code) { return (code == LENGTH || code == ANGLE || code == TIME); } 0080 0081 //! \brief this list holds the symbols of the reference unit per dimension. The index is equal to the value in UnitDimension so that the dimension name can be used to index the list. 0082 static const QStringList referenceUnitSymbols; 0083 0084 enum Constrain{ 0085 NOCONSTR = 0, 0086 REFISINT = 1, 0087 VALISINT = 2 0088 0089 }; 0090 0091 Q_DECLARE_FLAGS(Constrains, Constrain) 0092 0093 explicit KisSpinBoxUnitManager(QObject *parent = 0); 0094 ~KisSpinBoxUnitManager() override; 0095 0096 int getUnitDimensionType() const; 0097 QString getReferenceUnitSymbol() const; 0098 QString getApparentUnitSymbol() const; 0099 0100 //! \brief get the position of the apparent unit in the list of units. It is useful if we want to build a model for combo-box based unit management. 0101 int getApparentUnitId() const; 0102 0103 //! \brief get a hint of how many decimals the spinbox needs to display. 0104 int getApparentUnitRecommandedDecimals() const; 0105 0106 virtual QStringList getsUnitSymbolList(bool withName = false) const; 0107 0108 qreal getReferenceValue(double apparentValue) const; 0109 qreal getApparentValue(double refValue) const; 0110 0111 //! \brief gets the conversion factor of a managed unit, or -1 in case of error. This method is the one that needs to be overridden to extend the ability of the KisSpinBoxUnitManager. 0112 virtual qreal getConversionFactor(int dim, QString symbol) const; 0113 //! \brief some units conversions are done via an affine transform, not just a linear transform. This function gives the constant of this affine transform (usually 0). 0114 virtual qreal getConversionConstant(int dim, QString symbol) const; 0115 0116 int rowCount(const QModelIndex &parent = QModelIndex()) const override; 0117 QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; 0118 0119 Q_SIGNALS: 0120 0121 void unitDimensionChanged(int dimCode); 0122 void unitAboutToChange(); 0123 void unitChanged(QString symbol); 0124 void unitChanged(int index); 0125 void conversionFactorChanged(qreal newConversionFactor, qreal oldConversionFactor) const; 0126 void conversionConstantChanged(qreal newConversionFactor, qreal oldConversionFactor) const; 0127 void unitListChanged(); 0128 0129 public Q_SLOTS: 0130 0131 void setUnitDimension(UnitDimension dimension); 0132 void setApparentUnitFromSymbol(QString pSymbol); 0133 void selectApparentUnitFromIndex(int index); 0134 0135 void syncWithOtherUnitManager(KisSpinBoxUnitManager* other); 0136 void clearSyncWithOtherUnitManager(KisSpinBoxUnitManager* other); 0137 0138 protected: 0139 0140 class Private; 0141 Private * d; 0142 0143 //! \brief convert a unitChanged signal with a QString to one with an index. 0144 void newUnitSymbolToUnitIndex(QString symbol); 0145 0146 //! \brief indicate if the unit manager has some kind of way of using a percent unit, used by the main class to add percent when necessary. 0147 virtual bool hasPercent(int unitDim) const; 0148 0149 //unit's that may be used only if access to the document information exists. 0150 static const QStringList documentRelativeLengthUnitSymbols; 0151 static const QStringList documentRelativeTimeUnitSymbols; 0152 0153 void recomputeConversionFactor() const; 0154 void recomputeConvesrionConstant() const; 0155 0156 //! \brief calling this method gives access to document relative units. Only subclasses that manage those units should call it. 0157 void grantDocumentRelativeUnits(); 0158 0159 }; 0160 0161 #endif // KISSPINBOXUNITMANAGER_H