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