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

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 "KReportDesignerSectionScene.h"
0020 #include "KReportDesignerItemRectBase.h"
0021 #include "KReportDesigner.h"
0022 #include "KReportLabelSizeInfo.h"
0023 #include "KReportUtils_p.h"
0024 #include "kreport_debug.h"
0025 
0026 #include <QPainter>
0027 #include <QApplication>
0028 #include <QGraphicsItem>
0029 #include <QGraphicsSceneMouseEvent>
0030 
0031 KReportDesignerSectionScene::KReportDesignerSectionScene(qreal w, qreal h, KReportDesigner *rd)
0032         : QGraphicsScene(0, 0, w, h, rd), m_rd(rd)
0033 {
0034     m_dpiX = KReportPrivate::dpiX();
0035     m_dpiY = KReportPrivate::dpiY();
0036 
0037     if (m_unit.type() != m_rd->pageUnit().type()) {
0038         m_unit = m_rd->pageUnit();
0039         if (m_unit.type() == KReportUnit::Type::Cicero ||
0040             m_unit.type() == KReportUnit::Type::Pica ||
0041             m_unit.type() == KReportUnit::Type::Millimeter) {
0042             m_majorX = POINT_TO_INCH(m_unit.fromUserValue(10)) * m_dpiX;
0043             m_majorY = POINT_TO_INCH(m_unit.fromUserValue(10)) * m_dpiY;
0044         } else if (m_unit.type() == KReportUnit::Type::Point) {
0045             m_majorX = POINT_TO_INCH(m_unit.fromUserValue(100)) * m_dpiX;
0046             m_majorY = POINT_TO_INCH(m_unit.fromUserValue(100)) * m_dpiY;
0047         } else {
0048             m_majorX = POINT_TO_INCH(m_unit.fromUserValue(1)) * m_dpiX;
0049             m_majorY = POINT_TO_INCH(m_unit.fromUserValue(1)) * m_dpiY;
0050         }
0051     }
0052 }
0053 KReportDesignerSectionScene::~KReportDesignerSectionScene()
0054 {
0055     // Qt should be handling everything for us
0056 }
0057 
0058 void KReportDesignerSectionScene::drawBackground(QPainter* painter, const QRectF & clip)
0059 {
0060     //Draw the default background colour
0061     QGraphicsScene::drawBackground(painter, clip);
0062     painter->setRenderHint(QPainter::Antialiasing, false);
0063 
0064     if (m_rd->propertySet()->property("grid-visible").value().toBool()) {
0065         m_unit = m_rd->pageUnit();
0066         if (m_unit.type() == KReportUnit::Type::Cicero ||
0067             m_unit.type() == KReportUnit::Type::Pica ||
0068             m_unit.type() == KReportUnit::Type::Millimeter) {
0069             m_majorX = POINT_TO_INCH(m_unit.fromUserValue(10)) * m_dpiX;
0070             m_majorY = POINT_TO_INCH(m_unit.fromUserValue(10)) * m_dpiY;
0071         } else if (m_unit.type() == KReportUnit::Type::Point) {
0072             m_majorX = POINT_TO_INCH(m_unit.fromUserValue(100)) * m_dpiX;
0073             m_majorY = POINT_TO_INCH(m_unit.fromUserValue(100)) * m_dpiY;
0074         } else {
0075             m_majorX = POINT_TO_INCH(m_unit.fromUserValue(1)) * m_dpiX;
0076             m_majorY = POINT_TO_INCH(m_unit.fromUserValue(1)) * m_dpiY;
0077         }
0078 
0079         int minorSteps = m_rd->propertySet()->property("grid-divisions").value().toInt();
0080         m_pixelIncrementX = (m_majorX / minorSteps);
0081         m_pixelIncrementY = (m_majorY / minorSteps);
0082 
0083         QPen pen = painter->pen();
0084         painter->setPen(Qt::lightGray);
0085 
0086         //kreportDebug() << "dpix" << KReportPrivate::dpiX() << "dpiy" << KReportPrivate::dpiY() << "mayorx:" << majorx << "majory" << majory << "pix:" << pixel_incrementx << "piy:" << pixel_incrementy;
0087 
0088         QVector<QLine> lines;
0089         QVector<QPoint> points;
0090 
0091         if (m_pixelIncrementX > 2) { // do not bother painting points if increments are so small
0092             int wpoints = qRound(sceneRect().width() / m_pixelIncrementX);
0093             int hpoints = qRound(sceneRect().height() / m_pixelIncrementY);
0094             for (int i = 0; i < wpoints; ++i) {
0095                 for (int j = 0; j < hpoints; ++j) {
0096                     //if (clip.contains(i * pixel_incrementx, j * pixel_incrementy)){
0097                     if (i % minorSteps == 0 && j % minorSteps == 0) {
0098                         lines << QLine(QPoint(i * m_pixelIncrementX, j * m_pixelIncrementY), QPoint(i * m_pixelIncrementX, j * m_pixelIncrementY  + m_majorX));
0099                         //painter->drawLine();
0100                         lines << QLine(QPoint(i * m_pixelIncrementX, j * m_pixelIncrementY), QPoint(i * m_pixelIncrementX + m_majorY, j * m_pixelIncrementY));
0101                         //painter->drawLine();
0102                     } else {
0103                         points << QPoint(i * m_pixelIncrementX, j * m_pixelIncrementY);
0104                         //painter->drawPoint();
0105                     }
0106                     //}
0107                 }
0108             }
0109             painter->drawPoints(points);
0110             painter->drawLines(lines);
0111 
0112         }
0113 
0114         pen.setWidth(1);
0115         //update ( clip );
0116     }
0117 }
0118 
0119 void KReportDesignerSectionScene::mousePressEvent(QGraphicsSceneMouseEvent * e)
0120 {
0121     // clear the selection if Shift Key has not been pressed and it's a left mouse button   and
0122     // if the right mouse button has been pressed over an item which is not part of selected items
0123     if (((e->modifiers() & Qt::ShiftModifier) == 0 && e->button() == Qt::LeftButton)   ||
0124             (!(selectedItems().contains(itemAt(e->scenePos(), QTransform()))) && e->button() == Qt::RightButton))
0125         clearSelection();
0126 
0127     //This will be caught by the section to display its properties, if an item is under the cursor then they will display their properties
0128     QGraphicsItem* itemUnderCursor = itemAt(e->scenePos(), QTransform());
0129     emit clicked();
0130 
0131     KReportDesignerItemRectBase *rectUnderCursor = qgraphicsitem_cast< KReportDesignerItemRectBase* >(itemUnderCursor);
0132     if (itemUnderCursor && !rectUnderCursor) {
0133         rectUnderCursor = qgraphicsitem_cast< KReportDesignerItemRectBase* >(itemUnderCursor->parentItem());
0134     }
0135     exitInlineEditingModeInItems(rectUnderCursor);
0136 
0137     QGraphicsScene::mousePressEvent(e);
0138 }
0139 
0140 void KReportDesignerSectionScene::contextMenuEvent(QGraphicsSceneContextMenuEvent * e)
0141 {
0142     m_rd->sectionContextMenuEvent(this, e);
0143 }
0144 
0145 QPointF KReportDesignerSectionScene::gridPoint(const QPointF& p)
0146 {
0147     if (!m_rd->propertySet()->property("grid-snap").value().toBool()) {
0148         return p;
0149     }
0150 
0151     if (m_unit.type() != m_rd->pageUnit().type()) {
0152         m_unit = m_rd->pageUnit();
0153         if (m_unit.type() == KReportUnit::Type::Cicero ||
0154             m_unit.type() == KReportUnit::Type::Pica ||
0155             m_unit.type() == KReportUnit::Type::Millimeter) {
0156             m_majorX = POINT_TO_INCH(m_unit.fromUserValue(10)) * m_dpiX;
0157             m_majorY = POINT_TO_INCH(m_unit.fromUserValue(10)) * m_dpiY;
0158         } else if (m_unit.type() == KReportUnit::Type::Point) {
0159             m_majorX = POINT_TO_INCH(m_unit.fromUserValue(100)) * m_dpiX;
0160             m_majorY = POINT_TO_INCH(m_unit.fromUserValue(100)) * m_dpiY;
0161         } else {
0162             m_majorX = POINT_TO_INCH(m_unit.fromUserValue(1)) * m_dpiX;
0163             m_majorY = POINT_TO_INCH(m_unit.fromUserValue(1)) * m_dpiY;
0164         }
0165     }
0166     int minorSteps = m_rd->propertySet()->property("grid-divisions").value().toInt();
0167     m_pixelIncrementX = (m_majorX / minorSteps);
0168     m_pixelIncrementY = (m_majorY / minorSteps);
0169 
0170     return QPointF(qRound((p.x() / m_pixelIncrementX)) * m_pixelIncrementX, qRound((p.y() / m_pixelIncrementY)) * m_pixelIncrementY);
0171 }
0172 
0173 void KReportDesignerSectionScene::focusOutEvent(QFocusEvent * focusEvent)
0174 {
0175     exitInlineEditingModeInItems(nullptr);
0176 
0177     emit lostFocus();
0178     QGraphicsScene::focusOutEvent(focusEvent);
0179 }
0180 
0181 qreal KReportDesignerSectionScene::lowestZValue()
0182 {
0183     qreal z;
0184     qreal zz;
0185     z = 0;
0186     QGraphicsItemList list = items();
0187     for (QGraphicsItemList::iterator it = list.begin(); it != list.end(); ++it) {
0188         zz = (*it)->zValue();
0189         if (zz < z) {
0190             z = zz;
0191         }
0192 
0193     }
0194     return z;
0195 }
0196 
0197 qreal KReportDesignerSectionScene::highestZValue()
0198 {
0199     qreal z;
0200     qreal zz;
0201     z = 0;
0202     QGraphicsItemList list = items();
0203     for (QGraphicsItemList::iterator it = list.begin(); it != list.end(); ++it) {
0204         zz = (*it)->zValue();
0205         if (zz > z) {
0206             z = zz;
0207         }
0208     }
0209     return z;
0210 }
0211 
0212 void KReportDesignerSectionScene::lowerSelected()
0213 {
0214     QGraphicsItemList list = selectedItems();
0215     for (QGraphicsItemList::iterator it = list.begin();
0216             it != list.end(); ++it) {
0217         (*it)->setZValue(lowestZValue() - 1);
0218     }
0219 }
0220 
0221 void KReportDesignerSectionScene::raiseSelected()
0222 {
0223     QGraphicsItemList list = selectedItems();
0224     for (QGraphicsItemList::iterator it = list.begin();
0225             it != list.end(); ++it) {
0226         (*it)->setZValue(highestZValue() + 1);
0227     }
0228 }
0229 
0230 QGraphicsItemList KReportDesignerSectionScene::itemsOrdered() const
0231 {
0232     QGraphicsItemList r;
0233     QGraphicsItemList list = items();
0234     for (QGraphicsItemList::iterator it = list.begin(); it != list.end(); ++it) {
0235         for (QGraphicsItemList::iterator rit = r.begin(); rit != r.end(); ++rit) {
0236 
0237         }
0238     }
0239 
0240     return r;
0241 }
0242 
0243 void KReportDesignerSectionScene::exitInlineEditingModeInItems(KReportDesignerItemRectBase *rectUnderCursor)
0244 {
0245     foreach(QGraphicsItem *it, items()) {
0246         KReportDesignerItemRectBase *itm = qgraphicsitem_cast< KReportDesignerItemRectBase* >(it);
0247         if (itm && itm != rectUnderCursor) {
0248             itm->exitInlineEditingMode();
0249         }
0250     }
0251 }