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("@")) {
    mIncidence->addAttendee(new Attendee(name,name));
  } else {
    mIncidence->addAttendee(new Attendee(name,QString::null));
  }
}

void KOAgendaItem::dropEvent( QDropEvent *e )
{
#ifndef KORG_NODND
  QString text;
  QString vcards;

#ifndef KORG_NOKABC
  if ( KVCardDrag::decode( e, vcards ) ) {
    KABC::VCardConverter converter;

    KABC::Addressee::List list = converter.parseVCards( vcards );
    KABC::Addressee::List::Iterator it;
    for ( it = list.begin(); it != list.end(); ++it ) {
      QString em( (*it).fullEmail() );
      if (em.isEmpty()) {
        em=(*it).realName();
      }
      addAttendee( em );
    }
  } else
#endif
  if( QTextDrag::decode( e, text ) ) {
    kdDebug(5850) << "Dropped : " << text << endl;
00508     QStringList emails = QStringList::split( ",", text );
00509     for( QStringList::ConstIterator it = emails.begin(); it != emails.end();
00510          ++it ) {
00511       addAttendee( *it );
00512     }
00513   }
00514 #endif
00515 }
00516 
00517 
00518 QPtrList<KOAgendaItem> KOAgendaItem::conflictItems()
00519 {
00520   return mConflictItems;
00521 }
00522 
00523 void KOAgendaItem::setConflictItems( QPtrList<KOAgendaItem> ci )
00524 {
00525   mConflictItems = ci;
00526   KOAgendaItem *item;
00527   for ( item = mConflictItems.first(); item != 0;
00528         item = mConflictItems.next() ) {
00529     item->addConflictItem( this );
00530   }
00531 }
00532 
00533 void KOAgendaItem::addConflictItem( KOAgendaItem *ci )
00534 {
00535   if ( mConflictItems.find( ci ) < 0 ) mConflictItems.append( ci );
00536 }
00537 
00538 QString KOAgendaItem::label() const
00539 {
00540   return mLabelText;
00541 }
00542 
00543 bool KOAgendaItem::overlaps( KOrg::CellItem *o ) const
00544 {
00545   KOAgendaItem *other = static_cast<KOAgendaItem *>( o );
00546 
00547   if ( cellXLeft() <= other->cellXRight() &&
00548        cellXRight() >= other->cellXLeft() ) {
00549     if ( ( cellYTop() <= other->cellYBottom() ) &&
00550          ( cellYBottom() >= other->cellYTop() ) ) {
00551       return true;
00552     }
00553   }
00554 
00555   return false;
00556 }
00557 
00558 void KOAgendaItem::paintFrame( QPainter *p, const QColor &color )
00559 {
00560   p->setPen( color );
00561   p->drawRect( 0, 0, width(), height() );
00562   p->drawRect( 1, 1, width() - 2, height() - 2 );
00563 }
00564 
00565 static void conditionalPaint( QPainter *p, bool cond, int &x, int ft,
00566                               const QPixmap &pxmp )
00567 {
00568   if ( !cond ) return;
00569 
00570   p->drawPixmap( x, ft, pxmp );
00571   x += pxmp.width() + ft;
00572 }
00573 
00574 void KOAgendaItem::paintTodoIcon( QPainter *p, int &x, int ft )
00575 {
00576   static const QPixmap todoPxmp = KOGlobals::self()->smallIcon("todo");
00577   static const QPixmap completedPxmp = KOGlobals::self()->smallIcon("checkedbox");
00578   if ( mIncidence->type() != "Todo" )
00579     return;
00580   bool b = ( static_cast<Todo *>( mIncidence ) )->isCompleted();
00581   conditionalPaint( p, b, x, ft, todoPxmp );
00582   conditionalPaint( p, !b, x, ft, completedPxmp );
00583 }
00584 
00585 void KOAgendaItem::paintEvent( QPaintEvent * )
00586 {
00587   QPainter p( this );
00588   const int ft = 2; // frame thickness for layout, see paintFrame()
00589   const int margin = 1 + ft; // frame + space between frame and content
00590 
00591   static const QPixmap alarmPxmp = KOGlobals::self()->smallIcon("bell");
00592   static const QPixmap recurPxmp = KOGlobals::self()->smallIcon("recur");
00593   static const QPixmap readonlyPxmp = KOGlobals::self()->smallIcon("readonlyevent");
00594   static const QPixmap replyPxmp = KOGlobals::self()->smallIcon("mail_reply");
00595   static const QPixmap groupPxmp = KOGlobals::self()->smallIcon("groupevent");
00596   static const QPixmap organizerPxmp = KOGlobals::self()->smallIcon("organizer");
00597 
00598   QColor bgColor;
00599   if ( (mIncidence->type() == "Todo") &&
00600        ( !((static_cast<Todo*>(mIncidence))->isCompleted()) &&
00601          ((static_cast<Todo*>(mIncidence))->dtDue() < QDate::currentDate()) ) )
00602     bgColor = KOPrefs::instance()->mTodoOverdueColor;
00603   else {
00604     QStringList categories = mIncidence->categories();
00605     QString cat = categories.first();
00606     if (cat.isEmpty())
00607       bgColor = KOPrefs::instance()->mEventColor;
00608     else
00609       bgColor = *(KOPrefs::instance()->categoryColor(cat));
00610   }
00611 
00612   QColor frameColor = mSelected ? QColor( 85 + bgColor.red()*2/3,
00613                                           85 + bgColor.green()*2/3,
00614                                           85 + bgColor.blue()*2/3 )
00615                                 : bgColor.dark(115);
00616   QColor textColor = getTextColor(bgColor);
00617   p.setPen( textColor );
00618   p.setBackgroundColor( bgColor );
00619   p.setFont(KOPrefs::instance()->mAgendaViewFont);
00620   QFontMetrics fm = p.fontMetrics();
00621 
00622   int singleLineHeight = fm.boundingRect( mLabelText ).height();
00623 
00624   // case 1: do not draw text when not even a single line fits
00625   if ( ( singleLineHeight > height() ) || // ignore margin, be gentle..
00626        ( width() < 16 ) ) {
00627     p.eraseRect( 0, 0, width(), height() );
00628     int x = margin;
00629     paintTodoIcon( &p, x, ft );
00630     paintFrame( &p, frameColor );
00631     return;
00632   }
00633 
00634   // Used for multi-day events to make sure the summary is on screen
00635   QRect visRect=visibleRect();
00636 
00637   // case 2: draw a single line when no more space
00638   if ( (2 * singleLineHeight) > (height() - 2 * margin) ) {
00639     p.eraseRect( 0, 0, width(), height() );
00640     int x = margin;
00641     int txtWidth = width() - margin - x;
00642     if (mIncidence->doesFloat() ) {
00643       x += visRect.left();
00644       txtWidth = visRect.right() - margin - x;
00645     }
00646 
00647     paintTodoIcon( &p, x, ft );
00648     int y = ((height() - 2 * ft - singleLineHeight) / 2) + fm.ascent();
00649     KWordWrap::drawFadeoutText( &p, x, y,
00650                                 txtWidth, mLabelText );
00651     paintFrame( &p, frameColor );
00652     return;
00653   }
00654 
00655   KWordWrap *ww = KWordWrap::formatText( fm,
00656                                          QRect(0, 0,
00657                                          width() - (2 * margin), 0),
00658                                          0,
00659                                          mLabelText );
00660   int th = ww->boundingRect().height();
00661   delete ww;
00662 
00663   // calculate the height of the full version (case 4) to test whether it is
00664   // possible
00665   QString shortH;
00666   QString longH;
00667   if ( !isMultiItem() ) {
00668     shortH = KGlobal::locale()->formatTime(mIncidence->dtStart().time());
00669     if (mIncidence->type() != "Todo")
00670       longH = i18n("%1 - %2").arg(shortH)
00671                .arg(KGlobal::locale()->formatTime(mIncidence->dtEnd().time()));
00672     else
00673       longH = shortH;
00674   } else if ( !mMultiItemInfo->mFirstMultiItem ) {
00675     shortH = KGlobal::locale()->formatTime(mIncidence->dtStart().time());
00676     longH = shortH;
00677   } else {
00678     shortH = KGlobal::locale()->formatTime(mIncidence->dtEnd().time());
00679     longH = i18n("- %1").arg(shortH);
00680   }
00681 
00682   int hlHeight = QMAX(fm.boundingRect(longH).height(),
00683      QMAX(alarmPxmp.height(), QMAX(recurPxmp.height(),
00684      QMAX(readonlyPxmp.height(), QMAX(replyPxmp.height(),
00685      QMAX(groupPxmp.height(), organizerPxmp.height()))))));
00686   bool completelyRenderable =
00687     th <= (height() - 2 * ft - hlHeight);
00688 
00689   // case 3: enough for 2-5 lines, but not for the header.
00690   //         Also used for the middle days in multi-events
00691   //         or all-day events
00692   if ( ((!completelyRenderable) &&
00693         ((height() - (2 * margin)) <= (5 * singleLineHeight)) ) ||
00694          (isMultiItem() && mMultiItemInfo->mNextMultiItem && mMultiItemInfo->mFirstMultiItem) ||
00695          mIncidence->doesFloat() ) {
00696     int x = margin;
00697     int txtWidth = width() - margin - x;
00698     if (mIncidence->doesFloat() ) {
00699       x += visRect.left();
00700       txtWidth = visRect.right() - margin - x;
00701     }
00702     ww = KWordWrap::formatText( fm,
00703                                 QRect(x, 0, txtWidth,
00704                                 height() - (2 * margin)),
00705                                 0,
00706                                 mLabelText );
00707     p.eraseRect( 0, 0, width(), height() );
00708     paintTodoIcon( &p, x, ft );
00709     ww->drawText( &p, x, margin, Qt::AlignAuto | KWordWrap::FadeOut );
00710     delete ww;
00711     paintFrame( &p, frameColor );
00712     return;
00713   }
00714 
00715   // case 4: paint everything, with header:
00716   // consists of (vertically) ft + headline&icons + ft + text + margin
00717   int y = 2 * ft + hlHeight;
00718   if ( completelyRenderable )
00719     y += (height() - (2 * ft) - margin - hlHeight - th) / 2;
00720   ww = KWordWrap::formatText( fm,
00721                               QRect(0, 0, width() - (2 * margin),
00722                               height() - margin - y),
00723                               0,
00724                               mLabelText );
00725 
00726   p.eraseRect( 0, 0, width(), height() );
00727 
00728   // paint headline
00729   p.fillRect( 0, 0, width(), (ft/2) + margin + hlHeight,
00730               QBrush( frameColor ) );
00731 
00732   int x = margin;
00733   paintTodoIcon( &p, x, ft );
00734   conditionalPaint( &p, mIconAlarm, x, ft, alarmPxmp );
00735   conditionalPaint( &p, mIconRecur, x, ft, recurPxmp );
00736   conditionalPaint( &p, mIconReadonly, x, ft, readonlyPxmp );
00737   conditionalPaint( &p, mIconReply, x, ft, replyPxmp );
00738   conditionalPaint( &p, mIconGroup, x, ft, groupPxmp );
00739   conditionalPaint( &p, mIconOrganizer, x, ft, organizerPxmp );
00740 
00741   QString headline;
00742   int hw = fm.boundingRect( longH ).width();
00743   if ( hw > (width() - x - margin) ) {
00744     headline = shortH;
00745     hw = fm.boundingRect( shortH ).width();
00746     if ( hw < (width() - x - margin) )
00747       x += (width() - x - margin - hw) / 2;
00748     else
00749       headline = "";
00750   } else {
00751     headline = longH;
00752     x += (width() - x - margin - hw) / 2;
00753   }
00754   p.setBackgroundColor( frameColor );
00755   p.setPen( getTextColor( frameColor ) );
00756   KWordWrap::drawFadeoutText( &p, x, ft + fm.ascent(),
00757                               width() - margin - x, headline );
00758 
00759   // draw event text
00760   p.setBackgroundColor( bgColor );
00761   p.setPen( textColor );
00762   QString ws = ww->wrappedString();
00763   if ( ws.left( ws.length()-1 ).find( '\n' ) >= 0 )
00764     ww->drawText( &p, margin, y,
00765                   Qt::AlignAuto | KWordWrap::FadeOut );
00766   else
00767     ww->drawText( &p, margin + (width()-ww->boundingRect().width()-2*margin)/2,
00768                   y, Qt::AlignHCenter | KWordWrap::FadeOut );
00769   delete ww;
00770   paintFrame( &p, frameColor );
00771 }
00772 
00773 
KDE Logo
This file is part of the documentation for korganizer Library Version 3.2.1.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Sat Mar 6 17:18:31 2004 by doxygen 1.3.6-20040222 written by Dimitri van Heesch, © 1997-2003