Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
PIM
Kalendar
Commits
09ce9fee
Commit
09ce9fee
authored
Sep 25, 2022
by
Claudio Cambra
Browse files
Make sure the tasks view now updates at time intervals
Signed-off-by:
Claudio Cambra
<
claudio.cambra@gmail.com
>
parent
fec9b33a
Pipeline
#236836
failed with stage
in 2 minutes and 11 seconds
Changes
2
Pipelines
2
Hide whitespace changes
Inline
Side-by-side
src/models/todosortfilterproxymodel.cpp
View file @
09ce9fee
...
...
@@ -25,6 +25,10 @@ TodoSortFilterProxyModel::TodoSortFilterProxyModel(QObject *parent)
QObject
::
connect
(
m_colorWatcher
.
data
(),
&
KConfigWatcher
::
configChanged
,
this
,
&
TodoSortFilterProxyModel
::
loadColors
);
loadColors
();
m_dateRefreshTimer
.
setInterval
(
m_dateRefreshTimerInterval
);
m_dateRefreshTimer
.
callOnTimeout
(
this
,
&
TodoSortFilterProxyModel
::
updateDateLabels
);
m_dateRefreshTimer
.
start
();
}
TodoSortFilterProxyModel
::~
TodoSortFilterProxyModel
()
...
...
@@ -64,9 +68,9 @@ QHash<int, QByteArray> TodoSortFilterProxyModel::roleNames() const
roleNames
[
Roles
::
CategoriesRole
]
=
"todoCategories"
;
// Simply 'categories' causes issues
roleNames
[
Roles
::
CategoriesDisplayRole
]
=
"categoriesDisplay"
;
roleNames
[
Roles
::
TreeDepthRole
]
=
"treeDepth"
;
roleNames
[
Roles
::
TopMostParentDueDate
]
=
"topMostParentDueDate"
;
roleNames
[
Roles
::
TopMostParentSummary
]
=
"topMostParentSummary"
;
roleNames
[
Roles
::
TopMostParentPriority
]
=
"topMostParentPriority"
;
roleNames
[
Roles
::
TopMostParentDueDate
Role
]
=
"topMostParentDueDate"
;
roleNames
[
Roles
::
TopMostParentSummary
Role
]
=
"topMostParentSummary"
;
roleNames
[
Roles
::
TopMostParentPriority
Role
]
=
"topMostParentPriority"
;
return
roleNames
;
}
...
...
@@ -147,7 +151,7 @@ QVariant TodoSortFilterProxyModel::data(const QModelIndex &index, int role) cons
return
todoPtr
->
categories
();
}
else
if
(
role
==
Roles
::
CategoriesDisplayRole
)
{
return
todoPtr
->
categories
().
join
(
i18nc
(
"List separator"
,
", "
));
}
else
if
(
role
==
Roles
::
TreeDepthRole
||
role
==
TopMostParentSummary
||
role
==
TopMostParentDueDate
||
role
==
TopMostParentPriority
)
{
}
else
if
(
role
==
Roles
::
TreeDepthRole
||
role
==
TopMostParentSummary
Role
||
role
==
TopMostParentDueDate
Role
||
role
==
TopMostParentPriority
Role
)
{
int
depth
=
0
;
auto
idx
=
index
;
while
(
idx
.
parent
().
isValid
())
{
...
...
@@ -160,9 +164,9 @@ QVariant TodoSortFilterProxyModel::data(const QModelIndex &index, int role) cons
switch
(
role
)
{
case
Roles
::
TreeDepthRole
:
return
depth
;
case
TopMostParentSummary
:
case
TopMostParentSummary
Role
:
return
todo
->
summary
();
case
TopMostParentDueDate
:
{
case
TopMostParentDueDate
Role
:
{
if
(
!
todo
->
hasDueDate
())
{
return
i18n
(
"No set date"
);
}
...
...
@@ -176,7 +180,7 @@ QVariant TodoSortFilterProxyModel::data(const QModelIndex &index, int role) cons
return
isToday
?
i18n
(
"Today"
)
:
todoDueDateDisplayString
(
todo
,
DisplayDateOnly
);
}
case
TopMostParentPriority
:
case
TopMostParentPriority
Role
:
return
todo
->
priority
();
}
}
...
...
@@ -219,6 +223,71 @@ QString TodoSortFilterProxyModel::todoDueDateDisplayString(const KCalendarCore::
return
dateDueString
+
todoTimeDueString
+
todoOverdueString
;
}
void
TodoSortFilterProxyModel
::
updateDateLabels
()
{
if
(
rowCount
()
==
0
||
!
sourceModel
())
{
return
;
}
emitDateDataChanged
({});
sortTodoModel
();
m_lastDateRefreshDate
=
QDate
::
currentDate
();
}
void
TodoSortFilterProxyModel
::
emitDateDataChanged
(
const
QModelIndex
&
idx
)
{
const
auto
idxRowCount
=
rowCount
(
idx
);
const
auto
srcModel
=
sourceModel
();
if
(
idxRowCount
==
0
)
{
return
;
}
const
auto
bottomRow
=
idxRowCount
-
1
;
const
auto
currentDate
=
QDate
::
currentDate
();
const
auto
currentDateTime
=
QDateTime
::
currentDateTime
();
const
auto
iterateOverChildren
=
[
this
,
&
idx
,
&
srcModel
,
&
currentDate
,
&
currentDateTime
](
const
int
row
)
{
const
auto
childIdx
=
index
(
row
,
0
,
idx
);
const
auto
todo
=
childIdx
.
data
(
TodoModel
::
TodoPtrRole
).
value
<
KCalendarCore
::
Todo
::
Ptr
>
();
const
auto
isOverdue
=
todo
->
isOverdue
();
const
auto
dtDue
=
todo
->
dtDue
();
const
auto
isRecentlyOverdue
=
isOverdue
&&
currentDateTime
.
msecsTo
(
dtDue
)
>=
-
m_dateRefreshTimerInterval
;
if
(
isRecentlyOverdue
||
m_lastDateRefreshDate
!=
currentDate
)
{
Q_EMIT
dataChanged
(
childIdx
,
childIdx
,
{
DisplayDueDateRole
,
TopMostParentDueDateRole
});
// For the proxy model to re-sort items into their correct section we also need to emit a
// dataChanged() signal for the column we are sorting by in the source model
const
auto
srcChildIdx
=
mapToSource
(
childIdx
).
siblingAtColumn
(
TodoModel
::
DueDateColumn
);
Q_EMIT
srcModel
->
dataChanged
(
srcChildIdx
,
srcChildIdx
,
{
TodoModel
::
DueDateRole
});
}
// We recursively do the same for children
emitDateDataChanged
(
childIdx
);
};
// This is a workaround for weird sorting behaviour. If one of the items changes because it becomes
// overdue, for example, the way in which we emit dataChanged() signals of the sourceModel will
// dictate how the model gets sorted.
//
// Example: In a case where the sort is ascending (i.e. overdue at top), a 0 to rowCount() -1 sort
// will move the overdue item up by only one row due to how the QSortFilterProxyModel uses lessThan().
// If we go the opposite way then the QSFPM calls lessThan() on the overdue item more than once, moving
// it upwards.
if
(
m_sortAscending
)
{
for
(
auto
i
=
bottomRow
;
i
>=
0
;
--
i
)
{
iterateOverChildren
(
i
);
}
}
else
{
for
(
auto
i
=
0
;
i
<
idxRowCount
;
++
i
)
{
iterateOverChildren
(
i
);
}
}
}
bool
TodoSortFilterProxyModel
::
filterAcceptsRow
(
int
row
,
const
QModelIndex
&
sourceParent
)
const
{
if
(
filterAcceptsRowCheck
(
row
,
sourceParent
))
{
...
...
@@ -521,6 +590,13 @@ int TodoSortFilterProxyModel::compareDueDates(const QModelIndex &left, const QMo
return
0
;
}
const
auto
leftOverdue
=
leftTodo
->
isOverdue
();
const
auto
rightOverdue
=
rightTodo
->
isOverdue
();
if
(
leftOverdue
!=
rightOverdue
)
{
return
leftOverdue
?
-
1
:
1
;
}
const
bool
leftIsEmpty
=
!
leftTodo
->
hasDueDate
();
const
bool
rightIsEmpty
=
!
rightTodo
->
hasDueDate
();
...
...
@@ -530,15 +606,11 @@ int TodoSortFilterProxyModel::compareDueDates(const QModelIndex &left, const QMo
}
else
if
(
!
leftIsEmpty
)
{
// Both have due dates
const
auto
leftDateTime
=
leftTodo
->
dtDue
();
const
auto
rightDateTime
=
rightTodo
->
dtDue
();
const
auto
leftOverdue
=
leftTodo
->
isOverdue
();
const
auto
rightOverdue
=
rightTodo
->
isOverdue
();
if
(
leftDateTime
==
rightDateTime
&&
leftOverdue
==
rightOverdue
)
{
if
(
leftDateTime
==
rightDateTime
)
{
return
0
;
}
else
if
(
leftOverdue
==
rightOverdue
)
{
return
leftDateTime
<
rightDateTime
?
-
1
:
1
;
}
else
{
return
left
Overdu
e
?
-
1
:
1
;
return
left
DateTime
<
rightDateTim
e
?
-
1
:
1
;
}
}
else
{
// Neither has a due date
return
0
;
...
...
src/models/todosortfilterproxymodel.h
View file @
09ce9fee
...
...
@@ -3,16 +3,17 @@
#pragma once
#include
<QObject>
#include
<Akonadi/ETMCalendar>
#include
<CalendarSupport/KCalPrefs>
#include
<Akonadi/CalendarUtils>
#include
<Akonadi/ETMCalendar>
#include
<Akonadi/IncidenceTreeModel>
#include
<CalendarSupport/KCalPrefs>
#include
<EventViews/TodoModel>
#include
<KConfigWatcher>
#include
<KFormat>
#include
<KSharedConfig>
#include
<QObject>
#include
<QSortFilterProxyModel>
#include
<QTimer>
class
Filter
;
...
...
@@ -52,9 +53,9 @@ public:
CategoriesRole
,
CategoriesDisplayRole
,
TreeDepthRole
,
TopMostParentSummary
,
// These three here are used to help us conserve the proper sections
TopMostParentDueDate
,
// in the Kirigami TreeListView, which otherwise will create new
TopMostParentPriority
,
// sections for subtasks
TopMostParentSummary
Role
,
// These three here are used to help us conserve the proper sections
TopMostParentDueDate
Role
,
// in the Kirigami TreeListView, which otherwise will create new
TopMostParentPriority
Role
,
// sections for subtasks
};
Q_ENUM
(
Roles
)
...
...
@@ -131,6 +132,10 @@ protected:
void
setColorCache
(
QHash
<
QString
,
QColor
>
colorCache
);
void
loadColors
();
private
Q_SLOTS
:
void
updateDateLabels
();
void
emitDateDataChanged
(
const
QModelIndex
&
idx
);
private:
QString
todoDueDateDisplayString
(
const
KCalendarCore
::
Todo
::
Ptr
todo
,
const
DueDateDisplayFormat
format
)
const
;
...
...
@@ -153,4 +158,7 @@ private:
bool
m_sortAscending
=
false
;
bool
m_showCompletedSubtodosInIncomplete
=
true
;
KFormat
m_format
;
QTimer
m_dateRefreshTimer
;
int
m_dateRefreshTimerInterval
=
60000
;
// msecs
QDate
m_lastDateRefreshDate
=
QDate
::
currentDate
();
};
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment