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