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