diff --git a/examples/window.cpp b/examples/window.cpp --- a/examples/window.cpp +++ b/examples/window.cpp @@ -33,6 +33,15 @@ #include #include +QDebug operator<<(QDebug dbg, const QDomNode& node) +{ + QString s; + QTextStream str(&s, QIODevice::WriteOnly); + node.save(str, 2); + dbg << qPrintable(s); + return dbg; +} + Window::Window(QWidget *parent, Qt::WindowFlags flags) : QMainWindow(parent, flags) { @@ -117,6 +126,7 @@ void Window::showDesign(const QDomElement &design) { + //qDebug() << design; KReportPreRenderer preRenderer(design); if (!preRenderer.isValid()) { return; diff --git a/src/common/KReportDesign_p.h b/src/common/KReportDesign_p.h --- a/src/common/KReportDesign_p.h +++ b/src/common/KReportDesign_p.h @@ -21,7 +21,6 @@ #define KREPORTDESIGN_P_H #include "KReportDesign.h" -#include "KReportUnit.h" #include "KReportUtils_p.h" #include @@ -32,15 +31,6 @@ class QDomElement; class KReportPluginInterface; -extern const bool DEFAULT_SHOW_GRID; -extern const bool DEFAULT_SNAP_TO_GRID; -extern const int DEFAULT_GRID_DIVISIONS; -extern const KReportUnit::Type DEFAULT_UNIT_TYPE; -extern const KReportUnit DEFAULT_UNIT; -extern const int DEFAULT_PAGE_MARGIN; -extern const QPageSize::PageSizeId DEFAULT_PAGE_SIZE; -extern const QPageLayout::Orientation DEFAULT_PAGE_ORIENTATION; - class Q_DECL_HIDDEN KReportDesign::Private { public: diff --git a/src/common/KReportDesign_p.cpp b/src/common/KReportDesign_p.cpp --- a/src/common/KReportDesign_p.cpp +++ b/src/common/KReportDesign_p.cpp @@ -20,23 +20,15 @@ #include "KReportDesign_p.h" #include "KReportElement.h" #include "KReportUtils.h" +#include "KReportUtils_p.h" #include "KReportPluginManager.h" #include "KReportPluginInterface.h" #include #include #include #include -const bool DEFAULT_SHOW_GRID = true; -const bool DEFAULT_SNAP_TO_GRID = true; -const int DEFAULT_GRID_DIVISIONS = 4; -const KReportUnit::Type DEFAULT_UNIT_TYPE = KReportUnit::Type::Centimeter; -const KReportUnit DEFAULT_UNIT(DEFAULT_UNIT_TYPE); -const int DEFAULT_PAGE_MARGIN = CM_TO_POINT(1.0); -const QPageSize::PageSizeId DEFAULT_PAGE_SIZE = QPageSize::A4; -const QPageLayout::Orientation DEFAULT_PAGE_ORIENTATION = QPageLayout::Landscape; - KReportDesign::Private::Private(KReportDesign *design) : q(design) , showGrid(DEFAULT_SHOW_GRID) @@ -59,10 +51,10 @@ , defaultSectionBackgroundColor(Qt::white) { defaultPageLayout.setUnits(QPageLayout::Point); - defaultPageLayout.setMargins(QMarginsF(DEFAULT_PAGE_MARGIN, - DEFAULT_PAGE_MARGIN, - DEFAULT_PAGE_MARGIN, - DEFAULT_PAGE_MARGIN)); + defaultPageLayout.setMargins(QMarginsF(DEFAULT_PAGE_MARGIN_PT, + DEFAULT_PAGE_MARGIN_PT, + DEFAULT_PAGE_MARGIN_PT, + DEFAULT_PAGE_MARGIN_PT)); defaultPageLayout.setMode(QPageLayout::StandardMode); defaultPageLayout.setOrientation(DEFAULT_PAGE_ORIENTATION); } @@ -143,10 +135,10 @@ return false; } -static void setNoAttributeStatus(const QDomElement &el, const char *attrName, KReportDesignReadingStatus *status) +static void setNoAttributeStatus(const QDomElement &el, const QString &attrName, KReportDesignReadingStatus *status) { setStatus(status, QString::fromLatin1("Attribute \"%1\" expected inside of <%1>") - .arg(QLatin1String(attrName)).arg(el.tagName()), el); + .arg(attrName).arg(el.tagName()), el); } #if 0 // TODO unused for now @@ -163,21 +155,26 @@ KReportSection KReportDesign::Private::processSectionElement(const QDomElement &el, KReportDesignReadingStatus *status) { - const QString sectionTypeName = KReportUtils::attr(el, "report:section-type", QString()); - KReportSection::Type sectionType = s_global->sectionType(sectionTypeName); + qDebug() << el.nodeName(); + const KReportSection::Type sectionType + = s_global->sectionType(KReportUtils::readSectionTypeNameAttribute(el)); if (sectionType == KReportSection::Type::Invalid) { setStatus(status, - QString::fromLatin1("Invalid value of report:section-type=\"%1\" in element <%2>") - .arg(sectionTypeName).arg(el.tagName()), el); + QString::fromLatin1( + "Invalid value of report:section-type=\"%1\" in element <%2>") + .arg(KReportUtils::readSectionTypeNameAttribute(el)) + .arg(el.tagName()), + el); return KReportSection(); } KReportSection section; section.setType(sectionType); - qreal height = KReportUtils::attr(el, "svg:height", -1.0); - if (height >= 0.0) { - section.setHeight(height); + const QSizeF size(KReportUtils::readSizeAttributes(el)); + if (size.height() >= 0) { + section.setHeight(size.height()); } - section.setBackgroundColor(QColor(KReportUtils::attr(el, "fo:background-color", QString()))); + section.setBackgroundColor( + KReportUtils::attr(el, QLatin1String("fo:background-color"), QColor())); for (QDomNode node = el.firstChild(); !node.isNull(); node = node.nextSibling()) { if (!checkElement(node, status)) { return KReportSection(); @@ -223,9 +220,9 @@ if (!plugin->loadElement(&element, el, status)) { return KReportElement(); } - element.setName(KReportUtils::attr(el, "report:name", QString())); + element.setName(KReportUtils::readNameAttribute(el)); if (element.name().isEmpty()) { - setNoAttributeStatus(el, "report:name", status); + setNoAttributeStatus(el, QLatin1String("report:name"), status); return KReportElement(); } return element; @@ -350,14 +347,20 @@ #ifdef KREPORT_SCRIPTING } else if (name == "report:script") { script = el.firstChildElement().text(); - originalInterpreter = KReportUtils::attr(el, "report:script-interpreter", QString()); + originalInterpreter = KReportUtils::attr( + el, QLatin1String("report:script-interpreter"), QString()); #endif } else if (name == "report:grid") { - showGrid = KReportUtils::attr(el, "report:grid-visible", DEFAULT_SHOW_GRID); - snapToGrid = KReportUtils::attr(el, "report:grid-snap", DEFAULT_SNAP_TO_GRID); - gridDivisions = KReportUtils::attr(el, "report:grid-divisions", DEFAULT_GRID_DIVISIONS); - const QString pageUnitString = KReportUtils::attr(el, "report:page-unit", QString()); - pageUnit = KReportUnit(KReportUnit::symbolToType(pageUnitString)); + showGrid = KReportUtils::attr( + el, QLatin1String("report:grid-visible"), DEFAULT_SHOW_GRID); + snapToGrid = KReportUtils::attr( + el, QLatin1String("report:grid-snap"), DEFAULT_SNAP_TO_GRID); + gridDivisions = KReportUtils::attr( + el, QLatin1String("report:grid-divisions"), DEFAULT_GRID_DIVISIONS); + const QString pageUnitString + = KReportUtils::attr(el, QLatin1String("report:page-unit"), QString()); + + pageUnit = KReportUnit::symbolToType(pageUnitString); if (!pageUnit.isValid()) { pageUnit = DEFAULT_UNIT; if (!pageUnitString.isEmpty()) { @@ -369,12 +372,12 @@ else if (name == "report:page-style") { // see https://git.reviewboard.kde.org/r/115314 const QByteArray pagetype = el.text().toLatin1(); if (pagetype == "predefined") { - pageLayout.setPageSize( - KReportUtils::pageSize(KReportUtils::attr(el, "report:page-size", - QPageSize(DEFAULT_PAGE_SIZE).key()))); + pageLayout.setPageSize(KReportUtils::pageSize( + KReportUtils::attr(el, QLatin1String("report:page-size"), + QPageSize(DEFAULT_PAGE_SIZE).key()))); } else if (pagetype.isEmpty() || pagetype == "custom") { - QSizeF size(KReportUtils::attr(el, "fo:page-width", -1.0), - KReportUtils::attr(el, "fo:page-height", -1.0)); + QSizeF size(KReportUtils::attr(el, QLatin1String("fo:page-width"), -1.0), + KReportUtils::attr(el, QLatin1String("fo:page-height"), -1.0)); if (size.isValid()) { pageLayout.setPageSize(QPageSize(size, QPageSize::Point)); } else { @@ -384,15 +387,20 @@ //! @todo? pageLayout.setPageSize(defaultPageLayout.pageSize()); } - QMarginsF margins(KReportUtils::attr(el, "fo:margin-left", defaultPageLayout.margins().left()), - KReportUtils::attr(el, "fo:margin-top", defaultPageLayout.margins().top()), - KReportUtils::attr(el, "fo:margin-right", defaultPageLayout.margins().right()), - KReportUtils::attr(el, "fo:margin-bottom", defaultPageLayout.margins().bottom())); + QMarginsF margins(KReportUtils::attr(el, QLatin1String("fo:margin-left"), + defaultPageLayout.margins().left()), + KReportUtils::attr(el, QLatin1String("fo:margin-top"), + defaultPageLayout.margins().top()), + KReportUtils::attr(el, QLatin1String("fo:margin-right"), + defaultPageLayout.margins().right()), + KReportUtils::attr(el, QLatin1String("fo:margin-bottom"), + defaultPageLayout.margins().bottom())); bool b = pageLayout.setMargins(margins); if (!b) { qWarning() << "Failed to set page margins to" << margins; } - const QString s = KReportUtils::attr(el, "report:print-orientation", QString()); + const QString s = KReportUtils::attr( + el, QLatin1String("report:print-orientation"), QString()); if (s == QLatin1String("portrait")) { pageLayout.setOrientation(QPageLayout::Portrait); } else if (s == QLatin1String("landscape")) { diff --git a/src/common/KReportDetailSectionData.cpp b/src/common/KReportDetailSectionData.cpp --- a/src/common/KReportDetailSectionData.cpp +++ b/src/common/KReportDetailSectionData.cpp @@ -19,6 +19,7 @@ #include "KReportDetailSectionData.h" #include "KReportSectionData.h" #include "KReportDocument.h" +#include "KReportUtils.h" #include "kreport_debug.h" #include @@ -72,7 +73,7 @@ } for ( QDomElement e = elemThis.firstChildElement( QLatin1String("report:section") ); ! e.isNull(); e = e.nextSiblingElement( QLatin1String("report:section") ) ) { - QString s = e.attribute( QLatin1String("report:section-type") ); + const QString s = KReportUtils::readSectionTypeNameAttribute(e); if ( s == QLatin1String("group-header") ) { KReportSectionData * sd = new KReportSectionData(e, report); if (sd->isValid()) { @@ -93,10 +94,13 @@ KReportDataSource::SortedField s; s.setField(dgsd->column); s.setOrder(dgsd->m_sort); + sortedFields.append(s); - - } else if (elemThis.tagName() == QLatin1String("report:section") && elemThis.attribute(QLatin1String("report:section-type")) == QLatin1String("detail")) { - KReportSectionData * sd = new KReportSectionData(elemThis, report); + } else if (elemThis.tagName() == QLatin1String("report:section") + && KReportUtils::readSectionTypeNameAttribute(elemThis) + == QLatin1String("detail")) + { + KReportSectionData *sd = new KReportSectionData(elemThis, report); if (sd->isValid()) { detailSection = sd; } else diff --git a/src/common/KReportDocument.cpp b/src/common/KReportDocument.cpp --- a/src/common/KReportDocument.cpp +++ b/src/common/KReportDocument.cpp @@ -108,11 +108,20 @@ } //! @todo add config for default margins or add within templates support d->pageLayout.setUnits(QPageLayout::Point); - d->pageLayout.setLeftMargin(KReportUnit::parseValue(elemThis.attribute(QLatin1String("fo:margin-left"), QLatin1String("1.0cm")))); - d->pageLayout.setRightMargin(KReportUnit::parseValue(elemThis.attribute(QLatin1String("fo:margin-right"), QLatin1String("1.0cm")))); - d->pageLayout.setTopMargin(KReportUnit::parseValue(elemThis.attribute(QLatin1String("fo:margin-top"), QLatin1String("1.0cm")))); - d->pageLayout.setBottomMargin(KReportUnit::parseValue(elemThis.attribute(QLatin1String("fo:margin-bottom"), QLatin1String("1.0cm")))); - d->pageLayout.setOrientation(elemThis.attribute(QLatin1String("report:print-orientation"), QLatin1String("portrait")) == QLatin1String("portrait") ? QPageLayout::Portrait : QPageLayout::Landscape); + d->pageLayout.setLeftMargin(KReportUnit::parseValue(elemThis.attribute( + QLatin1String("fo:margin-left"), DEFAULT_PAGE_MARGIN_STRING))); + d->pageLayout.setRightMargin(KReportUnit::parseValue(elemThis.attribute( + QLatin1String("fo:margin-right"), DEFAULT_PAGE_MARGIN_STRING))); + d->pageLayout.setTopMargin(KReportUnit::parseValue(elemThis.attribute( + QLatin1String("fo:margin-top"), DEFAULT_PAGE_MARGIN_STRING))); + d->pageLayout.setBottomMargin(KReportUnit::parseValue(elemThis.attribute( + QLatin1String("fo:margin-bottom"), DEFAULT_PAGE_MARGIN_STRING))); + d->pageLayout.setOrientation( + elemThis.attribute(QLatin1String("report:print-orientation"), + QLatin1String("portrait")) + == QLatin1String("portrait") + ? QPageLayout::Portrait + : QPageLayout::Landscape); } else if (elemThis.tagName() == QLatin1String("report:body")) { QDomNodeList sectionlist = elemThis.childNodes(); QDomNode sec; diff --git a/src/common/KReportItemBase.h b/src/common/KReportItemBase.h --- a/src/common/KReportItemBase.h +++ b/src/common/KReportItemBase.h @@ -109,7 +109,11 @@ void setEntityName(const QString& n); QString entityName() const; - virtual void setUnit(const KReportUnit& u); + KReportUnit unit() const; + + //! Sets unit to @a a and converts values of position and size property from the old + //! unit to new if needed. + virtual void setUnit(const KReportUnit &u); /** * @brief Return the size in points @@ -121,16 +125,39 @@ */ QPointF position() const; - void setPosition(const QPointF &pos); - void setSize(const QSizeF &siz); + /** + * @brief Sets position for the element + * @param ptPos Position in points + */ + void setPosition(const QPointF &ptPos); + /** + * @brief Sets size for the element + * @param ptSize Size in points + */ + void setSize(const QSizeF &ptSize); + + /** + * @brief Return the z-value in points + */ qreal z() const; + + /** + * @brief Sets the z-value for the element + * @param z Z-value in points + */ void setZ(qreal z); - //Helper function to map between size/position units - static QPointF scenePosition(const QPointF &pos); - static QSizeF sceneSize(const QSizeF &size); + //! Helper function mapping to screen units (pixels), @a ptPos is in points + static QPointF scenePosition(const QPointF &ptPos); + + //! Helper function mapping to screen units (pixels), @a ptSize is in points + static QSizeF sceneSize(const QSizeF &ptSize); + + //! Helper function mapping from screen units to points, @a pos is in pixels static QPointF positionFromScene(const QPointF &pos); + + //! Helper function mapping from screen units to points, @a size is in pixels static QSizeF sizeFromScene(const QSizeF &size); protected: @@ -149,6 +176,8 @@ Q_DISABLE_COPY(KReportItemBase) class Private; Private * const d; + Q_SLOT void aboutToDeleteProperty(KPropertySet& set, KProperty& property); + }; #endif diff --git a/src/common/KReportItemBase.cpp b/src/common/KReportItemBase.cpp --- a/src/common/KReportItemBase.cpp +++ b/src/common/KReportItemBase.cpp @@ -29,24 +29,54 @@ public: Private(); ~Private(); - + + void setUnit(const KReportUnit& u, bool force) + { + if (!force && unit == u) { + return; + } + const QSignalBlocker blocker(set); + KReportUnit oldunit = unit; + unit = u; + // convert values + + if (positionProperty) { + positionProperty->setValue(KReportUnit::convertFromUnitToUnit( + positionProperty->value().toPointF(), oldunit, u), + KProperty::ValueOption::IgnoreOld); + + positionProperty->setOption("suffix", u.symbol()); + + } + if (sizeProperty) { + sizeProperty->setValue( + KReportUnit::convertFromUnitToUnit(sizeProperty->value().toSizeF(), oldunit, u), + KProperty::ValueOption::IgnoreOld); + + sizeProperty->setOption("suffix", u.symbol()); + } + + } + KPropertySet *set; KProperty *nameProperty; KProperty *sizeProperty; KProperty *positionProperty; QString oldName; qreal z = 0; + KReportUnit unit; }; KReportItemBase::Private::Private() { set = new KPropertySet(); nameProperty = new KProperty("name", QString(), tr("Name"), tr("Object Name")); nameProperty->setValueSyncPolicy(KProperty::ValueSyncPolicy::FocusOut); - + positionProperty = new KProperty("position", QPointF(), QCoreApplication::translate("ItemPosition", "Position")); sizeProperty = new KProperty("size", QSizeF(), QCoreApplication::translate("ItemSize", "Size")); - + setUnit(DEFAULT_UNIT, true); + set->addProperty(nameProperty); set->addProperty(positionProperty); set->addProperty(sizeProperty); @@ -59,14 +89,16 @@ KReportItemBase::KReportItemBase() : d(new Private()) -{ +{ connect(propertySet(), &KPropertySet::propertyChanged, this, &KReportItemBase::propertyChanged); + + connect(propertySet(), &KPropertySet::aboutToDeleteProperty, this, &KReportItemBase::aboutToDeleteProperty); } -KReportItemBase::~KReportItemBase() -{ - delete d; +KReportItemBase::~KReportItemBase() +{ + delete d; } bool KReportItemBase::parseReportTextStyleData(const QDomElement & elemSource, KReportTextStyleData *ts) @@ -82,26 +114,20 @@ bool KReportItemBase::parseReportRect(const QDomElement & elemSource) { - QPointF pos; - QSizeF size; - - pos.setX(KReportUnit::parseValue(elemSource.attribute(QLatin1String("svg:x"), QLatin1String("1cm")))); - pos.setY(KReportUnit::parseValue(elemSource.attribute(QLatin1String("svg:y"), QLatin1String("1cm")))); - size.setWidth(KReportUnit::parseValue(elemSource.attribute(QLatin1String("svg:width"), QLatin1String("1cm")))); - size.setHeight(KReportUnit::parseValue(elemSource.attribute(QLatin1String("svg:height"), QLatin1String("1cm")))); - - setPosition(pos); - setSize(size); - + const QRectF r(KReportUtils::readRectAttributes(elemSource, DEFAULT_ELEMENT_RECT_PT)); + setPosition(r.topLeft()); + setSize(r.size()); return true; - +} + +KReportUnit KReportItemBase::unit() const +{ + return d->unit; } void KReportItemBase::setUnit(const KReportUnit& u) { - qDebug() << "Setting page unit to: " << u.symbol(); - d->positionProperty->setOption("unit", u.symbol()); - d->sizeProperty->setOption("unit", u.symbol()); + d->setUnit(u, false); } int KReportItemBase::renderSimpleData(OROPage *page, OROSection *section, const QPointF &offset, @@ -168,31 +194,31 @@ QPointF KReportItemBase::position() const { - return d->positionProperty->value().toPointF(); + return d->unit.convertToPoint(d->positionProperty->value().toPointF()); } QSizeF KReportItemBase::size() const { - return d->sizeProperty->value().toSizeF(); + return d->unit.convertToPoint(d->sizeProperty->value().toSizeF()); } const KPropertySet * KReportItemBase::propertySet() const { return d->set; } -QPointF KReportItemBase::scenePosition(const QPointF &pos) +QPointF KReportItemBase::scenePosition(const QPointF &ptPos) { - const qreal x = POINT_TO_INCH(pos.x()) * KReportPrivate::dpiX(); - const qreal y = POINT_TO_INCH(pos.y()) * KReportPrivate::dpiY(); + const qreal x = POINT_TO_INCH(ptPos.x()) * KReportPrivate::dpiX(); + const qreal y = POINT_TO_INCH(ptPos.y()) * KReportPrivate::dpiY(); return QPointF(x, y); } -QSizeF KReportItemBase::sceneSize(const QSizeF &size) +QSizeF KReportItemBase::sceneSize(const QSizeF &ptSize) { - const qreal w = POINT_TO_INCH(size.width()) * KReportPrivate::dpiX(); - const qreal h = POINT_TO_INCH(size.height()) * KReportPrivate::dpiY(); - return QSizeF(w, h); + const qreal w = POINT_TO_INCH(ptSize.width()) * KReportPrivate::dpiX(); + const qreal h = POINT_TO_INCH(ptSize.height()) * KReportPrivate::dpiY(); + return QSizeF(w, h); } qreal KReportItemBase::z() const @@ -205,14 +231,14 @@ d->z = z; } -void KReportItemBase::setPosition(const QPointF& pos) +void KReportItemBase::setPosition(const QPointF& ptPos) { - d->positionProperty->setValue(pos); + d->positionProperty->setValue(d->unit.convertFromPoint(ptPos)); } -void KReportItemBase::setSize(const QSizeF& size) +void KReportItemBase::setSize(const QSizeF &ptSize) { - d->sizeProperty->setValue(size); + d->sizeProperty->setValue(d->unit.convertFromPoint(ptSize)); } QPointF KReportItemBase::positionFromScene(const QPointF& pos) @@ -234,3 +260,14 @@ Q_UNUSED(s) Q_UNUSED(p) } + +void KReportItemBase::aboutToDeleteProperty(KPropertySet& set, KProperty& property) +{ + Q_UNUSED(set) + if (property.name() == "size") { + d->sizeProperty = nullptr; + } + else if (property.name() == "position") { + d->positionProperty = nullptr; + } +} diff --git a/src/common/KReportItemLine.h b/src/common/KReportItemLine.h --- a/src/common/KReportItemLine.h +++ b/src/common/KReportItemLine.h @@ -42,14 +42,14 @@ int renderSimpleData(OROPage *page, OROSection *section, const QPointF &offset, const QVariant &data, KReportScriptHandler *script) override; - void setUnit(const KReportUnit&) override; + void setUnit(const KReportUnit &u) override; QPointF startPosition() const; + void setStartPosition(const QPointF &ptPos); QPointF endPosition() const; + void setEndPosition(const QPointF &ptPos); protected: - KProperty *m_start; - KProperty *m_end; KProperty *m_lineColor; KProperty *m_lineWeight; KProperty *m_lineStyle; @@ -59,6 +59,9 @@ void setWeight(qreal w); private: + KProperty *m_start; + KProperty *m_end; + void createProperties() override; friend class Scripting::Line; diff --git a/src/common/KReportItemLine.cpp b/src/common/KReportItemLine.cpp --- a/src/common/KReportItemLine.cpp +++ b/src/common/KReportItemLine.cpp @@ -17,6 +17,8 @@ #include "KReportItemLine.h" #include "KReportRenderObjects.h" +#include "KReportUtils.h" +#include "KReportUtils_p.h" #include "kreport_debug.h" #include @@ -32,21 +34,26 @@ KReportItemLine::KReportItemLine(const QDomNode & element) : KReportItemLine() { + nameProperty()->setValue(KReportUtils::readNameAttribute(element.toElement())); + setZ(KReportUtils::readZAttribute(element.toElement())); + + const QPointF s(KReportUnit::parseValue(element.toElement().attribute( + QLatin1String("svg:x1"), DEFAULT_ELEMENT_POS_STRING)), + KReportUnit::parseValue(element.toElement().attribute( + QLatin1String("svg:y1"), DEFAULT_ELEMENT_POS_STRING))); + const QPointF e(KReportUnit::parseValue(element.toElement().attribute( + QLatin1String("svg:x2"), DEFAULT_ELEMENT_POS_STRING)), + KReportUnit::parseValue(element.toElement().attribute( + QLatin1String("svg:y2"), + QString::number(POINT_TO_CM(DEFAULT_ELEMENT_POS_PT.y() + + DEFAULT_ELEMENT_SIZE_PT.height())) + + QLatin1String("cm")))); + setStartPosition(s); + setEndPosition(e); + QDomNodeList nl = element.childNodes(); QString n; QDomNode node; - QPointF _s, _e; - - nameProperty()->setValue(element.toElement().attribute(QLatin1String("report:name"))); - setZ(element.toElement().attribute(QLatin1String("report:z-index")).toDouble()); - - _s.setX(KReportUnit::parseValue(element.toElement().attribute(QLatin1String("svg:x1"), QLatin1String("1cm")))); - _s.setY(KReportUnit::parseValue(element.toElement().attribute(QLatin1String("svg:y1"), QLatin1String("1cm")))); - _e.setX(KReportUnit::parseValue(element.toElement().attribute(QLatin1String("svg:x2"), QLatin1String("1cm")))); - _e.setY(KReportUnit::parseValue(element.toElement().attribute(QLatin1String("svg:y2"), QLatin1String("2cm")))); - m_start->setValue(_s); - m_end->setValue(_e); - for (int i = 0; i < nl.count(); i++) { node = nl.item(i); n = node.nodeName(); @@ -121,8 +128,8 @@ Q_UNUSED(data) OROLine * ln = new OROLine(); - QPointF s = scenePosition(m_start->value().toPointF()); - QPointF e = scenePosition(m_end->value().toPointF()); + QPointF s = scenePosition(startPosition()); + QPointF e = scenePosition(endPosition()); s += offset; e += offset; @@ -134,27 +141,48 @@ OROLine *l2 = dynamic_cast(ln->clone()); if (l2) { - l2->setStartPoint(m_start->value().toPointF()); - l2->setEndPoint(m_end->value().toPointF()); + l2->setStartPoint(startPosition()); + l2->setEndPoint(endPosition()); if (section) section->addPrimitive(l2); } return 0; } void KReportItemLine::setUnit(const KReportUnit &u) { - m_start->setOption("unit", u.symbol()); - m_end->setOption("unit", u.symbol()); + if (unit() == u) { + return; + } + KReportUnit oldunit = unit(); + KReportItemBase::setUnit(u); + + // convert values + m_start->setValue(KReportUnit::convertFromUnitToUnit(m_start->value().toPointF(), oldunit, u), + KProperty::ValueOption::IgnoreOld); + m_end->setValue(KReportUnit::convertFromUnitToUnit(m_end->value().toPointF(), oldunit, u), + KProperty::ValueOption::IgnoreOld); + + m_start->setOption("suffix", u.symbol()); + m_end->setOption("suffix", u.symbol()); } QPointF KReportItemLine::startPosition() const { - return m_start->value().toPointF(); + return unit().convertToPoint(m_start->value().toPointF()); +} + +void KReportItemLine::setStartPosition(const QPointF &ptPos) +{ + m_start->setValue(unit().convertFromPoint(ptPos)); } QPointF KReportItemLine::endPosition() const { - return m_end->value().toPointF(); + return unit().convertToPoint(m_end->value().toPointF()); } +void KReportItemLine::setEndPosition(const QPointF &ptPos) +{ + m_end->setValue(unit().convertFromPoint(ptPos)); +} diff --git a/src/common/KReportPluginInterface.cpp b/src/common/KReportPluginInterface.cpp --- a/src/common/KReportPluginInterface.cpp +++ b/src/common/KReportPluginInterface.cpp @@ -66,13 +66,17 @@ { Q_ASSERT(el); Q_UNUSED(status); - el->setName(KReportUtils::attr(dom, "report:name", QString())); + el->setName(KReportUtils::readNameAttribute(dom)); el->setRect(KReportUtils::readRectAttributes(dom, el->rect())); - el->setZ(KReportUtils::attr(dom, "report:z-index", el->z())); + el->setZ(KReportUtils::readZAttribute(dom, el->z())); - const QDomElement textStyleDom = dom.firstChildElement(QLatin1String("report:text-style")); - el->setForegroundColor(KReportUtils::attr(textStyleDom, "fo:foreground-color", el->foregroundColor())); - el->setBackgroundColor(KReportUtils::attr(textStyleDom, "fo:background-color", el->backgroundColor())); - el->setBackgroundOpacity(KReportUtils::attrPercent(textStyleDom, "fo:background-opacity", el->backgroundOpacity())); + const QDomElement textStyleDom + = dom.firstChildElement(QLatin1String("report:text-style")); + el->setForegroundColor(KReportUtils::attr( + textStyleDom, QLatin1String("fo:foreground-color"), el->foregroundColor())); + el->setBackgroundColor(KReportUtils::attr( + textStyleDom, QLatin1String("fo:background-color"), el->backgroundColor())); + el->setBackgroundOpacity(KReportUtils::attrPercent( + textStyleDom, QLatin1String("fo:background-opacity"), el->backgroundOpacity())); return true; } diff --git a/src/common/KReportSection.cpp b/src/common/KReportSection.cpp --- a/src/common/KReportSection.cpp +++ b/src/common/KReportSection.cpp @@ -40,7 +40,7 @@ return; } - m_type = sectionTypeFromString(elemSource.attribute(QLatin1String("report:section-type"))); + m_type = sectionTypeFromString(KReportUtils::readSectionTypeNameAttribute(elemSource)); if (m_type == KReportSection::None) { m_valid = false; return; @@ -183,9 +183,9 @@ } //static -void KReportSection::setDefaultHeight(qreal height) +void KReportSection::setDefaultHeight(qreal ptHeight) { - KReportDesignGlobal::self()->defaultSectionHeight = height; + KReportDesignGlobal::self()->defaultSectionHeight = ptHeight; } //static diff --git a/src/common/KReportSectionData.h b/src/common/KReportSectionData.h --- a/src/common/KReportSectionData.h +++ b/src/common/KReportSectionData.h @@ -21,10 +21,12 @@ #ifndef KREPORTSECTIONDATA_H #define KREPORTSECTIONDATA_H -#include +#include "KReportUnit.h" #include +#include + class KReportItemBase; class KReportDocument; class QDomElement; @@ -66,21 +68,25 @@ explicit KReportSectionData(QObject* parent = nullptr); - explicit KReportSectionData(const QDomElement &elemSource, QObject* parent = nullptr); + explicit KReportSectionData(const QDomElement &elemSource, QObject *parent = nullptr); ~KReportSectionData() override; + KReportUnit unit() const; + + void setUnit(const KReportUnit &u); + KPropertySet* propertySet() const { return m_set; } bool isValid() const { return m_valid; } - qreal height() const { - return m_height->value().toDouble(); - } + qreal height() const; + + void setHeight(qreal ptHeight); QList objects() const { return m_objects; @@ -100,14 +106,16 @@ static QString sectionTypeString(KReportSectionData::Type type); protected: KPropertySet *m_set; - KProperty *m_height; KProperty *m_backgroundColor; private: void createProperties(const QDomElement & elemSource); void loadXml(const QDomElement &elemSource); + void setHeight(qreal ptHeight, KProperty::ValueOptions options); + KProperty *m_height; QList m_objects; + KReportUnit m_unit; Type m_type; diff --git a/src/common/KReportSectionData.cpp b/src/common/KReportSectionData.cpp --- a/src/common/KReportSectionData.cpp +++ b/src/common/KReportSectionData.cpp @@ -23,7 +23,10 @@ #include "KReportItemLine.h" #include "KReportPluginInterface.h" #include "KReportPluginManager.h" +#include "KReportItemLine.h" +#include "KReportDesigner.h" #include "KReportUtils.h" +#include "KReportUtils_p.h" #include "kreport_debug.h" #include @@ -34,14 +37,15 @@ { } -KReportSectionData::KReportSectionData(const QDomElement &elemSource, QObject *parent) - : QObject(parent) +KReportSectionData::KReportSectionData(const QDomElement & elemSource, QObject *parent) + : QObject(parent) + , m_unit(DEFAULT_UNIT_TYPE) { if (elemSource.isNull()) { m_type = Type::None; } else { setObjectName(elemSource.tagName()); - m_type = sectionTypeFromString(elemSource.attribute(QLatin1String("report:section-type"))); + m_type = sectionTypeFromString(KReportUtils::readSectionTypeNameAttribute(elemSource)); } createProperties(elemSource); @@ -85,9 +89,12 @@ if (krobj) { krobj->propertySet()->clearModifiedFlags(); m_objects.append(krobj); + } else { + kreportWarning() << "Could not create element of type" << reportItemName; } + } else { + kreportWarning() << "While parsing section encountered an unknown element:" << n; } - kreportWarning() << "While parsing section encountered an unknown element: " << n; } qSort(m_objects.begin(), m_objects.end(), zLessThan); m_valid = true; @@ -99,6 +106,25 @@ qDeleteAll(m_objects); } +KReportUnit KReportSectionData::unit() const +{ + return m_unit; +} + +void KReportSectionData::setUnit(const KReportUnit &u) +{ + if (m_unit == u) { + return; + } + // convert values + KReportUnit oldunit = m_unit; + m_unit = u; + + m_height->setValue(KReportUnit::convertFromUnitToUnit(m_height->value().toReal(), oldunit, u), + KProperty::ValueOption::IgnoreOld); + m_height->setOption("suffix", u.symbol()); +} + bool KReportSectionData::zLessThan(KReportItemBase* s1, KReportItemBase* s2) { return s1->z() < s2->z(); @@ -115,14 +141,18 @@ KReportDesigner::addMetaProperties(m_set, tr("Section", "Report section"), QLatin1String("kreport-section-element")); - m_height = new KProperty("height", KReportUnit(KReportUnit::Type::Centimeter).fromUserValue(2.0), tr("Height")); + m_height = new KProperty("height", 0.0, tr("Height")); m_backgroundColor = new KProperty( "background-color", - KReportUtils::attr(elemSource, "fo:background-color", QColor(Qt::white)), + KReportUtils::attr(elemSource, QLatin1String("fo:background-color"), QColor(Qt::white)), tr("Background Color")); m_height->setOption("unit", QLatin1String("cm")); - if (!elemSource.isNull()) - m_height->setValue(KReportUnit::parseValue(elemSource.attribute(QLatin1String("svg:height"), QLatin1String("2.0cm")))); + if (!elemSource.isNull()) { + m_height->setValue(m_unit.convertFromPoint( + KReportUtils::readSizeAttributes( + elemSource, QSizeF(DEFAULT_SECTION_SIZE_PT, DEFAULT_SECTION_SIZE_PT)) + .height())); + } m_set->addProperty(m_height); m_set->addProperty(m_backgroundColor); @@ -231,3 +261,18 @@ return type; } + +qreal KReportSectionData::height() const +{ + return m_unit.convertToPoint(m_height->value().toReal()); +} + +void KReportSectionData::setHeight(qreal ptHeight, KProperty::ValueOptions options) +{ + m_height->setValue(m_unit.convertFromPoint(ptHeight), options); +} + +void KReportSectionData::setHeight(qreal ptHeight) +{ + setHeight(ptHeight, KProperty::ValueOptions()); +} diff --git a/src/common/KReportUnit.h b/src/common/KReportUnit.h --- a/src/common/KReportUnit.h +++ b/src/common/KReportUnit.h @@ -1,9 +1,9 @@ /* 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) 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 + Copyright (C) 2012 Friedrich W. H. Kossebau Copyright (C) 2017 Jarosław Staniek This library is free software; you can redistribute it and/or @@ -217,9 +217,23 @@ } /** - * convert the given value directly from one unit to another + * convert the given value directly from one unit to another with high accuracy */ - static qreal convertFromUnitToUnit(qreal value, const KReportUnit &fromUnit, const KReportUnit &toUnit, qreal factor = 1.0); + static qreal convertFromUnitToUnit(qreal value, const KReportUnit &fromUnit, + const KReportUnit &toUnit, qreal factor = 1.0); + + /** + * convert the given value directly from one unit to another with high accuracy + */ + static QPointF convertFromUnitToUnit(const QPointF &value, + const KReportUnit &fromUnit, + const KReportUnit &toUnit); + + /** + * convert the given value directly from one unit to another with high accuracy + */ + static QSizeF convertFromUnitToUnit(const QSizeF &value, const KReportUnit &fromUnit, + const KReportUnit &toUnit); /** * This method is the one to use to display a value in a dialog @@ -238,16 +252,38 @@ /// @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; + //! @return the value converted to points with high accuracy + qreal convertToPoint(qreal value) const; + + //! @return the value converted from points to the actual unit with high accuracy + qreal convertFromPoint(qreal ptValue) const; - /// This method is the one to use to read a value from a dialog + //! @return the value converted from points to the actual unit with high accuracy + QPointF convertFromPoint(const QPointF &ptValue) const; + + //! @return the value converted from points to the actual unit with high accuracy + QSizeF convertFromPoint(const QSizeF &ptValue) const; + + //! Equal to convertToPoint(), use convertToPoint() instead for clarity + inline qreal fromUserValue(qreal value) const { return convertToPoint(value); } + + /// @return the value converted to points with high accuracy + QPointF convertToPoint(const QPointF &value) const; + + /// @return the value converted to points with high accuracy + QSizeF convertToPoint(const QSizeF &value) const; + + /// @return the value converted to points with high accuracy /// @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 = nullptr) const; + qreal convertToPoint(const QString &value, bool *ok = 0) const; + + //! Equal to convertToPoint(), use convertToPoint() instead for clarity + inline qreal fromUserValue(const QString &value, bool *ok = 0) const { + return convertToPoint(value, ok); + } //! Returns the symbol string of given unit type //! Symbol for Invalid type is empty string. @@ -284,9 +320,11 @@ /// Parses common %KReport and ODF values, like "10cm", "5mm" to pt. /// If no unit is specified, pt is assumed. + /// @a defaultVal is in Points static qreal parseValue(const QString &value, qreal defaultVal = 0.0); /// parse an angle to its value in degrees + /// @a defaultVal is in degrees static qreal parseAngle(const QString &value, qreal defaultVal = 0.0); private: diff --git a/src/common/KReportUnit.cpp b/src/common/KReportUnit.cpp --- a/src/common/KReportUnit.cpp +++ b/src/common/KReportUnit.cpp @@ -1,7 +1,7 @@ /* This file is part of the KDE project Copyright (C) 2001 David Faure - Copyright (C) 2004, Nicolas GOUTTE - Copyright 2012 Friedrich W. H. Kossebau + Copyright (C) 2004 Nicolas GOUTTE + Copyright (C) 2012 Friedrich W. H. Kossebau Copyright (C) 2017 Jarosław Staniek This library is free software; you can redistribute it and/or @@ -225,7 +225,40 @@ return QLocale::system().toString(toUserValue(ptValue)); } -qreal KReportUnit::fromUserValue(qreal value) const +qreal KReportUnit::convertFromPoint(qreal ptValue) const +{ + switch (d->type) { + case Type::Millimeter: + return POINT_TO_MM(ptValue); + case Type::Centimeter: + return POINT_TO_CM(ptValue); + case Type::Decimeter: + return POINT_TO_DM(ptValue); + case Type::Inch: + return POINT_TO_INCH(ptValue); + case Type::Pica: + return POINT_TO_PI(ptValue); + case Type::Cicero: + return POINT_TO_CC(ptValue); + case Type::Pixel: + return ptValue * d->pixelConversion; + case Type::Point: + default: + return ptValue; + } +} + +QPointF KReportUnit::convertFromPoint(const QPointF &ptValue) const +{ + return QPointF(convertFromPoint(ptValue.x()), convertFromPoint(ptValue.y())); +} + +QSizeF KReportUnit::convertFromPoint(const QSizeF &ptValue) const +{ + return QSizeF(convertFromPoint(ptValue.width()), convertFromPoint(ptValue.height())); +} + +qreal KReportUnit::convertToPoint(qreal value) const { switch (d->type) { case Type::Invalid: @@ -250,16 +283,21 @@ } } -qreal KReportUnit::fromUserValue(const QString &value, bool *ok) const +qreal KReportUnit::convertToPoint(const QString &value, bool *ok) const { - if (d->type == Type::Invalid) { - kreportWarning() << "Conversion from Invalid type not supported"; - if (ok) { - *ok = false; - } - return -1.0; - } - return fromUserValue(QLocale::system().toDouble(value, ok)); + return convertToPoint(QLocale::system().toDouble(value, ok)); +} + +QPointF KReportUnit::convertToPoint(const QPointF &value) const +{ + return QPointF(KReportUnit::convertToPoint(value.x()), + KReportUnit::convertToPoint(value.y())); +} + +QSizeF KReportUnit::convertToPoint(const QSizeF &value) const +{ + return QSizeF(KReportUnit::convertToPoint(value.width()), + KReportUnit::convertToPoint(value.height())); } qreal KReportUnit::parseValue(const QString& _value, qreal defaultVal) @@ -353,48 +391,65 @@ pt = MM_TO_POINT(value); break; case Type::Centimeter: - pt = CM_TO_POINT(value); - break; + pt = CM_TO_POINT(value); + break; case Type::Decimeter: - pt = DM_TO_POINT(value); - break; + pt = DM_TO_POINT(value); + break; case Type::Inch: - pt = INCH_TO_POINT(value); - break; + pt = INCH_TO_POINT(value); + break; case Type::Pica: - pt = PI_TO_POINT(value); - break; + pt = PI_TO_POINT(value); + break; case Type::Cicero: - pt = CC_TO_POINT(value); - break; + pt = CC_TO_POINT(value); + break; case Type::Pixel: - pt = value / factor; - break; + pt = value / factor; + break; case Type::Point: default: - pt = value; - } - + pt = value; + } + switch (toUnit.type()) { case Type::Millimeter: - return POINT_TO_MM(pt); + return POINT_TO_MM(pt); case Type::Centimeter: - return POINT_TO_CM(pt); + return POINT_TO_CM(pt); case Type::Decimeter: - return POINT_TO_DM(pt); + return POINT_TO_DM(pt); case Type::Inch: - return POINT_TO_INCH(pt); + return POINT_TO_INCH(pt); case Type::Pica: - return POINT_TO_PI(pt); + return POINT_TO_PI(pt); case Type::Cicero: - return POINT_TO_CC(pt); + return POINT_TO_CC(pt); case Type::Pixel: - return pt * factor; + return pt * factor; case Type::Invalid: - case Type::Point: default: - return pt; - } + return pt; + } +} + +QPointF KReportUnit::convertFromUnitToUnit(const QPointF &value, + const KReportUnit &fromUnit, + const KReportUnit &toUnit) +{ + return QPointF( + KReportUnit::convertFromUnitToUnit(value.x(), fromUnit, toUnit), + KReportUnit::convertFromUnitToUnit(value.y(), fromUnit, toUnit)); +} + +QSizeF KReportUnit::convertFromUnitToUnit(const QSizeF &value, + const KReportUnit &fromUnit, + const KReportUnit &toUnit) +{ + return QSizeF( + KReportUnit::convertFromUnitToUnit(value.width(), fromUnit, toUnit), + KReportUnit::convertFromUnitToUnit(value.height(), fromUnit, toUnit)); } QString KReportUnit::symbol() const diff --git a/src/common/KReportUtils.h b/src/common/KReportUtils.h --- a/src/common/KReportUtils.h +++ b/src/common/KReportUtils.h @@ -37,23 +37,23 @@ namespace KReportUtils { - KREPORT_EXPORT QString attr(const QDomElement &el, const char *attrName, + KREPORT_EXPORT QString attr(const QDomElement &el, const QString &attrName, const QString &defaultValue = QString()); - KREPORT_EXPORT QByteArray attr(const QDomElement &el, const char *attrName, + KREPORT_EXPORT QByteArray attr(const QDomElement &el, const QString &attrName, const QByteArray &defaultValue = QByteArray()); - KREPORT_EXPORT bool attr(const QDomElement &el, const char *attrName, bool defaultValue = false); + KREPORT_EXPORT bool attr(const QDomElement &el, const QString &attrName, bool defaultValue = false); - KREPORT_EXPORT int attr(const QDomElement &el, const char *attrName, int defaultValue = 0); + KREPORT_EXPORT int attr(const QDomElement &el, const QString &attrName, int defaultValue = 0); - KREPORT_EXPORT qreal attr(const QDomElement &el, const char *attrName, qreal defaultValue = 0.0); + KREPORT_EXPORT qreal attr(const QDomElement &el, const QString &attrName, qreal defaultValue = 0.0); - KREPORT_EXPORT QColor attr(const QDomElement &el, const char *attrName, const QColor &defaultValue = QColor()); + KREPORT_EXPORT QColor attr(const QDomElement &el, const QString &attrName, const QColor &defaultValue = QColor()); //! @return percent value converted to qreal, e.g. 1.0 for "100%", 0.505 for "50.5%". //! @a defaultValue is returned if there is not "%" suffix or no proper number. - KREPORT_EXPORT qreal attrPercent(const QDomElement& el, const char* attrName, qreal defaultValue = 0.0); + KREPORT_EXPORT qreal attrPercent(const QDomElement& el, const QString &attrName, qreal defaultValue = 0.0); //! @return pen style from @a str or @a defaultValue //! Values from ODF 1.2 19.493 style:line-style are also recognized. @@ -71,13 +71,37 @@ //! @return horizontal alignment flag from @a alignment KREPORT_EXPORT QString horizontalToString(Qt::Alignment alignment); + //! @return name value read from report:name attribute of @a el. + //! If the attribute is missing, @a defaultValue is returned. + KREPORT_EXPORT QString readNameAttribute( + const QDomElement &el, const QString &defaultValue = QString()); + + //! @return size value read from svg:width and svg:height attributes of @a el. + //! If any of the attributes are missing, @a defaultValue is returned. + //! @a defaultValue should be specified in Points. + KREPORT_EXPORT QSizeF readSizeAttributes( + const QDomElement &el, const QSizeF &defaultValue = QSizeF()); + //! @return rectangle value read from svg:x, svg:y, svg:width, svg:height attributes of @a el. - //! If any of the arguments are missing, @a defaultValue is returned. - KREPORT_EXPORT QRectF readRectAttributes(const QDomElement &el, const QRectF &defaultValue = QRectF()); + //! If any of the attributes are missing, @a defaultValue is returned. + //! @a defaultValue should be specified in Points. + KREPORT_EXPORT QRectF readRectAttributes( + const QDomElement &el, const QRectF &defaultValue = QRectF()); + + //! @return Z index value read from report:z-index attribute of @a el. + //! If the attribute is missing @a defaultValue is returned. + //! @a defaultValue should be specified in Points. + KREPORT_EXPORT qreal readZAttribute(const QDomElement &el, qreal defaultValue = 0.0); + + //! @return name of section type read from report:section-type attribute of @a el. + //! If the attribute is missing, @a defaultValue is returned. + KREPORT_EXPORT QString readSectionTypeNameAttribute( + const QDomElement &el, const QString &defaultValue = QString()); //! @return percent value for element @a name. If the element is missing, returns @a defaultPercentValue. //! If @a ok is not 0, *ok is set to the result. - KREPORT_EXPORT int readPercent(const QDomElement & el, const char* name, int defaultPercentValue, bool *ok); + KREPORT_EXPORT int readPercent(const QDomElement &el, const QString &attrName, + int defaultPercentValue, bool *ok); //! Reads all font attributes for element @a el into @a font. //! @todo add unit tests diff --git a/src/common/KReportUtils.cpp b/src/common/KReportUtils.cpp --- a/src/common/KReportUtils.cpp +++ b/src/common/KReportUtils.cpp @@ -29,55 +29,55 @@ #include -QString KReportUtils::attr(const QDomElement &el, const char *attrName, +QString KReportUtils::attr(const QDomElement &el, const QString &attrName, const QString &defaultValue) { - const QString val = el.attribute(QLatin1String(attrName)); + const QString val = el.attribute(attrName); return val.isEmpty() ? defaultValue : val; } -QByteArray KReportUtils::attr(const QDomElement &el, const char *attrName, +QByteArray KReportUtils::attr(const QDomElement &el, const QString &attrName, const QByteArray &defaultValue) { - const QByteArray val = el.attribute(QLatin1String(attrName)).toLatin1(); + const QByteArray val = el.attribute(attrName).toLatin1(); return val.isEmpty() ? defaultValue : val; } -bool KReportUtils::attr(const QDomElement &el, const char *attrName, bool defaultValue) +bool KReportUtils::attr(const QDomElement &el, const QString &attrName, bool defaultValue) { - const QString val = el.attribute(QLatin1String(attrName)); + const QString val = el.attribute(attrName); return val.isEmpty() ? defaultValue : QVariant(val).toBool(); } -int KReportUtils::attr(const QDomElement &el, const char *attrName, int defaultValue) +int KReportUtils::attr(const QDomElement &el, const QString &attrName, int defaultValue) { - const QString val = el.attribute(QLatin1String(attrName)); + const QString val = el.attribute(attrName); if (val.isEmpty()) { return defaultValue; } bool ok; const int result = QVariant(val).toInt(&ok); return ok ? result : defaultValue; } -qreal KReportUtils::attr(const QDomElement &el, const char *attrName, qreal defaultValue) +qreal KReportUtils::attr(const QDomElement &el, const QString &attrName, qreal defaultValue) { - const QString val = el.attribute(QLatin1String(attrName)); + const QString val = el.attribute(attrName); return KReportUnit::parseValue(val, defaultValue); } -QColor KReportUtils::attr(const QDomElement &el, const char *attrName, const QColor &defaultValue) +QColor KReportUtils::attr(const QDomElement &el, const QString &attrName, const QColor &defaultValue) { - const QString val = el.attribute(QLatin1String(attrName)); + const QString val = el.attribute(attrName); if (val.isEmpty()) { return defaultValue; } return QColor(val); } -qreal KReportUtils::attrPercent(const QDomElement& el, const char* attrName, qreal defaultValue) +qreal KReportUtils::attrPercent(const QDomElement& el, const QString &attrName, qreal defaultValue) { - QString str(el.attribute(QLatin1String(attrName))); + QString str(el.attribute(attrName)); if (str.isEmpty() || !str.endsWith(QLatin1Char('%'))) { return defaultValue; } @@ -162,20 +162,42 @@ return QString(); } +QString KReportUtils::readNameAttribute(const QDomElement &el, const QString &defaultValue) +{ + return attr(el, QLatin1String("report:name"), defaultValue); +} + +QSizeF KReportUtils::readSizeAttributes(const QDomElement &el, const QSizeF &defaultValue) +{ + QSizeF val; + val.setWidth(attr(el, QLatin1String("svg:width"), defaultValue.width())); + if (val.width() < 0.0) { + val.setWidth(defaultValue.width()); + } + val.setHeight(attr(el, QLatin1String("svg:height"), defaultValue.height())); + if (val.height() < 0.0) { + val.setHeight(defaultValue.height()); + } + return val; +} + QRectF KReportUtils::readRectAttributes(const QDomElement &el, const QRectF &defaultValue) { QRectF val; - val.setX(attr(el, "svg:x", defaultValue.x())); - val.setY(attr(el, "svg:y", defaultValue.y())); - val.setWidth(attr(el, "svg:width", defaultValue.width())); - val.setHeight(attr(el, "svg:height", defaultValue.height())); + val.setX(attr(el, QLatin1String("svg:x"), defaultValue.x())); + val.setY(attr(el, QLatin1String("svg:y"), defaultValue.y())); + val.setSize(readSizeAttributes(el, defaultValue.size())); return val; } -int KReportUtils::readPercent(const QDomElement& el, const char* name, int defaultPercentValue, bool *ok) +qreal KReportUtils::readZAttribute(const QDomElement &el, qreal defaultValue) +{ + return KReportUtils::attr(el, QLatin1String("report:z-index"), defaultValue); +} + +int KReportUtils::readPercent(const QDomElement& el, const QString &attrName, int defaultPercentValue, bool *ok) { - Q_ASSERT(name); - QString percent(el.attribute(QLatin1String(name))); + QString percent(el.attribute(attrName)); if (percent.isEmpty()) { if (ok) *ok = true; @@ -192,6 +214,11 @@ return percent.toInt(ok); } +QString KReportUtils::readSectionTypeNameAttribute(const QDomElement &el, const QString &defaultValue) +{ + return attr(el, QLatin1String("report:section-type"), defaultValue); +} + //! @return string representation of @a value, cuts of zeros; precision is set to 2 static QString roundValueToString(qreal value) { @@ -220,11 +247,12 @@ { Q_ASSERT(font); const QFont::Capitalization cap = readFontCapitalization( - attr(el, "fo:font-variant", QByteArray()), attr(el, "fo:text-transform", QByteArray())); + attr(el, QLatin1String("fo:font-variant"), QByteArray()), + attr(el, QLatin1String("fo:text-transform"), QByteArray())); font->setCapitalization(cap); // weight - const QByteArray fontWeight(attr(el, "fo:font-weight", QByteArray())); + const QByteArray fontWeight(attr(el, QLatin1String("fo:font-weight"), QByteArray())); int weight = -1; if (fontWeight == "bold") { weight = QFont::Bold; @@ -248,27 +276,31 @@ font->setWeight(weight); } - font->setItalic(attr(el, "fo:font-style", QByteArray()) == "italic"); - font->setFixedPitch(attr(el, "style:font-pitch", QByteArray()) == "fixed"); - font->setFamily(attr(el, "fo:font-family", font->family())); - font->setKerning(attr(el, "style:letter-kerning", font->kerning())); + font->setItalic(attr(el, QLatin1String("fo:font-style"), QByteArray()) == "italic"); + font->setFixedPitch(attr(el, QLatin1String("style:font-pitch"), QByteArray()) == "fixed"); + font->setFamily(attr(el, QLatin1String("fo:font-family"), font->family())); + font->setKerning(attr(el, QLatin1String("style:letter-kerning"), font->kerning())); // underline - const QByteArray underlineType(attr(el, "style:text-underline-type", QByteArray())); - font->setUnderline(!underlineType.isEmpty() && underlineType != "none"); // double or single (we don't recognize them) + const QByteArray underlineType( + attr(el, QLatin1String("style:text-underline-type"), QByteArray())); + font->setUnderline(!underlineType.isEmpty() + && underlineType + != "none"); // double or single (we don't recognize them) // stricken-out - const QByteArray strikeOutType(attr(el, "style:text-line-through-type", QByteArray())); + const QByteArray strikeOutType(attr(el, QLatin1String("style:text-line-through-type"), QByteArray())); font->setStrikeOut(!strikeOutType.isEmpty() && strikeOutType != "none"); // double or single (we don't recognize them) //! @todo support fo:font-size-rel? //! @todo support fo:font-size in px - font->setPointSizeF(KReportUtils::attr(el, "fo:font-size", font->pointSizeF())); + font->setPointSizeF(KReportUtils::attr(el, QLatin1String("fo:font-size"), font->pointSizeF())); // letter spacing // §7.16.2 of [XSL] http://www.w3.org/TR/xsl11/#letter-spacing font->setLetterSpacing(QFont::PercentageSpacing, - 100.0 * KReportUtils::attrPercent(el, "fo:letter-spacing", font->letterSpacing())); + 100.0 * KReportUtils::attrPercent( + el, QLatin1String("fo:letter-spacing"), font->letterSpacing())); } void KReportUtils::writeFontAttributes(QDomElement *el, const QFont &font) @@ -326,7 +358,8 @@ el->setAttribute(QLatin1String("fo:font-family"), font.family()); } // kerning, default is "true" - el->setAttribute(QLatin1String("style:letter-kerning"), QLatin1String(font.kerning() ? "true" : "false")); + el->setAttribute(QLatin1String("style:letter-kerning"), + font.kerning() ? QLatin1String("true") : QLatin1String("false")); // underline, default is "none" if (font.underline()) { el->setAttribute(QLatin1String("style:text-underline-type"), QLatin1String("single")); @@ -417,7 +450,7 @@ { Q_ASSERT(e); Q_ASSERT(p); - const QString name = QLatin1String("report:") + QLatin1String(p->name().toLower()); + const QString name = QLatin1String("report:") + QString::fromLatin1(p->name().toLower()); switch (p->value().type()) { case QVariant::Int : @@ -462,11 +495,14 @@ Q_ASSERT(ts); if (elemSource.tagName() != QLatin1String("report:text-style")) return false; - ts->backgroundColor = QColor(elemSource.attribute(QLatin1String("fo:background-color"), QLatin1String("#ffffff"))); - ts->foregroundColor = QColor(elemSource.attribute(QLatin1String("fo:foreground-color"), QLatin1String("#000000"))); + ts->backgroundColor = QColor(elemSource.attribute( + QLatin1String("fo:background-color"), QLatin1String("#ffffff"))); + ts->foregroundColor = QColor(elemSource.attribute( + QLatin1String("fo:foreground-color"), QLatin1String("#000000"))); bool ok; - ts->backgroundOpacity = KReportUtils::readPercent(elemSource, "fo:background-opacity", 100, &ok); + ts->backgroundOpacity = KReportUtils::readPercent( + elemSource, QLatin1String("fo:background-opacity"), 100, &ok); if (!ok) { return false; } diff --git a/src/common/KReportUtils_p.h b/src/common/KReportUtils_p.h --- a/src/common/KReportUtils_p.h +++ b/src/common/KReportUtils_p.h @@ -26,6 +26,25 @@ #include #include +const bool DEFAULT_SHOW_GRID = true; +const bool DEFAULT_SNAP_TO_GRID = true; +const int DEFAULT_GRID_DIVISIONS = 4; +const KReportUnit DEFAULT_UNIT(KReportUnit::Type::Centimeter); +const KReportUnit::Type DEFAULT_UNIT_TYPE = DEFAULT_UNIT.type(); +#define DEFAULT_UNIT_STRING QLatin1String("cm") +const QPointF DEFAULT_ELEMENT_POS_PT(CM_TO_POINT(1.0), CM_TO_POINT(1.0)); +const QSizeF DEFAULT_ELEMENT_SIZE_PT(CM_TO_POINT(1.0), CM_TO_POINT(1.0)); +const QRectF DEFAULT_ELEMENT_RECT_PT(DEFAULT_ELEMENT_POS_PT, DEFAULT_ELEMENT_SIZE_PT); +#define DEFAULT_ELEMENT_POS_STRING QLatin1String("1.0cm") // both X and Y +#define DEFAULT_ELEMENT_SIZE_STRING QLatin1String("1.0cm") // both width and height +const qreal DEFAULT_SECTION_SIZE_PT = CM_TO_POINT(2.0); +#define DEFAULT_SECTION_SIZE_STRING QLatin1String("2.0cm") +const qreal DEFAULT_PAGE_MARGIN_PT = CM_TO_POINT(1.0); +#define DEFAULT_PAGE_MARGIN_STRING QLatin1String("1.0cm") +const QPageSize::PageSizeId DEFAULT_PAGE_SIZE = QPageSize::A4; +const QPageLayout::Orientation DEFAULT_PAGE_ORIENTATION = QPageLayout::Landscape; +const QSizeF DEFAULT_CUSTOM_PAGE_SIZE(10.0,10.0); +const qreal SMALLEST_PAGE_SIZE_PT = MM_TO_POINT(5); // This is a private code made inline for use in the lib and examples. //! @todo Move to a shared lib to use in other Kexi libraries as well. diff --git a/src/items/check/KReportItemCheck.cpp b/src/items/check/KReportItemCheck.cpp --- a/src/items/check/KReportItemCheck.cpp +++ b/src/items/check/KReportItemCheck.cpp @@ -17,6 +17,8 @@ #include "KReportItemCheck.h" #include "KReportRenderObjects.h" +#include "KReportUtils.h" +#include "KReportUtils_p.h" #include "kreportplugin_debug.h" #ifdef KREPORT_SCRIPTING #include "KReportScriptHandler.h" @@ -36,9 +38,9 @@ KReportItemCheckBox::KReportItemCheckBox(const QDomNode &element) : KReportItemCheckBox() { - nameProperty()->setValue(element.toElement().attribute(QLatin1String("report:name"))); + nameProperty()->setValue(KReportUtils::readNameAttribute(element.toElement())); m_controlSource->setValue(element.toElement().attribute(QLatin1String("report:item-data-source"))); - setZ(element.toElement().attribute(QLatin1String("report:z-index")).toDouble()); + setZ(KReportUtils::readZAttribute(element.toElement())); m_foregroundColor->setValue(QColor(element.toElement().attribute(QLatin1String("fo:foreground-color")))); m_checkStyle->setValue(element.toElement().attribute(QLatin1String("report:check-style"))); m_staticValue->setValue(QVariant(element.toElement().attribute(QLatin1String("report:value"))).toBool()); diff --git a/src/items/check/KReportScriptCheck.cpp b/src/items/check/KReportScriptCheck.cpp --- a/src/items/check/KReportScriptCheck.cpp +++ b/src/items/check/KReportScriptCheck.cpp @@ -95,20 +95,21 @@ QPointF CheckBox::position() const { - return m_check->position(); + return KReportItemBase::scenePosition(m_check->position()); } + void CheckBox::setPosition(const QPointF &p) { - m_check->setPosition(p); + m_check->setPosition(KReportItemBase::positionFromScene(p)); } QSizeF CheckBox::size() const { - return m_check->size(); + return KReportItemBase::sceneSize(m_check->size()); } + void CheckBox::setSize(const QSizeF &s) { - m_check->setSize(s); + m_check->setSize(KReportItemBase::sizeFromScene(s)); } } - diff --git a/src/items/field/KReportDesignerItemField.h b/src/items/field/KReportDesignerItemField.h --- a/src/items/field/KReportDesignerItemField.h +++ b/src/items/field/KReportDesignerItemField.h @@ -47,7 +47,7 @@ private: void init(QGraphicsScene *scene); - QRect getTextRect() const; + QRectF getTextRect() const; private Q_SLOTS: void slotPropertyChanged(KPropertySet &, KProperty &); diff --git a/src/items/field/KReportDesignerItemField.cpp b/src/items/field/KReportDesignerItemField.cpp --- a/src/items/field/KReportDesignerItemField.cpp +++ b/src/items/field/KReportDesignerItemField.cpp @@ -75,9 +75,9 @@ KReportDesignerItemField::~KReportDesignerItemField() {} -QRect KReportDesignerItemField::getTextRect() const +QRectF KReportDesignerItemField::getTextRect() const { - return QFontMetrics(font()).boundingRect(x(), y(), 0, 0, textFlags(), renderText()); + return QFontMetricsF(font()).boundingRect(QRectF(x(), y(), 0, 0), textFlags(), renderText()); } diff --git a/src/items/field/KReportItemField.cpp b/src/items/field/KReportItemField.cpp --- a/src/items/field/KReportItemField.cpp +++ b/src/items/field/KReportItemField.cpp @@ -17,6 +17,7 @@ #include "KReportItemField.h" #include "KReportRenderObjects.h" +#include "KReportUtils.h" #include "kreportplugin_debug.h" #ifdef KREPORT_SCRIPTING #include "KReportScriptHandler.h" @@ -38,7 +39,7 @@ KReportItemField::KReportItemField(const QDomNode & element) : KReportItemField() { - nameProperty()->setValue(element.toElement().attribute(QLatin1String("report:name"))); + nameProperty()->setValue(KReportUtils::readNameAttribute(element.toElement())); m_controlSource->setValue(element.toElement().attribute(QLatin1String("report:item-data-source"))); m_itemValue->setValue(element.toElement().attribute(QLatin1String("report:value"))); setZ(element.toElement().attribute(QLatin1String("report:z-index")).toDouble()); @@ -110,7 +111,7 @@ m_backgroundOpacity = new KProperty("background-opacity", QVariant(0), tr("Background Opacity")); m_backgroundOpacity->setOption("max", 100); m_backgroundOpacity->setOption("min", 0); - m_backgroundOpacity->setOption("unit", QLatin1String("%")); + m_backgroundOpacity->setOption("suffix", QLatin1String("%")); m_lineWeight = new KProperty("line-weight", 1.0, tr("Line Weight")); m_lineWeight->setOption("step", 1.0); @@ -255,16 +256,16 @@ //Work out the size of the text if (tb->canGrow()) { - QRect r; + QRectF r; if (tb->wordWrap()) { //Grow vertically - QFontMetrics metrics(font()); - QRect temp(tb->position().x(), tb->position().y(), tb->size().width(), 5000); // a large vertical height + QFontMetricsF metrics(font()); + QRectF temp(tb->position().x(), tb->position().y(), tb->size().width(), 5000); // a large vertical height r = metrics.boundingRect(temp, tb->flags(), str); } else { //Grow Horizontally - QFontMetrics metrics(font()); - QRect temp(tb->position().x(), tb->position().y(), 5000, tb->size().height()); // a large vertical height + QFontMetricsF metrics(font()); + QRectF temp(tb->position().x(), tb->position().y(), 5000, tb->size().height()); // a large vertical height r = metrics.boundingRect(temp, tb->flags(), str); } tb->setSize(r.size() + QSize(4,4)); diff --git a/src/items/image/KReportItemImage.cpp b/src/items/image/KReportItemImage.cpp --- a/src/items/image/KReportItemImage.cpp +++ b/src/items/image/KReportItemImage.cpp @@ -16,6 +16,7 @@ */ #include "KReportItemImage.h" +#include "KReportUtils.h" #include "KReportRenderObjects.h" #include "kreportplugin_debug.h" @@ -34,7 +35,7 @@ KReportItemImage::KReportItemImage(const QDomNode & element) : KReportItemImage() { - nameProperty()->setValue(element.toElement().attribute(QLatin1String("report:name"))); + nameProperty()->setValue(KReportUtils::readNameAttribute(element.toElement())); m_controlSource->setValue(element.toElement().attribute(QLatin1String("report:item-data-source"))); m_resizeMode->setValue(element.toElement().attribute(QLatin1String("report:resize-mode"), QLatin1String("stretch"))); setZ(element.toElement().attribute(QLatin1String("report:z-index")).toDouble()); @@ -55,7 +56,6 @@ kreportpluginWarning() << "while parsing image element encountered unknown element: " << n; } } - } KReportItemImage::~KReportItemImage() diff --git a/src/items/label/KReportDesignerItemLabel.cpp b/src/items/label/KReportDesignerItemLabel.cpp --- a/src/items/label/KReportDesignerItemLabel.cpp +++ b/src/items/label/KReportDesignerItemLabel.cpp @@ -88,7 +88,7 @@ QRectF KReportDesignerItemLabel::getTextRect() const { - return QFontMetrics(font()).boundingRect(x(), y(), 0, 0, textFlags(), m_text->value().toString()); + return QFontMetricsF(font()).boundingRect(QRectF(x(), y(), 0, 0), textFlags(), m_text->value().toString()); } void KReportDesignerItemLabel::paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget) diff --git a/src/items/label/KReportItemLabel.cpp b/src/items/label/KReportItemLabel.cpp --- a/src/items/label/KReportItemLabel.cpp +++ b/src/items/label/KReportItemLabel.cpp @@ -17,6 +17,7 @@ #include "KReportItemLabel.h" #include "KReportRenderObjects.h" +#include "KReportUtils.h" #include "kreportplugin_debug.h" #include @@ -34,7 +35,7 @@ KReportItemLabel::KReportItemLabel(const QDomNode & element) : KReportItemLabel() { - nameProperty()->setValue(element.toElement().attribute(QLatin1String("report:name"))); + nameProperty()->setValue(KReportUtils::readNameAttribute(element.toElement())); m_text->setValue(element.toElement().attribute(QLatin1String("report:caption"))); setZ(element.toElement().attribute(QLatin1String("report:z-index")).toDouble()); m_horizontalAlignment->setValue(element.toElement().attribute(QLatin1String("report:horizontal-align"))); @@ -108,7 +109,7 @@ m_backgroundOpacity = new KProperty("background-opacity", QVariant(0), tr("Background Opacity")); m_backgroundOpacity->setOption("max", 100); m_backgroundOpacity->setOption("min", 0); - m_backgroundOpacity->setOption("unit", QLatin1String("%")); + m_backgroundOpacity->setOption("suffix", QLatin1String("%")); m_lineWeight = new KProperty("line-weight", 1.0, tr("Line Weight")); m_lineWeight->setOption("step", 1.0); diff --git a/src/items/label/KReportLabelPlugin.cpp b/src/items/label/KReportLabelPlugin.cpp --- a/src/items/label/KReportLabelPlugin.cpp +++ b/src/items/label/KReportLabelPlugin.cpp @@ -70,25 +70,29 @@ return false; } KReportLabelElement label(*el); - label.setText(KReportUtils::attr(dom, "report:caption", QString())); - QString s = KReportUtils::attr(dom, "report:horizontal-align", QString()); - Qt::Alignment alignment = KReportUtils::horizontalAlignment(s, label.alignment() & Qt::AlignHorizontal_Mask); - s = KReportUtils::attr(dom, "report:vertical-align", QString()); + label.setText(KReportUtils::attr(dom, QLatin1String("report:caption"), QString())); + QString s = KReportUtils::attr(dom, QLatin1String("report:horizontal-align"), QString()); + Qt::Alignment alignment = KReportUtils::horizontalAlignment( + s, label.alignment() & Qt::AlignHorizontal_Mask); + s = KReportUtils::attr(dom, QLatin1String("report:vertical-align"), QString()); alignment |= KReportUtils::verticalAlignment(s, label.alignment() & Qt::AlignVertical_Mask); label.setAlignment(alignment); const QDomElement textStyleDom = dom.firstChildElement(QLatin1String("report:text-style")); QFont font(label.font()); KReportUtils::readFontAttributes(textStyleDom, &font); label.setFont(font); - const QDomElement lineStyleDom = dom.firstChildElement(QLatin1String("report:line-style")); + const QDomElement lineStyleDom + = dom.firstChildElement(QLatin1String("report:line-style")); KReportLineStyle borderStyle(label.borderStyle()); - s = KReportUtils::attr(lineStyleDom, "report:line-style", QString()); + s = KReportUtils::attr(lineStyleDom, QLatin1String("report:line-style"), QString()); borderStyle.setPenStyle(KReportUtils::penStyle(s, borderStyle.penStyle())); - borderStyle.setColor(KReportUtils::attr(lineStyleDom, "report:line-color", borderStyle.color())); + borderStyle.setColor(KReportUtils::attr( + lineStyleDom, QLatin1String("report:line-color"), borderStyle.color())); // border-line-width could be better name but it's too late... - borderStyle.setWeight(KReportUtils::attr(lineStyleDom, "report:line-weight", borderStyle.weight())); + borderStyle.setWeight(KReportUtils::attr( + lineStyleDom, QLatin1String("report:line-weight"), borderStyle.weight())); label.setBorderStyle(borderStyle); return true; } diff --git a/src/items/text/KReportDesignerItemText.h b/src/items/text/KReportDesignerItemText.h --- a/src/items/text/KReportDesignerItemText.h +++ b/src/items/text/KReportDesignerItemText.h @@ -45,7 +45,7 @@ void mousePressEvent(QGraphicsSceneMouseEvent * event) override; private: - QRect getTextRect() const; + QRectF getTextRect() const; void init(QGraphicsScene *scene); private Q_SLOTS: diff --git a/src/items/text/KReportDesignerItemText.cpp b/src/items/text/KReportDesignerItemText.cpp --- a/src/items/text/KReportDesignerItemText.cpp +++ b/src/items/text/KReportDesignerItemText.cpp @@ -80,9 +80,9 @@ () {} -QRect KReportDesignerItemText::getTextRect() const +QRectF KReportDesignerItemText::getTextRect() const { - return QFontMetrics(font()).boundingRect(int (x()), int (y()), 0, 0, textFlags(), renderText()); + return QFontMetricsF(font()).boundingRect(QRectF(x(), y(), 0, 0), textFlags(), renderText()); } void KReportDesignerItemText::paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget) diff --git a/src/items/text/KReportItemText.cpp b/src/items/text/KReportItemText.cpp --- a/src/items/text/KReportItemText.cpp +++ b/src/items/text/KReportItemText.cpp @@ -18,6 +18,7 @@ #include "KReportItemText.h" #include "KReportRenderObjects.h" #include "kreportplugin_debug.h" +#include "KReportUtils.h" #include #include @@ -38,7 +39,7 @@ KReportItemText::KReportItemText(const QDomNode & element) : KReportItemText() { - nameProperty()->setValue(element.toElement().attribute(QLatin1String("report:name"))); + nameProperty()->setValue(KReportUtils::readNameAttribute(element.toElement())); m_controlSource->setValue(element.toElement().attribute(QLatin1String("report:item-data-source"))); m_itemValue->setValue(element.toElement().attribute(QLatin1String("report:value"))); setZ(element.toElement().attribute(QLatin1String("report:z-index")).toDouble()); @@ -138,7 +139,7 @@ m_backgroundOpacity = new KProperty("background-opacity", QVariant(0), tr("Background Opacity")); m_backgroundOpacity->setOption("max", 100); m_backgroundOpacity->setOption("min", 0); - m_backgroundOpacity->setOption("unit", QLatin1String("%")); + m_backgroundOpacity->setOption("suffix", QLatin1String("%")); propertySet()->addProperty(m_controlSource); propertySet()->addProperty(m_itemValue); @@ -230,7 +231,7 @@ QChar separator; QRegularExpression re(QLatin1String("\\s")); QPrinter prnt(QPrinter::HighResolution); - QFontMetrics fm(font(), &prnt); + QFontMetricsF fm(font(), &prnt); // int intRectWidth = (int)(trf.width() * prnt.resolution()) - 10; int intRectWidth = (int)((size().width() / 72) * prnt.resolution()); diff --git a/src/plugins/barcode/KReportDesignerItemBarcode.h b/src/plugins/barcode/KReportDesignerItemBarcode.h --- a/src/plugins/barcode/KReportDesignerItemBarcode.h +++ b/src/plugins/barcode/KReportDesignerItemBarcode.h @@ -50,7 +50,7 @@ private: void init(QGraphicsScene *scene); - QRect getTextRect(); + QRectF getTextRect() const; private Q_SLOTS: void slotPropertyChanged(KPropertySet &, KProperty &); diff --git a/src/plugins/barcode/KReportDesignerItemBarcode.cpp b/src/plugins/barcode/KReportDesignerItemBarcode.cpp --- a/src/plugins/barcode/KReportDesignerItemBarcode.cpp +++ b/src/plugins/barcode/KReportDesignerItemBarcode.cpp @@ -76,11 +76,11 @@ KReportDesignerItemBarcode::~KReportDesignerItemBarcode() {} -QRect KReportDesignerItemBarcode::getTextRect() +QRectF KReportDesignerItemBarcode::getTextRect() const { QFont fnt = QFont(); - return QFontMetrics(fnt) - .boundingRect(int (x()), int (y()), 0, 0, 0, + return QFontMetricsF(fnt) + .boundingRect(QRectF(x(), y(), 0, 0), 0, dataSourceAndObjectTypeName(itemDataSource(), QLatin1String("barcode"))); } diff --git a/src/plugins/barcode/KReportItemBarcode.cpp b/src/plugins/barcode/KReportItemBarcode.cpp --- a/src/plugins/barcode/KReportItemBarcode.cpp +++ b/src/plugins/barcode/KReportItemBarcode.cpp @@ -37,15 +37,14 @@ KReportItemBarcode::KReportItemBarcode(const QDomNode & element) : KReportItemBarcode() { - nameProperty()->setValue(element.toElement().attribute(QLatin1String("report:name"))); + nameProperty()->setValue(KReportUtils::readNameAttribute(element.toElement())); m_controlSource->setValue(element.toElement().attribute(QLatin1String("report:item-data-source"))); m_itemValue->setValue(element.toElement().attribute(QLatin1String("report:value"))); setZ(element.toElement().attribute(QLatin1String("report:z-index")).toDouble()); m_horizontalAlignment->setValue(element.toElement().attribute(QLatin1String("report:horizontal-align"))); m_maxLength->setValue(element.toElement().attribute(QLatin1String("report:barcode-max-length")).toInt()); m_format->setValue(element.toElement().attribute(QLatin1String("report:barcode-format"))); parseReportRect(element.toElement()); - } void KReportItemBarcode::setMaxLength(int i) diff --git a/src/plugins/chart/KReportItemChart.cpp b/src/plugins/chart/KReportItemChart.cpp --- a/src/plugins/chart/KReportItemChart.cpp +++ b/src/plugins/chart/KReportItemChart.cpp @@ -18,6 +18,7 @@ #include "KReportItemChart.h" #include "KReportRenderObjects.h" +#include "KReportUtils.h" #include #include @@ -51,7 +52,7 @@ : KReportItemChart() { QDomElement e = element->toElement(); - m_name->setValue(e.attribute("report:name")); + m_name->setValue(KReportUtils::readNameAttribute(e)); m_dataSource->setValue(e.attribute("report:data-source")); Z = e.attribute("report:z-index").toDouble(); m_chartType->setValue(e.attribute("report:chart-type").toInt()); @@ -70,7 +71,6 @@ m_linkChild->setValue(e.attribute("report:link-child")); parseReportRect(e, &m_pos, &m_size); - } diff --git a/src/plugins/maps/KReportItemMaps.cpp b/src/plugins/maps/KReportItemMaps.cpp --- a/src/plugins/maps/KReportItemMaps.cpp +++ b/src/plugins/maps/KReportItemMaps.cpp @@ -16,14 +16,14 @@ * License along with this library. If not, see . */ #include "KReportItemMaps.h" +#include "KReportUtils.h" +#include "KReportRenderObjects.h" #include #include #include -#include - #include #define myDebug() if (0) kDebug(44021) @@ -37,7 +37,7 @@ KReportItemMaps::KReportItemMaps(const QDomNode &element) : KReportItemMaps() { - nameProperty()->setValue(element.toElement().attribute(QLatin1String("report:name"))); + nameProperty()->setValue(KReportUtils::readNameAttribute(element.toElement())); m_controlSource->setValue(element.toElement().attribute(QLatin1String("report:item-data-source"))); setZ(element.toElement().attribute(QLatin1String("report:z-index")).toDouble()); m_latitudeProperty->setValue(element.toElement().attribute(QLatin1String("report:latitude")).toDouble()); @@ -61,13 +61,13 @@ m_latitudeProperty = new KProperty("latitude", 0.0, tr("Latitude"), QString(), KProperty::Double); m_latitudeProperty->setOption("min", -90); m_latitudeProperty->setOption("max", 90); - m_latitudeProperty->setOption("unit", QString::fromUtf8("°")); + m_latitudeProperty->setOption("suffix", QString::fromUtf8("°")); m_latitudeProperty->setOption("precision", 7); m_longitudeProperty = new KProperty("longitude", 0.0, tr("Longitude"), QString(), KProperty::Double); m_longitudeProperty->setOption("min", -180); m_longitudeProperty->setOption("max", 180); - m_longitudeProperty->setOption("unit", QString::fromUtf8("°")); + m_longitudeProperty->setOption("suffix", QString::fromUtf8("°")); m_longitudeProperty->setOption("precision", 7); m_zoomProperty = new KProperty("zoom", 1000, tr("Zoom") ); @@ -82,7 +82,8 @@ QVariant(mapThemIds[1]), tr("Theme")); if (mapThemIds.contains(QLatin1String("earth/srtm/srtm.dgml"))) { - m_themeProperty->setValue(QLatin1String("earth/srtm/srtm.dgml"), KProperty::ValueOption::IgnoreOld); + m_themeProperty->setValue(QLatin1String("earth/srtm/srtm.dgml"), + KProperty::ValueOption::IgnoreOld); } propertySet()->addProperty(m_controlSource); diff --git a/src/plugins/web/KReportItemWeb.cpp b/src/plugins/web/KReportItemWeb.cpp --- a/src/plugins/web/KReportItemWeb.cpp +++ b/src/plugins/web/KReportItemWeb.cpp @@ -19,7 +19,8 @@ */ #include "KReportItemWeb.h" -#include +#include "KReportUtils.h" +#include "KReportRenderObjects.h" #include #include @@ -42,15 +43,15 @@ KReportItemWeb::KReportItemWeb(const QDomNode &element) : KReportItemWeb() { + QDomElement e = element.toElement(); + + m_controlSource->setValue(e.attribute(QLatin1String("report:item-data-source"))); + nameProperty()->setValue(KReportUtils::readNameAttribute(e)); + setZ(e.attribute(QLatin1String("report:z-index")).toDouble()); + parseReportRect(e); QDomNodeList nl = element.childNodes(); QString n; QDomNode node; - QDomElement e = element.toElement(); - - m_controlSource->setValue(element.toElement().attribute(QLatin1String("report:item-data-source"))); - nameProperty()->setValue(element.toElement().attribute(QLatin1String("report:name"))); - setZ(element.toElement().attribute(QLatin1String("report:z-index")).toDouble()); - parseReportRect(element.toElement()); for (int i = 0; i < nl.count(); i++) { node = nl.item(i); n = node.nodeName(); diff --git a/src/renderer/scripting/KReportScriptDraw.cpp b/src/renderer/scripting/KReportScriptDraw.cpp --- a/src/renderer/scripting/KReportScriptDraw.cpp +++ b/src/renderer/scripting/KReportScriptDraw.cpp @@ -100,7 +100,7 @@ { if (m_curPage) { QFont f(fnt, pt); - QRectF r = QFontMetrics(f).boundingRect(txt); + QRectF r = QFontMetricsF(f).boundingRect(txt); KReportTextStyleData ts; ts.font = f; diff --git a/src/renderer/scripting/KReportScriptLine.cpp b/src/renderer/scripting/KReportScriptLine.cpp --- a/src/renderer/scripting/KReportScriptLine.cpp +++ b/src/renderer/scripting/KReportScriptLine.cpp @@ -67,21 +67,22 @@ QPointF Line::startPosition() const { - return m_line->m_start->value().toPointF(); + return m_line->startPosition(); } void Line::setStartPosition(const QPointF& startPosition) { - m_line->m_start->setValue(startPosition); + m_line->setStartPosition(startPosition); } QPointF Line::endPosition() const { - return m_line->m_end->value().toPointF(); + return m_line->endPosition(); } void Line::setEndPosition(const QPointF& endPosition) { - m_line->m_end->setValue(endPosition); + m_line->setEndPosition(endPosition); } + } diff --git a/src/renderer/scripting/KReportScriptSection.cpp b/src/renderer/scripting/KReportScriptSection.cpp --- a/src/renderer/scripting/KReportScriptSection.cpp +++ b/src/renderer/scripting/KReportScriptSection.cpp @@ -50,12 +50,12 @@ qreal Section::height() const { - return m_section->m_height->value().toDouble(); + return m_section->height(); } void Section::setHeight(qreal h) { - m_section->m_height->setValue(h); + m_section->setHeight(h); } QString Section::name() const diff --git a/src/wrtembed/KReportDesigner.h b/src/wrtembed/KReportDesigner.h --- a/src/wrtembed/KReportDesigner.h +++ b/src/wrtembed/KReportDesigner.h @@ -329,6 +329,10 @@ void createActions(); + QSize pageSizePt() const; + + void recalculateMaxMargins(); + private Q_SLOTS: void slotPropertyChanged(KPropertySet &s, KProperty &p); diff --git a/src/wrtembed/KReportDesigner.cpp b/src/wrtembed/KReportDesigner.cpp --- a/src/wrtembed/KReportDesigner.cpp +++ b/src/wrtembed/KReportDesigner.cpp @@ -121,6 +121,25 @@ void init(const QDomElement *xml); + void updateCurrentUnit() { + QString u = unit->value().toString(); + KReportUnit newUnit = KReportUnit(KReportUnit::symbolToType(u)); + if (newUnit.isValid()) { + currentUnit = newUnit; + } else { + currentUnit = DEFAULT_UNIT; + } + + if (u == QLatin1String("dm")) { + gridDivisions->setOption("max", 100); + } else { + gridDivisions->setOption("max", 10); + if (gridDivisions->value().toInt() > 10) { + gridDivisions->setValue(10, KProperty::ValueOption::IgnoreOld); + } + } + } + #ifdef KREPORT_SCRIPTING void updateScripts(); #endif @@ -172,6 +191,8 @@ KProperty *script; #endif + KReportUnit currentUnit; + //Actions QAction *editCutAction; QAction *editCopyAction; @@ -201,7 +222,8 @@ void loadXml(const QDomElement &data); }; -KReportDesigner::Private::Private(KReportDesigner *designer) : q(designer) +KReportDesigner::Private::Private(KReportDesigner *designer) + : q(designer), currentUnit(DEFAULT_UNIT_TYPE) { } @@ -227,6 +249,7 @@ //Create nice rulers hruler = new KReportRuler(nullptr, Qt::Horizontal, zoomHandler); + hruler->setUnit(DEFAULT_UNIT); pageButton = new KReportPropertiesButton; @@ -296,7 +319,8 @@ showGrid->setValue(it.toElement().attribute(QLatin1String("report:grid-visible"), QString::number(1)).toInt() != 0); gridSnap->setValue(it.toElement().attribute(QLatin1String("report:grid-snap"), QString::number(1)).toInt() != 0); gridDivisions->setValue(it.toElement().attribute(QLatin1String("report:grid-divisions"), QString::number(4)).toInt()); - unit->setValue(it.toElement().attribute(QLatin1String("report:page-unit"), QLatin1String("cm"))); + unit->setValue(it.toElement().attribute(QLatin1String("report:page-unit"), DEFAULT_UNIT_STRING)); + updateCurrentUnit(); } //! @todo Load page options @@ -313,13 +337,21 @@ //! @todo } - rightMargin->setValue(KReportUnit::parseValue(it.toElement().attribute(QLatin1String("fo:margin-right"), QLatin1String("1.0cm")))); - leftMargin->setValue(KReportUnit::parseValue(it.toElement().attribute(QLatin1String("fo:margin-left"), QLatin1String("1.0cm")))); - topMargin->setValue(KReportUnit::parseValue(it.toElement().attribute(QLatin1String("fo:margin-top"), QLatin1String("1.0cm")))); - bottomMargin->setValue(KReportUnit::parseValue(it.toElement().attribute(QLatin1String("fo:margin-bottom"), QLatin1String("1.0cm")))); - - orientation->setValue(it.toElement().attribute(QLatin1String("report:print-orientation"), QLatin1String("portrait"))); - + rightMargin->setValue(currentUnit.convertFromPoint( + KReportUnit::parseValue(it.toElement().attribute( + QLatin1String("fo:margin-right"), DEFAULT_PAGE_MARGIN_STRING)))); + leftMargin->setValue(currentUnit.convertFromPoint( + KReportUnit::parseValue(it.toElement().attribute( + QLatin1String("fo:margin-left"), DEFAULT_PAGE_MARGIN_STRING)))); + topMargin->setValue(currentUnit.convertFromPoint( + KReportUnit::parseValue(it.toElement().attribute( + QLatin1String("fo:margin-top"), DEFAULT_PAGE_MARGIN_STRING)))); + bottomMargin->setValue(currentUnit.convertFromPoint( + KReportUnit::parseValue(it.toElement().attribute( + QLatin1String("fo:margin-bottom"), DEFAULT_PAGE_MARGIN_STRING)))); + orientation->setValue( + it.toElement().attribute(QLatin1String("report:print-orientation"), + QLatin1String("portrait"))); } else if (n == QLatin1String("report:body")) { QDomNodeList sectionlist = it.childNodes(); QDomNode sec; @@ -330,7 +362,7 @@ QString sn = sec.nodeName().toLower(); //kreportDebug() << sn; if (sn == QLatin1String("report:section")) { - QString sectiontype = sec.toElement().attribute(QLatin1String("report:section-type")); + const QString sectiontype = KReportUtils::readSectionTypeNameAttribute(sec.toElement()); if (q->section(KReportSectionData::sectionTypeFromString(sectiontype)) == nullptr) { q->insertSection(KReportSectionData::sectionTypeFromString(sectiontype)); q->section(KReportSectionData::sectionTypeFromString(sectiontype))->initFromXML(sec); @@ -432,9 +464,13 @@ if (d->pageSize->value().toString() == QLatin1String("Custom")) { pagestyle.appendChild(doc.createTextNode(QLatin1String("custom"))); - KReportUtils::setAttribute(&pagestyle, QLatin1String("report:custom-page-width"), d->customPageSize->value().toSizeF().width()); - KReportUtils::setAttribute(&pagestyle, QLatin1String("report:custom-page-height"), d->customPageSize->value().toSizeF().height()); + KReportUtils::setAttribute( + &pagestyle, QLatin1String("report:custom-page-width"), + d->currentUnit.convertToPoint(d->customPageSize->value().toSizeF().width())); + KReportUtils::setAttribute( + &pagestyle, QLatin1String("report:custom-page-height"), + d->currentUnit.convertToPoint(d->customPageSize->value().toSizeF().height())); } else if (d->pageSize->value().toString() == QLatin1String("Label")) { pagestyle.appendChild(doc.createTextNode(QLatin1String("label"))); pagestyle.setAttribute(QLatin1String("report:page-label-type"), d->labelType->value().toString()); @@ -448,10 +484,18 @@ KReportUtils::addPropertyAsAttribute(&pagestyle, d->orientation); // -- margins: save as points, and not localized - KReportUtils::setAttribute(&pagestyle, QLatin1String("fo:margin-top"), d->topMargin->value().toDouble()); - KReportUtils::setAttribute(&pagestyle, QLatin1String("fo:margin-bottom"), d->bottomMargin->value().toDouble()); - KReportUtils::setAttribute(&pagestyle, QLatin1String("fo:margin-right"), d->rightMargin->value().toDouble()); - KReportUtils::setAttribute(&pagestyle, QLatin1String("fo:margin-left"), d->leftMargin->value().toDouble()); + KReportUtils::setAttribute( + &pagestyle, QLatin1String("fo:margin-top"), + d->currentUnit.convertToPoint(d->topMargin->value().toDouble())); + KReportUtils::setAttribute( + &pagestyle, QLatin1String("fo:margin-bottom"), + d->currentUnit.convertToPoint(d->bottomMargin->value().toDouble())); + KReportUtils::setAttribute( + &pagestyle, QLatin1String("fo:margin-right"), + d->currentUnit.convertToPoint(d->rightMargin->value().toDouble())); + KReportUtils::setAttribute( + &pagestyle, QLatin1String("fo:margin-left"), + d->currentUnit.convertToPoint(d->leftMargin->value().toDouble())); content.appendChild(pagestyle); @@ -772,8 +816,9 @@ QVariant defaultKey = KReportPageSize::pageSizeKey(KReportPageSize::defaultSize()); d->pageSize = new KProperty("page-size", listData, defaultKey, tr("Page Size")); - d->customPageSize = new KProperty("custom-page-size", QSizeF(KReportUnit(KReportUnit::Type::Centimeter).fromUserValue(10), KReportUnit(KReportUnit::Type::Centimeter).fromUserValue(10)), + d->customPageSize = new KProperty("custom-page-size", DEFAULT_CUSTOM_PAGE_SIZE, tr("Custom Page Size"), tr("Custom Page Size"), KProperty::SizeF); + d->customPageSize->setOption("suffix", d->currentUnit.symbol()); listData = new KPropertyListData({ QLatin1String("portrait"), QLatin1String("landscape") }, QVariantList{ tr("Portrait"), tr("Landscape") }); @@ -783,24 +828,26 @@ QList types(KReportUnit::allTypes()); types.removeOne(KReportUnit::Type::Pixel); listData = new KPropertyListData(KReportUnit::symbols(types), KReportUnit::descriptions(types)); - d->unit = new KProperty("page-unit", listData, QLatin1String("cm"), tr("Page Unit")); - + d->unit = new KProperty("page-unit", listData, DEFAULT_UNIT_STRING, tr("Page Unit")); d->showGrid = new KProperty("grid-visible", true, tr("Show Grid")); d->gridSnap = new KProperty("grid-snap", true, tr("Snap to Grid")); d->gridDivisions = new KProperty("grid-divisions", 4, tr("Grid Divisions")); + d->gridDivisions->setOption("min", 1); + d->gridDivisions->setOption("max", 10); + - d->leftMargin = new KProperty("margin-left", KReportUnit(KReportUnit::Type::Centimeter).fromUserValue(1.0), + d->leftMargin = new KProperty("margin-left", pageUnit().convertFromPoint(KReportUnit::parseValue(DEFAULT_PAGE_MARGIN_STRING)), tr("Left Margin"), tr("Left Margin"), KProperty::Double); - d->rightMargin = new KProperty("margin-right", KReportUnit(KReportUnit::Type::Centimeter).fromUserValue(1.0), + d->rightMargin = new KProperty("margin-right", pageUnit().convertFromPoint(KReportUnit::parseValue(DEFAULT_PAGE_MARGIN_STRING)), tr("Right Margin"), tr("Right Margin"), KProperty::Double); - d->topMargin = new KProperty("margin-top", KReportUnit(KReportUnit::Type::Centimeter).fromUserValue(1.0), + d->topMargin = new KProperty("margin-top", pageUnit().convertFromPoint(KReportUnit::parseValue(DEFAULT_PAGE_MARGIN_STRING)), tr("Top Margin"), tr("Top Margin"), KProperty::Double); - d->bottomMargin = new KProperty("margin-bottom", KReportUnit(KReportUnit::Type::Centimeter).fromUserValue(1.0), + d->bottomMargin = new KProperty("margin-bottom", pageUnit().convertFromPoint(KReportUnit::parseValue(DEFAULT_PAGE_MARGIN_STRING)), tr("Bottom Margin"), tr("Bottom Margin"), KProperty::Double); - d->leftMargin->setOption("unit", QLatin1String("cm")); - d->rightMargin->setOption("unit", QLatin1String("cm")); - d->topMargin->setOption("unit", QLatin1String("cm")); - d->bottomMargin->setOption("unit", QLatin1String("cm")); + d->leftMargin->setOption("suffix", d->currentUnit.symbol()); + d->rightMargin->setOption("suffix", d->currentUnit.symbol()); + d->topMargin->setOption("suffix", d->currentUnit.symbol()); + d->bottomMargin->setOption("suffix", d->currentUnit.symbol()); d->set.addProperty(d->title); d->set.addProperty(d->pageSize); @@ -815,6 +862,8 @@ d->set.addProperty(d->topMargin); d->set.addProperty(d->bottomMargin); + recalculateMaxMargins(); + #ifdef KREPORT_SCRIPTING d->script = new KProperty("script", new KPropertyListData, QVariant(), tr("Object Script")); d->set.addProperty(d->script); @@ -826,19 +875,47 @@ */ void KReportDesigner::slotPropertyChanged(KPropertySet &s, KProperty &p) { + const QSignalBlocker blocker(s); setModified(true); - emit pagePropertyChanged(s); + QByteArray propertyName = p.name(); - if (p.name() == "page-unit") { + if (propertyName == "page-unit") { + const KReportUnit oldUnit = d->currentUnit; + d->updateCurrentUnit(); d->hruler->setUnit(pageUnit()); - QString newstr = d->set.property("page-unit").value().toString(); - d->set.property("margin-left").setOption("unit", newstr); - d->set.property("margin-right").setOption("unit", newstr); - d->set.property("margin-top").setOption("unit", newstr); - d->set.property("margin-bottom").setOption("unit", newstr); - d->set.property("custom-page-size").setOption("unit", newstr); + // convert values + d->leftMargin->setValue(KReportUnit::convertFromUnitToUnit( + d->leftMargin->value().toDouble(), oldUnit, d->currentUnit), + KProperty::ValueOption::IgnoreOld); + + d->rightMargin->setValue(KReportUnit::convertFromUnitToUnit( + d->rightMargin->value().toDouble(), oldUnit, d->currentUnit), + KProperty::ValueOption::IgnoreOld); + + d->topMargin->setValue(KReportUnit::convertFromUnitToUnit(d->topMargin->value().toDouble(), + oldUnit, d->currentUnit), + KProperty::ValueOption::IgnoreOld); + + d->bottomMargin->setValue(KReportUnit::convertFromUnitToUnit( + d->bottomMargin->value().toDouble(), oldUnit, d->currentUnit), + KProperty::ValueOption::IgnoreOld); + + d->customPageSize->setValue( + KReportUnit::convertFromUnitToUnit(d->customPageSize->value().toSizeF(), oldUnit, + d->currentUnit), + KProperty::ValueOption::IgnoreOld); + + d->leftMargin->setOption("suffix", d->currentUnit.symbol()); + d->rightMargin->setOption("suffix", d->currentUnit.symbol()); + d->topMargin->setOption("suffix", d->currentUnit.symbol()); + d->bottomMargin->setOption("suffix", d->currentUnit.symbol()); + d->customPageSize->setOption("suffix", d->currentUnit.symbol()); + } else if (propertyName.startsWith("margin-") || propertyName == "page-size" || propertyName == "custom-page-size") { + recalculateMaxMargins(); } + emit pagePropertyChanged(s); + } void KReportDesigner::slotPageButton_Pressed() @@ -898,7 +975,7 @@ if (d->set.property("page-size").value().toString() == QLatin1String("Custom")) { KReportUnit unit = pageUnit(); - QSizeF customSize = d->set.property("custom-page-size").value().toSizeF(); + QSizeF customSize = d->currentUnit.convertToPoint(d->set.property("custom-page-size").value().toSizeF()); QPageLayout layout(QPageSize(customSize, QPageSize::Point, QString(), QPageSize::ExactMatch), d->set.property("print-orientation").value().toString() == QLatin1String("portrait") ? QPageLayout::Portrait : QPageLayout::Landscape, QMarginsF(0,0,0,0)); @@ -913,12 +990,35 @@ pageWidth = pageSizePx.width(); - pageWidth = pageWidth - POINT_TO_INCH(d->set.property("margin-left").value().toDouble()) * KReportPrivate::dpiX(); - pageWidth = pageWidth - POINT_TO_INCH(d->set.property("margin-right").value().toDouble()) * KReportPrivate::dpiX(); + pageWidth = pageWidth - KReportUnit::convertFromUnitToUnit(d->set.property("margin-left").value().toDouble(), pageUnit(), KReportUnit(KReportUnit::Type::Inch)) * KReportPrivate::dpiX(); + pageWidth = pageWidth - KReportUnit::convertFromUnitToUnit(d->set.property("margin-right").value().toDouble(), pageUnit(), KReportUnit(KReportUnit::Type::Inch)) * KReportPrivate::dpiX(); return pageWidth; } +QSize KReportDesigner::pageSizePt() const +{ + QSize pageSizePt; + + if (d->set.property("page-size").value().toString() == QLatin1String("Custom")) { + KReportUnit unit = pageUnit(); + + QSizeF customSize = d->currentUnit.convertToPoint(d->set.property("custom-page-size").value().toSizeF()); + QPageLayout layout(QPageSize(customSize, QPageSize::Point, QString(), QPageSize::ExactMatch), d->set.property("print-orientation").value().toString() + == QLatin1String("portrait") ? QPageLayout::Portrait : QPageLayout::Landscape, QMarginsF(0,0,0,0)); + + pageSizePt = layout.fullRectPoints().size(); + } else { + QPageLayout layout = QPageLayout( + QPageSize(KReportPageSize::pageSize(d->set.property("page-size").value().toString())), + d->set.property("print-orientation").value().toString() + == QLatin1String("portrait") ? QPageLayout::Portrait : QPageLayout::Landscape, QMarginsF(0,0,0,0)); + pageSizePt = layout.fullRectPoints().size(); + } + + return pageSizePt; +} + void KReportDesigner::resizeEvent(QResizeEvent * event) { Q_UNUSED(event); @@ -942,9 +1042,7 @@ KReportUnit KReportDesigner::pageUnit() const { - const QString symbol = d->unit->value().toString(); - KReportUnit unit(KReportUnit::symbolToType(symbol)); - return unit.isValid() ? unit : DEFAULT_UNIT; + return d->currentUnit; } void KReportDesigner::setGridOptions(bool vis, int div) @@ -1050,7 +1148,6 @@ item->setSelected(true); KReportItemBase* baseReportItem = dynamic_cast(item); if (baseReportItem) { - baseReportItem->setUnit(pageUnit()); KPropertySet *set = baseReportItem->propertySet(); KReportDesigner::addMetaProperties(set, classString, iconName); set->clearModifiedFlags(); @@ -1585,3 +1682,12 @@ set->addProperty(prop = new KProperty("this:iconName", iconName)); prop->setVisible(false); } + +void KReportDesigner::recalculateMaxMargins() +{ + QSize pageSize = pageSizePt(); + d->leftMargin->setOption("max", d->currentUnit.convertFromPoint(pageSize.width() - d->currentUnit.convertToPoint(d->rightMargin->value().toReal()) - SMALLEST_PAGE_SIZE_PT)); + d->rightMargin->setOption("max", d->currentUnit.convertFromPoint(pageSize.width() - d->currentUnit.convertToPoint(d->leftMargin->value().toReal())- SMALLEST_PAGE_SIZE_PT)); + d->topMargin->setOption("max", d->currentUnit.convertFromPoint(pageSize.height() - d->currentUnit.convertToPoint(d->bottomMargin->value().toReal())- SMALLEST_PAGE_SIZE_PT)); + d->bottomMargin->setOption("max", d->currentUnit.convertFromPoint(pageSize.height() - d->currentUnit.convertToPoint(d->topMargin->value().toReal())- SMALLEST_PAGE_SIZE_PT)); +} diff --git a/src/wrtembed/KReportDesignerItemBase.cpp b/src/wrtembed/KReportDesignerItemBase.cpp --- a/src/wrtembed/KReportDesignerItemBase.cpp +++ b/src/wrtembed/KReportDesignerItemBase.cpp @@ -17,6 +17,7 @@ */ #include "KReportDesignerItemBase.h" +#include "KReportDesigner.h" #include "KReportItemBase.h" #include "KReportUtils.h" @@ -52,6 +53,7 @@ { d->reportDesigner = r; d->item = b; + b->setUnit(r->pageUnit()); } void KReportDesignerItemBase::buildXML(QGraphicsItem * item, QDomDocument *doc, QDomElement *parent) diff --git a/src/wrtembed/KReportDesignerItemLine.cpp b/src/wrtembed/KReportDesignerItemLine.cpp --- a/src/wrtembed/KReportDesignerItemLine.cpp +++ b/src/wrtembed/KReportDesignerItemLine.cpp @@ -68,8 +68,8 @@ : KReportItemLine(entity), KReportDesignerItemBase(d, this) { init(scene, d); - QPointF s = scenePosition(m_start->value().toPointF()); - QPointF e = scenePosition(m_end->value().toPointF()); + QPointF s = scenePosition(startPosition()); + QPointF e = scenePosition(endPosition()); setLine ( s.x(), s.y(), e.x(), e.y() ); } @@ -118,10 +118,10 @@ // properties addPropertyAsAttribute(&entity, nameProperty()); entity.setAttribute(QLatin1String("report:z-index"), zValue()); - KReportUtils::setAttribute(&entity, QLatin1String("svg:x1"), m_start->value().toPointF().x()); - KReportUtils::setAttribute(&entity, QLatin1String("svg:y1"), m_start->value().toPointF().y()); - KReportUtils::setAttribute(&entity, QLatin1String("svg:x2"), m_end->value().toPointF().x()); - KReportUtils::setAttribute(&entity, QLatin1String("svg:y2"), m_end->value().toPointF().y()); + KReportUtils::setAttribute(&entity, QLatin1String("svg:x1"), startPosition().x()); + KReportUtils::setAttribute(&entity, QLatin1String("svg:y1"), startPosition().y()); + KReportUtils::setAttribute(&entity, QLatin1String("svg:x2"), endPosition().x()); + KReportUtils::setAttribute(&entity, QLatin1String("svg:y2"), endPosition().y()); buildXMLLineStyle(doc, &entity, lineStyle()); @@ -133,8 +133,8 @@ Q_UNUSED(s); if (p.name() == "startposition" || p.name() == "endposition") { - QPointF s = scenePosition(m_start->value().toPointF()); - QPointF e = scenePosition(m_end->value().toPointF()); + QPointF s = scenePosition(startPosition()); + QPointF e = scenePosition(endPosition()); setLine ( s.x(), s.y(), e.x(), e.y() ); } @@ -191,10 +191,10 @@ switch (m_grabAction) { case 1: - m_start->setValue(positionFromScene(QPointF(x,y))); + setStartPosition(positionFromScene(QPointF(x,y))); break; case 2: - m_end->setValue(positionFromScene(QPointF(x,y))); + setEndPosition(positionFromScene(QPointF(x,y))); break; default: QPointF d = mapToItem(this, section->gridPoint(event->scenePos())) - mapToItem(this, section->gridPoint(event->lastScenePos())); @@ -245,9 +245,8 @@ void KReportDesignerItemLine::setLineScene(const QLineF &line) { - m_start->setValue(positionFromScene(line.p1())); - m_end->setValue(positionFromScene(line.p2())); - + setStartPosition(positionFromScene(line.p1())); + setEndPosition(positionFromScene(line.p2())); setLine(line); } diff --git a/src/wrtembed/KReportDesignerItemRectBase.cpp b/src/wrtembed/KReportDesignerItemRectBase.cpp --- a/src/wrtembed/KReportDesignerItemRectBase.cpp +++ b/src/wrtembed/KReportDesignerItemRectBase.cpp @@ -31,10 +31,11 @@ public: Private(); ~Private(); - + int grabAction = 0; int dpiX = KReportPrivate::dpiX(); int dpiY = KReportPrivate::dpiY(); + bool insideSetSceneRect = false; }; KReportDesignerItemRectBase::Private::Private() @@ -74,13 +75,18 @@ void KReportDesignerItemRectBase::setSceneRect(const QRectF& rect, SceneRectFlag update) { + if (d->insideSetSceneRect) { + return; + } + d->insideSetSceneRect = true; QGraphicsRectItem::setPos(rect.x(), rect.y()); setRect(0, 0, rect.width(), rect.height()); if (update == SceneRectFlag::UpdateProperty) { item()->setPosition(KReportItemBase::positionFromScene(QPointF(rect.x(), rect.y()))); item()->setSize(KReportItemBase::sizeFromScene(QSizeF(rect.width(), rect.height()))); } this->update(); + d->insideSetSceneRect = false; } void KReportDesignerItemRectBase::mousePressEvent(QGraphicsSceneMouseEvent * event) @@ -113,7 +119,7 @@ if (!section) { return; } - + QPointF p = section->gridPoint(event->scenePos()); w = p.x() - scenePos().x(); h = p.y() - scenePos().y(); @@ -270,10 +276,10 @@ { KReportDesignerSectionScene *section = qobject_cast(scene()); if (section) { - + if (change == ItemPositionChange) { QPointF newPos = value.toPointF(); - + newPos = section->gridPoint(newPos); if (newPos.x() < 0) newPos.setX(0); @@ -288,7 +294,7 @@ return newPos; } else if (change == ItemPositionHasChanged) { setSceneRect(value.toPointF(), - KReportItemBase::sceneSize(item()->size()), SceneRectFlag::DontUpdateProperty); + KReportItemBase::sceneSize(item()->size()), SceneRectFlag::UpdateProperty); } else if (change == ItemSceneHasChanged && item()) { QPointF newPos = pos(); diff --git a/src/wrtembed/KReportDesignerSection.cpp b/src/wrtembed/KReportDesignerSection.cpp --- a/src/wrtembed/KReportDesignerSection.cpp +++ b/src/wrtembed/KReportDesignerSection.cpp @@ -94,6 +94,7 @@ KReportSectionData *sectionData; int dpiY; + bool slotPropertyChangedEnabled = true; }; @@ -128,19 +129,19 @@ d->sectionRuler->setUnit(d->reportDesigner->pageUnit()); d->scene = new KReportDesignerSectionScene(d->reportDesigner->pageWidthPx(), d->dpiY, rptdes); d->scene->setBackgroundBrush(d->sectionData->backgroundColor()); - + d->sceneView = new KReportDesignerSectionView(rptdes, d->scene, this); d->sceneView->setObjectName(QLatin1String("scene view")); d->sceneView->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); d->resizeBar = new ReportResizeBar(this); connect(d->resizeBar, SIGNAL(barDragged(int)), this, SLOT(slotResizeBarDragged(int))); - connect(d->reportDesigner, SIGNAL(pagePropertyChanged(KPropertySet&)), - this, SLOT(slotPageOptionsChanged(KPropertySet&))); - connect(d->scene, SIGNAL(clicked()), this, (SLOT(slotSceneClicked()))); + connect(d->reportDesigner, &KReportDesigner::pagePropertyChanged, + this, &KReportDesignerSection::slotPageOptionsChanged); + connect(d->scene, &KReportDesignerSectionScene::clicked, this, &KReportDesignerSection::slotSceneClicked); connect(d->scene, SIGNAL(lostFocus()), d->title, SLOT(update())); - connect(d->title, SIGNAL(clicked()), this, (SLOT(slotSceneClicked()))); + connect(d->title, &KReportDesignerSectionTitle::clicked, this, &KReportDesignerSection::slotSceneClicked); glayout->addWidget(d->title, 0, 0, 1, 2); glayout->addWidget(d->sectionRuler, 1, 0); @@ -167,32 +168,37 @@ if (d->sceneView->designer() && d->sceneView->designer()->propertySet()->property("page-size").value().toString() == QLatin1String("Labels")) { return; // we don't want to allow this on reports that are for labels } - + if (changeSet) { slotSceneClicked(); // switches property set to this section } - + qreal h = d->scene->height() + delta; if (h < 1) h = 1; h = d->scene->gridPoint(QPointF(0, h)).y(); - d->sectionData->m_height->setValue(INCH_TO_POINT(h / d->dpiY), - delta == 0 ? KProperty::ValueOption::IgnoreOld - : KProperty::ValueOption::None); + d->slotPropertyChangedEnabled = false; // reduce updates + d->sectionData->setHeight(INCH_TO_POINT(h / d->dpiY), + delta == 0 ? KProperty::ValueOption::IgnoreOld + : KProperty::ValueOption::None); + d->slotPropertyChangedEnabled = true; d->sectionRuler->setRulerLength(h); - d->scene->setSceneRect(0, 0, d->scene->width(), h); - d->sceneView->resizeContents(QSize(d->scene->width(), h)); + const QRect newSceneRect(0, 0, d->scene->width(), h); + if (d->scene->sceneRect() != newSceneRect) { + d->scene->setSceneRect(newSceneRect); + } + d->sceneView->resizeContents(newSceneRect.size()); if (delta != 0) { d->reportDesigner->setModified(true); } } void KReportDesignerSection::buildXML(QDomDocument *doc, QDomElement *section) { - KReportUtils::setAttribute(section, QLatin1String("svg:height"), d->sectionData->m_height->value().toDouble()); + KReportUtils::setAttribute(section, QLatin1String("svg:height"), d->sectionData->height()); section->setAttribute(QLatin1String("fo:background-color"), d->sectionData->backgroundColor().name()); // now get a list of all the QGraphicsItems on this scene and output them. @@ -209,10 +215,10 @@ QDomNode node; QString n; - qreal h = KReportUnit::parseValue(section.toElement().attribute(QLatin1String("svg:height"), QLatin1String("2.0cm"))); - d->sectionData->m_height->setValue(h); + qreal ptHeight = KReportUtils::readSizeAttributes(section.toElement(), QSizeF(DEFAULT_SECTION_SIZE_PT, DEFAULT_SECTION_SIZE_PT)).height(); + d->sectionData->setHeight(ptHeight); - h = POINT_TO_INCH(h) * d->dpiY; + qreal h = POINT_TO_INCH(ptHeight) * d->dpiY; //kreportDebug() << "Section Height: " << h; d->scene->setSceneRect(0, 0, d->scene->width(), h); slotResizeBarDragged(0); @@ -269,8 +275,7 @@ Q_UNUSED(set) KReportUnit unit = d->reportDesigner->pageUnit(); - - d->sectionData->m_height->setOption("unit", unit.symbol()); + d->sectionData->setUnit(unit); //update items position with unit QList itms = d->scene->items(); @@ -286,12 +291,13 @@ d->sectionRuler->setUnit(d->reportDesigner->pageUnit()); //Trigger a redraw of the background + d->sceneView->resizeContents(QSize(d->scene->width(), d->scene->height())); + d->sceneView->resetCachedContent(); + d->sceneView->update(); d->reportDesigner->adjustSize(); d->reportDesigner->repaint(); - - slotResizeBarDragged(0, false); } void KReportDesignerSection::slotSceneClicked() @@ -303,16 +309,22 @@ void KReportDesignerSection::slotPropertyChanged(KPropertySet &s, KProperty &p) { Q_UNUSED(s) + if (!d->slotPropertyChangedEnabled) { + return; + } //kreportDebug() << p.name(); //Handle Background Color if (p.name() == "background-color") { d->scene->setBackgroundBrush(p.value().value()); } if (p.name() == "height") { - d->scene->setSceneRect(0, 0, d->scene->width(), POINT_TO_INCH(p.value().toDouble()) * d->dpiY); - slotResizeBarDragged(0); + const QRect newSceneRect(0, 0, d->scene->width(), POINT_TO_INCH(d->sectionData->height()) * d->dpiY); + if (d->scene->sceneRect() != newSceneRect) { + d->scene->setSceneRect(newSceneRect); + } + d->sceneView->resizeContents(newSceneRect.size()); } if (d->reportDesigner) diff --git a/src/wrtembed/KReportDesignerSectionDetail.cpp b/src/wrtembed/KReportDesignerSectionDetail.cpp --- a/src/wrtembed/KReportDesignerSectionDetail.cpp +++ b/src/wrtembed/KReportDesignerSectionDetail.cpp @@ -20,6 +20,7 @@ #include "KReportDesignerSectionDetailGroup.h" #include "KReportDesignerSection.h" #include "KReportDesigner.h" +#include "KReportUtils.h" #include "kreport_debug.h" #include @@ -116,8 +117,10 @@ KReportDesignerSectionDetailGroup * rsdg = new KReportDesignerSectionDetailGroup(QLatin1String("unnamed"), this, this); rsdg->initFromXML( node.toElement() ); insertGroupSection(groupSectionCount(), rsdg); - } else if (n == QLatin1String("report:section") && node.toElement().attribute(QLatin1String("report:section-type")) == QLatin1String("detail")) { - //kreportDebug() << "Creating detail section"; + } else if (n == QLatin1String("report:section") + && KReportUtils::readSectionTypeNameAttribute(node.toElement()) == QLatin1String("detail")) + { + // kreportDebug() << "Creating detail section"; d->detail->initFromXML(node); } else { // unknown element diff --git a/src/wrtembed/KReportDesignerSectionDetailGroup.cpp b/src/wrtembed/KReportDesignerSectionDetailGroup.cpp --- a/src/wrtembed/KReportDesignerSectionDetailGroup.cpp +++ b/src/wrtembed/KReportDesignerSectionDetailGroup.cpp @@ -20,6 +20,7 @@ #include "KReportDesigner.h" #include "KReportDesignerSection.h" #include "KReportDesignerSectionDetail.h" +#include "KReportUtils.h" #include "kreport_debug.h" #include @@ -129,7 +130,7 @@ } for ( QDomElement e = element.firstChildElement( QLatin1String("report:section") ); ! e.isNull(); e = e.nextSiblingElement( QLatin1String("report:section") ) ) { - QString s = e.attribute( QLatin1String("report:section-type") ); + const QString s = KReportUtils::readSectionTypeNameAttribute(e); if ( s == QLatin1String("group-header") ) { setGroupHeaderVisible( true ); d->groupHeader->initFromXML( e ); diff --git a/src/wrtembed/KReportDesignerSectionScene.cpp b/src/wrtembed/KReportDesignerSectionScene.cpp --- a/src/wrtembed/KReportDesignerSectionScene.cpp +++ b/src/wrtembed/KReportDesignerSectionScene.cpp @@ -62,22 +62,20 @@ painter->setRenderHint(QPainter::Antialiasing, false); if (m_rd->propertySet()->property("grid-visible").value().toBool()) { - if (m_unit.type() != m_rd->pageUnit().type()) { - m_unit = m_rd->pageUnit(); - if (m_unit.type() == KReportUnit::Type::Cicero || - m_unit.type() == KReportUnit::Type::Pica || - m_unit.type() == KReportUnit::Type::Millimeter) { - m_majorX = POINT_TO_INCH(m_unit.fromUserValue(10)) * m_dpiX; - m_majorY = POINT_TO_INCH(m_unit.fromUserValue(10)) * m_dpiY; - } else if (m_unit.type() == KReportUnit::Type::Point) { - m_majorX = POINT_TO_INCH(m_unit.fromUserValue(100)) * m_dpiX; - m_majorY = POINT_TO_INCH(m_unit.fromUserValue(100)) * m_dpiY; - } else { - m_majorX = POINT_TO_INCH(m_unit.fromUserValue(1)) * m_dpiX; - m_majorY = POINT_TO_INCH(m_unit.fromUserValue(1)) * m_dpiY; - } - + m_unit = m_rd->pageUnit(); + if (m_unit.type() == KReportUnit::Type::Cicero || + m_unit.type() == KReportUnit::Type::Pica || + m_unit.type() == KReportUnit::Type::Millimeter) { + m_majorX = POINT_TO_INCH(m_unit.fromUserValue(10)) * m_dpiX; + m_majorY = POINT_TO_INCH(m_unit.fromUserValue(10)) * m_dpiY; + } else if (m_unit.type() == KReportUnit::Type::Point) { + m_majorX = POINT_TO_INCH(m_unit.fromUserValue(100)) * m_dpiX; + m_majorY = POINT_TO_INCH(m_unit.fromUserValue(100)) * m_dpiY; + } else { + m_majorX = POINT_TO_INCH(m_unit.fromUserValue(1)) * m_dpiX; + m_majorY = POINT_TO_INCH(m_unit.fromUserValue(1)) * m_dpiY; } + int minorSteps = m_rd->propertySet()->property("grid-divisions").value().toInt(); m_pixelIncrementX = (m_majorX / minorSteps); m_pixelIncrementY = (m_majorY / minorSteps); @@ -129,7 +127,7 @@ //This will be caught by the section to display its properties, if an item is under the cursor then they will display their properties QGraphicsItem* itemUnderCursor = itemAt(e->scenePos(), QTransform()); emit clicked(); - + KReportDesignerItemRectBase *rectUnderCursor = qgraphicsitem_cast< KReportDesignerItemRectBase* >(itemUnderCursor); if (itemUnderCursor && !rectUnderCursor) { rectUnderCursor = qgraphicsitem_cast< KReportDesignerItemRectBase* >(itemUnderCursor->parentItem()); @@ -152,22 +150,17 @@ if (m_unit.type() != m_rd->pageUnit().type()) { m_unit = m_rd->pageUnit(); - //! @todo Again? Copy&Paste error? - if (m_unit.type() != m_rd->pageUnit().type()) { - m_unit = m_rd->pageUnit(); - if (m_unit.type() == KReportUnit::Type::Cicero || - m_unit.type() == KReportUnit::Type::Pica || - m_unit.type() == KReportUnit::Type::Millimeter) { - m_majorX = POINT_TO_INCH(m_unit.fromUserValue(10)) * m_dpiX; - m_majorY = POINT_TO_INCH(m_unit.fromUserValue(10)) * m_dpiY; - } else if (m_unit.type() == KReportUnit::Type::Point) { - m_majorX = POINT_TO_INCH(m_unit.fromUserValue(100)) * m_dpiX; - m_majorY = POINT_TO_INCH(m_unit.fromUserValue(100)) * m_dpiY; - } else { - m_majorX = POINT_TO_INCH(m_unit.fromUserValue(1)) * m_dpiX; - m_majorY = POINT_TO_INCH(m_unit.fromUserValue(1)) * m_dpiY; - } - + if (m_unit.type() == KReportUnit::Type::Cicero || + m_unit.type() == KReportUnit::Type::Pica || + m_unit.type() == KReportUnit::Type::Millimeter) { + m_majorX = POINT_TO_INCH(m_unit.fromUserValue(10)) * m_dpiX; + m_majorY = POINT_TO_INCH(m_unit.fromUserValue(10)) * m_dpiY; + } else if (m_unit.type() == KReportUnit::Type::Point) { + m_majorX = POINT_TO_INCH(m_unit.fromUserValue(100)) * m_dpiX; + m_majorY = POINT_TO_INCH(m_unit.fromUserValue(100)) * m_dpiY; + } else { + m_majorX = POINT_TO_INCH(m_unit.fromUserValue(1)) * m_dpiX; + m_majorY = POINT_TO_INCH(m_unit.fromUserValue(1)) * m_dpiY; } } int minorSteps = m_rd->propertySet()->property("grid-divisions").value().toInt(); diff --git a/src/wrtembed/KReportDesignerSectionView.cpp b/src/wrtembed/KReportDesignerSectionView.cpp --- a/src/wrtembed/KReportDesignerSectionView.cpp +++ b/src/wrtembed/KReportDesignerSectionView.cpp @@ -49,6 +49,9 @@ //! @todo check void KReportDesignerSectionView::resizeContents(const QSize &s) { + if (size() == s) { + return; + } setMinimumSize(s); setMaximumSize(s); }