9#include "kganttgraphicsitem.h"
10#include "kganttgraphicsscene.h"
11#include "kganttgraphicsview.h"
12#include "kganttitemdelegate.h"
13#include "kganttconstraintgraphicsitem.h"
14#include "kganttconstraintmodel.h"
15#include "kganttconstraint.h"
16#include "kganttabstractgrid.h"
17#include "kganttabstractrowcontroller.h"
25#include <QAbstractItemModel>
26#include <QAbstractProxyModel>
27#include <QGraphicsSceneMouseEvent>
28#include <QGraphicsLineItem>
29#include <QApplication>
44 Updater(
bool* u ) : u_ptr( u ), oldval( *u ) {
54 : BASE( parent ), m_isupdating( false )
63 : BASE( parent ), m_index( idx ), m_isupdating( false )
70GraphicsItem::~GraphicsItem()
74void GraphicsItem::init()
84int GraphicsItem::type()
const
91 StyleOptionGanttItem opt;
92 if (!m_index.isValid()) {
105 qDebug() <<
"Item" << m_index.model()->data( m_index,
Qt::DisplayRole ).toString()
106 <<
", ends="<<m_endConstraints.size() <<
", starts="<<m_startConstraints.size();
108 opt.
displayPosition = m_endConstraints.size()<m_startConstraints.size()?StyleOptionGanttItem::Left:StyleOptionGanttItem::Right;
120 case StyleOptionGanttItem::Hidden:
121 case StyleOptionGanttItem::Center: opt.displayAlignment =
Qt::AlignCenter;
break;
124 opt.
grid =
const_cast<AbstractGrid*
>(scene()->getGrid());
137void GraphicsItem::setRect(
const QRectF& r )
140 qDebug() <<
"GraphicsItem::setRect("<<r<<
"), txt="<<m_index.model()->data( m_index,
Qt::DisplayRole ).toString();
141 if ( m_index.model()->data( m_index,
Qt::DisplayRole ).toString() == QLatin1String(
"Code Freeze" ) ) {
142 qDebug() <<
"gotcha";
148 updateConstraintItems();
152void GraphicsItem::setBoundingRect(
const QRectF& r )
159bool GraphicsItem::isEditable()
const
161 return !scene()->isReadOnly() && m_index.isValid() && m_index.model()->flags( m_index ) &
Qt::ItemIsEditable;
164void GraphicsItem::paint( QPainter* painter,
const QStyleOptionGraphicsItem* option,
168 if ( boundingRect().
isValid() && scene() ) {
169 StyleOptionGanttItem opt = getStyleOption();
170 *
static_cast<QStyleOption*
>(&opt) = *
static_cast<const QStyleOption*
>( option );
173 opt.palette = widget->
palette();
177 scene()->itemDelegate()->paintGanttItem( painter, opt, index() );
181void GraphicsItem::setIndex(
const QPersistentModelIndex& idx )
187QString GraphicsItem::ganttToolTip()
const
189 return scene()->itemDelegate()->toolTip( index() );
192QRectF GraphicsItem::boundingRect()
const
194 return m_boundingrect;
197QPointF GraphicsItem::startConnector(
int relationType )
const
199 switch ( relationType ) {
200 case Constraint::StartStart:
201 case Constraint::StartFinish:
202 return mapToScene( m_rect.left(), m_rect.top()+m_rect.height()/2. );
206 return mapToScene( m_rect.right(), m_rect.top()+m_rect.height()/2. );
209QPointF GraphicsItem::endConnector(
int relationType )
const
211 switch ( relationType ) {
212 case Constraint::FinishFinish:
213 case Constraint::StartFinish:
214 return mapToScene( m_rect.right(), m_rect.top()+m_rect.height()/2. );
218 return mapToScene( m_rect.left(), m_rect.top()+m_rect.height()/2. );
222void GraphicsItem::constraintsChanged()
224 if ( !scene() || !scene()->itemDelegate() )
return;
225 const Span bs = scene()->itemDelegate()->itemBoundingSpan( getStyleOption(), index() );
226 const QRectF br = boundingRect();
227 setBoundingRect( QRectF( bs.start(), 0., bs.length(), br.
height() ) );
233 m_startConstraints << item;
234 item->setStart( startConnector( item->constraint().
relationType() ) );
235 constraintsChanged();
241 m_endConstraints << item;
242 item->setEnd( endConnector( item->constraint().
relationType() ) );
243 constraintsChanged();
249 m_startConstraints.removeAll( item );
250 constraintsChanged();
256 m_endConstraints.removeAll( item );
257 constraintsChanged();
260void GraphicsItem::updateConstraintItems()
262 for ( ConstraintGraphicsItem* item : std::as_const(m_startConstraints) ) {
263 QPointF s = startConnector( item->constraint().
relationType() );
266 for ( ConstraintGraphicsItem* item : std::as_const(m_endConstraints) ) {
267 QPointF e = endConnector( item->constraint().
relationType() );
272void GraphicsItem::updateItem(
const Span& rowGeometry,
const QPersistentModelIndex& idx )
275 Updater updater( &m_isupdating );
282 const Span s = scene()->getGrid()->mapToChart(
static_cast<const QModelIndex&
>(idx) );
283 setPos( QPointF( s.start(), rowGeometry.start() ) );
284 setRect( QRectF( 0., 0., s.length(), rowGeometry.length() ) );
286 const Span bs = scene()->itemDelegate()->itemBoundingSpan( getStyleOption(), index() );
288 setBoundingRect( QRectF( bs.start(), 0., bs.length(), rowGeometry.length() ) );
289 const int maxh = scene()->rowController()->maximumItemHeight();
290 if ( maxh < rowGeometry.length() ) {
292 const Qt::Alignment align = getStyleOption().displayAlignment;
296 r.
setY( rowGeometry.length()-maxh );
299 r.
setY( ( rowGeometry.length()-maxh ) / 2. );
309QVariant GraphicsItem::itemChange( GraphicsItemChange change,
const QVariant& value )
313 if ( isEditable() ) {
329void GraphicsItem::focusInEvent( QFocusEvent* event )
334void GraphicsItem::updateModel()
337 if ( isEditable() ) {
338 QAbstractItemModel* model =
const_cast<QAbstractItemModel*
>( index().model() );
340 ConstraintModel* cmodel = scene()->constraintModel();
347 QList<Constraint> constraints;
348 for ( QList<ConstraintGraphicsItem*>::iterator it1 = m_startConstraints.begin() ;
349 it1 != m_startConstraints.end() ;
351 constraints.
push_back((*it1)->proxyConstraint());
352 for ( QList<ConstraintGraphicsItem*>::iterator it2 = m_endConstraints.begin() ;
353 it2 != m_endConstraints.end() ;
355 constraints.
push_back((*it2)->proxyConstraint());
356 if ( scene()->getGrid()->mapFromChart( Span(
scenePos().
x(), rect().width() ),
359 scene()->updateRow( index().parent() );
365void GraphicsItem::hoverMoveEvent( QGraphicsSceneHoverEvent* event )
367 if ( !isEditable() )
return;
368 StyleOptionGanttItem opt = getStyleOption();
369 ItemDelegate::InteractionState istate = scene()->itemDelegate()->interactionStateFor(
event->pos(), opt, index() );
371 case ItemDelegate::State_ExtendLeft:
375 scene()->itemEntered( index() );
377 case ItemDelegate::State_ExtendRight:
381 scene()->itemEntered( index() );
383 case ItemDelegate::State_Move:
387 scene()->itemEntered( index() );
397void GraphicsItem::hoverLeaveEvent( QGraphicsSceneHoverEvent* )
404void GraphicsItem::mousePressEvent( QGraphicsSceneMouseEvent* event )
407 StyleOptionGanttItem opt = getStyleOption();
408 int istate = scene()->itemDelegate()->interactionStateFor(
event->pos(), opt, index() );
412 if ( istate != ItemDelegate::State_None ) {
414 m_presspos =
event->pos();
415 m_pressscenepos =
event->scenePos();
417 scene()->itemPressed( index(), event );
419 switch ( m_istate ) {
420 case ItemDelegate::State_ExtendLeft:
421 case ItemDelegate::State_ExtendRight:
433void GraphicsItem::mouseReleaseEvent( QGraphicsSceneMouseEvent* event )
436 if ( !m_presspos.isNull() ) {
437 scene()->itemClicked( index() );
439 delete m_dragline; m_dragline =
nullptr;
440 if ( scene()->dragSource() ) {
443 if ( other && scene()->dragSource()!=other &&
449 QRectF itemRect = other->rect().
adjusted(-other->rect().
height()/2.0, 0, 0, 0 );
452 GraphicsView* view = qobject_cast<GraphicsView*>(
event->widget()->parentWidget() );
454 view->
addConstraint( scene()->summaryHandlingModel()->mapToSource( scene()->dragSource()->index() ),
455 scene()->summaryHandlingModel()->mapToSource( other->index() ),
event->modifiers() );
461 if ( other && scene()->dragSource()!=other &&
463 GraphicsView* view = qobject_cast<GraphicsView*>(
event->widget()->parentWidget() );
465 view->
addConstraint( scene()->summaryHandlingModel()->mapToSource( scene()->dragSource()->index() ),
466 scene()->summaryHandlingModel()->mapToSource( other->index() ),
event->modifiers() );
471 scene()->setDragSource(
nullptr );
474 if ( isEditable() ) {
475 updateItemFromMouse(
event->scenePos());
481 m_presspos = QPointF();
489 m_presspos = QPointF();
492void GraphicsItem::mouseDoubleClickEvent( QGraphicsSceneMouseEvent* event )
494 const int typ =
static_cast<ItemType>( index().model()->data( index(),
ItemTypeRole ).toInt() );
495 StyleOptionGanttItem opt = getStyleOption();
496 ItemDelegate::InteractionState istate = scene()->itemDelegate()->interactionStateFor(
event->pos(), opt, index() );
497 if ( (istate != ItemDelegate::State_None) || (typ == TypeSummary)) {
498 scene()->itemDoubleClicked( index() );
500 BASE::mouseDoubleClickEvent( event );
503void GraphicsItem::updateItemFromMouse(
const QPointF& scenepos )
506 const QPointF p = scenepos - m_presspos;
508 QRectF br = boundingRect();
509 switch ( m_istate ) {
510 case ItemDelegate::State_Move:
513 case ItemDelegate::State_ExtendLeft: {
514 const qreal brr = br.
right();
515 const qreal rr = r.
right();
516 const qreal delta =
pos().
x()-p.
x();
522 case ItemDelegate::State_ExtendRight: {
523 const qreal rr = r.
right();
531 setBoundingRect( br );
534void GraphicsItem::mouseMoveEvent( QGraphicsSceneMouseEvent* event )
536 if ( !isEditable() )
return;
537 if ( m_presspos.isNull() )
return;
540 switch ( m_istate ) {
541 case ItemDelegate::State_ExtendLeft:
542 case ItemDelegate::State_ExtendRight:
543 case ItemDelegate::State_Move:
545 if ( qAbs( m_pressscenepos.x()-
event->scenePos().x() ) < 10.
546 && qAbs( m_pressscenepos.y()-
event->scenePos().y() ) > 5. ) {
547 m_istate = ItemDelegate::State_DragConstraint;
548 m_dragline =
new QGraphicsLineItem(
this );
550 m_dragline->setLine(QLineF( rect().
center(),
event->pos() ));
551 scene()->setDragSource(
this );
555 updateItemFromMouse(
event->scenePos());
558 case ItemDelegate::State_DragConstraint: {
559 QLineF line = m_dragline->line();
560 m_dragline->setLine( QLineF( line.
p1(),
event->pos() ) );
RelationType relationType() const
virtual void addConstraint(const QModelIndex &from, const QModelIndex &to, Qt::KeyboardModifiers modifiers)
A class representing a start point and a length.
QStyleOption subclass for gantt items.
AKONADI_CALENDAR_EXPORT KCalendarCore::Event::Ptr event(const Akonadi::Item &item)
void init(KXmlGuiWindow *window, KGameDifficulty *difficulty=nullptr)
@ ItemTypeRole
The item type.
@ TextPositionRole
The position of the text label on the item. The type of this value is KGantt::StyleOptionGanttItem::P...
bool isValid(QStringView ifopt)
void setHandlesChildEvents(bool enabled)
GraphicsItemFlags flags() const const
bool hasFocus() const const
bool isEnabled() const const
bool isSelected() const const
virtual QVariant itemChange(GraphicsItemChange change, const QVariant &value)
QPainterPath mapToScene(const QPainterPath &path) const const
QPointF pos() const const
void prepareGeometryChange()
T qgraphicsitem_cast(QGraphicsItem *item)
QGraphicsScene * scene() const const
QPointF scenePos() const const
void setAcceptHoverEvents(bool enabled)
void setCacheMode(CacheMode mode, const QSize &logicalCacheSize)
void setCursor(const QCursor &cursor)
void setFlags(GraphicsItemFlags flags)
void setPos(const QPointF &pos)
void update(const QRectF &rect)
void addItem(QGraphicsItem *item)
void push_back(parameter_type value)
QRectF boundingRect() const const
QVariant data(int role) const const
bool isValid() const const
QRectF adjusted(qreal dx1, qreal dy1, qreal dx2, qreal dy2) const const
bool contains(const QPointF &point) const const
qreal height() const const
qreal right() const const
void setHeight(qreal height)
void setWidth(qreal width)
qreal width() const const
QTextStream & center(QTextStream &stream)
QVariant fromValue(T &&value)
bool isValid() const const
int toInt(bool *ok) const const
QPointF toPointF() const const