/* This file is part of the KDE project Copyright (C) 2003 - 2004 Dag Andersen This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; version 2 of the License. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "kpttask.h" #include "kptcanvasitem.h" #include "kptrelation.h" #include "kptpertcanvas.h" #include "kptganttview.h" #include #include #include #include #include #include namespace KPlato { PertNodeItem::PertNodeItem( PertCanvas *view, Node &node, int row, int col ) : TQCanvasPolygon(view->canvas()), m_node(node), m_row(row), m_col(col) { m_x = m_y = 0; m_wgap = view->verticalGap(); m_hgap = view->horizontalGap(); m_width = view->itemSize().width(); m_height = view->itemSize().height(); m_name = new TQCanvasText(node.name(), view->canvas()); m_childRelations.setAutoDelete(true); } PertNodeItem::~PertNodeItem() { TQCanvasItemList list = canvas()->allItems(); TQCanvasItemList::Iterator it = list.begin(); for (; it != list.end(); ++it) { if ( *it == m_name ) m_name->hide(); if ( *it == m_leader ) m_leader->hide(); } hide(); } int PertNodeItem::rtti() const { return RTTI; } int PertNodeItem::RTTI = 2000; void PertNodeItem::setVisible(bool yes) { //kdDebug()<allItems(); TQCanvasItemList::Iterator it = list.begin(); for (; it != list.end(); ++it) { if ( *it == m_name ) m_name->tqsetVisible(yes); if ( *it == m_leader ) m_leader->tqsetVisible(yes); } } void PertNodeItem::move(PertCanvas *view, int row, int col) { //kdDebug()<mapNode(this); // Now map my tqchildren TQPtrListIterator it(m_childRelations); for (; it.current(); ++it) { view->mapChildNode(this, it.current()->childItem, it.current()->relation->type()); } // now move the item on the canvas m_x = x(col); m_y = y(row); m_left = TQPoint(m_x, m_y + m_height/2); m_right = TQPoint(m_x + m_width, m_y + m_height/2); TQCanvasPolygon::move(m_x, m_y); if (m_name) m_name->move(m_x+5, m_y+2); setVisible(true); //kdDebug()<canvas()), m_view(view), m_rel(rel), m_parentItem(tqparent), m_childItem(child) { //kdDebug()<node().name()<<" Child="<node().name()< tqparent column // b) Relation::FinishFinish: child column >= tqparent column // c) Relation::StartStart: child column >= tqparent column // d) Child row can be >= tqparent row wgap = m_view->verticalGap(); hgap = m_view->horizontalGap(); // could not use ...rect() here, don't know why tqparentTop = (int)(m_parentItem->y()); tqparentBottom = tqparentTop + (int)(m_parentItem->height()); childTop = (int)(m_childItem->y()); childRow = m_childItem->row(); childCol = m_childItem->column(); tqparentRow = m_parentItem->row(); tqparentCol = m_parentItem->column(); //kdDebug()<node().name()<<" ("<tqparent()->name()<<" to child: "<child()->name()<exitPoint(Relation::FinishStart); TQPoint childPoint = m_childItem->entryPoint(Relation::FinishStart); TQPointArray a; a.putPoints(0, 1, tqparentPoint.x(), tqparentPoint.y()); if ( tqparentRow == childRow ) { if (tqparentCol == childCol - 1 || rowFree(tqparentRow, tqparentCol+1, childCol-1)) { a.putPoints(1, 1, childPoint.x(), childPoint.y()); } else // go around below { a.putPoints(1, 9, tqparentPoint.x()+(wgap/2)-3, tqparentPoint.y(), // stop short tqparentPoint.x()+(wgap/2), tqparentPoint.y()+3, // right/down tqparentPoint.x()+(wgap/2), tqparentBottom+(hgap/2)-3, // stop short tqparentPoint.x()+(wgap/2)+3, tqparentBottom+(hgap/2), // right/down childPoint.x()-(wgap/2)-3, tqparentBottom+(hgap/2), // stop short childPoint.x()-(wgap/2), tqparentBottom+(hgap/2)-3, // right/up childPoint.x()-(wgap/2), childPoint.y()+3, // stop short childPoint.x()-(wgap/2)+3, childPoint.y(), // right/up childPoint.x(), childPoint.y()); } } else if ( tqparentRow > childRow ) { if (tqparentCol == childCol - 1) { a.putPoints(1, 5, tqparentPoint.x()+(wgap/2)-3, tqparentPoint.y(), tqparentPoint.x()+(wgap/2), tqparentPoint.y()-3, tqparentPoint.x()+wgap/2, childPoint.y()+3, tqparentPoint.x()+(wgap/2)+3, childPoint.y(), childPoint.x(), childPoint.y()); } else // go around above { a.putPoints(1, 9, tqparentPoint.x()+(wgap/2)-3, tqparentPoint.y(), tqparentPoint.x()+(wgap/2), tqparentPoint.y()-3, tqparentPoint.x()+wgap/2, tqparentTop-(hgap/2)+3, tqparentPoint.x()+(wgap/2)+3, tqparentTop-(hgap/2), childPoint.x()-(wgap/2)-3, tqparentTop-hgap/2, childPoint.x()-(wgap/2), tqparentTop-(hgap/2)-3, childPoint.x()-wgap/2, childPoint.y()+3, childPoint.x()-(wgap/2)+3, childPoint.y(), childPoint.x(), childPoint.y()); } } else if ( tqparentRow < childRow ) { if (tqparentCol == childCol - 1) { a.putPoints(1, 5, tqparentPoint.x()+(wgap/2)-3, tqparentPoint.y(), tqparentPoint.x()+(wgap/2), tqparentPoint.y()+3, tqparentPoint.x()+wgap/2, childPoint.y()-3, tqparentPoint.x()+(wgap/2)+3, childPoint.y(), childPoint.x(), childPoint.y()); } else { a.putPoints(1, 9, tqparentPoint.x()+(wgap/2)-3, tqparentPoint.y(), tqparentPoint.x()+(wgap/2), tqparentPoint.y()+3, tqparentPoint.x()+wgap/2, childTop-(hgap/2)-3, tqparentPoint.x()+(wgap/2)+3, childTop-(hgap/2), childPoint.x()-(wgap/2)-3, childTop-(hgap/2), childPoint.x()-(wgap/2), childTop-(hgap/2)+3, childPoint.x()-wgap/2, childPoint.y()-3, childPoint.x()-wgap/2+3, childPoint.y(), childPoint.x(), childPoint.y()); } } setPoints(a); } void PertRelationItem::setFinishFinishPoints() { //kdDebug()<exitPoint(Relation::FinishFinish); TQPoint childPoint = m_childItem->entryPoint(Relation::FinishFinish); TQPointArray a; a.putPoints(0, 1, tqparentPoint.x(), tqparentPoint.y()); if ( tqparentRow >= childRow ) { if (tqparentCol == childCol) { a.putPoints(1, 5, childPoint.x()+(wgap/2)-3, tqparentPoint.y(), childPoint.x()+(wgap/2), tqparentPoint.y()-3, childPoint.x()+wgap/2, childPoint.y()+3, childPoint.x()+(wgap/2)-3, childPoint.y(), childPoint.x(), childPoint.y()); } else if (tqparentCol < childCol) { a.putPoints(1, 9, tqparentPoint.x()+(wgap/2)-3, tqparentPoint.y(), // stop short tqparentPoint.x()+(wgap/2), tqparentPoint.y()+3, // right/down tqparentPoint.x()+(wgap/2), tqparentBottom+(hgap/2)-3, // stop short tqparentPoint.x()+(wgap/2)+3, tqparentBottom+(hgap/2), // right/down childPoint.x()+(wgap/2)-3, tqparentBottom+(hgap/2), // stop short childPoint.x()+(wgap/2), tqparentBottom+(hgap/2)-3, // right/up childPoint.x()+(wgap/2), childPoint.y()+3, // stop short childPoint.x()+(wgap/2)-3, childPoint.y(), // left/up childPoint.x(), childPoint.y()); } } else // tqparentRow < choldRow { if (tqparentCol == childCol) { a.putPoints(1, 5, tqparentPoint.x()+(wgap/2)-3, tqparentPoint.y(), tqparentPoint.x()+(wgap/2), tqparentPoint.y()+3, tqparentPoint.x()+wgap/2, childPoint.y()-3, tqparentPoint.x()+(wgap/2)-3, childPoint.y(), childPoint.x(), childPoint.y()); } else if (tqparentCol < childCol) { if (rowFree(tqparentRow, tqparentCol+1, childCol)) a.putPoints(1, 5, childPoint.x()+(wgap/2)-3, tqparentPoint.y(), childPoint.x()+(wgap/2), tqparentPoint.y()+3, childPoint.x()+(wgap/2), childPoint.y()-3, childPoint.x()+(wgap/2)-3, childPoint.y(), childPoint.x(), childPoint.y()); else a.putPoints(1, 9, tqparentPoint.x()+(wgap/2)-3, tqparentPoint.y(), tqparentPoint.x()+(wgap/2), tqparentPoint.y()+3, tqparentPoint.x()+wgap/2, childTop-(hgap/2)-3, tqparentPoint.x()+(wgap/2)+3, childTop-(hgap/2), childPoint.x()+(wgap/2)-3, childTop-(hgap/2), childPoint.x()+(wgap/2), childTop-(hgap/2)+3, childPoint.x()+(wgap/2), childPoint.y()-3, childPoint.x()+(wgap/2)-3, childPoint.y(), childPoint.x(), childPoint.y()); } else { a.putPoints(1, 9, tqparentPoint.x()+(wgap/2)-3, tqparentPoint.y(), tqparentPoint.x()+(wgap/2), tqparentPoint.y()+3, tqparentPoint.x()+wgap/2, childTop-(hgap/2)-3, tqparentPoint.x()+(wgap/2)+3, childTop-(hgap/2), childPoint.x()+(wgap/2)-3, childTop-(hgap/2), childPoint.x()+(wgap/2), childTop-(hgap/2)+3, childPoint.x()+wgap/2, childPoint.y()-3, childPoint.x()+wgap/2-3, childPoint.y(), childPoint.x(), childPoint.y()); } } setPoints(a); } void PertRelationItem::setStartStartPoints() { //kdDebug()<exitPoint(Relation::StartStart); TQPoint childPoint = m_childItem->entryPoint(Relation::StartStart); TQPointArray a; a.putPoints(0, 1, tqparentPoint.x(), tqparentPoint.y()); if ( tqparentRow > childRow ) { if (tqparentCol == childCol) // go up { a.putPoints(1, 4, tqparentPoint.x()-(wgap/2)+3, tqparentPoint.y(), tqparentPoint.x()-(wgap/2), tqparentPoint.y()-3, tqparentPoint.x()-(wgap/2), childPoint.y()+3, tqparentPoint.x()-(wgap/2)+3, childPoint.y()); } else // go above myself { a.putPoints(1, 8, tqparentPoint.x()-(wgap/2)+3, tqparentPoint.y(), tqparentPoint.x()-(wgap/2), tqparentPoint.y()-3, tqparentPoint.x()-(wgap/2), tqparentTop-(hgap/2)+3, tqparentPoint.x()-(wgap/2)+3, tqparentTop-(hgap/2), childPoint.x()-(wgap/2)-3, tqparentTop-(hgap/2), childPoint.x()-(wgap/2), tqparentTop-(hgap/2)-3, childPoint.x()-(wgap/2), childPoint.y()+3, childPoint.x()-(wgap/2)+3, childPoint.y()); } } else // go left/down { a.putPoints(1, 2, tqparentPoint.x()-(wgap/2)+3, tqparentPoint.y(), tqparentPoint.x()-(wgap/2), tqparentPoint.y()+3); if (tqparentCol == childCol) { a.putPoints(3, 2, tqparentPoint.x()-(wgap/2), childPoint.y()-3, tqparentPoint.x()-(wgap/2)+3, childPoint.y()); } else // go below myself { if (tqparentRow == childRow) // go up { a.putPoints(3, 6, tqparentPoint.x()-(wgap/2), tqparentBottom+hgap/2-3, tqparentPoint.x()-(wgap/2)+3, tqparentBottom+hgap/2, childPoint.x()-(wgap/2)-3, tqparentBottom+hgap/2, childPoint.x()-(wgap/2), tqparentBottom+hgap/2-3, childPoint.x()-(wgap/2), childPoint.y()+3, childPoint.x()-(wgap/2)+3, childPoint.y()); } else // go down { a.putPoints(3, 6, tqparentPoint.x()-(wgap/2), childTop-(hgap/2)-3, tqparentPoint.x()-(wgap/2)+3, childTop-hgap/2, childPoint.x()-(wgap/2)-3, childTop-hgap/2, childPoint.x()-(wgap/2), childTop-(hgap/2)+3, childPoint.x()-(wgap/2), childPoint.y()-3, childPoint.x()-(wgap/2)+3, childPoint.y()); } } } a.putPoints(a.size(), 1, childPoint.x(), childPoint.y()); setPoints(a); } void PertRelationItem::drawShape(TQPainter &p) { //kdDebug()<tqparent()->name()<<" to "<child()->name()< 1&& a[pos-1].x() > a[pos].x()) xoffset = 3; TQPoint pnt(a[pos].x()+xoffset, a[pos].y()-3); p.drawLine(a[pos], pnt); pnt.setY(a[pos].y()+3); p.drawLine(a[pos], pnt); } TQPointArray PertRelationItem::areaPoints () const { TQPointArray pa(4); int pw = (pen().width()+1)/2; if ( pw < 1 ) pw = 1; if ( pen() == Qt::NoPen ) pw = 0; pa[0] = TQPoint(left-pw,top-pw); pa[1] = pa[0] + TQPoint(right-left+pw*2,0); pa[2] = pa[1] + TQPoint(0,bottom-top+pw*2); pa[3] = pa[0] + TQPoint(0,bottom-top+pw*2); /* kdDebug()<tqparent()->name()<<" to "<child()->name()<allItems(); TQCanvasItemList::Iterator it = list.begin(); for (; it != list.end(); ++it) { if ( (*it)->rtti() == PertProjectItem::RTTI || (*it)->rtti() == PertTaskItem::RTTI || (*it)->rtti() == PertMilestoneItem::RTTI ) { PertNodeItem *item = (PertNodeItem *)(*it); if ( item->row() == row ) { int col = item->column(); if (col >= startCol && col <= endCol) { //kdDebug()<name()), m_node(node), m_view(tqparent) { setExpandable(true); setOpen(true); } GanttViewSummaryItem::GanttViewSummaryItem(KDGanttViewItem *tqparent, Node *node) : KDGanttViewSummaryItem(tqparent, node->name()), m_node(node), m_view(0) { m_drawn = false; GanttViewSummaryItem *p = dynamic_cast(tqparent); if (p) m_view = p->ganttView(); setExpandable(true); setOpen(true); } void GanttViewSummaryItem::insertRelations(GanttView *view) { //kdDebug()< it(m_node->dependChildNodes()); for (; it.current(); ++it) { KDGanttViewItem *child = tqfind(m_view->firstChild(), it.current()->child()); if (child) { KDGanttViewTaskLink *link = new KDGanttViewTaskLink(this, child, kdLinkType(it.current()->type())); //TODO i18n TQString t = i18n("From: %1").tqarg(this->listViewText(0)); t += "\n" + i18n("To: %1").tqarg(child->listViewText(0)); if (it.current()->lag() > Duration::zeroDuration) { t += "\n" + i18n("Lag: %1").tqarg(it.current()->lag().toString(Duration::Format_i18nDayTime)); } link->setTooltipText(t); view->addTaskLink(link); } } } KDGanttViewItem *GanttViewSummaryItem::tqfind(Node *node) { //kdDebug()<type() == Event) { GanttViewEventItem *i = static_cast(item); return i->tqfind(node); } else if (item->type() == Task) { GanttViewTaskItem *i = static_cast(item); return i->tqfind(node); } else if (item->type() == Summary) { GanttViewSummaryItem *i = static_cast(item); return i->tqfind(node); } return 0; } //////////////////// GanttViewTaskItem ////////////////////////// GanttViewTaskItem::GanttViewTaskItem(KDGanttView *tqparent, KPlato::Task *task) : KDGanttViewTaskItem(tqparent, task->name()), m_task(task), m_view(tqparent) { } GanttViewTaskItem::GanttViewTaskItem(KDGanttViewItem *tqparent, KPlato::Task *task) : KDGanttViewTaskItem(tqparent, task->name()), m_task(task), m_view() { m_drawn = false; GanttViewSummaryItem *p = dynamic_cast(tqparent); if (p) m_view = p->ganttView(); } void GanttViewTaskItem::insertRelations(GanttView *view) { //kdDebug()< it(m_task->dependChildNodes()); for (; it.current(); ++it) { KDGanttViewItem *child = tqfind(m_view->firstChild(), it.current()->child()); if (child) { KDGanttViewTaskLink *link = new KDGanttViewTaskLink(this, child, kdLinkType(it.current()->type())); //TODO i18n TQString t = i18n("From: %1").tqarg(this->listViewText(0)); t += "\n" + i18n("To: %1").tqarg(child->listViewText(0)); if (it.current()->lag() > Duration::zeroDuration) { t += "\n" + i18n("Lag: %1").tqarg(it.current()->lag().toString(Duration::Format_i18nDayTime)); } link->setTooltipText(t); view->addTaskLink(link); } } } KDGanttViewItem *GanttViewTaskItem::tqfind(Node *node) { //kdDebug()<type() == Event) { GanttViewEventItem *i = static_cast(item); return i->tqfind(node); } else if (item->type() == Task) { GanttViewTaskItem *i= static_cast(item); return i->tqfind(node); } else if (item->type() == Summary) { GanttViewSummaryItem *i = static_cast(item); return i->tqfind(node); } return 0; // avoid warning } //////////////////// GanttViewEventItem ////////////////////////// GanttViewEventItem::GanttViewEventItem(KDGanttView *tqparent, KPlato::Task *task) : KDGanttViewEventItem(tqparent, task->name()), m_task(task), m_view(tqparent) { } GanttViewEventItem::GanttViewEventItem(KDGanttViewItem *tqparent, KPlato::Task *task) : KDGanttViewEventItem(tqparent, task->name()), m_task(task), m_view() { m_drawn = false; GanttViewSummaryItem *p = dynamic_cast(tqparent); if (p) m_view = p->ganttView(); } void GanttViewEventItem::insertRelations(GanttView *view) { //kdDebug()< it(m_task->dependChildNodes()); for (; it.current(); ++it) { KDGanttViewItem *child = tqfind(m_view->firstChild(), it.current()->child()); if (child) { KDGanttViewTaskLink *link = new KDGanttViewTaskLink(this, child, kdLinkType(it.current()->type())); TQString t = i18n("From: %1").tqarg(this->listViewText(0)); t += "\n" + i18n("To: %1").tqarg(child->listViewText(0)); if (it.current()->lag() > Duration::zeroDuration) { t += "\n" + i18n("Lag: %1").tqarg(it.current()->lag().toString(Duration::Format_i18nDayTime)); } link->setTooltipText(t); view->addTaskLink(link); } } } KDGanttViewItem *GanttViewEventItem::tqfind(Node *node) { //kdDebug()<type() == Event) { GanttViewEventItem *i = static_cast(item); return i->tqfind(node); } else if (item->type() == Task) { GanttViewTaskItem *i = static_cast(item); return i->tqfind(node); } else if (item->type() == Summary) { GanttViewSummaryItem *i = static_cast(item); return i->tqfind(node); } return 0; } } //KPlato namespace