00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include <qtooltip.h>
00027 #include <qdragobject.h>
00028 #include <qpainter.h>
00029
00030 #include <kiconloader.h>
00031 #include <kdebug.h>
00032 #include <klocale.h>
00033 #include <kwordwrap.h>
00034
00035 #include <libkcal/icaldrag.h>
00036 #include <libkcal/vcaldrag.h>
00037 #include <libkdepim/kvcarddrag.h>
00038 #ifndef KORG_NOKABC
00039 #include <kabc/addressee.h>
00040 #include <kabc/vcardconverter.h>
00041 #endif
00042
00043 #include "koprefs.h"
00044 #include "koglobals.h"
00045
00046 #include "koincidencetooltip.h"
00047 #include "koagendaitem.h"
00048 #include "koagendaitem.moc"
00049
00050
00051
00052 QToolTipGroup *KOAgendaItem::mToolTipGroup = 0;
00053
00054 QPixmap *KOAgendaItem::alarmPxmp = 0;
00055 QPixmap *KOAgendaItem::recurPxmp = 0;
00056 QPixmap *KOAgendaItem::readonlyPxmp = 0;
00057 QPixmap *KOAgendaItem::replyPxmp = 0;
00058 QPixmap *KOAgendaItem::groupPxmp = 0;
00059 QPixmap *KOAgendaItem::groupPxmpTentative = 0;
00060 QPixmap *KOAgendaItem::organizerPxmp = 0;
00061
00062
00063
00064 KOAgendaItem::KOAgendaItem( Incidence *incidence, const QDate &qd, QWidget *parent,
00065 const char *name, WFlags f ) :
00066 QWidget( parent, name, f ), mIncidence( incidence ), mDate( qd ),
00067 mLabelText( mIncidence->summary() ), mIconAlarm( false ),
00068 mIconRecur( false ), mIconReadonly( false ), mIconReply( false ),
00069 mIconGroup( false ), mIconGroupTentative( false ), mIconOrganizer( false ),
00070 mMultiItemInfo( 0 ), mStartMoveInfo( 0 )
00071 {
00072 setBackgroundMode( Qt::NoBackground );
00073
00074 setCellXY( 0, 0, 1 );
00075 setCellXRight( 0 );
00076 setMouseTracking( true );
00077 mResourceColor = QColor();
00078 updateIcons();
00079
00080
00081 mSelected = true;
00082 select( false );
00083
00084 KOIncidenceToolTip::add( this, incidence, toolTipGroup() );
00085 setAcceptDrops( true );
00086 }
00087
00088 void KOAgendaItem::updateIcons()
00089 {
00090 if ( !mIncidence ) return;
00091 mIconReadonly = mIncidence->isReadOnly();
00092 mIconRecur = mIncidence->doesRecur();
00093 mIconAlarm = mIncidence->isAlarmEnabled();
00094 if ( mIncidence->attendeeCount() > 0 ) {
00095 if ( KOPrefs::instance()->thatIsMe( mIncidence->organizer().email() ) ) {
00096 mIconReply = false;
00097 mIconGroup = false;
00098 mIconGroupTentative = false;
00099 mIconOrganizer = true;
00100 } else {
00101 Attendee *me = mIncidence->attendeeByMails( KOPrefs::instance()->allEmails() );
00102 if ( me ) {
00103 if ( me->status() == Attendee::NeedsAction && me->RSVP() ) {
00104 mIconReply = true;
00105 mIconGroup = false;
00106 mIconGroupTentative = false;
00107 mIconOrganizer = false;
00108 } else if ( me->status() == Attendee::Tentative ) {
00109 mIconReply = false;
00110 mIconGroup = false;
00111 mIconGroupTentative = true;
00112 mIconOrganizer = false;
00113 } else {
00114 mIconReply = false;
00115 mIconGroup = true;
00116 mIconGroupTentative = false;
00117 mIconOrganizer = false;
00118 }
00119 } else {
00120 mIconReply = false;
00121 mIconGroup = true;
00122 mIconGroupTentative = false;
00123 mIconOrganizer = false;
00124 }
00125 }
00126 }
00127 update();
00128 }
00129
00130
00131 void KOAgendaItem::select( bool selected )
00132 {
00133 if ( mSelected == selected ) return;
00134 mSelected = selected;
00135
00136 update();
00137 }
00138
00139 bool KOAgendaItem::dissociateFromMultiItem()
00140 {
00141 if ( !isMultiItem() ) return false;
00142 KOAgendaItem *firstItem = firstMultiItem();
00143 if ( firstItem == this ) firstItem = nextMultiItem();
00144 KOAgendaItem *lastItem = lastMultiItem();
00145 if ( lastItem == this ) lastItem = prevMultiItem();
00146
00147 KOAgendaItem *prevItem = prevMultiItem();
00148 KOAgendaItem *nextItem = nextMultiItem();
00149
00150 if ( prevItem ) {
00151 prevItem->setMultiItem( firstItem,
00152 prevItem->prevMultiItem(),
00153 nextItem, lastItem );
00154 }
00155 if ( nextItem ) {
00156 nextItem->setMultiItem( firstItem, prevItem,
00157 nextItem->prevMultiItem(),
00158 lastItem );
00159 }
00160 delete mMultiItemInfo;
00161 return true;
00162 }
00163
00164 bool KOAgendaItem::setIncidence( Incidence *i )
00165 {
00166 mIncidence = i;
00167 updateIcons();
00168 return true;
00169 }
00170
00171
00172
00173
00174
00175 int KOAgendaItem::cellHeight() const
00176 {
00177 return mCellYBottom - mCellYTop + 1;
00178 }
00179
00180
00181
00182
00183 int KOAgendaItem::cellWidth() const
00184 {
00185 return mCellXRight - mCellXLeft + 1;
00186 }
00187
00188 void KOAgendaItem::setItemDate( const QDate &qd )
00189 {
00190 mDate = qd;
00191 }
00192
00193 void KOAgendaItem::setCellXY( int X, int YTop, int YBottom )
00194 {
00195 mCellXLeft = X;
00196 mCellYTop = YTop;
00197 mCellYBottom = YBottom;
00198 }
00199
00200 void KOAgendaItem::setCellXRight( int xright )
00201 {
00202 mCellXRight = xright;
00203 }
00204
00205 void KOAgendaItem::setCellX( int XLeft, int XRight )
00206 {
00207 mCellXLeft = XLeft;
00208 mCellXRight = XRight;
00209 }
00210
00211 void KOAgendaItem::setCellY( int YTop, int YBottom )
00212 {
00213 mCellYTop = YTop;
00214 mCellYBottom = YBottom;
00215 }
00216
00217 void KOAgendaItem::setMultiItem(KOAgendaItem *first, KOAgendaItem *prev,
00218 KOAgendaItem *next, KOAgendaItem *last)
00219 {
00220 if (!mMultiItemInfo) mMultiItemInfo=new MultiItemInfo;
00221 mMultiItemInfo->mFirstMultiItem = first;
00222 mMultiItemInfo->mPrevMultiItem = prev;
00223 mMultiItemInfo->mNextMultiItem = next;
00224 mMultiItemInfo->mLastMultiItem = last;
00225 }
00226 bool KOAgendaItem::isMultiItem()
00227 {
00228 return mMultiItemInfo;
00229 }
00230 KOAgendaItem* KOAgendaItem::prependMoveItem(KOAgendaItem* e)
00231 {
00232 if (!e) return e;
00233
00234 KOAgendaItem*first=0, *last=0;
00235 if (isMultiItem()) {
00236 first=mMultiItemInfo->mFirstMultiItem;
00237 last=mMultiItemInfo->mLastMultiItem;
00238 }
00239 if (!first) first=this;
00240 if (!last) last=this;
00241
00242 e->setMultiItem(0, 0, first, last);
00243 first->setMultiItem(e, e, first->nextMultiItem(), first->lastMultiItem() );
00244
00245 KOAgendaItem*tmp=first->nextMultiItem();
00246 while (tmp) {
00247 tmp->setMultiItem( e, tmp->prevMultiItem(), tmp->nextMultiItem(), tmp->lastMultiItem() );
00248 tmp = tmp->nextMultiItem();
00249 }
00250
00251 if ( mStartMoveInfo && !e->moveInfo() ) {
00252 e->mStartMoveInfo=new MultiItemInfo( *mStartMoveInfo );
00253
00254
00255 e->moveInfo()->mPrevMultiItem = 0;
00256 e->moveInfo()->mNextMultiItem = first;
00257 }
00258
00259 if (first && first->moveInfo()) {
00260 first->moveInfo()->mPrevMultiItem = e;
00261 }
00262 return e;
00263 }
00264
00265 KOAgendaItem* KOAgendaItem::appendMoveItem(KOAgendaItem* e)
00266 {
00267 if (!e) return e;
00268
00269 KOAgendaItem*first=0, *last=0;
00270 if (isMultiItem()) {
00271 first=mMultiItemInfo->mFirstMultiItem;
00272 last=mMultiItemInfo->mLastMultiItem;
00273 }
00274 if (!first) first=this;
00275 if (!last) last=this;
00276
00277 e->setMultiItem( first, last, 0, 0 );
00278 KOAgendaItem*tmp=first;
00279
00280 while (tmp) {
00281 tmp->setMultiItem(tmp->firstMultiItem(), tmp->prevMultiItem(), tmp->nextMultiItem(), e);
00282 tmp = tmp->nextMultiItem();
00283 }
00284 last->setMultiItem( last->firstMultiItem(), last->prevMultiItem(), e, e);
00285
00286 if ( mStartMoveInfo && !e->moveInfo() ) {
00287 e->mStartMoveInfo=new MultiItemInfo( *mStartMoveInfo );
00288
00289
00290 e->moveInfo()->mPrevMultiItem = last;
00291 e->moveInfo()->mNextMultiItem = 0;
00292 }
00293 if (last && last->moveInfo()) {
00294 last->moveInfo()->mNextMultiItem = e;
00295 }
00296 return e;
00297 }
00298
00299 KOAgendaItem* KOAgendaItem::removeMoveItem(KOAgendaItem* e)
00300 {
00301 if (isMultiItem()) {
00302 KOAgendaItem *first = mMultiItemInfo->mFirstMultiItem;
00303 KOAgendaItem *next, *prev;
00304 KOAgendaItem *last = mMultiItemInfo->mLastMultiItem;
00305 if (!first) first = this;
00306 if (!last) last = this;
00307 if ( first==e ) {
00308 first = first->nextMultiItem();
00309 first->setMultiItem( 0, 0, first->nextMultiItem(), first->lastMultiItem() );
00310 }
00311 if ( last==e ) {
00312 last=last->prevMultiItem();
00313 last->setMultiItem( last->firstMultiItem(), last->prevMultiItem(), 0, 0 );
00314 }
00315
00316 KOAgendaItem *tmp = first;
00317 if ( first==last ) {
00318 delete mMultiItemInfo;
00319 tmp = 0;
00320 mMultiItemInfo = 0;
00321 }
00322 while ( tmp ) {
00323 next = tmp->nextMultiItem();
00324 prev = tmp->prevMultiItem();
00325 if ( e==next ) {
00326 next = next->nextMultiItem();
00327 }
00328 if ( e==prev ) {
00329 prev = prev->prevMultiItem();
00330 }
00331 tmp->setMultiItem((tmp==first)?0:first, (tmp==prev)?0:prev, (tmp==next)?0:next, (tmp==last)?0:last);
00332 tmp = tmp->nextMultiItem();
00333 }
00334 }
00335
00336 return e;
00337 }
00338
00339
00340 void KOAgendaItem::startMove()
00341 {
00342 KOAgendaItem* first = this;
00343 if ( isMultiItem() && mMultiItemInfo->mFirstMultiItem ) {
00344 first=mMultiItemInfo->mFirstMultiItem;
00345 }
00346 first->startMovePrivate();
00347 }
00348
00349 void KOAgendaItem::startMovePrivate()
00350 {
00351 mStartMoveInfo = new MultiItemInfo;
00352 mStartMoveInfo->mStartCellXLeft = mCellXLeft;
00353 mStartMoveInfo->mStartCellXRight = mCellXRight;
00354 mStartMoveInfo->mStartCellYTop = mCellYTop;
00355 mStartMoveInfo->mStartCellYBottom = mCellYBottom;
00356 if (mMultiItemInfo) {
00357 mStartMoveInfo->mFirstMultiItem = mMultiItemInfo->mFirstMultiItem;
00358 mStartMoveInfo->mLastMultiItem = mMultiItemInfo->mLastMultiItem;
00359 mStartMoveInfo->mPrevMultiItem = mMultiItemInfo->mPrevMultiItem;
00360 mStartMoveInfo->mNextMultiItem = mMultiItemInfo->mNextMultiItem;
00361 } else {
00362 mStartMoveInfo->mFirstMultiItem = 0;
00363 mStartMoveInfo->mLastMultiItem = 0;
00364 mStartMoveInfo->mPrevMultiItem = 0;
00365 mStartMoveInfo->mNextMultiItem = 0;
00366 }
00367 if ( isMultiItem() && mMultiItemInfo->mNextMultiItem )
00368 {
00369 mMultiItemInfo->mNextMultiItem->startMovePrivate();
00370 }
00371 }
00372
00373 void KOAgendaItem::resetMove()
00374 {
00375 if ( mStartMoveInfo ) {
00376 if ( mStartMoveInfo->mFirstMultiItem ) {
00377 mStartMoveInfo->mFirstMultiItem->resetMovePrivate();
00378 } else {
00379 resetMovePrivate();
00380 }
00381 }
00382 }
00383
00384 void KOAgendaItem::resetMovePrivate()
00385 {
00386 if (mStartMoveInfo) {
00387 mCellXLeft = mStartMoveInfo->mStartCellXLeft;
00388 mCellXRight = mStartMoveInfo->mStartCellXRight;
00389 mCellYTop = mStartMoveInfo->mStartCellYTop;
00390 mCellYBottom = mStartMoveInfo->mStartCellYBottom;
00391
00392
00393
00394
00395 if ( mMultiItemInfo ) {
00396
00397 mMultiItemInfo->mFirstMultiItem = mStartMoveInfo->mFirstMultiItem;
00398 mMultiItemInfo->mPrevMultiItem = mStartMoveInfo->mPrevMultiItem;
00399 mMultiItemInfo->mNextMultiItem = mStartMoveInfo->mNextMultiItem;
00400 mMultiItemInfo->mLastMultiItem = mStartMoveInfo->mLastMultiItem;
00401
00402 if ( !mStartMoveInfo->mFirstMultiItem ) {
00403
00404 KOAgendaItem*toDel=mStartMoveInfo->mPrevMultiItem;
00405 KOAgendaItem*nowDel=0L;
00406 while (toDel) {
00407 nowDel=toDel;
00408 if (nowDel->moveInfo()) {
00409 toDel=nowDel->moveInfo()->mPrevMultiItem;
00410 }
00411 emit removeAgendaItem( nowDel );
00412 }
00413 mMultiItemInfo->mFirstMultiItem = 0L;
00414 mMultiItemInfo->mPrevMultiItem = 0L;
00415 }
00416 if ( !mStartMoveInfo->mLastMultiItem ) {
00417
00418 KOAgendaItem*toDel=mStartMoveInfo->mNextMultiItem;
00419 KOAgendaItem*nowDel=0L;
00420 while (toDel) {
00421 nowDel=toDel;
00422 if (nowDel->moveInfo()) {
00423 toDel=nowDel->moveInfo()->mNextMultiItem;
00424 }
00425 emit removeAgendaItem( nowDel );
00426 }
00427 mMultiItemInfo->mLastMultiItem = 0L;
00428 mMultiItemInfo->mNextMultiItem = 0L;
00429 }
00430
00431 if ( mStartMoveInfo->mFirstMultiItem==0 && mStartMoveInfo->mLastMultiItem==0 ) {
00432
00433 delete mMultiItemInfo;
00434 mMultiItemInfo = 0;
00435 }
00436 }
00437 delete mStartMoveInfo;
00438 mStartMoveInfo = 0;
00439 }
00440 emit showAgendaItem( this );
00441 if ( nextMultiItem() ) {
00442 nextMultiItem()->resetMovePrivate();
00443 }
00444 }
00445
00446 void KOAgendaItem::endMove()
00447 {
00448 KOAgendaItem*first=firstMultiItem();
00449 if (!first) first=this;
00450 first->endMovePrivate();
00451 }
00452
00453 void KOAgendaItem::endMovePrivate()
00454 {
00455 if ( mStartMoveInfo ) {
00456
00457 if ( !firstMultiItem() || firstMultiItem()==this ) {
00458 KOAgendaItem*toDel=mStartMoveInfo->mPrevMultiItem;
00459 KOAgendaItem*nowDel = 0;
00460 while (toDel) {
00461 nowDel=toDel;
00462 if (nowDel->moveInfo()) {
00463 toDel=nowDel->moveInfo()->mPrevMultiItem;
00464 }
00465 emit removeAgendaItem( nowDel );
00466 }
00467 }
00468
00469 if ( !lastMultiItem() || lastMultiItem()==this ) {
00470 KOAgendaItem*toDel=mStartMoveInfo->mNextMultiItem;
00471 KOAgendaItem*nowDel = 0;
00472 while (toDel) {
00473 nowDel=toDel;
00474 if (nowDel->moveInfo()) {
00475 toDel=nowDel->moveInfo()->mNextMultiItem;
00476 }
00477 emit removeAgendaItem( nowDel );
00478 }
00479 }
00480
00481 delete mStartMoveInfo;
00482 mStartMoveInfo=0;
00483 if ( nextMultiItem() )
00484 nextMultiItem()->endMovePrivate();
00485 }
00486 }
00487
00488 void KOAgendaItem::moveRelative(int dx, int dy)
00489 {
00490 int newXLeft = cellXLeft() + dx;
00491 int newXRight = cellXRight() + dx;
00492 int newYTop = cellYTop() + dy;
00493 int newYBottom = cellYBottom() + dy;
00494 setCellXY(newXLeft,newYTop,newYBottom);
00495 setCellXRight(newXRight);
00496 }
00497
00498 void KOAgendaItem::expandTop(int dy)
00499 {
00500 int newYTop = cellYTop() + dy;
00501 int newYBottom = cellYBottom();
00502 if (newYTop > newYBottom) newYTop = newYBottom;
00503 setCellY(newYTop, newYBottom);
00504 }
00505
00506 void KOAgendaItem::expandBottom(int dy)
00507 {
00508 int newYTop = cellYTop();
00509 int newYBottom = cellYBottom() + dy;
00510 if (newYBottom < newYTop) newYBottom = newYTop;
00511 setCellY(newYTop, newYBottom);
00512 }
00513
00514 void KOAgendaItem::expandLeft(int dx)
00515 {
00516 int newXLeft = cellXLeft() + dx;
00517 int newXRight = cellXRight();
00518 if ( newXLeft > newXRight ) newXLeft = newXRight;
00519 setCellX( newXLeft, newXRight );
00520 }
00521
00522 void KOAgendaItem::expandRight(int dx)
00523 {
00524 int newXLeft = cellXLeft();
00525 int newXRight = cellXRight() + dx;
00526 if ( newXRight < newXLeft ) newXRight = newXLeft;
00527 setCellX( newXLeft, newXRight );
00528 }
00529
00530 QToolTipGroup *KOAgendaItem::toolTipGroup()
00531 {
00532 if (!mToolTipGroup) mToolTipGroup = new QToolTipGroup(0);
00533 return mToolTipGroup;
00534 }
00535
00536 void KOAgendaItem::dragEnterEvent( QDragEnterEvent *e )
00537 {
00538 #ifndef KORG_NODND
00539 if ( ICalDrag::canDecode( e ) || VCalDrag::canDecode( e ) ) {
00540 e->ignore();
00541 return;
00542 }
00543 if ( KVCardDrag::canDecode( e ) || QTextDrag::canDecode( e ) )
00544 e->accept();
00545 else
00546 e->ignore();
00547 #endif
00548 }
00549
00550 void KOAgendaItem::addAttendee( const QString &newAttendee )
00551 {
00552 kdDebug(5850) << " Email: " << newAttendee << endl;
00553
00554 int pos = newAttendee.find("<");
00555 QString name = newAttendee.left(pos);
00556 QString email = newAttendee.mid(pos);
00557 if (!email.isEmpty()) {
00558 mIncidence->addAttendee(new Attendee(name,email));
00559 } else if (name.contains("@")) {
00560 mIncidence->addAttendee(new Attendee(name,name));
00561 } else {
00562 mIncidence->addAttendee(new Attendee(name,QString::null));
00563 }
00564 }
00565
00566 void KOAgendaItem::dropEvent( QDropEvent *e )
00567 {
00568 #ifndef KORG_NODND
00569 QString text;
00570
00571 bool decoded = QTextDrag::decode( e, text );
00572 if( decoded && text.startsWith( "file:" ) ) {
00573 mIncidence->addAttachment( new Attachment( text ) );
00574 return;
00575 }
00576
00577 #ifndef KORG_NOKABC
00578 QString vcards;
00579 KABC::VCardConverter converter;
00580
00581 KVCardDrag::decode( e, vcards );
00582 KABC::Addressee::List list = converter.parseVCards( vcards );
00583 KABC::Addressee::List::Iterator it;
00584 for ( it = list.begin(); it != list.end(); ++it ) {
00585 QString em( (*it).fullEmail() );
00586 if (em.isEmpty()) {
00587 em=(*it).realName();
00588 }
00589 addAttendee( em );
00590 }
00591 #else
00592 if( decoded ) {
00593 kdDebug(5850) << "Dropped : " << text << endl;
00594
00595 QStringList emails = QStringList::split( ",", text );
00596 for( QStringList::ConstIterator it = emails.begin(); it != emails.end();
00597 ++it ) {
00598 addAttendee( *it );
00599 }
00600 }
00601 #endif // KORG_NOKABC
00602
00603 #endif // KORG_NODND
00604 }
00605
00606
00607 QPtrList<KOAgendaItem> KOAgendaItem::conflictItems()
00608 {
00609 return mConflictItems;
00610 }
00611
00612 void KOAgendaItem::setConflictItems( QPtrList<KOAgendaItem> ci )
00613 {
00614 mConflictItems = ci;
00615 KOAgendaItem *item;
00616 for ( item = mConflictItems.first(); item != 0;
00617 item = mConflictItems.next() ) {
00618 item->addConflictItem( this );
00619 }
00620 }
00621
00622 void KOAgendaItem::addConflictItem( KOAgendaItem *ci )
00623 {
00624 if ( mConflictItems.find( ci ) < 0 ) mConflictItems.append( ci );
00625 }
00626
00627 QString KOAgendaItem::label() const
00628 {
00629 return mLabelText;
00630 }
00631
00632 bool KOAgendaItem::overlaps( KOrg::CellItem *o ) const
00633 {
00634 KOAgendaItem *other = static_cast<KOAgendaItem *>( o );
00635
00636 if ( cellXLeft() <= other->cellXRight() &&
00637 cellXRight() >= other->cellXLeft() ) {
00638 if ( ( cellYTop() <= other->cellYBottom() ) &&
00639 ( cellYBottom() >= other->cellYTop() ) ) {
00640 return true;
00641 }
00642 }
00643
00644 return false;
00645 }
00646
00647 void KOAgendaItem::paintFrame( QPainter *p, const QColor &color )
00648 {
00649 QColor oldpen(p->pen().color());
00650 p->setPen( color );
00651 p->drawRect( 0, 0, width(), height() );
00652 p->drawRect( 1, 1, width() - 2, height() - 2 );
00653 p->setPen( oldpen );
00654 }
00655
00656 static void conditionalPaint( QPainter *p, bool cond, int &x, int ft,
00657 const QPixmap &pxmp )
00658 {
00659 if ( !cond ) return;
00660
00661 p->drawPixmap( x, ft, pxmp );
00662 x += pxmp.width() + ft;
00663 }
00664
00665 void KOAgendaItem::paintEventIcon( QPainter *p, int &x, int ft )
00666 {
00667 if ( !mIncidence ) return;
00668 static const QPixmap eventPxmp =
00669 KOGlobals::self()->smallIcon( "appointment" );
00670 if ( mIncidence->type() != "Event" )
00671 return;
00672 conditionalPaint( p, true, x, ft, eventPxmp );
00673 }
00674
00675 void KOAgendaItem::paintTodoIcon( QPainter *p, int &x, int ft )
00676 {
00677 if ( !mIncidence ) return;
00678 static const QPixmap todoPxmp =
00679 KOGlobals::self()->smallIcon( "todo" );
00680 static const QPixmap completedPxmp =
00681 KOGlobals::self()->smallIcon( "checkedbox" );
00682 if ( mIncidence->type() != "Todo" )
00683 return;
00684 bool b = ( static_cast<Todo *>( mIncidence ) )->isCompleted();
00685 conditionalPaint( p, !b, x, ft, todoPxmp );
00686 conditionalPaint( p, b, x, ft, completedPxmp );
00687 }
00688
00689 void KOAgendaItem::paintIcons( QPainter *p, int &x, int ft )
00690 {
00691 paintEventIcon( p, x, ft );
00692 paintTodoIcon( p, x, ft );
00693 conditionalPaint( p, mIconAlarm, x, ft, *alarmPxmp );
00694 conditionalPaint( p, mIconRecur, x, ft, *recurPxmp );
00695 conditionalPaint( p, mIconReadonly, x, ft, *readonlyPxmp );
00696 conditionalPaint( p, mIconReply, x, ft, *replyPxmp );
00697 conditionalPaint( p, mIconGroup, x, ft, *groupPxmp );
00698 conditionalPaint( p, mIconGroupTentative, x, ft, *groupPxmpTentative );
00699 conditionalPaint( p, mIconOrganizer, x, ft, *organizerPxmp );
00700 }
00701
00702 void KOAgendaItem::paintEvent( QPaintEvent * )
00703 {
00704
00705
00706
00707
00708
00709
00710 if ( !mIncidence )return;
00711
00712 QPainter p( this );
00713 const int ft = 2;
00714 const int margin = 1 + ft;
00715
00716
00717
00718
00719
00720
00721 if ( !alarmPxmp ) {
00722 alarmPxmp = new QPixmap( KOGlobals::self()->smallIcon("bell") );
00723 recurPxmp = new QPixmap( KOGlobals::self()->smallIcon("recur") );
00724 readonlyPxmp = new QPixmap( KOGlobals::self()->smallIcon("readonlyevent") );
00725 replyPxmp = new QPixmap( KOGlobals::self()->smallIcon("mail_reply") );
00726 groupPxmp = new QPixmap( KOGlobals::self()->smallIcon("groupevent") );
00727 groupPxmpTentative = new QPixmap( KOGlobals::self()->smallIcon("groupeventtentative") );
00728 organizerPxmp = new QPixmap( KOGlobals::self()->smallIcon("organizer") );
00729 }
00730
00731 QColor bgColor;
00732 if ( mIncidence->type() == "Todo" ) {
00733 if ( static_cast<Todo*>(mIncidence)->isOverdue() )
00734 bgColor = KOPrefs::instance()->todoOverdueColor();
00735 else if ( static_cast<Todo*>(mIncidence)->dtDue().date() ==
00736 QDateTime::currentDateTime().date() )
00737 bgColor = KOPrefs::instance()->todoDueTodayColor();
00738 }
00739
00740 if ( !bgColor.isValid() ) {
00741 QStringList categories = mIncidence->categories();
00742 QString cat = categories.first();
00743 if (cat.isEmpty())
00744 bgColor = KOPrefs::instance()->mEventColor;
00745 else
00746 bgColor = *(KOPrefs::instance()->categoryColor(cat));
00747 }
00748 QColor frameColor;
00749 if ( KOPrefs::instance()->agendaViewUsesResourceColor()
00750 && mResourceColor.isValid() ) {
00751 frameColor = mSelected ? QColor( 85 + mResourceColor.red() * 2/3,
00752 85 + mResourceColor.green() * 2/3,
00753 85 + mResourceColor.blue() * 2/3 )
00754 : mResourceColor;
00755 } else {
00756 frameColor = mSelected ? QColor( 85 + bgColor.red() * 2/3,
00757 85 + bgColor.green() * 2/3,
00758 85 + bgColor.blue() * 2/3 )
00759 : bgColor.dark(115);
00760 }
00761 QColor textColor = getTextColor(bgColor);
00762 p.setPen( textColor );
00763 p.setBackgroundColor( bgColor );
00764 p.setFont(KOPrefs::instance()->mAgendaViewFont);
00765 QFontMetrics fm = p.fontMetrics();
00766
00767 int singleLineHeight = fm.boundingRect( mLabelText ).height();
00768
00769 p.eraseRect( 0, 0, width(), height() );
00770 paintFrame( &p, frameColor );
00771
00772
00773
00774
00775 QString shortH;
00776 QString longH;
00777 if ( !isMultiItem() ) {
00778 shortH = KGlobal::locale()->formatTime(mIncidence->dtStart().time());
00779 if (mIncidence->type() != "Todo")
00780 longH = i18n("%1 - %2").arg(shortH)
00781 .arg(KGlobal::locale()->formatTime(mIncidence->dtEnd().time()));
00782 else
00783 longH = shortH;
00784 } else if ( !mMultiItemInfo->mFirstMultiItem ) {
00785 shortH = KGlobal::locale()->formatTime(mIncidence->dtStart().time());
00786 longH = shortH;
00787 } else {
00788 shortH = KGlobal::locale()->formatTime(mIncidence->dtEnd().time());
00789 longH = i18n("- %1").arg(shortH);
00790 }
00791
00792 KWordWrap *ww = KWordWrap::formatText( fm,
00793 QRect(0, 0, width() - (2 * margin), -1),
00794 0,
00795 mLabelText );
00796 int th = ww->boundingRect().height();
00797 delete ww;
00798
00799 int hlHeight = QMAX(fm.boundingRect(longH).height(),
00800 QMAX(alarmPxmp->height(), QMAX(recurPxmp->height(),
00801 QMAX(readonlyPxmp->height(), QMAX(replyPxmp->height(),
00802 QMAX(groupPxmp->height(), organizerPxmp->height()))))));
00803
00804 bool completelyRenderable = th < (height() - 2 * ft - 2 - hlHeight);
00805
00806
00807
00808
00809 if (
00810 ( width() < 16 ) ) {
00811 int x = margin;
00812 paintTodoIcon( &p, x, ft );
00813 return;
00814 }
00815
00816
00817 QRect visRect=visibleRect();
00818
00819
00820 if ( (2 * singleLineHeight) > (height() - 2 * margin) ) {
00821 int x = margin, txtWidth;
00822
00823 if ( mIncidence->doesFloat() ) {
00824 x += visRect.left();
00825 paintIcons( &p, x, ft );
00826 txtWidth = visRect.right() - margin - x;
00827 }
00828 else {
00829 paintIcons( &p, x, ft );
00830 txtWidth = width() - margin - x;
00831 }
00832
00833 int y = ((height() - 2 * ft - singleLineHeight) / 2) + fm.ascent();
00834 KWordWrap::drawFadeoutText( &p, x, y,
00835 txtWidth, mLabelText );
00836 return;
00837 }
00838
00839
00840
00841 if ( ((!completelyRenderable) && ((height() - (2 * margin)) <= (5 * singleLineHeight)) ) ||
00842 (isMultiItem() && mMultiItemInfo->mNextMultiItem && mMultiItemInfo->mFirstMultiItem) ) {
00843 int x = margin, txtWidth;
00844
00845 if ( mIncidence->doesFloat() ) {
00846 x += visRect.left();
00847 paintIcons( &p, x, ft );
00848 txtWidth = visRect.right() - margin - x;
00849 }
00850 else {
00851 paintIcons( &p, x, ft );
00852 txtWidth = width() - margin - x;
00853 }
00854
00855 ww = KWordWrap::formatText( fm,
00856 QRect( 0, 0, txtWidth,
00857 (height() - (2 * margin)) ),
00858 0,
00859 mLabelText );
00860
00861
00862 ww->drawText( &p, x, margin, Qt::AlignHCenter | KWordWrap::FadeOut );
00863 delete ww;
00864 return;
00865 }
00866
00867
00868
00869 int y = 2 * ft + hlHeight;
00870 if ( completelyRenderable )
00871 y += (height() - (2 * ft) - margin - hlHeight - th) / 2;
00872
00873 int x = margin, txtWidth, hTxtWidth, eventX;
00874
00875 if ( mIncidence->doesFloat() ) {
00876 shortH = longH = "";
00877
00878 if ( (mIncidence->type() != "Todo") &&
00879 (mIncidence->dtStart() != mIncidence->dtEnd()) ) {
00880 shortH = longH =
00881 i18n("%1 - %2")
00882 .arg(KGlobal::locale()->formatDate(mIncidence->dtStart().date()))
00883 .arg(KGlobal::locale()->formatDate(mIncidence->dtEnd().date()));
00884
00885
00886 p.fillRect( 0, 0, width(), (ft/2) + margin + hlHeight,
00887 QBrush( frameColor ) );
00888 }
00889
00890 x += visRect.left();
00891 eventX = x;
00892 txtWidth = visRect.right() - margin - x;
00893 paintIcons( &p, x, ft );
00894 hTxtWidth = visRect.right() - margin - x;
00895 }
00896 else {
00897
00898 p.fillRect( 0, 0, width(), (ft/2) + margin + hlHeight,
00899 QBrush( frameColor ) );
00900
00901 txtWidth = width() - margin - x;
00902 eventX = x;
00903 paintIcons( &p, x, ft );
00904 hTxtWidth = width() - margin - x;
00905 }
00906
00907 QString headline;
00908 int hw = fm.boundingRect( longH ).width();
00909 if ( hw > hTxtWidth ) {
00910 headline = shortH;
00911 hw = fm.boundingRect( shortH ).width();
00912 if ( hw < txtWidth )
00913 x += (hTxtWidth - hw) / 2;
00914 } else {
00915 headline = longH;
00916 x += (hTxtWidth - hw) / 2;
00917 }
00918 p.setBackgroundColor( frameColor );
00919 p.setPen( getTextColor( frameColor ) );
00920 KWordWrap::drawFadeoutText( &p, x, ft + fm.ascent(), hTxtWidth, headline );
00921
00922
00923 ww = KWordWrap::formatText( fm,
00924 QRect( 0, 0, txtWidth, height() - margin - y ),
00925 0,
00926 mLabelText );
00927
00928 p.setBackgroundColor( bgColor );
00929 p.setPen( textColor );
00930 QString ws = ww->wrappedString();
00931 if ( ws.left( ws.length()-1 ).find( '\n' ) >= 0 )
00932 ww->drawText( &p, eventX, y,
00933 Qt::AlignAuto | KWordWrap::FadeOut );
00934 else
00935 ww->drawText( &p, eventX + (txtWidth-ww->boundingRect().width()-2*margin)/2,
00936 y, Qt::AlignHCenter | KWordWrap::FadeOut );
00937 delete ww;
00938 }
00939