File indexing completed on 2024-04-28 04:42:09

0001 /* This file is part of the KDE project
0002  * Copyright (C) 2001-2007 by OpenMFG, LLC (info@openmfg.com)
0003  * Copyright (C) 2007-2008 by Adam Pigg (adam@piggz.co.uk)
0004  *
0005  * This library is free software; you can redistribute it and/or
0006  * modify it under the terms of the GNU Lesser General Public
0007  * License as published by the Free Software Foundation; either
0008  * version 2.1 of the License, or (at your option) any later version.
0009  *
0010  * This library is distributed in the hope that it will be useful,
0011  * but WITHOUT ANY WARRANTY; without even the implied warranty of
0012  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
0013  * Lesser General Public License for more details.
0014  *
0015  * You should have received a copy of the GNU Lesser General Public
0016  * License along with this library.  If not, see <http://www.gnu.org/licenses/>.
0017  */
0018 
0019 #include "KReportDesignerItemLine.h"
0020 #include "KReportDesignerItemBase.h"
0021 #include "KReportDesigner.h"
0022 #include "KReportDesignerSectionScene.h"
0023 #include "KReportUtils.h"
0024 #include "KReportLineStyle.h"
0025 
0026 #include <QDomDocument>
0027 #include <QPainter>
0028 #include <QGraphicsScene>
0029 #include <QGraphicsSceneMouseEvent>
0030 
0031 //
0032 // class ReportEntityLine
0033 //
0034 void KReportDesignerItemLine::init(QGraphicsScene* s, KReportDesigner *r)
0035 {
0036     setPos(0, 0);
0037     setUnit(r->pageUnit());
0038 
0039     nameProperty()->setValue(r->suggestEntityName(typeName()));
0040     
0041     setFlags(ItemIsSelectable | ItemIsMovable | ItemSendsGeometryChanges);
0042 
0043     setPen(QPen(Qt::black, 5));
0044     setAcceptHoverEvents(true);
0045 
0046     if (s)
0047         s->addItem(this);
0048 
0049     setZValue(z());
0050 }
0051 
0052 KReportDesignerItemLine::KReportDesignerItemLine(KReportDesigner * d, QGraphicsScene * scene, const QPointF &pos)
0053         : KReportDesignerItemBase(d, this)
0054 {
0055     init(scene, d);
0056     setLineScene(QLineF(pos, QPointF(20,20)+pos));
0057     
0058 }
0059 
0060 KReportDesignerItemLine::KReportDesignerItemLine(KReportDesigner * d, QGraphicsScene * scene, const QPointF &startPos, const QPointF &endPos)
0061         : KReportDesignerItemBase(d, this)
0062 {
0063     init(scene, d);
0064     setLineScene(QLineF(startPos, endPos));
0065 }
0066 
0067 KReportDesignerItemLine::KReportDesignerItemLine(const QDomNode & entity, KReportDesigner * d, QGraphicsScene * scene)
0068         : KReportItemLine(entity), KReportDesignerItemBase(d, this)
0069 {
0070     init(scene, d);
0071     QPointF s = scenePosition(startPosition());
0072     QPointF e = scenePosition(endPosition());
0073     
0074     setLine ( s.x(), s.y(), e.x(), e.y() );
0075 }
0076 
0077 KReportDesignerItemLine::~KReportDesignerItemLine()
0078 {
0079 }
0080 
0081 KReportDesignerItemLine* KReportDesignerItemLine::clone()
0082 {
0083     QDomDocument d;
0084     QDomElement e = d.createElement(QLatin1String("clone"));
0085     QDomNode n;
0086     buildXML(&d, &e);
0087     n = e.firstChild();
0088     return new KReportDesignerItemLine(n, designer(), nullptr);
0089 }
0090 
0091 void KReportDesignerItemLine::paint(QPainter* painter, const QStyleOptionGraphicsItem* option,
0092                              QWidget *widget)
0093 {
0094     Q_UNUSED(option);
0095     Q_UNUSED(widget);
0096 
0097     painter->setRenderHint(QPainter::Antialiasing, true);
0098     QPen p = painter->pen();
0099     painter->setPen(QPen(m_lineColor->value().value<QColor>(), m_lineWeight->value().toInt(), (Qt::PenStyle)m_lineStyle->value().toInt()));
0100     painter->drawLine(line());
0101     if (isSelected()) {
0102 
0103         // draw a selected border for visual purposes
0104         painter->setPen(QPen(QColor(128, 128, 255), 0, Qt::DotLine));
0105         QPointF pt = line().p1();
0106         painter->fillRect(pt.x(), pt.y() - 2, 5, 5, QColor(128, 128, 255));
0107         pt = line().p2();
0108         painter->fillRect(pt.x() - 4, pt.y() - 2, 5, 5, QColor(128, 128, 255));
0109 
0110         painter->setPen(p);
0111     }
0112 }
0113 
0114 void KReportDesignerItemLine::buildXML(QDomDocument *doc, QDomElement *parent)
0115 {
0116     QDomElement entity = doc->createElement(QLatin1String("report:") + typeName());
0117 
0118     // properties
0119     addPropertyAsAttribute(&entity, nameProperty());
0120     entity.setAttribute(QLatin1String("report:z-index"), zValue());
0121     KReportUtils::setAttribute(&entity, QLatin1String("svg:x1"), startPosition().x());
0122     KReportUtils::setAttribute(&entity, QLatin1String("svg:y1"), startPosition().y());
0123     KReportUtils::setAttribute(&entity, QLatin1String("svg:x2"), endPosition().x());
0124     KReportUtils::setAttribute(&entity, QLatin1String("svg:y2"), endPosition().y());
0125 
0126     buildXMLLineStyle(doc, &entity, lineStyle());
0127 
0128     parent->appendChild(entity);
0129 }
0130 
0131 void KReportDesignerItemLine::propertyChanged(KPropertySet &s, KProperty &p)
0132 {
0133     Q_UNUSED(s);
0134 
0135     if (p.name() == "startposition" || p.name() == "endposition") {
0136         QPointF s = scenePosition(startPosition());
0137         QPointF e = scenePosition(endPosition());
0138         
0139         setLine ( s.x(), s.y(), e.x(), e.y() );
0140     }
0141     else if (p.name() == "name") {
0142         //For some reason p.oldValue returns an empty string
0143         if (!designer()->isEntityNameUnique(p.value().toString(), this)) {
0144             p.setValue(oldName());
0145         } else {
0146             setOldName(p.value().toString());
0147         }
0148     }
0149     if (designer())
0150         designer()->setModified(true);
0151 
0152     update();
0153 }
0154 
0155 void KReportDesignerItemLine::mousePressEvent(QGraphicsSceneMouseEvent * event)
0156 {
0157     designer()->changeSet(propertySet());
0158     setSelected(true);
0159     QGraphicsLineItem::mousePressEvent(event);
0160 }
0161 
0162 QVariant KReportDesignerItemLine::itemChange(GraphicsItemChange change, const QVariant &value)
0163 {
0164     return QGraphicsItem::itemChange(change, value);
0165 }
0166 
0167 void KReportDesignerItemLine::mouseReleaseEvent(QGraphicsSceneMouseEvent * event)
0168 {
0169     QGraphicsLineItem::mouseReleaseEvent(event);
0170 }
0171 
0172 void KReportDesignerItemLine::mouseMoveEvent(QGraphicsSceneMouseEvent * event)
0173 {
0174     int x;
0175     int y;
0176 
0177     KReportDesignerSectionScene *section = qobject_cast<KReportDesignerSectionScene*>(scene());
0178     if (!section) {
0179         return;
0180     }
0181         
0182     QPointF p = section->gridPoint(event->scenePos());
0183     //kreportDebug() << p;
0184     x = p.x();
0185     y = p.y();
0186 
0187     if (x < 0) x = 0;
0188     if (y < 0) y = 0;
0189     if (x > scene()->width()) x = scene()->width();
0190     if (y > scene()->height()) y = scene()->height();
0191 
0192     switch (m_grabAction) {
0193     case 1:
0194         setStartPosition(positionFromScene(QPointF(x,y)));
0195         break;
0196     case 2:
0197         setEndPosition(positionFromScene(QPointF(x,y)));
0198         break;
0199     default:
0200         QPointF d = mapToItem(this, section->gridPoint(event->scenePos())) - mapToItem(this, section->gridPoint(event->lastScenePos()));
0201 
0202         if (((line().p1() + d).x() >= 0) &&
0203                 ((line().p2() + d).x() >= 0) &&
0204                 ((line().p1() + d).y() >= 0) &&
0205                 ((line().p2() + d).y() >= 0)  &&
0206                 ((line().p1() + d).x() <= scene()->width()) &&
0207                 ((line().p2() + d).x() <= scene()->width()) &&
0208                 ((line().p1() + d).y() <= scene()->height()) &&
0209                 ((line().p2() + d).y() <= scene()->height()))
0210             setLineScene(QLineF(line().p1() + d, line().p2() + d));
0211         break;
0212     }
0213 }
0214 
0215 int KReportDesignerItemLine::grabHandle(const QPointF &pos)
0216 {
0217     if (QRectF(line().p1().x(), line().p1().y() - 2, 5, 5).contains(pos)) {
0218         // we are over point 1
0219         return 1;
0220     } else if (QRectF(line().p2().x() - 4, line().p2().y() - 2, 5, 5).contains(pos)) {
0221         // we are over point 2
0222         return 2;
0223     } else {
0224         return 0;
0225     }
0226 
0227 }
0228 
0229 void KReportDesignerItemLine::hoverMoveEvent(QGraphicsSceneHoverEvent * event)
0230 {
0231     if (isSelected()) {
0232         m_grabAction = grabHandle(event->pos());
0233         switch (m_grabAction) {
0234         case 1: //Point 1
0235             setCursor(Qt::SizeAllCursor);
0236             break;
0237         case 2: //Point 2
0238             setCursor(Qt::SizeAllCursor);
0239             break;
0240         default:
0241             unsetCursor();
0242         }
0243     }
0244 }
0245 
0246 void KReportDesignerItemLine::setLineScene(const QLineF &line)
0247 {
0248     setStartPosition(positionFromScene(line.p1()));
0249     setEndPosition(positionFromScene(line.p2()));
0250     setLine(line);
0251 }
0252 
0253 void KReportDesignerItemLine::move(const QPointF& m)
0254 {
0255     QPointF original = scenePosition(position());
0256     original += m;
0257     
0258     setPosition(positionFromScene(original));
0259 }