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 <tdelocale.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( TDEGlobalSettings::textColor() ); //border 00272 p->setBrush( TDEGlobalSettings::baseColor() ); //filling 00273 p->drawRect( 2, 2, width-4, height()-4); 00274 p->fillRect( 3, 3, progress, height()-6, 00275 TDEGlobalSettings::highlightColor() ); 00276 p->restore(); 00277 } else { 00278 TQCheckListItem::paintCell(p, _cg, column, width, alignment); 00279 } 00280 }