Introduced styles - first version of Widgets
[opentodolist:opentodolist.git] / OpenTodoListCore / todosortfiltermodel.cpp
1 /*
2  *  OpenTodoList - A todo and task manager
3  *  Copyright (C) 2013  Martin Höher <martin@rpdev.net>
4  *
5  *  This program is free software: you can redistribute it and/or modify
6  *  it under the terms of the GNU General Public License as published by
7  *  the Free Software Foundation, either version 3 of the License, or
8  *  (at your option) any later version.
9  *
10  *  This program is distributed in the hope that it will be useful,
11  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  *  GNU General Public License for more details.
14  *
15  *  You should have received a copy of the GNU General Public License
16  *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
17  */
18
19 #include "todosortfiltermodel.h"
20
21 #include "abstracttodo.h"
22
23 TodoSortFilterModel::TodoSortFilterModel(QObject* parent): 
24     QSortFilterProxyModel(parent),
25     m_filterMode( NoFilter ),
26     m_sortMode( NoSort ),
27     m_parentTodo( 0 ),
28     m_searchString( QString() ),
29     m_maxDueDate( QDateTime() ),
30     m_minDueDate( QDateTime() )
31 {
32     setDynamicSortFilter( true );
33     sort( 0, Qt::AscendingOrder );
34     connect( this, SIGNAL(rowsInserted(QModelIndex,int,int)),
35              this, SIGNAL(itemCountChanged()) );
36     connect( this, SIGNAL(rowsRemoved(QModelIndex,int,int)),
37              this, SIGNAL(itemCountChanged()) );
38     connect( this, SIGNAL(modelReset()),
39              this, SIGNAL(itemCountChanged()) );
40     connect( this, SIGNAL(layoutChanged()),
41              this, SIGNAL(itemCountChanged()) );
42 }
43
44 void TodoSortFilterModel::setSourceModel(TodoSortFilterModel::TodoModel* sourceModel)
45 {
46     QSortFilterProxyModel::setSourceModel( sourceModel );
47     emit sourceModelChanged();
48 }
49
50 void TodoSortFilterModel::setSourceModel(TodoSortFilterModel* sourceModel)
51 {
52     QSortFilterProxyModel::setSourceModel( sourceModel );
53     emit sourceModelChanged();
54 }
55
56 void TodoSortFilterModel::setSourceModel(QObject *sourceModel)
57 {
58     QSortFilterProxyModel::setSourceModel(
59                 qobject_cast< QAbstractItemModel* >( sourceModel ) );
60     emit sourceModelChanged();
61 }
62
63 void TodoSortFilterModel::setParentTodo(AbstractTodo* todo)
64 {
65     if ( m_filterMode == SubTodos ) {
66         emit beginResetModel();
67         m_parentTodo = todo;
68         emit endResetModel();
69     } else {
70         m_parentTodo = todo;
71     }
72 }
73
74 QVariantMap TodoSortFilterModel::getItem(int index) const
75 {
76     QVariantMap result;
77     const QHash<int, QByteArray> &roles = this->roleNames();
78     foreach ( int key, roles.keys() ) {
79         result.insert( roles.value( key ), this->index( index, 0 ).data( key ) );
80     }
81     return result;
82 }
83
84 bool TodoSortFilterModel::filterAcceptsRow(int source_row, const QModelIndex& source_parent) const
85 {
86     bool result = QSortFilterProxyModel::filterAcceptsRow(source_row, source_parent);
87     AbstractTodo* todo = qobject_cast< AbstractTodo* >(
88                 sourceModel()->index( source_row, 0 ).data(
89                     TodoModel::ObjectRole ).value< QObject* >() );
90     if ( todo ) {
91         if ( !m_searchString.isEmpty() ) {
92             if ( !(todo->title().contains( m_searchString, Qt::CaseInsensitive ) ||
93                  todo->description().contains( m_searchString, Qt::CaseInsensitive )) ) {
94                 result = false;
95             }
96         }
97         if ( m_maxDueDate.isValid() ) {
98             result = !todo->isCompleted() && todo->dueDate().isValid() &&
99                     todo->dueDate().daysTo( m_maxDueDate ) >= 0;
100         }
101         if ( m_minDueDate.isValid() ) {
102             result = !todo->isCompleted() && todo->dueDate().isValid() &&
103                     todo->dueDate().daysTo( m_minDueDate ) <= 0;
104         }
105         if ( m_filterMode & TodoListEntries ) {
106             result = !todo->parentTodo() ? result : false;
107         }
108         if ( m_filterMode & SubTodos ) {
109             result = todo->parentTodo() == m_parentTodo ? result : false;
110         }
111         if ( m_filterMode & HideDeleted ) {
112             result = todo->isDeleted() ? false : result;
113         }
114         if ( m_filterMode & HideNonDeleted ) {
115             result = todo->isDeleted() ? result : false;
116         }
117     }
118     return result;
119 }
120
121 bool TodoSortFilterModel::lessThan(const QModelIndex& left, const QModelIndex& right) const
122 {
123     if ( m_sortMode != NoSort ) {
124         AbstractTodo* leftTodo = qobject_cast< AbstractTodo* >(
125                     left.data( TodoModel::ObjectRole ).value<QObject*>());
126         AbstractTodo* rightTodo = qobject_cast< AbstractTodo* >(
127                     right.data( TodoModel::ObjectRole ).value< QObject* >());
128         if ( leftTodo && rightTodo ) {
129             if ( leftTodo->isCompleted() && !rightTodo->isCompleted() ) {
130                 return false;
131             }
132             if ( !leftTodo->isCompleted() && rightTodo->isCompleted() ) {
133                 return true;
134             }
135             switch ( m_sortMode ) {
136             case PrioritySort:
137                 return leftTodo->priority() > rightTodo->priority();
138             case ProgressSort:
139                 return leftTodo->progress() < rightTodo->progress();
140             default:
141                 return QSortFilterProxyModel::lessThan( left, right );
142             }
143         }
144     }
145     return QSortFilterProxyModel::lessThan(left, right);
146 }
147