diff --git a/src/common/KReportDesign_p.cpp b/src/common/KReportDesign_p.cpp index f3b497fd..674952f4 100644 --- a/src/common/KReportDesign_p.cpp +++ b/src/common/KReportDesign_p.cpp @@ -1,458 +1,466 @@ /* This file is part of the KDE project * Copyright (C) 2001-2007 by OpenMFG, LLC * Copyright (C) 2007-2010 by Adam Pigg * Copyright (C) 2011-2015 Jarosław Staniek * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library. If not, see . */ #include "KReportDesign_p.h" #include "KReportElement.h" #include "KReportUtils.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) , snapToGrid(DEFAULT_SNAP_TO_GRID) , gridDivisions(DEFAULT_GRID_DIVISIONS) , pageUnit(DEFAULT_UNIT) , sections(KReportSection::Detail) { memset(static_cast(sections.data()), 0, sizeof(void*) * sections.length()); pageLayout.setUnits(QPageLayout::Point); // initializate because of https://bugreports.qt.io/browse/QTBUG-47551 } KReportDesign::Private::~Private() { qDeleteAll(sections); } KReportDesignGlobal::KReportDesignGlobal() : defaultSectionHeight(CM_TO_POINT(2.0)) , defaultSectionBackgroundColor(Qt::white) { defaultPageLayout.setUnits(QPageLayout::Point); defaultPageLayout.setMargins(QMarginsF(DEFAULT_PAGE_MARGIN, DEFAULT_PAGE_MARGIN, DEFAULT_PAGE_MARGIN, DEFAULT_PAGE_MARGIN)); defaultPageLayout.setMode(QPageLayout::StandardMode); defaultPageLayout.setOrientation(DEFAULT_PAGE_ORIENTATION); } KReportSection::Type KReportDesignGlobal::sectionType(const QString& typeName) { initSectionTypes(); return sectionTypesForName.value(typeName); // returns InvalidType for invalid name } QString KReportDesignGlobal::sectionTypeName(KReportSection::Type sectionType) { initSectionTypes(); return sectionTypeNames.value(sectionType); } void KReportDesignGlobal::initSectionTypes() { if (!sectionTypesForName.isEmpty()) { return; } for (const SectionTypeInfo *info = sectionTypes; info->name; ++info) { sectionTypesForName.insert(QString::fromLatin1(info->name), info->type); sectionTypeNames.insert(info->type, QString::fromLatin1(info->name)); } } const KReportDesignGlobal::SectionTypeInfo KReportDesignGlobal::sectionTypes[] = { { KReportSection::InvalidType, "" }, { KReportSection::PageHeaderAny, "header-page-any" }, { KReportSection::PageHeaderEven, "header-page-even" }, { KReportSection::PageHeaderOdd, "header-page-odd" }, { KReportSection::PageHeaderFirst, "header-page-first" }, { KReportSection::PageHeaderLast, "header-page-last" }, { KReportSection::PageFooterAny, "footer-page-any" }, { KReportSection::PageFooterEven, "footer-page-even" }, { KReportSection::PageFooterOdd, "footer-page-odd" }, { KReportSection::PageFooterFirst, "footer-page-first" }, { KReportSection::PageFooterLast, "footer-page-last" }, { KReportSection::ReportHeader, "header-report" }, { KReportSection::ReportFooter, "footer-report" }, { KReportSection::GroupHeader, "group-header" }, { KReportSection::GroupFooter, "group-footer" }, { KReportSection::Detail, "detail" }, { KReportSection::InvalidType, nullptr } }; Q_GLOBAL_STATIC(KReportDesignGlobal, s_global) //static KReportDesignGlobal* KReportDesignGlobal::self() { return s_global; } static void setStatus(KReportDesignReadingStatus *status, const QString& details, const QDomNode &node) { if (status) { status->setErrorDetails(details); status->setErrorLineNumber(node.lineNumber() == -1 ? 0 /* mark error */ : node.lineNumber()); status->setErrorColumnNumber(node.columnNumber() == -1 ? 0 /* mark error */ : node.columnNumber()); } } static bool checkElement(const QDomNode &node, KReportDesignReadingStatus *status) { if (node.isElement()) { return true; } setStatus(status, QString::fromLatin1("Element expected inside of <%1>") .arg(node.parentNode().toElement().tagName()), node); return false; } static void setNoAttributeStatus(const QDomElement &el, const char *attrName, KReportDesignReadingStatus *status) { setStatus(status, QString::fromLatin1("Attribute \"%1\" expected inside of <%1>") .arg(QLatin1String(attrName)).arg(el.tagName()), el); } #if 0 // TODO unused for now static bool checkAttribute(const QDomElement &el, const char *attrName, KReportDesignReadingStatus *status) { if (el.hasAttribute(QLatin1String(attrName))) { return true; } setNoAttributeStatus(el, attrName, status); return false; } #endif 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); if (sectionType == KReportSection::InvalidType) { setStatus(status, QString::fromLatin1("Invalid value of report:section-type=\"%1\" in element <%2>") .arg(sectionTypeName).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); } section.setBackgroundColor(QColor(KReportUtils::attr(el, "fo:background-color", QString()))); for (QDomNode node = el.firstChild(); !node.isNull(); node = node.nextSibling()) { if (!checkElement(node, status)) { return KReportSection(); } KReportElement element = processSectionElementChild(node.toElement(), status); if (!element.rect().isValid() || (status && status->isError())) { return KReportSection(); } (void)section.addElement(element); } return section; } KReportPluginInterface* KReportDesign::Private::findPlugin(const QString &typeName, const QDomElement &el, KReportDesignReadingStatus *status) { KReportPluginInterface* plugin = KReportPluginManager::self()->plugin(typeName); if (!plugin) { setStatus(status, QString::fromLatin1("No such plugin \"%1\"").arg(typeName), el); return nullptr; } return plugin; } KReportElement KReportDesign::Private::processSectionElementChild(const QDomElement &el, KReportDesignReadingStatus *status) { const QByteArray name = el.tagName().toLatin1(); const char* elNamespace = "report:"; if (!name.startsWith(elNamespace)) { unexpectedElement(el, status); return KReportElement(); } const QByteArray reportElementName = name.mid(qstrlen(elNamespace)); //qDebug() << "Found Report Element:" << reportElementName; KReportPluginInterface *plugin = findPlugin(QLatin1String(reportElementName), el, status); if (!plugin) { return KReportElement(); } KReportElement element = plugin->createElement(); if (!plugin->loadElement(&element, el, status)) { return KReportElement(); } element.setName(KReportUtils::attr(el, "report:name", QString())); if (element.name().isEmpty()) { setNoAttributeStatus(el, "report:name", status); return KReportElement(); } return element; } bool KReportDesign::Private::processGroupElement(const QDomElement &el, KReportDesignReadingStatus *status) { Q_UNUSED(el); Q_UNUSED(status); //! @todo return true; } //! The report:detail element contains a single report:section child of type 'detail' //! and 0 or more report:group children. bool KReportDesign::Private::processDetailElement(const QDomElement &el, KReportDesignReadingStatus *status) { QDomElement sectionEl; for (QDomNode node = el.firstChild(); !node.isNull(); node = node.nextSibling()) { if (!checkElement(node, status)) { return false; } QDomElement childEl = node.toElement(); const QByteArray name = childEl.tagName().toLatin1(); if (name == "report:section") { if (!sectionEl.isNull()) { return false; } KReportSection section = processSectionElement(childEl, status); if (status && status->isError()) { return false; } if (section.type() != KReportSection::Detail) { setStatus(status, QString::fromLatin1("Only section of type \"detail\" allowed in "), el); return false; } q->addSection(section); } else if (name == "report:group") { if (!processGroupElement(childEl, status)) { return false; } } else { unexpectedElement(childEl, status); return false; } } // finally make sure we have one report:section (void)requiredChildElement(el, "report:section", status); if (status && status->isError()) { return false; } return true; } /*!
        
         *.. (up to 12 sections)
          
             // any number of groups
              *.. (group-header, group-footer)
            
          
        
     
 */
 bool KReportDesign::Private::processBodyElementChild(const QDomElement &el,
                                                      KReportDesignReadingStatus *status)
 {
     const QByteArray name = el.tagName().toLatin1();
     //kreportDebug() << name;
     if (name == "report:section") {
         KReportSection section = processSectionElement(el, status);
         if (status && status->isError()) {
             return false;
         }
         if (q->hasSection(section.type())) {
             setStatus(status, QString::fromLatin1("Could not add two sections of type \"%1\" "
                                                   "to the same report design")
                                 .arg(s_global->sectionTypeName(section.type())), el);
             return false;
         }
         if (section.type() == KReportSection::Detail) {
             setStatus(status,
                 QString::fromLatin1("Section of type \"detail\" not allowed in "), el);
             return false;
         }
         q->addSection(section);
 #if 0 //TODO
         if (section(KReportSectionData::sectionTypeFromString(sectiontype)) == 0) {
             insertSection(KReportSectionData::sectionTypeFromString(sectiontype));
             section(KReportSectionData::sectionTypeFromString(sectiontype))->initFromXML(sec);
         }
 #endif
     } else if (name == "report:detail") {
         if (!processDetailElement(el, status)) {
             return false;
         }
 #if 0 //TODO
         ReportSectionDetail * rsd = new ReportSectionDetail(this);
         rsd->initFromXML(&sec);
         setDetail(rsd);
 #endif
     }
     return true;
 }
 
 /* NOTE: don't translate these extremely detailed messages. */
 //! @todo Load page options
 bool KReportDesign::Private::processContentElementChild(const QDomElement &el,
                                                         KReportDesignReadingStatus *status)
 {
     const QByteArray name = el.tagName().toLatin1();
     QPageLayout defaultPageLayout = KReportDesign::defaultPageLayout();
     //kreportDebug() << name;
     if (name == "report:title") {
         title = el.text();
 #ifdef KREPORT_SCRIPTING
     } else if (name == "report:script") {
         script = el.firstChildElement().text();
         originalInterpreter = KReportUtils::attr(el, "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());
-        bool found;
-        pageUnit = KReportUnit::fromSymbol(pageUnitString, &found);
-        if (!found) {
+        pageUnit = KReportUnit(KReportUnit::symbolToType(pageUnitString));
+        if (!pageUnit.isValid()) {
             pageUnit = DEFAULT_UNIT;
             if (!pageUnitString.isEmpty()) {
                 qWarning() << "Invalid page unit" << pageUnitString << "specified in" << name
                            << "element, defaulting to" << pageUnit.symbol();
             }
         }
     }
     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())));
         } else if (pagetype.isEmpty() || pagetype == "custom") {
             QSizeF size(KReportUtils::attr(el, "fo:page-width", -1.0),
                         KReportUtils::attr(el, "fo:page-height", -1.0));
             if (size.isValid()) {
                 pageLayout.setPageSize(QPageSize(size, QPageSize::Point));
             } else {
                 pageLayout.setPageSize(defaultPageLayout.pageSize());
             }
         } else if (pagetype == "label") {
             //! @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()));
         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());
         if (s == QLatin1String("portrait")) {
             pageLayout.setOrientation(QPageLayout::Portrait);
         } else if (s == QLatin1String("landscape")) {
             pageLayout.setOrientation(QPageLayout::Landscape);
         }
         else {
             pageLayout.setOrientation(defaultPageLayout.orientation());
         }
     } else if (name == "report:body") {
         for (QDomNode node = el.firstChild(); !node.isNull(); node = node.nextSibling()) {
             if (!checkElement(node, status)) {
                 return false;
             }
             if (!processBodyElementChild(node.toElement(), status)) {
                 return false;
             }
         }
     }
     return true;
 }
 
 void KReportDesign::Private::unexpectedElement(const QDomElement &element,
                                                KReportDesignReadingStatus *status) const
 {
     setStatus(status, QString::fromLatin1("Unexpected child element <%1> found in <%2>")
           .arg(element.tagName()).arg(element.parentNode().toElement().tagName()), element);
 }
 
 QDomElement KReportDesign::Private::requiredChildElement(const QDomElement &parent,
                                                          const char* childElementName,
                                                          KReportDesignReadingStatus *status) const
 {
     const QDomElement result = parent.firstChildElement(QLatin1String(childElementName));
     if (result.isNull()) {
         setStatus(status, QString::fromLatin1("Child element <%1> not found in <%2>")
               .arg(QLatin1String(childElementName)).arg(parent.tagName()), parent);
     }
     return result;
 }
 
 /* NOTE: don't translate these extremely detailed messages. */
 bool KReportDesign::Private::processDocument(const QDomDocument &doc,
                                              KReportDesignReadingStatus *status)
 {
     const QDomElement rootEl = doc.documentElement();
     const QLatin1String rootElName("kexireport"); // legacy name kept for compatibility
     if (doc.doctype().name() != rootElName) {
         setStatus(status, QString::fromLatin1("Document type should be \"%1\"").arg(rootElName), rootEl);
         return false;
     }
     if (rootEl.tagName() != rootElName) {
         setStatus(status, QString::fromLatin1("Root element should be <%1>").arg(rootElName), rootEl);
         return false;
     }
     const QDomElement contentEl = requiredChildElement(rootEl, "report:content", status);
     if (status && status->isError()) {
         return false;
     }
     //! @todo check namespaces as in:
     //! 
 
 //    deleteDetail();
 
     for (QDomNode node = contentEl.firstChild(); !node.isNull(); node = node.nextSibling()) {
         if (!checkElement(node, status)) {
             return false;
         }
         if (!processContentElementChild(node.toElement(), status)) {
             return false;
         }
     }
 
     if (status) {
         *status = KReportDesignReadingStatus();
     }
     return true;
 }
diff --git a/src/common/KReportDesign_p.h b/src/common/KReportDesign_p.h
index fa252787..2ea9b2f9 100644
--- a/src/common/KReportDesign_p.h
+++ b/src/common/KReportDesign_p.h
@@ -1,130 +1,131 @@
 /* This file is part of the KDE project
  * Copyright (C) 2001-2007 by OpenMFG, LLC 
  * Copyright (C) 2007-2010 by Adam Pigg 
  * Copyright (C) 2011-2015 Jarosław Staniek 
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
  * This library is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
  * License along with this library.  If not, see .
  */
 
 #ifndef KREPORTDESIGN_P_H
 #define KREPORTDESIGN_P_H
 
 #include "KReportDesign.h"
 #include "KReportUnit.h"
 #include "KReportUtils_p.h"
 
 #include 
 #include 
 #include 
 
 class QDomDocument;
 class QDomElement;
 class KReportPluginInterface;
 
-static const bool DEFAULT_SHOW_GRID = true;
-static const bool DEFAULT_SNAP_TO_GRID = true;
-static const int DEFAULT_GRID_DIVISIONS = 4;
-static const KReportUnit DEFAULT_UNIT = KReportUnit(KReportUnit::Centimeter);
-static const int DEFAULT_PAGE_MARGIN = CM_TO_POINT(1.0);
-static const QPageSize::PageSizeId DEFAULT_PAGE_SIZE = QPageSize::A4;
-static const QPageLayout::Orientation DEFAULT_PAGE_ORIENTATION = QPageLayout::Landscape;
+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:
     explicit Private(KReportDesign *design);
 
     ~Private();
 
     QDomElement requiredChildElement(const QDomElement &parent,
                                      const char* childElementName,
                                      KReportDesignReadingStatus *status) const;
 
     void unexpectedElement(const QDomElement &element,
                            KReportDesignReadingStatus *status) const;
 
     //! Processes document @a doc and sets status @a status
     bool processDocument(const QDomDocument &doc, KReportDesignReadingStatus *status);
 
     //! Processes @a el, a child of /report:content element and sets status @a status
     bool processContentElementChild(const QDomElement &el, KReportDesignReadingStatus *status);
 
     //! Processes @a el, a child of /report:content/report:body element and sets status @a status
     bool processBodyElementChild(const QDomElement &el, KReportDesignReadingStatus *status);
 
     //! Processes @a el, a /report:content/report:body/report:section element and sets status @a status
     KReportSection processSectionElement(const QDomElement &el, KReportDesignReadingStatus *status);
 
     //! Processes @a el,
     //! a child of /report:content/report:body/report:section element
     //! or a child of /report:content/report:body/report:detail/report:section element
     //! and sets status @a status.
     //! It is probably the lowest level in hierarchy and @a el refers to a single report element.
     KReportElement processSectionElementChild(const QDomElement &el, KReportDesignReadingStatus *status);
 
     //! Processes @a el, a child of /report:content/report:body/report:detail element and sets status @a status
     bool processDetailElement(const QDomElement &el, KReportDesignReadingStatus *status);
 
     //! Processes @a el, a /report:content/report:body/report:detail/report:group element and sets status @a status
     bool processGroupElement(const QDomElement &el, KReportDesignReadingStatus *status);
 
     KReportPluginInterface* findPlugin(const QString &typeName, const QDomElement &el,
                                         KReportDesignReadingStatus *status);
 
     KReportDesign * const q;
 
     // Visual settings only
     bool showGrid;
     bool snapToGrid;
     int gridDivisions;
     KReportUnit pageUnit;
     // END OF: Visual settings only
     QString title;
     KReportPrivate::PageLayout pageLayout;
     QVarLengthArray sections;
 #ifdef KREPORT_SCRIPTING
     QString script;
     QString originalInterpreter; //!< used for backward-compatibility to save the original
 #endif
 };
 
 class KReportDesignGlobal
 {
 public:
     KReportDesignGlobal();
 
     static KReportDesignGlobal* self();
 
     struct SectionTypeInfo {
         KReportSection::Type type;
         const char *name;
     };
 
     KReportSection::Type sectionType(const QString& typeName);
 
     QString sectionTypeName(KReportSection::Type sectionType);
 
     KReportPrivate::PageLayout defaultPageLayout;
     qreal defaultSectionHeight;
     QColor defaultSectionBackgroundColor;
 
 private:
     void initSectionTypes();
 
     static const SectionTypeInfo sectionTypes[];
     QHash sectionTypesForName;
     QHash sectionTypeNames;
 };
 
 #endif
diff --git a/src/common/KReportItemBase.cpp b/src/common/KReportItemBase.cpp
index b3851594..f08c375f 100644
--- a/src/common/KReportItemBase.cpp
+++ b/src/common/KReportItemBase.cpp
@@ -1,239 +1,239 @@
 /* This file is part of the KDE project
  * Copyright (C) 2007-2008 by Adam Pigg (adam@piggz.co.uk)
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
  * This library is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
  * License along with this library.  If not, see .
  */
 
 #include "KReportItemBase.h"
 
 #include "KReportUtils.h"
 #include "KReportUtils_p.h"
 
 #include 
 #include 
 #include 
 
 class Q_DECL_HIDDEN KReportItemBase::Private
 {
 public:
     Private();
     ~Private();
     
     KPropertySet *set;
     KProperty *nameProperty;
     KProperty *sizeProperty;
     KProperty *positionProperty;
     QString oldName;
     qreal z = 0;
 };
 
 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"));
     
     set->addProperty(nameProperty);
     set->addProperty(positionProperty);
     set->addProperty(sizeProperty);
 }
 
 KReportItemBase::Private::~Private()
 {
     delete set;
 }
 
 
 KReportItemBase::KReportItemBase() : d(new Private())
 {    
     connect(propertySet(), &KPropertySet::propertyChanged,
             this, &KReportItemBase::propertyChanged);
 }
 
 KReportItemBase::~KReportItemBase() 
 { 
     delete d;    
 }
 
 bool KReportItemBase::parseReportTextStyleData(const QDomElement & elemSource, KReportTextStyleData *ts)
 {
     return KReportUtils::parseReportTextStyleData(elemSource, ts);
 }
 
 bool KReportItemBase::parseReportLineStyleData(const QDomElement & elemSource, KReportLineStyle *ls)
 {
     return KReportUtils::parseReportLineStyleData(elemSource, ls);
 }
 
 
 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);
 
     return true;
     
 }
 
 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->sizeProperty->setOption("unit", u.symbol());
 }
 
 int KReportItemBase::renderSimpleData(OROPage *page, OROSection *section, const QPointF &offset,
                                        const QVariant &data, KReportScriptHandler* script)
 {
     Q_UNUSED(page)
     Q_UNUSED(section)
     Q_UNUSED(offset)
     Q_UNUSED(data)
     Q_UNUSED(script)
     return 0;
 }
 
 int KReportItemBase::renderReportData(OROPage *page, OROSection *section, const QPointF &offset,
                                        KReportDataSource *dataSource, KReportScriptHandler* script)
 {
     Q_UNUSED(page)
     Q_UNUSED(section)
     Q_UNUSED(offset)
     Q_UNUSED(dataSource)
     Q_UNUSED(script)
     return 0;
 }
 
 QString KReportItemBase::itemDataSource() const
 {
     return QString();
 }
 
 KPropertySet* KReportItemBase::propertySet()
 {
  return d->set;
 }
 
 bool KReportItemBase::supportsSubQuery() const
 {
     return false;
 }
 
 QString KReportItemBase::entityName() const
 {
     return d->nameProperty->value().toString();
 }
 
 void KReportItemBase::setEntityName(const QString& n)
 {
     d->nameProperty->setValue(n);
 }
 
 KProperty* KReportItemBase::nameProperty()
 {
     return d->nameProperty;
 }
 
 QString KReportItemBase::oldName() const
 {
     return d->oldName;
 }
 
 void KReportItemBase::setOldName(const QString& old)
 {
     d->oldName = old;
 }
 
 QPointF KReportItemBase::position() const
 {
     return d->positionProperty->value().toPointF();
 }
 
 QSizeF KReportItemBase::size() const
 {
     return d->sizeProperty->value().toSizeF();
 }
 
 const KPropertySet * KReportItemBase::propertySet() const
 {
     return d->set;
 }
 
 QPointF KReportItemBase::scenePosition(const QPointF &pos)
 {
     const qreal x = POINT_TO_INCH(pos.x()) * KReportPrivate::dpiX();
     const qreal y = POINT_TO_INCH(pos.y()) * KReportPrivate::dpiY();
     return QPointF(x, y);
 }
 
 QSizeF KReportItemBase::sceneSize(const QSizeF &size)
 {
     const qreal w = POINT_TO_INCH(size.width()) * KReportPrivate::dpiX();
     const qreal h = POINT_TO_INCH(size.height()) * KReportPrivate::dpiY();
     return QSizeF(w, h);    
 }
 
 qreal KReportItemBase::z() const
 {
     return d->z;
 }
 
 void KReportItemBase::setZ(qreal z)
 {
     d->z = z;
 }
 
 void KReportItemBase::setPosition(const QPointF& pos)
 {
     d->positionProperty->setValue(pos);
 }
 
 void KReportItemBase::setSize(const QSizeF& size)
 {
     d->sizeProperty->setValue(size);
 }
 
 QPointF KReportItemBase::positionFromScene(const QPointF& pos)
 {
     const qreal x = INCH_TO_POINT(pos.x() / KReportPrivate::dpiX());
     const qreal y = INCH_TO_POINT(pos.y() / KReportPrivate::dpiY());
     return QPointF(x, y);
 }
 
 QSizeF KReportItemBase::sizeFromScene(const QSizeF& size)
 {
     qreal w = INCH_TO_POINT(size.width() / KReportPrivate::dpiX());
     qreal h = INCH_TO_POINT(size.height() / KReportPrivate::dpiY());
     return QSizeF(w, h);
 }
 
 void KReportItemBase::propertyChanged(KPropertySet& s, KProperty& p)
 {
     Q_UNUSED(s)
     Q_UNUSED(p)
 }
 
 
 
diff --git a/src/common/KReportSectionData.cpp b/src/common/KReportSectionData.cpp
index 67393878..fc333588 100644
--- a/src/common/KReportSectionData.cpp
+++ b/src/common/KReportSectionData.cpp
@@ -1,216 +1,216 @@
 /* This file is part of the KDE project
  * Copyright (C) 2001-2007 by OpenMFG, LLC (info@openmfg.com)
  * Copyright (C) 2007-2008 by Adam Pigg (adam@piggz.co.uk)
  * Copyright (C) 2010 Jarosław Staniek 
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
  * This library is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
  * License along with this library.  If not, see .
  */
 
 #include "KReportSectionData.h"
 #include "KReportDocument.h"
 #include "KReportPluginInterface.h"
 #include "KReportPluginManager.h"
 #include "KReportItemLine.h"
 #include "KReportDesigner.h"
 #include "kreport_debug.h"
 
 #include 
 
 #include 
 
 KReportSectionData::KReportSectionData(QObject* parent)
  : QObject(parent)
 {
     createProperties(QDomElement());
 }
 
 KReportSectionData::KReportSectionData(const QDomElement & elemSource, KReportDocument* report)
  : QObject(report)
 {
     setObjectName(elemSource.tagName());
 
     m_type = sectionTypeFromString(elemSource.attribute(QLatin1String("report:section-type")));
     createProperties(elemSource);
     if (objectName() != QLatin1String("report:section") || m_type == KReportSectionData::None) {
         m_valid = false;
         return;
     }
 
     m_backgroundColor->setValue(QColor(elemSource.attribute(QLatin1String("fo:background-color"))));
 
     KReportPluginManager* manager = KReportPluginManager::self();
 
     QDomNodeList section = elemSource.childNodes();
     for (int nodeCounter = 0; nodeCounter < section.count(); nodeCounter++) {
         QDomElement elemThis = section.item(nodeCounter).toElement();
         QString n = elemThis.tagName();
         if (n.startsWith(QLatin1String("report:"))) {
             QString reportItemName = n.mid(qstrlen("report:"));
             if (reportItemName == QLatin1String("line")) {
                 KReportItemLine * line = new KReportItemLine(elemThis);
                 m_objects.append(line);
                 continue;
             }
             KReportPluginInterface *plugin = manager->plugin(reportItemName);
             if (plugin) {
                 QObject *obj = plugin->createRendererInstance(elemThis);
                 if (obj) {
                     KReportItemBase *krobj = dynamic_cast(obj);
                     if (krobj) {
                         m_objects.append(krobj);
                     }
                     continue;
                 }
             }
         }
         kreportWarning() << "While parsing section encountered an unknown element: " << n;
     }
     qSort(m_objects.begin(), m_objects.end(), zLessThan);
     m_valid = true;
 }
 
 KReportSectionData::~KReportSectionData()
 {
     delete m_set;
     qDeleteAll(m_objects);
 }
 
 bool KReportSectionData::zLessThan(KReportItemBase* s1, KReportItemBase* s2)
 {
     return s1->z() < s2->z();
 }
 
 bool KReportSectionData::xLessThan(KReportItemBase* s1, KReportItemBase* s2)
 {
     return s1->position().toPoint().x() < s2->position().toPoint().x();
 }
 
 void KReportSectionData::createProperties(const QDomElement & elemSource)
 {
     m_set = new KPropertySet(this);
     KReportDesigner::addMetaProperties(m_set,
         tr("Section", "Report section"), QLatin1String("kreport-section-element"));
 
-    m_height = new KProperty("height", KReportUnit(KReportUnit::Centimeter).fromUserValue(2.0), tr("Height"));
+    m_height = new KProperty("height", KReportUnit(KReportUnit::Type::Centimeter).fromUserValue(2.0), tr("Height"));
     m_backgroundColor = new KProperty("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"))));
 
     m_set->addProperty(m_height);
     m_set->addProperty(m_backgroundColor);
 }
 
 QString KReportSectionData::name() const
 {
     return (objectName() + QLatin1Char('-') + sectionTypeString(m_type));
 }
 
 QString KReportSectionData::sectionTypeString(KReportSectionData::Section s)
 {
 //! @todo use QMap
     QString sectiontype;
     switch (s) {
     case KReportSectionData::PageHeaderAny:
         sectiontype = QLatin1String("header-page-any");
         break;
     case KReportSectionData::PageHeaderEven:
         sectiontype = QLatin1String("header-page-even");
         break;
     case KReportSectionData::PageHeaderOdd:
         sectiontype = QLatin1String("header-page-odd");
         break;
     case KReportSectionData::PageHeaderFirst:
         sectiontype = QLatin1String("header-page-first");
         break;
     case KReportSectionData::PageHeaderLast:
         sectiontype = QLatin1String("header-page-last");
         break;
     case KReportSectionData::PageFooterAny:
         sectiontype = QLatin1String("footer-page-any");
         break;
     case KReportSectionData::PageFooterEven:
         sectiontype = QLatin1String("footer-page-even");
         break;
     case KReportSectionData::PageFooterOdd:
         sectiontype = QLatin1String("footer-page-odd");
         break;
     case KReportSectionData::PageFooterFirst:
         sectiontype = QLatin1String("footer-page-first");
         break;
     case KReportSectionData::PageFooterLast:
         sectiontype = QLatin1String("footer-page-last");
         break;
     case KReportSectionData::ReportHeader:
         sectiontype = QLatin1String("header-report");
         break;
     case KReportSectionData::ReportFooter:
         sectiontype = QLatin1String("footer-report");
         break;
     case KReportSectionData::GroupHeader:
         sectiontype = QLatin1String("group-header");
         break;
     case KReportSectionData::GroupFooter:
         sectiontype = QLatin1String("group-footer");
         break;
     case KReportSectionData::Detail:
         sectiontype = QLatin1String("detail");
         break;
     default:
         ;
     }
 
     return sectiontype;
 }
 
 KReportSectionData::Section KReportSectionData::sectionTypeFromString(const QString& s)
 {
 //! @todo use QMap
     KReportSectionData::Section sec;
     //kreportDebug() << "Determining section type for " << s;
     if (s == QLatin1String("header-page-any"))
         sec = KReportSectionData::PageHeaderAny;
     else if (s == QLatin1String("header-page-even"))
         sec = KReportSectionData::PageHeaderEven;
     else if (s == QLatin1String("header-page-odd"))
         sec = KReportSectionData::PageHeaderOdd;
     else if (s == QLatin1String("header-page-first"))
         sec = KReportSectionData::PageHeaderFirst;
     else if (s == QLatin1String("header-page-last"))
         sec = KReportSectionData::PageHeaderLast;
     else if (s == QLatin1String("header-report"))
         sec = KReportSectionData::ReportHeader;
     else if (s == QLatin1String("footer-page-any"))
         sec = KReportSectionData::PageFooterAny;
     else if (s == QLatin1String("footer-page-even"))
         sec = KReportSectionData::PageFooterEven;
     else if (s == QLatin1String("footer-page-odd"))
         sec = KReportSectionData::PageFooterOdd;
     else if (s == QLatin1String("footer-page-first"))
         sec = KReportSectionData::PageFooterFirst;
     else if (s == QLatin1String("footer-page-last"))
         sec = KReportSectionData::PageFooterLast;
     else if (s == QLatin1String("footer-report"))
         sec = KReportSectionData::ReportFooter;
     else if (s == QLatin1String("group-header"))
         sec = KReportSectionData::GroupHeader;
     else if (s == QLatin1String("group-footer"))
         sec = KReportSectionData::GroupFooter;
     else if (s == QLatin1String("detail"))
         sec = KReportSectionData::Detail;
     else
         sec = KReportSectionData::None;
 
     return sec;
 }
diff --git a/src/common/KReportUnit.cpp b/src/common/KReportUnit.cpp
index dab6dcc5..0a649391 100644
--- a/src/common/KReportUnit.cpp
+++ b/src/common/KReportUnit.cpp
@@ -1,453 +1,475 @@
 /* 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) 2017 Jarosław Staniek 
 
    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Library General Public
    License as published by the Free Software Foundation; either
    version 2 of the License, or (at your option) any later version.
 
    This library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    Library General Public License for more details.
 
    You should have received a copy of the GNU Library General Public License
    along with this library; see the file COPYING.LIB.  If not, write to
    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
  * Boston, MA 02110-1301, USA.
 */
 
 #include "KReportUnit.h"
 #include "kreport_debug.h"
 
 #include 
 
 #include 
 #include 
 
 class Q_DECL_HIDDEN KReportUnit::Private
 {
 public:
-    Type type;
+    KReportUnit::Type type;
     qreal pixelConversion;
 };
 
-// ensure the same order as in KReportUnit::Unit
-static const char* const unitNameList[KReportUnit::TypeCount] =
+// unit types
+// Note: ensure the same order as in KReportUnit::Unit
+static QList s_unitTypes = {
+    KReportUnit::Type::Millimeter,
+    KReportUnit::Type::Centimeter,
+    KReportUnit::Type::Decimeter,
+    KReportUnit::Type::Inch,
+    KReportUnit::Type::Pica,
+    KReportUnit::Type::Cicero,
+    KReportUnit::Type::Point,
+    KReportUnit::Type::Pixel
+};
+static int firstUnitIndex()
+{
+    return static_cast(KReportUnit::Type::Invalid) + 1;
+}
+
+static int lastUnitIndex()
 {
+    return static_cast(KReportUnit::Type::Last); // without Invalid
+}
+
+// unit symbols
+// Note: ensure the same order as in KReportUnit::Unit
+static const char* const s_unitSymbols[] =
+{
+    nullptr,
     "mm",
-    "pt",
-    "in",
     "cm",
     "dm",
+    "in",
     "pi",
     "cc",
+    "pt",
     "px"
 };
 
-KReportUnit::KReportUnit(Type type, qreal factor) : d(new Private) 
+KReportUnit::KReportUnit() : d(new Private)
+{
+    d->type = Type::Invalid;
+    d->pixelConversion = 1.0;
+}
+
+KReportUnit::KReportUnit(Type type, qreal factor) : d(new Private)
 {
     d->type = type;
     d->pixelConversion = factor;
 }
 
 KReportUnit::KReportUnit(const KReportUnit& other) : d(new Private)
 {
     d->type = other.type();
     d->pixelConversion = other.factor();
 }
 
 KReportUnit::~KReportUnit()
 {
     delete d;
 }
 
 bool KReportUnit::operator==(const KReportUnit& other) const 
 {
     return d->type == other.d->type &&
-           (d->type != Pixel ||
+           (d->type != Type::Pixel ||
             qFuzzyCompare(d->pixelConversion, other.d->pixelConversion));
 }
 
 bool KReportUnit::operator!=(const KReportUnit& other) const
 {
     return !operator==(other);
 }
 
 
 KReportUnit& KReportUnit::operator=(Type type)
 {
     d->type = type;
     d->pixelConversion = 1.0;
     return *this;
 }
 
 KReportUnit & KReportUnit::operator=(const KReportUnit& other)
 {
     d->type = other.type();
     d->pixelConversion = other.factor();
     return *this;
 }
 
-QString KReportUnit::unitDescription(KReportUnit::Type type)
+//static
+QList KReportUnit::allTypes()
 {
-    switch (type) {
-    case KReportUnit::Millimeter:
-        return QCoreApplication::translate("KReportUnit", "Millimeters (mm)");
-    case KReportUnit::Centimeter:
-        return QCoreApplication::translate("KReportUnit", "Centimeters (cm)");
-    case KReportUnit::Decimeter:
-        return QCoreApplication::translate("KReportUnit", "Decimeters (dm)");
-    case KReportUnit::Inch:
-        return QCoreApplication::translate("KReportUnit", "Inches (in)");
-    case KReportUnit::Pica:
-        return QCoreApplication::translate("KReportUnit", "Pica (pi)");
-    case KReportUnit::Cicero:
-        return QCoreApplication::translate("KReportUnit", "Cicero (cc)");
-    case KReportUnit::Point:
-        return QCoreApplication::translate("KReportUnit", "Points (pt)");
-    case KReportUnit::Pixel:
-        return QCoreApplication::translate("KReportUnit", "Pixels (px)");
-    default:
-        return QCoreApplication::translate("KReportUnit", "Unsupported unit");
-    }
+    return s_unitTypes;
 }
 
-// grouped by units which are similar
-static const KReportUnit::Type typesInUi[KReportUnit::TypeCount] =
-{
-    KReportUnit::Millimeter,
-    KReportUnit::Centimeter,
-    KReportUnit::Decimeter,
-    KReportUnit::Inch,
-    KReportUnit::Pica,
-    KReportUnit::Cicero,
-    KReportUnit::Point,
-    KReportUnit::Pixel,
-};
-
-QStringList KReportUnit::listOfUnitNameForUi(ListOptions listOptions)
+//static
+QString KReportUnit::description(KReportUnit::Type type)
 {
-    QStringList lst;
-    for (int i = 0; i < KReportUnit::TypeCount; ++i) {
-        const Type type = typesInUi[i];
-        if ((type != Pixel) || ((listOptions & HideMask) == ListAll))
-            lst.append(unitDescription(type));
+    switch (type) {
+    case KReportUnit::Type::Invalid:
+        return tr("Invalid");
+    case KReportUnit::Type::Millimeter:
+        return tr("Millimeters (mm)");
+    case KReportUnit::Type::Centimeter:
+        return tr("Centimeters (cm)");
+    case KReportUnit::Type::Decimeter:
+        return tr("Decimeters (dm)");
+    case KReportUnit::Type::Inch:
+        return tr("Inches (in)");
+    case KReportUnit::Type::Pica:
+        return tr("Pica (pi)");
+    case KReportUnit::Type::Cicero:
+        return tr("Cicero (cc)");
+    case KReportUnit::Type::Point:
+        return tr("Points (pt)");
+    case KReportUnit::Type::Pixel:
+        return tr("Pixels (px)");
+    default:
+        return tr("Unsupported unit");
     }
-    return lst;
 }
 
-KReportUnit KReportUnit::fromListForUi(int index, ListOptions listOptions, qreal factor)
+QString KReportUnit::description() const
 {
-    KReportUnit::Type type = KReportUnit::Point;
-
-    if ((0 <= index) && (index < KReportUnit::TypeCount)) {
-        // iterate through all enums and skip the Pixel enum if needed
-        for (int i = 0; i < KReportUnit::TypeCount; ++i) {
-            if ((listOptions&HidePixel) && (typesInUi[i] == Pixel)) {
-                ++index;
-                continue;
-            }
-            if (i == index) {
-                type = typesInUi[i];
-                break;
-            }
-        }
-    }
-
-    return KReportUnit(type, factor);
+    return KReportUnit::description(type());
 }
 
-int KReportUnit::indexInListForUi(ListOptions listOptions) const
+QStringList KReportUnit::descriptions(const QList &types)
 {
-    if ((listOptions&HidePixel) && (d->type == Pixel)) {
-        return -1;
+    QStringList result;
+    for (Type t : types) {
+        result.append(description(t));
     }
-
-    int result = -1;
-
-    int skipped = 0;
-    for (int i = 0; i < KReportUnit::TypeCount; ++i) {
-        if ((listOptions&HidePixel) && (typesInUi[i] == Pixel)) {
-            ++skipped;
-            continue;
-        }
-        if (typesInUi[i] == d->type) {
-            result = i - skipped;
-            break;
-        }
-    }
-
     return result;
 }
 
 qreal KReportUnit::toUserValue(qreal ptValue) const
 {
     switch (d->type) {
-    case Millimeter:
+    case Type::Invalid:
+        kreportWarning() << "Conversion for Invalid type not supported";
+        return -1.0;
+    case Type::Millimeter:
         return toMillimeter(ptValue);
-    case Centimeter:
+    case Type::Centimeter:
         return toCentimeter(ptValue);
-    case Decimeter:
+    case Type::Decimeter:
         return toDecimeter(ptValue);
-    case Inch:
+    case Type::Inch:
         return toInch(ptValue);
-    case Pica:
+    case Type::Pica:
         return toPica(ptValue);
-    case Cicero:
+    case Type::Cicero:
         return toCicero(ptValue);
-    case Pixel:
+    case Type::Pixel:
         return ptValue * d->pixelConversion;
-    case Point:
+    case Type::Point:
     default:
         return toPoint(ptValue);
     }
 }
 
 qreal KReportUnit::ptToUnit(qreal ptValue, const KReportUnit &unit)
 {
     switch (unit.d->type) {
-    case Millimeter:
+    case Type::Invalid:
+        return -1.0;
+    case Type::Millimeter:
         return POINT_TO_MM(ptValue);
-    case Centimeter:
+    case Type::Centimeter:
         return POINT_TO_CM(ptValue);
-    case Decimeter:
+    case Type::Decimeter:
         return POINT_TO_DM(ptValue);
-    case Inch:
+    case Type::Inch:
         return POINT_TO_INCH(ptValue);
-    case Pica:
+    case Type::Pica:
         return POINT_TO_PI(ptValue);
-    case Cicero:
+    case Type::Cicero:
         return POINT_TO_CC(ptValue);
-    case Pixel:
+    case Type::Pixel:
         return ptValue * unit.d->pixelConversion;
-    case Point:
+    case Type::Point:
     default:
         return ptValue;
     }
 }
 
 QString KReportUnit::toUserStringValue(qreal ptValue) const
 {
     return QLocale::system().toString(toUserValue(ptValue));
 }
 
 qreal KReportUnit::fromUserValue(qreal value) const
 {
     switch (d->type) {
-    case Millimeter:
+    case Type::Invalid:
+        return -1.0;
+    case Type::Millimeter:
         return MM_TO_POINT(value);
-    case Centimeter:
+    case Type::Centimeter:
         return CM_TO_POINT(value);
-    case Decimeter:
+    case Type::Decimeter:
         return DM_TO_POINT(value);
-    case Inch:
+    case Type::Inch:
         return INCH_TO_POINT(value);
-    case Pica:
+    case Type::Pica:
         return PI_TO_POINT(value);
-    case Cicero:
+    case Type::Cicero:
         return CC_TO_POINT(value);
-    case Pixel:
+    case Type::Pixel:
         return value / d->pixelConversion;
-    case Point:
+    case Type::Point:
     default:
         return value;
     }
 }
 
 qreal KReportUnit::fromUserValue(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));
 }
 
 qreal KReportUnit::parseValue(const QString& _value, qreal defaultVal)
 {
     if (_value.isEmpty())
         return defaultVal;
 
     QString value(_value.simplified());
     value.remove(QLatin1Char(' '));
 
     int firstLetter = -1;
     for (int i = 0; i < value.length(); ++i) {
         if (value.at(i).isLetter()) {
             if (value.at(i) == QLatin1Char('e'))
                 continue;
             firstLetter = i;
             break;
         }
     }
 
     bool ok;
     if (firstLetter == -1) {
         qreal result = QVariant(value).toReal(&ok);
         return ok ? result : defaultVal;
     }
 
     const QByteArray symbol = value.mid(firstLetter).toLatin1();
     value.truncate(firstLetter);
     const qreal val = value.toDouble();
 
     if (symbol == "pt" || symbol.isEmpty())
         return val;
 
-    KReportUnit u = KReportUnit::fromSymbol(QLatin1String(symbol), &ok);
-    if (ok)
+    KReportUnit u(KReportUnit::symbolToType(QLatin1String(symbol)));
+    if (u.isValid()) {
         return u.fromUserValue(val);
+    }
 
     if (symbol == "m")
         return DM_TO_POINT(val * 10.0);
     else if (symbol == "km")
         return DM_TO_POINT(val * 10000.0);
     kreportWarning() << "KReportUnit::parseValue: Unit" << symbol << "is not supported, please report.";
 
     //! @todo add support for mi/ft ?
     return defaultVal;
 }
 
-KReportUnit KReportUnit::fromSymbol(const QString &symbol, bool *ok)
+//static
+QString KReportUnit::symbol(KReportUnit::Type type)
 {
-    Type result = Point;
+    return QLatin1String(s_unitSymbols[static_cast(type)]);
+}
+
+//static
+KReportUnit::Type KReportUnit::symbolToType(const QString &symbol)
+{
+    Type result = Type::Invalid;
 
     if (symbol == QLatin1String("inch") /*compat*/) {
-        result = Inch;
-        if (ok)
-            *ok = true;
+        result = Type::Inch;
     } else {
-        if (ok)
-            *ok = false;
-
-        for (int i = 0; i < TypeCount; ++i) {
-            if (symbol == QLatin1String(unitNameList[i])) {
+        for (int i = firstUnitIndex(); i <= lastUnitIndex(); ++i) {
+            if (symbol == QLatin1String(s_unitSymbols[i])) {
                 result = static_cast(i);
-                if (ok)
-                    *ok = true;
+                break;
             }
         }
     }
+    return result;
+}
 
-    return KReportUnit(result);
+//static
+QStringList KReportUnit::symbols(const QList &types)
+{
+    QStringList result;
+    for (Type t : types) {
+        result.append(symbol(t));
+    }
+    return result;
 }
 
 qreal KReportUnit::convertFromUnitToUnit(qreal value, const KReportUnit &fromUnit, const KReportUnit &toUnit, qreal factor)
 {
     qreal pt;
     switch (fromUnit.type()) {
-    case Millimeter:
+    case Type::Invalid:
+        pt = -1.0;
+        break;
+    case Type::Millimeter:
         pt = MM_TO_POINT(value);
         break;
-    case Centimeter:
+    case Type::Centimeter:
         pt = CM_TO_POINT(value);
         break;
-    case Decimeter:
+    case Type::Decimeter:
         pt = DM_TO_POINT(value);
         break;
-    case Inch:
+    case Type::Inch:
         pt = INCH_TO_POINT(value);
         break;
-    case Pica:
+    case Type::Pica:
         pt = PI_TO_POINT(value);
         break;
-    case Cicero:
+    case Type::Cicero:
         pt = CC_TO_POINT(value);
         break;
-    case Pixel:
+    case Type::Pixel:
         pt = value / factor;
         break;
-    case Point:
+    case Type::Point:
     default:
         pt = value;
     }
 
     switch (toUnit.type()) {
-    case Millimeter:
+    case Type::Millimeter:
         return POINT_TO_MM(pt);
-    case Centimeter:
+    case Type::Centimeter:
         return POINT_TO_CM(pt);
-    case Decimeter:
+    case Type::Decimeter:
         return POINT_TO_DM(pt);
-    case Inch:
+    case Type::Inch:
         return POINT_TO_INCH(pt);
-    case Pica:
+    case Type::Pica:
         return POINT_TO_PI(pt);
-    case Cicero:
+    case Type::Cicero:
         return POINT_TO_CC(pt);
-    case Pixel:
+    case Type::Pixel:
         return pt * factor;
-    case Point:
+    case Type::Invalid:
+    case Type::Point:
     default:
         return pt;
     }
-
 }
 
 QString KReportUnit::symbol() const
 {
-    return QLatin1String(unitNameList[d->type]);
+    return QLatin1String(s_unitSymbols[static_cast(d->type)]);
 }
 
 qreal KReportUnit::parseAngle(const QString& _value, qreal defaultVal)
 {
     if (_value.isEmpty())
         return defaultVal;
 
     QString value(_value.simplified());
     value.remove(QLatin1Char(' '));
 
     int firstLetter = -1;
     for (int i = 0; i < value.length(); ++i) {
         if (value.at(i).isLetter()) {
             if (value.at(i) == QLatin1Char('e'))
                 continue;
             firstLetter = i;
             break;
         }
     }
 
     if (firstLetter == -1)
         return value.toDouble();
 
     const QString type = value.mid(firstLetter);
     value.truncate(firstLetter);
     const qreal val = value.toDouble();
 
     if (type == QLatin1String("deg"))
         return val;
     else if (type == QLatin1String("rad"))
         return val * 180 / M_PI;
     else if (type == QLatin1String("grad"))
         return val * 0.9;
 
     return defaultVal;
 }
 
 #ifndef QT_NO_DEBUG_STREAM
 QDebug operator<<(QDebug debug, const KReportUnit &unit)
 {
 #ifndef NDEBUG
-    debug.nospace() << unit.symbol();
+    if (unit.isValid()) {
+        debug.nospace() << QString::fromLatin1("Unit(%1, %2)").arg(unit.symbol()).arg(unit.factor());
+    } else {
+        debug.nospace() << QString::fromLatin1("Unit(Invalid)");
+    }
 #else
     Q_UNUSED(unit);
 #endif
     return debug.space();
-
 }
 
 void KReportUnit::setFactor(qreal factor) 
 {
     d->pixelConversion = factor;
 }
 
 qreal KReportUnit::factor() const
 {
     return d->pixelConversion;
 }
 
 KReportUnit::Type KReportUnit::type() const 
 {
     return d->type;
 }
 
+bool KReportUnit::isValid() const
+{
+    return d->type != KReportUnit::Type::Invalid;
+}
+
 #endif
diff --git a/src/common/KReportUnit.h b/src/common/KReportUnit.h
index 31d95a46..3f814493 100644
--- a/src/common/KReportUnit.h
+++ b/src/common/KReportUnit.h
@@ -1,265 +1,303 @@
 /* This file is part of the KDE project
    Copyright (C) 1998, 1999 Reginald Stadlbauer 
    Copyright (C) 1998, 1999 Torben Weis 
    Copyright (C) 2004, Nicolas GOUTTE 
    Copyright (C) 2010 Thomas Zander 
    Copyright 2012 Friedrich W. H. Kossebau 
+   Copyright (C) 2017 Jarosław Staniek 
 
    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Library General Public
    License as published by the Free Software Foundation; either
    version 2 of the License, or (at your option) any later version.
 
    This library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    Library General Public License for more details.
 
    You should have received a copy of the GNU Library General Public License
    along with this library; see the file COPYING.LIB.  If not, write to
    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
  * Boston, MA 02110-1301, USA.
 */
 
 #ifndef KREPORTUNIT_H
 #define KREPORTUNIT_H
 
 #include  // for floor
 
+#include 
 #include 
 #include 
 #include 
 
 #include "kreport_export.h"
 
-class QStringList;
-
 // 1 inch ^= 72 pt
 // 1 inch ^= 25.399956 mm (-pedantic ;p)
 // 1 pt = 1/12 pi
 // 1 pt ^= 0.0077880997 cc
 // 1 cc = 12 dd
 // Note: I don't use division but multiplication with the inverse value
 // because it's faster ;p (Werner)
 #define POINT_TO_MM(px) qreal((px)*0.352777167)
 #define MM_TO_POINT(mm) qreal((mm)*2.83465058)
 #define POINT_TO_CM(px) qreal((px)*0.0352777167)
 #define CM_TO_POINT(cm) qreal((cm)*28.3465058)
 #define POINT_TO_DM(px) qreal((px)*0.00352777167)
 #define DM_TO_POINT(dm) qreal((dm)*283.465058)
 #define POINT_TO_INCH(px) qreal((px)*0.01388888888889)
 #define INCH_TO_POINT(inch) qreal((inch)*72.0)
 #define MM_TO_INCH(mm) qreal((mm)*0.039370147)
 #define INCH_TO_MM(inch) qreal((inch)*25.399956)
 #define POINT_TO_PI(px) qreal((px)*0.083333333)
 #define POINT_TO_CC(px) qreal((px)*0.077880997)
 #define PI_TO_POINT(pi) qreal((pi)*12)
 #define CC_TO_POINT(cc) qreal((cc)*12.840103)
 /**
  * %KReport stores everything in pt (using "qreal") internally.
  * When displaying a value to the user, the value is converted to the user's unit
  * of choice, and rounded to a reasonable precision to avoid 0.999999
  *
- * For implementing the selection of a unit type in the UI use the *ForUi() methods.
- * They ensure the same order of the unit types in all places, with the order not
- * bound to the order in the enum (so ABI-compatible extension is possible) and
- * with the order and scope of listed types controlled by the @c ListOptions parameter.
+ * For implementing the selection of a unit type in the UI use the allTypes() method.
+ * it ensure the same order of the unit types in all places, with the order not
+ * bound to the order in the enum so ABI-compatible extension is possible.
  */
 class KREPORT_EXPORT KReportUnit
 {
+    Q_DECLARE_TR_FUNCTIONS(KReportUnit)
 public:
     /** Length units supported by %KReport. */
-    enum Type {
-        Millimeter = 0,
-        Point,  ///< Postscript point, 1/72th of an Inco
-        Inch,
+    enum class Type {
+        Invalid,
+        Millimeter,
         Centimeter,
         Decimeter,
+        Inch,
         Pica,
         Cicero,
+        Point,  ///< Postscript point, 1/72th of an Inco
         Pixel,
-        TypeCount ///< @internal
+        Last = Pixel ///< internal
     };
 
-    /// Used to control the scope of the unit types listed in the UI
-    enum ListOption {
-        ListAll = 0,
-        HidePixel = 1,
-        HideMask = HidePixel
-    };
-     Q_DECLARE_FLAGS(ListOptions, ListOption)
+    /**
+     * @brief Constructs invalid unit
+      *
+      * @since 3.1
+      */
+    KReportUnit();
+
+    /** Construct unit with given type and factor. */
+    explicit KReportUnit(Type type, qreal factor = 1.0);
 
-    /** Construction requires initialization. The factor is for variable factor units like pixel */
-    explicit KReportUnit(Type type = Point, qreal factor = 1.0);
-    
     KReportUnit(const KReportUnit &other);
-    
+
     ~KReportUnit();
 
     /// Assigns specified type and factor 1.0 to the object
     /// @param unit Type of unit
     KReportUnit& operator=(Type type);
-    
+
     KReportUnit& operator=(const KReportUnit& other);
-     
+
     bool operator!=(const KReportUnit &other) const;
 
     bool operator==(const KReportUnit &other) const;
 
+    /**
+     * @brief Returns true if type of this unit is valid
+     *
+     * @since 3.1
+     */
+    bool isValid() const;
+
+    /**
+     * @brief Returns list of all supported types (without Invalid)
+     *
+     * @since 3.1
+     */
+    static QList allTypes();
+
+    /** Returns the type of this unit */
     KReportUnit::Type type() const;
 
+    /**
+     * @brief Returns (translated) description string for type of this unit
+     *
+     * @since 3.1
+     */
+    QString description() const;
+
+    /**
+     * @brief Returns (translated) description string for given unit type
+     *
+     * @since 3.1
+     */
+    static QString description(KReportUnit::Type type);
+
+    /**
+     * @brief Returns the list of (translated) description strings for given list of types
+     *
+     * @since 3.1
+     */
+    static QStringList descriptions(const QList &types);
+
     void setFactor(qreal factor);
-    
-    qreal factor() const;
-    
-    /** Returns a KReportUnit instance with the type at the @p index of the UI list with the given @p listOptions. */
-    static KReportUnit fromListForUi(int index, ListOptions listOptions = ListAll, qreal factor = 1.0);
 
-    /// Convert a unit symbol string into a KReportUnit
-    /// @param symbol symbol to convert
-    /// @param ok if set, it will be true if the unit was known, false if unknown
-    static KReportUnit fromSymbol(const QString &symbol, bool *ok = nullptr);
+    qreal factor() const;
 
     /**
      * Prepare ptValue to be displayed in pt
      * This method will round to 0.001 precision
      */
     static inline qreal toPoint(qreal ptValue)
     {
         // No conversion, only rounding (to 0.001 precision)
         return floor(ptValue * 1000.0) / 1000.0;
     }
 
     /**
      * Prepare ptValue to be displayed in mm
      * This method will round to 0.0001 precision, use POINT_TO_MM() for lossless conversion.
      */
     static inline qreal toMillimeter(qreal ptValue)
     {
         // "mm" values are rounded to 0.0001 millimeters
         return floor(POINT_TO_MM(ptValue) * 10000.0) / 10000.0;
     }
 
     /**
      * Prepare ptValue to be displayed in cm
      * This method will round to 0.0001 precision, use POINT_TO_CM() for lossless conversion.
      */
     static inline qreal toCentimeter(qreal ptValue)
     {
         return floor(POINT_TO_CM(ptValue) * 10000.0) / 10000.0;
     }
 
     /**
      * Prepare ptValue to be displayed in dm
      * This method will round to 0.0001 precision, use POINT_TO_DM() for lossless conversion.
      */
     static inline qreal toDecimeter(qreal ptValue)
     {
         return floor(POINT_TO_DM(ptValue) * 10000.0) / 10000.0;
     }
 
     /**
      * Prepare ptValue to be displayed in inch
      * This method will round to 0.00001 precision, use POINT_TO_INCH() for lossless conversion.
      */
     static inline qreal toInch(qreal ptValue)
     {
         // "in" values are rounded to 0.00001 inches
         return floor(POINT_TO_INCH(ptValue) * 100000.0) / 100000.0;
     }
 
     /**
      * Prepare ptValue to be displayed in pica
      * This method will round to 0.00001 precision, use POINT_TO_PI() for lossless conversion.
      */
     static inline qreal toPica(qreal ptValue)
     {
         // "pi" values are rounded to 0.00001 inches
         return floor(POINT_TO_PI(ptValue) * 100000.0) / 100000.0;
     }
 
     /**
      * Prepare ptValue to be displayed in cicero
      * This method will round to 0.00001 precision, use POINT_TO_CC() for lossless conversion.
      */
     static inline qreal toCicero(qreal ptValue)
     {
         // "cc" values are rounded to 0.00001 inches
         return floor(POINT_TO_CC(ptValue) * 100000.0) / 100000.0;
     }
 
     /**
      * convert the given value directly from one unit to another
      */
     static qreal convertFromUnitToUnit(qreal value, const KReportUnit &fromUnit, const KReportUnit &toUnit, qreal factor = 1.0);
 
-
     /**
      * This method is the one to use to display a value in a dialog
      * \return the value @p ptValue converted to unit and rounded, ready to be displayed
      */
     qreal toUserValue(qreal ptValue) const;
 
     /**
      * Convert the value @p ptValue to a given unit @p unit
      * Unlike KReportUnit::ptToUnit the return value remains unrounded, so that it can be used in complex calculation
      * \return the converted value
      */
     static qreal ptToUnit(qreal ptValue, const KReportUnit &unit);
 
     /// This method is the one to use to display a value in a dialog
     /// @return the value @p ptValue converted the unit and rounded, ready to be displayed
     QString toUserStringValue(qreal ptValue) const;
 
     /// This method is the one to use to read a value from a dialog
     /// @return the value converted to points for internal use
     qreal fromUserValue(qreal value) const;
 
     /// This method is the one to use to read a value from a dialog
     /// @param value value entered by the user
     /// @param ok if set, the pointed bool is set to true if the value could be
     /// converted to a qreal, and to false otherwise.
     /// @return the value converted to points for internal use
     qreal fromUserValue(const QString &value, bool *ok = nullptr) const;
 
-    /// Get the description string of the given unit
-    static QString unitDescription(KReportUnit::Type type);
+    //! Returns the symbol string of given unit type
+    //! Symbol for Invalid type is empty string.
+    static QString symbol(KReportUnit::Type type);
 
-    /// Get the symbol string of the unit
+    //! Returns the symbol string of the unit
+    //! Symbol for Invalid type is empty string.
     QString symbol() const;
 
-    /// Returns the list of unit types for the UI, controlled with the given @p listOptions.
-    static QStringList listOfUnitNameForUi(ListOptions listOptions = ListAll);
+    /**
+     * Equal to symbol(): returns the symbol string of the unit.
+     */
+    inline QString toString() const
+    {
+        return symbol();
+    }
+
+    /**
+     * @brief Returns a unit symbol string to type
+     *
+     * @param symbol symbol to convert, must be lowercase
+     * @return Invalid type for unsupported symbol
+     *
+     * @since 3.1
+     */
+    static KReportUnit::Type symbolToType(const QString &symbol);
 
-    /// Get the index of this unit in the list of unit types for the UI,
-    /// if it is controlled with the given @p listOptions.
-    int indexInListForUi(ListOptions listOptions = ListAll) const;
+    /**
+     * @brief Returns the list of unit symbols for the given types
+     *
+     * @since 3.1
+     */
+    static QStringList symbols(const QList &types);
 
     /// Parses common %KReport and ODF values, like "10cm", "5mm" to pt.
     /// If no unit is specified, pt is assumed.
     static qreal parseValue(const QString &value, qreal defaultVal = 0.0);
 
     /// parse an angle to its value in degrees
     static qreal parseAngle(const QString &value, qreal defaultVal = 0.0);
 
-    /**
-     * Equal to symbol(): returns the symbol string of the unit.
-     */
-    inline QString toString() const
-    {
-        return symbol();
-    }
-        
 private:
     class Private;
     Private * const d;
 };
 
 #ifndef QT_NO_DEBUG_STREAM
 KREPORT_EXPORT QDebug operator<<(QDebug, const KReportUnit &);
 #endif
 
 Q_DECLARE_METATYPE(KReportUnit)
-Q_DECLARE_OPERATORS_FOR_FLAGS(KReportUnit::ListOptions)
 
 #endif
diff --git a/src/wrtembed/KReportDesigner.cpp b/src/wrtembed/KReportDesigner.cpp
index 16de7785..b1f6d8f8 100644
--- a/src/wrtembed/KReportDesigner.cpp
+++ b/src/wrtembed/KReportDesigner.cpp
@@ -1,1542 +1,1529 @@
 /* This file is part of the KDE project
  * Copyright (C) 2001-2007 by OpenMFG, LLC 
  * Copyright (C) 2007-2010 by Adam Pigg 
  * Copyright (C) 2011-2017 Jarosław Staniek 
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
  * This library is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
  * License along with this library.  If not, see .
  */
 
 #include "KReportDesigner.h"
+#include "KReportDesign_p.h"
+#include "KReportDesignerItemLine.h"
 #include "KReportDesignerSection.h"
+#include "KReportDesignerSectionDetail.h"
+#include "KReportDesignerSectionDetailGroup.h"
 #include "KReportDesignerSectionScene.h"
 #include "KReportDesignerSectionView.h"
-#include "KReportDesignerSectionDetailGroup.h"
-#include "KReportPropertiesButton.h"
-#include "KReportSectionEditor.h"
-#include "KReportDesignerSectionDetail.h"
-#include "KReportDesignerItemLine.h"
-#include "KReportRuler_p.h"
-#include "KReportZoomHandler_p.h"
 #include "KReportPageSize.h"
-#include "KReportUtils_p.h"
-#include "KReportUtils.h"
 #include "KReportPluginInterface.h"
 #include "KReportPluginManager.h"
-#include "KReportSection.h"
 #include "KReportPluginMetaData.h"
+#include "KReportPropertiesButton.h"
+#include "KReportRuler_p.h"
+#include "KReportSection.h"
+#include "KReportSectionEditor.h"
+#include "KReportUtils.h"
+#include "KReportUtils_p.h"
+#include "KReportZoomHandler_p.h"
 #include "kreport_debug.h"
 #ifdef KREPORT_SCRIPTING
 #include "KReportScriptSource.h"
 #endif
 
 #include 
 #include 
 #include 
 #include 
 #include 
 #include 
 #include 
 #include 
 #include 
 #include 
 #include 
 #include 
 #include 
 
 //! Also add public method for runtime?
 const char ns[] = "http://kexi-project.org/report/2.0";
 
 static QDomElement propertyToElement(QDomDocument* d, KProperty* p)
 {
     QDomElement e = d->createElement(QLatin1String("report:" + p->name().toLower()));
     e.appendChild(d->createTextNode(p->value().toString()));
     return e;
 }
 
 //
 // define and implement the ReportWriterSectionData class
 // a simple class to hold/hide data in the ReportHandler class
 //
 class ReportWriterSectionData
 {
 public:
     ReportWriterSectionData() {
         selected_x_offset = 0;
         selected_y_offset = 0;
         mouseAction = ReportWriterSectionData::MA_None;
     }
     virtual ~ReportWriterSectionData() {
     }
 
     enum MouseAction {
         MA_None = 0,
         MA_Insert = 1,
         MA_Grab = 2,
         MA_MoveStartPoint,
         MA_MoveEndPoint,
         MA_ResizeNW = 8,
         MA_ResizeN,
         MA_ResizeNE,
         MA_ResizeE,
         MA_ResizeSE,
         MA_ResizeS,
         MA_ResizeSW,
         MA_ResizeW
     };
 
     int selected_x_offset;
     int selected_y_offset;
 
     MouseAction mouseAction;
     QString itemToInsert;
 
     QList copy_list;
     QList cut_list;
 };
 
 //! @internal
 class Q_DECL_HIDDEN KReportDesigner::Private
 {
 public:
     Private(){}
 
     ~Private()
     {
         delete dataSource;
     }
 
     QGridLayout *grid;
     KReportRuler *hruler;
     KReportZoomHandler zoomHandler;
     QVBoxLayout *vboxlayout;
     KReportPropertiesButton *pageButton;
 
     QGraphicsScene *activeScene = nullptr;
 
     ReportWriterSectionData sectionData;
 
     KReportDesignerSection *reportHeader = nullptr;
     KReportDesignerSection *pageHeaderFirst = nullptr;
     KReportDesignerSection *pageHeaderOdd = nullptr;
     KReportDesignerSection *pageHeaderEven = nullptr;
     KReportDesignerSection *pageHeaderLast = nullptr;
     KReportDesignerSection *pageHeaderAny = nullptr;
 
     KReportDesignerSection *pageFooterFirst = nullptr;
     KReportDesignerSection *pageFooterOdd = nullptr;
     KReportDesignerSection *pageFooterEven = nullptr;
     KReportDesignerSection *pageFooterLast = nullptr;
     KReportDesignerSection *pageFooterAny = nullptr;
     KReportDesignerSection *reportFooter = nullptr;
     KReportDesignerSectionDetail *detail = nullptr;
 
     //Properties
     KPropertySet set;
     KPropertySet *itemSet;
     KProperty *title;
     KProperty *pageSize;
     KProperty *orientation;
     KProperty *unit;
     KProperty *customHeight;
     KProperty *customWidth;
     KProperty *leftMargin;
     KProperty *rightMargin;
     KProperty *topMargin;
     KProperty *bottomMargin;
     KProperty *showGrid;
     KProperty *gridDivisions;
     KProperty *gridSnap;
     KProperty *labelType;
 #ifdef KREPORT_SCRIPTING
     KProperty *script;
 #endif
 
     //Actions
     QAction *editCutAction;
     QAction *editCopyAction;
     QAction *editPasteAction;
     QAction *editDeleteAction;
     QAction *sectionEdit;
     QAction *parameterEdit;
     QAction *itemRaiseAction;
     QAction *itemLowerAction;
 
     qreal pressX = -1;
     qreal pressY = -1;
     qreal releaseX = -1;
     qreal releaseY = -1;
 
     bool modified = false; // true if this document has been modified, false otherwise
 
     QString originalInterpreter; //Value of the script interpreter at load time
     QString originalScript; //Value of the script at load time
 
     KReportDataSource *dataSource = nullptr;
 #ifdef KREPORT_SCRIPTING
     KReportScriptSource *scriptSource = nullptr;
 #endif
 };
 
 KReportDesigner::KReportDesigner(QWidget * parent)
         : QWidget(parent), d(new Private())
 {
     KReportPluginManager::self(); // this loads icons early enough
 
     createProperties();
     createActions();
 
     d->grid = new QGridLayout(this);
     d->grid->setSpacing(0);
     d->grid->setMargin(0);
     d->grid->setColumnStretch(1, 1);
     d->grid->setRowStretch(1, 1);
     d->grid->setSizeConstraint(QLayout::SetFixedSize);
 
     d->vboxlayout = new QVBoxLayout();
     d->vboxlayout->setSpacing(0);
     d->vboxlayout->setMargin(0);
     d->vboxlayout->setSizeConstraint(QLayout::SetFixedSize);
 
     //Create nice rulers
     d->hruler = new KReportRuler(this, Qt::Horizontal, d->zoomHandler);
 
     d->pageButton = new KReportPropertiesButton(this);
 
-    d->hruler->setUnit(KReportUnit(KReportUnit::Centimeter));
-
     d->grid->addWidget(d->pageButton, 0, 0);
     d->grid->addWidget(d->hruler, 0, 1);
     d->grid->addLayout(d->vboxlayout, 1, 0, 1, 2);
 
     d->pageButton->setMaximumSize(QSize(19, 22));
     d->pageButton->setMinimumSize(QSize(19, 22));
 
     d->detail = new KReportDesignerSectionDetail(this);
     d->vboxlayout->insertWidget(0, d->detail);
 
     setLayout(d->grid);
 
     connect(d->pageButton, SIGNAL(released()), this, SLOT(slotPageButton_Pressed()));
     emit pagePropertyChanged(d->set);
 
     connect(&d->set, SIGNAL(propertyChanged(KPropertySet&,KProperty&)),
             this, SLOT(slotPropertyChanged(KPropertySet&,KProperty&)));
 
     changeSet(&d->set);
 }
 
 KReportDesigner::~KReportDesigner()
 {
     delete d;
 }
 
 KReportDesigner::KReportDesigner(QWidget *parent, const QDomElement &data)
     : KReportDesigner(parent)
 {
     if (data.tagName() != QLatin1String("report:content")) {
         // arg we got an xml file but not one i know of
         kreportWarning() << "root element was not ";
     }
     //kreportDebug() << data.text();
     deleteDetail();
 
     QDomNodeList nlist = data.childNodes();
     QDomNode it;
 
     for (int i = 0; i < nlist.count(); ++i) {
         it = nlist.item(i);
         // at this level all the children we get should be Elements
         if (it.isElement()) {
             QString n = it.nodeName().toLower();
             //kreportDebug() << n;
             if (n == QLatin1String("report:title")) {
                 setReportTitle(it.firstChild().nodeValue());
 #ifdef KREPORT_SCRIPTING
             } else if (n == QLatin1String("report:script")) {
                 d->originalInterpreter = it.toElement().attribute(QLatin1String("report:script-interpreter"), QLatin1String("javascript"));
                 if (d->originalInterpreter.isEmpty()) {
                     d->originalInterpreter = QLatin1String("javascript");
                 }
                 d->originalScript = it.firstChild().nodeValue();
                 d->script->setValue(d->originalScript);
 
                 if (d->originalInterpreter != QLatin1String("javascript") && d->originalInterpreter != QLatin1String("qtscript")) {
                     QString msg = tr("This report contains scripts of type \"%1\". "
                                      "Only scripts written in JavaScript language are "
                                      "supported. To prevent losing the scripts, their type "
                                      "and content will not be changed unless you change these scripts."
                                      ).arg(d->originalInterpreter);
                     QMessageBox::warning(this, tr("Unsupported Script Type"), msg);
                 }
 #endif
             } else if (n == QLatin1String("report:grid")) {
                 d->showGrid->setValue(it.toElement().attribute(QLatin1String("report:grid-visible"), QString::number(1)).toInt() != 0);
                 d->gridSnap->setValue(it.toElement().attribute(QLatin1String("report:grid-snap"), QString::number(1)).toInt() != 0);
                 d->gridDivisions->setValue(it.toElement().attribute(QLatin1String("report:grid-divisions"), QString::number(4)).toInt());
                 d->unit->setValue(it.toElement().attribute(QLatin1String("report:page-unit"), QLatin1String("cm")));
             }
 
             //! @todo Load page options
             else if (n == QLatin1String("report:page-style")) {
                 QString pagetype = it.firstChild().nodeValue();
 
                 if (pagetype == QLatin1String("predefined")) {
                     d->pageSize->setValue(it.toElement().attribute(QLatin1String("report:page-size"), QLatin1String("A4")));
                 } else if (pagetype == QLatin1String("custom")) {
                     d->pageSize->setValue(QLatin1String("custom"));
                     d->customHeight->setValue(KReportUnit::parseValue(it.toElement().attribute(QLatin1String("report:custom-page-height"), QLatin1String(""))));
                     d->customWidth->setValue(KReportUnit::parseValue(it.toElement().attribute(QLatin1String("report:custom-page-widtht"), QLatin1String(""))));
                 } else if (pagetype == QLatin1String("label")) {
                     //! @todo
                 }
 
                 d->rightMargin->setValue(KReportUnit::parseValue(it.toElement().attribute(QLatin1String("fo:margin-right"), QLatin1String("1.0cm"))));
                 d->leftMargin->setValue(KReportUnit::parseValue(it.toElement().attribute(QLatin1String("fo:margin-left"), QLatin1String("1.0cm"))));
                 d->topMargin->setValue(KReportUnit::parseValue(it.toElement().attribute(QLatin1String("fo:margin-top"), QLatin1String("1.0cm"))));
                 d->bottomMargin->setValue(KReportUnit::parseValue(it.toElement().attribute(QLatin1String("fo:margin-bottom"), QLatin1String("1.0cm"))));
 
                 d->orientation->setValue(it.toElement().attribute(QLatin1String("report:print-orientation"), QLatin1String("portrait")));
 
             } else if (n == QLatin1String("report:body")) {
                 QDomNodeList sectionlist = it.childNodes();
                 QDomNode sec;
 
                 for (int s = 0; s < sectionlist.count(); ++s) {
                     sec = sectionlist.item(s);
                     if (sec.isElement()) {
                         QString sn = sec.nodeName().toLower();
                         //kreportDebug() << sn;
                         if (sn == QLatin1String("report:section")) {
                             QString sectiontype = sec.toElement().attribute(QLatin1String("report:section-type"));
                             if (section(KReportSectionData::sectionTypeFromString(sectiontype)) == nullptr) {
                                 insertSection(KReportSectionData::sectionTypeFromString(sectiontype));
                                 section(KReportSectionData::sectionTypeFromString(sectiontype))->initFromXML(sec);
                             }
                         } else if (sn == QLatin1String("report:detail")) {
                             KReportDesignerSectionDetail * rsd = new KReportDesignerSectionDetail(this);
                             rsd->initFromXML(&sec);
                             setDetail(rsd);
                         }
                     } else {
                         kreportWarning() << "Encountered an unknown Element: "  << n;
                     }
                 }
             }
         } else {
             kreportWarning() << "Encountered a child node of root that is not an Element";
         }
     }
     this->slotPageButton_Pressed();
     emit reportDataChanged();
     slotPropertyChanged(d->set, *d->unit); // set unit for all items
     setModified(false);
 }
 
 ///The saving code
 QDomElement KReportDesigner::document() const
 {
     QDomDocument doc;
     QString saveInterpreter;
 
     QDomElement content = doc.createElement(QLatin1String("report:content"));
     content.setAttribute(QLatin1String("xmlns:report"), QLatin1String(ns));
     content.setAttribute(QLatin1String("xmlns:fo"), QLatin1String("urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0"));
     content.setAttribute(QLatin1String("xmlns:svg"), QLatin1String("urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0"));
 
     doc.appendChild(content);
 
     //title
     content.appendChild(propertyToElement(&doc, d->title));
 
 #ifdef KREPORT_SCRIPTING
     if (d->originalInterpreter.isEmpty()) {
         d->originalInterpreter = QLatin1String("javascript");
     }
     saveInterpreter = d->originalInterpreter;
 
     if (!d->script->value().toString().isEmpty()) {
         if (d->script->value().toString() != d->originalScript || d->originalInterpreter == QLatin1String("qtscript") || d->originalInterpreter.isEmpty() ) {
             //The script has changed so force interpreter to 'javascript'.  Also set if was using qtscript
             saveInterpreter = QLatin1String("javascript");
         }
     }
 
     QDomElement scr = propertyToElement(&doc, d->script);
     scr.setAttribute(QLatin1String("report:script-interpreter"), saveInterpreter);
     content.appendChild(scr);
 #endif
 
     QDomElement grd = doc.createElement(QLatin1String("report:grid"));
     KReportUtils::addPropertyAsAttribute(&grd, d->showGrid);
     KReportUtils::addPropertyAsAttribute(&grd, d->gridDivisions);
     KReportUtils::addPropertyAsAttribute(&grd, d->gridSnap);
     KReportUtils::addPropertyAsAttribute(&grd, d->unit);
     content.appendChild(grd);
 
     // pageOptions
     // -- size
     QDomElement pagestyle = doc.createElement(QLatin1String("report:page-style"));
 
     if (d->pageSize->value().toString() == QLatin1String("Custom")) {
         pagestyle.appendChild(doc.createTextNode(QLatin1String("custom")));
         KReportUtils::setAttribute(&pagestyle, QLatin1String("report:custom-page-width"), d->customWidth->value().toDouble());
         KReportUtils::setAttribute(&pagestyle, QLatin1String("report:custom-page-height"), d->customHeight->value().toDouble());
 
     } 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());
     } else {
         pagestyle.appendChild(doc.createTextNode(QLatin1String("predefined")));
         KReportUtils::addPropertyAsAttribute(&pagestyle, d->pageSize);
         //pagestyle.setAttribute("report:page-size", d->pageSize->value().toString());
     }
 
     // -- orientation
     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());
 
     content.appendChild(pagestyle);
 
     QDomElement body = doc.createElement(QLatin1String("report:body"));
     QDomElement domsection;
 
     for (int i = KReportSectionData::PageHeaderFirst; i <= KReportSectionData::PageFooterAny; ++i) {
         KReportDesignerSection *sec = section((KReportSectionData::Section)i);
         if (sec) {
             domsection = doc.createElement(QLatin1String("report:section"));
             domsection.setAttribute(QLatin1String("report:section-type"), KReportSectionData::sectionTypeString(KReportSectionData::Section(i)));
             sec->buildXML(&doc, &domsection);
             body.appendChild(domsection);
         }
     }
 
     QDomElement detail = doc.createElement(QLatin1String("report:detail"));
     d->detail->buildXML(&doc, &detail);
     body.appendChild(detail);
 
     content.appendChild(body);
     return content;
 }
 
 void KReportDesigner::slotSectionEditor()
 {
     KReportSectionEditor se(this);
     (void)se.exec();
 }
 
 void KReportDesigner::setDataSource(KReportDataSource* source)
 {
     if (d->dataSource == source) {
         return;
     }
     delete d->dataSource;
 
     d->dataSource = source;
     slotPageButton_Pressed();
     setModified(true);
     emit reportDataChanged();
 }
 
 #ifdef KREPORT_SCRIPTING
 void KReportDesigner::setScriptSource(KReportScriptSource* source)
 {
     d->scriptSource = source;
 }
 #endif
 
 KReportDesignerSection * KReportDesigner::section(KReportSectionData::Section s) const
 {
     KReportDesignerSection *sec;
     switch (s) {
     case KReportSectionData::PageHeaderAny:
         sec = d->pageHeaderAny;
         break;
     case KReportSectionData::PageHeaderEven:
         sec = d->pageHeaderEven;
         break;
     case KReportSectionData::PageHeaderOdd:
         sec = d->pageHeaderOdd;
         break;
     case KReportSectionData::PageHeaderFirst:
         sec = d->pageHeaderFirst;
         break;
     case KReportSectionData::PageHeaderLast:
         sec = d->pageHeaderLast;
         break;
     case KReportSectionData::PageFooterAny:
         sec = d->pageFooterAny;
         break;
     case KReportSectionData::PageFooterEven:
         sec = d->pageFooterEven;
         break;
     case KReportSectionData::PageFooterOdd:
         sec = d->pageFooterOdd;
         break;
     case KReportSectionData::PageFooterFirst:
         sec = d->pageFooterFirst;
         break;
     case KReportSectionData::PageFooterLast:
         sec = d->pageFooterLast;
         break;
     case KReportSectionData::ReportHeader:
         sec = d->reportHeader;
         break;
     case KReportSectionData::ReportFooter:
         sec = d->reportFooter;
         break;
     default:
         sec = nullptr;
     }
     return sec;
 }
 
 KReportDesignerSection* KReportDesigner::createSection()
 {
     return new KReportDesignerSection(this, d->zoomHandler);
 }
 
 void KReportDesigner::removeSection(KReportSectionData::Section s)
 {
     KReportDesignerSection* sec = section(s);
     if (sec) {
         delete sec;
 
         switch (s) {
         case KReportSectionData::PageHeaderAny:
             d->pageHeaderAny = nullptr;
             break;
         case KReportSectionData::PageHeaderEven:
             sec = d->pageHeaderEven = nullptr;
             break;
         case KReportSectionData::PageHeaderOdd:
             d->pageHeaderOdd = nullptr;
             break;
         case KReportSectionData::PageHeaderFirst:
             d->pageHeaderFirst = nullptr;
             break;
         case KReportSectionData::PageHeaderLast:
             d->pageHeaderLast = nullptr;
             break;
         case KReportSectionData::PageFooterAny:
             d->pageFooterAny = nullptr;
             break;
         case KReportSectionData::PageFooterEven:
             d->pageFooterEven = nullptr;
             break;
         case KReportSectionData::PageFooterOdd:
             d->pageFooterOdd = nullptr;
             break;
         case KReportSectionData::PageFooterFirst:
             d->pageFooterFirst = nullptr;
             break;
         case KReportSectionData::PageFooterLast:
             d->pageFooterLast = nullptr;
             break;
         case KReportSectionData::ReportHeader:
             d->reportHeader = nullptr;
             break;
         case KReportSectionData::ReportFooter:
             d->reportFooter = nullptr;
             break;
         default:
             sec = nullptr;
         }
 
         setModified(true);
         adjustSize();
     }
 }
 
 void KReportDesigner::insertSection(KReportSectionData::Section s)
 {
     KReportDesignerSection* sec = section(s);
     if (!sec) {
         int idx = 0;
         for (int i = 1; i <= s; ++i) {
             if (section((KReportSectionData::Section)i))
                 idx++;
         }
         if (s > KReportSectionData::ReportHeader)
             idx++;
         //kreportDebug() << idx;
         KReportDesignerSection *rs = createSection();
         d->vboxlayout->insertWidget(idx, rs);
 
         switch (s) {
         case KReportSectionData::PageHeaderAny:
             rs->setTitle(tr("Page Header (Any)"));
             d->pageHeaderAny = rs;
             break;
         case KReportSectionData::PageHeaderEven:
             rs->setTitle(tr("Page Header (Even)"));
             d->pageHeaderEven = rs;
             break;
         case KReportSectionData::PageHeaderOdd:
             rs->setTitle(tr("Page Header (Odd)"));
             d->pageHeaderOdd = rs;
             break;
         case KReportSectionData::PageHeaderFirst:
             rs->setTitle(tr("Page Header (First)"));
             d->pageHeaderFirst = rs;
             break;
         case KReportSectionData::PageHeaderLast:
             rs->setTitle(tr("Page Header (Last)"));
             d->pageHeaderLast = rs;
             break;
         case KReportSectionData::PageFooterAny:
             rs->setTitle(tr("Page Footer (Any)"));
             d->pageFooterAny = rs;
             break;
         case KReportSectionData::PageFooterEven:
             rs->setTitle(tr("Page Footer (Even)"));
             d->pageFooterEven = rs;
             break;
         case KReportSectionData::PageFooterOdd:
             rs->setTitle(tr("Page Footer (Odd)"));
             d->pageFooterOdd = rs;
             break;
         case KReportSectionData::PageFooterFirst:
             rs->setTitle(tr("Page Footer (First)"));
             d->pageFooterFirst = rs;
             break;
         case KReportSectionData::PageFooterLast:
             rs->setTitle(tr("Page Footer (Last)"));
             d->pageFooterLast = rs;
             break;
         case KReportSectionData::ReportHeader:
             rs->setTitle(tr("Report Header"));
             d->reportHeader = rs;
             break;
         case KReportSectionData::ReportFooter:
             rs->setTitle(tr("Report Footer"));
             d->reportFooter = rs;
             break;
             //These sections cannot be inserted this way
         case KReportSectionData::None:
         case KReportSectionData::GroupHeader:
         case KReportSectionData::GroupFooter:
         case KReportSectionData::Detail:
             break;
         }
 
         rs->show();
         setModified(true);
         adjustSize();
         emit pagePropertyChanged(d->set);
     }
 }
 
 void KReportDesigner::setReportTitle(const QString & str)
 {
     if (reportTitle() != str) {
         d->title->setValue(str);
         setModified(true);
     }
 }
 
 KPropertySet* KReportDesigner::propertySet() const
 {
     return &d->set;
 }
 
 KPropertySet* KReportDesigner::selectedItemPropertySet() const
 {
     return d->itemSet;
 }
 
 KReportDataSource *KReportDesigner::reportDataSource() const
 {
     return d->dataSource;
 }
 
 KReportDesignerSectionDetail * KReportDesigner::detailSection() const
 {
     return d->detail;
 }
 
 QString KReportDesigner::reportTitle() const
 {
     return d->title->value().toString();
 }
 
 bool KReportDesigner::isModified() const
 {
     return d->modified;
 }
 
 void KReportDesigner::setModified(bool modified)
 {
     d->modified = modified;
 
     if (d->modified) {
         emit dirty();
     }
 }
 
 QStringList KReportDesigner::fieldNames() const
 {
     QStringList qs;
     qs << QString();
     if (d->dataSource)
         qs << d->dataSource->fieldNames();
 
     return qs;
 }
 
 QStringList KReportDesigner::fieldKeys() const
 {
     QStringList qs;
     qs << QString();
     if (d->dataSource)
         qs << d->dataSource->fieldKeys();
 
     return qs;
 }
 
 void KReportDesigner::createProperties()
 {
     QStringList keys, strings;
     KReportDesigner::addMetaProperties(&d->set,
         tr("Report", "Main report element"), QLatin1String("kreport-report-element"));
 
     connect(&d->set, SIGNAL(propertyChanged(KPropertySet&,KProperty&)),
             this, SLOT(slotPropertyChanged(KPropertySet&,KProperty&)));
 
     d->title = new KProperty("title", QLatin1String("Report"), tr("Title"), tr("Report Title"));
 
     keys.clear();
     keys =  KReportPageSize::pageFormatKeys();
     strings = KReportPageSize::pageFormatNames();
     QString defaultKey = KReportPageSize::pageSizeKey(KReportPageSize::defaultSize());
     d->pageSize = new KProperty("page-size", keys, strings, defaultKey, tr("Page Size"));
 
-    keys.clear(); strings.clear();
+    keys.clear();
+    strings.clear();
     keys << QLatin1String("portrait") << QLatin1String("landscape");
     strings << tr("Portrait") << tr("Landscape");
     d->orientation = new KProperty("print-orientation", keys, strings, QLatin1String("portrait"), tr("Page Orientation"));
 
-    keys.clear(); strings.clear();
-
-    strings = KReportUnit::listOfUnitNameForUi(KReportUnit::HidePixel);
-    QString unit;
-    foreach(const QString &un, strings) {
-        unit = un.mid(un.indexOf(QLatin1String("(")) + 1, 2);
-        keys << unit;
-    }
-
+    QList types(KReportUnit::allTypes());
+    types.removeOne(KReportUnit::Type::Pixel);
+    keys = KReportUnit::symbols(types);
+    strings = KReportUnit::descriptions(types);
     d->unit = new KProperty("page-unit", keys, strings, QLatin1String("cm"), 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->leftMargin = new KProperty("margin-left", KReportUnit(KReportUnit::Centimeter).fromUserValue(1.0),
+    d->leftMargin = new KProperty("margin-left", KReportUnit(KReportUnit::Type::Centimeter).fromUserValue(1.0),
         tr("Left Margin"), tr("Left Margin"), KProperty::Double);
-    d->rightMargin = new KProperty("margin-right", KReportUnit(KReportUnit::Centimeter).fromUserValue(1.0),
+    d->rightMargin = new KProperty("margin-right", KReportUnit(KReportUnit::Type::Centimeter).fromUserValue(1.0),
         tr("Right Margin"), tr("Right Margin"), KProperty::Double);
-    d->topMargin = new KProperty("margin-top", KReportUnit(KReportUnit::Centimeter).fromUserValue(1.0),
+    d->topMargin = new KProperty("margin-top", KReportUnit(KReportUnit::Type::Centimeter).fromUserValue(1.0),
         tr("Top Margin"), tr("Top Margin"), KProperty::Double);
-    d->bottomMargin = new KProperty("margin-bottom", KReportUnit(KReportUnit::Centimeter).fromUserValue(1.0),
+    d->bottomMargin = new KProperty("margin-bottom", KReportUnit(KReportUnit::Type::Centimeter).fromUserValue(1.0),
         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->set.addProperty(d->title);
     d->set.addProperty(d->pageSize);
     d->set.addProperty(d->orientation);
     d->set.addProperty(d->unit);
     d->set.addProperty(d->gridSnap);
     d->set.addProperty(d->showGrid);
     d->set.addProperty(d->gridDivisions);
     d->set.addProperty(d->leftMargin);
     d->set.addProperty(d->rightMargin);
     d->set.addProperty(d->topMargin);
     d->set.addProperty(d->bottomMargin);
 
 #ifdef KREPORT_SCRIPTING
     d->script = new KProperty("script", QStringList(), QStringList(), QString(), tr("Object Script"));
     d->set.addProperty(d->script);
 #endif
 
 //    KProperty* _customHeight;
 //    KProperty* _customWidth;
 
 }
 
 /**
 @brief Handle property changes
 */
 void KReportDesigner::slotPropertyChanged(KPropertySet &s, KProperty &p)
 {
     setModified(true);
     emit pagePropertyChanged(s);
 
     if (p.name() == "page-unit") {
         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);
     }
 }
 
 void KReportDesigner::slotPageButton_Pressed()
 {
 #ifdef KREPORT_SCRIPTING
     if (d->scriptSource) {
         QStringList sl = d->scriptSource->scriptList();
         sl.prepend(QString());
         d->script->setListData(sl, sl);
     }
     changeSet(&d->set);
 #endif
 }
 
 QSize KReportDesigner::sizeHint() const
 {
     int w = 0;
     int h = 0;
 
     if (d->pageFooterAny)
         h += d->pageFooterAny->sizeHint().height();
     if (d->pageFooterEven)
         h += d->pageFooterEven->sizeHint().height();
     if (d->pageFooterFirst)
         h += d->pageFooterFirst->sizeHint().height();
     if (d->pageFooterLast)
         h += d->pageFooterLast->sizeHint().height();
     if (d->pageFooterOdd)
         h += d->pageFooterOdd->sizeHint().height();
     if (d->pageHeaderAny)
         h += d->pageHeaderAny->sizeHint().height();
     if (d->pageHeaderEven)
         h += d->pageHeaderEven->sizeHint().height();
     if (d->pageHeaderFirst)
         h += d->pageHeaderFirst->sizeHint().height();
     if (d->pageHeaderLast)
         h += d->pageHeaderLast->sizeHint().height();
     if (d->pageHeaderOdd)
         h += d->pageHeaderOdd->sizeHint().height();
     if (d->reportHeader)
         h += d->reportHeader->sizeHint().height();
     if (d->reportFooter) {
         h += d->reportFooter->sizeHint().height();
 
     }
     if (d->detail) {
         h += d->detail->sizeHint().height();
         w += d->detail->sizeHint().width();
     }
 
     h += d->hruler->height();
 
     return QSize(w, h);
 }
 
 int KReportDesigner::pageWidthPx() const
 {
     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));
 
     QSize pageSizePx = layout.fullRectPixels(KReportPrivate::dpiX()).size();
 
     int width = pageSizePx.width();
     width = width - POINT_TO_INCH(d->set.property("margin-left").value().toDouble()) * KReportPrivate::dpiX();
     width = width - POINT_TO_INCH(d->set.property("margin-right").value().toDouble()) * KReportPrivate::dpiX();
 
     return width;
 }
 
 void KReportDesigner::resizeEvent(QResizeEvent * event)
 {
     Q_UNUSED(event);
     d->hruler->setRulerLength(pageWidthPx());
 }
 
 void KReportDesigner::setDetail(KReportDesignerSectionDetail *rsd)
 {
     if (!d->detail) {
         int idx = 0;
         if (d->pageHeaderFirst) idx++;
         if (d->pageHeaderOdd) idx++;
         if (d->pageHeaderEven) idx++;
         if (d->pageHeaderLast) idx++;
         if (d->pageHeaderAny) idx++;
         if (d->reportHeader) idx++;
         d->detail = rsd;
         d->vboxlayout->insertWidget(idx, d->detail);
     }
 }
 void KReportDesigner::deleteDetail()
 {
     delete d->detail;
     d->detail = nullptr;
 }
 
 KReportUnit KReportDesigner::pageUnit() const
 {
-    QString u;
-    bool found;
-
-    u = d->unit->value().toString();
-
-    KReportUnit unit = KReportUnit::fromSymbol(u, &found);
-    if (!found) {
-        unit = KReportUnit(KReportUnit::Centimeter);
-    }
-
-    return unit;
+    const QString symbol = d->unit->value().toString();
+    KReportUnit unit(KReportUnit::symbolToType(symbol));
+    return unit.isValid() ? unit : DEFAULT_UNIT;
 }
 
 void KReportDesigner::setGridOptions(bool vis, int div)
 {
     d->showGrid->setValue(QVariant(vis));
     d->gridDivisions->setValue(div);
 }
 
 //
 // methods for the sectionMouse*Event()
 //
 void KReportDesigner::sectionContextMenuEvent(KReportDesignerSectionScene * s, QGraphicsSceneContextMenuEvent * e)
 {
     Q_UNUSED(s);
 
     QMenu pop;
 
     bool itemsSelected = selectionCount() > 0;
     if (itemsSelected) {
         //! @todo KF5 use KStandardAction
         QAction *a = new QAction(QIcon::fromTheme(QLatin1String("edit-cut")), tr("Cut"), this);
         connect(a, SIGNAL(triggered()), this, SLOT(slotEditCut()));
         pop.addAction(a);
         //! @todo KF5 use KStandardAction
         a = new QAction(QIcon::fromTheme(QLatin1String("edit-copy")), tr("Copy"), this);
         connect(a, SIGNAL(triggered()), this, SLOT(slotEditCopy()));
         pop.addAction(a);
     }
     if (!d->sectionData.copy_list.isEmpty()) {
         QAction *a = new QAction(QIcon::fromTheme(QLatin1String("edit-paste")), tr("Paste"), this);
         connect(a, SIGNAL(triggered()), this, SLOT(slotEditPaste()));
         pop.addAction(a);
     }
 
     if (itemsSelected) {
         pop.addSeparator();
         //! @todo KF5 use KStandard*
         //const KGuiItem del = KStandardGuiItem::del();
         //a->setToolTip(del.toolTip());
         //a->setShortcut(QKeySequence(QKeySequence::Delete));
         QAction *a = new QAction(QIcon::fromTheme(QLatin1String("edit-delete")), tr("Delete"), this);
         connect(a, SIGNAL(triggered()), SLOT(slotEditDelete()));
         pop.addAction(a);
     }
     if (!pop.actions().isEmpty()) {
         pop.exec(e->screenPos());
     }
 }
 
 void KReportDesigner::sectionMousePressEvent(KReportDesignerSectionView * v, QMouseEvent * e)
 {
     Q_UNUSED(v);
     d->pressX = e->pos().x();
     d->pressY = e->pos().y();
 }
 
 void KReportDesigner::sectionMouseReleaseEvent(KReportDesignerSectionView * v, QMouseEvent * e)
 {
     e->accept();
 
     d->releaseX = e->pos().x();
     d->releaseY = e->pos().y();
 
     if (e->button() == Qt::LeftButton) {
         QPointF pos(d->pressX, d->pressY);
         QPointF end(d->releaseX, d->releaseY);
         if (d->releaseY >= v->scene()->height()) {
             d->releaseY = v->scene()->height();
             end.setY(v->scene()->height());
         }
 
         if (d->releaseX >= v->scene()->width()) {
             d->releaseX = v->scene()->width();
             end.setX(v->scene()->width());
         }
 
         if (d->sectionData.mouseAction == ReportWriterSectionData::MA_Insert) {
             QGraphicsItem * item = nullptr;
             QString classString;
             QString iconName;
             if (d->sectionData.itemToInsert == QLatin1String("org.kde.kreport.line")) {
                 item = new KReportDesignerItemLine(v->designer(), v->scene(), pos, end);
                 classString = tr("Line", "Report line element");
                 iconName = QLatin1String("kreport-line-element");
             }
             else {
                 KReportPluginManager* pluginManager = KReportPluginManager::self();
                 KReportPluginInterface *plug = pluginManager->plugin(d->sectionData.itemToInsert);
                 if (plug) {
                     QObject *obj = plug->createDesignerInstance(v->designer(), v->scene(), pos);
                     if (obj) {
                         item = dynamic_cast(obj);
                         classString = plug->metaData()->name();
                         iconName = plug->metaData()->iconName();
                     }
                 }
                 else {
                     kreportWarning() << "attempted to insert an unknown item";
                 }
             }
             if (item) {
                 item->setVisible(true);
                 item->setSelected(true);
                 KReportItemBase* baseReportItem = dynamic_cast(item);
                 if (baseReportItem) {
                     baseReportItem->setUnit(pageUnit());
                     KPropertySet *set = baseReportItem->propertySet();
                     KReportDesigner::addMetaProperties(set, classString, iconName);
                     changeSet(set);
                     if (v && v->designer()) {
                         v->designer()->setModified(true);
                     }
                     emit itemInserted(d->sectionData.itemToInsert);
                 }
             }
 
             d->sectionData.mouseAction = ReportWriterSectionData::MA_None;
             d->sectionData.itemToInsert.clear();
             unsetSectionCursor();
         }
     }
 }
 
 unsigned int KReportDesigner::selectionCount() const
 {
     if (activeScene())
         return activeScene()->selectedItems().count();
     else
         return 0;
 }
 
 void KReportDesigner::changeSet(KPropertySet *s)
 {
     //Set the checked state of the report properties button
     if (s == &d->set)
         d->pageButton->setCheckState(Qt::Checked);
     else
         d->pageButton->setCheckState(Qt::Unchecked);
 
     d->itemSet = s;
     emit propertySetChanged();
 }
 
 //
 // Actions
 //
 
 void KReportDesigner::slotItem(const QString &entity)
 {
     //kreportDebug() << entity;
     d->sectionData.mouseAction = ReportWriterSectionData::MA_Insert;
     d->sectionData.itemToInsert = entity;
     setSectionCursor(QCursor(Qt::CrossCursor));
 }
 
 void KReportDesigner::slotEditDelete()
 {
     QGraphicsItem * item = nullptr;
     bool modified = false;
     while (selectionCount() > 0) {
         item = activeScene()->selectedItems().value(0);
         if (item) {
             QGraphicsScene * scene = item->scene();
             delete item;
             scene->update();
             d->sectionData.mouseAction = ReportWriterSectionData::MA_None;
             modified = true;
         }
     }
     activeScene()->selectedItems().clear();
 
     /*! @todo temporary: clears cut and copy lists to make sure we do not crash
      if weve deleted something in the list
      should really check if an item is in the list first
      and remove it. */
     d->sectionData.cut_list.clear();
     d->sectionData.copy_list.clear();
     if (modified) {
         setModified(true);
     }
 }
 
 void KReportDesigner::slotEditCut()
 {
     if (selectionCount() > 0) {
         //First delete any items that are curerntly in the list
         //so as not to leak memory
         qDeleteAll(d->sectionData.cut_list);
         d->sectionData.cut_list.clear();
 
         QGraphicsItem * item = activeScene()->selectedItems().first();
         bool modified = false;
         if (item) {
             d->sectionData.copy_list.clear();
             foreach(QGraphicsItem *item, activeScene()->selectedItems()) {
                 d->sectionData.cut_list.append(dynamic_cast(item));
                 d->sectionData.copy_list.append(dynamic_cast(item));
             }
             foreach(QGraphicsItem *item, activeScene()->selectedItems()) {
                 activeScene()->removeItem(item);
                 activeScene()->update();
                 modified = true;
             }
             d->sectionData.selected_x_offset = 10;
             d->sectionData.selected_y_offset = 10;
         }
         if (modified) {
             setModified(true);
         }
     }
 }
 
 void KReportDesigner::slotEditCopy()
 {
     if (selectionCount() < 1)
         return;
 
     QGraphicsItem * item = activeScene()->selectedItems().first();
     if (item) {
         d->sectionData.copy_list.clear();
         foreach(QGraphicsItem *item, activeScene()->selectedItems()) {
             d->sectionData.copy_list.append(dynamic_cast(item));
         }
         d->sectionData.selected_x_offset = 10;
         d->sectionData.selected_y_offset = 10;
     }
 }
 
 void KReportDesigner::slotEditPaste()
 {
     // call the editPaste function passing it a reportsection
     slotEditPaste(activeScene());
 }
 
 void KReportDesigner::slotEditPaste(QGraphicsScene * canvas)
 {
 
     // paste a new item of the copy we have in the specified location
     if (!d->sectionData.copy_list.isEmpty()) {
         QList activeItems = canvas->selectedItems();
         QGraphicsItem *activeItem = nullptr;
         if (activeItems.count() == 1) {
             activeItem = activeItems.first();
         }
         canvas->clearSelection();
         d->sectionData.mouseAction = ReportWriterSectionData::MA_None;
 
         //! @todo this code sucks :)
         //! The setPos calls only work AFTER the name has been set ?!?!?
 
         foreach(KReportDesignerItemBase *item, d->sectionData.copy_list) {
             KReportItemBase *obj = dynamic_cast(item);
             const QString type = obj ? obj->typeName() : QLatin1String("object");
             //kreportDebug() << type;
             KReportDesignerItemBase *ent = item->clone();
             KReportItemBase *new_obj = dynamic_cast(ent);
             if (new_obj) {
                 new_obj->setEntityName(suggestEntityName(type));
                 if (activeItem) {
                     new_obj->setPosition(KReportItemBase::positionFromScene(QPointF(activeItem->x() + 10, activeItem->y() + 10)));
                 } else {
                     new_obj->setPosition(KReportItemBase::positionFromScene(QPointF(0, 0)));
                 }
                 changeSet(new_obj->propertySet());
             }
             QGraphicsItem *pasted_ent = dynamic_cast(ent);
             if (pasted_ent) {
                 pasted_ent->setSelected(true);
                 canvas->addItem(pasted_ent);
                 pasted_ent->show();
                 d->sectionData.mouseAction = ReportWriterSectionData::MA_Grab;
                 setModified(true);
             }
         }
     }
 }
 void KReportDesigner::slotRaiseSelected()
 {
     dynamic_cast(activeScene())->raiseSelected();
 }
 
 void KReportDesigner::slotLowerSelected()
 {
     dynamic_cast(activeScene())->lowerSelected();
 }
 
 QGraphicsScene* KReportDesigner::activeScene() const
 {
     return d->activeScene;
 }
 
 void KReportDesigner::setActiveScene(QGraphicsScene* a)
 {
     if (d->activeScene && d->activeScene != a)
         d->activeScene->clearSelection();
     d->activeScene = a;
 
     //Trigger an update so that the last scene redraws its title;
     update();
 }
 
 QString KReportDesigner::suggestEntityName(const QString &name) const
 {
     KReportDesignerSection *sec;
     int itemCount = 0;
     //Count items in the main sections
     for (int i = 1; i <= KReportSectionData::PageFooterAny; i++) {
         sec = section((KReportSectionData::Section) i);
         if (sec) {
             const QGraphicsItemList l = sec->items();
             itemCount += l.count();
         }
     }
 
     if (d->detail) {
         //Count items in the group headers/footers
         for (int i = 0; i < d->detail->groupSectionCount(); i++) {
             sec = d->detail->groupSection(i)->groupHeader();
             if (sec) {
                 const QGraphicsItemList l = sec->items();
                 itemCount += l.count();
             }
             sec = d->detail->groupSection(i)->groupFooter();
             if (sec) {
                 const QGraphicsItemList l = sec->items();
                 itemCount += l.count();
             }
         }
 
         sec = d->detail->detailSection();
         if (sec) {
             const QGraphicsItemList l = sec->items();
             itemCount += l.count();
         }
     }
 
     while (!isEntityNameUnique(name + QString::number(itemCount))) {
         itemCount++;
     }
     return name + QString::number(itemCount);
 }
 
 bool KReportDesigner::isEntityNameUnique(const QString &name, KReportItemBase* ignore) const
 {
     KReportDesignerSection *sec;
     bool unique = true;
 
     //Check items in the main sections
     for (int i = 1; i <= KReportSectionData::PageFooterAny; i++) {
         sec = section((KReportSectionData::Section)i);
         if (sec) {
             const QGraphicsItemList l = sec->items();
             for (QGraphicsItemList::const_iterator it = l.constBegin(); it != l.constEnd(); ++it) {
                 KReportItemBase* itm = dynamic_cast(*it);
                 if (itm && itm->entityName() == name  && itm != ignore) {
                     unique = false;
                     break;
                 }
             }
             if (!unique) break;
         }
     }
 
     //Count items in the group headers/footers
     if (unique && d->detail) {
         for (int i = 0; i < d->detail->groupSectionCount(); ++i) {
             sec = d->detail->groupSection(i)->groupHeader();
             if (sec) {
                 const QGraphicsItemList l = sec->items();
                 for (QGraphicsItemList::const_iterator it = l.constBegin(); it != l.constEnd(); ++it) {
                     KReportItemBase* itm = dynamic_cast(*it);
                     if (itm && itm->entityName() == name  && itm != ignore) {
                         unique = false;
                         break;
                     }
                 }
 
             }
             sec = d->detail->groupSection(i)->groupFooter();
             if (unique && sec) {
                 const QGraphicsItemList l = sec->items();
                 for (QGraphicsItemList::const_iterator it = l.constBegin(); it != l.constEnd(); ++it) {
                     KReportItemBase* itm = dynamic_cast(*it);
                     if (itm && itm->entityName() == name  && itm != ignore) {
                         unique = false;
                         break;
                     }
                 }
             }
         }
     }
     if (unique && d->detail) {
         sec = d->detail->detailSection();
         if (sec) {
             const QGraphicsItemList l = sec->items();
             for (QGraphicsItemList::const_iterator it = l.constBegin(); it != l.constEnd(); ++it) {
                 KReportItemBase* itm = dynamic_cast(*it);
                 if (itm && itm->entityName() == name  && itm != ignore) {
                     unique = false;
                     break;
                 }
             }
         }
     }
 
     return unique;
 }
 
 static bool actionPriortyLessThan(QAction* act1, QAction* act2)
 {
     if (act1->data().toInt() > 0 && act2->data().toInt() > 0) {
         return act1->data().toInt() < act2->data().toInt();
     }
     return false;
 }
 
 QList KReportDesigner::itemActions(QActionGroup* group)
 {
     KReportPluginManager* manager = KReportPluginManager::self();
     QList actList = manager->createActions(group);
 
     //! @todo make line a real plugin so this isn't needed:
     QAction *act = new QAction(QIcon::fromTheme(QLatin1String("kreport-line-element")), tr("Line"), group);
     act->setObjectName(QLatin1String("org.kde.kreport.line"));
     act->setData(9);
     act->setCheckable(true);
     actList << act;
 
     qSort(actList.begin(), actList.end(), actionPriortyLessThan);
     int i = 0;
 
     /*! @todo maybe this is a bit hackish
      It finds the first plugin based on the priority in userdata
      The lowest oriority a plugin can have is 10
      And inserts a separator before it. */
     bool sepInserted = false;
     foreach(QAction *a, actList) {
         ++i;
         if (!sepInserted && a->data().toInt() >= 10) {
             QAction *sep = new QAction(QLatin1String("separator"), group);
             sep->setSeparator(true);
             actList.insert(i-1, sep);
             sepInserted = true;
         }
         if (group) {
             group->addAction(a);
         }
     }
 
     return actList;
 }
 
 QList< QAction* > KReportDesigner::designerActions()
 {
     QList al;
     QAction *sep = new QAction(QString(), this);
     sep->setSeparator(true);
 
     al << d->editCutAction << d->editCopyAction << d->editPasteAction << d->editDeleteAction << sep << d->sectionEdit << sep << d->itemLowerAction << d->itemRaiseAction;
 
     return al;
 }
 
 void KReportDesigner::createActions()
 {
     d->editCutAction = new QAction(QIcon::fromTheme(QLatin1String("edit-cut")), tr("Cu&t"), this);
     d->editCutAction->setObjectName(QLatin1String("edit_cut"));
     d->editCutAction->setToolTip(tr("Cut selection to clipboard"));
     d->editCutAction->setShortcuts(KStandardShortcut::cut());
     d->editCutAction->setProperty("iconOnly", true);
 
     d->editCopyAction = new QAction(QIcon::fromTheme(QLatin1String("edit-copy")), tr("&Copy"), this);
     d->editCopyAction->setObjectName(QLatin1String("edit_copy"));
     d->editCopyAction->setToolTip(tr("Copy selection to clipboard"));
     d->editCopyAction->setShortcuts(KStandardShortcut::copy());
     d->editCopyAction->setProperty("iconOnly", true);
 
     d->editPasteAction = new QAction(QIcon::fromTheme(QLatin1String("edit-paste")), tr("&Paste"), this);
     d->editPasteAction->setObjectName(QLatin1String("edit_paste"));
     d->editPasteAction->setToolTip(tr("Paste clipboard content"));
     d->editPasteAction->setShortcuts(KStandardShortcut::paste());
     d->editPasteAction->setProperty("iconOnly", true);
 
     const KGuiItem del = KStandardGuiItem::del();
     d->editDeleteAction = new QAction(del.icon(), del.text(), this);
     d->editDeleteAction->setObjectName(QLatin1String("edit_delete"));
     d->editDeleteAction->setToolTip(del.toolTip());
     d->editDeleteAction->setWhatsThis(del.whatsThis());
     d->editDeleteAction->setProperty("iconOnly", true);
 
     d->sectionEdit = new QAction(tr("Edit Sections"), this);
     d->sectionEdit->setObjectName(QLatin1String("section_edit"));
 
     d->itemRaiseAction = new QAction(QIcon::fromTheme(QLatin1String("arrow-up")), tr("Raise"), this);
     d->itemRaiseAction->setObjectName(QLatin1String("item_raise"));
     d->itemLowerAction = new QAction(QIcon::fromTheme(QLatin1String("arrow-down")), tr("Lower"), this);
     d->itemLowerAction->setObjectName(QLatin1String("item_lower"));
 
     //Edit Actions
     connect(d->editCutAction, SIGNAL(triggered(bool)), this, SLOT(slotEditCut()));
     connect(d->editCopyAction, SIGNAL(triggered(bool)), this, SLOT(slotEditCopy()));
     connect(d->editPasteAction, SIGNAL(triggered(bool)), this, SLOT(slotEditPaste()));
     connect(d->editDeleteAction, SIGNAL(triggered(bool)), this, SLOT(slotEditDelete()));
 
     connect(d->sectionEdit, SIGNAL(triggered(bool)), this, SLOT(slotSectionEditor()));
 
     //Raise/Lower
     connect(d->itemRaiseAction, SIGNAL(triggered(bool)), this, SLOT(slotRaiseSelected()));
     connect(d->itemLowerAction, SIGNAL(triggered(bool)), this, SLOT(slotLowerSelected()));
 }
 
 void KReportDesigner::setSectionCursor(const QCursor& c)
 {
     if (d->pageFooterAny)
         d->pageFooterAny->setSectionCursor(c);
     if (d->pageFooterEven)
         d->pageFooterEven->setSectionCursor(c);
     if (d->pageFooterFirst)
         d->pageFooterFirst->setSectionCursor(c);
     if (d->pageFooterLast)
         d->pageFooterLast->setSectionCursor(c);
     if (d->pageFooterOdd)
         d->pageFooterOdd->setSectionCursor(c);
 
     if (d->pageHeaderAny)
         d->pageHeaderAny->setSectionCursor(c);
     if (d->pageHeaderEven)
         d->pageHeaderEven->setSectionCursor(c);
     if (d->pageHeaderFirst)
         d->pageHeaderFirst->setSectionCursor(c);
     if (d->pageHeaderLast)
         d->pageHeaderLast->setSectionCursor(c);
     if (d->pageHeaderOdd)
         d->pageHeaderOdd->setSectionCursor(c);
 
     if (d->detail)
         d->detail->setSectionCursor(c);
 }
 
 void KReportDesigner::unsetSectionCursor()
 {
     if (d->pageFooterAny)
         d->pageFooterAny->unsetSectionCursor();
     if (d->pageFooterEven)
         d->pageFooterEven->unsetSectionCursor();
     if (d->pageFooterFirst)
         d->pageFooterFirst->unsetSectionCursor();
     if (d->pageFooterLast)
         d->pageFooterLast->unsetSectionCursor();
     if (d->pageFooterOdd)
         d->pageFooterOdd->unsetSectionCursor();
 
     if (d->pageHeaderAny)
         d->pageHeaderAny->unsetSectionCursor();
     if (d->pageHeaderEven)
         d->pageHeaderEven->unsetSectionCursor();
     if (d->pageHeaderFirst)
         d->pageHeaderFirst->unsetSectionCursor();
     if (d->pageHeaderLast)
         d->pageHeaderLast->unsetSectionCursor();
     if (d->pageHeaderOdd)
         d->pageHeaderOdd->unsetSectionCursor();
 
     if (d->detail)
         d->detail->unsetSectionCursor();
 }
 
 qreal KReportDesigner::countSelectionHeight() const
 {
     if (d->releaseY == -1 || d->pressY == -1) {
         return -1;
     }
     return qAbs(d->releaseY - d->pressY);
 }
 
 qreal KReportDesigner::countSelectionWidth() const
 {
     if (d->releaseX == -1 || d->pressX == -1) {
         return -1;
     }
     return qAbs(d->releaseX - d->pressX);
 }
 
 qreal KReportDesigner::getSelectionPressX() const
 {
     return d->pressX;
 }
 
 qreal KReportDesigner::getSelectionPressY() const
 {
     return d->pressY;
 }
 
 QPointF KReportDesigner::getPressPoint() const
 {
     return QPointF(d->pressX, d->pressY);
 }
 
 QPointF KReportDesigner::getReleasePoint() const
 {
     return QPointF(d->releaseX, d->releaseY);
 }
 
 void KReportDesigner::plugItemActions(const QList &actList)
 {
     foreach(QAction *a, actList) {
         connect(a, SIGNAL(triggered(bool)), this, SLOT(slotItemTriggered(bool)));
     }
 }
 
 void KReportDesigner::slotItemTriggered(bool checked)
 {
     if (!checked) {
         return;
     }
     QObject *theSender = sender();
     if (!theSender) {
         return;
     }
     slotItem(theSender->objectName());
 }
 
 void KReportDesigner::addMetaProperties(KPropertySet* set, const QString &classString,
                                         const QString &iconName)
 {
     Q_ASSERT(set);
     KProperty *prop;
     set->addProperty(prop = new KProperty("this:classString", classString));
     prop->setVisible(false);
     set->addProperty(prop = new KProperty("this:iconName", iconName));
     prop->setVisible(false);
 }
diff --git a/src/wrtembed/KReportDesignerSectionScene.cpp b/src/wrtembed/KReportDesignerSectionScene.cpp
index d51d5a03..ba721ddb 100644
--- a/src/wrtembed/KReportDesignerSectionScene.cpp
+++ b/src/wrtembed/KReportDesignerSectionScene.cpp
@@ -1,258 +1,258 @@
 /* This file is part of the KDE project
  * Copyright (C) 2001-2007 by OpenMFG, LLC (info@openmfg.com)
  * Copyright (C) 2007-2008 by Adam Pigg (adam@piggz.co.uk)
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
  * This library is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
  * License along with this library.  If not, see .
  */
 
 #include "KReportDesignerSectionScene.h"
 #include "KReportDesignerItemRectBase.h"
 #include "KReportDesigner.h"
 #include "KReportLabelSizeInfo.h"
 #include "KReportUtils_p.h"
 #include "kreport_debug.h"
 
 #include 
 #include 
 #include 
 #include 
 
 KReportDesignerSectionScene::KReportDesignerSectionScene(qreal w, qreal h, KReportDesigner *rd)
         : QGraphicsScene(0, 0, w, h, rd), m_rd(rd)
 {
     m_dpiX = KReportPrivate::dpiX();
     m_dpiY = KReportPrivate::dpiY();
 
     if (m_unit.type() != m_rd->pageUnit().type()) {
         m_unit = m_rd->pageUnit();
-        if (m_unit.type() == KReportUnit::Cicero ||
-            m_unit.type() == KReportUnit::Pica ||
-            m_unit.type() == KReportUnit::Millimeter) {
+        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::Point) {
+        } 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;
         }
     }
 }
 KReportDesignerSectionScene::~KReportDesignerSectionScene()
 {
     // Qt should be handling everything for us
 }
 
 void KReportDesignerSectionScene::drawBackground(QPainter* painter, const QRectF & clip)
 {
     //Draw the default background colour
     QGraphicsScene::drawBackground(painter, clip);
     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::Cicero ||
-                m_unit.type() == KReportUnit::Pica ||
-                m_unit.type() == KReportUnit::Millimeter) {
+            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::Point) {
+            } 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);
 
         QPen pen = painter->pen();
         painter->setPen(Qt::lightGray);
 
         //kreportDebug() << "dpix" << KReportPrivate::dpiX() << "dpiy" << KReportPrivate::dpiY() << "mayorx:" << majorx << "majory" << majory << "pix:" << pixel_incrementx << "piy:" << pixel_incrementy;
 
         QVector lines;
         QVector points;
 
         if (m_pixelIncrementX > 2) { // do not bother painting points if increments are so small
             int wpoints = qRound(sceneRect().width() / m_pixelIncrementX);
             int hpoints = qRound(sceneRect().height() / m_pixelIncrementY);
             for (int i = 0; i < wpoints; ++i) {
                 for (int j = 0; j < hpoints; ++j) {
                     //if (clip.contains(i * pixel_incrementx, j * pixel_incrementy)){
                     if (i % minorSteps == 0 && j % minorSteps == 0) {
                         lines << QLine(QPoint(i * m_pixelIncrementX, j * m_pixelIncrementY), QPoint(i * m_pixelIncrementX, j * m_pixelIncrementY  + m_majorX));
                         //painter->drawLine();
                         lines << QLine(QPoint(i * m_pixelIncrementX, j * m_pixelIncrementY), QPoint(i * m_pixelIncrementX + m_majorY, j * m_pixelIncrementY));
                         //painter->drawLine();
                     } else {
                         points << QPoint(i * m_pixelIncrementX, j * m_pixelIncrementY);
                         //painter->drawPoint();
                     }
                     //}
                 }
             }
             painter->drawPoints(points);
             painter->drawLines(lines);
 
         }
 
         pen.setWidth(1);
         //update ( clip );
     }
 }
 
 void KReportDesignerSectionScene::mousePressEvent(QGraphicsSceneMouseEvent * e)
 {
     // clear the selection if Shift Key has not been pressed and it's a left mouse button   and
     // if the right mouse button has been pressed over an item which is not part of selected items
     if (((e->modifiers() & Qt::ShiftModifier) == 0 && e->button() == Qt::LeftButton)   ||
             (!(selectedItems().contains(itemAt(e->scenePos(), QTransform()))) && e->button() == Qt::RightButton))
         clearSelection();
 
     //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());
     }
     exitInlineEditingModeInItems(rectUnderCursor);
 
     QGraphicsScene::mousePressEvent(e);
 }
 
 void KReportDesignerSectionScene::contextMenuEvent(QGraphicsSceneContextMenuEvent * e)
 {
     m_rd->sectionContextMenuEvent(this, e);
 }
 
 QPointF KReportDesignerSectionScene::gridPoint(const QPointF& p)
 {
     if (!m_rd->propertySet()->property("grid-snap").value().toBool()) {
         return p;
     }
 
     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::Cicero ||
-                m_unit.type() == KReportUnit::Pica ||
-                m_unit.type() == KReportUnit::Millimeter) {
+            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::Point) {
+            } 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);
 
     return QPointF(qRound((p.x() / m_pixelIncrementX)) * m_pixelIncrementX, qRound((p.y() / m_pixelIncrementY)) * m_pixelIncrementY);
 }
 
 void KReportDesignerSectionScene::focusOutEvent(QFocusEvent * focusEvent)
 {
     exitInlineEditingModeInItems(nullptr);
 
     emit lostFocus();
     QGraphicsScene::focusOutEvent(focusEvent);
 }
 
 qreal KReportDesignerSectionScene::lowestZValue()
 {
     qreal z;
     qreal zz;
     z = 0;
     QGraphicsItemList list = items();
     for (QGraphicsItemList::iterator it = list.begin(); it != list.end(); ++it) {
         zz = (*it)->zValue();
         if (zz < z) {
             z = zz;
         }
 
     }
     return z;
 }
 
 qreal KReportDesignerSectionScene::highestZValue()
 {
     qreal z;
     qreal zz;
     z = 0;
     QGraphicsItemList list = items();
     for (QGraphicsItemList::iterator it = list.begin(); it != list.end(); ++it) {
         zz = (*it)->zValue();
         if (zz > z) {
             z = zz;
         }
     }
     return z;
 }
 
 void KReportDesignerSectionScene::lowerSelected()
 {
     QGraphicsItemList list = selectedItems();
     for (QGraphicsItemList::iterator it = list.begin();
             it != list.end(); ++it) {
         (*it)->setZValue(lowestZValue() - 1);
     }
 }
 
 void KReportDesignerSectionScene::raiseSelected()
 {
     QGraphicsItemList list = selectedItems();
     for (QGraphicsItemList::iterator it = list.begin();
             it != list.end(); ++it) {
         (*it)->setZValue(highestZValue() + 1);
     }
 }
 
 QGraphicsItemList KReportDesignerSectionScene::itemsOrdered() const
 {
     QGraphicsItemList r;
     QGraphicsItemList list = items();
     for (QGraphicsItemList::iterator it = list.begin(); it != list.end(); ++it) {
         for (QGraphicsItemList::iterator rit = r.begin(); rit != r.end(); ++rit) {
 
         }
     }
 
     return r;
 }
 
 void KReportDesignerSectionScene::exitInlineEditingModeInItems(KReportDesignerItemRectBase *rectUnderCursor)
 {
     foreach(QGraphicsItem *it, items()) {
         KReportDesignerItemRectBase *itm = qgraphicsitem_cast< KReportDesignerItemRectBase* >(it);
         if (itm && itm != rectUnderCursor) {
             itm->exitInlineEditingMode();
         }
     }
 }
diff --git a/src/wrtembed/KReportRuler_p.cpp b/src/wrtembed/KReportRuler_p.cpp
index 60cc9ea2..4561e801 100644
--- a/src/wrtembed/KReportRuler_p.cpp
+++ b/src/wrtembed/KReportRuler_p.cpp
@@ -1,1518 +1,1519 @@
 /* This file is part of the KDE project
    Copyright (C) 1998, 1999 Reginald Stadlbauer 
    Copyright (C) 2006 Peter Simonsson 
    Copyright (C) 2007 C. Boemann 
    Copyright (C) 2007-2008 Jan Hambrecht 
    Copyright (C) 2007 Thomas Zander 
 
    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Library General Public
    License as published by the Free Software Foundation; either
    version 2 of the License, or (at your option) any later version.
 
    This library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    Library General Public License for more details.
 
    You should have received a copy of the GNU Library General Public License
    along with this library; see the file COPYING.LIB.  If not, write to
    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
    Boston, MA 02110-1301, USA.
 */
 
 #include "KReportRuler_p.h"
+#include "KReportDesign_p.h"
 #include "KReportZoomHandler_p.h"
 
 #include 
 #include 
 #include 
 #include 
 
 // the distance in pixels of a mouse position considered outside the rule
 static const int OutsideRulerThreshold = 20;
 //
 static const int fullStepMarkerLength = 6;
 static const int halfStepMarkerLength = 6;
 static const int quarterStepMarkerLength = 3;
 static const int measurementTextAboveBelowMargin = 1;
 
 class RulerTabChooser : public QWidget
 {
 public:
     RulerTabChooser(QWidget *parent) : QWidget(parent), m_type(QTextOption::LeftTab), m_showTabs(false) {}
     ~RulerTabChooser() override {}
 
     inline QTextOption::TabType type() {return m_type;}
     void setShowTabs(bool showTabs) { if (m_showTabs == showTabs) return; m_showTabs = showTabs; update(); }
     void mousePressEvent(QMouseEvent *) override;
 
     void paintEvent(QPaintEvent *) override;
 
 private:
     QTextOption::TabType m_type;
     bool m_showTabs :1;
 };
 
 // ----
 
 class PaintingStrategy
 {
 public:
     /// constructor
     PaintingStrategy() {}
     /// destructor
     virtual ~PaintingStrategy() {}
 
     /**
      * Draw the background of the ruler.
      * @param ruler the ruler to draw on.
      * @param painter the painter we can paint with.
      */
     virtual QRectF drawBackground(const KReportRuler::Private *ruler, QPainter *painter) = 0;
 
     /**
      * Draw the indicators for text-tabs.
      * @param ruler the ruler to draw on.
      * @param painter the painter we can paint with.
      */
     virtual void drawTabs(const KReportRuler::Private *ruler, QPainter *painter) = 0;
 
     /**
      * Draw the indicators for the measurements which typically are drawn every [unit].
      * @param ruler the ruler to draw on.
      * @param painter the painter we can paint with.
      * @param rectangle
      */
     virtual void drawMeasurements(const KReportRuler::Private *ruler, QPainter *painter, const QRectF &rectangle) = 0;
 
     /**
      * Draw the indicators for the indents of a text paragraph
      * @param ruler the ruler to draw on.
      * @param painter the painter we can paint with.
      */
     virtual void drawIndents(const KReportRuler::Private *ruler, QPainter *painter) = 0;
 
     /**
      *returns the size suggestion for a ruler with this strategy.
      */
     virtual QSize sizeHint() = 0;
 };
 
 // ----
 
 class HorizontalPaintingStrategy : public PaintingStrategy
 {
 public:
     HorizontalPaintingStrategy() : lengthInPixel(1) {}
 
     QRectF drawBackground(const KReportRuler::Private *ruler, QPainter *painter) override;
     void drawTabs(const KReportRuler::Private *ruler, QPainter *painter) override;
     void drawMeasurements(const KReportRuler::Private *ruler, QPainter *painter, const QRectF &rectangle) override;
     void drawIndents(const KReportRuler::Private *ruler, QPainter *painter) override;
     QSize sizeHint() override;
 
 private:
     qreal lengthInPixel;
 };
 
 // ----
 
 class VerticalPaintingStrategy : public PaintingStrategy
 {
 public:
     VerticalPaintingStrategy() : lengthInPixel(1) {}
 
     QRectF drawBackground(const KReportRuler::Private *ruler, QPainter *painter) override;
     void drawTabs(const KReportRuler::Private *, QPainter *) override {}
     void drawMeasurements(const KReportRuler::Private *ruler, QPainter *painter, const QRectF &rectangle) override;
     void drawIndents(const KReportRuler::Private *, QPainter *) override {}
     QSize sizeHint() override;
 
 private:
     qreal lengthInPixel;
 };
 
 class HorizontalDistancesPaintingStrategy : public HorizontalPaintingStrategy
 {
 public:
     HorizontalDistancesPaintingStrategy() {}
 
     void drawMeasurements(const KReportRuler::Private *ruler, QPainter *painter, const QRectF &rectangle) override;
 
 private:
     void drawDistanceLine(const KReportRuler::Private *d, QPainter *painter, qreal start, qreal end);
 };
 
 // ----
 
 class KReportRuler::Private
 {
 public:
     Private(KReportRuler *parent, const KReportZoomHandler &zoomHandler, Qt::Orientation orientation);
     ~Private();
 
     void emitTabChanged();
 
     KReportUnit unit;
     const Qt::Orientation orientation;
     const KReportZoomHandler * const viewConverter;
 
     int offset;
     qreal rulerLength;
     qreal activeRangeStart;
     qreal activeRangeEnd;
     qreal activeOverrideRangeStart;
     qreal activeOverrideRangeEnd;
 
     int mouseCoordinate;
     int showMousePosition;
 
     bool showSelectionBorders;
     qreal firstSelectionBorder;
     qreal secondSelectionBorder;
 
     bool showIndents;
     qreal firstLineIndent;
     qreal paragraphIndent;
     qreal endIndent;
 
     bool showTabs;
     bool relativeTabs;
     bool tabMoved; // set to true on first move of a selected tab
     QList tabs;
     int originalIndex; //index of selected tab before we started dragging it.
     int currentIndex; //index of selected tab or selected HotSpot - only valid when selected indicates tab or hotspot
     KReportRuler::Tab deletedTab;
     qreal tabDistance;
 
     struct HotSpotData {
         qreal position;
         int id;
     };
     QList hotspots;
 
     bool rightToLeft;
     enum Selection {
         None,
         Tab,
         FirstLineIndent,
         ParagraphIndent,
         EndIndent,
         HotSpot
     };
     Selection selected;
     int selectOffset;
 
     QList popupActions;
 
     RulerTabChooser *tabChooser;
 
     // Cached painting strategies
     PaintingStrategy * normalPaintingStrategy;
     PaintingStrategy * distancesPaintingStrategy;
 
     // Current painting strategy
     PaintingStrategy * paintingStrategy;
 
     KReportRuler *ruler;
 
     qreal numberStepForUnit() const;
     /// @return The rounding of value to the nearest multiple of stepValue
     qreal doSnapping(qreal value) const;
     Selection selectionAtPosition(const QPoint &pos, int *selectOffset = nullptr);
     int hotSpotIndex(const QPoint &pos);
     qreal effectiveActiveRangeStart() const;
     qreal effectiveActiveRangeEnd() const;
 
     friend class VerticalPaintingStrategy;
     friend class HorizontalPaintingStrategy;
 };
 
 // ----
 
 void RulerTabChooser::mousePressEvent(QMouseEvent *)
 {
     if (! m_showTabs) {
         return;
     }
 
     switch(m_type) {
     case QTextOption::LeftTab:
         m_type = QTextOption::RightTab;
         break;
     case QTextOption::RightTab:
         m_type = QTextOption::CenterTab;
         break;
     case QTextOption::CenterTab:
         m_type = QTextOption::DelimiterTab;
         break;
     case QTextOption::DelimiterTab:
         m_type = QTextOption::LeftTab;
         break;
     }
     update();
 }
 
 void RulerTabChooser::paintEvent(QPaintEvent *)
 {
     if (! m_showTabs) {
         return;
     }
 
     QPainter painter(this);
     QPolygonF polygon;
 
     painter.setPen(palette().color(QPalette::Text));
     painter.setBrush(palette().color(QPalette::Text));
     painter.setRenderHint( QPainter::Antialiasing );
 
     qreal x = qreal(width())/2.0;
     painter.translate(0,-height()/2+5);
 
     switch (m_type) {
     case QTextOption::LeftTab:
         polygon << QPointF(x+0.5, height() - 8.5)
             << QPointF(x+6.5, height() - 2.5)
             << QPointF(x+0.5, height() - 2.5);
         painter.drawPolygon(polygon);
         break;
     case QTextOption::RightTab:
         polygon << QPointF(x+0.5, height() - 8.5)
             << QPointF(x-5.5, height() - 2.5)
             << QPointF(x+0.5, height() - 2.5);
         painter.drawPolygon(polygon);
         break;
     case QTextOption::CenterTab:
         polygon << QPointF(x+0.5, height() - 8.5)
             << QPointF(x-5.5, height() - 2.5)
             << QPointF(x+6.5, height() - 2.5);
         painter.drawPolygon(polygon);
         break;
     case QTextOption::DelimiterTab:
         polygon << QPointF(x-5.5, height() - 2.5)
             << QPointF(x+6.5, height() - 2.5);
         painter.drawPolyline(polygon);
         polygon << QPointF(x+0.5, height() - 2.5)
             << QPointF(x+0.5, height() - 8.5);
         painter.drawPolyline(polygon);
         break;
     default:
         break;
     }
 }
 
 static int compareTabs(const KReportRuler::Tab &tab1, const KReportRuler::Tab &tab2)
 {
     return tab1.position < tab2.position;
 }
 
 QRectF HorizontalPaintingStrategy::drawBackground(const KReportRuler::Private *d, QPainter *painter)
 {
     lengthInPixel = d->viewConverter->documentToViewX(d->rulerLength);
     QRectF rectangle;
     rectangle.setX(qMax(0, d->offset));
     rectangle.setY(0);
     rectangle.setWidth(qMin(qreal(d->ruler->width() - 1.0 - rectangle.x()),
                             (d->offset >= 0) ? lengthInPixel : lengthInPixel + d->offset));
     rectangle.setHeight(d->ruler->height() - 1);
     QRectF activeRangeRectangle;
     activeRangeRectangle.setX(qMax(rectangle.x() + 1,
           d->viewConverter->documentToViewX(d->effectiveActiveRangeStart()) + d->offset));
     activeRangeRectangle.setY(rectangle.y() + 1);
     activeRangeRectangle.setRight(qMin(rectangle.right() - 1,
           d->viewConverter->documentToViewX(d->effectiveActiveRangeEnd()) + d->offset));
     activeRangeRectangle.setHeight(rectangle.height() - 2);
 
     painter->setPen(d->ruler->palette().color(QPalette::Mid));
     painter->drawRect(rectangle);
 
     if(d->effectiveActiveRangeStart() != d->effectiveActiveRangeEnd())
         painter->fillRect(activeRangeRectangle, d->ruler->palette().brush(QPalette::Base));
 
     if(d->showSelectionBorders) {
         // Draw first selection border
         if(d->firstSelectionBorder > 0) {
             qreal border = d->viewConverter->documentToViewX(d->firstSelectionBorder) + d->offset;
             painter->drawLine(QPointF(border, rectangle.y() + 1), QPointF(border, rectangle.bottom() - 1));
         }
         // Draw second selection border
         if(d->secondSelectionBorder > 0) {
             qreal border = d->viewConverter->documentToViewX(d->secondSelectionBorder) + d->offset;
             painter->drawLine(QPointF(border, rectangle.y() + 1), QPointF(border, rectangle.bottom() - 1));
         }
     }
 
     return rectangle;
 }
 
 void HorizontalPaintingStrategy::drawTabs(const KReportRuler::Private *d, QPainter *painter)
 {
     if (! d->showTabs)
         return;
     QPolygonF polygon;
 
     const QColor tabColor = d->ruler->palette().color(QPalette::Text);
     painter->setPen(tabColor);
     painter->setBrush(tabColor);
     painter->setRenderHint( QPainter::Antialiasing );
 
     qreal position = -10000;
 
     foreach (const KReportRuler::Tab & t, d->tabs) {
         qreal x;
         if (d->rightToLeft) {
             x = d->viewConverter->documentToViewX(d->effectiveActiveRangeEnd()
                     - (d->relativeTabs ? d->paragraphIndent : 0) - t.position) + d->offset;
         } else {
             x = d->viewConverter->documentToViewX(d->effectiveActiveRangeStart()
                     + (d->relativeTabs ? d->paragraphIndent : 0) + t.position) + d->offset;
         }
         position = qMax(position, t.position);
 
         polygon.clear();
         switch (t.type) {
         case QTextOption::LeftTab:
             polygon << QPointF(x+0.5, d->ruler->height() - 6.5)
                 << QPointF(x+6.5, d->ruler->height() - 0.5)
                 << QPointF(x+0.5, d->ruler->height() - 0.5);
             painter->drawPolygon(polygon);
             break;
         case QTextOption::RightTab:
             polygon << QPointF(x+0.5, d->ruler->height() - 6.5)
                 << QPointF(x-5.5, d->ruler->height() - 0.5)
                 << QPointF(x+0.5, d->ruler->height() - 0.5);
             painter->drawPolygon(polygon);
             break;
         case QTextOption::CenterTab:
             polygon << QPointF(x+0.5, d->ruler->height() - 6.5)
                 << QPointF(x-5.5, d->ruler->height() - 0.5)
                 << QPointF(x+6.5, d->ruler->height() - 0.5);
             painter->drawPolygon(polygon);
             break;
         case QTextOption::DelimiterTab:
             polygon << QPointF(x-5.5, d->ruler->height() - 0.5)
                 << QPointF(x+6.5, d->ruler->height() - 0.5);
             painter->drawPolyline(polygon);
             polygon << QPointF(x+0.5, d->ruler->height() - 0.5)
                 << QPointF(x+0.5, d->ruler->height() - 6.5);
             painter->drawPolyline(polygon);
             break;
         default:
             break;
         }
     }
 
     // and also draw the regular interval tab that are non editable
     if (d->tabDistance > 0.0) {
         // first possible position
         position = qMax(position, d->relativeTabs ? 0 : d->paragraphIndent);
         if (position < 0) {
             position = int(position / d->tabDistance) * d->tabDistance;
         } else {
             position = (int(position / d->tabDistance) + 1) * d->tabDistance;
         }
         while (position < d->effectiveActiveRangeEnd() - d->effectiveActiveRangeStart()
                 - d->endIndent) {
             qreal x;
             if (d->rightToLeft) {
                 x = d->viewConverter->documentToViewX(d->effectiveActiveRangeEnd()
                         - (d->relativeTabs ? d->paragraphIndent : 0) - position) + d->offset;
             } else {
                 x = d->viewConverter->documentToViewX(d->effectiveActiveRangeStart()
                         + (d->relativeTabs ? d->paragraphIndent : 0) + position) + d->offset;
             }
 
             polygon.clear();
             polygon << QPointF(x+0.5, d->ruler->height() - 3.5)
                 << QPointF(x+4.5, d->ruler->height() - 0.5)
                 << QPointF(x+0.5, d->ruler->height() - 0.5);
             painter->drawPolygon(polygon);
 
             position += d->tabDistance;
         }
     }
 }
 
 void HorizontalPaintingStrategy::drawMeasurements(const KReportRuler::Private *d, QPainter *painter, const QRectF &rectangle)
 {
     qreal numberStep = d->numberStepForUnit(); // number step in unit
 //    QRectF activeRangeRectangle;
     int numberStepPixel = qRound(d->viewConverter->documentToViewX(d->unit.fromUserValue(numberStep)));
 //    const bool adjustMillimeters = (d->unit.type() == KReportUnit::Millimeter);
 
     const QFont font = QFontDatabase::systemFont(QFontDatabase::SmallestReadableFont);
     const QFontMetrics fontMetrics(font);
     painter->setFont(font);
 
     if (numberStepPixel == 0 || numberStep == 0)
         return;
 
     // Calc the longest text length
     int textLength = 0;
     for(int i = 0; i < lengthInPixel; i += numberStepPixel) {
         int number = qRound((i / numberStepPixel) * numberStep);
 
         textLength = qMax(textLength, fontMetrics.width(QString::number(number)));
     }
     textLength += 4;  // Add some padding
 
     // Change number step so all digits fits
     while(textLength > numberStepPixel) {
         numberStepPixel += numberStepPixel;
         numberStep += numberStep;
     }
 
     int start=0;
     // Calc the first number step
     if(d->offset < 0)
         start = qAbs(d->offset);
 
     // make a little hack so rulers shows correctly inversed number aligned
     const qreal lengthInUnit = d->unit.toUserValue(d->rulerLength);
     const qreal hackyLength = lengthInUnit - fmod(lengthInUnit, numberStep);
     if(d->rightToLeft) {
         start -= int(d->viewConverter->documentToViewX(fmod(d->rulerLength,
                     d->unit.fromUserValue(numberStep))));
     }
 
     int stepCount = (start / numberStepPixel) + 1;
     int halfStepCount = (start / qRound(numberStepPixel * 0.5)) + 1;
     int quarterStepCount = (start / qRound(numberStepPixel * 0.25)) + 1;
 
     int pos = 0;
     const QPen numberPen(d->ruler->palette().color(QPalette::Text));
     const QPen markerPen(d->ruler->palette().color(QPalette::Inactive, QPalette::Text));
     painter->setPen(markerPen);
 
     if(d->offset > 0)
         painter->translate(d->offset, 0);
 
     const int len = qRound(rectangle.width()) + start;
     int nextStep = qRound(d->viewConverter->documentToViewX(
         d->unit.fromUserValue(numberStep * stepCount)));
     int nextHalfStep = qRound(d->viewConverter->documentToViewX(d->unit.fromUserValue(
         numberStep * 0.5 * halfStepCount)));
     int nextQuarterStep = qRound(d->viewConverter->documentToViewX(d->unit.fromUserValue(
         numberStep * 0.25 * quarterStepCount)));
 
     for(int i = start; i < len; ++i) {
         pos = i - start;
 
         if(i == nextStep) {
             if(pos != 0)
                 painter->drawLine(QPointF(pos, rectangle.bottom()-1),
                                  QPointF(pos, rectangle.bottom() - fullStepMarkerLength));
 
             int number = qRound(stepCount * numberStep);
 
             QString numberText = QString::number(number);
             int x = pos;
             if (d->rightToLeft) { // this is done in a hacky way with the fine tuning done above
                 numberText = QString::number(hackyLength - stepCount * numberStep);
             }
             painter->setPen(numberPen);
             painter->drawText(QPointF(x-fontMetrics.width(numberText)/2.0,
                                      rectangle.bottom() -fullStepMarkerLength -measurementTextAboveBelowMargin),
                              numberText);
             painter->setPen(markerPen);
 
             ++stepCount;
             nextStep = qRound(d->viewConverter->documentToViewX(
                 d->unit.fromUserValue(numberStep * stepCount)));
             ++halfStepCount;
             nextHalfStep = qRound(d->viewConverter->documentToViewX(d->unit.fromUserValue(
                 numberStep * 0.5 * halfStepCount)));
             ++quarterStepCount;
             nextQuarterStep = qRound(d->viewConverter->documentToViewX(d->unit.fromUserValue(
                 numberStep * 0.25 * quarterStepCount)));
         }
         else if(i == nextHalfStep) {
             if(pos != 0)
                 painter->drawLine(QPointF(pos, rectangle.bottom()-1),
                                  QPointF(pos, rectangle.bottom() - halfStepMarkerLength));
 
             ++halfStepCount;
             nextHalfStep = qRound(d->viewConverter->documentToViewX(d->unit.fromUserValue(
                 numberStep * 0.5 * halfStepCount)));
             ++quarterStepCount;
             nextQuarterStep = qRound(d->viewConverter->documentToViewX(d->unit.fromUserValue(
                 numberStep * 0.25 * quarterStepCount)));
         }
         else if(i == nextQuarterStep) {
             if(pos != 0)
                 painter->drawLine(QPointF(pos, rectangle.bottom()-1),
                                  QPointF(pos, rectangle.bottom() - quarterStepMarkerLength));
 
             ++quarterStepCount;
             nextQuarterStep = qRound(d->viewConverter->documentToViewX(d->unit.fromUserValue(
                 numberStep * 0.25 * quarterStepCount)));
         }
     }
 
     // Draw the mouse indicator
     const int mouseCoord = d->mouseCoordinate - start;
     if (d->selected == KReportRuler::Private::None || d->selected == KReportRuler::Private::HotSpot) {
         const qreal top = rectangle.y() + 1;
         const qreal bottom = rectangle.bottom() -1;
         if (d->selected == KReportRuler::Private::None && d->showMousePosition && mouseCoord > 0 && mouseCoord < rectangle.width() )
             painter->drawLine(QPointF(mouseCoord, top), QPointF(mouseCoord, bottom));
         foreach (const KReportRuler::Private::HotSpotData & hp, d->hotspots) {
             const qreal x = d->viewConverter->documentToViewX(hp.position) + d->offset;
             painter->drawLine(QPointF(x, top), QPointF(x, bottom));
         }
     }
 }
 
 void HorizontalPaintingStrategy::drawIndents(const KReportRuler::Private *d, QPainter *painter)
 {
     QPolygonF polygon;
 
     painter->setBrush(d->ruler->palette().brush(QPalette::Base));
     painter->setRenderHint( QPainter::Antialiasing );
 
     qreal x;
     // Draw first line start indent
     if (d->rightToLeft)
         x = d->effectiveActiveRangeEnd() - d->firstLineIndent - d->paragraphIndent;
     else
         x = d->effectiveActiveRangeStart() + d->firstLineIndent + d->paragraphIndent;
     // convert and use the +0.5 to go to nearest integer so that the 0.5 added below ensures sharp lines
     x = int(d->viewConverter->documentToViewX(x) + d->offset + 0.5);
     polygon << QPointF(x+6.5, 0.5)
         << QPointF(x+0.5, 8.5)
         << QPointF(x-5.5, 0.5)
         << QPointF(x+5.5, 0.5);
     painter->drawPolygon(polygon);
 
     // draw the hanging indent.
     if (d->rightToLeft)
         x = d->effectiveActiveRangeStart() + d->endIndent;
     else
         x = d->effectiveActiveRangeStart() + d->paragraphIndent;
     // convert and use the +0.5 to go to nearest integer so that the 0.5 added below ensures sharp lines
     x = int(d->viewConverter->documentToViewX(x) + d->offset + 0.5);
     const int bottom = d->ruler->height();
     polygon.clear();
     polygon << QPointF(x+6.5, bottom - 0.5)
         << QPointF(x+0.5, bottom - 8.5)
         << QPointF(x-5.5, bottom - 0.5)
         << QPointF(x+5.5, bottom - 0.5);
     painter->drawPolygon(polygon);
 
     // Draw end-indent or paragraph indent if mode is rightToLeft
     qreal diff;
     if (d->rightToLeft)
         diff = d->viewConverter->documentToViewX(d->effectiveActiveRangeEnd()
                      - d->paragraphIndent) + d->offset - x;
     else
         diff = d->viewConverter->documentToViewX(d->effectiveActiveRangeEnd() - d->endIndent)
                 + d->offset - x;
     polygon.translate(diff, 0);
     painter->drawPolygon(polygon);
 }
 
 QSize HorizontalPaintingStrategy::sizeHint()
 {
     // assumes that digits for the number only use glyphs which do not go below the baseline
     const QFontMetrics fm(QFontDatabase::systemFont(QFontDatabase::SmallestReadableFont));
     const int digitsHeight = fm.ascent() + 1; // +1 for baseline
     const int minimum = digitsHeight + fullStepMarkerLength + 2*measurementTextAboveBelowMargin;
 
     return QSize(0, minimum);
 }
 
 QRectF VerticalPaintingStrategy::drawBackground(const KReportRuler::Private *d, QPainter *painter)
 {
     lengthInPixel = d->viewConverter->documentToViewY(d->rulerLength);
     QRectF rectangle;
     rectangle.setX(0);
     rectangle.setY(qMax(0, d->offset));
     rectangle.setWidth(d->ruler->width() - 1.0);
     rectangle.setHeight(qMin(qreal(d->ruler->height() - 1.0 - rectangle.y()),
                              (d->offset >= 0) ? lengthInPixel : lengthInPixel + d->offset));
 
     QRectF activeRangeRectangle;
     activeRangeRectangle.setX(rectangle.x() + 1);
     activeRangeRectangle.setY(qMax(rectangle.y() + 1,
         d->viewConverter->documentToViewY(d->effectiveActiveRangeStart()) + d->offset));
     activeRangeRectangle.setWidth(rectangle.width() - 2);
     activeRangeRectangle.setBottom(qMin(rectangle.bottom() - 1,
         d->viewConverter->documentToViewY(d->effectiveActiveRangeEnd()) + d->offset));
 
     painter->setPen(d->ruler->palette().color(QPalette::Mid));
     painter->drawRect(rectangle);
 
     if(d->effectiveActiveRangeStart() != d->effectiveActiveRangeEnd())
         painter->fillRect(activeRangeRectangle, d->ruler->palette().brush(QPalette::Base));
 
     if(d->showSelectionBorders) {
         // Draw first selection border
         if(d->firstSelectionBorder > 0) {
             qreal border = d->viewConverter->documentToViewY(d->firstSelectionBorder) + d->offset;
             painter->drawLine(QPointF(rectangle.x() + 1, border), QPointF(rectangle.right() - 1, border));
         }
         // Draw second selection border
         if(d->secondSelectionBorder > 0) {
             qreal border = d->viewConverter->documentToViewY(d->secondSelectionBorder) + d->offset;
             painter->drawLine(QPointF(rectangle.x() + 1, border), QPointF(rectangle.right() - 1, border));
         }
     }
 
     return rectangle;
 }
 
 void VerticalPaintingStrategy::drawMeasurements(const KReportRuler::Private *d, QPainter *painter, const QRectF &rectangle)
 {
     qreal numberStep = d->numberStepForUnit(); // number step in unit
     int numberStepPixel = qRound(d->viewConverter->documentToViewY( d->unit.fromUserValue(numberStep)));
     if (numberStepPixel <= 0)
         return;
 
     const QFont font = QFontDatabase::systemFont(QFontDatabase::SmallestReadableFont);
     const QFontMetrics fontMetrics(font);
     painter->setFont(font);
 
     // Calc the longest text length
     int textLength = 0;
 
     for(int i = 0; i < lengthInPixel; i += numberStepPixel) {
         int number = qRound((i / numberStepPixel) * numberStep);
         textLength = qMax(textLength, fontMetrics.width(QString::number(number)));
     }
     textLength += 4;  // Add some padding
 
     if (numberStepPixel == 0 || numberStep == 0)
         return;
     // Change number step so all digits will fit
     while(textLength > numberStepPixel) {
         numberStepPixel += numberStepPixel;
         numberStep += numberStep;
     }
 
     // Calc the first number step
     const int start = d->offset < 0 ? qAbs(d->offset) : 0;
 
     // make a little hack so rulers shows correctly inversed number aligned
     int stepCount = (start / numberStepPixel) + 1;
     int halfStepCount = (start / qRound(numberStepPixel * 0.5)) + 1;
     int quarterStepCount = (start / qRound(numberStepPixel * 0.25)) + 1;
 
     const QPen numberPen(d->ruler->palette().color(QPalette::Text));
     const QPen markerPen(d->ruler->palette().color(QPalette::Inactive, QPalette::Text));
     painter->setPen(markerPen);
 
     if(d->offset > 0)
         painter->translate(0, d->offset);
 
     const int len = qRound(rectangle.height()) + start;
     int nextStep = qRound(d->viewConverter->documentToViewY(
         d->unit.fromUserValue(numberStep * stepCount)));
     int nextHalfStep = qRound(d->viewConverter->documentToViewY(d->unit.fromUserValue(
         numberStep * 0.5 * halfStepCount)));
     int nextQuarterStep = qRound(d->viewConverter->documentToViewY(d->unit.fromUserValue(
         numberStep * 0.25 * quarterStepCount)));
 
     int pos = 0;
     for(int i = start; i < len; ++i) {
         pos = i - start;
 
         if(i == nextStep) {
             painter->save();
             painter->translate(rectangle.right()-fullStepMarkerLength, pos);
             if(pos != 0)
                 painter->drawLine(QPointF(0, 0), QPointF(fullStepMarkerLength-1, 0));
 
             painter->rotate(-90);
             int number = qRound(stepCount * numberStep);
             QString numberText = QString::number(number);
             painter->setPen(numberPen);
             painter->drawText(QPointF(-fontMetrics.width(numberText) / 2.0, -measurementTextAboveBelowMargin), numberText);
             painter->restore();
 
             ++stepCount;
             nextStep = qRound(d->viewConverter->documentToViewY(
                 d->unit.fromUserValue(numberStep * stepCount)));
             ++halfStepCount;
             nextHalfStep = qRound(d->viewConverter->documentToViewY(d->unit.fromUserValue(
                 numberStep * 0.5 * halfStepCount)));
             ++quarterStepCount;
             nextQuarterStep = qRound(d->viewConverter->documentToViewY(d->unit.fromUserValue(
                 numberStep * 0.25 * quarterStepCount)));
         } else if(i == nextHalfStep) {
             if(pos != 0)
                 painter->drawLine(QPointF(rectangle.right() - halfStepMarkerLength, pos),
                                  QPointF(rectangle.right() - 1, pos));
 
             ++halfStepCount;
             nextHalfStep = qRound(d->viewConverter->documentToViewY(d->unit.fromUserValue(
                 numberStep * 0.5 * halfStepCount)));
             ++quarterStepCount;
             nextQuarterStep = qRound(d->viewConverter->documentToViewY(d->unit.fromUserValue(
                 numberStep * 0.25 * quarterStepCount)));
         } else if(i == nextQuarterStep) {
             if(pos != 0)
                 painter->drawLine(QPointF(rectangle.right() - quarterStepMarkerLength, pos),
                                  QPointF(rectangle.right() - 1, pos));
 
             ++quarterStepCount;
             nextQuarterStep = qRound(d->viewConverter->documentToViewY(d->unit.fromUserValue(
                 numberStep * 0.25 * quarterStepCount)));
         }
     }
 
     // Draw the mouse indicator
     const int mouseCoord = d->mouseCoordinate - start;
     if (d->selected == KReportRuler::Private::None || d->selected == KReportRuler::Private::HotSpot) {
         const qreal left = rectangle.left() + 1;
         const qreal right = rectangle.right() -1;
         if (d->selected == KReportRuler::Private::None && d->showMousePosition && mouseCoord > 0 && mouseCoord < rectangle.height() )
             painter->drawLine(QPointF(left, mouseCoord), QPointF(right, mouseCoord));
         foreach (const KReportRuler::Private::HotSpotData & hp, d->hotspots) {
             const qreal y = d->viewConverter->documentToViewY(hp.position) + d->offset;
             painter->drawLine(QPointF(left, y), QPointF(right, y));
         }
     }
 }
 
 QSize VerticalPaintingStrategy::sizeHint()
 {
     // assumes that digits for the number only use glyphs which do not go below the baseline
     const QFontMetrics fm(QFontDatabase::systemFont(QFontDatabase::SmallestReadableFont));
     const int digitsHeight = fm.ascent() + 1; // +1 for baseline
     const int minimum = digitsHeight + fullStepMarkerLength + 2*measurementTextAboveBelowMargin;
 
     return QSize(minimum, 0);
 }
 
 
 void HorizontalDistancesPaintingStrategy::drawDistanceLine(const KReportRuler::Private *d,
                                                            QPainter *painter, qreal start,
                                                            qreal end)
 {
 
     // Don't draw too short lines
     if (qMax(start, end) - qMin(start, end) < 1)
         return;
 
     painter->save();
     painter->translate(d->offset, d->ruler->height() / 2);
     painter->setPen(d->ruler->palette().color(QPalette::Text));
     painter->setBrush(d->ruler->palette().color(QPalette::Text));
 
     QLineF line(QPointF(d->viewConverter->documentToViewX(start), 0),
             QPointF(d->viewConverter->documentToViewX(end), 0));
     QPointF midPoint = line.pointAt(0.5);
 
     // Draw the label text
     const QFont font = QFontDatabase::systemFont(QFontDatabase::SmallestReadableFont);
     const QFontMetrics fontMetrics(font);
     QString label = d->unit.toUserStringValue(
             d->viewConverter->viewToDocumentX(line.length())) + QLatin1String("") + d->unit.symbol();
     QPointF labelPosition = QPointF(midPoint.x() - fontMetrics.width(label)/2,
             midPoint.y() + fontMetrics.ascent()/2);
     painter->setFont(font);
     painter->drawText(labelPosition, label);
 
     // Draw the arrow lines
     qreal arrowLength = (line.length() - fontMetrics.width(label)) / 2 - 2;
     arrowLength = qMax(qreal(0.0), arrowLength);
     QLineF startArrow(line.p1(), line.pointAt(arrowLength / line.length()));
     QLineF endArrow(line.p2(), line.pointAt(1.0 - arrowLength / line.length()));
     painter->drawLine(startArrow);
     painter->drawLine(endArrow);
 
     // Draw the arrow heads
     QPolygonF arrowHead;
     arrowHead << line.p1() << QPointF(line.x1()+3, line.y1()-3)
         << QPointF(line.x1()+3, line.y1()+3);
     painter->drawPolygon(arrowHead);
     arrowHead.clear();
     arrowHead << line.p2() << QPointF(line.x2()-3, line.y2()-3)
         << QPointF(line.x2()-3, line.y2()+3);
     painter->drawPolygon(arrowHead);
 
     painter->restore();
 }
 
 void HorizontalDistancesPaintingStrategy::drawMeasurements(const KReportRuler::Private *d,
                                                            QPainter *painter, const QRectF&)
 {
     QList points;
     points << 0.0;
     points << d->effectiveActiveRangeStart() + d->paragraphIndent + d->firstLineIndent;
     points << d->effectiveActiveRangeStart() + d->paragraphIndent;
     points << d->effectiveActiveRangeEnd() - d->endIndent;
     points << d->effectiveActiveRangeStart();
     points << d->effectiveActiveRangeEnd();
     points << d->rulerLength;
     qSort(points.begin(), points.end());
     QListIterator i(points);
     i.next();
     while (i.hasNext() && i.hasPrevious()) {
         drawDistanceLine(d, painter, i.peekPrevious(), i.peekNext());
         i.next();
     }
 }
 
 KReportRuler::Private::Private(KReportRuler *parent,
                                          const KReportZoomHandler &zoomHandler, Qt::Orientation o)
-    : unit(KReportUnit(KReportUnit::Point)),
+    : unit(DEFAULT_UNIT),
     orientation(o),
     viewConverter(&zoomHandler),
     offset(0),
     rulerLength(0),
     activeRangeStart(0),
     activeRangeEnd(0),
     activeOverrideRangeStart(0),
     activeOverrideRangeEnd(0),
     mouseCoordinate(-1),
     showMousePosition(0),
     showSelectionBorders(false),
     firstSelectionBorder(0),
     secondSelectionBorder(0),
     showIndents(false),
     firstLineIndent(0),
     paragraphIndent(0),
     endIndent(0),
     showTabs(false),
     relativeTabs(false),
     tabMoved(false),
     originalIndex(-1),
     currentIndex(0),
     tabDistance(0.0),
     rightToLeft(false),
     selected(None),
     selectOffset(0),
     tabChooser(nullptr),
     normalPaintingStrategy(o == Qt::Horizontal ?
             (PaintingStrategy*)new HorizontalPaintingStrategy() : (PaintingStrategy*)new VerticalPaintingStrategy()),
     distancesPaintingStrategy((PaintingStrategy*)new HorizontalDistancesPaintingStrategy()),
     paintingStrategy(normalPaintingStrategy),
     ruler(parent)
 {
 }
 
 KReportRuler::Private::~Private()
 {
     delete normalPaintingStrategy;
     delete distancesPaintingStrategy;
 }
 
 qreal KReportRuler::Private::numberStepForUnit() const
 {
     switch(unit.type()) {
-        case KReportUnit::Inch:
-        case KReportUnit::Centimeter:
-        case KReportUnit::Decimeter:
-        case KReportUnit::Millimeter:
+        case KReportUnit::Type::Inch:
+        case KReportUnit::Type::Centimeter:
+        case KReportUnit::Type::Decimeter:
+        case KReportUnit::Type::Millimeter:
             return 1.0;
-        case KReportUnit::Pica:
-        case KReportUnit::Cicero:
+        case KReportUnit::Type::Pica:
+        case KReportUnit::Type::Cicero:
             return 10.0;
-        case KReportUnit::Point:
+        case KReportUnit::Type::Point:
         default:
             return 100.0;
     }
 }
 
 qreal KReportRuler::Private::doSnapping(qreal value) const
 {
     qreal numberStep = unit.fromUserValue(numberStepForUnit()/4.0);
     return numberStep * qRound(value / numberStep);
 }
 
 KReportRuler::Private::Selection KReportRuler::Private::selectionAtPosition(const QPoint & pos, int *selectOffset )
 {
     const int height = ruler->height();
     if (rightToLeft) {
         int x = int(viewConverter->documentToViewX(effectiveActiveRangeEnd() - firstLineIndent - paragraphIndent) + offset);
         if (pos.x() >= x - 8 && pos.x() <= x +8 && pos.y() < height / 2) {
             if (selectOffset)
                 *selectOffset = x - pos.x();
             return KReportRuler::Private::FirstLineIndent;
         }
 
         x = int(viewConverter->documentToViewX(effectiveActiveRangeEnd() - paragraphIndent) + offset);
         if (pos.x() >= x - 8 && pos.x() <= x +8 && pos.y() > height / 2) {
             if (selectOffset)
                 *selectOffset = x - pos.x();
             return KReportRuler::Private::ParagraphIndent;
         }
 
         x = int(viewConverter->documentToViewX(effectiveActiveRangeStart() + endIndent) + offset);
         if (pos.x() >= x - 8 && pos.x() <= x + 8) {
             if (selectOffset)
                 *selectOffset = x - pos.x();
             return KReportRuler::Private::EndIndent;
         }
     }
     else {
         int x = int(viewConverter->documentToViewX(effectiveActiveRangeStart() + firstLineIndent + paragraphIndent) + offset);
         if (pos.x() >= x -8 && pos.x() <= x + 8 && pos.y() < height / 2) {
             if (selectOffset)
                 *selectOffset = x - pos.x();
             return KReportRuler::Private::FirstLineIndent;
         }
 
         x = int(viewConverter->documentToViewX(effectiveActiveRangeStart() + paragraphIndent) + offset);
         if (pos.x() >= x - 8 && pos.x() <= x + 8 && pos.y() > height/2) {
             if (selectOffset)
                 *selectOffset = x - pos.x();
             return KReportRuler::Private::ParagraphIndent;
         }
 
         x = int(viewConverter->documentToViewX(effectiveActiveRangeEnd() - endIndent) + offset);
         if (pos.x() >= x - 8 && pos.x() <= x + 8) {
             if (selectOffset)
                 *selectOffset = x - pos.x();
             return KReportRuler::Private::EndIndent;
         }
     }
 
     return KReportRuler::Private::None;
 }
 
 int KReportRuler::Private::hotSpotIndex(const QPoint & pos)
 {
     for(int counter = 0; counter < hotspots.count(); counter++) {
         bool hit;
         if (orientation == Qt::Horizontal)
             hit = qAbs(viewConverter->documentToViewX(hotspots[counter].position) - pos.x() + offset) < 3;
         else
             hit = qAbs(viewConverter->documentToViewY(hotspots[counter].position) - pos.y() + offset) < 3;
 
         if (hit)
             return counter;
     }
     return -1;
 }
 
 qreal KReportRuler::Private::effectiveActiveRangeStart() const
 {
     if (activeOverrideRangeStart != activeOverrideRangeEnd) {
         return activeOverrideRangeStart;
     } else {
         return activeRangeStart;
     }
 }
 
 qreal KReportRuler::Private::effectiveActiveRangeEnd() const
 {
     if (activeOverrideRangeStart != activeOverrideRangeEnd) {
         return activeOverrideRangeEnd;
     } else {
         return activeRangeEnd;
     }
 }
 
 void KReportRuler::Private::emitTabChanged()
 {
     KReportRuler::Tab tab;
     if (currentIndex >= 0)
         tab = tabs[currentIndex];
     emit ruler->tabChanged(originalIndex, currentIndex >= 0 ? &tab : nullptr);
 }
 
 
 KReportRuler::KReportRuler(QWidget* parent, Qt::Orientation orientation,
                            const KReportZoomHandler &zoomHandler)
   : QWidget(parent)
   , d(new KReportRuler::Private(this, zoomHandler, orientation))
 {
     setMouseTracking( true );
 }
 
 KReportRuler::~KReportRuler()
 {
     delete d;
 }
 
 KReportUnit KReportRuler::unit() const
 {
     return d->unit;
 }
 
 void KReportRuler::setUnit(const KReportUnit &unit)
 {
     d->unit = unit;
     update();
 }
 
 qreal KReportRuler::rulerLength() const
 {
     return d->rulerLength;
 }
 
 Qt::Orientation KReportRuler::orientation() const
 {
     return d->orientation;
 }
 
 void KReportRuler::setOffset(int offset)
 {
     d->offset = offset;
     update();
 }
 
 void KReportRuler::setRulerLength(qreal length)
 {
     d->rulerLength = length;
     update();
 }
 
 void KReportRuler::paintEvent(QPaintEvent* event)
 {
     QPainter painter(this);
     painter.setClipRegion(event->region());
     painter.save();
     QRectF rectangle = d->paintingStrategy->drawBackground(d, &painter);
     painter.restore();
     painter.save();
     d->paintingStrategy->drawMeasurements(d, &painter, rectangle);
     painter.restore();
     if (d->showIndents) {
         painter.save();
         d->paintingStrategy->drawIndents(d, &painter);
         painter.restore();
     }
     d->paintingStrategy->drawTabs(d, &painter);
 }
 
 QSize KReportRuler::minimumSizeHint() const
 {
     return d->paintingStrategy->sizeHint();
 }
 
 QSize KReportRuler::sizeHint() const
 {
     return d->paintingStrategy->sizeHint();
 }
 
 void KReportRuler::setActiveRange(qreal start, qreal end)
 {
     d->activeRangeStart = start;
     d->activeRangeEnd = end;
     update();
 }
 
 void KReportRuler::setOverrideActiveRange(qreal start, qreal end)
 {
     d->activeOverrideRangeStart = start;
     d->activeOverrideRangeEnd = end;
     update();
 }
 
 void KReportRuler::updateMouseCoordinate(int coordinate)
 {
     if(d->mouseCoordinate == coordinate)
         return;
     d->mouseCoordinate = coordinate;
     update();
 }
 
 void KReportRuler::setShowMousePosition(bool show)
 {
     d->showMousePosition = show;
     update();
 }
 
 void KReportRuler::setRightToLeft(bool isRightToLeft)
 {
     d->rightToLeft = isRightToLeft;
     update();
 }
 
 void KReportRuler::setShowIndents(bool show)
 {
     d->showIndents = show;
     update();
 }
 
 void KReportRuler::setFirstLineIndent(qreal indent)
 {
     d->firstLineIndent = indent;
     if (d->showIndents) {
         update();
     }
 }
 
 void KReportRuler::setParagraphIndent(qreal indent)
 {
     d->paragraphIndent = indent;
     if (d->showIndents) {
         update();
     }
 }
 
 void KReportRuler::setEndIndent(qreal indent)
 {
     d->endIndent = indent;
     if (d->showIndents) {
         update();
     }
 }
 
 qreal KReportRuler::firstLineIndent() const
 {
     return d->firstLineIndent;
 }
 
 qreal KReportRuler::paragraphIndent() const
 {
     return d->paragraphIndent;
 }
 
 qreal KReportRuler::endIndent() const
 {
     return d->endIndent;
 }
 
 QWidget *KReportRuler::tabChooser()
 {
     if ((d->tabChooser == nullptr) && (d->orientation == Qt::Horizontal)) {
         d->tabChooser = new RulerTabChooser(parentWidget());
         d->tabChooser->setShowTabs(d->showTabs);
     }
 
     return d->tabChooser;
 }
 
 void KReportRuler::setShowSelectionBorders(bool show)
 {
     d->showSelectionBorders = show;
     update();
 }
 
 void KReportRuler::updateSelectionBorders(qreal first, qreal second)
 {
     d->firstSelectionBorder = first;
     d->secondSelectionBorder = second;
 
     if(d->showSelectionBorders)
         update();
 }
 
 void KReportRuler::setShowTabs(bool show)
 {
     if (d->showTabs == show) {
         return;
     }
 
     d->showTabs = show;
     if (d->tabChooser) {
         d->tabChooser->setShowTabs(show);
     }
     update();
 }
 
 void KReportRuler::setRelativeTabs(bool relative)
 {
     d->relativeTabs = relative;
     if (d->showTabs) {
         update();
     }
 }
 
 void KReportRuler::updateTabs(const QList &tabs, qreal tabDistance)
 {
     d->tabs = tabs;
     d->tabDistance = tabDistance;
     if (d->showTabs) {
         update();
     }
 }
 
 QList KReportRuler::tabs() const
 {
     QList answer = d->tabs;
     qSort(answer.begin(), answer.end(), compareTabs);
 
     return answer;
 }
 
 void KReportRuler::setPopupActionList(const QList &popupActionList)
 {
     d->popupActions = popupActionList;
 }
 
 QList KReportRuler::popupActionList() const
 {
     return d->popupActions;
 }
 
 void KReportRuler::mousePressEvent ( QMouseEvent* ev )
 {
     d->tabMoved = false;
     d->selected = KReportRuler::Private::None;
     if (ev->button() == Qt::RightButton && !d->popupActions.isEmpty())
         QMenu::exec(d->popupActions, ev->globalPos());
     if (ev->button() != Qt::LeftButton) {
         ev->ignore();
         return;
     }
 
     QPoint pos = ev->pos();
 
     if (d->showTabs) {
         int i = 0;
         int x;
         foreach (const Tab & t, d->tabs) {
             if (d->rightToLeft) {
                 x = d->viewConverter->documentToViewX(d->effectiveActiveRangeEnd()
                         - (d->relativeTabs ? d->paragraphIndent : 0) - t.position) + d->offset;
             } else {
                 x = d->viewConverter->documentToViewX(d->effectiveActiveRangeStart()
                         + (d->relativeTabs ? d->paragraphIndent : 0) + t.position) + d->offset;
             }
             if (pos.x() >= x-6 && pos.x() <= x+6) {
                 d->selected = KReportRuler::Private::Tab;
                 d->selectOffset = x - pos.x();
                 d->currentIndex = i;
                 break;
             }
             i++;
         }
         d->originalIndex = d->currentIndex;
     }
 
     if (d->selected == KReportRuler::Private::None)
         d->selected = d->selectionAtPosition(ev->pos(), &d->selectOffset);
     if (d->selected == KReportRuler::Private::None) {
         int hotSpotIndex = d->hotSpotIndex(ev->pos());
         if (hotSpotIndex >= 0) {
             d->selected = KReportRuler::Private::HotSpot;
             update();
         }
     }
 
     if (d->showTabs && d->selected == KReportRuler::Private::None) {
         // still haven't found something so let assume the user wants to add a tab
         qreal tabpos;
         if (d->rightToLeft) {
             tabpos = d->viewConverter->viewToDocumentX(pos.x() - d->offset)
                     + d->effectiveActiveRangeEnd() + (d->relativeTabs ? d->paragraphIndent : 0);
         } else {
             tabpos = d->viewConverter->viewToDocumentX(pos.x() - d->offset)
                     - d->effectiveActiveRangeStart() - (d->relativeTabs ? d->paragraphIndent : 0);
         }
         Tab t(tabpos, d->tabChooser ?  d->tabChooser->type() :
                          d->rightToLeft ? QTextOption::RightTab :
                                           QTextOption::LeftTab);
         d->tabs.append(t);
         d->selectOffset = 0;
         d->selected = KReportRuler::Private::Tab;
         d->currentIndex = d->tabs.count() - 1;
         d->originalIndex = -1; // new!
         update();
     }
     if (d->orientation == Qt::Horizontal && (ev->modifiers() & Qt::ShiftModifier) &&
             (d->selected == KReportRuler::Private::FirstLineIndent ||
              d->selected == KReportRuler::Private::ParagraphIndent ||
              d->selected == KReportRuler::Private::Tab ||
              d->selected == KReportRuler::Private::EndIndent))
         d->paintingStrategy = d->distancesPaintingStrategy;
 
     if (d->selected != KReportRuler::Private::None)
         emit aboutToChange();
 }
 
 void KReportRuler::mouseReleaseEvent ( QMouseEvent* ev )
 {
     ev->accept();
     if (d->selected == KReportRuler::Private::Tab) {
         if (d->originalIndex >= 0 && !d->tabMoved) {
             int type = d->tabs[d->currentIndex].type;
             type++;
             if (type > 3)
                 type = 0;
             d->tabs[d->currentIndex].type = static_cast (type);
             update();
         }
         d->emitTabChanged();
     }
     else if( d->selected != KReportRuler::Private::None)
         emit indentsChanged(true);
     else
         ev->ignore();
 
     d->paintingStrategy = d->normalPaintingStrategy;
     d->selected = KReportRuler::Private::None;
 }
 
 void KReportRuler::mouseMoveEvent ( QMouseEvent* ev )
 {
     QPoint pos = ev->pos();
 
     qreal activeLength = d->effectiveActiveRangeEnd() - d->effectiveActiveRangeStart();
 
     switch (d->selected) {
     case KReportRuler::Private::FirstLineIndent:
         if (d->rightToLeft)
             d->firstLineIndent = d->effectiveActiveRangeEnd() - d->paragraphIndent -
                 d->viewConverter->viewToDocumentX(pos.x() + d->selectOffset - d->offset);
         else
             d->firstLineIndent = d->viewConverter->viewToDocumentX(pos.x() + d->selectOffset
                 - d->offset) - d->effectiveActiveRangeStart() - d->paragraphIndent;
         if( ! (ev->modifiers() & Qt::ShiftModifier)) {
             d->firstLineIndent = d->doSnapping(d->firstLineIndent);
             d->paintingStrategy = d->normalPaintingStrategy;
         } else {
             if (d->orientation == Qt::Horizontal)
                 d->paintingStrategy = d->distancesPaintingStrategy;
         }
 
         emit indentsChanged(false);
         break;
     case KReportRuler::Private::ParagraphIndent:
         if (d->rightToLeft)
             d->paragraphIndent = d->effectiveActiveRangeEnd() -
                 d->viewConverter->viewToDocumentX(pos.x() + d->selectOffset - d->offset);
         else
             d->paragraphIndent = d->viewConverter->viewToDocumentX(pos.x() + d->selectOffset
                 - d->offset) - d->effectiveActiveRangeStart();
         if( ! (ev->modifiers() & Qt::ShiftModifier)) {
             d->paragraphIndent = d->doSnapping(d->paragraphIndent);
             d->paintingStrategy = d->normalPaintingStrategy;
         } else {
             if (d->orientation == Qt::Horizontal)
                 d->paintingStrategy = d->distancesPaintingStrategy;
         }
 
         if (d->paragraphIndent + d->endIndent > activeLength)
             d->paragraphIndent = activeLength - d->endIndent;
         emit indentsChanged(false);
         break;
     case KReportRuler::Private::EndIndent:
         if (d->rightToLeft)
             d->endIndent = d->viewConverter->viewToDocumentX(pos.x()
                  + d->selectOffset - d->offset) - d->effectiveActiveRangeStart();
         else
             d->endIndent = d->effectiveActiveRangeEnd() - d->viewConverter->viewToDocumentX(pos.x()
                  + d->selectOffset - d->offset);
         if (!(ev->modifiers() & Qt::ShiftModifier)) {
             d->endIndent = d->doSnapping(d->endIndent);
             d->paintingStrategy = d->normalPaintingStrategy;
         } else {
             if (d->orientation == Qt::Horizontal)
                 d->paintingStrategy = d->distancesPaintingStrategy;
         }
 
         if (d->paragraphIndent + d->endIndent > activeLength)
             d->endIndent = activeLength - d->paragraphIndent;
         emit indentsChanged(false);
         break;
     case KReportRuler::Private::Tab:
         d->tabMoved = true;
         if (d->currentIndex < 0) { // tab is deleted.
             if (ev->pos().y() < height()) { // reinstante it.
                 d->currentIndex = d->tabs.count();
                 d->tabs.append(d->deletedTab);
             } else {
                 break;
             }
         }
         if (d->rightToLeft)
             d->tabs[d->currentIndex].position = d->effectiveActiveRangeEnd() -
                 d->viewConverter->viewToDocumentX(pos.x() + d->selectOffset - d->offset);
         else
             d->tabs[d->currentIndex].position = d->viewConverter->viewToDocumentX(pos.x() + d->selectOffset
                 - d->offset) - d->effectiveActiveRangeStart();
         if (!(ev->modifiers() & Qt::ShiftModifier))
             d->tabs[d->currentIndex].position = d->doSnapping(d->tabs[d->currentIndex].position);
         if (d->tabs[d->currentIndex].position < 0)
             d->tabs[d->currentIndex].position = 0;
         if (d->tabs[d->currentIndex].position > activeLength)
             d->tabs[d->currentIndex].position = activeLength;
 
         if (ev->pos().y() > height() + OutsideRulerThreshold ) { // moved out of the ruler, delete it.
             d->deletedTab = d->tabs.takeAt(d->currentIndex);
             d->currentIndex = -1;
             // was that a temporary added tab?
             if ( d->originalIndex == -1 )
                 emit guideLineCreated(d->orientation,
                         d->orientation == Qt::Horizontal
                         ? d->viewConverter->viewToDocumentY(ev->pos().y())
                         : d->viewConverter->viewToDocumentX(ev->pos().x()));
         }
 
         d->emitTabChanged();
         break;
     case KReportRuler::Private::HotSpot:
         qreal newPos;
         if (d->orientation == Qt::Horizontal)
             newPos= d->viewConverter->viewToDocumentX(pos.x() - d->offset);
         else
             newPos= d->viewConverter->viewToDocumentY(pos.y() - d->offset);
         d->hotspots[d->currentIndex].position = newPos;
         emit hotSpotChanged(d->hotspots[d->currentIndex].id, newPos);
         break;
     case KReportRuler::Private::None:
         d->mouseCoordinate = (d->orientation == Qt::Horizontal ?  pos.x() : pos.y()) - d->offset;
         int hotSpotIndex = d->hotSpotIndex(pos);
         if (hotSpotIndex >= 0) {
             setCursor(QCursor( d->orientation == Qt::Horizontal ? Qt::SplitHCursor : Qt::SplitVCursor ));
             break;
         }
         unsetCursor();
 
         KReportRuler::Private::Selection selection = d->selectionAtPosition(pos);
         QString text;
         switch(selection) {
         case KReportRuler::Private::FirstLineIndent: text = tr("First line indent"); break;
         case KReportRuler::Private::ParagraphIndent: text = tr("Left indent"); break;
         case KReportRuler::Private::EndIndent: text = tr("Right indent"); break;
         case KReportRuler::Private::None:
             if (ev->buttons() & Qt::LeftButton) {
                 if (d->orientation == Qt::Horizontal && ev->pos().y() > height() + OutsideRulerThreshold)
                     emit guideLineCreated(d->orientation, d->viewConverter->viewToDocumentY(ev->pos().y()));
                 else if (d->orientation == Qt::Vertical && ev->pos().x() > width() + OutsideRulerThreshold)
                     emit guideLineCreated(d->orientation, d->viewConverter->viewToDocumentX(ev->pos().x()));
             }
             break;
         default:
             break;
         }
         setToolTip(text);
     }
     update();
 }
 
 void KReportRuler::clearHotSpots()
 {
     if (d->hotspots.isEmpty())
         return;
     d->hotspots.clear();
     update();
 }
 
 void KReportRuler::setHotSpot(qreal position, int id)
 {
     int hotspotCount = d->hotspots.count();
     for (int i = 0; i < hotspotCount; ++i) {
         KReportRuler::Private::HotSpotData & hs = d->hotspots[i];
         if (hs.id == id) {
             hs.position = position;
             update();
             return;
         }
     }
     // not there yet, then insert it.
     KReportRuler::Private::HotSpotData hs;
     hs.position = position;
     hs.id = id;
     d->hotspots.append(hs);
 }
 
 bool KReportRuler::removeHotSpot(int id)
 {
     QList::Iterator iter = d->hotspots.begin();
     while(iter != d->hotspots.end()) {
         if (iter->id == id) {
             d->hotspots.erase(iter);
             update();
             return true;
         }
     }
     return false;
 }
diff --git a/src/wrtembed/KReportRuler_p.h b/src/wrtembed/KReportRuler_p.h
index e333f8c8..b5b91aa4 100644
--- a/src/wrtembed/KReportRuler_p.h
+++ b/src/wrtembed/KReportRuler_p.h
@@ -1,265 +1,266 @@
 /* This file is part of the KDE project
  * Copyright (C) 1998, 1999 Reginald Stadlbauer 
  * Copyright (C) 2006 Peter Simonsson 
  * Copyright (C) 2007 C. Boemann 
  * Copyright (C) 2007 Thomas Zander 
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Library General Public
  * License as published by the Free Software Foundation; either
  * version 2 of the License, or (at your option) any later version.
  *
  * This library is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Library General Public License for more details.
  *
  * You should have received a copy of the GNU Library General Public License
  * along with this library; see the file COPYING.LIB.  If not, write to
  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
  * Boston, MA 02110-1301, USA.
 */
 
 #ifndef KREPORTRULER_P_H
 #define KREPORTRULER_P_H
 
 #include "KReportUnit.h"
 #include 
 #include 
 
 class KReportZoomHandler;
 
 /**
  * Decorator widget to draw a single ruler around a canvas.
  */
 class KReportRuler : public QWidget
 {
 Q_OBJECT
 public:
     /**
      * Creates a ruler with the orientation @p orientation
      * @param parent parent widget
      * @param orientation the orientation of the ruler
      * @param viewConverter the view converter used to convert from point to pixel
      */
     KReportRuler(QWidget* parent, Qt::Orientation orientation,
                  const KReportZoomHandler &zoomHandler);
     ~KReportRuler() override;
 
     /// For paragraphs each tab definition is represented by this struct.
     struct Tab {
         inline Tab(qreal aPosition, QTextOption::TabType aType) : position(aPosition), type(aType) {}
         inline Tab() : position(0.0), type(QTextOption::LeftTab) {}
         qreal position;            ///< distance in point from the start of the text-shape
         QTextOption::TabType type; ///< Determine which type is used.
     };
 
     /// The ruler's unit
+    /// Default is Centimeter.
     KReportUnit unit() const;
 
     /// The length of the ruler in points (pt)
     qreal rulerLength() const;
 
     /// The orientation of the ruler
     Qt::Orientation orientation() const;
 
     /// The start indent of the first line
     qreal firstLineIndent() const;
 
     /// The start indent of the rest of the lines
     qreal paragraphIndent() const;
 
     /// The end indent of all lines
     qreal endIndent() const;
 
     /// The tab chooser widget, which you must put into a layout along with the ruler.
     /// Returns 0 for vertical rulers,
     QWidget *tabChooser();
 
     /**
      * set a list of actions that will be shown in a popup should the user right click on this ruler.
      * @param popupActionList the list of actions
      * @see popupActionList()
      */
     void setPopupActionList(const QList &popupActionList);
     /**
      * Return the actions list.
      * @see setPopupActionList()
      */
     QList popupActionList() const;
 
     /// reimplemented
     QSize minimumSizeHint() const override;
 
     /// reimplemented
     QSize sizeHint() const override;
 
     class Private;
 
 public Q_SLOTS:
     /// Set the unit of the ruler
     void setUnit(const KReportUnit &unit);
 
     /** Set the offset. Use this function to sync the ruler with
       * the canvas' position on screen
       * @param offset The offset in pixels
       */
     void setOffset(int offset);
 
     /// Sets the length of the ruler to @p length in points (pt)
     void setRulerLength(qreal length);
 
     /** Set the active range, ie the part of the ruler that is most likely used.
       * set to 0, 0 when there is no longer any active range
       * @param start the start of the range in pt
       * @param end the end of the range in pt
       */
     void setActiveRange(qreal start, qreal end);
 
     /** Set the override active range, ie the part of the ruler that is most likely used.
       * set to 0, 0 when there is no longer any active range
       * The override, means that if set it takes precedence over the normal active range.
       * @param start the start of the range in pt
       * @param end the end of the range in pt
       */
     void setOverrideActiveRange(qreal start, qreal end);
 
     /** Set the state of the ruler so that it shows everything in right to left mode.
       * @param isRightToLeft state of right to left mode. Default is false.
       */
     void setRightToLeft(bool isRightToLeft);
 
     /** Set if the ruler should show indents as used in textditors.
       * Set the indents with setFirstLineIndent(), setParagraphIndent(), setEndIndent() .
       * @param show show indents if true. Default is false.
       */
     void setShowIndents(bool show);
 
     /** Set the position of the first line start indent relative to the active range.
       * If Right To left is set the indent is relative to the right side of the active range .
       * @param indent the value relative to the active range.
       */
     void setFirstLineIndent(qreal indent);
 
     /** Set the position of the rest of the lines start indent relative to the active range.
       * If Right To left is set the indent is relative to the right side of the active range .
       * @param indent the value relative to the active range.
       */
     void setParagraphIndent(qreal indent);
 
     /** Set the position of the end indent relative to the active range.
       * If Right To left is set the indent is relative to the left side of the active range .
       * @param indent the value relative to the active range.
       */
     void setEndIndent(qreal indent);
 
     /** Set whether the ruler should show the current mouse position.
       * Update the position with updateMouseCoordinate().
       * @param show show mouse position if true. Default is false.
       */
     void setShowMousePosition(bool show);
 
     /** Update the current position of the mouse pointer, repainting if changed.
       * The ruler offset will be applied before painting.
       * @param coordinate Either the x or y coordinate of the mouse depending
       *                   of the orientation of the ruler.
       */
     void updateMouseCoordinate(int coordinate);
 
     /**
      * Set whether the ruler should show the selection borders
      * @param show show selection borders if true, default is false.
      */
     void setShowSelectionBorders(bool show);
 
     /**
      * Update the selection borders
      * @param first the first selection border in points
      * @param second the other selection border in points
      */
     void updateSelectionBorders(qreal first, qreal second);
 
     /**
      * Set whether the ruler should show tabs
      * @param show show selection borders if true, default is false.
      */
     void setShowTabs(bool show);
 
     /**
      * Set whether the tabs is relative to the paragraph indent
      * @param relative tabs are relative to pragraph indent if true, default is false.
      */
     void setRelativeTabs(bool relative);
 
     /**
      * Update the tabs
      * @param tabs a list of tabs that is shown on the ruler
      * @param tabDistance the distance between regular interval tabs
      */
     void updateTabs(const QList &tabs, qreal tabDistance);
 
     /***
      * Return the list of tabs set on this ruler.
      */
     QList tabs() const;
 
     /**
      * Clear all previously set hotspots.
      * A hotspot is a position on the ruler that the user can manipulate by dragging.
      */
     void clearHotSpots();
 
     /**
      * Add or set a hotspot.
      * A hotspot is a position on the ruler that the user can manipulate by dragging.
      * @param position the new position of the hotspot.
      * @param id the unique id for the hotspot. If the id has not been set before, it will be added.
      */
     void setHotSpot(qreal position, int id = -1);
 
     /**
      * Remove a previously set hotspot, returning true if one is actually returned.
      * @param id the unique id for the hotspot.
      * A hotspot is a position on the ruler that the user can manipulate by dragging.
      */
     bool removeHotSpot(int id);
 
 Q_SIGNALS:
     /**
      * emitted when any of the indents is moved by the user.
      * @param final false until the user releases the mouse. So you can implement live update.
      */
     void indentsChanged(bool final);
 
     /**
      * Emitted when any of the tabs are moved, deleted or inserted by the user.
      * @param originalTabIndex the index in the list of tabs before the user interaction
      *          started, or -1 if this is a new tab
      * @param tab the new tab, or zero when the tab has been removed.
      */
     void tabChanged(int originalTabIndex, KReportRuler::Tab *tab);
 
     /// emitted when there the user is about to change a tab or hotspot
     void aboutToChange();
 
     void hotSpotChanged(int id, qreal newPosition);
 
     /// emitted when the mouse is drag+released outside the ruler
     void guideLineCreated(Qt::Orientation orientation, qreal viewPosition);
 
 protected:
     /// reimplemented
     void paintEvent(QPaintEvent* event) override;
     /// reimplemented
     void mousePressEvent(QMouseEvent *ev) override;
     /// reimplemented
     void mouseReleaseEvent(QMouseEvent *ev) override;
     /// reimplemented
     void mouseMoveEvent(QMouseEvent *ev) override;
 
 private:
     Private * const d;
     friend class KReportRuler::Private;
 };
 
 #endif