[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kde-commits
Subject:    [kreport/nonvisual-T517-staniek] /: Add KReportElement and KReportLabelElement -- explicitly shared
From:       Jaroslaw Staniek <staniek () kde ! org>
Date:       2015-08-01 0:04:27
Message-ID: E1ZLKHr-00044c-VU () scm ! kde ! org
[Download RAW message or body]

Git commit 5c5cc1af970917fc5fe28c777dbd048d3867b63b by Jaroslaw Staniek.
Committed on 01/08/2015 at 00:02.
Pushed by staniek into branch 'nonvisual-T517-staniek'.

Add KReportElement and KReportLabelElement -- explicitly shared

+Early support by the plugin
+Add support for adding elements to section
+Loading elements into sections works
+Add title property to reports
+Update tests

M  +52   -0    autotests/format/FormatTest.cpp
M  +5    -0    src/CMakeLists.txt
M  +54   -2    src/common/KReportDesign.cpp
M  +21   -0    src/common/KReportDesign.h
M  +95   -51   src/common/KReportDesign_p.cpp
M  +10   -5    src/common/KReportDesign_p.h
A  +24   -0    src/common/KReportElement.cpp     [License: LGPL (v2.1+)]
A  +63   -0    src/common/KReportElement.shared.h     [License: LGPL (v2.1+)]
M  +10   -0    src/common/KReportSection.cpp
M  +14   -22   src/common/KReportSection.shared.h
M  +3    -0    src/common/KoReportPluginInterface.h
A  +24   -0    src/items/label/KReportLabelElement.cpp     [License: LGPL (v2.1+)]
A  +38   -0    src/items/label/KReportLabelElement.shared.h     [License: LGPL \
(v2.1+)] M  +6    -0    src/items/label/KoReportLabelPlugin.cpp
M  +1    -0    src/items/label/KoReportLabelPlugin.h
M  +10   -10   tools/sdc.py

http://commits.kde.org/kreport/5c5cc1af970917fc5fe28c777dbd048d3867b63b

diff --git a/autotests/format/FormatTest.cpp b/autotests/format/FormatTest.cpp
index 5be3ff6..e9f4214 100644
--- a/autotests/format/FormatTest.cpp
+++ b/autotests/format/FormatTest.cpp
@@ -22,6 +22,7 @@
 #include "FormatTest.h"
 #include "KoReportPreRenderer.h"
 #include "KoReportDesigner.h"
+#include "KReportLabelElement.h"
 #include "krreportdata.h"
 #include "reportpageoptions.h"
 #include "reportsectiondetail.h"
@@ -41,6 +42,7 @@
 #include <QScreen>
 #include <QDir>
 #include <QTest>
+#include <QPageLayout>
 
 QTEST_MAIN(FormatTest)
 
@@ -176,6 +178,56 @@ void FormatTest::testRectItem()
         QDebug(&message) << status;
         QFAIL(qPrintable(QLatin1String("Failed to load content. ") + message));
     }
+    QCOMPARE(design.title(), QLatin1String("RectItem Test Report"));
+
+    qDebug()<<design.pageLayout();
+    const QPageLayout pageLayout = design.pageLayout();
+    QVERIFY(pageLayout.isValid());
+    QCOMPARE(pageLayout.pageSize().id(), QPageSize::A5);
+    QCOMPARE(pageLayout.pageSize().sizePoints(), \
QPageSize(QPageSize::A5).sizePoints()); +    QCOMPARE(pageLayout.orientation(), \
QPageLayout::Portrait); +    QCOMPARE(pageLayout.margins(QPageLayout::Millimeter), \
QMarginsF(30.0, 20.0, 40.0, 15.0)); +
+    QVERIFY(design.hasSection(KReportSection::Detail));
+    KReportSection detailSection = design.section(KReportSection::Detail);
+    QCOMPARE(detailSection.type(), KReportSection::Detail);
+    QCOMPARE(detailSection.height(), CM_TO_POINT(5.0));
+    QCOMPARE(detailSection.backgroundColor(), QColor("#eeeeee"));
+
+    QList<KReportElement> elements = detailSection.elements();
+    QCOMPARE(elements.count(), 1);
+    KReportElement element = elements.first();
+    QCOMPARE(element.name(), QLatin1String("label1"));
+
+    //TODO: move to an elements API test
+    KReportElement e;
+    e.setName("foo");
+
+    KReportElement e2 = e;
+    qDebug() << e2.name();
+    e.setName("");
+    qDebug() << e2.name();
+    KReportLabelElement l1, l2;
+    l1.setText("text");
+    l2 = l1.clone();
+    l1.setText("");
+    qDebug() << "cloned:" << l2.text();
+    e = l2;
+    l2.setText("text");
+    KReportLabelElement l3(e);
+    qDebug() << l3.text() << KReportLabelElement(e).text() << \
KReportLabelElement(e2).text(); +    KReportElement ee = e.clone();
+    qDebug() << "KReportLabelElement(e).text():" << KReportLabelElement(e).text();
+
+    qDebug() << element.name();
+    detailSection.elements().first().setName("new_label_name");
+
+    detailSection.addElement(e);
+    qDebug() << KReportLabelElement(detailSection.elements().at(1)).text();
+    qDebug() << detailSection.elements().at(0).name() << element.name();
+    // end of TODO
+
+    //TODO: move this renderer test to a separate place
     KoReportDesigner designer(0);//, doc.documentElement());
     ReportSectionDetail *ds = designer.detailSection();
     ReportSection *sec = ds->detailSection();
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 788dff8..93a8787 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -34,6 +34,8 @@ set(kreport_LIB_SRCS
     common/KReportUnit.cpp
     common/KReportDesign.cpp
     common/KReportDesign_p.cpp
+    common/KReportElement.cpp
+    ${PROJECT_BINARY_DIR}/src/KReportElement_sdc.cpp
     common/KReportSection.cpp
 
     renderer/KoReportPrintRenderer.cpp
@@ -71,6 +73,7 @@ set(kreport_LIB_SRCS
     items/label/KoReportDesignerItemLabel.cpp
     items/label/KoReportLabelPlugin.cpp
     items/label/BoundedTextItem.cpp
+    items/label/KReportLabelElement.cpp
 
     items/check/KoReportItemCheck.cpp
     items/check/KoReportDesignerItemCheck.cpp
@@ -131,7 +134,9 @@ add_library(KReport SHARED ${kreport_LIB_SRCS})
 kdb_create_shared_data_classes(
     kreport_GENERATED_SHARED_DATA_CLASS_HEADERS # output variable with list of \
headers  NO_PREFIX # subdirectory in which the headers should be generated
+    common/KReportElement.shared.h
     common/KReportSection.shared.h
+    items/label/KReportLabelElement.shared.h
 )
 
 kdb_remove_extensions(
diff --git a/src/common/KReportDesign.cpp b/src/common/KReportDesign.cpp
index be2d261..ecaa8e4 100644
--- a/src/common/KReportDesign.cpp
+++ b/src/common/KReportDesign.cpp
@@ -19,10 +19,10 @@
 
 #include "KReportDesign.h"
 #include "KReportDesign_p.h"
+#include "KReportElement.h"
 #include "KReportUnit.h"
 #include "krutils.h"
 
-#include <QDebug>
 #include <QDomDocument>
 #include <QDomElement>
 #include <QPrinter>
@@ -55,7 +55,7 @@ QDebug operator<<(QDebug dbg, const KReportDesignReadingStatus& \
status)  //-----------------------------------
 
 KReportDesign::KReportDesign()
-    : d(new Private)
+    : d(new Private(this))
 {
 }
 
@@ -90,12 +90,64 @@ QPageLayout KReportDesign::pageLayout() const
     return d->pageLayout;
 }
 
+QString KReportDesign::title() const
+{
+    return d->title;
+}
+
+void KReportDesign::setTitle(const QString &title)
+{
+    d->title = title;
+}
+
 void KReportDesign::setPageLayout(const QPageLayout &pageLayout)
 {
     d->pageLayout = pageLayout;
     d->pageLayout.setUnits(QPageLayout::Point);
 }
 
+KReportElement KReportDesign::createElement(const QString &typeName, QString \
*errorMessage) +{
+    KReportElement element;
+    if (errorMessage) {
+        errorMessage->clear();
+    }
+    return element;
+}
+
+bool KReportDesign::hasSection(KReportSection::Type type) const
+{
+    const int index = type - 1;
+    if (0 <= index && index < d->sections.length()) {
+        return d->sections[index];
+    }
+    return false;
+}
+
+KReportSection KReportDesign::section(KReportSection::Type type) const
+{
+    const int index = type - 1;
+    if (0 <= index && index < d->sections.length()) {
+        KReportSection *section = d->sections[index];
+        if (section) {
+            return *section;
+        }
+    }
+    return KReportSection();
+}
+
+void KReportDesign::addSection(const KReportSection &section)
+{
+    const int index = section.type() - 1;
+    if (0 <= index && index < d->sections.length()) {
+        if (d->sections[index]) {
+            *d->sections[index] = section;
+        } else {
+            d->sections[index] = new KReportSection(section);
+        }
+    }
+}
+
 // static
 QPageLayout KReportDesign::defaultPageLayout()
 {
diff --git a/src/common/KReportDesign.h b/src/common/KReportDesign.h
index d1e6fdd..cb8a525 100644
--- a/src/common/KReportDesign.h
+++ b/src/common/KReportDesign.h
@@ -20,12 +20,14 @@
 #define KREPORTDESIGN_H
 
 #include "kreport_export.h"
+#include "KReportSection.h"
 
 #include <QCoreApplication>
 
 class QPageSize;
 class QMarginsF;
 class QPageLayout;
+class KReportElement;
 
 //! The KReportDesignReadStatus represents status of reading a report design in \
.kreport format.  /*! It is used by KReportDesign::setContent(). */
@@ -73,6 +75,12 @@ public:
     //! Converts the report document back to its textual representation.
     QString toString(int indent = 1) const;
 
+    //! @return title for this design
+    QString title() const;
+
+    //! Sets title for this design to @a title
+    void setTitle(const QString &title);
+
     //! @return page layout for this design
     QPageLayout pageLayout() const;
 
@@ -80,6 +88,19 @@ public:
     //! @note Calling this method does not alter page layouts of existing \
KReportDesign objects.  void setPageLayout(const QPageLayout &pageLayout);
 
+    //! @return true if this design has section defined of type @a type
+    bool hasSection(KReportSection::Type type) const;
+
+    //! @return section of type @a type
+    KReportSection section(KReportSection::Type type) const;
+
+    //! Add section @a section. Previous section of the same type is removed from \
this design. +    void addSection(const KReportSection &section);
+
+    //! Creates and returns report element of type @a typeName
+    //! On success @a errorMessage is cleared, on failure it is set to a nonempty \
value. +    KReportElement createElement(const QString &typeName, QString \
*errorMessage); +
     //! @return default page layout that is used for creating new report designs
     /*! Attributes that are specified in the design format:
         - margins: by default equal to equivalent of 1cm in points \
                (QPageLayout::Point).
diff --git a/src/common/KReportDesign_p.cpp b/src/common/KReportDesign_p.cpp
index 7b387c5..2a4cba0 100644
--- a/src/common/KReportDesign_p.cpp
+++ b/src/common/KReportDesign_p.cpp
@@ -18,6 +18,7 @@
  */
 
 #include "KReportDesign_p.h"
+#include "KReportElement.h"
 #include "krutils.h"
 
 #include <QDebug>
@@ -25,12 +26,21 @@
 #include <QDomElement>
 #include <QSizeF>
 
-KReportDesign::Private::Private()
- : showGrid(DEFAULT_SHOW_GRID)
+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<void*>(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()
@@ -51,7 +61,7 @@ KReportSection::Type KReportDesignGlobal::sectionType(const \
                QString& typeName) {
     return sectionTypesForName.value(typeName); // returns InvalidType for invalid \
name  }
 
-QString KReportDesignGlobal::setionTypeName(KReportSection::Type sectionType) {
+QString KReportDesignGlobal::sectionTypeName(KReportSection::Type sectionType) {
     initSectionTypes();
     return sectionTypeNames.value(sectionType);
 }
@@ -104,17 +114,33 @@ static void setStatus(KReportDesignReadingStatus *status, const \
QString& details  }
 }
 
-static bool checkElement(const QDomNode &node, const QDomElement &parent,
-                         KReportDesignReadingStatus *status)
+static bool checkElement(const QDomNode &node, KReportDesignReadingStatus *status)
 {
     if (node.isElement()) {
         return true;
     }
     setStatus(status, QString::fromLatin1("Element expected inside of <%1>")
-              .arg(parent.tagName()), node);
+              .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
+
 inline static QString attr(const QDomElement &el, const char *attrName,
                            QString defaultValue = QString())
 {
@@ -145,8 +171,8 @@ inline static qreal attr(const QDomElement &el, const char \
*attrName, qreal defa  return KReportUnit::parseValue(val, defaultValue);
 }
 
-bool KReportDesign::Private::processSectionElement(const QDomElement &el,
-                                                   KReportDesignReadingStatus \
*status) +KReportSection KReportDesign::Private::processSectionElement(const \
QDomElement &el, +                                                             \
KReportDesignReadingStatus *status)  {
     const QString sectionTypeName = attr(el, "report:section-type", QString());
     KReportSection::Type sectionType = s_global->sectionType(sectionTypeName);
@@ -154,27 +180,30 @@ bool KReportDesign::Private::processSectionElement(const \
QDomElement &el,  setStatus(status,
             QString::fromLatin1("Invalid value of report:section-type=\"%1\" in \
                element <%2>")
                                 .arg(sectionTypeName).arg(el.tagName()), el);
-        return false;
+        return KReportSection();
     }
-    KReportSection *section = new KReportSection;
-    section->setType(sectionType);
+    KReportSection section;
+    section.setType(sectionType);
     qreal height = attr(el, "svg:height", -1.0);
     if (height >= 0.0) {
-        section->setHeight(height);
+        section.setHeight(height);
     }
-    section->setBackgroundColor(QColor(attr(el, "fo:background-color", QString())));
+    section.setBackgroundColor(QColor(attr(el, "fo:background-color", QString())));
     for (QDomNode node = el.firstChild(); !node.isNull(); node = node.nextSibling()) \
                {
-        if (!checkElement(node, el, status)) {
-            return false;
+        if (!checkElement(node, status)) {
+            return KReportSection();
         }
-        if (!processSectionElementChild(node.toElement(), status)) {
-            return false;
+        KReportElement element = processSectionElementChild(node.toElement(), \
status); +        if (status->isError()) {
+            return KReportSection();
         }
+        section.addElement(element);
     }
-    return true;
+    return section;
 }
 
-bool KReportDesign::Private::processSectionElementChild(const QDomElement &el,
+KReportElement KReportDesign::Private::processSectionElementChild(
+                                                        const QDomElement &el,
                                                         KReportDesignReadingStatus \
*status)  {
     const QByteArray name = el.tagName().toLatin1();
@@ -182,36 +211,28 @@ bool KReportDesign::Private::processSectionElementChild(const \
QDomElement &el,  
     if (!name.startsWith(elNamespace)) {
         unexpectedElement(el, status);
-        return false;
+        return KReportElement();
     }
     const QByteArray reportElementName = name.mid(qstrlen(elNamespace));
     qDebug() << "Found Report Element:" << reportElementName;
-#if 0
-
-
-        if (reportItemName == QLatin1String("line")) {
-            KoReportItemLine * line = new KoReportItemLine(elemThis);
-            m_objects.append(line);
-            continue;
-        }
-        KoReportPluginInterface *plugin = manager->plugin(reportItemName);
-        if (plugin) {
-            QObject *obj = plugin->createRendererInstance(elemThis);
-            if (obj) {
-                KoReportItemBase *krobj = dynamic_cast<KoReportItemBase*>(obj);
-                if (krobj) {
-                    m_objects.append(krobj);
-                }
-                continue;
-            }
-        }
-#endif
-    return true;
+    QString errorMessage;
+    KReportElement element = q->createElement(QLatin1String(reportElementName), \
&errorMessage); +    if (!errorMessage.isEmpty()) {
+        setStatus(status, errorMessage, el);
+        return KReportElement();
+    }
+    element.setName(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)
 {
+    //! @todo
     return true;
 }
 
@@ -222,7 +243,7 @@ bool KReportDesign::Private::processDetailElement(const \
QDomElement &el,  {
     QDomElement sectionEl;
     for (QDomNode node = el.firstChild(); !node.isNull(); node = node.nextSibling()) \
                {
-        if (!checkElement(node, el, status)) {
+        if (!checkElement(node, status)) {
             return false;
         }
         QDomElement childEl = node.toElement();
@@ -231,9 +252,16 @@ bool KReportDesign::Private::processDetailElement(const \
QDomElement &el,  if (!sectionEl.isNull()) {
                 return false;
             }
-            if (!processSectionElement(childEl, status)) {
+            KReportSection section = processSectionElement(childEl, status);
+            if (status->isError()) {
+                return false;
+            }
+            if (section.type() != KReportSection::Detail) {
+                setStatus(status,
+                    QString::fromLatin1("Only section of type \"detail\" allowed in \
<report:detail>"), el);  return false;
             }
+            q->addSection(section);
         }
         else if (name == "report:group") {
             if (!processGroupElement(childEl, status)) {
@@ -270,9 +298,22 @@ bool KReportDesign::Private::processBodyElementChild(const \
QDomElement &el,  const QByteArray name = el.tagName().toLatin1();
     //kreportDebug() << name;
     if (name == "report:section") {
-        if (!processSectionElement(el, status)) {
+        KReportSection section = processSectionElement(el, status);
+        if (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 \
<report:body>"), el);  return false;
         }
+        q->addSection(section);
 #if 0 //TODO
         if (section(KRSectionData::sectionTypeFromString(sectiontype)) == 0) {
             insertSection(KRSectionData::sectionTypeFromString(sectiontype));
@@ -340,11 +381,14 @@ bool KReportDesign::Private::processContentElementChild(const \
QDomElement &el,  //! @todo?
             pageLayout.setPageSize(defaultPageLayout.pageSize());
         }
-        pageLayout.setMargins(
-                   QMarginsF(attr(el, "fo:margin-left", \
                defaultPageLayout.margins().left()),
-                            attr(el, "fo:margin-top", \
                defaultPageLayout.margins().top()),
-                            attr(el, "fo:margin-right", \
                defaultPageLayout.margins().right()),
-                            attr(el, "fo:margin-bottom", \
defaultPageLayout.margins().bottom()))); +        QMarginsF margins(attr(el, \
"fo:margin-left", defaultPageLayout.margins().left()), +                 attr(el, \
"fo:margin-top", defaultPageLayout.margins().top()), +                 attr(el, \
"fo:margin-right", defaultPageLayout.margins().right()), +                 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 = attr(el, "report:print-orientation", QString());
         if (s == QLatin1String("portrait")) {
             pageLayout.setOrientation(QPageLayout::Portrait);
@@ -356,7 +400,7 @@ bool KReportDesign::Private::processContentElementChild(const \
QDomElement &el,  }
     } else if (name == "report:body") {
         for (QDomNode node = el.firstChild(); !node.isNull(); node = \
                node.nextSibling()) {
-            if (!checkElement(node, el, status)) {
+            if (!checkElement(node, status)) {
                 return false;
             }
             if (!processBodyElementChild(node.toElement(), status)) {
@@ -412,7 +456,7 @@ bool KReportDesign::Private::processDocument(const QDomDocument \
&doc,  //    deleteDetail();
 
     for (QDomNode node = contentEl.firstChild(); !node.isNull(); node = \
                node.nextSibling()) {
-        if (!checkElement(node, contentEl, status)) {
+        if (!checkElement(node, status)) {
             return false;
         }
         if (!processContentElementChild(node.toElement(), status)) {
diff --git a/src/common/KReportDesign_p.h b/src/common/KReportDesign_p.h
index f0bf93d..3044144 100644
--- a/src/common/KReportDesign_p.h
+++ b/src/common/KReportDesign_p.h
@@ -21,11 +21,11 @@
 #define KREPORTDESIGN_P_H
 
 #include "KReportDesign.h"
-#include "KReportSection.h"
 #include "KReportUnit.h"
 
 #include <QPageSize>
 #include <QPageLayout>
+#include <QVarLengthArray>
 
 class QDomDocument;
 class QDomElement;
@@ -41,7 +41,9 @@ static const QPageLayout::Orientation DEFAULT_PAGE_ORIENTATION = \
QPageLayout::La  class KReportDesign::Private
 {
 public:
-    Private();
+    explicit Private(KReportDesign *design);
+
+    ~Private();
 
     QDomElement requiredChildElement(const QDomElement &parent,
                                      const char* childElementName,
@@ -60,14 +62,14 @@ public:
     bool processBodyElementChild(const QDomElement &el, KReportDesignReadingStatus \
*status);  
     //! Processes @a el, a /report:content/report:body/report:section element and \
                sets status @a status
-    bool processSectionElement(const QDomElement &el, KReportDesignReadingStatus \
*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.
-    bool processSectionElementChild(const QDomElement &el, \
KReportDesignReadingStatus *status); +    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); @@ -75,6 +77,8 @@ public:
     //! 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);  
+    KReportDesign * const q;
+
     // Visual settings only
     bool showGrid;
     bool snapToGrid;
@@ -83,6 +87,7 @@ public:
     // END OF: Visual settings only
     QString title;
     QPageLayout pageLayout;
+    QVarLengthArray<KReportSection*, KReportSection::Detail> sections;
 };
 
 class KReportDesignGlobal
@@ -99,7 +104,7 @@ public:
 
     KReportSection::Type sectionType(const QString& typeName);
 
-    QString setionTypeName(KReportSection::Type sectionType);
+    QString sectionTypeName(KReportSection::Type sectionType);
 
     QPageLayout defaultPageLayout;
     qreal defaultSectionHeight;
diff --git a/src/common/KReportElement.cpp b/src/common/KReportElement.cpp
new file mode 100644
index 0000000..b3f6458
--- /dev/null
+++ b/src/common/KReportElement.cpp
@@ -0,0 +1,24 @@
+/* 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-2015 Jarosław Staniek <staniek@kde.org>
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+#include "KReportElement.h"
+
+KReportElement::~KReportElement()
+{
+}
diff --git a/src/common/KReportElement.shared.h b/src/common/KReportElement.shared.h
new file mode 100644
index 0000000..3b714ea
--- /dev/null
+++ b/src/common/KReportElement.shared.h
@@ -0,0 +1,63 @@
+/* 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-2015 Jarosław Staniek <staniek@kde.org>
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef KREPORTELEMENT_H
+#define KREPORTELEMENT_H
+
+#include "kreport_export.h"
+
+#include <QColor>
+#include <QRect>
+
+//! @brief The KReportElement class represents a functional visual element of a \
report design +shared class export=KREPORT_EXPORT explicit operator== virtual_dtor \
KReportElement +{
+public:
+    /*!
+    @getter
+    @return element's name.
+    @setter
+    Sets the element's name to @a name.
+    */
+    data_member QString name;
+
+    /*!
+    @getter
+    @return element's rectangle.
+    @setter
+    Sets the element's rectangle to @a rect.
+    */
+    data_member QRect rect;
+
+    /*!
+    @getter
+    @return element's Z-value.
+    The Z value decides the stacking order of sibling (neighboring) elements.
+    A sibling element of high Z value will always be drawn on top of another sibling
+    element with a lower Z value.
+    If you restore the Z value, the element's insertion order will decide its \
stacking order. +    The Z-value does not affect the element's size in any way.
+    The default Z-value is 0.
+    @setter
+    Sets the element's Z-value to @a z.
+    */
+    data_member qreal z;
+};
+
+#endif // KREPORTELEMENT_H
diff --git a/src/common/KReportSection.cpp b/src/common/KReportSection.cpp
index 21fa487..a4be56b 100644
--- a/src/common/KReportSection.cpp
+++ b/src/common/KReportSection.cpp
@@ -123,6 +123,16 @@ QColor KReportSection::backgroundColor() const
     return d->backgroundColor.isValid() ? d->backgroundColor : \
KReportSection::defaultBackgroundColor();  }
 
+QList<KReportElement> KReportSection::elements() const
+{
+    return d->elements;
+}
+
+void KReportSection::addElement(const KReportElement &element)
+{
+    d->elements.append(element);
+}
+
 //static
 qreal KReportSection::defaultHeight()
 {
diff --git a/src/common/KReportSection.shared.h b/src/common/KReportSection.shared.h
index 3a2899a..34f027a 100644
--- a/src/common/KReportSection.shared.h
+++ b/src/common/KReportSection.shared.h
@@ -20,26 +20,13 @@
 #ifndef KREPORTSECTION_H
 #define KREPORTSECTION_H
 
-#include "kreport_export.h"
+#include <KReportElement>
 
-#include <QColor>
-
-class KoReportItemBase;
-class KoReportReportData;
-
-class QDomElement;
-
-namespace Scripting
-{
-class Section;
-}
-
-//! @brief The KReportSection class represents a section of report design in \
.kreport format +//! @brief The KReportSection class represents a section of a report \
design  /*! A section has optional report header, report footer, page header, page \
                footer,
- * group header, group footer and detail.
- * In the case of page header and page footer it is possible to define (firstpage, \
                odd, even or lastpage).
- */
-shared class export=KREPORT_EXPORT operator== KReportSection
+    group header, group footer and detail.
+    In the case of page header and page footer it is possible to define (firstpage, \
odd, even or lastpage). */ +shared class export=KREPORT_EXPORT explicit operator== \
KReportSection  {
 public:
     enum Type {
@@ -92,6 +79,15 @@ public:
     */
     data_member QColor backgroundColor custom_getter;
 
+    /*!
+    @getter
+    @return all elements of this section
+    */
+    data_member QList<KReportElement> elements custom_getter no_setter;
+
+    //! Adds element to this section
+    void addElement(const KReportElement &element);
+
     //! @return default height for report sections. The standard is 2cm (converted \
to points).  static qreal defaultHeight();
 
@@ -103,10 +99,6 @@ public:
 
     //! Sets default background color for report sections.
     static void setDefaultBackgroundColor(const QColor &color);
-
-//private:
-//    static bool zLessThan(KoReportItemBase* s1, KoReportItemBase* s2);
-//    static bool xLessThan(KoReportItemBase* s1, KoReportItemBase* s2);
 };
 
 #endif // KREPORTSECTION_H
diff --git a/src/common/KoReportPluginInterface.h \
b/src/common/KoReportPluginInterface.h index eaf28cb..e39d8b6 100644
--- a/src/common/KoReportPluginInterface.h
+++ b/src/common/KoReportPluginInterface.h
@@ -23,6 +23,7 @@
 
 #include "config-kreport.h"
 #include "kreport_export.h"
+#include "KReportElement.h"
 
 #include <KPluginFactory>
 
@@ -54,6 +55,8 @@ public:
 
     virtual QObject* createRendererInstance(const QDomNode &element) = 0;
 
+    virtual KReportElement createElement() { return KReportElement(); } // TODO \
remove {} +
 #ifdef KREPORT_SCRIPTING
     virtual QObject* createScriptInstance(KoReportItemBase* item) = 0;
 #endif
diff --git a/src/items/label/KReportLabelElement.cpp \
b/src/items/label/KReportLabelElement.cpp new file mode 100644
index 0000000..862ddee
--- /dev/null
+++ b/src/items/label/KReportLabelElement.cpp
@@ -0,0 +1,24 @@
+/* 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-2015 Jarosław Staniek <staniek@kde.org>
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+#include "KReportLabelElement.h"
+
+KReportLabelElement::~KReportLabelElement()
+{
+}
diff --git a/src/items/label/KReportLabelElement.shared.h \
b/src/items/label/KReportLabelElement.shared.h new file mode 100644
index 0000000..3a8ec9b
--- /dev/null
+++ b/src/items/label/KReportLabelElement.shared.h
@@ -0,0 +1,38 @@
+/* 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-2015 Jarosław Staniek <staniek@kde.org>
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef KREPORTLABELELEMENT_H
+#define KREPORTLABELELEMENT_H
+
+#include "KReportElement.h"
+
+//! @brief The KReportLabelElement class represents a label element of a report \
design +shared class export=KREPORT_EXPORT explicit operator== KReportLabelElement : \
public KReportElement +{
+public:
+    /*!
+    @getter
+    @return element's name.
+    @setter
+    Sets the element's name to @a name.
+    */
+    data_member QString text;
+};
+
+#endif // KREPORTLABELELEMENT_H
diff --git a/src/items/label/KoReportLabelPlugin.cpp \
b/src/items/label/KoReportLabelPlugin.cpp index 3bce609..d638ece 100644
--- a/src/items/label/KoReportLabelPlugin.cpp
+++ b/src/items/label/KoReportLabelPlugin.cpp
@@ -22,6 +22,7 @@
 #include "KoReportDesignerItemLabel.h"
 #include "wrtembed/KoReportDesigner.h"
 #include "common/KReportPluginMetaData.h"
+#include "KReportLabelElement.h"
 #ifdef KREPORT_SCRIPTING
 #include "krscriptlabel.h"
 #endif
@@ -53,6 +54,11 @@ QObject* KoReportLabelPlugin::createDesignerInstance(const \
QDomNode & element, K  return new KoReportDesignerItemLabel(element, designer, \
scene);  }
 
+KReportElement KoReportLabelPlugin::createElement()
+{
+    return KReportLabelElement();
+}
+
 #ifdef KREPORT_SCRIPTING
 QObject* KoReportLabelPlugin::createScriptInstance(KoReportItemBase *item)
 {
diff --git a/src/items/label/KoReportLabelPlugin.h \
b/src/items/label/KoReportLabelPlugin.h index 9d0da83..edec844 100644
--- a/src/items/label/KoReportLabelPlugin.h
+++ b/src/items/label/KoReportLabelPlugin.h
@@ -35,6 +35,7 @@ public:
     virtual QObject* createRendererInstance(const QDomNode&);
     virtual QObject* createDesignerInstance(KoReportDesigner* , QGraphicsScene* \
                scene, const QPointF&);
     virtual QObject* createDesignerInstance(const QDomNode & element, \
KoReportDesigner *, QGraphicsScene * scene); +    virtual KReportElement \
createElement();  #ifdef KREPORT_SCRIPTING
     virtual QObject* createScriptInstance(KoReportItemBase* item);
 #endif
diff --git a/tools/sdc.py b/tools/sdc.py
index 2eba0e8..4ec480d 100755
--- a/tools/sdc.py
+++ b/tools/sdc.py
@@ -590,17 +590,17 @@ def process():
             if inherits:
                 inherits = ' : ' + inherits
             if shared_class_options['explicit']:
-                outfile.write("""//! @note objects of this class are explicitly \
                shared, what means they behave like regular
-//!       C++ pointers, except that by doing reference counting and not deleting the \
                shared
-//!       data object until the reference count is 0, they avoid the dangling \
                pointer problem.
-//!       See <a href="http://doc.qt.io/qt-5/qexplicitlyshareddatapointer.html#details">Qt \
                documentation</a>.
-//!
+                outfile.write("""/*! @note objects of this class are explicitly \
shared, what means they behave like regular +          C++ pointers, except that by \
doing reference counting and not deleting the shared +          data object until the \
reference count is 0, they avoid the dangling pointer problem. +          See <a \
href="http://doc.qt.io/qt-5/qexplicitlyshareddatapointer.html#details">Qt \
documentation</a>. + */
 """)
             else:
-                outfile.write("""//! @note objects of this class are implicitly \
                shared, what means they have value semantics
-//! by offering copy-on-write behaviour to maximize resource usage and minimize \
                copying.
-//! Only a pointer to the data is passed around. See <a \
                href="http://doc.qt.io/qt-5/qshareddatapointer.html#details">Qt \
                documentation</a>.
-//!
+                outfile.write("""/*! @note objects of this class are implicitly \
shared, what means they have value semantics +          by offering copy-on-write \
behaviour to maximize resource usage and minimize copying. +          Only a pointer \
to the data is passed around. See <a \
href="http://doc.qt.io/qt-5/qshareddatapointer.html#details">Qt documentation</a>. + \
*/  """)
 
             outfile.write("class %s%s\n" % (name, inherits))
@@ -699,7 +699,7 @@ def process():
             member['invokable'] = param_exists(lst, 'invokable')
             #print member
             if not data_class_ctor_changed:
-                data_class_ctor = """    //! Internal data class used to implement \
%s shared class %s. +                data_class_ctor = """    //! @internal data \
class used to implement %s shared class %s.  //! Provides thread-safe reference \
counting.  class Data : public %s
     {


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic