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 TQt, and distribute the resulting executable,
00024     without including the source code for TQt 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 void KOTodoViewItem::paintBranches(TQPainter *p,const TQColorGroup & cg,int w,
00123                                    int y,int h)
00124 {
00125   TQListViewItem::paintBranches(p,cg,w,y,h);
00126 }
00127 
00128 void KOTodoViewItem::construct()
00129 {
00130   if ( !mTodo ) return;
00131   m_init = true;
00132 
00133   setOn( mTodo->isCompleted() );
00134   setText( KOTodoView::eSummaryColumn, mTodo->summary());
00135   static const TQPixmap recurPxmp = KOGlobals::self()->smallIcon("recur");
00136   if ( mTodo->doesRecur() )
00137     setPixmap( KOTodoView::eRecurColumn, recurPxmp );
00138 
00139   if ( mTodo->priority()==0 ) {
00140     setText( KOTodoView::ePriorityColumn, i18n("--") );
00141   } else {
00142     setText( KOTodoView::ePriorityColumn, TQString::number(mTodo->priority()) );
00143   }
00144   setText( KOTodoView::ePercentColumn, TQString::number(mTodo->percentComplete()) );
00145 
00146   if (mTodo->hasDueDate()) {
00147     TQString dtStr = mTodo->dtDueDateStr();
00148     if (!mTodo->doesFloat()) {
00149       dtStr += " " + mTodo->dtDueTimeStr();
00150     }
00151     setText( KOTodoView::eDueDateColumn, dtStr );
00152     mEffectiveDueDate = mTodo->dtDue();
00153     KOTodoViewItem *myParent;
00154     if ( ( myParent = dynamic_cast<KOTodoViewItem *>( parent() ) ) )
00155       if ( !myParent->mEffectiveDueDate.isValid() ||
00156           myParent->mEffectiveDueDate > mEffectiveDueDate ) {
00157         myParent->mEffectiveDueDate = mEffectiveDueDate;
00158       }
00159   } else
00160     setText( KOTodoView::eDueDateColumn, "" );
00161 
00162   setText( KOTodoView::eCategoriesColumn, mTodo->categoriesStr() );
00163 
00164   setText( KOTodoView::eFolderColumn,
00165            IncidenceFormatter::resourceString( mTodoView->calendar(), mTodo ) );
00166 
00167 #if 0
00168   // Find sort id in description. It's the text behind the last '#' character
00169   // found in the description. White spaces are removed from beginning and end
00170   // of sort id.
00171   int pos = mTodo->description().findRev('#');
00172   if (pos < 0) {
00173     setText( KOTodoView::eDescriptionColumn, "" );
00174   } else {
00175     TQString str = mTodo->description().mid(pos+1);
00176     str.stripWhiteSpace();
00177     setText( KOTodoView::eDescriptionColumn, str );
00178   }
00179 #endif
00180 
00181   m_known = false;
00182   m_init = false;
00183 }
00184 
00185 void KOTodoViewItem::stateChange( bool state )
00186 {
00187   // do not change setting on startup or if no valid todo item is given
00188   if ( m_init || !mTodo ) return;
00189 
00190   if ( mTodo->isReadOnly() ) {
00191     setOn( mTodo->isCompleted() );
00192     return;
00193   }
00194 
00195   kdDebug(5850) << "State changed, modified " << state << endl;
00196   mTodoView->setNewPercentageDelayed( this, state ? 100 : 0 );
00197 }
00198 
00199 bool KOTodoViewItem::isAlternate()
00200 {
00201 #ifndef KORG_NOLVALTERNATION
00202   KOTodoListView *lv = static_cast<KOTodoListView *>(listView());
00203   if (lv && lv->alternateBackground().isValid())
00204   {
00205     KOTodoViewItem *above = 0;
00206     above = dynamic_cast<KOTodoViewItem *>(itemAbove());
00207     m_known = above ? above->m_known : true;
00208     if (m_known)
00209     {
00210        m_odd = above ? !above->m_odd : false;
00211     }
00212     else
00213     {
00214        KOTodoViewItem *item;
00215        bool previous = true;
00216        if (TQListViewItem::parent())
00217        {
00218           item = dynamic_cast<KOTodoViewItem *>(TQListViewItem::parent());
00219           if (item)
00220              previous = item->m_odd;
00221           item = dynamic_cast<KOTodoViewItem *>(TQListViewItem::parent()->firstChild());
00222        }
00223        else
00224        {
00225           item = dynamic_cast<KOTodoViewItem *>(lv->firstChild());
00226        }
00227 
00228        while(item)
00229        {
00230           item->m_odd = previous = !previous;
00231           item->m_known = true;
00232           item = dynamic_cast<KOTodoViewItem *>(item->nextSibling());
00233        }
00234     }
00235     return m_odd;
00236   }
00237   return false;
00238 #else
00239   return false;
00240 #endif
00241 }
00242 
00243 void KOTodoViewItem::paintCell(TQPainter *p, const TQColorGroup &cg, int column, int width, int alignment)
00244 {
00245   TQColorGroup _cg = cg;
00246   // If no todo is set, just don't paint anything...
00247   if ( !mTodo ) return;
00248 #ifndef KORG_NOLVALTERNATION
00249   if (isAlternate())
00250         _cg.setColor(TQColorGroup::Base, static_cast< KOTodoListView* >(listView())->alternateBackground());
00251   if (mTodo->hasDueDate()) {
00252     if (mTodo->dtDue().date()==TQDate::currentDate() &&
00253         !mTodo->isCompleted()) {
00254       _cg.setColor(TQColorGroup::Base, KOPrefs::instance()->mTodoDueTodayColor);
00255       _cg.setColor(TQColorGroup::Text, getTextColor(KOPrefs::instance()->mTodoDueTodayColor));
00256     }
00257     if (mTodo->dtDue().date() < TQDate::currentDate() &&
00258         !mTodo->isCompleted()) {
00259       _cg.setColor(TQColorGroup::Base, KOPrefs::instance()->mTodoOverdueColor);
00260       _cg.setColor(TQColorGroup::Text, getTextColor(KOPrefs::instance()->mTodoOverdueColor));
00261     }
00262   }
00263 #endif
00264 
00265   // show the progess by a horizontal bar
00266   if ( column == KOTodoView::ePercentColumn ) {
00267     p->save();
00268     int progress = (int)(( (width-6)*mTodo->percentComplete())/100.0 + 0.5);
00269 
00270     p->fillRect( 0, 0, width, height(), _cg.base() ); // background
00271     p->setPen( KGlobalSettings::textColor() );  //border
00272     p->setBrush( KGlobalSettings::baseColor() );  //filling
00273     p->drawRect( 2, 2, width-4, height()-4);
00274     p->fillRect( 3, 3, progress, height()-6,
00275         KGlobalSettings::highlightColor() );
00276     p->restore();
00277   } else {
00278     TQCheckListItem::paintCell(p, _cg, column, width, alignment);
00279   }
00280 }