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
c7970346
Commit
c7970346
authored
Oct 09, 2022
by
Claudio Cambra
Browse files
Granularly update the incidenceoccurrencemodel rather than resetting it all
Signed-off-by:
Claudio Cambra
<
claudio.cambra@gmail.com
>
parent
a07c17e8
Changes
3
Hide whitespace changes
Inline
Side-by-side
src/models/incidenceoccurrencemodel.cpp
View file @
c7970346
...
...
@@ -105,58 +105,95 @@ void IncidenceOccurrenceModel::refreshView()
void
IncidenceOccurrenceModel
::
updateFromSource
()
{
beginResetModel
();
if
(
!
m_coreCalendar
)
{
return
;
}
m_incidences
.
clear
();
load
();
if
(
m_coreCalendar
)
{
KCalendarCore
::
OccurrenceIterator
occurrenceIterator
{
*
m_coreCalendar
,
QDateTime
{
mStart
,
{
0
,
0
,
0
}},
QDateTime
{
mEnd
,
{
12
,
59
,
59
}}};
while
(
occurrenceIterator
.
hasNext
())
{
occurrenceIterator
.
next
();
const
auto
incidence
=
occurrenceIterator
.
incidence
();
if
(
mFilter
&&
mFilter
->
tags
().
length
()
>
0
)
{
bool
match
=
false
;
QStringList
tags
=
mFilter
->
tags
();
for
(
const
auto
&
tag
:
tags
)
{
if
(
incidence
->
categories
().
contains
(
tag
))
{
match
=
true
;
break
;
}
}
const
auto
existingOccurrenceKeys
=
m_occurrenceIndexHash
.
keys
();
QSet
deadKeysSet
(
existingOccurrenceKeys
.
cbegin
(),
existingOccurrenceKeys
.
cend
());
KCalendarCore
::
OccurrenceIterator
occurrenceIterator
{
*
m_coreCalendar
,
QDateTime
{
mStart
,
{
0
,
0
,
0
}},
QDateTime
{
mEnd
,
{
12
,
59
,
59
}}};
while
(
occurrenceIterator
.
hasNext
())
{
occurrenceIterator
.
next
();
const
auto
incidence
=
occurrenceIterator
.
incidence
();
if
(
!
match
)
{
continue
;
if
(
mFilter
&&
mFilter
->
tags
().
length
()
>
0
)
{
auto
match
=
false
;
const
auto
tags
=
mFilter
->
tags
();
for
(
const
auto
&
tag
:
tags
)
{
if
(
incidence
->
categories
().
contains
(
tag
))
{
match
=
true
;
break
;
}
}
auto
start
=
occurrenceIterator
.
occurrenceStartDate
();
auto
end
=
incidence
->
endDateForStart
(
start
);
if
(
!
match
)
{
continue
;
}
}
if
(
incidence
->
type
()
==
KCalendarCore
::
Incidence
::
IncidenceType
::
TypeTodo
)
{
KCalendarCore
::
Todo
::
Ptr
todo
=
incidence
.
staticCast
<
KCalendarCore
::
Todo
>
(
);
auto
start
=
occurrenceIterator
.
occurrenceStartDate
();
const
auto
end
=
incidence
->
endDateForStart
(
start
);
if
(
!
start
.
isValid
())
{
// Todos are very likely not to have a set start date
start
=
todo
->
dtDue
();
}
}
if
(
incidence
->
type
()
==
KCalendarCore
::
Incidence
::
IncidenceType
::
TypeTodo
)
{
KCalendarCore
::
Todo
::
Ptr
todo
=
incidence
.
staticCast
<
KCalendarCore
::
Todo
>
();
if
(
start
.
date
()
<
mEnd
&&
end
.
date
()
>=
mStart
)
{
m_incidences
.
append
(
Occurrence
{
start
,
end
,
incidence
,
getColor
(
incidence
),
getCollectionId
(
incidence
),
incidence
->
allDay
(),
});
if
(
!
start
.
isValid
())
{
// Todos are very likely not to have a set start date
start
=
todo
->
dtDue
();
}
}
if
(
start
.
date
()
>
mEnd
||
end
.
date
()
<
mStart
)
{
qDebug
()
<<
"Skipping incidence:"
<<
incidence
->
summary
()
<<
mStart
<<
start
<<
mEnd
<<
end
;
continue
;
}
const
auto
occurrenceHashKey
=
qHash
(
QString
::
number
(
start
.
toSecsSinceEpoch
())
+
QString
::
number
(
end
.
toSecsSinceEpoch
())
+
incidence
->
uid
());
const
Occurrence
occurrence
{
start
,
end
,
incidence
,
getColor
(
incidence
),
getCollectionId
(
incidence
),
incidence
->
allDay
(),
};
if
(
m_occurrenceIndexHash
.
contains
(
occurrenceHashKey
))
{
const
auto
existingOccurrenceIndex
=
m_occurrenceIndexHash
.
value
(
occurrenceHashKey
);
const
auto
existingOccurrenceRow
=
existingOccurrenceIndex
.
row
();
m_incidences
.
replace
(
existingOccurrenceRow
,
occurrence
);
Q_EMIT
dataChanged
(
existingOccurrenceIndex
,
existingOccurrenceIndex
);
deadKeysSet
.
remove
(
occurrenceHashKey
);
}
else
{
const
auto
indexRow
=
m_incidences
.
count
();
beginInsertRows
({},
indexRow
,
indexRow
);
m_incidences
.
append
(
occurrence
);
endInsertRows
();
const
auto
occurrenceIndex
=
index
(
indexRow
);
const
QPersistentModelIndex
persistentIndex
(
occurrenceIndex
);
m_occurrenceIndexHash
.
insert
(
occurrenceHashKey
,
persistentIndex
);
}
}
endResetModel
();
for
(
const
auto
&
deadKey
:
deadKeysSet
)
{
const
auto
deadOccurrenceIndex
=
m_occurrenceIndexHash
.
value
(
deadKey
);
const
auto
deadOccurrenceRow
=
deadOccurrenceIndex
.
row
();
beginRemoveRows
({},
deadOccurrenceRow
,
deadOccurrenceRow
);
m_occurrenceIndexHash
.
remove
(
deadKey
);
m_incidences
.
removeAt
(
deadOccurrenceRow
);
endRemoveRows
();
}
}
int
IncidenceOccurrenceModel
::
rowCount
(
const
QModelIndex
&
parent
)
const
...
...
@@ -206,24 +243,29 @@ QVariant IncidenceOccurrenceModel::data(const QModelIndex &idx, int role) const
if
(
!
hasIndex
(
idx
.
row
(),
idx
.
column
()))
{
return
{};
}
auto
incidence
=
m_incidences
.
at
(
idx
.
row
());
auto
icalIncid
ence
=
incidence
.
incidence
;
const
KCalendarCore
::
Duration
duration
(
incidence
.
start
,
incidence
.
end
)
;
const
auto
occurr
ence
=
m_
incidence
s
.
at
(
idx
.
row
())
;
const
auto
incidence
=
occurrence
.
incidence
;
switch
(
role
)
{
case
Summary
:
return
i
calI
ncidence
->
summary
();
return
incidence
->
summary
();
case
Description
:
return
i
calI
ncidence
->
description
();
return
incidence
->
description
();
case
Location
:
return
i
calI
ncidence
->
location
();
return
incidence
->
location
();
case
StartTime
:
return
incid
ence
.
start
;
return
occurr
ence
.
start
;
case
EndTime
:
return
incid
ence
.
end
;
return
occurr
ence
.
end
;
case
Duration
:
{
const
KCalendarCore
::
Duration
duration
(
occurrence
.
start
,
occurrence
.
end
);
return
QVariant
::
fromValue
(
duration
);
}
case
DurationString
:
{
const
KCalendarCore
::
Duration
duration
(
occurrence
.
start
,
occurrence
.
end
);
if
(
duration
.
asSeconds
()
==
0
)
{
return
QString
();
}
...
...
@@ -231,51 +273,51 @@ QVariant IncidenceOccurrenceModel::data(const QModelIndex &idx, int role) const
return
m_format
.
formatSpelloutDuration
(
duration
.
asSeconds
()
*
1000
);
}
case
Recurs
:
return
i
calI
ncidence
->
recurs
();
return
incidence
->
recurs
();
case
HasReminders
:
return
i
calI
ncidence
->
alarms
().
length
()
>
0
;
return
incidence
->
alarms
().
length
()
>
0
;
case
Priority
:
return
i
calI
ncidence
->
priority
();
return
incidence
->
priority
();
case
Color
:
return
incid
ence
.
color
;
return
occurr
ence
.
color
;
case
CollectionId
:
return
incid
ence
.
collectionId
;
return
occurr
ence
.
collectionId
;
case
AllDay
:
return
incid
ence
.
allDay
;
return
occurr
ence
.
allDay
;
case
TodoCompleted
:
{
if
(
i
calI
ncidence
->
type
()
!=
KCalendarCore
::
IncidenceBase
::
TypeTodo
)
{
if
(
incidence
->
type
()
!=
KCalendarCore
::
IncidenceBase
::
TypeTodo
)
{
return
false
;
}
auto
todo
=
i
calI
ncidence
.
staticCast
<
KCalendarCore
::
Todo
>
();
auto
todo
=
incidence
.
staticCast
<
KCalendarCore
::
Todo
>
();
return
todo
->
isCompleted
();
}
case
IsOverdue
:
{
if
(
i
calI
ncidence
->
type
()
!=
KCalendarCore
::
IncidenceBase
::
TypeTodo
)
{
if
(
incidence
->
type
()
!=
KCalendarCore
::
IncidenceBase
::
TypeTodo
)
{
return
false
;
}
auto
todo
=
i
calI
ncidence
.
staticCast
<
KCalendarCore
::
Todo
>
();
auto
todo
=
incidence
.
staticCast
<
KCalendarCore
::
Todo
>
();
return
todo
->
isOverdue
();
}
case
IsReadOnly
:
{
const
auto
collection
=
m_coreCalendar
->
collection
(
incid
ence
.
collectionId
);
const
auto
collection
=
m_coreCalendar
->
collection
(
occurr
ence
.
collectionId
);
return
collection
.
rights
().
testFlag
(
Akonadi
::
Collection
::
ReadOnly
);
}
case
IncidenceId
:
return
i
calI
ncidence
->
uid
();
return
incidence
->
uid
();
case
IncidenceType
:
return
i
calI
ncidence
->
type
();
return
incidence
->
type
();
case
IncidenceTypeStr
:
return
i
calI
ncidence
->
type
()
==
KCalendarCore
::
Incidence
::
TypeTodo
?
i18n
(
"Task"
)
:
i18n
(
i
calI
ncidence
->
typeStr
().
constData
());
return
incidence
->
type
()
==
KCalendarCore
::
Incidence
::
TypeTodo
?
i18n
(
"Task"
)
:
i18n
(
incidence
->
typeStr
().
constData
());
case
IncidenceTypeIcon
:
return
i
calI
ncidence
->
iconName
();
return
incidence
->
iconName
();
case
IncidencePtr
:
return
QVariant
::
fromValue
(
icalIncidence
);
case
IncidenceOccurrence
:
return
QVariant
::
fromValue
(
incidence
);
case
IncidenceOccurrence
:
return
QVariant
::
fromValue
(
occurrence
);
default:
qCWarning
(
KALENDAR_LOG
)
<<
"Unknown role for
incid
ence:"
<<
QMetaEnum
::
fromType
<
Roles
>
().
valueToKey
(
role
);
qCWarning
(
KALENDAR_LOG
)
<<
"Unknown role for
occurr
ence:"
<<
QMetaEnum
::
fromType
<
Roles
>
().
valueToKey
(
role
);
return
{};
}
}
...
...
src/models/incidenceoccurrencemodel.h
View file @
c7970346
...
...
@@ -94,7 +94,7 @@ public:
struct
Occurrence
{
QDateTime
start
;
QDateTime
end
;
QSharedPointer
<
KCalendarCore
::
Incidence
>
incidence
;
KCalendarCore
::
Incidence
::
Ptr
incidence
;
QColor
color
;
qint64
collectionId
;
bool
allDay
;
...
...
@@ -120,7 +120,9 @@ private:
QTimer
mRefreshTimer
;
QList
<
Occurrence
>
m_incidences
;
// We need it to be ordered for the model
QVector
<
Occurrence
>
m_incidences
;
QHash
<
uint
,
QPersistentModelIndex
>
m_occurrenceIndexHash
;
QHash
<
QString
,
QColor
>
m_colors
;
KConfigWatcher
::
Ptr
m_colorWatcher
;
Filter
*
mFilter
;
...
...
@@ -128,6 +130,7 @@ private:
};
Q_DECLARE_METATYPE
(
IncidenceOccurrenceModel
::
Occurrence
)
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
Q_DECLARE_METATYPE
(
KCalendarCore
::
Incidence
::
Ptr
)
#endif
src/models/multidayincidencemodel.cpp
View file @
c7970346
...
...
@@ -13,6 +13,12 @@ MultiDayIncidenceModel::MultiDayIncidenceModel(QObject *parent)
:
QAbstractItemModel
(
parent
)
{
mRefreshTimer
.
setSingleShot
(
true
);
mRefreshTimer
.
callOnTimeout
(
this
,
[
this
]
{
beginResetModel
();
endResetModel
();
Q_EMIT
incidenceCountChanged
();
});
m_config
=
KalendarConfig
::
self
();
QObject
::
connect
(
m_config
,
&
KalendarConfig
::
showSubtodosInCalendarViewsChanged
,
this
,
[
&
]()
{
beginResetModel
();
...
...
@@ -271,10 +277,7 @@ void MultiDayIncidenceModel::setModel(IncidenceOccurrenceModel *model)
Q_EMIT
modelChanged
();
auto
resetModel
=
[
this
]
{
if
(
!
mRefreshTimer
.
isActive
())
{
beginResetModel
();
endResetModel
();
Q_EMIT
incidenceCountChanged
();
mRefreshTimer
.
start
(
50
);
mRefreshTimer
.
start
(
100
);
}
};
QObject
::
connect
(
model
,
&
QAbstractItemModel
::
dataChanged
,
this
,
resetModel
);
...
...
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