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