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::GPtr first, KOAgendaItem::GPtr prev,
00224 KOAgendaItem::GPtr next, KOAgendaItem::GPtr 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::GPtr KOAgendaItem::prependMoveItem( KOAgendaItem::GPtr 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::GPtr KOAgendaItem::appendMoveItem( KOAgendaItem::GPtr 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::GPtr KOAgendaItem::removeMoveItem( KOAgendaItem::GPtr e)
00308 {
00309 if (isMultiItem()) {
00310 KOAgendaItem::GPtr first = mMultiItemInfo->mFirstMultiItem;
00311 KOAgendaItem::GPtr next, prev;
00312 KOAgendaItem::GPtr 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::GPtr 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::GPtr toDel = mStartMoveInfo->mPrevMultiItem;
00413 KOAgendaItem::GPtr nowDel=0L;
00414 while (toDel) {
00415 nowDel=toDel;
00416 if (nowDel->moveInfo()) {
00417 toDel=nowDel->moveInfo()->mPrevMultiItem;
00418 }
00419 emit removeAgendaItem( KOAgendaItem::GPtr( nowDel ) );
00420 }
00421 mMultiItemInfo->mFirstMultiItem = 0L;
00422 mMultiItemInfo->mPrevMultiItem = 0L;
00423 }
00424 if ( !mStartMoveInfo->mLastMultiItem ) {
00425
00426 KOAgendaItem::GPtr toDel = mStartMoveInfo->mNextMultiItem;
00427 KOAgendaItem::GPtr nowDel = 0;
00428 while (toDel) {
00429 nowDel=toDel;
00430 if (nowDel->moveInfo()) {
00431 toDel=nowDel->moveInfo()->mNextMultiItem;
00432 }
00433 emit removeAgendaItem( KOAgendaItem::GPtr( nowDel ) );
00434 }
00435 mMultiItemInfo->mLastMultiItem = 0L;
00436 mMultiItemInfo->mNextMultiItem = 0L;
00437 }
00438
00439 if ( !mStartMoveInfo->mFirstMultiItem && !mStartMoveInfo->mLastMultiItem ) {
00440
00441 delete mMultiItemInfo;
00442 mMultiItemInfo = 0;
00443 }
00444 }
00445 delete mStartMoveInfo;
00446 mStartMoveInfo = 0;
00447 }
00448 emit showAgendaItem( KOAgendaItem::GPtr( 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() == KOAgendaItem::GPtr( 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( KOAgendaItem::GPtr( nowDel ) );
00474 }
00475 }
00476
00477 if ( !lastMultiItem() || lastMultiItem() == KOAgendaItem::GPtr( 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( KOAgendaItem::GPtr( 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 AgendaItemList KOAgendaItem::conflictItems()
00611 {
00612 return mConflictItems;
00613 }
00614
00615 void KOAgendaItem::setConflictItems( AgendaItemList ci )
00616 {
00617 mConflictItems = ci;
00618 AgendaItemList::Iterator it;
00619 for ( it = mConflictItems.begin(); it != mConflictItems.end(); ++it ) {
00620 if ( *it ) {
00621 (*it)->addConflictItem( KOAgendaItem::GPtr( this ) );
00622 }
00623 }
00624 }
00625
00626 void KOAgendaItem::addConflictItem( KOAgendaItem::GPtr ci )
00627 {
00628 if ( !mConflictItems.contains( ci ) ) {
00629 mConflictItems.append( ci );
00630 }
00631 }
00632
00633 QString KOAgendaItem::label() const
00634 {
00635 return mLabelText;
00636 }
00637
00638 bool KOAgendaItem::overlaps( KOrg::CellItem *o ) const
00639 {
00640 KOAgendaItem *other = static_cast<KOAgendaItem *>( o );
00641
00642 if ( cellXLeft() <= other->cellXRight() &&
00643 cellXRight() >= other->cellXLeft() ) {
00644 if ( ( cellYTop() <= other->cellYBottom() ) &&
00645 ( cellYBottom() >= other->cellYTop() ) ) {
00646 return true;
00647 }
00648 }
00649
00650 return false;
00651 }
00652
00653 void KOAgendaItem::paintFrame( QPainter *p, const QColor &color )
00654 {
00655 QColor oldpen(p->pen().color());
00656 p->setPen( color );
00657 p->drawRect( 0, 0, width(), height() );
00658 p->drawRect( 1, 1, width() - 2, height() - 2 );
00659 p->setPen( oldpen );
00660 }
00661
00662 static void conditionalPaint( QPainter *p, bool cond, int &x, int ft,
00663 const QPixmap &pxmp )
00664 {
00665 if ( !cond ) return;
00666
00667 p->drawPixmap( x, ft, pxmp );
00668 x += pxmp.width() + ft;
00669 }
00670
00671 void KOAgendaItem::paintEventIcon( QPainter *p, int &x, int ft )
00672 {
00673 if ( !mIncidence ) return;
00674
00675 if ( mIncidence->type() == "Event" ) {
00676 QPixmap eventPxmp;
00677 if ( mIncidence->customProperty( "KABC", "BIRTHDAY" ) == "YES" ) {
00678 mSpecialEvent = true;
00679 if ( mIncidence->customProperty( "KABC", "ANNIVERSARY" ) == "YES" ) {
00680 eventPxmp = KOGlobals::self()->smallIcon( "calendaranniversary" );
00681 } else {
00682 eventPxmp = KOGlobals::self()->smallIcon( "calendarbirthday" );
00683 }
00684 conditionalPaint( p, true, x, ft, eventPxmp );
00685 }
00686
00687 }
00688
00689 }
00690
00691 void KOAgendaItem::paintTodoIcon( QPainter *p, int &x, int ft )
00692 {
00693 if ( !mIncidence ) return;
00694 static const QPixmap todoPxmp =
00695 KOGlobals::self()->smallIcon( "todo" );
00696 static const QPixmap completedPxmp =
00697 KOGlobals::self()->smallIcon( "checkedbox" );
00698 if ( mIncidence->type() != "Todo" )
00699 return;
00700 bool b = ( static_cast<Todo *>( mIncidence ) )->isCompleted();
00701 conditionalPaint( p, !b, x, ft, todoPxmp );
00702 conditionalPaint( p, b, x, ft, completedPxmp );
00703 }
00704
00705 void KOAgendaItem::paintAlarmIcon( QPainter *p, int &x, int ft )
00706 {
00707 if (!mIconAlarm) return;
00708 int y = ft;
00709
00710
00711 if ( visibleRect().height() - ft < alarmPxmp->height() )
00712 y -= ( alarmPxmp->height() - visibleRect().height() - ft );
00713 p->drawPixmap( x, y, *alarmPxmp );
00714 x += alarmPxmp->width() + ft;
00715 }
00716
00717 void KOAgendaItem::paintIcons( QPainter *p, int &x, int ft )
00718 {
00719 paintEventIcon( p, x, ft );
00720 paintTodoIcon( p, x, ft );
00721 if ( !mSpecialEvent ) {
00722 paintAlarmIcon( p, x, ft );
00723 }
00724 conditionalPaint( p, mIconRecur && !mSpecialEvent, x, ft, *recurPxmp );
00725 conditionalPaint( p, mIconReadonly && !mSpecialEvent, x, ft, *readonlyPxmp );
00726 conditionalPaint( p, mIconReply, x, ft, *replyPxmp );
00727 conditionalPaint( p, mIconGroup, x, ft, *groupPxmp );
00728 conditionalPaint( p, mIconGroupTentative, x, ft, *groupPxmpTentative );
00729 conditionalPaint( p, mIconOrganizer, x, ft, *organizerPxmp );
00730 }
00731
00732 void KOAgendaItem::paintEvent( QPaintEvent *ev )
00733 {
00734
00735
00736
00737
00738
00739
00740 if ( !mIncidence )return;
00741
00742 QRect visRect = visibleRect();
00743
00744
00745
00746 if ( ev->rect() != visRect && visRect.isValid() && ev->rect().isValid() ) {
00747 repaint( visRect );
00748 return;
00749 }
00750
00751 QPainter p( this );
00752 const int ft = 2;
00753 const int margin = 1 + ft;
00754
00755
00756
00757
00758
00759
00760 if ( !alarmPxmp ) {
00761 alarmPxmp = new QPixmap( KOGlobals::self()->smallIcon("bell") );
00762 recurPxmp = new QPixmap( KOGlobals::self()->smallIcon("recur") );
00763 readonlyPxmp = new QPixmap( KOGlobals::self()->smallIcon("readonlyevent") );
00764 replyPxmp = new QPixmap( KOGlobals::self()->smallIcon("mail_reply") );
00765 groupPxmp = new QPixmap( KOGlobals::self()->smallIcon("groupevent") );
00766 groupPxmpTentative = new QPixmap( KOGlobals::self()->smallIcon("groupeventtentative") );
00767 organizerPxmp = new QPixmap( KOGlobals::self()->smallIcon("organizer") );
00768 }
00769
00770 QColor bgColor;
00771 if ( mIncidence->type() == "Todo" ) {
00772 if ( static_cast<Todo*>(mIncidence)->isOverdue() )
00773 bgColor = KOPrefs::instance()->todoOverdueColor();
00774 else if ( static_cast<Todo*>(mIncidence)->dtDue().date() ==
00775 QDateTime::currentDateTime().date() )
00776 bgColor = KOPrefs::instance()->todoDueTodayColor();
00777 }
00778
00779 QColor categoryColor;
00780 QStringList categories = mIncidence->categories();
00781 QString cat = categories.first();
00782 if (cat.isEmpty())
00783 categoryColor = KOPrefs::instance()->unsetCategoryColor();
00784 else
00785 categoryColor = *(KOPrefs::instance()->categoryColor(cat));
00786
00787 QColor resourceColor = mResourceColor;
00788 if ( !resourceColor.isValid() )
00789 resourceColor = categoryColor;
00790
00791 QColor frameColor;
00792 if ( KOPrefs::instance()->agendaViewColors() == KOPrefs::ResourceOnly ||
00793 KOPrefs::instance()->agendaViewColors() == KOPrefs::CategoryInsideResourceOutside ) {
00794 frameColor = bgColor.isValid() ? bgColor : resourceColor;
00795 } else {
00796 frameColor = bgColor.isValid() ? bgColor : categoryColor;
00797 }
00798
00799 if ( !bgColor.isValid() ) {
00800 if ( KOPrefs::instance()->agendaViewColors() == KOPrefs::ResourceOnly ||
00801 KOPrefs::instance()->agendaViewColors() == KOPrefs::ResourceInsideCategoryOutside ) {
00802 bgColor = resourceColor;
00803 } else {
00804 bgColor = categoryColor;
00805 }
00806 }
00807
00808 if ( cat.isEmpty() &&
00809 KOPrefs::instance()->agendaViewColors() == KOPrefs::ResourceInsideCategoryOutside ) {
00810 frameColor = bgColor;
00811 }
00812
00813 if ( cat.isEmpty() &&
00814 KOPrefs::instance()->agendaViewColors() == KOPrefs::CategoryInsideResourceOutside ) {
00815 bgColor = frameColor;
00816 }
00817
00818 if ( mSelected ) {
00819 frameColor = QColor( 85 + frameColor.red() * 2/3,
00820 85 + frameColor.green() * 2/3,
00821 85 + frameColor.blue() * 2/3 );
00822 } else {
00823 frameColor = frameColor.dark( 115 );
00824 }
00825 QColor textColor = getTextColor(bgColor);
00826 p.setPen( textColor );
00827 p.setBackgroundColor( bgColor );
00828 p.setFont(KOPrefs::instance()->mAgendaViewFont);
00829 QFontMetrics fm = p.fontMetrics();
00830
00831 int singleLineHeight = fm.boundingRect( mLabelText ).height();
00832
00833 p.eraseRect( 0, 0, width(), height() );
00834 paintFrame( &p, frameColor );
00835
00836
00837
00838
00839 QString shortH;
00840 QString longH;
00841 if ( !isMultiItem() ) {
00842 shortH = KGlobal::locale()->formatTime(mIncidence->dtStart().time());
00843 if (mIncidence->type() != "Todo")
00844 longH = i18n("%1 - %2").arg(shortH)
00845 .arg(KGlobal::locale()->formatTime(mIncidence->dtEnd().time()));
00846 else
00847 longH = shortH;
00848 } else if ( !mMultiItemInfo->mFirstMultiItem ) {
00849 shortH = KGlobal::locale()->formatTime(mIncidence->dtStart().time());
00850 longH = shortH;
00851 } else {
00852 shortH = KGlobal::locale()->formatTime(mIncidence->dtEnd().time());
00853 longH = i18n("- %1").arg(shortH);
00854 }
00855
00856 KWordWrap *ww = KWordWrap::formatText( fm,
00857 QRect(0, 0, width() - (2 * margin), -1),
00858 0,
00859 mLabelText );
00860 int th = ww->boundingRect().height();
00861 delete ww;
00862
00863 int hlHeight = QMAX(fm.boundingRect(longH).height(),
00864 QMAX(alarmPxmp->height(), QMAX(recurPxmp->height(),
00865 QMAX(readonlyPxmp->height(), QMAX(replyPxmp->height(),
00866 QMAX(groupPxmp->height(), organizerPxmp->height()))))));
00867
00868 bool completelyRenderable = th < (height() - 2 * ft - 2 - hlHeight);
00869
00870
00871
00872
00873 if (
00874 ( width() < 16 ) ) {
00875 int x = margin;
00876 paintTodoIcon( &p, x, ft );
00877 return;
00878 }
00879
00880
00881 if ( (2 * singleLineHeight) > (height() - 2 * margin) ) {
00882 int x = margin, txtWidth;
00883
00884 if ( mIncidence->doesFloat() ) {
00885 x += visRect.left();
00886 paintIcons( &p, x, ft );
00887 txtWidth = visRect.right() - margin - x;
00888 }
00889 else {
00890 paintIcons( &p, x, ft );
00891 txtWidth = width() - margin - x;
00892 }
00893
00894 int y = ((height() - 2 * ft - singleLineHeight) / 2) + fm.ascent();
00895 KWordWrap::drawFadeoutText( &p, x, y,
00896 txtWidth, mLabelText );
00897 return;
00898 }
00899
00900
00901
00902 if ( ((!completelyRenderable) && ((height() - (2 * margin)) <= (5 * singleLineHeight)) ) ||
00903 (isMultiItem() && mMultiItemInfo->mNextMultiItem && mMultiItemInfo->mFirstMultiItem) ) {
00904 int x = margin, txtWidth;
00905
00906 if ( mIncidence->doesFloat() ) {
00907 x += visRect.left();
00908 paintIcons( &p, x, ft );
00909 txtWidth = visRect.right() - margin - x;
00910 }
00911 else {
00912 paintIcons( &p, x, ft );
00913 txtWidth = width() - margin - x;
00914 }
00915
00916 ww = KWordWrap::formatText( fm,
00917 QRect( 0, 0, txtWidth,
00918 (height() - (2 * margin)) ),
00919 0,
00920 mLabelText );
00921
00922
00923 ww->drawText( &p, x, margin, Qt::AlignHCenter | KWordWrap::FadeOut );
00924 delete ww;
00925 return;
00926 }
00927
00928
00929
00930 int y = 2 * ft + hlHeight;
00931 if ( completelyRenderable )
00932 y += (height() - (2 * ft) - margin - hlHeight - th) / 2;
00933
00934 int x = margin, txtWidth, hTxtWidth, eventX;
00935
00936 if ( mIncidence->doesFloat() ) {
00937 shortH = longH = "";
00938
00939 if ( (mIncidence->type() != "Todo") &&
00940 (mIncidence->dtStart() != mIncidence->dtEnd()) ) {
00941 shortH = longH =
00942 i18n("%1 - %2")
00943 .arg(KGlobal::locale()->formatDate(mIncidence->dtStart().date()))
00944 .arg(KGlobal::locale()->formatDate(mIncidence->dtEnd().date()));
00945
00946
00947 p.fillRect( 0, 0, width(), (ft/2) + margin + hlHeight,
00948 QBrush( frameColor ) );
00949 }
00950
00951 x += visRect.left();
00952 eventX = x;
00953 txtWidth = visRect.right() - margin - x;
00954 paintIcons( &p, x, ft );
00955 hTxtWidth = visRect.right() - margin - x;
00956 }
00957 else {
00958
00959 p.fillRect( 0, 0, width(), (ft/2) + margin + hlHeight,
00960 QBrush( frameColor ) );
00961
00962 txtWidth = width() - margin - x;
00963 eventX = x;
00964 paintIcons( &p, x, ft );
00965 hTxtWidth = width() - margin - x;
00966 }
00967
00968 QString headline;
00969 int hw = fm.boundingRect( longH ).width();
00970 if ( hw > hTxtWidth ) {
00971 headline = shortH;
00972 hw = fm.boundingRect( shortH ).width();
00973 if ( hw < txtWidth )
00974 x += (hTxtWidth - hw) / 2;
00975 } else {
00976 headline = longH;
00977 x += (hTxtWidth - hw) / 2;
00978 }
00979 p.setBackgroundColor( frameColor );
00980 p.setPen( getTextColor( frameColor ) );
00981 KWordWrap::drawFadeoutText( &p, x, ft + fm.ascent(), hTxtWidth, headline );
00982
00983
00984 ww = KWordWrap::formatText( fm,
00985 QRect( 0, 0, txtWidth, height() - margin - y ),
00986 0,
00987 mLabelText );
00988
00989 p.setBackgroundColor( bgColor );
00990 p.setPen( textColor );
00991 QString ws = ww->wrappedString();
00992 if ( ws.left( ws.length()-1 ).find( '\n' ) >= 0 )
00993 ww->drawText( &p, eventX, y,
00994 Qt::AlignAuto | KWordWrap::FadeOut );
00995 else
00996 ww->drawText( &p, eventX + (txtWidth-ww->boundingRect().width()-2*margin)/2,
00997 y, Qt::AlignHCenter | KWordWrap::FadeOut );
00998 delete ww;
00999 }
01000