diff --git a/src/common/KReportItemBase.h b/src/common/KReportItemBase.h index cc9d6b41..3a4dddf1 100644 --- a/src/common/KReportItemBase.h +++ b/src/common/KReportItemBase.h @@ -1,155 +1,156 @@ /* This file is part of the KDE project * Copyright (C) 2007-2010 by Adam Pigg (adam@piggz.co.uk) * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library. If not, see . */ #ifndef KREPORTITEMBASE_H #define KREPORTITEMBASE_H #include "config-kreport.h" #include "kreport_export.h" #include "KReportDpi.h" #include "KReportUnit.h" #include #include #include class OROPage; class OROSection; class KReportSize; class KReportData; class KReportLineStyle; #ifdef KREPORT_SCRIPTING class KReportScriptHandler; #else #define KReportScriptHandler void #endif class KProperty; class KPropertySet; class QDomElement; class KRTextStyleData { public: QFont font; Qt::Alignment alignment; QColor backgroundColor; QColor foregroundColor; int backgroundOpacity; }; /* class KReportLineStyle { public: int weight; QColor lineColor; Qt::PenStyle style; }; */ /** */ class KREPORT_EXPORT KReportItemBase : public QObject { Q_OBJECT public: KReportItemBase(); virtual ~KReportItemBase(); /** @brief Return the item type as a string. Required by all items @return Item type */ virtual QString typeName() const = 0; /** @brief Render the item into a primitive which is used by the second stage renderer @return the height required by the object */ virtual int renderSimpleData(OROPage *page, OROSection *section, const QPointF &offset, const QVariant &data, KReportScriptHandler *script); /** @brief Render a complex item that uses a sub query as a data source @return the height required by the object */ virtual int renderReportData(OROPage *page, OROSection *section, const QPointF &offset, KReportData *data, KReportScriptHandler *script); /** @brief Override if the item supports a simple data source, such as a field @return The field name or expression for the data source */ virtual QString itemDataSource() const; /** @brief Override if the item uses a sub query and linked fields, such as a chart or sub-report @return True if uses a sub query */ virtual bool supportsSubQuery() const; KPropertySet* propertySet(); const KPropertySet* propertySet() const; void setEntityName(const QString& n); QString entityName() const; virtual void setUnit(const KReportUnit& u); /** * @brief Return the size in points */ QSizeF size() const; /** * @brief Return the position in points */ QPointF position() const; void setPosition(const QPointF &pos); void setSize(const QSizeF &siz); qreal z() const; void setZ(qreal z); //Helper function to map between size/position units static QPointF scenePosition(const QPointF &pos); static QSizeF sceneSize(const QSizeF &size); static QPointF positionFromScene(const QPointF &pos); static QSizeF sizeFromScene(const QSizeF &size); protected: virtual void createProperties() = 0; bool parseReportRect(const QDomElement &elem); static bool parseReportTextStyleData(const QDomElement &, KRTextStyleData*); static bool parseReportLineStyleData(const QDomElement &, KReportLineStyle*); KProperty *nameProperty(); QString oldName() const; void setOldName(const QString &old); Q_SLOT virtual void propertyChanged(KPropertySet &s, KProperty &p); private: + Q_DISABLE_COPY(KReportItemBase) class Private; Private * const d; }; #endif diff --git a/src/common/KReportUnit.cpp b/src/common/KReportUnit.cpp index dc7ad189..dab6dcc5 100644 --- a/src/common/KReportUnit.cpp +++ b/src/common/KReportUnit.cpp @@ -1,386 +1,453 @@ /* This file is part of the KDE project Copyright (C) 2001 David Faure Copyright (C) 2004, Nicolas GOUTTE Copyright 2012 Friedrich W. H. Kossebau This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "KReportUnit.h" #include "kreport_debug.h" #include #include #include +class Q_DECL_HIDDEN KReportUnit::Private +{ +public: + Type type; + qreal pixelConversion; +}; + // ensure the same order as in KReportUnit::Unit static const char* const unitNameList[KReportUnit::TypeCount] = { "mm", "pt", "in", "cm", "dm", "pi", "cc", "px" }; +KReportUnit::KReportUnit(Type type, qreal factor) : d(new Private) +{ + d->type = type; + d->pixelConversion = factor; +} + +KReportUnit::KReportUnit(const KReportUnit& other) : d(new Private) +{ + d->type = other.type(); + d->pixelConversion = other.factor(); +} + +KReportUnit::~KReportUnit() +{ + delete d; +} + +bool KReportUnit::operator==(const KReportUnit& other) const +{ + return d->type == other.d->type && + (d->type != Pixel || + qFuzzyCompare(d->pixelConversion, other.d->pixelConversion)); +} + +bool KReportUnit::operator!=(const KReportUnit& other) const +{ + return !operator==(other); +} + + +KReportUnit& KReportUnit::operator=(Type type) +{ + d->type = type; + d->pixelConversion = 1.0; + return *this; +} + +KReportUnit & KReportUnit::operator=(const KReportUnit& other) +{ + d->type = other.type(); + d->pixelConversion = other.factor(); + return *this; +} + QString KReportUnit::unitDescription(KReportUnit::Type type) { switch (type) { case KReportUnit::Millimeter: return QCoreApplication::translate("KReportUnit", "Millimeters (mm)"); case KReportUnit::Centimeter: return QCoreApplication::translate("KReportUnit", "Centimeters (cm)"); case KReportUnit::Decimeter: return QCoreApplication::translate("KReportUnit", "Decimeters (dm)"); case KReportUnit::Inch: return QCoreApplication::translate("KReportUnit", "Inches (in)"); case KReportUnit::Pica: return QCoreApplication::translate("KReportUnit", "Pica (pi)"); case KReportUnit::Cicero: return QCoreApplication::translate("KReportUnit", "Cicero (cc)"); case KReportUnit::Point: return QCoreApplication::translate("KReportUnit", "Points (pt)"); case KReportUnit::Pixel: return QCoreApplication::translate("KReportUnit", "Pixels (px)"); default: return QCoreApplication::translate("KReportUnit", "Unsupported unit"); } } // grouped by units which are similar static const KReportUnit::Type typesInUi[KReportUnit::TypeCount] = { KReportUnit::Millimeter, KReportUnit::Centimeter, KReportUnit::Decimeter, KReportUnit::Inch, KReportUnit::Pica, KReportUnit::Cicero, KReportUnit::Point, KReportUnit::Pixel, }; QStringList KReportUnit::listOfUnitNameForUi(ListOptions listOptions) { QStringList lst; for (int i = 0; i < KReportUnit::TypeCount; ++i) { const Type type = typesInUi[i]; if ((type != Pixel) || ((listOptions & HideMask) == ListAll)) lst.append(unitDescription(type)); } return lst; } KReportUnit KReportUnit::fromListForUi(int index, ListOptions listOptions, qreal factor) { KReportUnit::Type type = KReportUnit::Point; if ((0 <= index) && (index < KReportUnit::TypeCount)) { // iterate through all enums and skip the Pixel enum if needed for (int i = 0; i < KReportUnit::TypeCount; ++i) { if ((listOptions&HidePixel) && (typesInUi[i] == Pixel)) { ++index; continue; } if (i == index) { type = typesInUi[i]; break; } } } return KReportUnit(type, factor); } int KReportUnit::indexInListForUi(ListOptions listOptions) const { - if ((listOptions&HidePixel) && (m_type == Pixel)) { + if ((listOptions&HidePixel) && (d->type == Pixel)) { return -1; } int result = -1; int skipped = 0; for (int i = 0; i < KReportUnit::TypeCount; ++i) { if ((listOptions&HidePixel) && (typesInUi[i] == Pixel)) { ++skipped; continue; } - if (typesInUi[i] == m_type) { + if (typesInUi[i] == d->type) { result = i - skipped; break; } } return result; } qreal KReportUnit::toUserValue(qreal ptValue) const { - switch (m_type) { + switch (d->type) { case Millimeter: return toMillimeter(ptValue); case Centimeter: return toCentimeter(ptValue); case Decimeter: return toDecimeter(ptValue); case Inch: return toInch(ptValue); case Pica: return toPica(ptValue); case Cicero: return toCicero(ptValue); case Pixel: - return ptValue * m_pixelConversion; + return ptValue * d->pixelConversion; case Point: default: return toPoint(ptValue); } } qreal KReportUnit::ptToUnit(qreal ptValue, const KReportUnit &unit) { - switch (unit.m_type) { + switch (unit.d->type) { case Millimeter: return POINT_TO_MM(ptValue); case Centimeter: return POINT_TO_CM(ptValue); case Decimeter: return POINT_TO_DM(ptValue); case Inch: return POINT_TO_INCH(ptValue); case Pica: return POINT_TO_PI(ptValue); case Cicero: return POINT_TO_CC(ptValue); case Pixel: - return ptValue * unit.m_pixelConversion; + return ptValue * unit.d->pixelConversion; case Point: default: return ptValue; } } QString KReportUnit::toUserStringValue(qreal ptValue) const { return QLocale::system().toString(toUserValue(ptValue)); } qreal KReportUnit::fromUserValue(qreal value) const { - switch (m_type) { + switch (d->type) { case Millimeter: return MM_TO_POINT(value); case Centimeter: return CM_TO_POINT(value); case Decimeter: return DM_TO_POINT(value); case Inch: return INCH_TO_POINT(value); case Pica: return PI_TO_POINT(value); case Cicero: return CC_TO_POINT(value); case Pixel: - return value / m_pixelConversion; + return value / d->pixelConversion; case Point: default: return value; } } qreal KReportUnit::fromUserValue(const QString &value, bool *ok) const { return fromUserValue(QLocale::system().toDouble(value, ok)); } qreal KReportUnit::parseValue(const QString& _value, qreal defaultVal) { if (_value.isEmpty()) return defaultVal; QString value(_value.simplified()); value.remove(QLatin1Char(' ')); int firstLetter = -1; for (int i = 0; i < value.length(); ++i) { if (value.at(i).isLetter()) { if (value.at(i) == QLatin1Char('e')) continue; firstLetter = i; break; } } bool ok; if (firstLetter == -1) { qreal result = QVariant(value).toReal(&ok); return ok ? result : defaultVal; } const QByteArray symbol = value.mid(firstLetter).toLatin1(); value.truncate(firstLetter); const qreal val = value.toDouble(); if (symbol == "pt" || symbol.isEmpty()) return val; KReportUnit u = KReportUnit::fromSymbol(QLatin1String(symbol), &ok); if (ok) return u.fromUserValue(val); if (symbol == "m") return DM_TO_POINT(val * 10.0); else if (symbol == "km") return DM_TO_POINT(val * 10000.0); kreportWarning() << "KReportUnit::parseValue: Unit" << symbol << "is not supported, please report."; //! @todo add support for mi/ft ? return defaultVal; } KReportUnit KReportUnit::fromSymbol(const QString &symbol, bool *ok) { Type result = Point; if (symbol == QLatin1String("inch") /*compat*/) { result = Inch; if (ok) *ok = true; } else { if (ok) *ok = false; for (int i = 0; i < TypeCount; ++i) { if (symbol == QLatin1String(unitNameList[i])) { result = static_cast(i); if (ok) *ok = true; } } } return KReportUnit(result); } qreal KReportUnit::convertFromUnitToUnit(qreal value, const KReportUnit &fromUnit, const KReportUnit &toUnit, qreal factor) { qreal pt; switch (fromUnit.type()) { case Millimeter: pt = MM_TO_POINT(value); break; case Centimeter: pt = CM_TO_POINT(value); break; case Decimeter: pt = DM_TO_POINT(value); break; case Inch: pt = INCH_TO_POINT(value); break; case Pica: pt = PI_TO_POINT(value); break; case Cicero: pt = CC_TO_POINT(value); break; case Pixel: pt = value / factor; break; case Point: default: pt = value; } switch (toUnit.type()) { case Millimeter: return POINT_TO_MM(pt); case Centimeter: return POINT_TO_CM(pt); case Decimeter: return POINT_TO_DM(pt); case Inch: return POINT_TO_INCH(pt); case Pica: return POINT_TO_PI(pt); case Cicero: return POINT_TO_CC(pt); case Pixel: return pt * factor; case Point: default: return pt; } } QString KReportUnit::symbol() const { - return QLatin1String(unitNameList[m_type]); + return QLatin1String(unitNameList[d->type]); } qreal KReportUnit::parseAngle(const QString& _value, qreal defaultVal) { if (_value.isEmpty()) return defaultVal; QString value(_value.simplified()); value.remove(QLatin1Char(' ')); int firstLetter = -1; for (int i = 0; i < value.length(); ++i) { if (value.at(i).isLetter()) { if (value.at(i) == QLatin1Char('e')) continue; firstLetter = i; break; } } if (firstLetter == -1) return value.toDouble(); const QString type = value.mid(firstLetter); value.truncate(firstLetter); const qreal val = value.toDouble(); if (type == QLatin1String("deg")) return val; else if (type == QLatin1String("rad")) return val * 180 / M_PI; else if (type == QLatin1String("grad")) return val * 0.9; return defaultVal; } #ifndef QT_NO_DEBUG_STREAM QDebug operator<<(QDebug debug, const KReportUnit &unit) { #ifndef NDEBUG debug.nospace() << unit.symbol(); #else Q_UNUSED(unit); #endif return debug.space(); } + +void KReportUnit::setFactor(qreal factor) +{ + d->pixelConversion = factor; +} + +qreal KReportUnit::factor() const +{ + return d->pixelConversion; +} + +KReportUnit::Type KReportUnit::type() const +{ + return d->type; +} + #endif diff --git a/src/common/KReportUnit.h b/src/common/KReportUnit.h index 952b1562..87ed739c 100644 --- a/src/common/KReportUnit.h +++ b/src/common/KReportUnit.h @@ -1,261 +1,265 @@ /* This file is part of the KDE project Copyright (C) 1998, 1999 Reginald Stadlbauer Copyright (C) 1998, 1999 Torben Weis Copyright (C) 2004, Nicolas GOUTTE Copyright (C) 2010 Thomas Zander Copyright 2012 Friedrich W. H. Kossebau This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KREPORTUNIT_H #define KREPORTUNIT_H #include // for floor #include #include #include #include "kreport_export.h" class QStringList; // 1 inch ^= 72 pt // 1 inch ^= 25.399956 mm (-pedantic ;p) // 1 pt = 1/12 pi // 1 pt ^= 0.0077880997 cc // 1 cc = 12 dd // Note: I don't use division but multiplication with the inverse value // because it's faster ;p (Werner) #define POINT_TO_MM(px) qreal((px)*0.352777167) #define MM_TO_POINT(mm) qreal((mm)*2.83465058) #define POINT_TO_CM(px) qreal((px)*0.0352777167) #define CM_TO_POINT(cm) qreal((cm)*28.3465058) #define POINT_TO_DM(px) qreal((px)*0.00352777167) #define DM_TO_POINT(dm) qreal((dm)*283.465058) #define POINT_TO_INCH(px) qreal((px)*0.01388888888889) #define INCH_TO_POINT(inch) qreal((inch)*72.0) #define MM_TO_INCH(mm) qreal((mm)*0.039370147) #define INCH_TO_MM(inch) qreal((inch)*25.399956) #define POINT_TO_PI(px) qreal((px)*0.083333333) #define POINT_TO_CC(px) qreal((px)*0.077880997) #define PI_TO_POINT(pi) qreal((pi)*12) #define CC_TO_POINT(cc) qreal((cc)*12.840103) /** * %KReport stores everything in pt (using "qreal") internally. * When displaying a value to the user, the value is converted to the user's unit * of choice, and rounded to a reasonable precision to avoid 0.999999 * * For implementing the selection of a unit type in the UI use the *ForUi() methods. * They ensure the same order of the unit types in all places, with the order not * bound to the order in the enum (so ABI-compatible extension is possible) and * with the order and scope of listed types controlled by the @c ListOptions parameter. */ class KREPORT_EXPORT KReportUnit { public: /** Length units supported by %KReport. */ enum Type { Millimeter = 0, Point, ///< Postscript point, 1/72th of an Inco Inch, Centimeter, Decimeter, Pica, Cicero, Pixel, TypeCount ///< @internal }; /// Used to control the scope of the unit types listed in the UI enum ListOption { ListAll = 0, HidePixel = 1, HideMask = HidePixel }; Q_DECLARE_FLAGS(ListOptions, ListOption) + /** Construction requires initialization. The factor is for variable factor units like pixel */ + explicit KReportUnit(Type type = Point, qreal factor = 1.0); + + KReportUnit(const KReportUnit &other); + + ~KReportUnit(); + + /// Assigns specified type and factor 1.0 to the object + /// @param unit Type of unit + KReportUnit& operator=(Type type); + + KReportUnit& operator=(const KReportUnit& other); + + bool operator!=(const KReportUnit &other) const; + + bool operator==(const KReportUnit &other) const; + + KReportUnit::Type type() const; + + void setFactor(qreal factor); + + qreal factor() const; + /** Returns a KReportUnit instance with the type at the @p index of the UI list with the given @p listOptions. */ static KReportUnit fromListForUi(int index, ListOptions listOptions = ListAll, qreal factor = 1.0); /// Convert a unit symbol string into a KReportUnit /// @param symbol symbol to convert /// @param ok if set, it will be true if the unit was known, false if unknown static KReportUnit fromSymbol(const QString &symbol, bool *ok = 0); - /** Construction requires initialization. The factor is for variable factor units like pixel */ - explicit KReportUnit(Type unit = Point, qreal factor = 1.0) { - m_type = unit; - m_pixelConversion = factor; - } - - KReportUnit& operator=(Type unit) { - m_type = unit; m_pixelConversion = 1.0; return *this; - } - - bool operator!=(const KReportUnit &other) const { - return !operator==(other); - } - - bool operator==(const KReportUnit &other) const { - return m_type == other.m_type && - (m_type != Pixel || - qFuzzyCompare(m_pixelConversion, other.m_pixelConversion)); - } - - KReportUnit::Type type() const { - return m_type; - } - - void setFactor(qreal factor) { - m_pixelConversion = factor; - } /** * Prepare ptValue to be displayed in pt * This method will round to 0.001 precision */ - static qreal toPoint(qreal ptValue) { + static inline qreal toPoint(qreal ptValue) + { // No conversion, only rounding (to 0.001 precision) return floor(ptValue * 1000.0) / 1000.0; } /** * Prepare ptValue to be displayed in mm * This method will round to 0.0001 precision, use POINT_TO_MM() for lossless conversion. */ - static qreal toMillimeter(qreal ptValue) { + static inline qreal toMillimeter(qreal ptValue) + { // "mm" values are rounded to 0.0001 millimeters return floor(POINT_TO_MM(ptValue) * 10000.0) / 10000.0; } /** * Prepare ptValue to be displayed in cm * This method will round to 0.0001 precision, use POINT_TO_CM() for lossless conversion. */ - static qreal toCentimeter(qreal ptValue) { + static inline qreal toCentimeter(qreal ptValue) + { return floor(POINT_TO_CM(ptValue) * 10000.0) / 10000.0; } /** * Prepare ptValue to be displayed in dm * This method will round to 0.0001 precision, use POINT_TO_DM() for lossless conversion. */ - static qreal toDecimeter(qreal ptValue) { + static inline qreal toDecimeter(qreal ptValue) + { return floor(POINT_TO_DM(ptValue) * 10000.0) / 10000.0; } /** * Prepare ptValue to be displayed in inch * This method will round to 0.00001 precision, use POINT_TO_INCH() for lossless conversion. */ - static qreal toInch(qreal ptValue) { + static inline qreal toInch(qreal ptValue) + { // "in" values are rounded to 0.00001 inches return floor(POINT_TO_INCH(ptValue) * 100000.0) / 100000.0; } /** * Prepare ptValue to be displayed in pica * This method will round to 0.00001 precision, use POINT_TO_PI() for lossless conversion. */ - static qreal toPica(qreal ptValue) { + static inline qreal toPica(qreal ptValue) + { // "pi" values are rounded to 0.00001 inches return floor(POINT_TO_PI(ptValue) * 100000.0) / 100000.0; } /** * Prepare ptValue to be displayed in cicero * This method will round to 0.00001 precision, use POINT_TO_CC() for lossless conversion. */ - static qreal toCicero(qreal ptValue) { + static inline qreal toCicero(qreal ptValue) + { // "cc" values are rounded to 0.00001 inches return floor(POINT_TO_CC(ptValue) * 100000.0) / 100000.0; } /** * convert the given value directly from one unit to another */ static qreal convertFromUnitToUnit(qreal value, const KReportUnit &fromUnit, const KReportUnit &toUnit, qreal factor = 1.0); /** * This method is the one to use to display a value in a dialog * \return the value @p ptValue converted to unit and rounded, ready to be displayed */ qreal toUserValue(qreal ptValue) const; /** * Convert the value @p ptValue to a given unit @p unit * Unlike KReportUnit::ptToUnit the return value remains unrounded, so that it can be used in complex calculation * \return the converted value */ static qreal ptToUnit(qreal ptValue, const KReportUnit &unit); /// This method is the one to use to display a value in a dialog /// @return the value @p ptValue converted the unit and rounded, ready to be displayed QString toUserStringValue(qreal ptValue) const; /// This method is the one to use to read a value from a dialog /// @return the value converted to points for internal use qreal fromUserValue(qreal value) const; /// This method is the one to use to read a value from a dialog /// @param value value entered by the user /// @param ok if set, the pointed bool is set to true if the value could be /// converted to a qreal, and to false otherwise. /// @return the value converted to points for internal use qreal fromUserValue(const QString &value, bool *ok = 0) const; /// Get the description string of the given unit static QString unitDescription(KReportUnit::Type type); /// Get the symbol string of the unit QString symbol() const; /// Returns the list of unit types for the UI, controlled with the given @p listOptions. static QStringList listOfUnitNameForUi(ListOptions listOptions = ListAll); /// Get the index of this unit in the list of unit types for the UI, /// if it is controlled with the given @p listOptions. int indexInListForUi(ListOptions listOptions = ListAll) const; /// Parses common %KReport and ODF values, like "10cm", "5mm" to pt. /// If no unit is specified, pt is assumed. static qreal parseValue(const QString &value, qreal defaultVal = 0.0); /// parse an angle to its value in degrees static qreal parseAngle(const QString &value, qreal defaultVal = 0.0); /** * Equal to symbol(): returns the symbol string of the unit. */ - inline QString toString() const { + inline QString toString() const + { return symbol(); } - + private: - Type m_type; - qreal m_pixelConversion; + class Private; + Private * const d; }; #ifndef QT_NO_DEBUG_STREAM KREPORT_EXPORT QDebug operator<<(QDebug, const KReportUnit &); #endif Q_DECLARE_METATYPE(KReportUnit) Q_DECLARE_OPERATORS_FOR_FLAGS(KReportUnit::ListOptions) #endif