00001
00002
00003
00004
00005
00006
00007
00008
00009 #include "KGanttItem.h"
00010
00011
00012 QBrush KGanttItem::_selectBrush(QColor(255,0,0));
00013
00014
00015 KGanttItem::KGanttItem(KGanttItem* parentItem, const QString& text,
00016 const QDateTime& start, const QDateTime& end)
00017 : QObject()
00019 {
00020 init(parentItem,text, start,end);
00021 }
00022
00023
00024
00025 KGanttItem::KGanttItem(KGanttItem* parentItem, const QString& text,
00026 const QDateTime& start, long durationMin)
00027 : QObject()
00029 {
00030 init(parentItem, text, start, start.addSecs( durationMin * 60));
00031 }
00032
00033
00034
00035 void
00036 KGanttItem::init(KGanttItem* parentItem, const QString& text,
00037 const QDateTime& start, const QDateTime& end)
00039 {
00040 _style = DrawAll - DrawHandle;
00041 _open = true;
00042 _selected = false;
00043 _editable = true;
00044
00045 _mode = Normal;
00046
00047 _brush = QBrush(QColor(140,140,255));
00048 _pen = QPen(QColor(100,100,100));
00049 _textPen = QPen(QColor(black));
00050
00051 _height = 24;
00052
00053 _text = text;
00054
00055 _start = start; _minDateTime = start;
00056 _end = end; _maxDateTime = end;
00057
00058 _parentItem = parentItem;
00059
00060 if(_parentItem)
00061 _parentItem->registerItem(this);
00062
00063 }
00064
00065
00066
00067 KGanttItem::~KGanttItem()
00069 {
00070 #ifdef _DEBUG_
00071 printf("-> delete %s \n", getText().latin1() );
00072 #endif
00073
00074 if(_parentItem)
00075 _parentItem->unregisterItem(this);
00076
00077 _subitems.setAutoDelete(true);
00078 _subitems.clear();
00079
00080 emit destroyed(this);
00081
00082 #ifdef _DEBUG_
00083 printf("<- delete %s \n", getText().latin1() );
00084 #endif
00085 }
00086
00087
00088
00089 KGanttRelation*
00090 KGanttItem::addRelation(KGanttItem* from, KGanttItem* to,
00091 const QString& text)
00092 {
00093 if(_subitems.containsRef(from) > 0 && _subitems.containsRef(to) >0) {
00094 KGanttRelation* rel = new KGanttRelation(from,to,text);
00095 _relations.append(rel);
00096
00097 connect(rel, SIGNAL(destroyed(KGanttRelation*)),
00098 this, SLOT(removeRelation(KGanttRelation*)));
00099
00100 emit changed(this, RelationAdded);
00101 return rel;
00102 }
00103 else
00104 return NULL;
00105 }
00106
00107
00108
00109 void
00110 KGanttItem::removeRelation(KGanttRelation* rel)
00111 {
00112 if( _relations.removeRef(rel) )
00113 emit changed(this, RelationRemoved);
00114 }
00115
00116
00117
00118 void
00119 KGanttItem::endTransaction()
00121 {
00122 blockSignals(false);
00123 emit changed(this, Unknown);
00124 }
00125
00126
00127
00128 void
00129 KGanttItem::registerItem(KGanttItem* item)
00130 {
00131 _subitems.append(item);
00132
00133 connect(item, SIGNAL(changed(KGanttItem*, KGanttItem::Change)),
00134 this, SLOT(subItemChanged(KGanttItem*, KGanttItem::Change)) );
00135
00136 bool minChanged = false;
00137 bool maxChanged = false;
00138
00139
00140
00141 if(_subitems.count() == 1) {
00142
00143 _minDateTime = item->getStart();
00144 _maxDateTime = item->getEnd();
00145
00146 minChanged = true;
00147 maxChanged = true;
00148
00149 }
00150 else {
00151
00152 if(item->getEnd() > _maxDateTime) {
00153 _maxDateTime = item->getEnd();
00154 maxChanged = true;
00155 }
00156
00157 if(_minDateTime > item->getStart()) {
00158 _minDateTime = item->getStart();
00159 minChanged = true;
00160 }
00161
00162 }
00163
00164
00165
00166 Change change = adjustStartEnd();
00167
00168 if(_mode == Rubberband) {
00169 if(minChanged && !(change & StartChanged))
00170 change = (Change) (change + StartChanged);
00171 if(maxChanged && !(change & EndChanged))
00172 change = (Change) (change + EndChanged);
00173 }
00174
00175 if( isOpen() ) {
00176 if(!(change & TotalHeightChanged))
00177 change = (Change) (change + TotalHeightChanged);
00178 }
00179
00180 if(change != NoChange)
00181 emit changed(this,change);
00182
00183 }
00184
00185
00186
00187 void
00188 KGanttItem::unregisterItem(KGanttItem* item)
00189 {
00190 _subitems.removeRef(item);
00191 disconnect(item);
00192
00193 Change change = adjustMinMax();
00194
00195 if( isOpen() ) {
00196 if(!(change & TotalHeightChanged))
00197 change = (Change) (change + TotalHeightChanged);
00198 }
00199
00200 if(change != NoChange)
00201 emit changed(this,change);
00202
00203 }
00204
00205
00206
00207 QDateTime
00208 KGanttItem::getStart()
00209 {
00210 if(_mode == Rubberband && _subitems.count()>0)
00211 return _minDateTime;
00212 else
00213 return _start;
00214 }
00215
00216
00217
00218
00219 QDateTime
00220 KGanttItem::getEnd()
00222 {
00223 if(_mode == Rubberband && _subitems.count()>0)
00224 return _maxDateTime;
00225 else
00226 return _end;
00227 }
00228
00229
00230
00231 void
00232 KGanttItem::setStart(const QDateTime& start)
00233 {
00234 if(!_editable) return;
00235
00236
00237 if(_subitems.count()==0) {
00238
00239 if(_start != start) {
00240 _start = start;
00241 _minDateTime = _start;
00242 emit changed(this,StartChanged);
00243 }
00244
00245 }
00246 else {
00247
00248
00249
00250
00251 if(_mode != Rubberband) {
00252
00253 if(start < _minDateTime)
00254 _start = start;
00255 else
00256 _start = _minDateTime;
00257
00258 emit changed(this,StartChanged);
00259
00260 }
00261
00262 }
00263
00264 }
00265
00266
00267
00268 void
00269 KGanttItem::setEnd(const QDateTime& end)
00270 {
00271 if(!_editable) return;
00272
00273
00274 if(_subitems.count()==0) {
00275
00276 if(_end != end) {
00277 _end = end;
00278 _maxDateTime = _end;
00279 emit changed(this,EndChanged);
00280 }
00281
00282 }
00283 else {
00284
00285
00286
00287
00288 if(_mode != Rubberband) {
00289
00290 if(end > _maxDateTime)
00291 _end = end;
00292 else
00293 _end = _maxDateTime;
00294
00295 emit changed(this,EndChanged);
00296
00297 }
00298
00299 }
00300
00301 }
00302
00303
00304
00305
00306 KGanttItem::Change
00307 KGanttItem::adjustStartEnd()
00309 {
00310
00311
00312 Change c = adjustMinMax();
00313
00314 if(_start > _minDateTime) {
00315 _start = _minDateTime;
00316 if(!(c & StartChanged))
00317 c = (Change) (c + StartChanged);
00318 }
00319
00320 if(_end < _maxDateTime) {
00321 _end = _maxDateTime;
00322 if(!(c & EndChanged))
00323 c = (Change) (c + EndChanged);
00324 }
00325
00326 return c;
00327
00328 }
00329
00330
00331
00332 KGanttItem::Change
00333 KGanttItem::adjustMinMax()
00335 {
00336
00337
00338
00339
00340
00341
00342 QDateTime min = _minDateTime;
00343 QDateTime max = _maxDateTime;
00344 Change c = NoChange;
00345
00346 if(_subitems.count()==0) {
00347
00348 _minDateTime = _start;
00349 _maxDateTime = _end;
00350
00351 if(min != _minDateTime) c = MinChanged;
00352 if(max != _maxDateTime) c = (Change) (c + MaxChanged);
00353
00354 }
00355 else {
00356
00357
00358
00359 KGanttItem* item = _subitems.first();
00360
00361 _minDateTime = item->getStart();
00362 _maxDateTime = item->getEnd();
00363
00364 item = _subitems.next();
00365
00366 for(; item != 0; item = _subitems.next() ) {
00367
00368 if(_minDateTime > item->getStart()) {
00369 _minDateTime = item->getStart();
00370 }
00371
00372 if(item->getEnd() > _maxDateTime) {
00373 _maxDateTime = item->getEnd();
00374 }
00375
00376 }
00377
00378
00379 if(min != _minDateTime) c = MinChanged;
00380 if(max != _maxDateTime) c = (Change) (c + MaxChanged);
00381
00382 }
00383
00384 return c;
00385
00386 }
00387
00388
00389
00390 void
00391 KGanttItem::subItemChanged(KGanttItem* item, Change change)
00393 {
00394 if(change & StyleChanged)
00395 emit changed(this, change);
00396
00397 if( (change & Opened) || (change & Closed) ||
00398 (change & TotalHeightChanged) || (change & HeightChanged) )
00399 emit changed(this, TotalHeightChanged);
00400
00401 if( (change & StartChanged) ||
00402 (change & EndChanged) ) {
00403
00404 Change c = adjustStartEnd();
00405
00406 if(_mode == Rubberband) {
00407 if(c & MinChanged && !(c & StartChanged))
00408 c = (Change) (c + StartChanged);
00409 if(c & MaxChanged && !(c & EndChanged))
00410 c = (Change) ( c +EndChanged);
00411 }
00412
00413 if(c != NoChange)
00414 emit changed(this, c);
00415
00416 }
00417 }
00418
00419
00420
00421 void
00422 KGanttItem::setText(const QString& text)
00424 {
00425 if(!_editable) return;
00426 if(text != _text) {
00427 _text = text;
00428 emit changed(this,TextChanged);
00429 }
00430 }
00431
00432
00433
00434 void
00435 KGanttItem::open(bool f)
00437 {
00438 if(f != _open) {
00439 _open = f;
00440 if(_open)
00441 emit changed(this, Opened);
00442 else
00443 emit changed(this, Closed);
00444 }
00445 }
00446
00447
00448
00449 void
00450 KGanttItem::select(bool f)
00452 {
00453 if(!_editable) return;
00454 if(f != _selected) {
00455 _selected = f;
00456 if(_selected)
00457 emit changed(this, Selected);
00458 else
00459 emit changed(this, Unselected);
00460 }
00461 }
00462
00463
00464
00465 void
00466 KGanttItem::setMode(Mode flag)
00468 {
00469 if(!_editable) return;
00470 if(_mode != flag) {
00471 _mode = flag;
00472 emit changed(this,ModeChanged);
00473 }
00474
00475 }
00476
00477
00478
00479 void
00480 KGanttItem::setStyle(int flag, bool includeSubItems)
00482 {
00483 if(!_editable) return;
00484 if(_style != flag) {
00485
00486 _style = flag;
00487
00488 if(includeSubItems)
00489 for(KGanttItem* item = _subitems.first();
00490 item != 0;
00491 item = _subitems.next() )
00492 item->setStyle(flag,true);
00493
00494 emit changed(this,StyleChanged);
00495
00496 }
00497
00498 }
00499
00500
00501
00502 void
00503 KGanttItem::setBrush(const QBrush& brush)
00505 {
00506 _brush = brush;
00507 }
00508
00509
00510
00511 void
00512 KGanttItem::setPen(const QPen& pen)
00514 {
00515 _pen = pen;
00516 }
00517
00518
00519
00520 void
00521 KGanttItem::setHeight(int h)
00523 {
00524 if(!_editable) return;
00525 if(_height != h) {
00526 _height = h;
00527 emit changed(this,HeightChanged);
00528 }
00529 }
00530
00531
00532
00533 int
00534 KGanttItem::getTotalHeight()
00536 {
00537 int h = _height;
00538
00539 if( isOpen() ) {
00540 for(KGanttItem* item = _subitems.first(); item != 0; item = _subitems.next() ) {
00541 h += item->getTotalHeight();
00542 }
00543 }
00544 return h;
00545 }
00546
00547
00548
00549 int
00550 KGanttItem::getWidth()
00552 {
00553
00554
00555 int width = getStart().secsTo(getEnd())/60;
00556
00557
00558
00559 return width;
00560 }
00561
00562
00563
00564 void
00565 KGanttItem::dump(QTextOStream& cout, const QString& pre)
00567 {
00568 cout << pre << "<Item. text = [" << _text << "]>\n";
00569 cout << pre << "| start : " << getStart().toString() << " ("
00570 <<_start.toString() << ")" << endl;
00571 cout << pre << "| end : " << getEnd().toString() << " ("
00572 <<_end.toString() << ")" << endl;
00573 if(_editable)
00574 cout << pre << "| - editable " << endl;
00575 else
00576 cout << pre << "| - not editable " << endl;
00577 if(_mode == Rubberband)
00578 cout << pre << "| mode = 'rubberband'" << endl;
00579 else
00580 cout << pre << "| mode = 'normal'" << endl;
00581
00582 cout << pre << "| min date/time : " << _minDateTime.toString() << endl;
00583 cout << pre << "| max date/time : " << _maxDateTime.toString() << endl;
00584
00585 for(KGanttItem* item = _subitems.first(); item != 0; item = _subitems.next() )
00586 item->dump(cout, pre + "| ");
00587
00588 for(KGanttRelation* rel = _relations.first();
00589 rel != 0;
00590 rel = _relations.next() )
00591 rel->dump(cout, pre + "| ");
00592
00593 cout << pre << "</Item>\n";
00594
00595 }
00596
00597
00598 QString
00599 KGanttItem::ChangeAsString(Change c)
00601 {
00602 QString ret;
00603
00604 if(c & StartChanged) ret += "StartChanged, ";
00605 if(c & EndChanged) ret += "EndChanged, ";
00606 if(c & HeightChanged) ret += "HeightChanged, ";
00607 if(c & TotalHeightChanged) ret += "TotalHeightChanged, ";
00608 if(c & StyleChanged) ret += "StyleChanged, ";
00609 if(c & TextChanged) ret += "TextChanged, ";
00610 if(c & ModeChanged) ret += "ModeChanged, ";
00611 if(c & MinChanged) ret += "MinChanged, ";
00612 if(c & MaxChanged) ret += "MaxChanged, ";
00613 if(c & Opened) ret += "Opened, ";
00614 if(c & Closed) ret += "Closed, ";
00615 if(c & Selected) ret += "Selected, ";
00616 if(c & Unselected) ret += "Unselected, ";
00617 if(c & Unknown) ret += "Unknown, ";
00618 return ret;
00619
00620 }
00621 #include "KGanttItem.moc"