1 /* This file is part of the KDE project
2  * Copyright (C) 2001-2007 by OpenMFG, LLC (info@openmfg.com)
3  * Copyright (C) 2007-2008 by Adam Pigg (adam@piggz.co.uk)
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2.1 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this library.  If not, see <http://www.gnu.org/licenses/>.
17  */
18 
19 #include "KReportDesignerSectionScene.h"
20 #include "KReportDesignerItemRectBase.h"
21 #include "KReportDesigner.h"
22 #include "KReportLabelSizeInfo.h"
23 #include "KReportUtils_p.h"
24 #include "kreport_debug.h"
25 
26 #include <QPainter>
27 #include <QApplication>
28 #include <QGraphicsItem>
29 #include <QGraphicsSceneMouseEvent>
30 
KReportDesignerSectionScene(qreal w,qreal h,KReportDesigner * rd)31 KReportDesignerSectionScene::KReportDesignerSectionScene(qreal w, qreal h, KReportDesigner *rd)
32         : QGraphicsScene(0, 0, w, h, rd), m_rd(rd)
33 {
34     m_dpiX = KReportPrivate::dpiX();
35     m_dpiY = KReportPrivate::dpiY();
36 
37     if (m_unit.type() != m_rd->pageUnit().type()) {
38         m_unit = m_rd->pageUnit();
39         if (m_unit.type() == KReportUnit::Type::Cicero ||
40             m_unit.type() == KReportUnit::Type::Pica ||
41             m_unit.type() == KReportUnit::Type::Millimeter) {
42             m_majorX = POINT_TO_INCH(m_unit.fromUserValue(10)) * m_dpiX;
43             m_majorY = POINT_TO_INCH(m_unit.fromUserValue(10)) * m_dpiY;
44         } else if (m_unit.type() == KReportUnit::Type::Point) {
45             m_majorX = POINT_TO_INCH(m_unit.fromUserValue(100)) * m_dpiX;
46             m_majorY = POINT_TO_INCH(m_unit.fromUserValue(100)) * m_dpiY;
47         } else {
48             m_majorX = POINT_TO_INCH(m_unit.fromUserValue(1)) * m_dpiX;
49             m_majorY = POINT_TO_INCH(m_unit.fromUserValue(1)) * m_dpiY;
50         }
51     }
52 }
~KReportDesignerSectionScene()53 KReportDesignerSectionScene::~KReportDesignerSectionScene()
54 {
55     // Qt should be handling everything for us
56 }
57 
drawBackground(QPainter * painter,const QRectF & clip)58 void KReportDesignerSectionScene::drawBackground(QPainter* painter, const QRectF & clip)
59 {
60     //Draw the default background colour
61     QGraphicsScene::drawBackground(painter, clip);
62     painter->setRenderHint(QPainter::Antialiasing, false);
63 
64     if (m_rd->propertySet()->property("grid-visible").value().toBool()) {
65         m_unit = m_rd->pageUnit();
66         if (m_unit.type() == KReportUnit::Type::Cicero ||
67             m_unit.type() == KReportUnit::Type::Pica ||
68             m_unit.type() == KReportUnit::Type::Millimeter) {
69             m_majorX = POINT_TO_INCH(m_unit.fromUserValue(10)) * m_dpiX;
70             m_majorY = POINT_TO_INCH(m_unit.fromUserValue(10)) * m_dpiY;
71         } else if (m_unit.type() == KReportUnit::Type::Point) {
72             m_majorX = POINT_TO_INCH(m_unit.fromUserValue(100)) * m_dpiX;
73             m_majorY = POINT_TO_INCH(m_unit.fromUserValue(100)) * m_dpiY;
74         } else {
75             m_majorX = POINT_TO_INCH(m_unit.fromUserValue(1)) * m_dpiX;
76             m_majorY = POINT_TO_INCH(m_unit.fromUserValue(1)) * m_dpiY;
77         }
78 
79         int minorSteps = m_rd->propertySet()->property("grid-divisions").value().toInt();
80         m_pixelIncrementX = (m_majorX / minorSteps);
81         m_pixelIncrementY = (m_majorY / minorSteps);
82 
83         QPen pen = painter->pen();
84         painter->setPen(Qt::lightGray);
85 
86         //kreportDebug() << "dpix" << KReportPrivate::dpiX() << "dpiy" << KReportPrivate::dpiY() << "mayorx:" << majorx << "majory" << majory << "pix:" << pixel_incrementx << "piy:" << pixel_incrementy;
87 
88         QVector<QLine> lines;
89         QVector<QPoint> points;
90 
91         if (m_pixelIncrementX > 2) { // do not bother painting points if increments are so small
92             int wpoints = qRound(sceneRect().width() / m_pixelIncrementX);
93             int hpoints = qRound(sceneRect().height() / m_pixelIncrementY);
94             for (int i = 0; i < wpoints; ++i) {
95                 for (int j = 0; j < hpoints; ++j) {
96                     //if (clip.contains(i * pixel_incrementx, j * pixel_incrementy)){
97                     if (i % minorSteps == 0 && j % minorSteps == 0) {
98                         lines << QLine(QPoint(i * m_pixelIncrementX, j * m_pixelIncrementY), QPoint(i * m_pixelIncrementX, j * m_pixelIncrementY  + m_majorX));
99                         //painter->drawLine();
100                         lines << QLine(QPoint(i * m_pixelIncrementX, j * m_pixelIncrementY), QPoint(i * m_pixelIncrementX + m_majorY, j * m_pixelIncrementY));
101                         //painter->drawLine();
102                     } else {
103                         points << QPoint(i * m_pixelIncrementX, j * m_pixelIncrementY);
104                         //painter->drawPoint();
105                     }
106                     //}
107                 }
108             }
109             painter->drawPoints(points);
110             painter->drawLines(lines);
111 
112         }
113 
114         pen.setWidth(1);
115         //update ( clip );
116     }
117 }
118 
mousePressEvent(QGraphicsSceneMouseEvent * e)119 void KReportDesignerSectionScene::mousePressEvent(QGraphicsSceneMouseEvent * e)
120 {
121     // clear the selection if Shift Key has not been pressed and it's a left mouse button   and
122     // if the right mouse button has been pressed over an item which is not part of selected items
123     if (((e->modifiers() & Qt::ShiftModifier) == 0 && e->button() == Qt::LeftButton)   ||
124             (!(selectedItems().contains(itemAt(e->scenePos(), QTransform()))) && e->button() == Qt::RightButton))
125         clearSelection();
126 
127     //This will be caught by the section to display its properties, if an item is under the cursor then they will display their properties
128     QGraphicsItem* itemUnderCursor = itemAt(e->scenePos(), QTransform());
129     emit clicked();
130 
131     KReportDesignerItemRectBase *rectUnderCursor = qgraphicsitem_cast< KReportDesignerItemRectBase* >(itemUnderCursor);
132     if (itemUnderCursor && !rectUnderCursor) {
133         rectUnderCursor = qgraphicsitem_cast< KReportDesignerItemRectBase* >(itemUnderCursor->parentItem());
134     }
135     exitInlineEditingModeInItems(rectUnderCursor);
136 
137     QGraphicsScene::mousePressEvent(e);
138 }
139 
contextMenuEvent(QGraphicsSceneContextMenuEvent * e)140 void KReportDesignerSectionScene::contextMenuEvent(QGraphicsSceneContextMenuEvent * e)
141 {
142     m_rd->sectionContextMenuEvent(this, e);
143 }
144 
gridPoint(const QPointF & p)145 QPointF KReportDesignerSectionScene::gridPoint(const QPointF& p)
146 {
147     if (!m_rd->propertySet()->property("grid-snap").value().toBool()) {
148         return p;
149     }
150 
151     if (m_unit.type() != m_rd->pageUnit().type()) {
152         m_unit = m_rd->pageUnit();
153         if (m_unit.type() == KReportUnit::Type::Cicero ||
154             m_unit.type() == KReportUnit::Type::Pica ||
155             m_unit.type() == KReportUnit::Type::Millimeter) {
156             m_majorX = POINT_TO_INCH(m_unit.fromUserValue(10)) * m_dpiX;
157             m_majorY = POINT_TO_INCH(m_unit.fromUserValue(10)) * m_dpiY;
158         } else if (m_unit.type() == KReportUnit::Type::Point) {
159             m_majorX = POINT_TO_INCH(m_unit.fromUserValue(100)) * m_dpiX;
160             m_majorY = POINT_TO_INCH(m_unit.fromUserValue(100)) * m_dpiY;
161         } else {
162             m_majorX = POINT_TO_INCH(m_unit.fromUserValue(1)) * m_dpiX;
163             m_majorY = POINT_TO_INCH(m_unit.fromUserValue(1)) * m_dpiY;
164         }
165     }
166     int minorSteps = m_rd->propertySet()->property("grid-divisions").value().toInt();
167     m_pixelIncrementX = (m_majorX / minorSteps);
168     m_pixelIncrementY = (m_majorY / minorSteps);
169 
170     return QPointF(qRound((p.x() / m_pixelIncrementX)) * m_pixelIncrementX, qRound((p.y() / m_pixelIncrementY)) * m_pixelIncrementY);
171 }
172 
focusOutEvent(QFocusEvent * focusEvent)173 void KReportDesignerSectionScene::focusOutEvent(QFocusEvent * focusEvent)
174 {
175     exitInlineEditingModeInItems(nullptr);
176 
177     emit lostFocus();
178     QGraphicsScene::focusOutEvent(focusEvent);
179 }
180 
lowestZValue()181 qreal KReportDesignerSectionScene::lowestZValue()
182 {
183     qreal z;
184     qreal zz;
185     z = 0;
186     QGraphicsItemList list = items();
187     for (QGraphicsItemList::iterator it = list.begin(); it != list.end(); ++it) {
188         zz = (*it)->zValue();
189         if (zz < z) {
190             z = zz;
191         }
192 
193     }
194     return z;
195 }
196 
highestZValue()197 qreal KReportDesignerSectionScene::highestZValue()
198 {
199     qreal z;
200     qreal zz;
201     z = 0;
202     QGraphicsItemList list = items();
203     for (QGraphicsItemList::iterator it = list.begin(); it != list.end(); ++it) {
204         zz = (*it)->zValue();
205         if (zz > z) {
206             z = zz;
207         }
208     }
209     return z;
210 }
211 
lowerSelected()212 void KReportDesignerSectionScene::lowerSelected()
213 {
214     QGraphicsItemList list = selectedItems();
215     for (QGraphicsItemList::iterator it = list.begin();
216             it != list.end(); ++it) {
217         (*it)->setZValue(lowestZValue() - 1);
218     }
219 }
220 
raiseSelected()221 void KReportDesignerSectionScene::raiseSelected()
222 {
223     QGraphicsItemList list = selectedItems();
224     for (QGraphicsItemList::iterator it = list.begin();
225             it != list.end(); ++it) {
226         (*it)->setZValue(highestZValue() + 1);
227     }
228 }
229 
itemsOrdered() const230 QGraphicsItemList KReportDesignerSectionScene::itemsOrdered() const
231 {
232     QGraphicsItemList r;
233     QGraphicsItemList list = items();
234     for (QGraphicsItemList::iterator it = list.begin(); it != list.end(); ++it) {
235         for (QGraphicsItemList::iterator rit = r.begin(); rit != r.end(); ++rit) {
236 
237         }
238     }
239 
240     return r;
241 }
242 
exitInlineEditingModeInItems(KReportDesignerItemRectBase * rectUnderCursor)243 void KReportDesignerSectionScene::exitInlineEditingModeInItems(KReportDesignerItemRectBase *rectUnderCursor)
244 {
245     foreach(QGraphicsItem *it, items()) {
246         KReportDesignerItemRectBase *itm = qgraphicsitem_cast< KReportDesignerItemRectBase* >(it);
247         if (itm && itm != rectUnderCursor) {
248             itm->exitInlineEditingMode();
249         }
250     }
251 }
252