File indexing completed on 2024-05-19 04:44:32

0001 /* This file is part of the KDE project
0002  * Copyright (C) 2007-2008 by Adam Pigg (adam@piggz.co.uk)
0003  *
0004  * This library is free software; you can redistribute it and/or
0005  * modify it under the terms of the GNU Lesser General Public
0006  * License as published by the Free Software Foundation; either
0007  * version 2.1 of the License, or (at your option) any later version.
0008  *
0009  * This library is distributed in the hope that it will be useful,
0010  * but WITHOUT ANY WARRANTY; without even the implied warranty of
0011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
0012  * Lesser General Public License for more details.
0013  *
0014  * You should have received a copy of the GNU Lesser General Public
0015  * License along with this library.  If not, see <http://www.gnu.org/licenses/>.
0016  */
0017 
0018 #include "KReportItemField.h"
0019 #include "KReportRenderObjects.h"
0020 #include "KReportUtils.h"
0021 #include "kreportplugin_debug.h"
0022 #ifdef KREPORT_SCRIPTING
0023 #include "KReportScriptHandler.h"
0024 #endif
0025 
0026 #include <KPropertyListData>
0027 #include <KPropertySet>
0028 
0029 #include <QPalette>
0030 #include <QDomNodeList>
0031 #include <QFontMetrics>
0032 #include <QApplication>
0033 
0034 KReportItemField::KReportItemField()
0035 {
0036     createProperties();
0037 }
0038 
0039 KReportItemField::KReportItemField(const QDomNode & element)
0040     : KReportItemField()
0041 {
0042     nameProperty()->setValue(KReportUtils::readNameAttribute(element.toElement()));
0043     setItemDataSource(element.toElement().attribute(QLatin1String("report:item-data-source")));
0044     m_itemValue->setValue(element.toElement().attribute(QLatin1String("report:value")));
0045     setZ(element.toElement().attribute(QLatin1String("report:z-index")).toDouble());
0046     m_horizontalAlignment->setValue(element.toElement().attribute(QLatin1String("report:horizontal-align")));
0047     m_verticalAlignment->setValue(element.toElement().attribute(QLatin1String("report:vertical-align")));
0048     KReportUtils::setPropertyValue(m_canGrow, element.toElement());
0049     KReportUtils::setPropertyValue(m_wordWrap, element.toElement());
0050 
0051     parseReportRect(element.toElement());
0052 
0053     QDomNodeList nl = element.childNodes();
0054     QString n;
0055     QDomNode node;
0056     for (int i = 0; i < nl.count(); i++) {
0057         node = nl.item(i);
0058         n = node.nodeName();
0059 
0060         if (n == QLatin1String("report:text-style")) {
0061             KReportTextStyleData ts;
0062             if (parseReportTextStyleData(node.toElement(), &ts)) {
0063                 m_backgroundColor->setValue(ts.backgroundColor);
0064                 m_foregroundColor->setValue(ts.foregroundColor);
0065                 m_backgroundOpacity->setValue(ts.backgroundOpacity);
0066                 m_font->setValue(ts.font);
0067 
0068             }
0069         } else if (n == QLatin1String("report:line-style")) {
0070             KReportLineStyle ls;
0071             if (parseReportLineStyleData(node.toElement(), &ls)) {
0072                 m_lineWeight->setValue(ls.weight());
0073                 m_lineColor->setValue(ls.color());
0074                 m_lineStyle->setValue(static_cast<int>(ls.penStyle()));
0075             }
0076         } else {
0077             kreportpluginWarning() << "while parsing field element encountered unknown element: " << n;
0078         }
0079     }
0080 }
0081 
0082 KReportItemField::~KReportItemField()
0083 {
0084 }
0085 
0086 void KReportItemField::createProperties()
0087 {
0088     createDataSourceProperty();
0089 
0090     m_itemValue = new KProperty("value", QString(), tr("Value"), tr("Value used if not bound to a field"));
0091 
0092     KPropertyListData *listData = new KPropertyListData(
0093         { QLatin1String("left"), QLatin1String("center"), QLatin1String("right") },
0094         QVariantList{ tr("Left"), tr("Center"), tr("Right") });
0095     m_horizontalAlignment = new KProperty("horizontal-align", listData, QLatin1String("left"),
0096                                           tr("Horizontal Alignment"));
0097 
0098     listData = new KPropertyListData(
0099         { QLatin1String("top"), QLatin1String("center"), QLatin1String("bottom") },
0100         QVariantList{ tr("Top"), tr("Center"), tr("Bottom") });
0101     m_verticalAlignment = new KProperty("vertical-align", listData, QLatin1String("center"),
0102                                         tr("Vertical Alignment"));
0103 
0104     m_font = new KProperty("font", QApplication::font(), tr("Font"));
0105 
0106     m_backgroundColor = new KProperty("background-color", QColor(Qt::white), tr("Background Color"));
0107     m_foregroundColor = new KProperty("foreground-color", QColor(Qt::black), tr("Foreground Color"));
0108 
0109     m_backgroundOpacity = new KProperty("background-opacity", QVariant(0), tr("Background Opacity"));
0110     m_backgroundOpacity->setOption("max", 100);
0111     m_backgroundOpacity->setOption("min", 0);
0112     m_backgroundOpacity->setOption("suffix", QLatin1String("%"));
0113 
0114     m_lineWeight = new KProperty("line-weight", 1.0, tr("Line Weight"));
0115     m_lineWeight->setOption("step", 1.0);
0116     m_lineColor = new KProperty("line-color", QColor(Qt::black), tr("Line Color"));
0117     m_lineStyle = new KProperty("line-style", static_cast<int>(Qt::NoPen), tr("Line Style"), QString(), KProperty::LineStyle);
0118 
0119     m_wordWrap = new KProperty("word-wrap", QVariant(false), tr("Word Wrap"));
0120     m_canGrow = new KProperty("can-grow", QVariant(false), tr("Can Grow"));
0121 
0122     //! @todo I do not think we need these
0123 #if 0 //Field Totals
0124     m_trackTotal = new KProperty("trackTotal", QVariant(false), futureI18n("Track Total"));
0125     m_trackBuiltinFormat = new KProperty("trackBuiltinFormat", QVariant(false), futureI18n("Track Builtin Format"));
0126     _useSubTotal = new KProperty("useSubTotal", QVariant(false), futureI18n("Use Sub Total"_));
0127     _trackTotalFormat = new KProperty("trackTotalFormat", QString(), futureI18n("Track Total Format"));
0128 #endif
0129 
0130     propertySet()->addProperty(m_itemValue);
0131     propertySet()->addProperty(m_horizontalAlignment);
0132     propertySet()->addProperty(m_verticalAlignment);
0133     propertySet()->addProperty(m_font);
0134     propertySet()->addProperty(m_backgroundColor);
0135     propertySet()->addProperty(m_foregroundColor);
0136     propertySet()->addProperty(m_backgroundOpacity);
0137     propertySet()->addProperty(m_lineWeight);
0138     propertySet()->addProperty(m_lineColor);
0139     propertySet()->addProperty(m_lineStyle);
0140     propertySet()->addProperty(m_wordWrap);
0141     propertySet()->addProperty(m_canGrow);
0142 
0143     //_set->addProperty ( _trackTotal );
0144     //_set->addProperty ( _trackBuiltinFormat );
0145     //_set->addProperty ( _useSubTotal );
0146     //_set->addProperty ( _trackTotalFormat );
0147 }
0148 
0149 int KReportItemField::textFlags() const
0150 {
0151     int flags;
0152     QString t;
0153     t = m_horizontalAlignment->value().toString();
0154     if (t == QLatin1String("center"))
0155         flags = Qt::AlignHCenter;
0156     else if (t == QLatin1String("right"))
0157         flags = Qt::AlignRight;
0158     else
0159         flags = Qt::AlignLeft;
0160 
0161     t = m_verticalAlignment->value().toString();
0162     if (t == QLatin1String("center"))
0163         flags |= Qt::AlignVCenter;
0164     else if (t == QLatin1String("bottom"))
0165         flags |= Qt::AlignBottom;
0166     else
0167         flags |= Qt::AlignTop;
0168 
0169     if (m_wordWrap->value().toBool() == true) {
0170         flags |= Qt::TextWordWrap;
0171     }
0172     return flags;
0173 }
0174 
0175 KReportTextStyleData KReportItemField::textStyle() const
0176 {
0177     KReportTextStyleData d;
0178     d.backgroundColor = m_backgroundColor->value().value<QColor>();
0179     d.foregroundColor = m_foregroundColor->value().value<QColor>();
0180     d.font = m_font->value().value<QFont>();
0181     d.backgroundOpacity = m_backgroundOpacity->value().toInt();
0182 
0183     return d;
0184 }
0185 
0186 KReportLineStyle KReportItemField::lineStyle() const
0187 {
0188     KReportLineStyle ls;
0189     ls.setWeight(m_lineWeight->value().toReal());
0190     ls.setColor(m_lineColor->value().value<QColor>());
0191     ls.setPenStyle((Qt::PenStyle)m_lineStyle->value().toInt());
0192     return ls;
0193 }
0194 // RTTI
0195 QString KReportItemField::typeName() const
0196 {
0197     return QLatin1String("field");
0198 }
0199 
0200 int KReportItemField::renderSimpleData(OROPage *page, OROSection *section, const QPointF &offset,
0201                                         const QVariant &data, KReportScriptHandler *script)
0202 {
0203     OROTextBox * tb = new OROTextBox();
0204     tb->setPosition(scenePosition(position()) + offset);
0205     tb->setSize(sceneSize(size()));
0206     tb->setFont(font());
0207     tb->setFlags(textFlags());
0208     tb->setTextStyle(textStyle());
0209     tb->setLineStyle(lineStyle());
0210     tb->setCanGrow(m_canGrow->value().toBool());
0211     tb->setWordWrap(m_wordWrap->value().toBool());
0212 
0213     QString str;
0214 
0215     QString ids = itemDataSource();
0216     if (!ids.isEmpty()) {
0217 #ifdef KREPORT_SCRIPTING
0218         if (ids.left(1) == QLatin1String("=") && script) { //Everything after = is treated as code
0219             if (!ids.contains(QLatin1String("PageTotal()"))) {
0220                 QVariant v = script->evaluate(ids.mid(1));
0221                 str = v.toString();
0222             } else {
0223                 str = ids.mid(1);
0224                 tb->setRequiresPostProcessing(true);
0225             }
0226         } else
0227 #else
0228         Q_UNUSED(script);
0229 #endif
0230         str = data.toString();
0231     } else {
0232         str = m_itemValue->value().toString();
0233     }
0234 
0235     tb->setText(str);
0236 
0237     //Work out the size of the text
0238     if (tb->canGrow()) {
0239         QRectF r;
0240         if (tb->wordWrap()) {
0241             //Grow vertically
0242             QFontMetricsF metrics(font());
0243             QRectF temp(tb->position().x(), tb->position().y(), tb->size().width(), 5000); // a large vertical height
0244             r = metrics.boundingRect(temp, tb->flags(), str);
0245         } else {
0246             //Grow Horizontally
0247             QFontMetricsF metrics(font());
0248             QRectF temp(tb->position().x(), tb->position().y(), 5000, tb->size().height()); // a large vertical height
0249             r = metrics.boundingRect(temp, tb->flags(), str);
0250         }
0251         tb->setSize(r.size() + QSize(4,4));
0252     }
0253 
0254     if (page) {
0255         page->insertPrimitive(tb);
0256     }
0257 
0258     if (section) {
0259         OROPrimitive *clone = tb->clone();
0260         clone->setPosition(scenePosition(position()));
0261         section->addPrimitive(clone);
0262     }
0263     int height = scenePosition(position()).y() + tb->size().height();
0264     //If there is no page to add the item to, delete it now because it wont be deleted later
0265     if (!page) {
0266         delete tb;
0267     }
0268     return height;
0269 }