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