KReport

KReportDesignerItemRectBase.cpp
1 /* This file is part of the KDE project
2  * Copyright (C) 2001-2007 by OpenMFG, LLC ([email protected])
3  * Copyright (C) 2007-2008 by Adam Pigg ([email protected])
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 "KReportDesignerItemRectBase.h"
20 #include "KReportDesignerSectionView.h"
21 #include "KReportDesigner.h"
22 #include "KReportDesignerSectionScene.h"
23 #include "KReportUtils_p.h"
24 
25 #include <KPropertySet>
26 #include <QGraphicsSceneMouseEvent>
27 #include <QApplication>
28 
29 class Q_DECL_HIDDEN KReportDesignerItemRectBase::Private
30 {
31 public:
32  Private();
33  ~Private();
34 
35  int grabAction = 0;
36  int dpiX = KReportPrivate::dpiX();
37  int dpiY = KReportPrivate::dpiY();
38  bool insideSetSceneRect = false;
39 };
40 
41 KReportDesignerItemRectBase::Private::Private()
42 {
43 }
44 
45 KReportDesignerItemRectBase::Private::~Private()
46 {
47 }
48 
49 KReportDesignerItemRectBase::KReportDesignerItemRectBase(KReportDesigner *r, KReportItemBase *b)
51 {
52  setAcceptHoverEvents(true);
53  setFlags(ItemIsSelectable | ItemIsMovable | ItemSendsGeometryChanges);
54 }
55 
56 KReportDesignerItemRectBase::~KReportDesignerItemRectBase()
57 {
58  delete d;
59 }
60 
61 QRectF KReportDesignerItemRectBase::sceneRect()
62 {
63  return QRectF(KReportItemBase::scenePosition(item()->position()), KReportItemBase::sceneSize(item()->size()));
64 }
65 
66 QRectF KReportDesignerItemRectBase::pointRect() const
67 {
68  return QRectF(item()->position(), item()->size());
69 }
70 
71 void KReportDesignerItemRectBase::setSceneRect(const QPointF& topLeft, const QSizeF& size, SceneRectFlag update)
72 {
73  setSceneRect(QRectF(topLeft, size), update);
74 }
75 
76 void KReportDesignerItemRectBase::setSceneRect(const QRectF& rect, SceneRectFlag update)
77 {
78  if (d->insideSetSceneRect) {
79  return;
80  }
81  d->insideSetSceneRect = true;
83  setRect(0, 0, rect.width(), rect.height());
84  if (update == SceneRectFlag::UpdateProperty) {
87  }
88  this->update();
89  d->insideSetSceneRect = false;
90 }
91 
92 void KReportDesignerItemRectBase::mousePressEvent(QGraphicsSceneMouseEvent * event)
93 {
94  //Update and show properties
95  if (item()->dataSourceProperty()) {
96  item()->dataSourceProperty()->setListData(designer()->fieldKeys(), designer()->fieldNames());
97  }
98  item()->setPosition(KReportItemBase::positionFromScene(QPointF(sceneRect().x(), sceneRect().y())));
99  designer()->changeSet(item()->propertySet());
100  setSelected(true);
101  scene()->update();
102 
104 }
105 
106 void KReportDesignerItemRectBase::mouseReleaseEvent(QGraphicsSceneMouseEvent * event)
107 {
108  //Keep the size and position in sync
110  item()->setSize(KReportItemBase::sizeFromScene(QSizeF(rect().width(), rect().height())));
111 
113 }
114 
116 {
117  //kreportDebug() << m_grabAction;
118 
119  qreal w, h;
120 
121  KReportDesignerSectionScene *section = qobject_cast<KReportDesignerSectionScene*>(scene());
122  if (!section) {
123  return;
124  }
125 
126  QPointF p = section->gridPoint(event->scenePos());
127  w = p.x() - scenePos().x();
128  h = p.y() - scenePos().y();
129 
130  //! @todo use an enum for the directions
131 
132  switch (d->grabAction) {
133  case 1:
134  if (sceneRect().y() - p.y() + rect().height() > 0 && sceneRect().x() - p.x() + rect().width() >= 0)
135  setSceneRect(QPointF(p.x(), p.y()), QSizeF(sceneRect().x() - p.x() + rect().width(), sceneRect().y() - p.y() + rect().height()));
136  break;
137  case 2:
138  if (sceneRect().y() - p.y() + rect().height() >= 0)
139  setSceneRect(QPointF(sceneRect().x(), p.y()), QSizeF(rect().width(), sceneRect().y() - p.y() + rect().height()));
140  break;
141  case 3:
142  if (sceneRect().y() - p.y() + rect().height() >= 0 && w >= 0)
143  setSceneRect(QPointF(sceneRect().x(), p.y()), QSizeF(w, sceneRect().y() - p.y() + rect().height()));
144  break;
145  case 4:
146  if (w >= 0)
147  setSceneRect(QPointF(sceneRect().x(), sceneRect().y()), QSizeF(w, (rect().height())));
148  break;
149  case 5:
150  if (h >= 0 && w >= 0)
151  setSceneRect(QPointF(sceneRect().x(), sceneRect().y()), QSizeF(w, h));
152  break;
153  case 6:
154  if (h >= 0)
155  setSceneRect(QPointF(sceneRect().x(), sceneRect().y()), QSizeF((rect().width()), h));
156  break;
157  case 7:
158  if (sceneRect().x() - p.x() + rect().width() >= 0 && h >= 0)
159  setSceneRect(QPointF(p.x(), sceneRect().y()), QSizeF(sceneRect().x() - p.x() + rect().width(), h));
160  break;
161  case 8:
162  if (sceneRect().x() - p.x() + rect().width() >= 0)
163  setSceneRect(QPointF(p.x(), sceneRect().y()), QSizeF(sceneRect().x() - p.x() + rect().width(), rect().height()));
164  break;
165  default:
167  }
168 }
169 
170 void KReportDesignerItemRectBase::hoverMoveEvent(QGraphicsSceneHoverEvent * event)
171 {
172  //m_grabAction = 0;
173 
174  if (isSelected()) {
175  d->grabAction = grabHandle(event->pos());
176  switch (d->grabAction) {
177  case 1:
179  break;
180  case 2:
182  break;
183  case 3:
185  break;
186  case 4:
188  break;
189  case 5:
191  break;
192  case 6:
194  break;
195  case 7:
197  break;
198  case 8:
200  break;
201  default:
202  unsetCursor();
203  }
204  }
205  //kreportDebug() << m_grabAction;
206 }
207 
208 void KReportDesignerItemRectBase::drawHandles(QPainter *painter)
209 {
210  if (isSelected()) {
211  // draw a selected border for visual purposes
212  painter->setPen(QPen(QColor(128, 128, 255), 0, Qt::DotLine));
213 
214  painter->drawRect(rect());
215 
216  const QRectF r = rect();
217  double halfW = (r.width() / 2);
218  double halfH = (r.height() / 2);
219  QPointF center = r.center();
220 
221  center += QPointF(0.75,0.75);
222 
223  painter->fillRect(center.x() - halfW, center.y() - halfH , 5, 5, QColor(128, 128, 255));
224  painter->fillRect(center.x() - 2, center.y() - halfH , 5, 5, QColor(128, 128, 255));
225  painter->fillRect(center.x() + halfW - 4, center.y() - halfH, 5, 5, QColor(128, 128, 255));
226 
227  painter->fillRect(center.x() + (halfW - 4), center.y() - 2, 5, 5, QColor(128, 128, 255));
228 
229  painter->fillRect(center.x() + halfW - 4 , center.y() + halfH - 4 , 5, 5, QColor(128, 128, 255));
230  painter->fillRect(center.x() - 2, center.y() + halfH - 4, 5, 5, QColor(128, 128, 255));
231  painter->fillRect(center.x() - halfW, center.y() + halfH - 4 , 5, 5, QColor(128, 128, 255));
232 
233  painter->fillRect(center.x() - halfW, center.y() - 2, 5, 5, QColor(128, 128, 255));
234 
235  }
236 }
237 
238 /**
239  @return 1 2 3
240  8 0 4
241  7 6 5
242 */
243 int KReportDesignerItemRectBase::grabHandle(const QPointF &pos)
244 {
245  QRectF r = boundingRect();
246  int halfW = (int)(r.width() / 2);
247  int halfH = (int)(r.height() / 2);
248  QPointF center = r.center();
249 
250  if (QRectF(center.x() - (halfW), center.y() - (halfH), 5, 5).contains(pos)) {
251  // we are over the top-left handle
252  return 1;
253  } else if (QRectF(center.x() - 2, center.y() - (halfH), 5, 5).contains(pos)) {
254  // top-middle handle
255  return 2;
256  } else if (QRectF(center.x() + (halfW - 4), center.y() - (halfH), 5, 5).contains(pos)) {
257  // top-right
258  return 3;
259  } else if (QRectF(center.x() + (halfW - 4), center.y() - 2, 5, 5).contains(pos)) {
260  // middle-right
261  return 4;
262  } else if (QRectF(center.x() + (halfW - 4), center.y() + (halfH - 4), 5, 5).contains(pos)) {
263  // bottom-left
264  return 5;
265  } else if (QRectF(center.x() - 2, center.y() + (halfH - 4), 5, 5).contains(pos)) {
266  // bottom-middle
267  return 6;
268  } else if (QRectF(center.x() - (halfW), center.y() + (halfH - 4), 5, 5).contains(pos)) {
269  // bottom-right
270  return 7;
271  } else if (QRectF(center.x() - (halfW), center.y() - 2, 5, 5).contains(pos)) {
272  // middle-right
273  return 8;
274  }
275  return 0;
276 }
277 
278 QVariant KReportDesignerItemRectBase::itemChange(GraphicsItemChange change, const QVariant &value)
279 {
280  KReportDesignerSectionScene *section = qobject_cast<KReportDesignerSectionScene*>(scene());
281  if (section) {
282 
283  if (change == ItemPositionChange) {
284  QPointF newPos = value.toPointF();
285 
286  newPos = section->gridPoint(newPos);
287  if (newPos.x() < 0)
288  newPos.setX(0);
289  else if (newPos.x() > (scene()->width() - rect().width()))
290  newPos.setX(scene()->width() - rect().width());
291 
292  if (newPos.y() < 0)
293  newPos.setY(0);
294  else if (newPos.y() > (scene()->height() - rect().height()))
295  newPos.setY(scene()->height() - rect().height());
296 
297  return newPos;
298  } else if (change == ItemPositionHasChanged) {
299  setSceneRect(value.toPointF(),
300  KReportItemBase::sceneSize(item()->size()), SceneRectFlag::UpdateProperty);
301  } else if (change == ItemSceneHasChanged && item()) {
302  QPointF newPos = pos();
303 
304  newPos = section->gridPoint(newPos);
305  if (newPos.x() < 0)
306  newPos.setX(0);
307  else if (newPos.x() > (scene()->width() - rect().width()))
308  newPos.setX(scene()->width() - rect().width());
309 
310  if (newPos.y() < 0)
311  newPos.setY(0);
312  else if (newPos.y() > (scene()->height() - rect().height()))
313  newPos.setY(scene()->height() - rect().height());
314 
315  setSceneRect(newPos, KReportItemBase::sceneSize(item()->size()),
316  KReportDesignerItemRectBase::SceneRectFlag::DontUpdateProperty);
317  }
318  }
319  return QGraphicsItem::itemChange(change, value);
320 }
321 
322 void KReportDesignerItemRectBase::propertyChanged(const KPropertySet &s, const KProperty &p)
323 {
324  Q_UNUSED(s)
325  Q_UNUSED(p)
326 #if 0
327  if (p.name() == "position") {
328  item()->setPosition(item()->unit().convertToPoint(p.value().toPointF())); //TODO dont update property
329  } else if (p.name() == "size") {
330  item()->setSize(item()->unit().convertToPoint(p.value().toSizeF())); //TODO dont update property
331  }
332 #endif
333  setSceneRect(KReportItemBase::scenePosition(item()->position()),
334  KReportItemBase::sceneSize(item()->size()), SceneRectFlag::DontUpdateProperty);
335 }
336 
338 {
339 //! @todo
340 }
341 
342 QPointF KReportDesignerItemRectBase::properPressPoint(const KReportDesigner &d) const
343 {
344  const QPointF pressPoint = d.getPressPoint();
345  const QPointF releasePoint = d.getReleasePoint();
346  if (releasePoint.x() < pressPoint.x() && releasePoint.y() < pressPoint.y()) {
347  return releasePoint;
348  }
349  if (releasePoint.x() < pressPoint.x() && releasePoint.y() > pressPoint.y()) {
350  return QPointF(releasePoint.x(), pressPoint.y());
351  }
352  if (releasePoint.x() > pressPoint.x() && releasePoint.y() < pressPoint.y()) {
353  return QPointF(pressPoint.x(), releasePoint.y());
354  }
355  return QPointF(pressPoint);
356 }
357 
358 QRectF KReportDesignerItemRectBase::properRect(const KReportDesigner &d, qreal minWidth, qreal minHeight) const
359 {
360  QPointF tempPressPoint = properPressPoint(d);
361  qreal currentPressX = tempPressPoint.x();
362  qreal currentPressY = tempPressPoint.y();
363  const qreal width = qMax(d.countSelectionWidth(), minWidth);
364  const qreal height = qMax(d.countSelectionHeight(), minHeight);
365 
366  qreal tempReleasePointX = tempPressPoint.x() + width;
367  qreal tempReleasePointY = tempPressPoint.y() + height;
368 
369  if (tempReleasePointX > scene()->width()) {
370  int offsetWidth = tempReleasePointX - scene()->width();
371  currentPressX = tempPressPoint.x() - offsetWidth;
372  }
373  if (tempReleasePointY > scene()->height()) {
374  int offsetHeight = tempReleasePointY - scene()->height();
375  currentPressY = tempPressPoint.y() - offsetHeight;
376  }
377  return (QRectF(QPointF(currentPressX, currentPressY), QSizeF(width, height)));
378 }
379 
380 void KReportDesignerItemRectBase::enterInlineEditingMode()
381 {
382 }
383 
384 void KReportDesignerItemRectBase::exitInlineEditingMode()
385 {
386 }
387 
388 void KReportDesignerItemBase::updateRenderText(const QString &itemDataSource, const QString &itemStaticValue, const QString &itemType)
389 {
390  if (itemDataSource.isEmpty()) {
391  if (itemType.isEmpty()) {
392  setRenderText(itemStaticValue);
393  } else {
394  setRenderText(dataSourceAndObjectTypeName(itemStaticValue, itemType));
395  }
396  } else {
397  if (itemType.isEmpty()) {
398  setRenderText(itemDataSource);
399  } else {
400  setRenderText(dataSourceAndObjectTypeName(itemDataSource, itemType));
401  }
402  }
403 }
404 
405 int KReportDesignerItemRectBase::dpiX() const
406 {
407  return d->dpiX;
408 }
409 
410 int KReportDesignerItemRectBase::dpiY() const
411 {
412  return d->dpiY;
413 }
static QSizeF sizeFromScene(const QSizeF &size)
Helper function mapping from screen units to points, size is in pixels.
QByteArray name() const
Base class for items that are drawn syncronously.
qreal width() const const
virtual QVariant itemChange(QGraphicsItem::GraphicsItemChange change, const QVariant &value)
void setPen(const QColor &color)
void setRect(const QRectF &rectangle)
QSizeF toSizeF() const const
void setCursor(const QCursor &cursor)
void update(const QRectF &rect)
void drawRect(const QRectF &rectangle)
qreal x() const const
qreal y() const const
qreal countSelectionWidth() const
void setListData(const QStringList &keys, const QStringList &names)
bool isSelected() const const
void unsetCursor()
KCRASH_EXPORT void setFlags(KCrash::CrashFlags flags)
void fillRect(const QRectF &rectangle, const QBrush &brush)
virtual bool contains(const QPointF &point) const const override
void mouseMoveEvent(QGraphicsSceneMouseEvent *event) override
QPointF getReleasePoint() const
static QPointF scenePosition(const QPointF &ptPos)
Helper function mapping to screen units (pixels), ptPos is in points.
void setPos(const QPointF &pos)
void setX(qreal x)
void setY(qreal y)
static QSizeF sceneSize(const QSizeF &ptSize)
Helper function mapping to screen units (pixels), ptSize is in points.
QGraphicsScene * scene() const const
bool contains(const QRectF &rectangle) const const
void setPosition(const QPointF &ptPos)
Sets position for the element.
bool isEmpty() const const
SizeFDiagCursor
void setSelected(bool selected)
void changeSet(KPropertySet *set)
Sets the property set for the currently selected item.
virtual void mousePressEvent(QGraphicsSceneMouseEvent *event)
qreal countSelectionHeight() const
QPointF getPressPoint() const
static QPointF positionFromScene(const QPointF &pos)
Helper function mapping from screen units to points, pos is in pixels.
void setSize(const QSizeF &ptSize)
Sets size for the element.
QPointF center() const const
void update(qreal x, qreal y, qreal w, qreal h)
qreal x() const const
qreal y() const const
QRectF rect() const const
qreal width() const const
Base class for rectangular report items used within the designer GUI.
QVariant value() const
QTextStream & center(QTextStream &stream)
QPointF pos() const const
QPointF toPointF() const const
The ReportDesigner is the main widget for designing a report.
virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
virtual void mouseMoveEvent(QGraphicsSceneMouseEvent *event)
qreal height() const const
void move(const QPointF &) override
void updateRenderText(const QString &itemDataSource, const QString &itemStaticValue, const QString &itemType)
Updates the text that is shown for the item in the report designer If itemDataSource is set then it i...
QPointF scenePos() const const
qreal x() const const
qreal y() const const
virtual QRectF boundingRect() const const override
qreal height() const const
Base class for report items used within the designer GUI.
This file is part of the KDE documentation.
Documentation copyright © 1996-2023 The KDE developers.
Generated on Sat Sep 30 2023 04:06:37 by doxygen 1.8.17 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.