KD Chart API Documentation  3.1
kdganttgraphicsview.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 "kdganttgraphicsview.h"
13 #include "kdganttconstraintmodel.h"
14 #include "kdganttgraphicsitem.h"
15 #include "kdganttgraphicsview_p.h"
16 
17 #include <QAbstractProxyModel>
18 #include <QActionGroup>
19 #include <QMenu>
20 #include <QPaintEvent>
21 #include <QPainter>
22 #include <QPrinter>
23 #include <QResizeEvent>
24 #include <QScrollBar>
25 
26 #include <cassert>
27 
28 #if defined KDAB_EVAL
29 #include "../evaldialog/evaldialog.h"
30 #endif
31 
36 using namespace KDGantt;
37 
38 HeaderWidget::HeaderWidget(GraphicsView *parent)
39  : QWidget(parent)
40  , m_offset(0.)
41 {
42  assert(parent); // Parent must be set
43 }
44 
45 HeaderWidget::~HeaderWidget()
46 {
47 }
48 
49 void HeaderWidget::scrollTo(int v)
50 {
51  m_offset = v;
52  // QWidget::scroll() won't work properly for me on Mac
53  // scroll( static_cast<int>( old-v ), 0 );
54  update();
55 }
56 
57 void HeaderWidget::paintEvent(QPaintEvent *ev)
58 {
59  QPainter p(this);
60  view()->grid()->paintHeader(&p, rect(), ev->rect(), m_offset, this);
61 }
62 
63 bool HeaderWidget::event(QEvent *event)
64 {
65  if (event->type() == QEvent::ToolTip) {
66  auto *const grid = qobject_cast<DateTimeGrid *>(view()->grid());
67  if (grid) {
68  auto *e = static_cast<QHelpEvent *>(event);
69  QDateTime dt = grid->mapFromChart(view()->mapToScene(e->x(), 0).x()).toDateTime();
70  setToolTip(dt.toString());
71  }
72  }
73  return QWidget::event(event);
74 }
75 
76 void HeaderWidget::contextMenuEvent(QContextMenuEvent *event)
77 {
78  QMenu contextMenu;
79 
80  auto *const grid = qobject_cast<DateTimeGrid *>(view()->grid());
81  QAction *actionScaleAuto = nullptr;
82  QAction *actionScaleMonth = nullptr;
83  QAction *actionScaleWeek = nullptr;
84  QAction *actionScaleDay = nullptr;
85  QAction *actionScaleHour = nullptr;
86  QAction *actionZoomIn = nullptr;
87  QAction *actionZoomOut = nullptr;
88  if (grid != nullptr) {
89  auto *menuScale = new QMenu(tr("Scale"), &contextMenu);
90  auto *scaleGroup = new QActionGroup(&contextMenu);
91  scaleGroup->setExclusive(true);
92 
93  actionScaleAuto = new QAction(tr("Auto"), menuScale);
94  actionScaleAuto->setCheckable(true);
95  actionScaleAuto->setChecked(grid->scale() == DateTimeGrid::ScaleAuto);
96  actionScaleMonth = new QAction(tr("Month"), menuScale);
97  actionScaleMonth->setCheckable(true);
98  actionScaleMonth->setChecked(grid->scale() == DateTimeGrid::ScaleMonth);
99  actionScaleWeek = new QAction(tr("Week"), menuScale);
100  actionScaleWeek->setCheckable(true);
101  actionScaleWeek->setChecked(grid->scale() == DateTimeGrid::ScaleWeek);
102  actionScaleDay = new QAction(tr("Day"), menuScale);
103  actionScaleDay->setCheckable(true);
104  actionScaleDay->setChecked(grid->scale() == DateTimeGrid::ScaleDay);
105  actionScaleHour = new QAction(tr("Hour"), menuScale);
106  actionScaleHour->setCheckable(true);
107  actionScaleHour->setChecked(grid->scale() == DateTimeGrid::ScaleHour);
108 
109  scaleGroup->addAction(actionScaleAuto);
110  menuScale->addAction(actionScaleAuto);
111 
112  scaleGroup->addAction(actionScaleMonth);
113  menuScale->addAction(actionScaleMonth);
114 
115  scaleGroup->addAction(actionScaleWeek);
116  menuScale->addAction(actionScaleWeek);
117 
118  scaleGroup->addAction(actionScaleDay);
119  menuScale->addAction(actionScaleDay);
120 
121  scaleGroup->addAction(actionScaleHour);
122  menuScale->addAction(actionScaleHour);
123 
124  contextMenu.addMenu(menuScale);
125 
126  contextMenu.addSeparator();
127 
128  actionZoomIn = new QAction(tr("Zoom In"), &contextMenu);
129  contextMenu.addAction(actionZoomIn);
130  actionZoomOut = new QAction(tr("Zoom Out"), &contextMenu);
131  contextMenu.addAction(actionZoomOut);
132  }
133 
134  if (contextMenu.isEmpty()) {
135  event->ignore();
136  return;
137  }
138 
139  const QAction *const action = contextMenu.exec(event->globalPos());
140  if (action == nullptr) {
141  } else if (action == actionScaleAuto) {
142  assert(grid != nullptr);
143  grid->setScale(DateTimeGrid::ScaleAuto);
144  } else if (action == actionScaleMonth) {
145  assert(grid != nullptr);
146  grid->setScale(DateTimeGrid::ScaleMonth);
147  } else if (action == actionScaleWeek) {
148  assert(grid != nullptr);
149  grid->setScale(DateTimeGrid::ScaleWeek);
150  } else if (action == actionScaleDay) {
151  assert(grid != nullptr);
152  grid->setScale(DateTimeGrid::ScaleDay);
153  } else if (action == actionScaleHour) {
154  assert(grid != nullptr);
155  grid->setScale(DateTimeGrid::ScaleHour);
156  } else if (action == actionZoomIn) {
157  assert(grid != nullptr);
158  grid->setDayWidth(qMax(0.1, grid->dayWidth() + grid->dayWidth() * 0.2));
159  } else if (action == actionZoomOut) {
160  assert(grid != nullptr);
161  grid->setDayWidth(qMax(0.1, grid->dayWidth() - grid->dayWidth() * 0.2));
162  }
163 
164  event->accept();
165 }
166 
167 GraphicsView::Private::Private(GraphicsView *_q)
168  : q(_q)
169  , rowcontroller(nullptr)
170  , headerwidget(_q)
171 {
172 }
173 
174 void GraphicsView::Private::updateHeaderGeometry()
175 {
176  q->setViewportMargins(0, rowcontroller->headerHeight(), 0, 0);
177  headerwidget.setGeometry(q->viewport()->x(),
178  q->viewport()->y() - rowcontroller->headerHeight(),
179  q->viewport()->width(),
180  rowcontroller->headerHeight());
181 }
182 
183 void GraphicsView::Private::slotGridChanged()
184 {
185  updateHeaderGeometry();
186  headerwidget.update();
187  q->updateSceneRect();
188  q->update();
189 }
190 
191 void GraphicsView::Private::slotHorizontalScrollValueChanged(int val)
192 {
193  const QRectF viewRect = q->transform().mapRect(q->sceneRect());
194  headerwidget.scrollTo(val - q->horizontalScrollBar()->minimum() + static_cast<int>(viewRect.left()));
195 }
196 
197 void GraphicsView::Private::slotColumnsInserted(const QModelIndex &parent, int start, int end)
198 {
199  Q_UNUSED(start);
200  Q_UNUSED(end);
201  QModelIndex idx = scene.model()->index(0, 0, scene.summaryHandlingModel()->mapToSource(parent));
202  do {
203  scene.updateRow(scene.summaryHandlingModel()->mapFromSource(idx));
204  } while ((idx = rowcontroller->indexBelow(idx)) != QModelIndex() && rowcontroller->isRowVisible(idx));
205  //} while ( ( idx = d->treeview.indexBelow( idx ) ) != QModelIndex() && d->treeview.visualRect(idx).isValid() );
206  q->updateSceneRect();
207 }
208 
209 void GraphicsView::Private::slotColumnsRemoved(const QModelIndex &parent, int start, int end)
210 {
211  // TODO
212  Q_UNUSED(start);
213  Q_UNUSED(end);
214  Q_UNUSED(parent);
215  q->updateScene();
216 }
217 
218 void GraphicsView::Private::slotDataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight)
219 {
220  // qDebug() << "GraphicsView::slotDataChanged("<<topLeft<<bottomRight<<")";
221  const QModelIndex parent = topLeft.parent();
222  for (int row = topLeft.row(); row <= bottomRight.row(); ++row) {
223  scene.updateRow(scene.summaryHandlingModel()->index(row, 0, parent));
224  }
225 }
226 
227 void GraphicsView::Private::slotLayoutChanged()
228 {
229  // qDebug() << "slotLayoutChanged()";
230  q->updateScene();
231 }
232 
233 void GraphicsView::Private::slotModelReset()
234 {
235  // qDebug() << "slotModelReset()";
236  q->updateScene();
237 }
238 
239 void GraphicsView::Private::slotRowsInserted(const QModelIndex &parent, int start, int end)
240 {
241  Q_UNUSED(parent);
242  Q_UNUSED(start);
243  Q_UNUSED(end);
244  q->updateScene(); // TODO: This might be optimised
245 }
246 
247 void GraphicsView::Private::slotRowsAboutToBeRemoved(const QModelIndex &parent, int start, int end)
248 {
249  // qDebug() << "GraphicsView::Private::slotRowsAboutToBeRemoved("<<parent<<start<<end<<")";
250  for (int row = start; row <= end; ++row) {
251  for (int col = 0; col < scene.summaryHandlingModel()->columnCount(parent); ++col) {
252  // qDebug() << "removing "<<scene.summaryHandlingModel()->index( row, col, parent );
253  scene.removeItem(scene.summaryHandlingModel()->index(row, col, parent));
254  }
255  }
256 }
257 
258 void GraphicsView::Private::slotRowsRemoved(const QModelIndex &parent, int start, int end)
259 {
260  // qDebug() << "GraphicsView::Private::slotRowsRemoved("<<parent<<start<<end<<")";
261  // TODO
262  Q_UNUSED(parent);
263  Q_UNUSED(start);
264  Q_UNUSED(end);
265 
266  q->updateScene();
267 }
268 
269 void GraphicsView::Private::slotItemClicked(const QModelIndex &idx)
270 {
271  QModelIndex sidx = idx; // scene.summaryHandlingModel()->mapToSource( idx );
272  Q_EMIT q->clicked(sidx);
273  if (q->style()->styleHint(QStyle::SH_ItemView_ActivateItemOnSingleClick, nullptr, q))
274  Q_EMIT q->activated(sidx);
275 }
276 
277 void GraphicsView::Private::slotItemDoubleClicked(const QModelIndex &idx)
278 {
279  QModelIndex sidx = idx; // scene.summaryHandlingModel()->mapToSource( idx );
280  Q_EMIT q->qrealClicked(sidx);
281  if (!q->style()->styleHint(QStyle::SH_ItemView_ActivateItemOnSingleClick, nullptr, q))
282  Q_EMIT q->activated(sidx);
283 }
284 
285 void GraphicsView::Private::slotHeaderContextMenuRequested(const QPoint &pt)
286 {
287  Q_EMIT q->headerContextMenuRequested(headerwidget.mapToGlobal(pt));
288 }
289 
311 GraphicsView::GraphicsView(QWidget *parent)
312  : QGraphicsView(parent)
313  , _d(new Private(this))
314 {
315 #if defined KDAB_EVAL
316  EvalDialog::checkEvalLicense("KD Gantt");
317 #endif
318  connect(horizontalScrollBar(), &QScrollBar::valueChanged,
319  this, [this](int value) {
320  _d->slotHorizontalScrollValueChanged(value);
321  });
322  connect(&_d->scene, &GraphicsScene::gridChanged,
323  this, [this] {
324  _d->slotGridChanged();
325  });
326  connect(&_d->scene, &GraphicsScene::entered,
327  this, &GraphicsView::entered);
328  connect(&_d->scene, &GraphicsScene::pressed,
329  this, &GraphicsView::pressed);
330  connect(&_d->scene, &GraphicsScene::clicked,
331  this, [this](const QModelIndex &index) {
332  _d->slotItemClicked(index);
333  });
334  connect(&_d->scene, &GraphicsScene::qrealClicked,
335  this, [this](const QModelIndex &index) {
336  _d->slotItemDoubleClicked(index);
337  });
338  connect(&_d->scene, &GraphicsScene::sceneRectChanged,
340  connect(&_d->headerwidget, &HeaderWidget::customContextMenuRequested,
341  this, [this](const QPoint &point) {
342  _d->slotHeaderContextMenuRequested(point);
343  });
344  setScene(&_d->scene);
345 
346  // HACK!
347  setSummaryHandlingModel(_d->scene.summaryHandlingModel());
348 
349  // So that AbstractGrid::drawBackground() and AbstractGrid::drawForeground()
350  // works properly
351  setViewportUpdateMode(QGraphicsView::FullViewportUpdate);
352 
353  // setCacheMode( CacheBackground );
354 }
355 
358 {
359  delete _d;
360 }
361 
362 #define d d_func()
363 
377 void GraphicsView::setModel(QAbstractItemModel *model)
378 {
379  if (d->scene.model()) {
380  disconnect(d->scene.model());
381  }
382 
383  d->scene.setModel(model);
384  connect(model, &QAbstractItemModel::dataChanged, this, &GraphicsView::updateSceneRect);
385  updateScene();
386 }
387 
390 QAbstractItemModel *GraphicsView::model() const
391 {
392  return d->scene.model();
393 }
394 
395 void GraphicsView::setSummaryHandlingModel(QAbstractProxyModel *proxyModel)
396 {
397  disconnect(d->scene.summaryHandlingModel());
398  d->scene.setSummaryHandlingModel(proxyModel);
399 
400  /* Connections. We have to rely on the treeview
401  * to receive the signals before we do(!)
402  */
403  connect(proxyModel, &QAbstractProxyModel::columnsInserted,
404  this, [this](const QModelIndex &parent, int first, int last) {
405  d->slotColumnsInserted(parent, first, last);
406  });
407  connect(proxyModel, &QAbstractProxyModel::columnsRemoved,
408  this, [this](const QModelIndex &parent, int first, int last) {
409  d->slotColumnsRemoved(parent, first, last);
410  });
411  connect(proxyModel, &QAbstractProxyModel::dataChanged,
412  this, [this](const QModelIndex &topLeft, const QModelIndex &bottomRight) {
413  d->slotDataChanged(topLeft, bottomRight);
414  });
415  connect(proxyModel, &QAbstractProxyModel::layoutChanged,
416  this, [this] {
417  d->slotLayoutChanged();
418  });
419  connect(proxyModel, &QAbstractProxyModel::modelReset,
420  this, [this] {
421  d->slotModelReset();
422  });
423  connect(proxyModel, &QAbstractProxyModel::rowsInserted,
424  this, [this](const QModelIndex &parent, int first, int last) {
425  d->slotRowsInserted(parent, first, last);
426  });
427  connect(proxyModel, &QAbstractProxyModel::rowsAboutToBeRemoved,
428  this, [this](const QModelIndex &parent, int first, int last) {
429  d->slotRowsAboutToBeRemoved(parent, first, last);
430  });
431  connect(proxyModel, &QAbstractProxyModel::rowsRemoved,
432  this, [this](const QModelIndex &parent, int first, int last) {
433  d->slotRowsRemoved(parent, first, last);
434  });
435 
436  updateScene();
437 }
438 
443 {
444  d->scene.setConstraintModel(cmodel);
445 }
446 
450 {
451  return d->scene.constraintModel();
452 }
453 
456 QAbstractProxyModel *GraphicsView::summaryHandlingModel() const
457 {
458  return d->scene.summaryHandlingModel();
459 }
460 
464 void GraphicsView::setRootIndex(const QModelIndex &idx)
465 {
466  d->scene.setRootIndex(idx);
467 }
468 
471 QModelIndex GraphicsView::rootIndex() const
472 {
473  return d->scene.rootIndex();
474 }
475 
479 void GraphicsView::setSelectionModel(QItemSelectionModel *model)
480 {
481  d->scene.setSelectionModel(model);
482 }
483 
486 QItemSelectionModel *GraphicsView::selectionModel() const
487 {
488  return d->scene.selectionModel();
489 }
490 
495 {
496  d->scene.setItemDelegate(delegate);
497 }
498 
502 {
503  return d->scene.itemDelegate();
504 }
505 
512 {
513  d->rowcontroller = rowcontroller;
514  d->scene.setRowController(rowcontroller);
515  updateScene();
516 }
517 
522 {
523  return d->rowcontroller;
524 }
525 
532 {
533  d->scene.setGrid(grid);
534  d->slotGridChanged();
535 }
536 
540 {
541  return d->scene.grid();
542 }
543 
548 {
549  d->scene.setReadOnly(ro);
550 }
551 
555 {
556  return d->scene.isReadOnly();
557 }
558 
568 void GraphicsView::setHeaderContextMenuPolicy(Qt::ContextMenuPolicy p)
569 {
570  d->headerwidget.setContextMenuPolicy(p);
571 }
572 
575 Qt::ContextMenuPolicy GraphicsView::headerContextMenuPolicy() const
576 {
577  return d->headerwidget.contextMenuPolicy();
578 }
579 
588 void GraphicsView::addConstraint(const QModelIndex &from,
589  const QModelIndex &to,
590  Qt::KeyboardModifiers modifiers)
591 {
592  if (isReadOnly())
593  return;
594  ConstraintModel *cmodel = constraintModel();
595  assert(cmodel);
596  Constraint c(from, to, (modifiers & Qt::ShiftModifier) ? Constraint::TypeHard : Constraint::TypeSoft);
597  if (cmodel->hasConstraint(c))
598  cmodel->removeConstraint(c);
599  else
600  cmodel->addConstraint(c);
601 }
602 
603 void GraphicsView::resizeEvent(QResizeEvent *ev)
604 {
605  d->updateHeaderGeometry();
606  QRectF r = scene()->itemsBoundingRect();
607  // To scroll more to the left than the actual item start, bug #4516
608  r.setLeft(qMin<qreal>(0.0, r.left()));
609  // TODO: take scrollbars into account (if not always on)
610  // The scene should be at least the size of the viewport
611  QSizeF size = viewport()->size();
612  // TODO: why -2 below? size should be ex. frames etc?
613  if (size.width() > r.width()) {
614  r.setWidth(size.width() - 2);
615  }
616  if (size.height() > r.height()) {
617  r.setHeight(size.height() - 2);
618  }
619  const int totalh = rowController()->totalHeight();
620  if (r.height() < totalh) {
621  r.setHeight(totalh);
622  }
623 
624  scene()->setSceneRect(r);
625 
626  QGraphicsView::resizeEvent(ev);
627 }
628 
635 QModelIndex GraphicsView::indexAt(const QPoint &pos) const
636 {
637  QGraphicsItem *item = itemAt(pos);
638  if (auto *gitem = qgraphicsitem_cast<GraphicsItem *>(item)) {
639  return d->scene.summaryHandlingModel()->mapToSource(gitem->index());
640  } else {
641  return QModelIndex();
642  }
643 }
644 
647 {
648  d->scene.clearItems();
649 }
650 
652 void GraphicsView::updateRow(const QModelIndex &idx)
653 {
654  d->scene.updateRow(d->scene.summaryHandlingModel()->mapFromSource(idx));
655 }
656 
661 {
662  /* What to do with this? We need to shrink the view to
663  * make collapsing items work
664  */
665  qreal range = horizontalScrollBar()->maximum() - horizontalScrollBar()->minimum();
666  const qreal hscroll = horizontalScrollBar()->value() / (range > 0 ? range : 1);
667  QRectF r = d->scene.itemsBoundingRect();
668  // To scroll more to the left than the actual item start, bug #4516
669  r.setTop(0.);
670  r.setLeft(qMin<qreal>(0.0, r.left()));
671  r.setSize(r.size().expandedTo(viewport()->size()));
672  const int totalh = rowController()->totalHeight();
673  if (r.height() < totalh)
674  r.setHeight(totalh);
675  d->scene.setSceneRect(r);
676 
677  /* set scrollbar to keep the same time in view */
678  range = horizontalScrollBar()->maximum() - horizontalScrollBar()->minimum();
679  if (range > 0)
680  horizontalScrollBar()->setValue(qRound(hscroll * range));
681 
682  /* We have to update here to adjust for any rows with no
683  * information because they are painted with a different
684  * background brush
685  */
686  d->scene.invalidate(QRectF(), QGraphicsScene::BackgroundLayer);
687 }
688 
693 {
694  clearItems();
695  if (!model())
696  return;
697  if (!rowController())
698  return;
699  QModelIndex idx = model()->index(0, 0, rootIndex());
700  do {
701  updateRow(idx);
702  } while ((idx = rowController()->indexBelow(idx)) != QModelIndex() && rowController()->isRowVisible(idx));
703  // constraintModel()->cleanup();
704  // qDebug() << constraintModel();
705  updateSceneRect();
706  if (scene())
707  scene()->invalidate(QRectF(), QGraphicsScene::BackgroundLayer);
708 }
709 
711 GraphicsItem *GraphicsView::createItem(ItemType type) const
712 {
713  return d->scene.createItem(type);
714 }
715 
717 void GraphicsView::deleteSubtree(const QModelIndex &idx)
718 {
719  d->scene.deleteSubtree(d->scene.summaryHandlingModel()->mapFromSource(idx));
720 }
721 
730 void GraphicsView::print(QPrinter *printer, bool drawRowLabels, bool drawColumnLabels)
731 {
732  d->scene.print(printer, drawRowLabels, drawColumnLabels);
733 }
734 
747 void GraphicsView::print(QPrinter *printer, qreal start, qreal end, bool drawRowLabels, bool drawColumnLabels)
748 {
749  d->scene.print(printer, start, end, drawRowLabels, drawColumnLabels);
750 }
751 
758 void GraphicsView::print(QPainter *painter, const QRectF &targetRect, bool drawRowLabels, bool drawColumnLabels)
759 {
760  d->scene.print(painter, targetRect, drawRowLabels, drawColumnLabels);
761 }
762 
773 void GraphicsView::print(QPainter *painter, qreal start, qreal end,
774  const QRectF &targetRect, bool drawRowLabels, bool drawColumnLabels)
775 {
776  d->scene.print(painter, start, end, targetRect, drawRowLabels, drawColumnLabels);
777 }
778 
779 #include "moc_kdganttgraphicsview.cpp"
Abstract baseclass for grids.
Abstract baseclass for row controllers.
virtual int totalHeight() const =0
The ConstraintModel keeps track of the interdependencies between gantt items in a View.
virtual void addConstraint(const Constraint &c)
Adds the constraint c to this ConstraintModel If the Constraint c is already in this ConstraintModel,...
bool hasConstraint(const Constraint &c) const
Returns true if a Constraint with start s and end e exists, otherwise false.
virtual bool removeConstraint(const Constraint &c)
Removes the Constraint c from this ConstraintModel.
A class used to represent a dependency.
void entered(const QModelIndex &index)
void clicked(const QModelIndex &index)
void qrealClicked(const QModelIndex &index)
void pressed(const QModelIndex &index)
The GraphicsView class provides a model/view implementation of a gantt chart.
void setItemDelegate(ItemDelegate *delegate)
Sets the KDGantt::ItemDelegate used for rendering items on this view.
void setModel(QAbstractItemModel *)
Sets the model to be displayed in this view to model.
QAbstractItemModel * model() const
void entered(const QModelIndex &index)
void pressed(const QModelIndex &index)
void setRootIndex(const QModelIndex &)
Sets the root index of the model displayed by this view.
void setRowController(AbstractRowController *)
Sets the AbstractRowController used by this view.
~GraphicsView() override
Destroys this view.
void print(QPrinter *printer, bool drawRowLabels=true, bool drawColumnLabels=true)
Print the Gantt chart using printer.
void setSelectionModel(QItemSelectionModel *)
Sets the QItemSelectionModel used by this view to manage selections.
void setGrid(AbstractGrid *)
Sets the AbstractGrid for this view.
void resizeEvent(QResizeEvent *) override
void setHeaderContextMenuPolicy(Qt::ContextMenuPolicy)
Sets the context menu policy for the header.
QModelIndex rootIndex() const
ConstraintModel * constraintModel() const
void setConstraintModel(ConstraintModel *)
Sets the constraintmodel displayed by this view.
virtual void addConstraint(const QModelIndex &from, const QModelIndex &to, Qt::KeyboardModifiers modifiers)
Adds a constraint from from to to.
QItemSelectionModel * selectionModel() const
AbstractGrid * grid() const
AbstractRowController * rowController() const
void setSummaryHandlingModel(QAbstractProxyModel *model)
Qt::ContextMenuPolicy headerContextMenuPolicy() const
void setReadOnly(bool)
Sets the view to read-only mode if to is true.
void updateRow(const QModelIndex &)
ItemDelegate * itemDelegate() const
QModelIndex indexAt(const QPoint &pos) const
QAbstractProxyModel * summaryHandlingModel() const
void deleteSubtree(const QModelIndex &)
Class used to render gantt items in a KDGantt::GraphicsView.
#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