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 ( mIncidence->organizer() == KOPrefs::instance()->email() ) { 00086 mIconReply = false; 00087 mIconGroup = false; 00088 mIconOrganizer = true; 00089 } else { 00090 Attendee *me = mIncidence->attendeeByMails( KOPrefs::instance()->mAdditionalMails,KOPrefs::instance()->email() ); 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 00121 /* 00122 Return height of item in units of agenda cells 00123 */ 00124 int KOAgendaItem::cellHeight() const 00125 { 00126 return mCellYBottom - mCellYTop + 1; 00127 } 00128 00129 /* 00130 Return height of item in units of agenda cells 00131 */ 00132 int KOAgendaItem::cellWidth() const 00133 { 00134 return mCellXRight - mCellXLeft + 1; 00135 } 00136 00137 void KOAgendaItem::setItemDate( QDate qd ) 00138 { 00139 mDate = qd; 00140 } 00141 00142 void KOAgendaItem::setCellXY( int X, int YTop, int YBottom ) 00143 { 00144 mCellXLeft = X; 00145 mCellYTop = YTop; 00146 mCellYBottom = YBottom; 00147 } 00148 00149 void KOAgendaItem::setCellXRight( int xright ) 00150 { 00151 mCellXRight = xright; 00152 } 00153 00154 void KOAgendaItem::setCellX( int XLeft, int XRight ) 00155 { 00156 mCellXLeft = XLeft; 00157 mCellXRight = XRight; 00158 } 00159 00160 void KOAgendaItem::setCellY( int YTop, int YBottom ) 00161 { 00162 mCellYTop = YTop; 00163 mCellYBottom = YBottom; 00164 } 00165 00166 void KOAgendaItem::setMultiItem(KOAgendaItem *first, KOAgendaItem *prev, 00167 KOAgendaItem *next, KOAgendaItem *last) 00168 { 00169 if (!mMultiItemInfo) mMultiItemInfo=new MultiItemInfo; 00170 mMultiItemInfo->mFirstMultiItem = first; 00171 mMultiItemInfo->mPrevMultiItem = prev; 00172 mMultiItemInfo->mNextMultiItem = next; 00173 mMultiItemInfo->mLastMultiItem = last; 00174 } 00175 bool KOAgendaItem::isMultiItem() 00176 { 00177 return mMultiItemInfo; 00178 } 00179 KOAgendaItem* KOAgendaItem::prependMoveItem(KOAgendaItem* e) 00180 { 00181 if (!e) return e; 00182 00183 KOAgendaItem*first=0, *last=0; 00184 if (isMultiItem()) { 00185 first=mMultiItemInfo->mFirstMultiItem; 00186 last=mMultiItemInfo->mLastMultiItem; 00187 } 00188 if (!first) first=this; 00189 if (!last) last=this; 00190 00191 e->setMultiItem(0, 0, first, last); 00192 first->setMultiItem(e, e, first->nextMultiItem(), first->lastMultiItem() ); 00193 00194 KOAgendaItem*tmp=first->nextMultiItem(); 00195 while (tmp) { 00196 tmp->setMultiItem( e, tmp->prevMultiItem(), tmp->nextMultiItem(), tmp->lastMultiItem() ); 00197 tmp = tmp->nextMultiItem(); 00198 } 00199 00200 if ( mStartMoveInfo && !e->moveInfo() ) { 00201 e->mStartMoveInfo=new MultiItemInfo( *mStartMoveInfo ); 00202 // e->moveInfo()->mFirstMultiItem = moveInfo()->mFirstMultiItem; 00203 // e->moveInfo()->mLastMultiItem = moveInfo()->mLastMultiItem; 00204 e->moveInfo()->mPrevMultiItem = 0; 00205 e->moveInfo()->mNextMultiItem = first; 00206 } 00207 00208 if (first && first->moveInfo()) { 00209 first->moveInfo()->mPrevMultiItem = e; 00210 } 00211 return e; 00212 } 00213 00214 KOAgendaItem* KOAgendaItem::appendMoveItem(KOAgendaItem* e) 00215 { 00216 if (!e) return e; 00217 00218 KOAgendaItem*first=0, *last=0; 00219 if (isMultiItem()) { 00220 first=mMultiItemInfo->mFirstMultiItem; 00221 last=mMultiItemInfo->mLastMultiItem; 00222 } 00223 if (!first) first=this; 00224 if (!last) last=this; 00225 00226 e->setMultiItem( first, last, 0, 0 ); 00227 KOAgendaItem*tmp=first; 00228 00229 while (tmp) { 00230 tmp->setMultiItem(tmp->firstMultiItem(), tmp->prevMultiItem(), tmp->nextMultiItem(), e); 00231 tmp = tmp->nextMultiItem(); 00232 } 00233 last->setMultiItem( last->firstMultiItem(), last->prevMultiItem(), e, e); 00234 00235 if ( mStartMoveInfo && !e->moveInfo() ) { 00236 e->mStartMoveInfo=new MultiItemInfo( *mStartMoveInfo ); 00237 // e->moveInfo()->mFirstMultiItem = moveInfo()->mFirstMultiItem; 00238 // e->moveInfo()->mLastMultiItem = moveInfo()->mLastMultiItem; 00239 e->moveInfo()->mPrevMultiItem = last; 00240 e->moveInfo()->mNextMultiItem = 0; 00241 } 00242 if (last && last->moveInfo()) { 00243 last->moveInfo()->mNextMultiItem = e; 00244 } 00245 return e; 00246 } 00247 00248 KOAgendaItem* KOAgendaItem::removeMoveItem(KOAgendaItem* e) 00249 { 00250 if (isMultiItem()) { 00251 KOAgendaItem *first = mMultiItemInfo->mFirstMultiItem; 00252 KOAgendaItem *next, *prev; 00253 KOAgendaItem *last = mMultiItemInfo->mLastMultiItem; 00254 if (!first) first = this; 00255 if (!last) last = this; 00256 if ( first==e ) { 00257 first = first->nextMultiItem(); 00258 first->setMultiItem( 0, 0, first->nextMultiItem(), first->lastMultiItem() ); 00259 } 00260 if ( last==e ) { 00261 last=last->prevMultiItem(); 00262 last->setMultiItem( last->firstMultiItem(), last->prevMultiItem(), 0, 0 ); 00263 } 00264 00265 KOAgendaItem *tmp = first; 00266 if ( first==last ) { 00267 delete mMultiItemInfo; 00268 tmp = 0; 00269 mMultiItemInfo = 0; 00270 } 00271 while ( tmp ) { 00272 next = tmp->nextMultiItem(); 00273 prev = tmp->prevMultiItem(); 00274 if ( e==next ) { 00275 next = next->nextMultiItem(); 00276 } 00277 if ( e==prev ) { 00278 prev = prev->prevMultiItem(); 00279 } 00280 tmp->setMultiItem((tmp==first)?0:first, (tmp==prev)?0:prev, (tmp==next)?0:next, (tmp==last)?0:last); 00281 tmp = tmp->nextMultiItem(); 00282 } 00283 } 00284 00285 return e; 00286 } 00287 00288 00289 void KOAgendaItem::startMove() 00290 { 00291 KOAgendaItem* first = this; 00292 if ( isMultiItem() && mMultiItemInfo->mFirstMultiItem ) { 00293 first=mMultiItemInfo->mFirstMultiItem; 00294 } 00295 first->startMovePrivate(); 00296 } 00297 00298 void KOAgendaItem::startMovePrivate() 00299 { 00300 mStartMoveInfo = new MultiItemInfo; 00301 mStartMoveInfo->mStartCellXLeft = mCellXLeft; 00302 mStartMoveInfo->mStartCellXRight = mCellXRight; 00303 mStartMoveInfo->mStartCellYTop = mCellYTop; 00304 mStartMoveInfo->mStartCellYBottom = mCellYBottom; 00305 if (mMultiItemInfo) { 00306 mStartMoveInfo->mFirstMultiItem = mMultiItemInfo->mFirstMultiItem; 00307 mStartMoveInfo->mLastMultiItem = mMultiItemInfo->mLastMultiItem; 00308 mStartMoveInfo->mPrevMultiItem = mMultiItemInfo->mPrevMultiItem; 00309 mStartMoveInfo->mNextMultiItem = mMultiItemInfo->mNextMultiItem; 00310 } else { 00311 mStartMoveInfo->mFirstMultiItem = 0; 00312 mStartMoveInfo->mLastMultiItem = 0; 00313 mStartMoveInfo->mPrevMultiItem = 0; 00314 mStartMoveInfo->mNextMultiItem = 0; 00315 } 00316 if ( isMultiItem() && mMultiItemInfo->mNextMultiItem ) 00317 { 00318 mMultiItemInfo->mNextMultiItem->startMovePrivate(); 00319 } 00320 } 00321 00322 void KOAgendaItem::resetMove() 00323 { 00324 if ( mStartMoveInfo ) { 00325 if ( mStartMoveInfo->mFirstMultiItem ) { 00326 mStartMoveInfo->mFirstMultiItem->resetMovePrivate(); 00327 } else { 00328 resetMovePrivate(); 00329 } 00330 } 00331 } 00332 00333 void KOAgendaItem::resetMovePrivate() 00334 { 00335 if (mStartMoveInfo) { 00336 mCellXLeft = mStartMoveInfo->mStartCellXLeft; 00337 mCellXRight = mStartMoveInfo->mStartCellXRight; 00338 mCellYTop = mStartMoveInfo->mStartCellYTop; 00339 mCellYBottom = mStartMoveInfo->mStartCellYBottom; 00340 00341 // if we don't have mMultiItemInfo, the item didn't span two days before, 00342 // and wasn't moved over midnight, either, so we don't have to reset 00343 // anything. Otherwise, restore from mMoveItemInfo 00344 if ( mMultiItemInfo ) { 00345 // It was already a multi-day info 00346 mMultiItemInfo->mFirstMultiItem = mStartMoveInfo->mFirstMultiItem; 00347 mMultiItemInfo->mPrevMultiItem = mStartMoveInfo->mPrevMultiItem; 00348 mMultiItemInfo->mNextMultiItem = mStartMoveInfo->mNextMultiItem; 00349 mMultiItemInfo->mLastMultiItem = mStartMoveInfo->mLastMultiItem; 00350 00351 if ( !mStartMoveInfo->mFirstMultiItem ) { 00352 // This was the first multi-item when the move started, delete all previous 00353 KOAgendaItem*toDel=mStartMoveInfo->mPrevMultiItem; 00354 KOAgendaItem*nowDel=0L; 00355 while (toDel) { 00356 nowDel=toDel; 00357 if (nowDel->moveInfo()) { 00358 toDel=nowDel->moveInfo()->mPrevMultiItem; 00359 } 00360 emit removeAgendaItem( nowDel ); 00361 } 00362 mMultiItemInfo->mFirstMultiItem = 0L; 00363 mMultiItemInfo->mPrevMultiItem = 0L; 00364 } 00365 if ( !mStartMoveInfo->mLastMultiItem ) { 00366 // This was the last multi-item when the move started, delete all next 00367 KOAgendaItem*toDel=mStartMoveInfo->mNextMultiItem; 00368 KOAgendaItem*nowDel=0L; 00369 while (toDel) { 00370 nowDel=toDel; 00371 if (nowDel->moveInfo()) { 00372 toDel=nowDel->moveInfo()->mNextMultiItem; 00373 } 00374 emit removeAgendaItem( nowDel ); 00375 } 00376 mMultiItemInfo->mLastMultiItem = 0L; 00377 mMultiItemInfo->mNextMultiItem = 0L; 00378 } 00379 00380 if ( mStartMoveInfo->mFirstMultiItem==0 && mStartMoveInfo->mLastMultiItem==0 ) { 00381 // it was a single-day event before we started the move. 00382 delete mMultiItemInfo; 00383 mMultiItemInfo = 0; 00384 } 00385 } 00386 delete mStartMoveInfo; 00387 mStartMoveInfo = 0; 00388 } 00389 emit showAgendaItem( this ); 00390 if ( nextMultiItem() ) { 00391 nextMultiItem()->resetMovePrivate(); 00392 } 00393 } 00394 00395 void KOAgendaItem::endMove() 00396 { 00397 KOAgendaItem*first=firstMultiItem(); 00398 if (!first) first=this; 00399 first->endMovePrivate(); 00400 } 00401 00402 void KOAgendaItem::endMovePrivate() 00403 { 00404 if ( mStartMoveInfo ) { 00405 // if first, delete all previous 00406 if ( !firstMultiItem() || firstMultiItem()==this ) { 00407 KOAgendaItem*toDel=mStartMoveInfo->mPrevMultiItem; 00408 KOAgendaItem*nowDel = 0; 00409 while (toDel) { 00410 nowDel=toDel; 00411 if (nowDel->moveInfo()) { 00412 toDel=nowDel->moveInfo()->mPrevMultiItem; 00413 } 00414 emit removeAgendaItem( nowDel ); 00415 } 00416 } 00417 // if last, delete all next 00418 if ( !lastMultiItem() || lastMultiItem()==this ) { 00419 KOAgendaItem*toDel=mStartMoveInfo->mNextMultiItem; 00420 KOAgendaItem*nowDel = 0; 00421 while (toDel) { 00422 nowDel=toDel; 00423 if (nowDel->moveInfo()) { 00424 toDel=nowDel->moveInfo()->mNextMultiItem; 00425 } 00426 emit removeAgendaItem( nowDel ); 00427 } 00428 } 00429 // also delete the moving info 00430 delete mStartMoveInfo; 00431 mStartMoveInfo=0; 00432 if ( nextMultiItem() ) 00433 nextMultiItem()->endMovePrivate(); 00434 } 00435 } 00436 00437 void KOAgendaItem::moveRelative(int dx, int dy) 00438 { 00439 int newXLeft = cellXLeft() + dx; 00440 int newXRight = cellXRight() + dx; 00441 int newYTop = cellYTop() + dy; 00442 int newYBottom = cellYBottom() + dy; 00443 setCellXY(newXLeft,newYTop,newYBottom); 00444 setCellXRight(newXRight); 00445 } 00446 00447 void KOAgendaItem::expandTop(int dy) 00448 { 00449 int newYTop = cellYTop() + dy; 00450 int newYBottom = cellYBottom(); 00451 if (newYTop > newYBottom) newYTop = newYBottom; 00452 setCellY(newYTop, newYBottom); 00453 } 00454 00455 void KOAgendaItem::expandBottom(int dy) 00456 { 00457 int newYTop = cellYTop(); 00458 int newYBottom = cellYBottom() + dy; 00459 if (newYBottom < newYTop) newYBottom = newYTop; 00460 setCellY(newYTop, newYBottom); 00461 } 00462 00463 void KOAgendaItem::expandLeft(int dx) 00464 { 00465 int newXLeft = cellXLeft() + dx; 00466 int newXRight = cellXRight(); 00467 if ( newXLeft > newXRight ) newXLeft = newXRight; 00468 setCellX( newXLeft, newXRight ); 00469 } 00470 00471 void KOAgendaItem::expandRight(int dx) 00472 { 00473 int newXLeft = cellXLeft(); 00474 int newXRight = cellXRight() + dx; 00475 if ( newXRight < newXLeft ) newXRight = newXLeft; 00476 setCellX( newXLeft, newXRight ); 00477 } 00478 00479 QToolTipGroup *KOAgendaItem::toolTipGroup() 00480 { 00481 if (!mToolTipGroup) mToolTipGroup = new QToolTipGroup(0); 00482 return mToolTipGroup; 00483 } 00484 00485 void KOAgendaItem::dragEnterEvent( QDragEnterEvent *e ) 00486 { 00487 #ifndef KORG_NODND 00488 if ( ICalDrag::canDecode( e ) || VCalDrag::canDecode( e ) ) { 00489 e->ignore(); 00490 return; 00491 } 00492 if ( KVCardDrag::canDecode( e ) || QTextDrag::canDecode( e ) ) 00493 e->accept(); 00494 else 00495 e->ignore(); 00496 #endif 00497 } 00498 00499 void KOAgendaItem::addAttendee(QString newAttendee) 00500 { 00501 kdDebug(5850) << " Email: " << newAttendee << endl; 00502 int pos = newAttendee.find("<"); 00503 QString name = newAttendee.left(pos); 00504 QString email = newAttendee.mid(pos); 00505 if (!email.isEmpty()) { 00506 mIncidence->addAttendee(new Attendee(name,email)); 00507 } else if (name.contains("@")) { 00508 mIncidence->addAttendee(new Attendee(name,name)); 00509 } else { 00510 mIncidence->addAttendee(new Attendee(name,QString::null)); 00511 } 00512 } 00513 00514 void KOAgendaItem::dropEvent( QDropEvent *e ) 00515 { 00516 #ifndef KORG_NODND 00517 QString text; 00518 QString vcards; 00519 00520 #ifndef KORG_NOKABC 00521 if ( KVCardDrag::decode( e, vcards ) ) { 00522 KABC::VCardConverter converter; 00523 00524 KABC::Addressee::List list = converter.parseVCards( vcards ); 00525 KABC::Addressee::List::Iterator it; 00526 for ( it = list.begin(); it != list.end(); ++it ) { 00527 QString em( (*it).fullEmail() ); 00528 if (em.isEmpty()) { 00529 em=(*it).realName(); 00530 } 00531 addAttendee( em ); 00532 } 00533 } else 00534 #endif 00535 if( QTextDrag::decode( e, text ) ) { 00536 kdDebug(5850) << "Dropped : " << text << endl; 00537 QStringList emails = QStringList::split( ",", text ); 00538 for( QStringList::ConstIterator it = emails.begin(); it != emails.end(); 00539 ++it ) { 00540 addAttendee( *it ); 00541 } 00542 } 00543 #endif 00544 } 00545 00546 00547 QPtrList<KOAgendaItem> KOAgendaItem::conflictItems() 00548 { 00549 return mConflictItems; 00550 } 00551 00552 void KOAgendaItem::setConflictItems( QPtrList<KOAgendaItem> ci ) 00553 { 00554 mConflictItems = ci; 00555 KOAgendaItem *item; 00556 for ( item = mConflictItems.first(); item != 0; 00557 item = mConflictItems.next() ) { 00558 item->addConflictItem( this ); 00559 } 00560 } 00561 00562 void KOAgendaItem::addConflictItem( KOAgendaItem *ci ) 00563 { 00564 if ( mConflictItems.find( ci ) < 0 ) mConflictItems.append( ci ); 00565 } 00566 00567 QString KOAgendaItem::label() const 00568 { 00569 return mLabelText; 00570 } 00571 00572 bool KOAgendaItem::overlaps( KOrg::CellItem *o ) const 00573 { 00574 KOAgendaItem *other = static_cast<KOAgendaItem *>( o ); 00575 00576 if ( cellXLeft() <= other->cellXRight() && 00577 cellXRight() >= other->cellXLeft() ) { 00578 if ( ( cellYTop() <= other->cellYBottom() ) && 00579 ( cellYBottom() >= other->cellYTop() ) ) { 00580 return true; 00581 } 00582 } 00583 00584 return false; 00585 } 00586 00587 void KOAgendaItem::paintFrame( QPainter *p, const QColor &color ) 00588 { 00589 QColor oldpen(p->pen().color()); 00590 p->setPen( color ); 00591 p->drawRect( 0, 0, width(), height() ); 00592 p->drawRect( 1, 1, width() - 2, height() - 2 ); 00593 p->setPen( oldpen ); 00594 } 00595 00596 static void conditionalPaint( QPainter *p, bool cond, int &x, int ft, 00597 const QPixmap &pxmp ) 00598 { 00599 if ( !cond ) return; 00600 00601 p->drawPixmap( x, ft, pxmp ); 00602 x += pxmp.width() + ft; 00603 } 00604 00605 void KOAgendaItem::paintTodoIcon( QPainter *p, int &x, int ft ) 00606 { 00607 static const QPixmap todoPxmp = KOGlobals::self()->smallIcon("todo"); 00608 static const QPixmap completedPxmp = KOGlobals::self()->smallIcon("checkedbox"); 00609 if ( mIncidence->type() != "Todo" ) 00610 return; 00611 bool b = ( static_cast<Todo *>( mIncidence ) )->isCompleted(); 00612 conditionalPaint( p, b, x, ft, todoPxmp ); 00613 conditionalPaint( p, !b, x, ft, completedPxmp ); 00614 } 00615 00616 void KOAgendaItem::paintEvent( QPaintEvent * ) 00617 { 00618 QPainter p( this ); 00619 const int ft = 2; // frame thickness for layout, see paintFrame() 00620 const int margin = 1 + ft; // frame + space between frame and content 00621 00622 static const QPixmap alarmPxmp = KOGlobals::self()->smallIcon("bell"); 00623 static const QPixmap recurPxmp = KOGlobals::self()->smallIcon("recur"); 00624 static const QPixmap readonlyPxmp = KOGlobals::self()->smallIcon("readonlyevent"); 00625 static const QPixmap replyPxmp = KOGlobals::self()->smallIcon("mail_reply"); 00626 static const QPixmap groupPxmp = KOGlobals::self()->smallIcon("groupevent"); 00627 static const QPixmap organizerPxmp = KOGlobals::self()->smallIcon("organizer"); 00628 00629 QColor bgColor; 00630 if ( (mIncidence->type() == "Todo") && 00631 ( !((static_cast<Todo*>(mIncidence))->isCompleted()) && 00632 ((static_cast<Todo*>(mIncidence))->dtDue() < QDate::currentDate()) ) ) 00633 bgColor = KOPrefs::instance()->mTodoOverdueColor; 00634 else { 00635 QStringList categories = mIncidence->categories(); 00636 QString cat = categories.first(); 00637 if (cat.isEmpty()) 00638 bgColor = KOPrefs::instance()->mEventColor; 00639 else 00640 bgColor = *(KOPrefs::instance()->categoryColor(cat)); 00641 } 00642 00643 QColor frameColor = mSelected ? QColor( 85 + bgColor.red()*2/3, 00644 85 + bgColor.green()*2/3, 00645 85 + bgColor.blue()*2/3 ) 00646 : bgColor.dark(115); 00647 QColor textColor = getTextColor(bgColor); 00648 p.setPen( textColor ); 00649 p.setBackgroundColor( bgColor ); 00650 p.setFont(KOPrefs::instance()->mAgendaViewFont); 00651 QFontMetrics fm = p.fontMetrics(); 00652 00653 int singleLineHeight = fm.boundingRect( mLabelText ).height(); 00654 00655 // case 1: do not draw text when not even a single line fits 00656 if ( //( singleLineHeight > height()-4 ) || // ignore margin, be gentle.. Even ignore 2 pixel outside the item 00657 ( width() < 16 ) ) { 00658 p.eraseRect( 0, 0, width(), height() ); 00659 int x = margin; 00660 paintTodoIcon( &p, x, ft ); 00661 paintFrame( &p, frameColor ); 00662 return; 00663 } 00664 00665 // Used for multi-day events to make sure the summary is on screen 00666 QRect visRect=visibleRect(); 00667 00668 // case 2: draw a single line when no more space 00669 if ( (2 * singleLineHeight) > (height() - 2 * margin) ) { 00670 p.eraseRect( 0, 0, width(), height() ); 00671 int x = margin; 00672 int txtWidth = width() - margin - x; 00673 if (mIncidence->doesFloat() ) { 00674 x += visRect.left(); 00675 txtWidth = visRect.right() - margin - x; 00676 } 00677 00678 paintTodoIcon( &p, x, ft ); 00679 paintFrame( &p, frameColor ); 00680 int y = ((height() - 2 * ft - singleLineHeight) / 2) + fm.ascent(); 00681 KWordWrap::drawFadeoutText( &p, x, y, 00682 txtWidth, mLabelText ); 00683 return; 00684 } 00685 00686 KWordWrap *ww = KWordWrap::formatText( fm, 00687 QRect(0, 0, 00688 width() - (2 * margin), 0), 00689 0, 00690 mLabelText ); 00691 int th = ww->boundingRect().height(); 00692 delete ww; 00693 00694 // calculate the height of the full version (case 4) to test whether it is 00695 // possible 00696 QString shortH; 00697 QString longH; 00698 if ( !isMultiItem() ) { 00699 shortH = KGlobal::locale()->formatTime(mIncidence->dtStart().time()); 00700 if (mIncidence->type() != "Todo") 00701 longH = i18n("%1 - %2").arg(shortH) 00702 .arg(KGlobal::locale()->formatTime(mIncidence->dtEnd().time())); 00703 else 00704 longH = shortH; 00705 } else if ( !mMultiItemInfo->mFirstMultiItem ) { 00706 shortH = KGlobal::locale()->formatTime(mIncidence->dtStart().time()); 00707 longH = shortH; 00708 } else { 00709 shortH = KGlobal::locale()->formatTime(mIncidence->dtEnd().time()); 00710 longH = i18n("- %1").arg(shortH); 00711 } 00712 00713 int hlHeight = QMAX(fm.boundingRect(longH).height(), 00714 QMAX(alarmPxmp.height(), QMAX(recurPxmp.height(), 00715 QMAX(readonlyPxmp.height(), QMAX(replyPxmp.height(), 00716 QMAX(groupPxmp.height(), organizerPxmp.height())))))); 00717 bool completelyRenderable = 00718 th < (height() - 2 * ft - 2 - hlHeight); 00719 // case 3: enough for 2-5 lines, but not for the header. 00720 // Also used for the middle days in multi-events 00721 // or all-day events 00722 if ( ((!completelyRenderable) && ((height() - (2 * margin)) <= (5 * singleLineHeight)) ) || 00723 (isMultiItem() && mMultiItemInfo->mNextMultiItem && mMultiItemInfo->mFirstMultiItem) || 00724 mIncidence->doesFloat() ) { 00725 int x = margin; 00726 int txtWidth = width() - margin - x; 00727 if (mIncidence->doesFloat() ) { 00728 x += visRect.left(); 00729 txtWidth = visRect.right() - margin - x; 00730 } 00731 ww = KWordWrap::formatText( fm, 00732 QRect(x, 0, txtWidth, 00733 height() - (2 * margin)), 00734 0, 00735 mLabelText ); 00736 p.eraseRect( 0, 0, width(), height() ); 00737 paintTodoIcon( &p, x, ft ); 00738 paintFrame( &p, frameColor ); 00739 ww->drawText( &p, x, margin, Qt::AlignAuto | KWordWrap::FadeOut ); 00740 delete ww; 00741 return; 00742 } 00743 00744 // case 4: paint everything, with header: 00745 // consists of (vertically) ft + headline&icons + ft + text + margin 00746 int y = 2 * ft + hlHeight; 00747 if ( completelyRenderable ) 00748 y += (height() - (2 * ft) - margin - hlHeight - th) / 2; 00749 ww = KWordWrap::formatText( fm, 00750 QRect(0, 0, width() - (2 * margin), 00751 height() - margin - y), 00752 0, 00753 mLabelText ); 00754 00755 p.eraseRect( 0, 0, width(), height() ); 00756 00757 // paint headline 00758 p.fillRect( 0, 0, width(), (ft/2) + margin + hlHeight, 00759 QBrush( frameColor ) ); 00760 00761 int x = margin; 00762 paintTodoIcon( &p, x, ft ); 00763 conditionalPaint( &p, mIconAlarm, x, ft, alarmPxmp ); 00764 conditionalPaint( &p, mIconRecur, x, ft, recurPxmp ); 00765 conditionalPaint( &p, mIconReadonly, x, ft, readonlyPxmp ); 00766 conditionalPaint( &p, mIconReply, x, ft, replyPxmp ); 00767 conditionalPaint( &p, mIconGroup, x, ft, groupPxmp ); 00768 conditionalPaint( &p, mIconOrganizer, x, ft, organizerPxmp ); 00769 00770 QString headline; 00771 int hw = fm.boundingRect( longH ).width(); 00772 if ( hw > (width() - x - margin) ) { 00773 headline = shortH; 00774 hw = fm.boundingRect( shortH ).width(); 00775 if ( hw < (width() - x - margin) ) 00776 x += (width() - x - margin - hw) / 2; 00777 else 00778 headline = ""; 00779 } else { 00780 headline = longH; 00781 x += (width() - x - margin - hw) / 2; 00782 } 00783 p.setBackgroundColor( frameColor ); 00784 p.setPen( getTextColor( frameColor ) ); 00785 KWordWrap::drawFadeoutText( &p, x, ft + fm.ascent(), 00786 width() - margin - x, headline ); 00787 00788 // draw event text 00789 p.setBackgroundColor( bgColor ); 00790 p.setPen( textColor ); 00791 paintFrame( &p, frameColor ); 00792 QString ws = ww->wrappedString(); 00793 if ( ws.left( ws.length()-1 ).find( '\n' ) >= 0 ) 00794 ww->drawText( &p, margin, y, 00795 Qt::AlignAuto | KWordWrap::FadeOut ); 00796 else 00797 ww->drawText( &p, margin + (width()-ww->boundingRect().width()-2*margin)/2, 00798 y, Qt::AlignHCenter | KWordWrap::FadeOut ); 00799 delete ww; 00800 } 00801
KDE Logo
This file is part of the documentation for korganizer Library Version 3.2.2.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Wed Jul 28 23:58:13 2004 by doxygen 1.3.7 written by Dimitri van Heesch, © 1997-2003