Commit f0cae7ed authored by Carl Schwan's avatar Carl Schwan 🚴 Committed by Claudio Cambra
Browse files

Refactor filter



Use singleton to hold the Filter instead of passing them around. Allow
to reuse it for the mail and contact search. And move code from main.qml
to the subcomponents.

Signed-off-by: Carl Schwan's avatarCarl Schwan <carl@carlschwan.eu>
parent 548bdef9
Pipeline #230140 canceled with stage
in 2 minutes and 9 seconds
......@@ -22,11 +22,13 @@ set (commonAkonadiTest_LIBS
set(incidenceOccurrenceModelTest_SRCS
incidenceoccurrencemodeltest.cpp
../src/models/incidenceoccurrencemodel.cpp
../src/filter.cpp
)
set(todoSortFilterProxyModelTest_SRCS
todosortfilterproxymodeltest.cpp
../src/models/todosortfilterproxymodel.cpp
../src/filter.cpp
)
ecm_qt_declare_logging_category(incidenceOccurrenceModelTest_SRCS HEADER kalendar_debug.h IDENTIFIER KALENDAR_LOG CATEGORY_NAME org.kde.kalendar DESCRIPTION "kalendar" EXPORT KALENDAR)
......
......@@ -3,6 +3,7 @@
#include "../src/models/incidenceoccurrencemodel.h"
#include "../src/filter.h"
#include <Akonadi/IncidenceChanger>
#include <KCalendarCore/Incidence>
#include <KCheckableProxyModel>
......@@ -180,12 +181,12 @@ private Q_SLOTS:
void testFilter()
{
QVariantMap filter;
filter[QStringLiteral("tags")] = QStringList(QStringLiteral("Tag 2"));
Filter filter;
filter.setTags(QStringList(QStringLiteral("Tag 2")));
QSignalSpy fetchFinished(&model, &QAbstractItemModel::modelReset);
model.setFilter(filter);
QCOMPARE(model.filter(), filter);
model.setFilter(&filter);
QCOMPARE(model.filter(), &filter);
fetchFinished.wait(10000);
QCOMPARE(model.rowCount(), 1);
......
......@@ -22,6 +22,8 @@ set(kalendar_SRCS
models/attendeesmodel.h
calendarmanager.cpp
calendarmanager.h
filter.cpp
filter.h
models/commandbarfiltermodel.cpp
models/commandbarfiltermodel.h
models/hourlyincidencemodel.cpp
......
......@@ -16,6 +16,11 @@ Kirigami.ScrollablePage {
property var attendeeAkonadiIds
title: i18n("Contacts")
Connections {
target: Filter
onNameChanged: ContactManager.filteredContacts.setFilterFixedString(Filter.name)
}
actions.main: Kirigami.Action {
icon.name: 'contact-new-symbolic'
text: i18n('Create')
......
......@@ -12,20 +12,12 @@ import "labelutils.js" as LabelUtils
RowLayout {
id: headerLayout
signal resetFilterCollection()
signal removeFilterTag(string tagName)
signal searchTextChanged(string text)
property bool isDark: KalendarUiUtils.darkMode
property var mode: Kalendar.KalendarApplication.Event
property var filter: {
"tags": [],
"collectionId": -1
}
property var filterCollectionDetails: filter && filter.collectionId >= 0 ?
Kalendar.CalendarManager.getCollectionDetails(filter.collectionId) : null
property var filterCollectionDetails: Kalendar.Filter.collectionId >= 0 ?
Kalendar.CalendarManager.getCollectionDetails(Kalendar.Filter.collectionId) : null
visible: mode === Kalendar.KalendarApplication.Todo || filter.tags.length > 0 || filter.collectionId > -1
visible: mode === Kalendar.KalendarApplication.Todo || Kalendar.Filter.tags.length > 0 || Kalendar.Filter.collectionId > -1
height: visible ? implicitHeight : 0
spacing: Kirigami.Units.smallSpacing
......@@ -34,7 +26,7 @@ RowLayout {
target: Kalendar.CalendarManager
function onCollectionColorsChanged() {
// Trick into reevaluating filterCollectionDetails
headerLayout.filterChanged();
Kalendar.Filter.tagsChanged();
}
}
......@@ -46,10 +38,10 @@ RowLayout {
Layout.alignment: Qt.AlignVCenter
width: implicitWidth
text: headerLayout.mode !== Kalendar.KalendarApplication.Todo ? i18n("Filtering by tags") : headerLayout.filterCollectionDetails && headerLayout.filter.collectionId > -1 ?
text: headerLayout.mode !== Kalendar.KalendarApplication.Todo ? i18n("Filtering by tags") : headerLayout.filterCollectionDetails && Kalendar.Filter.collectionId > -1 ?
headerLayout.filterCollectionDetails.displayName : i18n("All Tasks")
font.weight: headerLayout.mode !== Kalendar.KalendarApplication.Todo ? Font.Normal : Font.Bold
color: headerLayout.mode === Kalendar.KalendarApplication.Todo && headerLayout.filterCollectionDetails && headerLayout.filter.collectionId > -1 ?
color: headerLayout.mode === Kalendar.KalendarApplication.Todo && headerLayout.filterCollectionDetails && Kalendar.Filter.collectionId > -1 ?
headerLayout.filterCollectionDetails.color : Kirigami.Theme.textColor
elide: Text.ElideRight
level: headerLayout.mode === Kalendar.KalendarApplication.Todo ? 1 : 2
......@@ -57,8 +49,8 @@ RowLayout {
QQC2.ToolButton {
Layout.alignment: Qt.AlignVCenter
icon.name: "edit-reset"
visible: headerLayout.mode === Kalendar.KalendarApplication.Todo && headerLayout.filter.collectionId > -1
onClicked: headerLayout.resetFilterCollection()
visible: headerLayout.mode === Kalendar.KalendarApplication.Todo && Kalendar.Filter.collectionId > -1
onClicked: Kalendar.Filter.collectionId = -1
}
}
......@@ -72,11 +64,11 @@ RowLayout {
spacing: Kirigami.Units.smallSpacing
layoutDirection: Qt.RightToLeft
clip: true
visible: headerLayout.filter.tags.length > 0
visible: Kalendar.Filter.tags.length > 0
Repeater {
id: tagRepeater
model: headerLayout.filter ? headerLayout.filter.tags : {}
model: Kalendar.Filter ? Kalendar.Filter.tags : {}
Tag {
id: filterTag
......@@ -89,7 +81,7 @@ RowLayout {
headingItem.color: headerLayout.mode === Kalendar.KalendarApplication.Todo && headerLayout.filterCollectionDetails ?
headerLayout.filterCollectionDetails.color : Kirigami.Theme.textColor
onClicked: headerLayout.removeFilterTag(modelData)
onClicked: Kalendar.Filter.removeTag(modelData)
actionIcon.name: "edit-delete-remove"
actionText: i18n("Remove filtering tag")
}
......@@ -122,7 +114,7 @@ RowLayout {
text: headerLayout.mode === Kalendar.KalendarApplication.Todo ? applicationWindow().pageStack.currentItem.incompleteView.model.rowCount() : ''
font.weight: Font.Bold
color: headerLayout.mode === Kalendar.KalendarApplication.Todo && headerLayout.filterCollectionDetails && headerLayout.filter.collectionId > -1 ?
color: headerLayout.mode === Kalendar.KalendarApplication.Todo && headerLayout.filterCollectionDetails && Kalendar.Filter.collectionId > -1 ?
headerLayout.filterCollectionDetails.color : Kirigami.Theme.textColor
elide: Text.ElideRight
visible: headerLayout.mode === Kalendar.KalendarApplication.Todo
......
......@@ -16,7 +16,6 @@ Kirigami.OverlayDrawer {
signal addSubTodo(var parentWrapper)
signal editIncidence(var incidencePtr)
signal deleteIncidence(var incidencePtr, date deleteDate)
signal tagClicked(string tagName)
/**
* We use both incidenceData and incidenceWrapper to get info about the occurrence.
......@@ -30,7 +29,7 @@ Kirigami.OverlayDrawer {
property var incidenceData
property var incidenceWrapper
property var collectionData
property var activeTags : []
readonly property var activeTags : Filter.tags
readonly property int relatedIncidenceDelegateHeight: Kirigami.Units.gridUnit * 3
......@@ -261,7 +260,7 @@ Kirigami.OverlayDrawer {
implicitWidth: itemLayout.implicitWidth > tagFlow.width ? tagFlow.width : itemLayout.implicitWidth
activeFocusOnTab: true
backgroundColor: mainDrawer.activeTags.includes(modelData) ? Kirigami.Theme.highlightColor : Kirigami.Theme.backgroundColor
onClicked: incidenceInfoDrawer.tagClicked(modelData)
onClicked: Filter.toggleFilterTag(modelData)
}
}
}
......
......@@ -18,15 +18,11 @@ Kirigami.OverlayDrawer {
id: mainDrawer
signal calendarClicked(int collectionId)
signal calendarCheckChanged(int collectionId, bool checked)
signal viewAllTodosClicked
signal tagClicked(string tagName)
signal deleteCalendar(int collectionId, var collectionDetails)
property var mode: KalendarApplication.Event
property alias toolbar: toolbar
property var activeTags : []
property alias searchText: searchField.text
property var activeTags : Filter.tags
Connections {
target: applicationWindow()
......@@ -99,6 +95,7 @@ Kirigami.OverlayDrawer {
Kirigami.SearchField { // TODO: Make this open a new search results page
id: searchField
Layout.fillWidth: true
onTextChanged: Filter.name = text
visible: mainDrawer.mode & (KalendarApplication.Todo | KalendarApplication.Mail | KalendarApplication.Contact)
opacity: mainDrawer.collapsed ? 0 : 1
......@@ -426,7 +423,7 @@ Kirigami.OverlayDrawer {
activeFocusOnTab: true
backgroundColor: mainDrawer.activeTags.includes(model.display) ? Kirigami.Theme.highlightColor : Kirigami.Theme.backgroundColor
enabled: !mainDrawer.collapsed
onClicked: tagClicked(model.display)
onClicked: Filter.toggleFilterTag(model.display)
}
}
}
......@@ -550,10 +547,10 @@ Kirigami.OverlayDrawer {
visible: model.checkState != null
color: model.collectionColor ?? Kirigami.Theme.highlightedTextColor
checked: model.checkState === 2
onCheckedChanged: calendarCheckChanged(collectionId, checked)
onCheckedChanged: mainDrawer.calendarCheckChanged()
onClicked: {
model.checkState = model.checkState === 0 ? 2 : 0
calendarCheckChanged(collectionId, checked)
calendarCheckChanged()
}
}
}
......@@ -611,16 +608,18 @@ Kirigami.OverlayDrawer {
visible: model.checkState != null
color: model.collectionColor
checked: model.checkState === 2
onCheckedChanged: calendarCheckChanged(collectionId, checked)
onCheckedChanged: mainDrawer.calendarCheckChanged()
onClicked: {
model.checkState = model.checkState === 0 ? 2 : 0
calendarCheckChanged(collectionId, checked)
calendarCheckChanged()
}
}
onClicked: {
calendarClicked(collectionId);
if(mainDrawer.modal) mainDrawer.close()
Filter.collectionId = collectionId;
if (mainDrawer.modal) {
mainDrawer.close()
}
}
CalendarItemTapHandler {
......@@ -664,8 +663,8 @@ Kirigami.OverlayDrawer {
Kirigami.Separator {
Layout.fillWidth: true
}
Kirigami.BasicListItem {
Kirigami.BasicListItem {
FontMetrics {
id: textMetrics
}
......@@ -677,8 +676,16 @@ Kirigami.OverlayDrawer {
visible: mainDrawer.mode === KalendarApplication.Todo
separatorVisible: false
onClicked: {
viewAllTodosClicked();
if(mainDrawer.modal && mainDrawer.mode === KalendarApplication.Todo) mainDrawer.close()
Filter.reset()
if (mainDrawer.modal && mainDrawer.mode === KalendarApplication.Todo) {
mainDrawer.close()
}
}
}
function calendarCheckChanged() {
if (mode & (KalendarApplication.Event | KalendarApplication.Todo)) {
CalendarManager.save();
}
}
}
......@@ -17,7 +17,6 @@ Item {
id: root
property var openOccurrence
property var filter: ({})
property int daysToShow: daysPerRow * 6
property int daysPerRow: 7
......@@ -241,7 +240,7 @@ Item {
start: root.startDate
length: root.daysToShow
calendar: Kalendar.CalendarManager.calendar
filter: root.filter
filter: Kalendar.Filter
}
}
//One row => one week
......
......@@ -16,7 +16,6 @@ Kirigami.Page {
id: root
property var openOccurrence: ({})
property var filter: ({})
property date selectedDate: new Date()
property date startDate: DateUtils.getFirstDayOfMonth(selectedDate)
......@@ -442,7 +441,7 @@ Kirigami.Page {
start: viewLoader.startDate
length: root.daysToShow
calendar: Kalendar.CalendarManager.calendar
filter: root.filter
filter: Kalendar.Filter
}
}
......@@ -783,7 +782,7 @@ Kirigami.Page {
start: viewLoader.startDate
length: root.daysToShow
calendar: Kalendar.CalendarManager.calendar
filter: root.filter
filter: Kalendar.Filter
}
}
......
......@@ -15,7 +15,6 @@ Kirigami.Page {
id: monthPage
property var openOccurrence
property var filter: ({})
property date startDate
property date currentDate
property date firstDayOfMonth
......@@ -150,7 +149,6 @@ Kirigami.Page {
height: pathView.height
isCurrentView: viewLoader.isCurrentItem
dragDropEnabled: monthPage.dragDropEnabled
filter: root.filter
startDate: viewLoader.startDate
currentDate: monthPage.currentDate
......
......@@ -51,7 +51,6 @@ Kirigami.Page {
}
property var openOccurrence
property var filter: ({})
property date selectedDate: new Date()
property date startDate: DateUtils.getFirstDayOfMonth(selectedDate)
property int day: selectedDate.getDate()
......@@ -241,7 +240,7 @@ Kirigami.Page {
start: viewLoader.firstDayOfMonth
length: viewLoader.daysInMonth
calendar: Kalendar.CalendarManager.calendar
filter: root.filter
filter: Kalendar.Filter
}
}
......
......@@ -34,7 +34,6 @@ TreeListView {
property var retainedCollectionData: ({})
property date currentDate: new Date()
property var filter
property var filterCollectionDetails
property int showCompleted: Kalendar.TodoSortFilterProxyModel.ShowAll
......@@ -101,14 +100,14 @@ TreeListView {
Kirigami.PlaceholderMessage {
id: allTasksPlaceholderMessage
anchors.centerIn: parent
visible: (!root.filter || !root.filter.collectionId || root.filter.collectionId < 0) && Kalendar.CalendarManager.enabledTodoCollections.length === 0 && parent.count === 0
visible: (!Kalendar.Filter.collectionId || Kalendar.Filter.collectionId < 0) && Kalendar.CalendarManager.enabledTodoCollections.length === 0 && parent.count === 0
text: i18n("No task calendars enabled.")
}
Kirigami.PlaceholderMessage {
id: collectionPlaceholderMessage
anchors.centerIn: parent
visible: root.filter && root.filter.collectionId >= 0 && !Kalendar.CalendarManager.enabledTodoCollections.includes(root.filter.collectionId) && parent.count === 0
visible: Kalendar.Filter && Kalendar.Filter.collectionId >= 0 && !Kalendar.CalendarManager.enabledTodoCollections.includes(Kalendar.Filter.collectionId) && parent.count === 0
text: i18n("Calendar is not enabled")
helpfulAction: Kirigami.Action {
icon.name: "gtk-yes"
......@@ -133,7 +132,7 @@ TreeListView {
id: todoModel
calendar: Kalendar.CalendarManager.calendar
incidenceChanger: Kalendar.CalendarManager.incidenceChanger
filterMap: root.filter
filterMap: Kalendar.Filter
showCompleted: root.showCompleted
sortBy: root.sortBy
sortAscending: root.ascendingOrder
......
......@@ -20,13 +20,8 @@ Kirigami.ScrollablePage {
property var mode: Kalendar.KalendarApplication.Todo
property var filter: {
"collectionId": -1,
"tags": [],
"name": ""
}
property var filterCollectionDetails: root.filter && root.filter.collectionId >= 0 ?
Kalendar.CalendarManager.getCollectionDetails(root.filter.collectionId) : null
property var filterCollectionDetails: Kalendar.Filter.collectionId >= 0 ?
Kalendar.CalendarManager.getCollectionDetails(Kalendar.Filter.collectionId) : null
property int sortBy: switch (Kalendar.Config.sort) {
case Kalendar.Config.DueTime:
......@@ -57,7 +52,7 @@ Kirigami.ScrollablePage {
main: Kirigami.Action {
text: i18n("Create")
icon.name: "list-add"
onTriggered: KalendarUiUtils.setUpAdd(Kalendar.IncidenceWrapper.TypeTodo, new Date(), root.filter.collectionId);
onTriggered: KalendarUiUtils.setUpAdd(Kalendar.IncidenceWrapper.TypeTodo, new Date(), Kalendar.Filter.collectionId);
}
left: Kirigami.Action {
text: i18n("Sort")
......@@ -101,7 +96,7 @@ Kirigami.ScrollablePage {
property Component completedSheetComponent: Kirigami.ScrollablePage {
id: completedSheet
title: root.filterCollectionDetails && root.filter && root.filter.collectionId > -1 ?
title: root.filterCollectionDetails && Kalendar.Filter.collectionId > -1 ?
i18n("Completed Tasks in %1", root.filterCollectionDetails.displayName) : i18n("Completed Tasks")
TodoTreeView {
......@@ -109,7 +104,6 @@ Kirigami.ScrollablePage {
Layout.fillWidth: true
Layout.fillHeight: true
filter: root.filter
filterCollectionDetails: root.filterCollectionDetails
showCompleted: Kalendar.TodoSortFilterProxyModel.ShowCompleteOnly
......@@ -141,7 +135,6 @@ Kirigami.ScrollablePage {
Layout.fillWidth: true
Layout.fillHeight: true
filter: root.filter
filterCollectionDetails: root.filterCollectionDetails
showCompleted: Kalendar.TodoSortFilterProxyModel.ShowIncompleteOnly
......@@ -178,8 +171,8 @@ Kirigami.ScrollablePage {
incidenceWrapper.setNewTodo();
incidenceWrapper.summary = addField.text;
if(root.filter && root.filter.collectionId >= 0) {
incidenceWrapper.collectionId = root.filter.collectionId;
if(Kalendar.Filter.collectionId >= 0) {
incidenceWrapper.collectionId = Kalendar.Filter.collectionId;
Kalendar.CalendarManager.addIncidence(incidenceWrapper);
addField.clear();
} else {
......
......@@ -36,14 +36,6 @@ Kirigami.ApplicationWindow {
}
property date selectedDate: new Date()
property var openOccurrence: {}
property var filter: {
"collectionId": -1,
"tags": [],
"name": ""
}
onFilterChanged: if(pageStack.currentItem.mode === KalendarApplication.Todo) {
pageStack.currentItem.filter = filter
}
readonly property var monthViewAction: KalendarApplication.action("open_month_view")
readonly property var weekViewAction: KalendarApplication.action("open_week_view")
......@@ -491,45 +483,7 @@ Kirigami.ApplicationWindow {
id: mainDrawer
bottomPadding: menuLoader.active ? menuLoader.height : 0
mode: pageStack.currentItem ? pageStack.currentItem.mode : KalendarApplication.Event
activeTags: root.filter && root.filter.tags ?
root.filter.tags : []
onSearchTextChanged: {
if (mode === KalendarApplication.Contact) {
ContactManager.filteredContacts.setFilterFixedString(searchText)
return;
}
if (mode === KalendarApplication.Mail) {
MailManager.folderModel.searchString = searchText;
return;
}
if(root.filter) {
root.filter.name = searchText;
} else {
root.filter = {name: searchText};
}
root.filterChanged();
}
onCalendarClicked: if (mode === KalendarApplication.Todo) {
root.filter ?
root.filter.collectionId = collectionId :
root.filter = {"collectionId" : collectionId};
root.filterChanged();
pageStack.currentItem.filterCollectionDetails = CalendarManager.getCollectionDetails(collectionId);
}
onCalendarCheckChanged: {
CalendarManager.save();
if(mode === KalendarApplication.Todo && collectionId === pageStack.currentItem.filterCollectionId) {
pageStack.currentItem.filterCollectionDetails = CalendarManager.getCollectionDetails(pageStack.currentItem.filterCollectionId);
// HACK: The Todo View should be able to detect change in collection filtering independently
}
}
onTagClicked: root.toggleFilterTag(tagName)
onViewAllTodosClicked: if(mode === KalendarApplication.Todo) {
root.filter.collectionId = -1;
root.filter.tags = [];
root.filter.name = "";
root.filterChanged();
}
onDeleteCalendar: {
const openDialogWindow = pageStack.pushDialogLayer(deleteCalendarPageComponent, {
collectionId: collectionId,
......@@ -548,9 +502,9 @@ Kirigami.ApplicationWindow {
id: incidenceInfoDrawer
width: if(!Kirigami.Settings.isMobile) actualWidth
height: if(Kirigami.Settings.isMobile) applicationWindow().height * 0.6
bottomPadding: menuLoader.active ? menuLoader.height : 0
height: if(Kirigami.Settings.isMobile) applicationWindow().height * 0.6
bottomPadding: menuLoader.active ? menuLoader.height : 0
modal: !root.wideScreen || !enabled
onEnabledChanged: drawerOpen = enabled && !modal
onModalChanged: drawerOpen = !modal
......@@ -558,8 +512,6 @@ Kirigami.ApplicationWindow {
handleVisible: enabled
interactive: Kirigami.Settings.isMobile // Otherwise get weird bug where drawer gets dragged around despite no click
activeTags: root.filter && root.filter.tags ?
root.filter.tags : []
onIncidenceDataChanged: root.openOccurrence = incidenceData;
onVisibleChanged: {
if(visible) {
......@@ -581,7 +533,6 @@ Kirigami.ApplicationWindow {
KalendarUiUtils.setUpDelete(incidencePtr, deleteDate)
if (modal) { incidenceInfoDrawer.close() }
}
onTagClicked: root.toggleFilterTag(tagName)
readonly property int minWidth: Kirigami.Units.gridUnit * 15
readonly property int maxWidth: Kirigami.Units.gridUnit * 25
......@@ -697,7 +648,7 @@ Kirigami.ApplicationWindow {
active: false
sourceComponent: Item {
readonly property bool show: header.mode === KalendarApplication.Todo ||
header.filter.tags.length > 0 ||
Filter.tags.length > 0 ||
notifyMessage.visible
readonly property alias messageItem: notifyMessage
......@@ -736,20 +687,8 @@ Kirigami.ApplicationWindow {
Layout.fillWidth: true
Layout.fillHeight: true
mode: pageStack.currentItem ? pageStack.currentItem.mode : KalendarApplication.Event
filter: root.filter ?
root.filter : {"tags": [], "collectionId": -1, "name": ""}
isDark: KalendarUiUtils.darkMode
visible: mode === KalendarApplication.Todo || filter.tags.length > 0
clip: true
onRemoveFilterTag: {
root.filter.tags.splice(root.filter.tags.indexOf(tagName), 1);
root.filterChanged();
}
onResetFilterCollection: {
root.filter.collectionId = -1;
root.filterChanged();
}
}
}
Kirigami.Separator {
......@@ -863,21 +802,6 @@ Kirigami.ApplicationWindow {
}
}
function toggleFilterTag(tagName) {
if(!root.filter || !root.filter.tags || !root.filter.tags.includes(tagName)) {
root.filter ? root.filter.tags ?
root.filter.tags.push(tagName) :
root.filter.tags = [tagName] :
root.filter = {"tags" : [tagName]};
root.filterChanged();
filterHeaderBar.active = true;
pageStack.currentItem.header = filterHeaderBar.item;
} else if (root.filter.tags.includes(tagName)) {
root.filter.tags = root.filter.tags.filter((tag) => tag !== tagName);
root.filterChanged();
}
}
Connections {
target: CalendarManager
function onUpdateIncidenceDatesCompleted() { KalendarUiUtils.reenableDragOnCurrentView(); }
......@@ -991,7 +915,6 @@ Kirigami.ApplicationWindow {
}
currentDate: root.currentDate
openOccurrence: root.openOccurrence
filter: root.filter
onMonthChanged: if(month !== root.selectedDate.getMonth() && !initialMonth) root.selectedDate = new Date (year, month, 1)
onYearChanged: if(year !== root.selectedDate.getFullYear() && !initialMonth) root.selectedDate = new Date (year, month, 1)
......@@ -1013,7 +936,6 @@ Kirigami.ApplicationWindow {
}