File indexing completed on 2024-04-21 04:41:51
0001 /* This file is part of the KDE project 0002 Copyright (C) 1998 1999 Reginald Stadlbauer <reggie@kde.org> 0003 Copyright (C) 1998 1999 Torben Weis <weis@kde.org> 0004 Copyright (C) 2004 Nicolas GOUTTE <goutte@kde.org> 0005 Copyright (C) 2010 Thomas Zander <zander@kde.org> 0006 Copyright (C) 2012 Friedrich W. H. Kossebau <kossebau@kde.org> 0007 Copyright (C) 2017 Jarosław Staniek <staniek@kde.org> 0008 0009 This library is free software; you can redistribute it and/or 0010 modify it under the terms of the GNU Library General Public 0011 License as published by the Free Software Foundation; either 0012 version 2 of the License, or (at your option) any later version. 0013 0014 This library is distributed in the hope that it will be useful, 0015 but WITHOUT ANY WARRANTY; without even the implied warranty of 0016 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 0017 Library General Public License for more details. 0018 0019 You should have received a copy of the GNU Library General Public License 0020 along with this library; see the file COPYING.LIB. If not, write to 0021 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 0022 * Boston, MA 02110-1301, USA. 0023 */ 0024 0025 #ifndef KREPORTUNIT_H 0026 #define KREPORTUNIT_H 0027 0028 #include <math.h> // for floor 0029 0030 #include <QCoreApplication> 0031 #include <QString> 0032 #include <QDebug> 0033 #include <QMetaType> 0034 0035 #include "kreport_export.h" 0036 0037 // 1 inch ^= 72 pt 0038 // 1 inch ^= 25.399956 mm (-pedantic ;p) 0039 // 1 pt = 1/12 pi 0040 // 1 pt ^= 0.0077880997 cc 0041 // 1 cc = 12 dd 0042 // Note: I don't use division but multiplication with the inverse value 0043 // because it's faster ;p (Werner) 0044 #define POINT_TO_MM(px) qreal((px)*0.352777167) 0045 #define MM_TO_POINT(mm) qreal((mm)*2.83465058) 0046 #define POINT_TO_CM(px) qreal((px)*0.0352777167) 0047 #define CM_TO_POINT(cm) qreal((cm)*28.3465058) 0048 #define POINT_TO_DM(px) qreal((px)*0.00352777167) 0049 #define DM_TO_POINT(dm) qreal((dm)*283.465058) 0050 #define POINT_TO_INCH(px) qreal((px)*0.01388888888889) 0051 #define INCH_TO_POINT(inch) qreal((inch)*72.0) 0052 #define MM_TO_INCH(mm) qreal((mm)*0.039370147) 0053 #define INCH_TO_MM(inch) qreal((inch)*25.399956) 0054 #define POINT_TO_PI(px) qreal((px)*0.083333333) 0055 #define POINT_TO_CC(px) qreal((px)*0.077880997) 0056 #define PI_TO_POINT(pi) qreal((pi)*12) 0057 #define CC_TO_POINT(cc) qreal((cc)*12.840103) 0058 0059 /*! 0060 * @brief Converts between different units 0061 * 0062 * KReportUnit stores everything in pt (using "qreal") internally. 0063 * When displaying a value to the user, the value is converted to the user's unit 0064 * of choice, and rounded to a reasonable precision to avoid 0.999999 0065 * 0066 * For implementing the selection of a unit type in the UI use the allTypes() method. 0067 * it ensure the same order of the unit types in all places, with the order not 0068 * bound to the order in the enum so ABI-compatible extension is possible. 0069 */ 0070 class KREPORT_EXPORT KReportUnit 0071 { 0072 Q_DECLARE_TR_FUNCTIONS(KReportUnit) 0073 public: 0074 /** Length units supported by %KReport. */ 0075 enum class Type { 0076 Invalid, 0077 Millimeter, 0078 Centimeter, 0079 Decimeter, 0080 Inch, 0081 Pica, 0082 Cicero, 0083 Point, ///< Postscript point, 1/72th of an Inco 0084 Pixel, 0085 Last = Pixel ///< internal 0086 }; 0087 0088 /** 0089 * @brief Constructs invalid unit 0090 * 0091 * @since 3.1 0092 */ 0093 KReportUnit(); 0094 0095 /** Construct unit with given type and factor. */ 0096 explicit KReportUnit(Type type, qreal factor = 1.0); 0097 0098 KReportUnit(const KReportUnit &other); 0099 0100 ~KReportUnit(); 0101 0102 /// Assigns specified type and factor 1.0 to the object 0103 /// @param unit Type of unit 0104 KReportUnit& operator=(Type type); 0105 0106 KReportUnit& operator=(const KReportUnit& other); 0107 0108 bool operator!=(const KReportUnit &other) const; 0109 0110 bool operator==(const KReportUnit &other) const; 0111 0112 /** 0113 * @brief Returns true if type of this unit is valid 0114 * 0115 * @since 3.1 0116 */ 0117 bool isValid() const; 0118 0119 /** 0120 * @brief Returns list of all supported types (without Invalid) 0121 * 0122 * @since 3.1 0123 */ 0124 static QList<Type> allTypes(); 0125 0126 /** Returns the type of this unit */ 0127 KReportUnit::Type type() const; 0128 0129 /** 0130 * @brief Returns (translated) description string for type of this unit 0131 * 0132 * @since 3.1 0133 */ 0134 QString description() const; 0135 0136 /** 0137 * @brief Returns (translated) description string for given unit type 0138 * 0139 * @since 3.1 0140 */ 0141 static QString description(KReportUnit::Type type); 0142 0143 /** 0144 * @brief Returns the list of (translated) description strings for given list of types 0145 * 0146 * @since 3.1 0147 */ 0148 static QStringList descriptions(const QList<Type> &types); 0149 0150 void setFactor(qreal factor); 0151 0152 qreal factor() const; 0153 0154 /** 0155 * Prepare ptValue to be displayed in pt 0156 * This method will round to 0.001 precision 0157 */ 0158 static inline qreal toPoint(qreal ptValue) 0159 { 0160 // No conversion, only rounding (to 0.001 precision) 0161 return floor(ptValue * 1000.0) / 1000.0; 0162 } 0163 0164 /** 0165 * Prepare ptValue to be displayed in mm 0166 * This method will round to 0.0001 precision, use POINT_TO_MM() for lossless conversion. 0167 */ 0168 static inline qreal toMillimeter(qreal ptValue) 0169 { 0170 // "mm" values are rounded to 0.0001 millimeters 0171 return floor(POINT_TO_MM(ptValue) * 10000.0) / 10000.0; 0172 } 0173 0174 /** 0175 * Prepare ptValue to be displayed in cm 0176 * This method will round to 0.0001 precision, use POINT_TO_CM() for lossless conversion. 0177 */ 0178 static inline qreal toCentimeter(qreal ptValue) 0179 { 0180 return floor(POINT_TO_CM(ptValue) * 10000.0) / 10000.0; 0181 } 0182 0183 /** 0184 * Prepare ptValue to be displayed in dm 0185 * This method will round to 0.0001 precision, use POINT_TO_DM() for lossless conversion. 0186 */ 0187 static inline qreal toDecimeter(qreal ptValue) 0188 { 0189 return floor(POINT_TO_DM(ptValue) * 10000.0) / 10000.0; 0190 } 0191 0192 /** 0193 * Prepare ptValue to be displayed in inch 0194 * This method will round to 0.00001 precision, use POINT_TO_INCH() for lossless conversion. 0195 */ 0196 static inline qreal toInch(qreal ptValue) 0197 { 0198 // "in" values are rounded to 0.00001 inches 0199 return floor(POINT_TO_INCH(ptValue) * 100000.0) / 100000.0; 0200 } 0201 0202 /** 0203 * Prepare ptValue to be displayed in pica 0204 * This method will round to 0.00001 precision, use POINT_TO_PI() for lossless conversion. 0205 */ 0206 static inline qreal toPica(qreal ptValue) 0207 { 0208 // "pi" values are rounded to 0.00001 inches 0209 return floor(POINT_TO_PI(ptValue) * 100000.0) / 100000.0; 0210 } 0211 0212 /** 0213 * Prepare ptValue to be displayed in cicero 0214 * This method will round to 0.00001 precision, use POINT_TO_CC() for lossless conversion. 0215 */ 0216 static inline qreal toCicero(qreal ptValue) 0217 { 0218 // "cc" values are rounded to 0.00001 inches 0219 return floor(POINT_TO_CC(ptValue) * 100000.0) / 100000.0; 0220 } 0221 0222 /** 0223 * convert the given value directly from one unit to another with high accuracy 0224 */ 0225 static qreal convertFromUnitToUnit(qreal value, const KReportUnit &fromUnit, 0226 const KReportUnit &toUnit, qreal factor = 1.0); 0227 0228 /** 0229 * convert the given value directly from one unit to another with high accuracy 0230 */ 0231 static QPointF convertFromUnitToUnit(const QPointF &value, 0232 const KReportUnit &fromUnit, 0233 const KReportUnit &toUnit); 0234 0235 /** 0236 * convert the given value directly from one unit to another with high accuracy 0237 */ 0238 static QSizeF convertFromUnitToUnit(const QSizeF &value, const KReportUnit &fromUnit, 0239 const KReportUnit &toUnit); 0240 0241 /** 0242 * This method is the one to use to display a value in a dialog 0243 * \return the value @a ptValue converted to unit and rounded, ready to be displayed 0244 */ 0245 qreal toUserValue(qreal ptValue) const; 0246 0247 /** 0248 * Convert the value @a ptValue to a given unit @a unit 0249 * Unlike KReportUnit::ptToUnit the return value remains unrounded, so that it can be used in complex calculation 0250 * \return the converted value 0251 */ 0252 static qreal ptToUnit(qreal ptValue, const KReportUnit &unit); 0253 0254 /// This method is the one to use to display a value in a dialog 0255 /// @return the value @a ptValue converted the unit and rounded, ready to be displayed 0256 QString toUserStringValue(qreal ptValue) const; 0257 0258 //! @return the value converted to points with high accuracy 0259 qreal convertToPoint(qreal value) const; 0260 0261 //! @return the value converted from points to the actual unit with high accuracy 0262 qreal convertFromPoint(qreal ptValue) const; 0263 0264 //! @return the value converted from points to the actual unit with high accuracy 0265 QPointF convertFromPoint(const QPointF &ptValue) const; 0266 0267 //! @return the value converted from points to the actual unit with high accuracy 0268 QSizeF convertFromPoint(const QSizeF &ptValue) const; 0269 0270 //! Equal to convertToPoint(), use convertToPoint() instead for clarity 0271 inline qreal fromUserValue(qreal value) const { return convertToPoint(value); } 0272 0273 /// @return the value converted to points with high accuracy 0274 QPointF convertToPoint(const QPointF &value) const; 0275 0276 /// @return the value converted to points with high accuracy 0277 QSizeF convertToPoint(const QSizeF &value) const; 0278 0279 /// @return the value converted to points with high accuracy 0280 /// @param value value entered by the user 0281 /// @param ok if set, the pointed bool is set to true if the value could be 0282 /// converted to a qreal, and to false otherwise. 0283 /// @return the value converted to points for internal use 0284 qreal convertToPoint(const QString &value, bool *ok = nullptr) const; 0285 0286 //! Equal to convertToPoint(), use convertToPoint() instead for clarity 0287 inline qreal fromUserValue(const QString &value, bool *ok = nullptr) const { 0288 return convertToPoint(value, ok); 0289 } 0290 0291 //! Returns the symbol string of given unit type 0292 //! Symbol for Invalid type is empty string. 0293 static QString symbol(KReportUnit::Type type); 0294 0295 //! Returns the symbol string of the unit 0296 //! Symbol for Invalid type is empty string. 0297 QString symbol() const; 0298 0299 /** 0300 * Equal to symbol(): returns the symbol string of the unit. 0301 */ 0302 inline QString toString() const 0303 { 0304 return symbol(); 0305 } 0306 0307 /** 0308 * @brief Returns a unit symbol string to type 0309 * 0310 * @param symbol symbol to convert, must be lowercase 0311 * @return Invalid type for unsupported symbol 0312 * 0313 * @since 3.1 0314 */ 0315 static KReportUnit::Type symbolToType(const QString &symbol); 0316 0317 /** 0318 * @brief Returns the list of unit symbols for the given types 0319 * 0320 * @since 3.1 0321 */ 0322 static QStringList symbols(const QList<Type> &types); 0323 0324 /// Parses common %KReport and ODF values, like "10cm", "5mm" to pt. 0325 /// If no unit is specified, pt is assumed. 0326 /// @a defaultVal is in Points 0327 static qreal parseValue(const QString &value, qreal defaultVal = 0.0); 0328 0329 /// parse an angle to its value in degrees 0330 /// @a defaultVal is in degrees 0331 static qreal parseAngle(const QString &value, qreal defaultVal = 0.0); 0332 0333 private: 0334 class Private; 0335 Private * const d; 0336 }; 0337 0338 #ifndef QT_NO_DEBUG_STREAM 0339 KREPORT_EXPORT QDebug operator<<(QDebug, const KReportUnit &); 0340 #endif 0341 0342 Q_DECLARE_METATYPE(KReportUnit) 0343 0344 #endif