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