/* Copyright (C) 2010 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.net, author Tobias Koenig This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "taskthreadgroupercomparator.h" #include "settings.h" #include #include TaskThreadGrouperComparator::TaskThreadGrouperComparator() { } TaskThreadGrouperComparator::~TaskThreadGrouperComparator() { } QByteArray TaskThreadGrouperComparator::identifierForItem( const Akonadi::Item &item ) const { Q_ASSERT( item.hasPayload() ); const KCalCore::Todo::Ptr todo = item.payload(); QByteArray identifier = todo->uid().toLatin1(); if ( identifier.isEmpty() ) identifier = QByteArray::number( item.id() ); return identifier; } QByteArray TaskThreadGrouperComparator::parentIdentifierForItem( const Akonadi::Item &item ) const { Q_ASSERT( item.hasPayload() ); const KCalCore::Todo::Ptr todo = item.payload(); return todo->relatedTo( KCalCore::Todo::RelTypeParent ).toLatin1(); } bool TaskThreadGrouperComparator::lessThan( const Akonadi::Item &leftItem, const Akonadi::Item &rightItem ) const { Q_ASSERT( leftItem.isValid() ); Q_ASSERT( rightItem.isValid() ); const Akonadi::Item leftThreadRootItem = threadItem( leftItem ); const Akonadi::Item rightThreadRootItem = threadItem( rightItem ); Q_ASSERT( rightThreadRootItem.isValid() ); Q_ASSERT( leftThreadRootItem.isValid() ); const bool leftItemIsThreadLeader = (leftThreadRootItem == leftItem); const bool rightItemIsThreadLeader = (rightThreadRootItem == rightItem); if ( leftItemIsThreadLeader && rightItemIsThreadLeader ) { const KCalCore::Todo::Ptr leftTodo = CalendarSupport::todo( leftThreadRootItem ); const KCalCore::Todo::Ptr rightTodo = CalendarSupport::todo( rightThreadRootItem ); if ( !leftTodo || !rightTodo ) { kDebug() << "This shouldn't happen, but i didn't check. Better safe than sorry."; return false; } const bool leftCompleted = leftTodo->isCompleted(); const bool rightCompleted = rightTodo->isCompleted(); const int leftPriority = leftTodo->priority(); const int rightPriority = rightTodo->priority(); if ( Settings::self()->showCompletedTodosAtBottom() && leftCompleted != rightCompleted ) { return rightCompleted; } if ( leftPriority != rightPriority ) { // higher priority first. ( Also note that 9 is low, and 1 is high ) return leftPriority < rightPriority; } else { // lower id first return leftItem.id() < rightItem.id(); } return leftThreadRootItem.id() < rightThreadRootItem.id(); } else if ( leftItemIsThreadLeader && !rightItemIsThreadLeader ) { if ( leftThreadRootItem == rightThreadRootItem ) return true; // right item is in thread of left thread leader -> right item located below left item else return lessThan( leftThreadRootItem, rightThreadRootItem ); // based on thread leaders order } else if ( !leftItemIsThreadLeader && rightItemIsThreadLeader ) { if ( leftThreadRootItem == rightThreadRootItem ) return false; // left item is in thread of right thread leader -> left item must be located below right item else return lessThan( leftThreadRootItem, rightThreadRootItem ); // based on thread leaders order } else if ( !leftItemIsThreadLeader && !rightItemIsThreadLeader ) { if ( leftThreadRootItem == rightThreadRootItem ) // both in the same thread return leftItem.id() < rightItem.id(); // default else return lessThan( leftThreadRootItem, rightThreadRootItem ); // based on thread leaders order } return leftItem.id() < rightItem.id(); // default }