kplato
kptpertcanvas.cc00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "kptpertcanvas.h"
00021 #include "kptnode.h"
00022 #include "kptrelation.h"
00023 #include "kptrelationdialog.h"
00024 #include "kptcanvasitem.h"
00025
00026 #include <qbuffer.h>
00027 #include <qtimer.h>
00028 #include <qclipboard.h>
00029 #include <qprogressdialog.h>
00030 #include <qobjectlist.h>
00031 #include <qpainter.h>
00032 #include <qheader.h>
00033 #include <qcursor.h>
00034 #include <qrect.h>
00035 #include <qsize.h>
00036 #include <qptrlist.h>
00037
00038 #include <KoStore.h>
00039 #include <ktempfile.h>
00040 #include <klocale.h>
00041 #include <kdebug.h>
00042 #include <kapplication.h>
00043 #include <kmessagebox.h>
00044 #include <assert.h>
00045 #include <kmultipledrag.h>
00046 #include <klistview.h>
00047
00048 namespace KPlato
00049 {
00050
00051 PertCanvas::PertCanvas( QWidget *parent )
00052 : QCanvasView( parent, "Pert canvas" ),
00053 m_verticalGap(20),
00054 m_horizontalGap(10),
00055 m_itemSize(100,30)
00056
00057 {
00058
00059 m_canvas = new QCanvas( this );
00060 setCanvas( m_canvas );
00061 }
00062
00063 PertCanvas::~PertCanvas()
00064 {
00065 }
00066
00067 void PertCanvas::draw(Project& project)
00068 {
00069
00070 clear();
00071 updateContents();
00072
00073
00074 QPtrListIterator<Node> nit(project.childNodeIterator());
00075 for ( ; nit.current(); ++nit ) {
00076 createChildItems(createNodeItem(nit.current()));
00077 }
00078
00079
00080 QPtrDictIterator<PertNodeItem> it(m_nodes);
00081 for(; it.current(); ++it)
00082 {
00083 if (!(it.current()->hasParent()) && it.current()->hasChild())
00084 {
00085 m_rows.append(new QMemArray<bool>(1));
00086 it.current()->move(this, m_rows.count()-1, 0);
00087 }
00088 }
00089
00090 for(it.toFirst(); it.current(); ++it)
00091 {
00092 if (!(it.current()->hasParent() || it.current()->hasChild()))
00093 {
00094 m_rows.append(new QMemArray<bool>(1));
00095 it.current()->move(this, m_rows.count()-1, 0);
00096 }
00097 }
00098 drawRelations();
00099 QSize s = canvasSize();
00100 m_canvas->resize(s.width(), s.height());
00101 update();
00102 }
00103
00104 PertNodeItem *PertCanvas::createNodeItem(Node *node)
00105 {
00106 PertNodeItem *item = m_nodes.find(node);
00107 if (!item)
00108 {
00109 if ( node->type() == Node::Type_Project)
00110 kdDebug()<<k_funcinfo<<"Project nodes should not have relations"<<endl;
00111 else if (node->type() == Node::Type_Subproject)
00112 item = new PertProjectItem(this, *node);
00113 else if (node->type()== Node::Type_Summarytask)
00114 item = new PertTaskItem(this, *node);
00115 else if (node->type()== Node::Type_Task)
00116 item = new PertTaskItem(this, *node);
00117 else if (node->type() == Node::Type_Milestone)
00118 item = new PertMilestoneItem(this, *node);
00119 else
00120 kdDebug()<<k_funcinfo<<"Not implemented yet"<<endl;
00121
00122 if (item)
00123 m_nodes.insert(node, item);
00124 }
00125 return item;
00126 }
00127
00128 void PertCanvas::createChildItems(PertNodeItem *parentItem)
00129 {
00130
00131 if (!parentItem)
00132 return;
00133
00134 QPtrListIterator<Relation> it(parentItem->node().dependChildNodes());
00135 for (; it.current(); ++it)
00136 {
00137 PertNodeItem *childItem = createNodeItem(it.current()->child());
00138 if (childItem)
00139 parentItem->addChildRelation(it.current(), childItem);
00140 m_relations.append(it.current());
00141 }
00142
00143
00144 QPtrListIterator<Node> nit(parentItem->node().childNodeIterator());
00145 for ( ; nit.current(); ++nit ) {
00146 createChildItems(createNodeItem(nit.current()));
00147 }
00148 }
00149
00150 void PertCanvas::drawRelations()
00151 {
00152
00153 QPtrListIterator<Relation> it(m_relations);
00154 for (; it.current(); ++it)
00155 {
00156 PertNodeItem *parentItem = m_nodes.find(it.current()->parent());
00157 PertNodeItem *childItem = m_nodes.find(it.current()->child());
00158 if (parentItem && childItem)
00159 {
00160 PertRelationItem *item = new PertRelationItem(this, parentItem, childItem, it.current());
00161 item->show();
00162 }
00163 }
00164 }
00165
00166 void PertCanvas::mapNode(PertNodeItem *item)
00167 {
00168
00169 if (! m_rows.at(item->row()) || (item->column() >= 0 && m_rows.at(item->row())->count() <= uint(item->column())))
00170 {
00171 kdError()<<k_funcinfo<<item->node().name()<<": non existing map for: ("<<item->row()<<","<<item->column()<<")"<<endl;
00172 return;
00173 }
00174 m_rows.at(item->row())->at(item->column()) = true;
00175 }
00176
00177 void PertCanvas::mapChildNode(PertNodeItem *parentItem, PertNodeItem *childItem, Relation::Type type)
00178 {
00179
00180 if (!childItem)
00181 {
00182 kdError()<<k_funcinfo<<"No childItem"<<endl;
00183 return;
00184 }
00185 int row = parentItem->row();
00186 int col = parentItem->column();
00187 int chRow = childItem->row();
00188 int chCol = childItem->column();
00189 bool chMapped = (chRow > -1 && chCol > -1);
00190
00191
00192 if (type == Relation::StartStart ||
00193 type == Relation::FinishFinish)
00194 {
00195
00196 if (chMapped)
00197 {
00198 m_rows.at(chRow)->at(chCol) = false;
00199
00200 if (chRow <= row)
00201 {
00202 chRow = row+1;
00203 if (chRow >= 0 && m_rows.count() <= uint(chRow)) {
00204 m_rows.append(new QMemArray<bool>(1));
00205 chRow = m_rows.count()-1;
00206 }
00207
00208 }
00209 if (chCol < col)
00210 {
00211 chCol = col;
00212 if (chCol >= 0 && m_rows.at(chRow)->count() <= uint(chCol))
00213 m_rows.at(chRow)->resize(chCol+1);
00214
00215
00216 }
00217
00218 }
00219 else
00220 {
00221 if (!(m_rows.at(row+1)) ||
00222 m_rows.at(row+1)->at(col) == true)
00223 {
00224 m_rows.append(new QMemArray<bool>(col+1));
00225 }
00226 else if (col >= 0 && m_rows.at(row+1)->count() <= uint(col))
00227 m_rows.at(row)->resize(col+1);
00228
00229 chRow = m_rows.count() -1;
00230 chCol = col;
00231 }
00232 }
00233 else if (type == Relation::FinishStart)
00234 {
00235
00236 if (chMapped)
00237 {
00238 m_rows.at(chRow)->at(chCol) = false;
00239 if (chRow < row)
00240 chRow = row;
00241 if (chCol <= col)
00242 {
00243 chCol = col+1;
00244 }
00245 if (chCol >= 0 && m_rows.at(chRow)->count() <= uint(chCol))
00246 m_rows.at(chRow)->resize(chCol+1);
00247 }
00248 else
00249 {
00250 ++col;
00251 if (col >= 0 && m_rows.at(row)->count() <= uint(col))
00252 m_rows.at(row)->resize(col+1);
00253 else if (m_rows.at(row)->at(col) = true)
00254 m_rows.append(new QMemArray<bool>(col+1));
00255
00256 chRow = m_rows.count() -1;
00257 chCol = col;
00258 }
00259 }
00260 else
00261 {
00262 kdError()<<k_funcinfo<<"Unknow relation type"<<endl;
00263 return;
00264 }
00265 childItem->move(this, chRow, chCol);
00266 }
00267
00268 QSize PertCanvas::canvasSize()
00269 {
00270
00271 QSize s(0,0);
00272 QCanvasItemList list = canvas()->allItems();
00273 QCanvasItemList::Iterator it = list.begin();
00274 for (; it != list.end(); ++it)
00275 {
00276 QRect r = (*it)->boundingRect();
00277 s.setWidth(QMAX(s.width(), r.right()));
00278 s.setHeight(QMAX(s.height(), r.bottom()));
00279 }
00280 s.setWidth(s.width()+20);
00281 s.setHeight(s.height()+20);
00282 return s;
00283 }
00284
00285 void PertCanvas::clear()
00286 {
00287 m_nodes.clear();
00288 m_relations.clear();
00289 m_rows.clear();
00290 QCanvasItemList list = canvas()->allItems();
00291 QCanvasItemList::Iterator it = list.begin();
00292 for (; it != list.end(); ++it)
00293 {
00294 if ( *it )
00295 delete *it;
00296 }
00297 }
00298
00299 void PertCanvas::contentsMousePressEvent ( QMouseEvent * e )
00300 {
00301
00302 switch (e->button())
00303 {
00304 case QEvent::LeftButton:
00305 {
00306 break;
00307 }
00308 case QEvent::RightButton:
00309 {
00310 PertNodeItem *item = selectedItem();
00311 if (item)
00312 item->setSelected(false);
00313 canvas()->update();
00314
00315 QCanvasItemList l = canvas()->collisions(e->pos());
00316 for (QCanvasItemList::Iterator it=l.begin(); it!=l.end(); ++it)
00317 {
00318 if ( (*it)->rtti() == PertProjectItem::RTTI ||
00319 (*it)->rtti() == PertTaskItem::RTTI ||
00320 (*it)->rtti() == PertMilestoneItem::RTTI )
00321 {
00322 PertNodeItem *item = (PertNodeItem *)(*it);
00323 {
00324 item->setSelected(true);
00325 canvas()->update();
00326 emit rightButtonPressed(&(item->node()), e->globalPos());
00327 if (item == selectedItem()) {
00328
00329 item->setSelected(false);
00330 }
00331 canvas()->update();
00332 break;
00333 }
00334 }
00335 }
00336 break;
00337 }
00338 case QEvent::MidButton:
00339 break;
00340 default:
00341 break;
00342 }
00343 }
00344
00345 void PertCanvas::contentsMouseReleaseEvent ( QMouseEvent * e )
00346 {
00347
00348 switch (e->button())
00349 {
00350 case QEvent::LeftButton:
00351 {
00352 bool hit = false;
00353 QCanvasItemList l = canvas()->collisions(e->pos());
00354 for (QCanvasItemList::Iterator it=l.begin(); it!=l.end(); ++it)
00355 {
00356 if ( (*it)->rtti() == PertProjectItem::RTTI ||
00357 (*it)->rtti() == PertTaskItem::RTTI ||
00358 (*it)->rtti() == PertMilestoneItem::RTTI )
00359 {
00360 hit = true;
00361 PertNodeItem *item = (PertNodeItem *)(*it);
00362 PertNodeItem *par = selectedItem();
00363 if ( !par)
00364 {
00365
00366 item->setSelected(true);
00367 canvas()->update();
00368 return;
00369 }
00370 par->setSelected(false);
00371 if (&(item->node()) == &(par->node()))
00372 {
00373 break;
00374 }
00375
00376
00377 if (!par->node().legalToLink(&(item->node()))) {
00378 KMessageBox::sorry(this, i18n("Cannot link these nodes"));
00379 } else {
00380 Relation *rel = item->node().findRelation(&(par->node()));
00381 if (rel)
00382 emit modifyRelation(rel);
00383 else
00384 emit addRelation(&(par->node()), &(item->node()));
00385 }
00386 break;
00387 }
00388 }
00389 if (!hit) {
00390 PertNodeItem *i = selectedItem();
00391 if (i) i->setSelected(false);
00392 }
00393 canvas()->update();
00394 break;
00395 }
00396 case QEvent::RightButton:
00397 {
00398 break;
00399 }
00400 case QEvent::MidButton:
00401 break;
00402 default:
00403 break;
00404 }
00405 }
00406
00407 PertNodeItem *PertCanvas::selectedItem()
00408 {
00409 QCanvasItemList list = canvas()->allItems();
00410 QCanvasItemList::Iterator it = list.begin();
00411 for (; it != list.end(); ++it)
00412 {
00413 if ( (*it)->isSelected() )
00414 {
00415 if ( (*it)->rtti() == PertProjectItem::RTTI ||
00416 (*it)->rtti() == PertTaskItem::RTTI ||
00417 (*it)->rtti() == PertMilestoneItem::RTTI )
00418 return (PertNodeItem *)(*it);
00419 }
00420 }
00421 return 0;
00422 }
00423
00424 Node *PertCanvas::selectedNode() {
00425 return selectedItem() ? &(selectedItem()->node()) : 0;
00426 }
00427
00428 #ifndef NDEBUG
00429 void PertCanvas::printDebug( int )
00430 {
00431 }
00432 #endif
00433
00434 }
00435
00436 #include "kptpertcanvas.moc"
|