/* This file is part of KOrganizer. Copyright (c) 2000,2001 Cornelius Schumacher <schumacher@kde.org> Copyright (C) 2003-2004 Reinhold Kainhofer <reinhold@kainhofer.com> Copyright (c) 2005 Rafal Rzepecki <divide@users.sourceforge.net> This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. As a special exception, permission is given to link this program with any edition of TQt, and distribute the resulting executable, without including the source code for TQt in the source distribution. */ #include "kotodoviewitem.h" #include "kotodoview.h" #include "koprefs.h" #include "koglobals.h" #include <libkcal/incidenceformatter.h> #include <tdelocale.h> #include <kdebug.h> #include <tqpainter.h> #include <tqpixmap.h> #include <tqpainter.h> KOTodoViewItem::KOTodoViewItem( TQListView *parent, Todo *todo, KOTodoView *kotodo) : TQCheckListItem( parent , "", CheckBox ), mTodo( todo ), mTodoView( kotodo ) { construct(); } KOTodoViewItem::KOTodoViewItem( KOTodoViewItem *parent, Todo *todo, KOTodoView *kotodo ) : TQCheckListItem( parent, "", CheckBox ), mTodo( todo ), mTodoView( kotodo ) { construct(); } inline int KOTodoViewItem::compareDueDates( const KOTodoViewItem *b ) const { if ( mEffectiveDueDate.isValid() && !b->mEffectiveDueDate.isValid() ) return -1; else if ( !mEffectiveDueDate.isValid() && b->mEffectiveDueDate.isValid() ) return 1; else return b->mEffectiveDueDate.secsTo( mEffectiveDueDate ); } int KOTodoViewItem::compare( TQListViewItem *it, int col, bool ascending ) const { KOTodoViewItem *i = dynamic_cast<KOTodoViewItem *>( it ); if ( !i ) { return TQListViewItem::compare( it, col, ascending ); } // throw completed todos to the bottom if ( mTodo->isCompleted() && !i->todo()->isCompleted() ) { return ascending ? 1 : -1; } else if ( !mTodo->isCompleted() && i->todo()->isCompleted() ) { return ascending ? -1 : 1; } int c; switch ( col ) { case KOTodoView::eSummaryColumn: return mTodo->summary().localeAwareCompare( i->todo()->summary() ); case KOTodoView::eRecurColumn: return ( mTodo->doesRecur() ? 1 : 0 ) - ( i->todo()->doesRecur() ? 1 : 0 ); case KOTodoView::ePriorityColumn: c = mTodo->priority() - i->todo()->priority(); if ( c ) { return c; } else { return compareDueDates( i ); } case KOTodoView::ePercentColumn: return mTodo->percentComplete() - i->todo()->percentComplete(); case KOTodoView::eDueDateColumn: c = compareDueDates( i ); if ( c ) { return c; } else { return mTodo->priority() - i->todo()->priority(); } case KOTodoView::eCategoriesColumn: return mTodo->categoriesStr().localeAwareCompare( i->todo()->categoriesStr() ); case KOTodoView::eFolderColumn: return TQListViewItem::compare( it, col, ascending ); #if 0 case KOTodoView::eDescriptionColumn: return mTodo->description().localeAwareCompare( i->todo()->description() ); #endif default: Q_ASSERT( false && "unknown column to compare" ); return TQListViewItem::compare( it, col, ascending ); } } void KOTodoViewItem::paintBranches(TQPainter *p,const TQColorGroup & cg,int w, int y,int h) { TQListViewItem::paintBranches(p,cg,w,y,h); } void KOTodoViewItem::construct() { if ( !mTodo ) return; m_init = true; setOn( mTodo->isCompleted() ); setText( KOTodoView::eSummaryColumn, mTodo->summary()); static const TQPixmap recurPxmp = KOGlobals::self()->smallIcon("recur"); if ( mTodo->doesRecur() ) setPixmap( KOTodoView::eRecurColumn, recurPxmp ); if ( mTodo->priority()==0 ) { setText( KOTodoView::ePriorityColumn, i18n("--") ); } else { setText( KOTodoView::ePriorityColumn, TQString::number(mTodo->priority()) ); } setText( KOTodoView::ePercentColumn, TQString::number(mTodo->percentComplete()) ); if (mTodo->hasDueDate()) { TQString dtStr = mTodo->dtDueDateStr(); if (!mTodo->doesFloat()) { dtStr += " " + mTodo->dtDueTimeStr(); } setText( KOTodoView::eDueDateColumn, dtStr ); mEffectiveDueDate = mTodo->dtDue(); KOTodoViewItem *myParent; if ( ( myParent = dynamic_cast<KOTodoViewItem *>( parent() ) ) ) if ( !myParent->mEffectiveDueDate.isValid() || myParent->mEffectiveDueDate > mEffectiveDueDate ) { myParent->mEffectiveDueDate = mEffectiveDueDate; } } else setText( KOTodoView::eDueDateColumn, "" ); setText( KOTodoView::eCategoriesColumn, mTodo->categoriesStr() ); setText( KOTodoView::eFolderColumn, IncidenceFormatter::resourceString( mTodoView->calendar(), mTodo ) ); #if 0 // Find sort id in description. It's the text behind the last '#' character // found in the description. White spaces are removed from beginning and end // of sort id. int pos = mTodo->description().findRev('#'); if (pos < 0) { setText( KOTodoView::eDescriptionColumn, "" ); } else { TQString str = mTodo->description().mid(pos+1); str.stripWhiteSpace(); setText( KOTodoView::eDescriptionColumn, str ); } #endif m_known = false; m_init = false; } void KOTodoViewItem::stateChange( bool state ) { // do not change setting on startup or if no valid todo item is given if ( m_init || !mTodo ) return; if ( mTodo->isReadOnly() ) { setOn( mTodo->isCompleted() ); return; } kdDebug(5850) << "State changed, modified " << state << endl; mTodoView->setNewPercentageDelayed( this, state ? 100 : 0 ); } bool KOTodoViewItem::isAlternate() { #ifndef KORG_NOLVALTERNATION KOTodoListView *lv = static_cast<KOTodoListView *>(listView()); if (lv && lv->alternateBackground().isValid()) { KOTodoViewItem *above = 0; above = dynamic_cast<KOTodoViewItem *>(itemAbove()); m_known = above ? above->m_known : true; if (m_known) { m_odd = above ? !above->m_odd : false; } else { KOTodoViewItem *item; bool previous = true; if (TQListViewItem::parent()) { item = dynamic_cast<KOTodoViewItem *>(TQListViewItem::parent()); if (item) previous = item->m_odd; item = dynamic_cast<KOTodoViewItem *>(TQListViewItem::parent()->firstChild()); } else { item = dynamic_cast<KOTodoViewItem *>(lv->firstChild()); } while(item) { item->m_odd = previous = !previous; item->m_known = true; item = dynamic_cast<KOTodoViewItem *>(item->nextSibling()); } } return m_odd; } return false; #else return false; #endif } void KOTodoViewItem::paintCell(TQPainter *p, const TQColorGroup &cg, int column, int width, int alignment) { TQColorGroup _cg = cg; // If no todo is set, just don't paint anything... if ( !mTodo ) return; #ifndef KORG_NOLVALTERNATION if (isAlternate()) _cg.setColor(TQColorGroup::Base, static_cast< KOTodoListView* >(listView())->alternateBackground()); if (mTodo->hasDueDate()) { if (mTodo->dtDue().date()==TQDate::currentDate() && !mTodo->isCompleted()) { _cg.setColor(TQColorGroup::Base, KOPrefs::instance()->mTodoDueTodayColor); _cg.setColor(TQColorGroup::Text, getTextColor(KOPrefs::instance()->mTodoDueTodayColor)); } if (mTodo->dtDue().date() < TQDate::currentDate() && !mTodo->isCompleted()) { _cg.setColor(TQColorGroup::Base, KOPrefs::instance()->mTodoOverdueColor); _cg.setColor(TQColorGroup::Text, getTextColor(KOPrefs::instance()->mTodoOverdueColor)); } } #endif // show the progess by a horizontal bar if ( column == KOTodoView::ePercentColumn ) { p->save(); int progress = (int)(( (width-6)*mTodo->percentComplete())/100.0 + 0.5); p->fillRect( 0, 0, width, height(), _cg.base() ); // background p->setPen( TDEGlobalSettings::textColor() ); //border p->setBrush( TDEGlobalSettings::baseColor() ); //filling p->drawRect( 2, 2, width-4, height()-4); p->fillRect( 3, 3, progress, height()-6, TDEGlobalSettings::highlightColor() ); p->restore(); } else { TQCheckListItem::paintCell(p, _cg, column, width, alignment); } }