KD Chart API Documentation  3.1
kdganttlegend.cpp
Go to the documentation of this file.
1 /****************************************************************************
2 **
3 ** This file is part of the KD Chart library.
4 **
5 ** SPDX-FileCopyrightText: 2001 Klarälvdalens Datakonsult AB, a KDAB Group company <info@kdab.com>
6 **
7 ** SPDX-License-Identifier: MIT
8 **
9 ****************************************************************************/
10 
11 #include "kdganttlegend.h"
12 #include "kdganttlegend_p.h"
13 
14 #include "kdganttitemdelegate.h"
15 
16 #include <QApplication>
17 #include <QPainter>
18 
19 #include <cassert>
20 
21 using namespace KDGantt;
22 
33 Legend::Legend(QWidget *parent)
34  : QAbstractItemView(parent)
35  , _d(new Private)
36 {
37  setItemDelegate(new ItemDelegate(this));
38  setFrameStyle(QFrame::NoFrame);
39 }
40 
43 {
44  delete _d;
45 }
46 
47 #define d d_func()
48 
49 QModelIndex Legend::indexAt(const QPoint &point) const
50 {
51  Q_UNUSED(point);
52  return QModelIndex();
53 }
54 
55 QRect Legend::visualRect(const QModelIndex &index) const
56 {
57  Q_UNUSED(index);
58  return QRect();
59 }
60 
61 QSize Legend::sizeHint() const
62 {
63  return measureItem(rootIndex());
64 }
65 
67 {
68  return measureItem(rootIndex());
69 }
70 
71 void Legend::setModel(QAbstractItemModel *newModel)
72 {
73  QAbstractItemModel *oldModel = model();
74  if (oldModel != nullptr) {
75  disconnect(oldModel, &QAbstractItemModel::dataChanged, this, &Legend::modelDataChanged);
76  disconnect(oldModel, &QAbstractItemModel::rowsRemoved, this, &Legend::modelDataChanged);
77  disconnect(oldModel, &QAbstractItemModel::columnsRemoved, this, &Legend::modelDataChanged);
78  }
79 
80  QAbstractItemView::setModel(newModel);
81  d->proxyModel.setSourceModel(newModel);
82 
83  if (newModel != nullptr) {
84  connect(newModel, &QAbstractItemModel::dataChanged, this, &Legend::modelDataChanged);
85  connect(newModel, &QAbstractItemModel::rowsRemoved, this, &Legend::modelDataChanged);
86  connect(newModel, &QAbstractItemModel::columnsRemoved, this, &Legend::modelDataChanged);
87  }
88 }
89 
93 {
94  updateGeometry();
95  viewport()->update();
96 }
97 
98 void Legend::paintEvent(QPaintEvent *event)
99 {
100  Q_UNUSED(event);
101  // no model, no legend...
102  if (model() == nullptr)
103  return;
104 
105  QPainter p(viewport());
106  p.fillRect(viewport()->rect(), palette().color(QPalette::Window));
107  drawItem(&p, rootIndex());
108 }
109 
113 StyleOptionGanttItem Legend::getStyleOption(const QModelIndex &index) const
114 {
117  opt.displayAlignment = Qt::Alignment(d->proxyModel.data(index, Qt::TextAlignmentRole).toInt());
118  opt.text = index.model()->data(index, LegendRole).toString();
119  opt.font = (index.model()->data(index, Qt::FontRole)).value<QFont>();
120  return opt;
121 }
122 
128 QRect Legend::drawItem(QPainter *painter, const QModelIndex &index, const QPoint &pos) const
129 {
130  int xPos = pos.x();
131  int yPos = pos.y();
132 
133  if (index.isValid() && index.model() == &d->proxyModel) {
134  auto *const delegate = qobject_cast<ItemDelegate *>(itemDelegate(index));
135  assert(delegate != nullptr);
136  const QRect r(pos, measureItem(index, false));
138  opt.rect = r;
139  opt.rect.setWidth(r.height());
140 
141  const ItemType typ = static_cast<ItemType>(index.model()->data(index, ItemTypeRole).toInt());
142  const int dx = (typ == TypeEvent) ? (r.height() / 2) : 0;
143 
144  opt.itemRect = opt.rect.adjusted(dx, 0, dx, 0);
145  opt.boundingRect = r;
146  opt.boundingRect.setWidth(r.width() + r.height());
147  if (!opt.text.isNull())
148  delegate->paintGanttItem(painter, opt, index);
149 
150  xPos = r.right();
151  yPos = r.bottom();
152  }
153 
154  const int rowCount = d->proxyModel.rowCount(index);
155  for (int row = 0; row < rowCount; ++row) {
156  const QRect r = drawItem(painter, d->proxyModel.index(row, 0, index), QPoint(pos.x(), yPos));
157  xPos = qMax(xPos, r.right());
158  yPos = qMax(yPos, r.bottom());
159  }
160 
161  return QRect(pos, QPoint(xPos, yPos));
162 }
163 
167 QSize Legend::measureItem(const QModelIndex &index, bool recursive) const
168 {
169  if (model() == nullptr)
170  return QSize();
171 
172  QSize baseSize;
173  if (index.model() != nullptr) {
174  QFontMetrics fm((index.model()->data(index, Qt::FontRole)).value<QFont>());
175  const QString text = index.model()->data(index, LegendRole).toString();
176  if (!text.isEmpty())
177  baseSize += QSize(fm.horizontalAdvance(text) + fm.height() + 2, fm.height() + 2);
178  }
179 
180  if (!recursive)
181  return baseSize;
182 
183  QSize childrenSize;
184 
185  const int rowCount = d->proxyModel.rowCount(index);
186  for (int row = 0; row < rowCount; ++row) {
187  const QSize childSize = measureItem(d->proxyModel.index(row, 0, index));
188  childrenSize.setWidth(qMax(childrenSize.width(), childSize.width()));
189  childrenSize.rheight() += childSize.height();
190  }
191  return baseSize + childrenSize;
192 }
Class used to render gantt items in a KDGantt::GraphicsView.
void setModel(QAbstractItemModel *model) override
virtual void modelDataChanged()
Triggers repainting of the legend.
~Legend() override
Destructor.
QSize minimumSizeHint() const override
virtual StyleOptionGanttItem getStyleOption(const QModelIndex &index) const
Creates a StyleOptionGanttItem with all style options filled in except the target rectangles.
QModelIndex indexAt(const QPoint &point) const override
void paintEvent(QPaintEvent *event) override
QSize sizeHint() const override
Legend(QWidget *parent=nullptr)
Constructor.
virtual QSize measureItem(const QModelIndex &index, bool recursive=true) const
Calculates the needed space for the legend item at index and, if recursive is true,...
QRect visualRect(const QModelIndex &index) const override
virtual QRect drawItem(QPainter *painter, const QModelIndex &index, const QPoint &pos=QPoint()) const
Draws the legend item at index and all of it's children recursively at pos onto painter.
QStyleOption subclass for gantt items.
QRectF boundingRect
Contains the bounding rectangle for the item.
QString text
Contains a string printed to the item.
QRectF itemRect
Contains the "active" item rectangle that corresponds to the values from the model.
#define d
ItemType
The values of this enum are used to represent the different types of gantt items that KDGantt underst...

© 2001 Klarälvdalens Datakonsult AB (KDAB)
"The Qt, C++ and OpenGL Experts"
https://www.kdab.com/
https://www.kdab.com/development-resources/qt-tools/kd-chart/
Generated by doxygen 1.9.1