24 #include "kdganttview_p.h" 30 #include <QAbstractItemModel> 31 #include <QHeaderView> 32 #include <QVBoxLayout> 33 #include <QGraphicsItem> 34 #include <QGraphicsRectItem> 36 #include <QPaintEvent> 43 #include "../evaldialog/evaldialog.h" 49 class HeaderView :
public QHeaderView {
51 explicit HeaderView(
QWidget* parent=0 ) : QHeaderView( Qt::Horizontal, parent ) {
54 QSize sizeHint()
const override { QSize s = QHeaderView::sizeHint(); s.rheight() *= 2;
return s; }
59 : QTreeView( parent ),
60 m_controller( this, proxy )
62 setHeader(
new HeaderView );
65 KDGanttTreeView::~KDGanttTreeView()
69 void KDGanttTreeView::expandAll(QModelIndex index)
71 for (
int i = 0; i < model()->rowCount(index); i++) {
72 QModelIndex
indexAt = model()->index(i, 0, index);
73 if (model()->hasChildren(indexAt))
75 if (isExpanded(indexAt))
81 void KDGanttTreeView::collapseAll(QModelIndex index)
83 for (
int i = 0; i < model()->rowCount(index); i++) {
84 QModelIndex indexAt = model()->index(i, 0, index);
85 if (model()->hasChildren(indexAt))
87 if (!isExpanded(indexAt))
93 View::Private::Private(
View* v)
103 View::Private::~Private()
108 void View::Private::init()
110 KDGanttTreeView* tw =
new KDGanttTreeView( &ganttProxyModel, &splitter );
111 tw->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
112 tw->setVerticalScrollMode( QAbstractItemView::ScrollPerPixel );
114 q->setLeftView( tw );
115 q->setRowController( tw->rowController() );
119 tw->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
121 QVBoxLayout* layout =
new QVBoxLayout(q);
122 layout->setMargin(0);
123 layout->addWidget(&splitter);
124 q->setLayout(layout);
126 constraintProxy.setProxyModel( &ganttProxyModel );
127 constraintProxy.setDestinationModel( &mappedConstraintModel );
131 void View::Private::setupGraphicsView()
133 gfxview->setParent( &splitter );
134 gfxview->setAlignment(Qt::AlignTop|Qt::AlignLeft);
135 gfxview->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
136 gfxview->setSelectionModel( leftWidget->selectionModel() );
137 gfxview->setConstraintModel( &mappedConstraintModel );
138 q->setLeftView( leftWidget );
139 q->setRowController( rowController );
143 void View::Private::updateScene()
145 gfxview->clearItems();
148 if ( QTreeView* tw = qobject_cast<QTreeView*>(leftWidget)) {
149 QModelIndex idx = ganttProxyModel.mapFromSource( model->index( 0, 0, leftWidget->rootIndex() ) );
151 gfxview->updateRow( idx );
152 }
while ( ( idx = tw->indexBelow( idx ) ) != QModelIndex() &&
153 gfxview->rowController()->isRowVisible(idx) );
154 gfxview->updateSceneRect();
156 const QModelIndex rootidx = ganttProxyModel.mapFromSource( leftWidget->rootIndex() );
157 for (
int r = 0; r < ganttProxyModel.rowCount(rootidx); ++r ) {
158 gfxview->updateRow( ganttProxyModel.index( r, 0, rootidx ) );
163 void View::Private::slotCollapsed(
const QModelIndex& _idx)
165 QTreeView* tw = qobject_cast<QTreeView*>(leftWidget);
168 bool blocked = gfxview->blockSignals(
true );
170 QModelIndex idx( _idx );
171 const QAbstractItemModel* model = leftWidget->model();
172 const QModelIndex pidx = ganttProxyModel.mapFromSource(idx);
173 bool isMulti =
false;
174 for ( QModelIndex treewalkidx = pidx; treewalkidx.isValid(); treewalkidx = treewalkidx.parent() ) {
176 && !gfxview->rowController()->isRowExpanded( treewalkidx ) ) {
183 for (
int i = 0; i < model->rowCount( idx ); ++i ) {
184 gfxview->deleteSubtree( ganttProxyModel.index( i, 0, pidx ) );
187 gfxview->updateRow(pidx);
190 while ( ( idx=tw->indexBelow( idx ) ) != QModelIndex() &&
191 gfxview->rowController()->isRowVisible( ganttProxyModel.mapFromSource(idx) ) ) {
192 const QModelIndex proxyidx( ganttProxyModel.mapFromSource( idx ) );
193 gfxview->updateRow(proxyidx);
195 gfxview->blockSignals( blocked );
196 gfxview->updateSceneRect();
199 void View::Private::slotExpanded(
const QModelIndex& _idx)
201 QModelIndex idx( ganttProxyModel.mapFromSource( _idx ) );
204 gfxview->updateRow(idx);
205 }
while ( ( idx=gfxview->rowController()->indexBelow( idx ) ) != QModelIndex()
206 && gfxview->rowController()->isRowVisible( idx ) );
207 gfxview->updateSceneRect();
210 void View::Private::slotVerticalScrollValueChanged(
int val )
213 qDebug() <<
"View::Private::slotVerticalScrollValueChanged("<<val<<
")=" 214 << val/gfxview->verticalScrollBar()->singleStep();
216 leftWidget->verticalScrollBar()->setValue( val/gfxview->verticalScrollBar()->singleStep() );
219 void View::Private::slotLeftWidgetVerticalRangeChanged(
int min,
int max )
222 gfxview->verticalScrollBar()->setRange( min, max );
223 gfxview->updateSceneRect();
226 void View::Private::slotGfxViewVerticalRangeChanged(
int min,
int max )
229 if ( !leftWidget.isNull() && !gfxview.isNull() ) {
230 int leftMin = leftWidget->verticalScrollBar()->minimum();
231 int leftMax = leftWidget->verticalScrollBar()->maximum();
232 bool blocked = gfxview->verticalScrollBar()->blockSignals(
true );
233 gfxview->verticalScrollBar()->setRange( qMax( min, leftMin ), qMax( max, leftMax ) );
234 gfxview->verticalScrollBar()->blockSignals( blocked );
253 _d(new Private(this))
255 #if defined KDAB_EVAL 256 EvalDialog::checkEvalLicense(
"KD Gantt" );
276 if ( aiv==
d->leftWidget )
return;
277 if ( !
d->leftWidget.isNull() ) {
278 d->leftWidget->disconnect(
this );
279 d->leftWidget->hide();
280 d->leftWidget->verticalScrollBar()->disconnect(
d->gfxview->verticalScrollBar() );
281 d->gfxview->verticalScrollBar()->disconnect(
d->leftWidget->verticalScrollBar() );
285 d->splitter.insertWidget( 0,
d->leftWidget );
287 if ( qobject_cast<QTreeView*>(
d->leftWidget) ) {
288 connect(
d->leftWidget, SIGNAL( collapsed(
const QModelIndex& ) ),
289 this, SLOT( slotCollapsed(
const QModelIndex& ) ) );
290 connect(
d->leftWidget, SIGNAL( expanded(
const QModelIndex& ) ),
291 this, SLOT( slotExpanded(
const QModelIndex& ) ) );
294 connect(
d->gfxview->verticalScrollBar(), SIGNAL( valueChanged(
int ) ),
295 d->leftWidget->verticalScrollBar(), SLOT( setValue(
int ) ) );
296 connect(
d->leftWidget->verticalScrollBar(), SIGNAL( valueChanged(
int ) ),
297 d->gfxview->verticalScrollBar(), SLOT( setValue(
int ) ) );
298 connect(
d->leftWidget->verticalScrollBar(), SIGNAL( rangeChanged(
int,
int ) ),
299 this, SLOT( slotLeftWidgetVerticalRangeChanged(
int,
int ) ) );
300 connect(
d->gfxview->verticalScrollBar(), SIGNAL( rangeChanged(
int,
int ) ),
301 this, SLOT( slotGfxViewVerticalRangeChanged(
int,
int ) ) );
311 if ( ctrl ==
d->rowController &&
d->gfxview->rowController() == ctrl )
return;
312 d->rowController = ctrl;
313 d->gfxview->setRowController(
d->rowController );
321 return d->rowController;
328 return d->rowController;
337 return d->leftWidget;
345 return d->leftWidget;
356 if ( gv !=
d->gfxview ) {
359 d->setupGraphicsView();
360 d->gfxview->setGrid( old->
grid() );
413 d->ganttProxyModel.setSourceModel( model );
414 d->gfxview->setModel( &
d->ganttProxyModel );
421 return leftView()->selectionModel();
429 leftView()->setSelectionModel( smodel );
430 d->gfxview->setSelectionModel(
new QItemSelectionModel( &(
d->ganttProxyModel ),
this ) );
440 d->gfxview->setGrid( grid );
445 KDGanttTreeView* tw = qobject_cast<KDGanttTreeView*>(
leftView());
446 tw->expandAll(index);
451 KDGanttTreeView* tw = qobject_cast<KDGanttTreeView*>(
leftView());
452 tw->collapseAll(index);
459 return d->gfxview->grid();
475 d->gfxview->setRootIndex( idx );
482 return d->gfxview->itemDelegate();
490 leftView()->setItemDelegate( delegate );
491 d->gfxview->setItemDelegate( delegate );
499 d->constraintProxy.setSourceModel( cm );
500 d->gfxview->setConstraintModel( &
d->mappedConstraintModel );
507 return d->constraintProxy.sourceModel();
512 return &(
d->ganttProxyModel );
517 return &(
d->ganttProxyModel );
529 const QModelIndex pidx =
d->ganttProxyModel.mapFromSource(index);
532 view->ensureVisible(item);
537 QWidget::resizeEvent(ev);
548 return d->gfxview->indexAt( pos );
559 void View::print( QPrinter* printer,
bool drawRowLabels,
bool drawColumnLabels )
576 void View::print( QPrinter* printer, qreal start, qreal end,
bool drawRowLabels,
bool drawColumnLabels )
587 void View::print( QPainter* painter,
const QRectF& target,
bool drawRowLabels,
bool drawColumnLabels)
589 d->gfxview->print( painter,
605 void View::print( QPainter* painter, qreal start, qreal end,
const QRectF& target,
bool drawRowLabels,
bool drawColumnLabels)
607 d->gfxview->print( painter,
615 #include "moc_kdganttview.cpp" 617 #ifndef KDAB_NO_UNIT_TESTS 621 #include <QApplication> 628 #if 0 // GUI tests do not work well on the server 629 QTimer::singleShot( 1000, qApp, SLOT( quit() ) );
633 QPixmap screenshot1 = QPixmap::grabWidget( &view );
635 QTreeView* tv =
new QTreeView;
639 QTimer::singleShot( 1000, qApp, SLOT( quit() ) );
642 QPixmap screenshot2 = QPixmap::grabWidget( &view );
644 assertEqual( screenshot1.toImage(), screenshot2.toImage() );
646 QListView* lv =
new QListView;
650 QTimer::singleShot( 1000, qApp, SLOT( quit() ) );
QAbstractProxyModel * summaryHandlingModel() const
void setLeftView(QAbstractItemView *)
QModelIndex indexAt(int height) const override
Proxy model that supports summary gantt items.
void setSelectionModel(QItemSelectionModel *smodel)
void setItemDelegate(ItemDelegate *)
const QAbstractProxyModel * ganttProxyModel() const
Abstract baseclass for grids. A grid is used to convert between QModelIndex'es and gantt chart values...
ConstraintModel * constraintModel() const
void print(QPrinter *printer, bool drawRowLabels=true, bool drawColumnLabels=true)
QAbstractItemModel * model() const
Class used to render gantt items in a KDGantt::GraphicsView.
GraphicsItem * findItem(const QModelIndex &) const
QModelIndex mapFromSource(const QModelIndex &sourceIndex) const override
const GraphicsView * graphicsView() const
void ensureVisible(const QModelIndex &index)
void setModel(QAbstractItemModel *model)
ItemDelegate * itemDelegate() const
Class only listed here to document inheritance of some KDChart classes.
const QAbstractItemView * leftView() const
void setConstraintModel(ConstraintModel *)
Class only listed here to document inheritance of some KDChart classes.
The GraphicsView class provides a model/view implementation of a gantt chart.
AbstractGrid * grid() const
void expandAll(QModelIndex index=QModelIndex())
void print(QPrinter *printer, bool drawRowLabels=true, bool drawColumnLabels=true)
void collapseAll(QModelIndex index=QModelIndex())
void setGrid(AbstractGrid *)
AbstractRowController * rowController()
KDAB_SCOPED_UNITTEST_SIMPLE(KDGantt, View,"test")
const QSplitter * splitter() const
QModelIndex indexAt(const QPoint &pos) const
void resizeEvent(QResizeEvent *) override
This widget that consists of a QTreeView and a GraphicsView.
AbstractGrid * grid() const
void setRowController(AbstractRowController *)
QItemSelectionModel * selectionModel() const
void setRootIndex(const QModelIndex &idx)
QModelIndex rootIndex() const
void setGraphicsView(GraphicsView *)
Abstract baseclass for row controllers. A row controller is used by the GraphicsView to nagivate the ...
#define assertEqual(x, y)