TodoTreeView.qml 9.07 KB
Newer Older
1
2
3
4
5
6
7
8
// SPDX-FileCopyrightText: 2021 Claudio Cambra <claudio.cambra@gmail.com>

// SPDX-License-Identifier: GPL-2.0-or-later

import QtQuick 2.15
import QtQuick.Layouts 1.1
import QtQuick.Controls 2.15 as QQC2
import org.kde.kirigami 2.14 as Kirigami
9
//import org.kde.kirigamiaddons.treeview 1.0 as KirigamiAddonsTreeView
10
11
12
13
14

import org.kde.kalendar 1.0 as Kalendar
import "dateutils.js" as DateUtils
import "labelutils.js" as LabelUtils

15
TreeListView {
16
17
    id: root

18
    signal addTodo(int collectionId)
19
20
21
22
    signal viewTodo(var todoData, var collectionData)
    signal editTodo(var todoPtr, var collectionId)
    signal deleteTodo(var todoPtr, date deleteDate)
    signal completeTodo(var todoPtr)
23
    signal addSubTodo(var parentWrapper)
24
    signal deselect()
25
26

    property date currentDate: new Date()
27
    property var filter
28
    property var filterCollectionDetails
29

30
    property int showCompleted: Kalendar.TodoSortFilterProxyModel.ShowAll
31
    property int sortBy: Kalendar.TodoSortFilterProxyModel.SummaryColumn
32
33
34
    property bool ascendingOrder: false

    property alias model: todoModel
35
    readonly property bool isDark: LabelUtils.isDarkColor(Kirigami.Theme.backgroundColor)
36
37
38
39

    currentIndex: -1
    clip: true

40
41
42
43
44
45
46
47
48
    MouseArea {
        id: incidenceDeselectorMouseArea
        anchors.fill: parent
        enabled: !Kirigami.Settings.isMobile
        parent: background
        onClicked: deselect()
        propagateComposedEvents: true
    }

49
    Kirigami.PlaceholderMessage {
50
        id: allTasksPlaceholderMessage
51
        anchors.centerIn: parent
52
53
54
55
56
57
58
59
        visible: (!root.filter || !root.filter.collectionId || root.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
60
61
62
63
64
65
66
67
68
69
70
        text: i18n("Calendar is not enabled")
        helpfulAction: Kirigami.Action {
            icon.name: "gtk-yes"
            text: i18n("Enable")
            onTriggered: Kalendar.CalendarManager.allCalendars.setData(Kalendar.CalendarManager.allCalendars.index(root.filterCollectionDetails.allCalendarsRow, 0), 2, 10)
            // HACK: Last two numbers are Qt.Checked and Qt.CheckStateRole
        }
    }

    Kirigami.PlaceholderMessage {
        anchors.centerIn: parent
71
        visible: parent.count === 0 && !allTasksPlaceholderMessage.visible && !collectionPlaceholderMessage.visible
72
        text: root.showCompleted === Kalendar.TodoSortFilterProxyModel.ShowCompleteOnly ?
73
            i18n("No tasks completed") : i18n("No tasks left to complete")
74
75
76
        helpfulAction: Kirigami.Action {
            text: i18n("Create")
            icon.name: "list-add"
77
            onTriggered: root.addTodo(filter.collectionId);
78
79
80
        }
    }

81
82
83
84
    sourceModel: Kalendar.TodoSortFilterProxyModel {
        id: todoModel
        calendar: Kalendar.CalendarManager.calendar
        incidenceChanger: Kalendar.CalendarManager.incidenceChanger
85
        filter: root.filter
86
        showCompleted: root.showCompleted
87
88
        sortBy: root.sortBy
        sortAscending: root.ascendingOrder
89
    }
90
    delegate: BasicTreeItem {
91
92
93
94
95
96
97
98
99
100
101
        id: listItem
        Layout.fillWidth: true

        Binding {
            target: contentItem.anchors
            property: "right"
            value: this.right
        }

        background.anchors.right: this.right
        separatorVisible: true
102
        decoration.decorationHighlightColor: model.color
103
104
        activeBackgroundColor: LabelUtils.getIncidenceBackgroundColor(model.color, root.isDark)
        onActiveBackgroundColorChanged: activeBackgroundColor.a = 0.15
105
106
107

        contentItem: IncidenceMouseArea {
            implicitWidth: todoItemContents.implicitWidth
108
109
            implicitHeight: Kirigami.Settings.isMobile ?
                todoItemContents.implicitHeight + Kirigami.Units.largeSpacing : todoItemContents.implicitHeight + Kirigami.Units.smallSpacing
110
            incidenceData: model
111
            collectionId: model.collectionId
112
            propagateComposedEvents: true
113

114
            onViewClicked: root.viewTodo(model, collectionDetails), listItem.clicked()
115
116
117
            onEditClicked: root.editTodo(model.incidencePtr, model.collectionId)
            onDeleteClicked: root.deleteTodo(model.incidencePtr, model.endTime ? model.endTime : model.startTime ? model.startTime : null)
            onTodoCompletedClicked: model.checked = model.checked === 0 ? 2 : 0
118
            onAddSubTodoClicked: root.addSubTodo(parentWrapper)
119
120
121
122

            GridLayout {
                id: todoItemContents

123
124
125
126
127
128
                anchors {
                    left: parent.left
                    leftMargin: Kirigami.Units.smallSpacing
                    right: parent.right
                    verticalCenter: parent.verticalCenter
                }
129

130
                columns: 4
131
                rows: 2
132
                columnSpacing: Kirigami.Settings.isMobile ? Kirigami.Units.largeSpacing * 2 : Kirigami.Units.largeSpacing
133

134
                ColoredCheckbox {
135
136
137
138
                    id: todoCheckbox

                    Layout.row: 0
                    Layout.column: 0
139
                    Layout.rowSpan: root.width < Kirigami.Units.gridUnit * 28 || recurIcon.visible || dateLabel.visible ? 1 : 2
140

141
142
                    color: model.color
                    radius: 100
143
144
145
146
147
                    checked: model.todoCompleted
                    onClicked: completeTodo(model.incidencePtr)
                }

                QQC2.Label {
148
                    id: nameLabel
149
150
                    Layout.row: 0
                    Layout.column: 1
151
                    Layout.columnSpan: root.width < Kirigami.Units.gridUnit * 28 && (recurIcon.visible || dateLabel.visible) ? 2 : 1
152
                    Layout.rowSpan: occurrenceLayout.visible ? 1 : 2
153
                    Layout.fillWidth: true
154
                    Layout.alignment: Qt.AlignVCenter
155
156
                    text: model.text
                    font.strikeout: model.todoCompleted
157
                    font.weight: Font.Medium
158
159
160
                    wrapMode: Text.Wrap
                }

161
162
                Flow {
                    id: tagFlow
163
                    Layout.fillWidth: true
164
                    Layout.row: root.width < Kirigami.Units.gridUnit * 28 && (recurIcon.visible || dateLabel.visible || priorityLayout.visible) ? 1 : 0
165
166
167
168
                    Layout.column: 2
                    Layout.rowSpan: root.width < Kirigami.Units.gridUnit * 28 ? 1 : 2
                    Layout.columnSpan: root.width < Kirigami.Units.gridUnit * 28 ? 2 : 1
                    Layout.rightMargin: Kirigami.Units.largeSpacing
169
170
171
172
173
174

                    layoutDirection: Qt.RightToLeft
                    spacing: Kirigami.Units.largeSpacing

                    Repeater {
                        id: tagsRepeater
175
                        model: todoCategories // From todoModel
176
177
178
179
180
181
182

                        Tag {
                            implicitWidth: itemLayout.implicitWidth > tagFlow.width ? tagFlow.width : itemLayout.implicitWidth
                            text: modelData
                            showAction: false
                        }
                    }
183
184
                }

185
                RowLayout {
186
                    id: priorityLayout
187
                    Layout.row: 0
188
189
                    Layout.column: 3
                    Layout.rowSpan: root.width < Kirigami.Units.gridUnit * 28 ? 1 : 2
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
                    Layout.alignment: Qt.AlignRight
                    Layout.rightMargin: Kirigami.Units.largeSpacing
                    spacing: 0
                    visible: model.priority > 0

                    Kirigami.Icon {
                        Layout.maximumHeight: priorityLabel.height
                        source: "emblem-important-symbolic"
                    }
                    QQC2.Label {
                        id: priorityLabel
                        text: model.priority
                    }
                }

                RowLayout {
206
                    id: occurrenceLayout
207
208
209
                    Layout.row: 1
                    Layout.column: 1
                    Layout.fillWidth: true
210
                    visible: !isNaN(model.endTime.getTime()) || model.recurs
211
212
213
214
215
216
217
218
219

                    QQC2.Label {
                        id: dateLabel
                        text: LabelUtils.todoDateTimeLabel(model.endTime, model.allDay, model.checked)
                        color: model.isOverdue ? Kirigami.Theme.negativeTextColor : Kirigami.Theme.textColor
                        font: Kirigami.Theme.smallFont
                        visible: !isNaN(model.endTime.getTime())
                    }
                    Kirigami.Icon {
220
                        id: recurIcon
221
222
223
224
225
226
227
228
229
230
231
                        source: "task-recurring"
                        visible: model.recurs
                        Layout.maximumHeight: parent.height
                    }
                }
            }
        }

        onClicked: root.viewTodo(model, Kalendar.CalendarManager.getCollectionDetails(model.collectionId))
    }
}