korganizer Library API Documentation

koagendaitem.cpp

00001 /* 00002 This file is part of KOrganizer. 00003 00004 Copyright (c) 2000,2001,2003 Cornelius Schumacher <schumacher@kde.org> 00005 00006 This program is free software; you can redistribute it and/or modify 00007 it under the terms of the GNU General Public License as published by 00008 the Free Software Foundation; either version 2 of the License, or 00009 (at your option) any later version. 00010 00011 This program is distributed in the hope that it will be useful, 00012 but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 GNU General Public License for more details. 00015 00016 You should have received a copy of the GNU General Public License 00017 along with this program; if not, write to the Free Software 00018 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 00019 00020 As a special exception, permission is given to link this program 00021 with any edition of Qt, and distribute the resulting executable, 00022 without including the source code for Qt in the source distribution. 00023 */ 00024 00025 #include <qtooltip.h> 00026 #include <qdragobject.h> 00027 #include <qpainter.h> 00028 00029 #include <kiconloader.h> 00030 #include <kdebug.h> 00031 #include <klocale.h> 00032 #include <kwordwrap.h> 00033 00034 #include <libkcal/icaldrag.h> 00035 #include <libkcal/vcaldrag.h> 00036 #include <libkdepim/kvcarddrag.h> 00037 #ifndef KORG_NOKABC 00038 #include <kabc/addressee.h> 00039 #include <kabc/vcardconverter.h> 00040 #endif 00041 00042 #include "koprefs.h" 00043 #include "koglobals.h" 00044 00045 #include "koincidencetooltip.h" 00046 #include "koagendaitem.h" 00047 #include "koagendaitem.moc" 00048 00049 //-------------------------------------------------------------------------- 00050 00051 QToolTipGroup *KOAgendaItem::mToolTipGroup = 0; 00052 00053 //-------------------------------------------------------------------------- 00054 00055 KOAgendaItem::KOAgendaItem( Incidence *incidence, QDate qd, QWidget *parent, 00056 const char *name, WFlags f ) : 00057 QWidget( parent, name, f ), mIncidence( incidence ), mDate( qd ), 00058 mLabelText( mIncidence->summary() ), mIconAlarm( false ), 00059 mIconRecur( false ), mIconReadonly( false ), mIconReply( false ), 00060 mIconGroup( false ), mIconOrganizer( false ), 00061 mMultiItemInfo( 0 ), mStartMoveInfo( 0 ) 00062 { 00063 setBackgroundMode( Qt::NoBackground ); 00064 00065 setCellXY( 0, 0, 1 ); 00066 setCellXRight( 0 ); 00067 setMouseTracking( true ); 00068 00069 updateIcons(); 00070 00071 // select() does nothing, if state hasn't change, so preset mSelected. 00072 mSelected = true; 00073 select( false ); 00074 00075 KOIncidenceToolTip::add( this, incidence, toolTipGroup() ); 00076 setAcceptDrops( true ); 00077 } 00078 00079 void KOAgendaItem::updateIcons() 00080 { 00081 mIconReadonly = mIncidence->isReadOnly(); 00082 mIconRecur = mIncidence->doesRecur(); 00083 mIconAlarm = mIncidence->isAlarmEnabled(); 00084 if ( mIncidence->attendeeCount() > 0 ) { 00085 if ( KOPrefs::instance()->thatIsMe( mIncidence->organizer() ) ) { 00086 mIconReply = false; 00087 mIconGroup = false; 00088 mIconOrganizer = true; 00089 } else { 00090 Attendee *me = mIncidence->attendeeByMails( KOPrefs::instance()->allEmails() ); 00091 if ( me ) { 00092 if ( me->status() == Attendee::NeedsAction && me->RSVP() ) { 00093 mIconReply = true; 00094 mIconGroup = false; 00095 mIconOrganizer = false; 00096 } else { 00097 mIconReply = false; 00098 mIconGroup = true; 00099 mIconOrganizer = false; 00100 } 00101 } else { 00102 mIconReply = false; 00103 mIconGroup = true; 00104 mIconOrganizer = false; 00105 } 00106 } 00107 } 00108 update(); 00109 } 00110 00111 00112 void KOAgendaItem::select( bool selected ) 00113 { 00114 if ( mSelected == selected ) return; 00115 mSelected = selected; 00116 00117 update(); 00118 } 00119 00120 bool KOAgendaItem::setIncidence( Incidence *i ) 00121 { 00122 mIncidence = i; 00123 updateIcons(); 00124 return true; 00125 } 00126 00127 00128 /* 00129 Return height of item in units of agenda cells 00130 */ 00131 int KOAgendaItem::cellHeight() const 00132 { 00133 return mCellYBottom - mCellYTop + 1; 00134 } 00135 00136 /* 00137 Return height of item in units of agenda cells 00138 */ 00139 int KOAgendaItem::cellWidth() const 00140 { 00141 return mCellXRight - mCellXLeft + 1; 00142 } 00143 00144 void KOAgendaItem::setItemDate( QDate qd ) 00145 { 00146 mDate = qd; 00147 } 00148 00149 void KOAgendaItem::setCellXY( int X, int YTop, int YBottom ) 00150 { 00151 mCellXLeft = X; 00152 mCellYTop = YTop; 00153 mCellYBottom = YBottom; 00154 } 00155 00156 void KOAgendaItem::setCellXRight( int xright ) 00157 { 00158 mCellXRight = xright; 00159 } 00160 00161 void KOAgendaItem::setCellX( int XLeft, int XRight ) 00162 { 00163 mCellXLeft = XLeft; 00164 mCellXRight = XRight; 00165 } 00166 00167 void KOAgendaItem::setCellY( int YTop, int YBottom ) 00168 { 00169 mCellYTop = YTop; 00170 mCellYBottom = YBottom; 00171 } 00172 00173 void KOAgendaItem::setMultiItem(KOAgendaItem *first, KOAgendaItem *prev, 00174 KOAgendaItem *next, KOAgendaItem *last) 00175 { 00176 if (!mMultiItemInfo) mMultiItemInfo=new MultiItemInfo; 00177 mMultiItemInfo->mFirstMultiItem = first; 00178 mMultiItemInfo->mPrevMultiItem = prev; 00179 mMultiItemInfo->mNextMultiItem = next; 00180 mMultiItemInfo->mLastMultiItem = last; 00181 } 00182 bool KOAgendaItem::isMultiItem() 00183 { 00184 return mMultiItemInfo; 00185 } 00186 KOAgendaItem* KOAgendaItem::prependMoveItem(KOAgendaItem* e) 00187 { 00188 if (!e) return e; 00189 00190 KOAgendaItem*first=0, *last=0; 00191 if (isMultiItem()) { 00192 first=mMultiItemInfo->mFirstMultiItem; 00193 last=mMultiItemInfo->mLastMultiItem; 00194 } 00195 if (!first) first=this; 00196 if (!last) last=this; 00197 00198 e->setMultiItem(0, 0, first, last); 00199 first->setMultiItem(e, e, first->nextMultiItem(), first->lastMultiItem() ); 00200 00201 KOAgendaItem*tmp=first->nextMultiItem(); 00202 while (tmp) { 00203 tmp->setMultiItem( e, tmp->prevMultiItem(), tmp->nextMultiItem(), tmp->lastMultiItem() ); 00204 tmp = tmp->nextMultiItem(); 00205 } 00206 00207 if ( mStartMoveInfo && !e->moveInfo() ) { 00208 e->mStartMoveInfo=new MultiItemInfo( *mStartMoveInfo ); 00209 // e->moveInfo()->mFirstMultiItem = moveInfo()->mFirstMultiItem; 00210 // e->moveInfo()->mLastMultiItem = moveInfo()->mLastMultiItem; 00211 e->moveInfo()->mPrevMultiItem = 0; 00212 e->moveInfo()->mNextMultiItem = first; 00213 } 00214 00215 if (first && first->moveInfo()) { 00216 first->moveInfo()->mPrevMultiItem = e; 00217 } 00218 return e; 00219 } 00220 00221 KOAgendaItem* KOAgendaItem::appendMoveItem(KOAgendaItem* e) 00222 { 00223 if (!e) return e; 00224 00225 KOAgendaItem*first=0, *last=0; 00226 if (isMultiItem()) { 00227 first=mMultiItemInfo->mFirstMultiItem; 00228 last=mMultiItemInfo->mLastMultiItem; 00229 } 00230 if (!first) first=this; 00231 if (!last) last=this; 00232 00233 e->setMultiItem( first, last, 0, 0 ); 00234 KOAgendaItem*tmp=first; 00235 00236 while (tmp) { 00237 tmp->setMultiItem(tmp->firstMultiItem(), tmp->prevMultiItem(), tmp->nextMultiItem(), e); 00238 tmp = tmp->nextMultiItem(); 00239 } 00240 last->setMultiItem( last->firstMultiItem(), last->prevMultiItem(), e, e); 00241 00242 if ( mStartMoveInfo && !e->moveInfo() ) { 00243 e->mStartMoveInfo=new MultiItemInfo( *mStartMoveInfo ); 00244 // e->moveInfo()->mFirstMultiItem = moveInfo()->mFirstMultiItem; 00245 // e->moveInfo()->mLastMultiItem = moveInfo()->mLastMultiItem; 00246 e->moveInfo()->mPrevMultiItem = last; 00247 e->moveInfo()->mNextMultiItem = 0; 00248 } 00249 if (last && last->moveInfo()) { 00250 last->moveInfo()->mNextMultiItem = e; 00251 } 00252 return e; 00253 } 00254 00255 KOAgendaItem* KOAgendaItem::removeMoveItem(KOAgendaItem* e) 00256 { 00257 if (isMultiItem()) { 00258 KOAgendaItem *first = mMultiItemInfo->mFirstMultiItem; 00259 KOAgendaItem *next, *prev; 00260 KOAgendaItem *last = mMultiItemInfo->mLastMultiItem; 00261 if (!first) first = this; 00262 if (!last) last = this; 00263 if ( first==e ) { 00264 first = first->nextMultiItem(); 00265 first->setMultiItem( 0, 0, first->nextMultiItem(), first->lastMultiItem() ); 00266 } 00267 if ( last==e ) { 00268 last=last->prevMultiItem(); 00269 last->setMultiItem( last->firstMultiItem(), last->prevMultiItem(), 0, 0 ); 00270 } 00271 00272 KOAgendaItem *tmp = first; 00273 if ( first==last ) { 00274 delete mMultiItemInfo; 00275 tmp = 0; 00276 mMultiItemInfo = 0; 00277 } 00278 while ( tmp ) { 00279 next = tmp->nextMultiItem(); 00280 prev = tmp->prevMultiItem(); 00281 if ( e==next ) { 00282 next = next->nextMultiItem(); 00283 } 00284 if ( e==prev ) { 00285 prev = prev->prevMultiItem(); 00286 } 00287 tmp->setMultiItem((tmp==first)?0:first, (tmp==prev)?0:prev, (tmp==next)?0:next, (tmp==last)?0:last); 00288 tmp = tmp->nextMultiItem(); 00289 } 00290 } 00291 00292 return e; 00293 } 00294 00295 00296 void KOAgendaItem::startMove() 00297 { 00298 KOAgendaItem* first = this; 00299 if ( isMultiItem() && mMultiItemInfo->mFirstMultiItem ) { 00300 first=mMultiItemInfo->mFirstMultiItem; 00301 } 00302 first->startMovePrivate(); 00303 } 00304 00305 void KOAgendaItem::startMovePrivate() 00306 { 00307 mStartMoveInfo = new MultiItemInfo; 00308 mStartMoveInfo->mStartCellXLeft = mCellXLeft; 00309 mStartMoveInfo->mStartCellXRight = mCellXRight; 00310 mStartMoveInfo->mStartCellYTop = mCellYTop; 00311 mStartMoveInfo->mStartCellYBottom = mCellYBottom; 00312 if (mMultiItemInfo) { 00313 mStartMoveInfo->mFirstMultiItem = mMultiItemInfo->mFirstMultiItem; 00314 mStartMoveInfo->mLastMultiItem = mMultiItemInfo->mLastMultiItem; 00315 mStartMoveInfo->mPrevMultiItem = mMultiItemInfo->mPrevMultiItem; 00316 mStartMoveInfo->mNextMultiItem = mMultiItemInfo->mNextMultiItem; 00317 } else { 00318 mStartMoveInfo->mFirstMultiItem = 0; 00319 mStartMoveInfo->mLastMultiItem = 0; 00320 mStartMoveInfo->mPrevMultiItem = 0; 00321 mStartMoveInfo->mNextMultiItem = 0; 00322 } 00323 if ( isMultiItem() && mMultiItemInfo->mNextMultiItem ) 00324 { 00325 mMultiItemInfo->mNextMultiItem->startMovePrivate(); 00326 } 00327 } 00328 00329 void KOAgendaItem::resetMove() 00330 { 00331 if ( mStartMoveInfo ) { 00332 if ( mStartMoveInfo->mFirstMultiItem ) { 00333 mStartMoveInfo->mFirstMultiItem->resetMovePrivate(); 00334 } else { 00335 resetMovePrivate(); 00336 } 00337 } 00338 } 00339 00340 void KOAgendaItem::resetMovePrivate() 00341 { 00342 if (mStartMoveInfo) { 00343 mCellXLeft = mStartMoveInfo->mStartCellXLeft; 00344 mCellXRight = mStartMoveInfo->mStartCellXRight; 00345 mCellYTop = mStartMoveInfo->mStartCellYTop; 00346 mCellYBottom = mStartMoveInfo->mStartCellYBottom; 00347 00348 // if we don't have mMultiItemInfo, the item didn't span two days before, 00349 // and wasn't moved over midnight, either, so we don't have to reset 00350 // anything. Otherwise, restore from mMoveItemInfo 00351 if ( mMultiItemInfo ) { 00352 // It was already a multi-day info 00353 mMultiItemInfo->mFirstMultiItem = mStartMoveInfo->mFirstMultiItem; 00354 mMultiItemInfo->mPrevMultiItem = mStartMoveInfo->mPrevMultiItem; 00355 mMultiItemInfo->mNextMultiItem = mStartMoveInfo->mNextMultiItem; 00356 mMultiItemInfo->mLastMultiItem = mStartMoveInfo->mLastMultiItem; 00357 00358 if ( !mStartMoveInfo->mFirstMultiItem ) { 00359 // This was the first multi-item when the move started, delete all previous 00360 KOAgendaItem*toDel=mStartMoveInfo->mPrevMultiItem; 00361 KOAgendaItem*nowDel=0L; 00362 while (toDel) { 00363 nowDel=toDel; 00364 if (nowDel->moveInfo()) { 00365 toDel=nowDel->moveInfo()->mPrevMultiItem; 00366 } 00367 emit removeAgendaItem( nowDel ); 00368 } 00369 mMultiItemInfo->mFirstMultiItem = 0L; 00370 mMultiItemInfo->mPrevMultiItem = 0L; 00371 } 00372 if ( !mStartMoveInfo->mLastMultiItem ) { 00373 // This was the last multi-item when the move started, delete all next 00374 KOAgendaItem*toDel=mStartMoveInfo->mNextMultiItem; 00375 KOAgendaItem*nowDel=0L; 00376 while (toDel) { 00377 nowDel=toDel; 00378 if (nowDel->moveInfo()) { 00379 toDel=nowDel->moveInfo()->mNextMultiItem; 00380 } 00381 emit removeAgendaItem( nowDel ); 00382 } 00383 mMultiItemInfo->mLastMultiItem = 0L; 00384 mMultiItemInfo->mNextMultiItem = 0L; 00385 } 00386 00387 if ( mStartMoveInfo->mFirstMultiItem==0 && mStartMoveInfo->mLastMultiItem==0 ) { 00388 // it was a single-day event before we started the move. 00389 delete mMultiItemInfo; 00390 mMultiItemInfo = 0; 00391 } 00392 } 00393 delete mStartMoveInfo; 00394 mStartMoveInfo = 0; 00395 } 00396 emit showAgendaItem( this ); 00397 if ( nextMultiItem() ) { 00398 nextMultiItem()->resetMovePrivate(); 00399 } 00400 } 00401 00402 void KOAgendaItem::endMove() 00403 { 00404 KOAgendaItem*first=firstMultiItem(); 00405 if (!first) first=this; 00406 first->endMovePrivate(); 00407 } 00408 00409 void KOAgendaItem::endMovePrivate() 00410 { 00411 if ( mStartMoveInfo ) { 00412 // if first, delete all previous 00413 if ( !firstMultiItem() || firstMultiItem()==this ) { 00414 KOAgendaItem*toDel=mStartMoveInfo->mPrevMultiItem; 00415 KOAgendaItem*nowDel = 0; 00416 while (toDel) { 00417 nowDel=toDel; 00418 if (nowDel->moveInfo()) { 00419 toDel=nowDel->moveInfo()->mPrevMultiItem; 00420 } 00421 emit removeAgendaItem( nowDel ); 00422 } 00423 } 00424 // if last, delete all next 00425 if ( !lastMultiItem() || lastMultiItem()==this ) { 00426 KOAgendaItem*toDel=mStartMoveInfo->mNextMultiItem; 00427 KOAgendaItem*nowDel = 0; 00428 while (toDel) { 00429 nowDel=toDel; 00430 if (nowDel->moveInfo()) { 00431 toDel=nowDel->moveInfo()->mNextMultiItem; 00432 } 00433 emit removeAgendaItem( nowDel ); 00434 } 00435 } 00436 // also delete the moving info 00437 delete mStartMoveInfo; 00438 mStartMoveInfo=0; 00439 if ( nextMultiItem() ) 00440 nextMultiItem()->endMovePrivate(); 00441 } 00442 } 00443 00444 void KOAgendaItem::moveRelative(int dx, int dy) 00445 { 00446 int newXLeft = cellXLeft() + dx; 00447 int newXRight = cellXRight() + dx; 00448 int newYTop = cellYTop() + dy; 00449 int newYBottom = cellYBottom() + dy; 00450 setCellXY(newXLeft,newYTop,newYBottom); 00451 setCellXRight(newXRight); 00452 } 00453 00454 void KOAgendaItem::expandTop(int dy) 00455 { 00456 int newYTop = cellYTop() + dy; 00457 int newYBottom = cellYBottom(); 00458 if (newYTop > newYBottom) newYTop = newYBottom; 00459 setCellY(newYTop, newYBottom); 00460 } 00461 00462 void KOAgendaItem::expandBottom(int dy) 00463 { 00464 int newYTop = cellYTop(); 00465 int newYBottom = cellYBottom() + dy; 00466 if (newYBottom < newYTop) newYBottom = newYTop; 00467 setCellY(newYTop, newYBottom); 00468 } 00469 00470 void KOAgendaItem::expandLeft(int dx) 00471 { 00472 int newXLeft = cellXLeft() + dx; 00473 int newXRight = cellXRight(); 00474 if ( newXLeft > newXRight ) newXLeft = newXRight; 00475 setCellX( newXLeft, newXRight ); 00476 } 00477 00478 void KOAgendaItem::expandRight(int dx) 00479 { 00480 int newXLeft = cellXLeft(); 00481 int newXRight = cellXRight() + dx; 00482 if ( newXRight < newXLeft ) newXRight = newXLeft; 00483 setCellX( newXLeft, newXRight ); 00484 } 00485 00486 QToolTipGroup *KOAgendaItem::toolTipGroup() 00487 { 00488 if (!mToolTipGroup) mToolTipGroup = new QToolTipGroup(0); 00489 return mToolTipGroup; 00490 } 00491 00492 void KOAgendaItem::dragEnterEvent( QDragEnterEvent *e ) 00493 { 00494 #ifndef KORG_NODND 00495 if ( ICalDrag::canDecode( e ) || VCalDrag::canDecode( e ) ) { 00496 e->ignore(); 00497 return; 00498 } 00499 if ( KVCardDrag::canDecode( e ) || QTextDrag::canDecode( e ) ) 00500 e->accept(); 00501 else 00502 e->ignore(); 00503 #endif 00504 } 00505 00506 void KOAgendaItem::addAttendee(QString newAttendee) 00507 { 00508 kdDebug(5850) << " Email: " << newAttendee << endl; 00509 int pos = newAttendee.find("<"); 00510 QString name = newAttendee.left(pos); 00511 QString email = newAttendee.mid(pos); 00512 if (!email.isEmpty()) { 00513 mIncidence->addAttendee(new Attendee(name,email)); 00514 } else if (name.contains("@")) { 00515 mIncidence->addAttendee(new Attendee(name,name)); 00516 } else { 00517 mIncidence->addAttendee(new Attendee(name,QString::null)); 00518 } 00519 } 00520 00521 void KOAgendaItem::dropEvent( QDropEvent *e ) 00522 { 00523 #ifndef KORG_NODND 00524 QString text; 00525 QString vcards; 00526 00527 #ifndef KORG_NOKABC 00528 if ( KVCardDrag::decode( e, vcards ) ) { 00529 KABC::VCardConverter converter; 00530 00531 KABC::Addressee::List list = converter.parseVCards( vcards ); 00532 KABC::Addressee::List::Iterator it; 00533 for ( it = list.begin(); it != list.end(); ++it ) { 00534 QString em( (*it).fullEmail() ); 00535 if (em.isEmpty()) { 00536 em=(*it).realName(); 00537 } 00538 addAttendee( em ); 00539 } 00540 } else 00541 #endif 00542 if( QTextDrag::decode( e, text ) ) { 00543 kdDebug(5850) << "Dropped : " << text << endl; 00544 QStringList emails = QStringList::split( ",", text ); 00545 for( QStringList::ConstIterator it = emails.begin(); it != emails.end(); 00546 ++it ) { 00547 addAttendee( *it ); 00548 } 00549 } 00550 #endif 00551 } 00552 00553 00554 QPtrList<KOAgendaItem> KOAgendaItem::conflictItems() 00555 { 00556 return mConflictItems; 00557 } 00558 00559 void KOAgendaItem::setConflictItems( QPtrList<KOAgendaItem> ci ) 00560 { 00561 mConflictItems = ci; 00562 KOAgendaItem *item; 00563 for ( item = mConflictItems.first(); item != 0; 00564 item = mConflictItems.next() ) { 00565 item->addConflictItem( this ); 00566 } 00567 } 00568 00569 void KOAgendaItem::addConflictItem( KOAgendaItem *ci ) 00570 { 00571 if ( mConflictItems.find( ci ) < 0 ) mConflictItems.append( ci ); 00572 } 00573 00574 QString KOAgendaItem::label() const 00575 { 00576 return mLabelText; 00577 } 00578 00579 bool KOAgendaItem::overlaps( KOrg::CellItem *o ) const 00580 { 00581 KOAgendaItem *other = static_cast<KOAgendaItem *>( o ); 00582 00583 if ( cellXLeft() <= other->cellXRight() && 00584 cellXRight() >= other->cellXLeft() ) { 00585 if ( ( cellYTop() <= other->cellYBottom() ) && 00586 ( cellYBottom() >= other->cellYTop() ) ) { 00587 return true; 00588 } 00589 } 00590 00591 return false; 00592 } 00593 00594 void KOAgendaItem::paintFrame( QPainter *p, const QColor &color ) 00595 { 00596 QColor oldpen(p->pen().color()); 00597 p->setPen( color ); 00598 p->drawRect( 0, 0, width(), height() ); 00599 p->drawRect( 1, 1, width() - 2, height() - 2 ); 00600 p->setPen( oldpen ); 00601 } 00602 00603 static void conditionalPaint( QPainter *p, bool cond, int &x, int ft, 00604 const QPixmap &pxmp ) 00605 { 00606 if ( !cond ) return; 00607 00608 p->drawPixmap( x, ft, pxmp ); 00609 x += pxmp.width() + ft; 00610 } 00611 00612 void KOAgendaItem::paintTodoIcon( QPainter *p, int &x, int ft ) 00613 { 00614 static const QPixmap todoPxmp = KOGlobals::self()->smallIcon("todo"); 00615 static const QPixmap completedPxmp = KOGlobals::self()->smallIcon("checkedbox"); 00616 if ( mIncidence->type() != "Todo" ) 00617 return; 00618 bool b = ( static_cast<Todo *>( mIncidence ) )->isCompleted() || 00619 ( mDate < ( static_cast<Todo *>( mIncidence )->dtDue().date() ) ); 00620 conditionalPaint( p, !b, x, ft, todoPxmp ); 00621 conditionalPaint( p, b, x, ft, completedPxmp ); 00622 } 00623 00624 void KOAgendaItem::paintEvent( QPaintEvent * ) 00625 { 00626 QPainter p( this ); 00627 const int ft = 2; // frame thickness for layout, see paintFrame() 00628 const int margin = 1 + ft; // frame + space between frame and content 00629 bool isTodoOverdue = false; 00630 00631 static const QPixmap alarmPxmp = KOGlobals::self()->smallIcon("bell"); 00632 static const QPixmap recurPxmp = KOGlobals::self()->smallIcon("recur"); 00633 static const QPixmap readonlyPxmp = KOGlobals::self()->smallIcon("readonlyevent"); 00634 static const QPixmap replyPxmp = KOGlobals::self()->smallIcon("mail_reply"); 00635 static const QPixmap groupPxmp = KOGlobals::self()->smallIcon("groupevent"); 00636 static const QPixmap organizerPxmp = KOGlobals::self()->smallIcon("organizer"); 00637 00638 QColor bgColor; 00639 if ( (mIncidence->type() == "Todo") && 00640 ( !((static_cast<Todo*>(mIncidence))->isCompleted()) && 00641 ((static_cast<Todo*>(mIncidence))->dtDue() < QDate::currentDate()) ) ) { 00642 bgColor = KOPrefs::instance()->mTodoOverdueColor; 00643 isTodoOverdue = true; 00644 } else { 00645 QStringList categories = mIncidence->categories(); 00646 QString cat = categories.first(); 00647 if (cat.isEmpty()) 00648 bgColor = KOPrefs::instance()->mEventColor; 00649 else 00650 bgColor = *(KOPrefs::instance()->categoryColor(cat)); 00651 } 00652 00653 QColor frameColor = mSelected ? QColor( 85 + bgColor.red()*2/3, 00654 85 + bgColor.green()*2/3, 00655 85 + bgColor.blue()*2/3 ) 00656 : bgColor.dark(115); 00657 QColor textColor = getTextColor(bgColor); 00658 p.setPen( textColor ); 00659 p.setBackgroundColor( bgColor ); 00660 p.setFont(KOPrefs::instance()->mAgendaViewFont); 00661 QFontMetrics fm = p.fontMetrics(); 00662 00663 int singleLineHeight = fm.boundingRect( mLabelText ).height(); 00664 00665 // case 1: do not draw text when not even a single line fits 00666 // Don't do this any more, always try to print out the text. Even if 00667 // it's just a few pixel, one can still guess the whole text from just four pixels' height! 00668 if ( //( singleLineHeight > height()-4 ) || // ignore margin, be gentle.. Even ignore 2 pixel outside the item 00669 ( width() < 16 ) ) { 00670 p.eraseRect( 0, 0, width(), height() ); 00671 int x = margin; 00672 paintTodoIcon( &p, x, ft ); 00673 paintFrame( &p, frameColor ); 00674 return; 00675 } 00676 00677 // Used for multi-day events to make sure the summary is on screen 00678 QRect visRect=visibleRect(); 00679 00680 // case 2: draw a single line when no more space 00681 if ( (2 * singleLineHeight) > (height() - 2 * margin) ) { 00682 p.eraseRect( 0, 0, width(), height() ); 00683 int x = margin; 00684 int txtWidth = width() - margin - x; 00685 if (mIncidence->doesFloat() ) { 00686 x += visRect.left(); 00687 txtWidth = visRect.right() - margin - x; 00688 } 00689 00690 paintTodoIcon( &p, x, ft ); 00691 paintFrame( &p, frameColor ); 00692 int y = ((height() - 2 * ft - singleLineHeight) / 2) + fm.ascent(); 00693 KWordWrap::drawFadeoutText( &p, x, y, 00694 txtWidth, mLabelText ); 00695 return; 00696 } 00697 00698 KWordWrap *ww = KWordWrap::formatText( fm, 00699 QRect(0, 0, 00700 width() - (2 * margin), -1), 00701 0, 00702 mLabelText ); 00703 int th = ww->boundingRect().height(); 00704 delete ww; 00705 00706 // calculate the height of the full version (case 4) to test whether it is 00707 // possible 00708 QString shortH; 00709 QString longH; 00710 if ( !isMultiItem() ) { 00711 shortH = KGlobal::locale()->formatTime(mIncidence->dtStart().time()); 00712 if (mIncidence->type() != "Todo") 00713 longH = i18n("%1 - %2").arg(shortH) 00714 .arg(KGlobal::locale()->formatTime(mIncidence->dtEnd().time())); 00715 else 00716 longH = shortH; 00717 } else if ( !mMultiItemInfo->mFirstMultiItem ) { 00718 shortH = KGlobal::locale()->formatTime(mIncidence->dtStart().time()); 00719 longH = shortH; 00720 } else { 00721 shortH = KGlobal::locale()->formatTime(mIncidence->dtEnd().time()); 00722 longH = i18n("- %1").arg(shortH); 00723 } 00724 00725 int hlHeight = QMAX(fm.boundingRect(longH).height(), 00726 QMAX(alarmPxmp.height(), QMAX(recurPxmp.height(), 00727 QMAX(readonlyPxmp.height(), QMAX(replyPxmp.height(), 00728 QMAX(groupPxmp.height(), organizerPxmp.height())))))); 00729 bool completelyRenderable = 00730 th < (height() - 2 * ft - 2 - hlHeight); 00731 // case 3: enough for 2-5 lines, but not for the header. 00732 // Also used for the middle days in multi-events 00733 // or all-day events, or overdue todo items 00734 if ( ((!completelyRenderable) && ((height() - (2 * margin)) <= (5 * singleLineHeight)) ) || 00735 (isMultiItem() && mMultiItemInfo->mNextMultiItem && mMultiItemInfo->mFirstMultiItem) || 00736 mIncidence->doesFloat() || 00737 isTodoOverdue ) { 00738 int x = margin; 00739 int txtWidth = width() - margin - x; 00740 if (mIncidence->doesFloat() ) { 00741 x += visRect.left(); 00742 txtWidth = visRect.right() - margin - x; 00743 } 00744 ww = KWordWrap::formatText( fm, 00745 QRect(x, 0, txtWidth, 00746 height() - (2 * margin)), 00747 0, 00748 mLabelText ); 00749 p.eraseRect( 0, 0, width(), height() ); 00750 paintTodoIcon( &p, x, ft ); 00751 paintFrame( &p, frameColor ); 00752 ww->drawText( &p, x, margin, Qt::AlignAuto | KWordWrap::FadeOut ); 00753 delete ww; 00754 return; 00755 } 00756 00757 // case 4: paint everything, with header: 00758 // consists of (vertically) ft + headline&icons + ft + text + margin 00759 int y = 2 * ft + hlHeight; 00760 if ( completelyRenderable ) 00761 y += (height() - (2 * ft) - margin - hlHeight - th) / 2; 00762 ww = KWordWrap::formatText( fm, 00763 QRect(0, 0, width() - (2 * margin), 00764 height() - margin - y), 00765 0, 00766 mLabelText ); 00767 00768 p.eraseRect( 0, 0, width(), height() ); 00769 00770 // paint headline 00771 p.fillRect( 0, 0, width(), (ft/2) + margin + hlHeight, 00772 QBrush( frameColor ) ); 00773 00774 int x = margin; 00775 paintTodoIcon( &p, x, ft ); 00776 conditionalPaint( &p, mIconAlarm, x, ft, alarmPxmp ); 00777 conditionalPaint( &p, mIconRecur, x, ft, recurPxmp ); 00778 conditionalPaint( &p, mIconReadonly, x, ft, readonlyPxmp ); 00779 conditionalPaint( &p, mIconReply, x, ft, replyPxmp ); 00780 conditionalPaint( &p, mIconGroup, x, ft, groupPxmp ); 00781 conditionalPaint( &p, mIconOrganizer, x, ft, organizerPxmp ); 00782 00783 QString headline; 00784 int hw = fm.boundingRect( longH ).width(); 00785 if ( hw > (width() - x - margin) ) { 00786 headline = shortH; 00787 hw = fm.boundingRect( shortH ).width(); 00788 if ( hw < (width() - x - margin) ) 00789 x += (width() - x - margin - hw) / 2; 00790 } else { 00791 headline = longH; 00792 x += (width() - x - margin - hw) / 2; 00793 } 00794 p.setBackgroundColor( frameColor ); 00795 p.setPen( getTextColor( frameColor ) ); 00796 KWordWrap::drawFadeoutText( &p, x, ft + fm.ascent(), 00797 width() - margin - x, headline ); 00798 00799 // draw event text 00800 p.setBackgroundColor( bgColor ); 00801 p.setPen( textColor ); 00802 paintFrame( &p, frameColor ); 00803 QString ws = ww->wrappedString(); 00804 if ( ws.left( ws.length()-1 ).find( '\n' ) >= 0 ) 00805 ww->drawText( &p, margin, y, 00806 Qt::AlignAuto | KWordWrap::FadeOut ); 00807 else 00808 ww->drawText( &p, margin + (width()-ww->boundingRect().width()-2*margin)/2, 00809 y, Qt::AlignHCenter | KWordWrap::FadeOut ); 00810 delete ww; 00811 } 00812
KDE Logo
This file is part of the documentation for korganizer Library Version 3.3.0.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Fri Oct 1 15:19:30 2004 by doxygen 1.3.7 written by Dimitri van Heesch, © 1997-2003