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