korganizer

kotodoviewitem.cpp

00001 /*
00002     This file is part of KOrganizer.
00003 
00004     Copyright (c) 2000,2001 Cornelius Schumacher <schumacher@kde.org>
00005     Copyright (C) 2003-2004 Reinhold Kainhofer <reinhold@kainhofer.com>
00006     Copyright (c) 2005 Rafal Rzepecki <divide@users.sourceforge.net>
00007 
00008     This program is free software; you can redistribute it and/or modify
00009     it under the terms of the GNU General Public License as published by
00010     the Free Software Foundation; either version 2 of the License, or
00011     (at your option) any later version.
00012 
00013     This program is distributed in the hope that it will be useful,
00014     but WITHOUT ANY WARRANTY; without even the implied warranty of
00015     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
00016     GNU General Public License for more details.
00017 
00018     You should have received a copy of the GNU General Public License
00019     along with this program; if not, write to the Free Software
00020     Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00021 
00022     As a special exception, permission is given to link this program
00023     with any edition of Qt, and distribute the resulting executable,
00024     without including the source code for Qt in the source distribution.
00025 */
00026 
00027 #include "kotodoviewitem.h"
00028 #include "kotodoview.h"
00029 #include "koprefs.h"
00030 #include "koglobals.h"
00031 
00032 #include <libkcal/incidenceformatter.h>
00033 
00034 #include <klocale.h>
00035 #include <kdebug.h>
00036 #include <tqpainter.h>
00037 #include <tqpixmap.h>
00038 
00039 #include <tqpainter.h>
00040 
00041 KOTodoViewItem::KOTodoViewItem( TQListView *parent, Todo *todo, KOTodoView *kotodo)
00042   : TQCheckListItem( parent , "", CheckBox ), mTodo( todo ), mTodoView( kotodo )
00043 {
00044   construct();
00045 }
00046 
00047 KOTodoViewItem::KOTodoViewItem( KOTodoViewItem *parent, Todo *todo, KOTodoView *kotodo )
00048   : TQCheckListItem( parent, "", CheckBox ), mTodo( todo ), mTodoView( kotodo )
00049 {
00050   construct();
00051 }
00052 
00053 inline int KOTodoViewItem::compareDueDates( const KOTodoViewItem *b ) const
00054 {
00055   if ( mEffectiveDueDate.isValid() &&
00056        !b->mEffectiveDueDate.isValid() )
00057     return -1;
00058   else if ( !mEffectiveDueDate.isValid() &&
00059             b->mEffectiveDueDate.isValid() )
00060     return 1;
00061   else
00062     return b->mEffectiveDueDate.secsTo( mEffectiveDueDate );
00063 }
00064 
00065 int KOTodoViewItem::compare( TQListViewItem *it, int col, bool ascending ) const
00066 {
00067   KOTodoViewItem *i = dynamic_cast<KOTodoViewItem *>( it );
00068   if ( !i ) {
00069     return TQListViewItem::compare( it, col, ascending );
00070   }
00071 
00072   // throw completed todos to the bottom
00073   if ( mTodo->isCompleted() && !i->todo()->isCompleted() ) {
00074     return ascending ? 1 : -1;
00075   } else if ( !mTodo->isCompleted() && i->todo()->isCompleted() ) {
00076     return ascending ? -1 : 1;
00077   }
00078 
00079   int c;
00080   switch ( col ) {
00081   case KOTodoView::eSummaryColumn:
00082     return mTodo->summary().localeAwareCompare( i->todo()->summary() );
00083 
00084   case KOTodoView::eRecurColumn:
00085     return ( mTodo->doesRecur() ? 1 : 0 ) - ( i->todo()->doesRecur() ? 1 : 0 );
00086 
00087   case KOTodoView::ePriorityColumn:
00088     c = mTodo->priority() - i->todo()->priority();
00089     if ( c ) {
00090       return c;
00091     } else {
00092       return compareDueDates( i );
00093     }
00094 
00095   case KOTodoView::ePercentColumn:
00096     return mTodo->percentComplete() - i->todo()->percentComplete();
00097 
00098   case KOTodoView::eDueDateColumn:
00099     c = compareDueDates( i );
00100     if ( c ) {
00101       return c;
00102     } else {
00103       return mTodo->priority() - i->todo()->priority();
00104     }
00105   case KOTodoView::eCategoriesColumn:
00106     return mTodo->categoriesStr().localeAwareCompare( i->todo()->categoriesStr() );
00107 
00108   case KOTodoView::eFolderColumn:
00109     return TQListViewItem::compare( it, col, ascending );
00110 
00111 #if 0
00112   case KOTodoView::eDescriptionColumn:
00113     return mTodo->description().localeAwareCompare( i->todo()->description() );
00114 #endif
00115 
00116   default:
00117     Q_ASSERT( false && "unknown column to compare" );
00118     return TQListViewItem::compare( it, col, ascending );
00119   }
00120 }
00121 
00122 #if QT_VERSION >= 300
00123 void KOTodoViewItem::paintBranches(TQPainter *p,const TQColorGroup & cg,int w,
00124                                    int y,int h)
00125 {
00126   TQListViewItem::paintBranches(p,cg,w,y,h);
00127 }
00128 #else
00129 #endif
00130 
00131 void KOTodoViewItem::construct()
00132 {
00133   if ( !mTodo ) return;
00134   m_init = true;
00135 
00136   setOn( mTodo->isCompleted() );
00137   setText( KOTodoView::eSummaryColumn, mTodo->summary());
00138   static const TQPixmap recurPxmp = KOGlobals::self()->smallIcon("recur");
00139   if ( mTodo->doesRecur() )
00140     setPixmap( KOTodoView::eRecurColumn, recurPxmp );
00141 
00142   if ( mTodo->priority()==0 ) {
00143     setText( KOTodoView::ePriorityColumn, i18n("--") );
00144   } else {
00145     setText( KOTodoView::ePriorityColumn, TQString::number(mTodo->priority()) );
00146   }
00147   setText( KOTodoView::ePercentColumn, TQString::number(mTodo->percentComplete()) );
00148 
00149   if (mTodo->hasDueDate()) {
00150     TQString dtStr = mTodo->dtDueDateStr();
00151     if (!mTodo->doesFloat()) {
00152       dtStr += " " + mTodo->dtDueTimeStr();
00153     }
00154     setText( KOTodoView::eDueDateColumn, dtStr );
00155     mEffectiveDueDate = mTodo->dtDue();
00156     KOTodoViewItem *myParent;
00157     if ( ( myParent = dynamic_cast<KOTodoViewItem *>( parent() ) ) )
00158       if ( !myParent->mEffectiveDueDate.isValid() ||
00159           myParent->mEffectiveDueDate > mEffectiveDueDate ) {
00160         myParent->mEffectiveDueDate = mEffectiveDueDate;
00161       }
00162   } else
00163     setText( KOTodoView::eDueDateColumn, "" );
00164 
00165   setText( KOTodoView::eCategoriesColumn, mTodo->categoriesStr() );
00166 
00167   setText( KOTodoView::eFolderColumn,
00168            IncidenceFormatter::resourceString( mTodoView->calendar(), mTodo ) );
00169 
00170 #if 0
00171   // Find sort id in description. It's the text behind the last '#' character
00172   // found in the description. White spaces are removed from beginning and end
00173   // of sort id.
00174   int pos = mTodo->description().findRev('#');
00175   if (pos < 0) {
00176     setText( KOTodoView::eDescriptionColumn, "" );
00177   } else {
00178     TQString str = mTodo->description().mid(pos+1);
00179     str.stripWhiteSpace();
00180     setText( KOTodoView::eDescriptionColumn, str );
00181   }
00182 #endif
00183 
00184   m_known = false;
00185   m_init = false;
00186 }
00187 
00188 void KOTodoViewItem::stateChange( bool state )
00189 {
00190   // do not change setting on startup or if no valid todo item is given
00191   if ( m_init || !mTodo ) return;
00192 
00193   if ( mTodo->isReadOnly() ) {
00194     setOn( mTodo->isCompleted() );
00195     return;
00196   }
00197 
00198   kdDebug(5850) << "State changed, modified " << state << endl;
00199   mTodoView->setNewPercentageDelayed( this, state ? 100 : 0 );
00200 }
00201 
00202 bool KOTodoViewItem::isAlternate()
00203 {
00204 #ifndef KORG_NOLVALTERNATION
00205   KOTodoListView *lv = static_cast<KOTodoListView *>(listView());
00206   if (lv && lv->alternateBackground().isValid())
00207   {
00208     KOTodoViewItem *above = 0;
00209     above = dynamic_cast<KOTodoViewItem *>(itemAbove());
00210     m_known = above ? above->m_known : true;
00211     if (m_known)
00212     {
00213        m_odd = above ? !above->m_odd : false;
00214     }
00215     else
00216     {
00217        KOTodoViewItem *item;
00218        bool previous = true;
00219        if (TQListViewItem::parent())
00220        {
00221           item = dynamic_cast<KOTodoViewItem *>(TQListViewItem::parent());
00222           if (item)
00223              previous = item->m_odd;
00224           item = dynamic_cast<KOTodoViewItem *>(TQListViewItem::parent()->firstChild());
00225        }
00226        else
00227        {
00228           item = dynamic_cast<KOTodoViewItem *>(lv->firstChild());
00229        }
00230 
00231        while(item)
00232        {
00233           item->m_odd = previous = !previous;
00234           item->m_known = true;
00235           item = dynamic_cast<KOTodoViewItem *>(item->nextSibling());
00236        }
00237     }
00238     return m_odd;
00239   }
00240   return false;
00241 #else
00242   return false;
00243 #endif
00244 }
00245 
00246 void KOTodoViewItem::paintCell(TQPainter *p, const TQColorGroup &cg, int column, int width, int alignment)
00247 {
00248   TQColorGroup _cg = cg;
00249   // If no todo is set, just don't paint anything...
00250   if ( !mTodo ) return;
00251 #ifndef KORG_NOLVALTERNATION
00252   if (isAlternate())
00253         _cg.setColor(TQColorGroup::Base, static_cast< KOTodoListView* >(listView())->alternateBackground());
00254   if (mTodo->hasDueDate()) {
00255     if (mTodo->dtDue().date()==TQDate::currentDate() &&
00256         !mTodo->isCompleted()) {
00257       _cg.setColor(TQColorGroup::Base, KOPrefs::instance()->mTodoDueTodayColor);
00258       _cg.setColor(TQColorGroup::Text, getTextColor(KOPrefs::instance()->mTodoDueTodayColor));
00259     }
00260     if (mTodo->dtDue().date() < TQDate::currentDate() &&
00261         !mTodo->isCompleted()) {
00262       _cg.setColor(TQColorGroup::Base, KOPrefs::instance()->mTodoOverdueColor);
00263       _cg.setColor(TQColorGroup::Text, getTextColor(KOPrefs::instance()->mTodoOverdueColor));
00264     }
00265   }
00266 #endif
00267 
00268   // show the progess by a horizontal bar
00269   if ( column == KOTodoView::ePercentColumn ) {
00270     p->save();
00271     int progress = (int)(( (width-6)*mTodo->percentComplete())/100.0 + 0.5);
00272 
00273     p->fillRect( 0, 0, width, height(), _cg.base() ); // background
00274     p->setPen( KGlobalSettings::textColor() );  //border
00275     p->setBrush( KGlobalSettings::baseColor() );  //filling
00276     p->drawRect( 2, 2, width-4, height()-4);
00277     p->fillRect( 3, 3, progress, height()-6,
00278         KGlobalSettings::highlightColor() );
00279     p->restore();
00280   } else {
00281     TQCheckListItem::paintCell(p, _cg, column, width, alignment);
00282   }
00283 }