From 16228ff2a7c9dc362df027152a6b706ec811eece Mon Sep 17 00:00:00 2001 From: Claudio Cambra Date: Wed, 15 Sep 2021 17:20:15 +0200 Subject: [PATCH 01/10] Replaced strings with tags --- src/contents/ui/IncidenceInfo.qml | 23 +++++--- src/contents/ui/Tag.qml | 90 +++++++++++++++++++++++++++++++ src/resources.qrc | 1 + 3 files changed, 108 insertions(+), 6 deletions(-) create mode 100644 src/contents/ui/Tag.qml diff --git a/src/contents/ui/IncidenceInfo.qml b/src/contents/ui/IncidenceInfo.qml index 482146bb..464622a6 100644 --- a/src/contents/ui/IncidenceInfo.qml +++ b/src/contents/ui/IncidenceInfo.qml @@ -215,13 +215,24 @@ Kirigami.OverlayDrawer { text: i18n("Tags:") visible: incidenceInfo.incidenceWrapper.categories.length > 0 } - QQC2.Label { - Layout.alignment: Qt.AlignTop + Flow { + Layout.preferredWidth: tagInputLayout.implicitWidth Layout.fillWidth: true - - visible: incidenceInfo.incidenceWrapper.categories.length > 0 - text: incidenceInfo.incidenceWrapper.categories.join(i18nc("List separator", ", ")) - wrapMode: Text.Wrap + spacing: Kirigami.Units.largeSpacing + Repeater { + model: incidenceInfo.incidenceWrapper.categories + Tag { + text: modelData + icon.name: "edit-delete-remove" + actionText: i18n("Remove %1 tag", modelData) + /*onClicked: { + const index = flickable.extractor.tags.indexOf(modelData) + if (index > -1) { + flickable.extractor.tags.splice(index, 1) + } + }*/ + } + } } QQC2.Label { diff --git a/src/contents/ui/Tag.qml b/src/contents/ui/Tag.qml new file mode 100644 index 00000000..569b1f87 --- /dev/null +++ b/src/contents/ui/Tag.qml @@ -0,0 +1,90 @@ +/* + * SPDX-FileCopyrightText: (C) 2021 Mikel Johnson + * + * SPDX-License-Identifier: LGPL-2.0-or-later + */ + +import QtQuick 2.15 +import QtQuick.Layouts 1.15 +import QtQuick.Controls 2.15 as QQC2 +import org.kde.kirigami 2.15 as Kirigami + +Item { + id: tagRoot + property string text + property alias icon: toolButton.icon + property alias actionText: toolButton.text + signal clicked() + + implicitWidth: layout.implicitWidth + implicitHeight: layout.implicitHeight + + Kirigami.Theme.colorSet: Kirigami.Theme.View + Kirigami.Theme.inherit: false + + Rectangle { + id: mainBg + anchors.fill: parent + anchors.leftMargin: pointyBit.anchors.leftMargin + pointyBit.width / 2 - radius / 2 + radius: 3 + color: Kirigami.Theme.backgroundColor + border.color: Kirigami.ColorUtils.tintWithAlpha(Kirigami.Theme.backgroundColor, + Kirigami.Theme.textColor, + 0.3) + border.width: 1 + } + Rectangle { + id: pointyBit + antialiasing: true + rotation: 45 + y: (parent.height - height) / 2 + anchors.left: parent.left + anchors.leftMargin: y + radius / 2 + // `parent.height * Math.cos(radians)` fits a rotated square inside the parent. + // `rotation * (Math.PI / 180)` is rotation in radians instead of degrees. + // `Math.PI / 4` is 45 degrees. 180 / 4 is 45. + // `height + radius / 2` accounts for the rounded corners reducing visual size. + height: parent.height * Math.cos(Math.PI / 4) + radius / 2 + width: height + color: mainBg.color + border.width: 1 + border.color: mainBg.border.color + radius: 3 + } + Rectangle { + id: borderCover + antialiasing: true + anchors { + left: parent.left + top: parent.top + bottom: parent.bottom + leftMargin: pointyBit.anchors.leftMargin + pointyBit.width / 2 + margins: mainBg.border.width + } + width: height + color: mainBg.color + radius: mainBg.radius - mainBg.border.width + } + + RowLayout { + id: layout + spacing: Math.round(label.Layout.leftMargin - (toolButton.implicitWidth - toolButton.icon.width)) + anchors.fill: parent + QQC2.Label { + id: label + horizontalAlignment: Qt.AlignLeft + verticalAlignment: Qt.AlignVCenter + Layout.leftMargin: borderCover.anchors.leftMargin + text: tagRoot.text + } + QQC2.ToolButton { + id: toolButton + icon.width: Kirigami.Units.iconSizes.sizeForLabels + icon.height: Kirigami.Units.iconSizes.sizeForLabels + text: i18n("Remove Tag") + display: QQC2.AbstractButton.IconOnly + onClicked: tagRoot.clicked() + } + } +} + diff --git a/src/resources.qrc b/src/resources.qrc index 4f7eafb3..ef36c877 100644 --- a/src/resources.qrc +++ b/src/resources.qrc @@ -36,5 +36,6 @@ contents/ui/NativeMenuItemFromAction.qml contents/ui/KActionFromAction.qml contents/ui/ColoredCheckbox.qml + contents/ui/Tag.qml -- GitLab From f17df04620d76da82a142cb667ea9ee6dcabeaf8 Mon Sep 17 00:00:00 2001 From: Claudio Cambra Date: Wed, 15 Sep 2021 17:29:15 +0200 Subject: [PATCH 02/10] Modified tags to make action hideable --- src/contents/ui/IncidenceInfo.qml | 7 +------ src/contents/ui/Tag.qml | 3 +++ 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/src/contents/ui/IncidenceInfo.qml b/src/contents/ui/IncidenceInfo.qml index 464622a6..6f7a0b9d 100644 --- a/src/contents/ui/IncidenceInfo.qml +++ b/src/contents/ui/IncidenceInfo.qml @@ -225,12 +225,7 @@ Kirigami.OverlayDrawer { text: modelData icon.name: "edit-delete-remove" actionText: i18n("Remove %1 tag", modelData) - /*onClicked: { - const index = flickable.extractor.tags.indexOf(modelData) - if (index > -1) { - flickable.extractor.tags.splice(index, 1) - } - }*/ + showAction: false } } } diff --git a/src/contents/ui/Tag.qml b/src/contents/ui/Tag.qml index 569b1f87..4dfc73e6 100644 --- a/src/contents/ui/Tag.qml +++ b/src/contents/ui/Tag.qml @@ -14,6 +14,7 @@ Item { property string text property alias icon: toolButton.icon property alias actionText: toolButton.text + property bool showAction: true signal clicked() implicitWidth: layout.implicitWidth @@ -75,6 +76,7 @@ Item { horizontalAlignment: Qt.AlignLeft verticalAlignment: Qt.AlignVCenter Layout.leftMargin: borderCover.anchors.leftMargin + Layout.rightMargin: tagRoot.showAction ? 0 : Kirigami.Units.smallSpacing text: tagRoot.text } QQC2.ToolButton { @@ -84,6 +86,7 @@ Item { text: i18n("Remove Tag") display: QQC2.AbstractButton.IconOnly onClicked: tagRoot.clicked() + visible: tagRoot.showAction } } } -- GitLab From 5fbb4994e7328c3c86d7c3903f5a9b8071d0a288 Mon Sep 17 00:00:00 2001 From: Claudio Cambra Date: Wed, 15 Sep 2021 17:36:37 +0200 Subject: [PATCH 03/10] Added more padding to tags and fixed hiding of flow --- src/contents/ui/IncidenceInfo.qml | 1 + src/contents/ui/Tag.qml | 2 ++ 2 files changed, 3 insertions(+) diff --git a/src/contents/ui/IncidenceInfo.qml b/src/contents/ui/IncidenceInfo.qml index 6f7a0b9d..ade8d32b 100644 --- a/src/contents/ui/IncidenceInfo.qml +++ b/src/contents/ui/IncidenceInfo.qml @@ -218,6 +218,7 @@ Kirigami.OverlayDrawer { Flow { Layout.preferredWidth: tagInputLayout.implicitWidth Layout.fillWidth: true + visible: incidenceInfo.incidenceWrapper.categories.length > 0 spacing: Kirigami.Units.largeSpacing Repeater { model: incidenceInfo.incidenceWrapper.categories diff --git a/src/contents/ui/Tag.qml b/src/contents/ui/Tag.qml index 4dfc73e6..eb143383 100644 --- a/src/contents/ui/Tag.qml +++ b/src/contents/ui/Tag.qml @@ -77,6 +77,8 @@ Item { verticalAlignment: Qt.AlignVCenter Layout.leftMargin: borderCover.anchors.leftMargin Layout.rightMargin: tagRoot.showAction ? 0 : Kirigami.Units.smallSpacing + Layout.topMargin: tagRoot.showAction ? 0 : Kirigami.Units.smallSpacing + Layout.bottomMargin: tagRoot.showAction ? 0 : Kirigami.Units.smallSpacing text: tagRoot.text } QQC2.ToolButton { -- GitLab From 9f7d8dbc0877b41be8f59433d76926f341bbea37 Mon Sep 17 00:00:00 2001 From: Claudio Cambra Date: Wed, 15 Sep 2021 18:24:47 +0200 Subject: [PATCH 04/10] TodoTreeView now also uses tag component --- src/contents/ui/IncidenceInfo.qml | 1 - src/contents/ui/TodoTreeView.qml | 23 ++++++++++++++++------- 2 files changed, 16 insertions(+), 8 deletions(-) diff --git a/src/contents/ui/IncidenceInfo.qml b/src/contents/ui/IncidenceInfo.qml index ade8d32b..fdc09164 100644 --- a/src/contents/ui/IncidenceInfo.qml +++ b/src/contents/ui/IncidenceInfo.qml @@ -216,7 +216,6 @@ Kirigami.OverlayDrawer { visible: incidenceInfo.incidenceWrapper.categories.length > 0 } Flow { - Layout.preferredWidth: tagInputLayout.implicitWidth Layout.fillWidth: true visible: incidenceInfo.incidenceWrapper.categories.length > 0 spacing: Kirigami.Units.largeSpacing diff --git a/src/contents/ui/TodoTreeView.qml b/src/contents/ui/TodoTreeView.qml index 3194e8da..5ec24ff8 100644 --- a/src/contents/ui/TodoTreeView.qml +++ b/src/contents/ui/TodoTreeView.qml @@ -129,21 +129,30 @@ KirigamiAddonsTreeView.TreeListView { wrapMode: Text.Wrap } - QQC2.Label { - id: tagLabel + Flow { Layout.fillWidth: true - Layout.row: root.width < Kirigami.Units.gridUnit * 28 && (recurIcon.visible || dateLabel.visible) ? 1 : 0 + Layout.row: root.width < Kirigami.Units.gridUnit * 28 && (recurIcon.visible || dateLabel.visible || priorityLayout.visible) ? 1 : 0 Layout.column: 2 Layout.rowSpan: root.width < Kirigami.Units.gridUnit * 28 ? 1 : 2 Layout.columnSpan: root.width < Kirigami.Units.gridUnit * 28 ? 2 : 1 - Layout.alignment: Qt.AlignVCenter | Qt.AlignRight Layout.rightMargin: Kirigami.Units.largeSpacing - horizontalAlignment: Text.AlignRight - text: model.categoriesDisplay - elide: Text.ElideRight + + layoutDirection: Qt.RightToLeft + visible: categories.length > 0 + spacing: Kirigami.Units.largeSpacing + Repeater { + property var categoriesModel: categories + model: categoriesModel + Tag { + text: modelData + showAction: false + } + Component.onCompleted: if(count === 0 && categories.length > 0) modelChanged(); // HACK: Otherwise half the time tags won't appear + } } RowLayout { + id: priorityLayout Layout.row: 0 Layout.column: 3 Layout.rowSpan: root.width < Kirigami.Units.gridUnit * 28 ? 1 : 2 -- GitLab From 1103592c2ab31bac44a2b2e8958c11b6aedaebbb Mon Sep 17 00:00:00 2001 From: Claudio Cambra Date: Wed, 15 Sep 2021 20:22:42 +0200 Subject: [PATCH 05/10] Properly fixed tags not appearing --- src/contents/ui/ScheduleView.qml | 2 +- src/contents/ui/TodoTreeView.qml | 12 +++++++----- src/todosortfilterproxymodel.cpp | 3 ++- src/todosortfilterproxymodel.h | 25 +++++++++++++++++++++++++ 4 files changed, 35 insertions(+), 7 deletions(-) diff --git a/src/contents/ui/ScheduleView.qml b/src/contents/ui/ScheduleView.qml index b25e41c9..184fde52 100644 --- a/src/contents/ui/ScheduleView.qml +++ b/src/contents/ui/ScheduleView.qml @@ -365,7 +365,7 @@ Kirigami.Page { property int dayOfMultidayIncidence: DateUtils.fullDaysBetweenDates(modelData.startTime, periodStartDate) Component.onCompleted: { - incidenceWrapper = Qt.createQmlObject('import org.kde.kalendar 1.0; IncidenceWrapper {id: incidence}', incidenceInfo, "incidence"); + incidenceWrapper = Qt.createQmlObject('import org.kde.kalendar 1.0; IncidenceWrapper {id: incidence}', incidenceCard, "incidence"); incidenceWrapper.incidencePtr = modelData.incidencePtr } diff --git a/src/contents/ui/TodoTreeView.qml b/src/contents/ui/TodoTreeView.qml index 5ec24ff8..8f8bc3a5 100644 --- a/src/contents/ui/TodoTreeView.qml +++ b/src/contents/ui/TodoTreeView.qml @@ -52,7 +52,7 @@ KirigamiAddonsTreeView.TreeListView { Kirigami.PlaceholderMessage { anchors.centerIn: parent - visible: parent.count === 0 && !root.filterCollectionDetails.isFiltered + visible: parent.count === 0 && root.filterCollectionDetails && !root.filterCollectionDetails.isFiltered text: root.showCompleted === Kalendar.TodoSortFilterProxyModel.ShowCompleteOnly ? i18n("No todos completed") : i18n("No todos left to complete") helpfulAction: Kirigami.Action { @@ -110,6 +110,7 @@ KirigamiAddonsTreeView.TreeListView { Layout.row: 0 Layout.column: 0 + Layout.rowSpan: root.width < Kirigami.Units.gridUnit * 28 || recurIcon.visible || dateLabel.visible ? 1 : 2 color: model.color radius: 100 @@ -122,6 +123,7 @@ KirigamiAddonsTreeView.TreeListView { Layout.row: 0 Layout.column: 1 Layout.columnSpan: root.width < Kirigami.Units.gridUnit * 28 && (recurIcon.visible || dateLabel.visible) ? 2 : 1 + Layout.rowSpan: root.width < Kirigami.Units.gridUnit * 28 || recurIcon.visible || dateLabel.visible ? 1 : 2 Layout.fillWidth: true text: model.text font.strikeout: model.todoCompleted @@ -138,16 +140,16 @@ KirigamiAddonsTreeView.TreeListView { Layout.rightMargin: Kirigami.Units.largeSpacing layoutDirection: Qt.RightToLeft - visible: categories.length > 0 spacing: Kirigami.Units.largeSpacing + Repeater { - property var categoriesModel: categories - model: categoriesModel + id: tagsRepeater + model: todoModel.data(todoModel.index(index, 0), Kalendar.TodoSortFilterProxyModel.CategoriesRole) // Getting categories from the model is *very* faulty + Tag { text: modelData showAction: false } - Component.onCompleted: if(count === 0 && categories.length > 0) modelChanged(); // HACK: Otherwise half the time tags won't appear } } diff --git a/src/todosortfilterproxymodel.cpp b/src/todosortfilterproxymodel.cpp index c39a4b82..006434fa 100644 --- a/src/todosortfilterproxymodel.cpp +++ b/src/todosortfilterproxymodel.cpp @@ -2,6 +2,7 @@ // SPDX-License-Identifier: LGPL-2.1-or-later #include +#include #include class ExtraTodoModel : public KExtraColumnsProxyModel @@ -82,7 +83,7 @@ public: } }; - QVariant data (const QModelIndex &index, int role = Qt::DisplayRole) const override { + QVariant data (const QModelIndex &index, int role = Qt::DisplayRole) const override { if (!index.isValid()) { return QVariant(); } diff --git a/src/todosortfilterproxymodel.h b/src/todosortfilterproxymodel.h index c84530c8..91d00293 100644 --- a/src/todosortfilterproxymodel.h +++ b/src/todosortfilterproxymodel.h @@ -46,6 +46,31 @@ public: }; Q_ENUM(ExtraTodoModelColumns); + enum ExtraTodoModelRoles { + StartTimeRole = TodoModel::CalendarRole + 1, + EndTimeRole, + LocationRole, + AllDayRole, + CompletedRole, + PriorityRole, + ColorRole, + CollectionIdRole, + DurationStringRole, + RecursRole, + IsOverdueRole, + IncidenceIdRole, + IncidenceTypeRole, + IncidenceTypeStrRole, + IncidenceTypeIconRole, + IncidencePtrRole, + TagsRole, + ItemRole, + CategoriesRole, + CategoriesDisplayRole, + TreeDepthRole + }; + Q_ENUM(ExtraTodoModelRoles); + enum ShowComplete { ShowAll = 0, ShowCompleteOnly, -- GitLab From 03d5d0cf9a31a4896d811bbde4add6eabf24882f Mon Sep 17 00:00:00 2001 From: Claudio Cambra Date: Wed, 15 Sep 2021 22:45:49 +0200 Subject: [PATCH 06/10] Separated ExtraTodoModel from TodoSortFilterProxyModel --- src/CMakeLists.txt | 2 +- src/contents/ui/TodoTreeView.qml | 2 +- src/extratodomodel.cpp | 178 ++++++++++++++++++++++++ src/extratodomodel.h | 71 ++++++++++ src/main.cpp | 1 + src/todosortfilterproxymodel.cpp | 227 ------------------------------- src/todosortfilterproxymodel.h | 51 +------ 7 files changed, 253 insertions(+), 279 deletions(-) create mode 100644 src/extratodomodel.cpp create mode 100644 src/extratodomodel.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 854c5330..9b743326 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -2,7 +2,7 @@ # # SPDX-License-Identifier: BSD-2-Clause -add_executable(kalendar about.cpp main.cpp agentconfiguration.cpp incidenceoccurrencemodel.cpp monthviewmodel.cpp calendarmanager.cpp multidayincidencemodel.cpp incidencewrapper.cpp remindersmodel.cpp attendeesmodel.cpp recurrenceexceptionsmodel.cpp attachmentsmodel.cpp contactsmanager.cpp todomodel.cpp incidencetreemodel.cpp todosortfilterproxymodel.cpp kalendarapplication.cpp itemtagsmodel.cpp tagmanager.cpp resources.qrc) +add_executable(kalendar about.cpp main.cpp agentconfiguration.cpp incidenceoccurrencemodel.cpp monthviewmodel.cpp calendarmanager.cpp multidayincidencemodel.cpp incidencewrapper.cpp remindersmodel.cpp attendeesmodel.cpp recurrenceexceptionsmodel.cpp attachmentsmodel.cpp contactsmanager.cpp todomodel.cpp incidencetreemodel.cpp todosortfilterproxymodel.cpp kalendarapplication.cpp itemtagsmodel.cpp tagmanager.cpp extratodomodel.cpp resources.qrc) target_link_libraries(kalendar Qt5::Core diff --git a/src/contents/ui/TodoTreeView.qml b/src/contents/ui/TodoTreeView.qml index 8f8bc3a5..7f4a7cb1 100644 --- a/src/contents/ui/TodoTreeView.qml +++ b/src/contents/ui/TodoTreeView.qml @@ -144,7 +144,7 @@ KirigamiAddonsTreeView.TreeListView { Repeater { id: tagsRepeater - model: todoModel.data(todoModel.index(index, 0), Kalendar.TodoSortFilterProxyModel.CategoriesRole) // Getting categories from the model is *very* faulty + model: todoModel.data(todoModel.index(index, 0), Kalendar.ExtraTodoModel.CategoriesRole) // Getting categories from the model is *very* faulty Tag { text: modelData diff --git a/src/extratodomodel.cpp b/src/extratodomodel.cpp new file mode 100644 index 00000000..8b0666af --- /dev/null +++ b/src/extratodomodel.cpp @@ -0,0 +1,178 @@ +// SPDX-FileCopyrightText: 2021 Claudio Cambra +// SPDX-License-Identifier: LGPL-2.1-or-later + +#include + +ExtraTodoModel::ExtraTodoModel(QObject *parent) +: KExtraColumnsProxyModel(parent) { + const QString todoMimeType = QStringLiteral("application/x-vnd.akonadi.calendar.todo"); + m_todoTreeModel = new IncidenceTreeModel(QStringList() << todoMimeType, this); + const auto pref = EventViews::PrefsPtr(); + m_baseTodoModel = new TodoModel(pref, this); + m_baseTodoModel->setSourceModel(m_todoTreeModel); + setSourceModel(m_baseTodoModel); + + appendColumn(QLatin1String("StartDateTime")); + appendColumn(QLatin1String("EndDateTime")); + appendColumn(QLatin1String("PriorityInt")); + + KSharedConfig::Ptr config = KSharedConfig::openConfig(); + KConfigGroup rColorsConfig(config, "Resources Colors"); + m_colorWatcher = KConfigWatcher::create(config); + + QObject::connect(m_colorWatcher.data(), &KConfigWatcher::configChanged, this, &ExtraTodoModel::loadColors); + + loadColors(); +} + +QVariant ExtraTodoModel::extraColumnData(const QModelIndex &parent, int row, int extraColumn, int role) const { + if (role != Qt::DisplayRole && role != Qt::EditRole) { + return QVariant(); + } + + const auto todoItem = index(row, extraColumn, parent).data(TodoModel::TodoRole).value(); + const auto todoPtr = CalendarSupport::todo(todoItem); + + switch (extraColumn) { + case StartTimeColumn: + return todoPtr->dtStart(); + case EndTimeColumn: + return todoPtr->dtDue(); + case PriorityIntColumn: + return todoPtr->priority(); + default: + return QVariant(); + } +} + +QVariant ExtraTodoModel::data (const QModelIndex &index, int role) const { + if (!index.isValid()) { + return QVariant(); + } + + auto idx = mapToSource(index); + auto todoItem = idx.data(TodoModel::TodoRole).value(); + auto collectionId = todoItem.parentCollection().id(); + auto todoPtr = CalendarSupport::todo(todoItem); + + if(role == Roles::StartTimeRole) { + return todoPtr->dtStart(); + } else if (role == Roles::EndTimeRole) { + return todoPtr->dtDue(); + } else if(role == Roles::LocationRole) { + return todoPtr->location(); + } else if(role == Roles::AllDayRole) { + return todoPtr->allDay(); + } else if(role == Roles::ColorRole) { + QColor nullcolor; + return m_colors.contains(QString::number(collectionId)) ? m_colors[QString::number(collectionId)] : nullcolor; + } else if(role == Roles::CompletedRole) { + return todoPtr->isCompleted(); + } else if(role == Roles::PriorityRole) { + return todoPtr->priority(); + } else if(role == Roles::CollectionIdRole) { + return collectionId; + } else if (role == DurationStringRole) { + KFormat format; + if (todoPtr->allDay()) { + return format.formatSpelloutDuration(24*60*60*1000); // format milliseconds in 1 day + } + return format.formatSpelloutDuration(todoPtr->duration().asSeconds() * 1000); + } else if (role == Roles::RecursRole) { + return todoPtr->recurs(); + } else if (role == Roles::IsOverdueRole) { + return todoPtr->isOverdue(); + } else if(role == Roles::IncidenceIdRole) { + return todoPtr->uid(); + } else if(role == Roles::IncidenceTypeRole) { + return todoPtr->type(); + } else if(role == Roles::IncidenceTypeStrRole) { + return todoPtr->typeStr(); + } else if(role == Roles::IncidenceTypeIconRole) { + return todoPtr->iconName(); + } else if(role == Roles::IncidencePtrRole) { + return QVariant::fromValue(CalendarSupport::incidence(todoItem)); + } else if(role == Roles::TagsRole) { + return QVariant::fromValue(todoItem.tags()); + } else if(role == Roles::ItemRole) { + return QVariant::fromValue(todoItem); + } else if(role == Roles::CategoriesRole) { + return todoPtr->categories(); + } else if(role == Roles::CategoriesDisplayRole) { + return todoPtr->categories().join(i18nc("List separator", ", ")); + } else if(role == Roles::TreeDepthRole) { + int depth = 0; + auto idx = index; + while(idx.parent().isValid()) { + idx = idx.parent(); + depth++; + } + return depth; + } + + return KExtraColumnsProxyModel::data(index, role); +} + +QHash ExtraTodoModel::roleNames() const { + QHash roleNames = KExtraColumnsProxyModel::roleNames(); + roleNames[TodoModel::SummaryRole] = "text"; + roleNames[Roles::StartTimeRole] = "startTime"; + roleNames[Roles::EndTimeRole] = "endTime"; + roleNames[Roles::LocationRole] = "location"; + roleNames[Roles::AllDayRole] = "allDay"; + roleNames[Roles::ColorRole] = "color"; + roleNames[Roles::CompletedRole] = "todoCompleted"; + roleNames[Roles::PriorityRole] = "priority"; + roleNames[Roles::CollectionIdRole] = "collectionId"; + roleNames[Roles::DurationStringRole] = "durationString"; + roleNames[Roles::RecursRole] = "recurs"; + roleNames[Roles::IsOverdueRole] = "isOverdue"; + roleNames[Roles::IncidenceIdRole] = "incidenceId"; + roleNames[Roles::IncidenceTypeRole] = "incidenceType"; + roleNames[Roles::IncidenceTypeStrRole] = "incidenceTypeStr"; + roleNames[Roles::IncidenceTypeIconRole] = "incidenceTypeIcon"; + roleNames[Roles::IncidencePtrRole] = "incidencePtr"; + roleNames[Roles::TagsRole] = "tags"; + roleNames[Roles::ItemRole] = "item"; + roleNames[Roles::CategoriesRole] = "categories"; + roleNames[Roles::CategoriesDisplayRole] = "categoriesDisplay"; + roleNames[Roles::TreeDepthRole] = "treeDepth"; + + return roleNames; +} + +Akonadi::ETMCalendar::Ptr ExtraTodoModel::calendar() { + return m_calendar; +} + +void ExtraTodoModel::setCalendar(Akonadi::ETMCalendar::Ptr calendar) { + m_calendar = calendar; + m_todoTreeModel->setSourceModel(calendar->model()); + m_baseTodoModel->setCalendar(calendar); +} + +void ExtraTodoModel::setIncidenceChanger(Akonadi::IncidenceChanger* changer) { + m_baseTodoModel->setIncidenceChanger(changer); +} + +QHash ExtraTodoModel::colorCache() { + return m_colors; +} + +void ExtraTodoModel::setColorCache(QHash colorCache) { + m_colors = colorCache; +} + +void ExtraTodoModel::loadColors() { + KSharedConfig::Ptr config = KSharedConfig::openConfig(); + KConfigGroup rColorsConfig(config, "Resources Colors"); + const QStringList colorKeyList = rColorsConfig.keyList(); + + for (const QString &key : colorKeyList) { + QColor color = rColorsConfig.readEntry(key, QColor("blue")); + m_colors[key] = color; + } + Q_EMIT layoutChanged(); +} + +Q_DECLARE_METATYPE(KCalendarCore::Incidence::Ptr) diff --git a/src/extratodomodel.h b/src/extratodomodel.h new file mode 100644 index 00000000..ac811046 --- /dev/null +++ b/src/extratodomodel.h @@ -0,0 +1,71 @@ +// SPDX-FileCopyrightText: 2021 Claudio Cambra +// SPDX-License-Identifier: LGPL-2.1-or-later + +#pragma once +#include +#include +#include +#include +#include +#include +#include + +class ExtraTodoModel : public KExtraColumnsProxyModel +{ + Q_OBJECT + +public: + enum Columns { + StartTimeColumn = 0, + EndTimeColumn, + PriorityIntColumn + }; + Q_ENUM(Columns); + enum Roles { // Remember to update roles in todosortfilterproxymodel + StartTimeRole = TodoModel::CalendarRole + 1, + EndTimeRole, + LocationRole, + AllDayRole, + CompletedRole, + PriorityRole, + ColorRole, + CollectionIdRole, + DurationStringRole, + RecursRole, + IsOverdueRole, + IncidenceIdRole, + IncidenceTypeRole, + IncidenceTypeStrRole, + IncidenceTypeIconRole, + IncidencePtrRole, + TagsRole, + ItemRole, + CategoriesRole, + CategoriesDisplayRole, + TreeDepthRole + }; + Q_ENUM(Roles); + + ExtraTodoModel(QObject *parent = nullptr); + ~ExtraTodoModel() = default; + + QVariant extraColumnData(const QModelIndex &parent, int row, int extraColumn, int role = Qt::DisplayRole) const override; + QVariant data (const QModelIndex &index, int role = Qt::DisplayRole) const override; + QHash roleNames() const override; + + Akonadi::ETMCalendar::Ptr calendar(); + void setCalendar(Akonadi::ETMCalendar::Ptr calendar); + void setIncidenceChanger(Akonadi::IncidenceChanger* changer); + + QHash colorCache(); + void setColorCache(QHash colorCache); + void loadColors(); + +private: + Akonadi::ETMCalendar::Ptr m_calendar; + IncidenceTreeModel *m_todoTreeModel = nullptr; + TodoModel *m_baseTodoModel = nullptr; + QHash m_colors; + KConfigWatcher::Ptr m_colorWatcher; +}; + diff --git a/src/main.cpp b/src/main.cpp index 20dab3a0..77873a59 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -69,6 +69,7 @@ int main(int argc, char *argv[]) qmlRegisterType("org.kde.kalendar", 1, 0, "AttendeesModel"); qmlRegisterType("org.kde.kalendar", 1, 0, "MultiDayIncidenceModel"); qmlRegisterType("org.kde.kalendar", 1, 0, "IncidenceOccurrenceModel"); + qmlRegisterType("org.kde.kalendar", 1, 0, "ExtraTodoModel"); qmlRegisterType("org.kde.kalendar", 1, 0, "TodoSortFilterProxyModel"); qmlRegisterType("org.kde.kalendar", 1, 0, "MonthViewModel"); qmlRegisterType("org.kde.kalendar", 1, 0, "ItemTagsModel"); diff --git a/src/todosortfilterproxymodel.cpp b/src/todosortfilterproxymodel.cpp index 006434fa..2d84a1df 100644 --- a/src/todosortfilterproxymodel.cpp +++ b/src/todosortfilterproxymodel.cpp @@ -1,230 +1,8 @@ // SPDX-FileCopyrightText: 2021 Claudio Cambra // SPDX-License-Identifier: LGPL-2.1-or-later -#include -#include #include -class ExtraTodoModel : public KExtraColumnsProxyModel -{ - Q_OBJECT - -public: - enum Columns { - StartTimeColumn = 0, - EndTimeColumn, - PriorityIntColumn - }; - Q_ENUM(Columns); - enum Roles { // Remember to update roles in todosortfilterproxymodel - StartTimeRole = TodoModel::CalendarRole + 1, - EndTimeRole, - LocationRole, - AllDayRole, - CompletedRole, - PriorityRole, - ColorRole, - CollectionIdRole, - DurationStringRole, - RecursRole, - IsOverdueRole, - IncidenceIdRole, - IncidenceTypeRole, - IncidenceTypeStrRole, - IncidenceTypeIconRole, - IncidencePtrRole, - TagsRole, - ItemRole, - CategoriesRole, - CategoriesDisplayRole, - TreeDepthRole - }; - Q_ENUM(Roles); - - ExtraTodoModel(QObject *parent = nullptr) : KExtraColumnsProxyModel(parent) { - const QString todoMimeType = QStringLiteral("application/x-vnd.akonadi.calendar.todo"); - m_todoTreeModel = new IncidenceTreeModel(QStringList() << todoMimeType, this); - const auto pref = EventViews::PrefsPtr(); - m_baseTodoModel = new TodoModel(pref, this); - m_baseTodoModel->setSourceModel(m_todoTreeModel); - setSourceModel(m_baseTodoModel); - - appendColumn(QLatin1String("StartDateTime")); - appendColumn(QLatin1String("EndDateTime")); - appendColumn(QLatin1String("PriorityInt")); - - KSharedConfig::Ptr config = KSharedConfig::openConfig(); - KConfigGroup rColorsConfig(config, "Resources Colors"); - m_colorWatcher = KConfigWatcher::create(config); - - QObject::connect(m_colorWatcher.data(), &KConfigWatcher::configChanged, this, &ExtraTodoModel::loadColors); - - loadColors(); - }; - ~ExtraTodoModel() = default; - - QVariant extraColumnData(const QModelIndex &parent, int row, int extraColumn, int role = Qt::DisplayRole) const override { - if (role != Qt::DisplayRole && role != Qt::EditRole) { - return QVariant(); - } - - const auto todoItem = index(row, extraColumn, parent).data(TodoModel::TodoRole).value(); - const auto todoPtr = CalendarSupport::todo(todoItem); - - switch (extraColumn) { - case StartTimeColumn: - return todoPtr->dtStart(); - case EndTimeColumn: - return todoPtr->dtDue(); - case PriorityIntColumn: - return todoPtr->priority(); - default: - return QVariant(); - } - }; - - QVariant data (const QModelIndex &index, int role = Qt::DisplayRole) const override { - if (!index.isValid()) { - return QVariant(); - } - - auto idx = mapToSource(index); - auto todoItem = idx.data(TodoModel::TodoRole).value(); - auto collectionId = todoItem.parentCollection().id(); - auto todoPtr = CalendarSupport::todo(todoItem); - - if(role == Roles::StartTimeRole) { - return todoPtr->dtStart(); - } else if (role == Roles::EndTimeRole) { - return todoPtr->dtDue(); - } else if(role == Roles::LocationRole) { - return todoPtr->location(); - } else if(role == Roles::AllDayRole) { - return todoPtr->allDay(); - } else if(role == Roles::ColorRole) { - QColor nullcolor; - return m_colors.contains(QString::number(collectionId)) ? m_colors[QString::number(collectionId)] : nullcolor; - } else if(role == Roles::CompletedRole) { - return todoPtr->isCompleted(); - } else if(role == Roles::PriorityRole) { - return todoPtr->priority(); - } else if(role == Roles::CollectionIdRole) { - return collectionId; - } else if (role == DurationStringRole) { - KFormat format; - if (todoPtr->allDay()) { - return format.formatSpelloutDuration(24*60*60*1000); // format milliseconds in 1 day - } - return format.formatSpelloutDuration(todoPtr->duration().asSeconds() * 1000); - } else if (role == Roles::RecursRole) { - return todoPtr->recurs(); - } else if (role == Roles::IsOverdueRole) { - return todoPtr->isOverdue(); - } else if(role == Roles::IncidenceIdRole) { - return todoPtr->uid(); - } else if(role == Roles::IncidenceTypeRole) { - return todoPtr->type(); - } else if(role == Roles::IncidenceTypeStrRole) { - return todoPtr->typeStr(); - } else if(role == Roles::IncidenceTypeIconRole) { - return todoPtr->iconName(); - } else if(role == Roles::IncidencePtrRole) { - return QVariant::fromValue(CalendarSupport::incidence(todoItem)); - } else if(role == Roles::TagsRole) { - return QVariant::fromValue(todoItem.tags()); - } else if(role == Roles::ItemRole) { - return QVariant::fromValue(todoItem); - } else if(role == Roles::CategoriesRole) { - return todoPtr->categories(); - } else if(role == Roles::CategoriesDisplayRole) { - return todoPtr->categories().join(i18nc("List separator", ", ")); - } else if(role == Roles::TreeDepthRole) { - int depth = 0; - auto idx = index; - while(idx.parent().isValid()) { - idx = idx.parent(); - depth++; - } - return depth; - } - - return KExtraColumnsProxyModel::data(index, role); - }; - - QHash roleNames() const override { - QHash roleNames = KExtraColumnsProxyModel::roleNames(); - roleNames[TodoModel::SummaryRole] = "text"; - roleNames[Roles::StartTimeRole] = "startTime"; - roleNames[Roles::EndTimeRole] = "endTime"; - roleNames[Roles::LocationRole] = "location"; - roleNames[Roles::AllDayRole] = "allDay"; - roleNames[Roles::ColorRole] = "color"; - roleNames[Roles::CompletedRole] = "todoCompleted"; - roleNames[Roles::PriorityRole] = "priority"; - roleNames[Roles::CollectionIdRole] = "collectionId"; - roleNames[Roles::DurationStringRole] = "durationString"; - roleNames[Roles::RecursRole] = "recurs"; - roleNames[Roles::IsOverdueRole] = "isOverdue"; - roleNames[Roles::IncidenceIdRole] = "incidenceId"; - roleNames[Roles::IncidenceTypeRole] = "incidenceType"; - roleNames[Roles::IncidenceTypeStrRole] = "incidenceTypeStr"; - roleNames[Roles::IncidenceTypeIconRole] = "incidenceTypeIcon"; - roleNames[Roles::IncidencePtrRole] = "incidencePtr"; - roleNames[Roles::TagsRole] = "tags"; - roleNames[Roles::ItemRole] = "item"; - roleNames[Roles::CategoriesRole] = "categories"; - roleNames[Roles::CategoriesDisplayRole] = "categoriesDisplay"; - roleNames[Roles::TreeDepthRole] = "treeDepth"; - - return roleNames; - } - - Akonadi::ETMCalendar::Ptr calendar() { - return m_calendar; - } - - void setCalendar(Akonadi::ETMCalendar::Ptr calendar) { - m_calendar = calendar; - m_todoTreeModel->setSourceModel(calendar->model()); - m_baseTodoModel->setCalendar(calendar); - }; - - void setIncidenceChanger(Akonadi::IncidenceChanger* changer) { - m_baseTodoModel->setIncidenceChanger(changer); - }; - - QHash colorCache() { - return m_colors; - }; - - void setColorCache(QHash colorCache) { - m_colors = colorCache; - }; - - void loadColors() { - KSharedConfig::Ptr config = KSharedConfig::openConfig(); - KConfigGroup rColorsConfig(config, "Resources Colors"); - const QStringList colorKeyList = rColorsConfig.keyList(); - - for (const QString &key : colorKeyList) { - QColor color = rColorsConfig.readEntry(key, QColor("blue")); - m_colors[key] = color; - } - Q_EMIT layoutChanged(); - } - -private: - Akonadi::ETMCalendar::Ptr m_calendar; - IncidenceTreeModel *m_todoTreeModel = nullptr; - TodoModel *m_baseTodoModel = nullptr; - QHash m_colors; - KConfigWatcher::Ptr m_colorWatcher; -}; - - - - - TodoSortFilterProxyModel::TodoSortFilterProxyModel(QObject* parent) : QSortFilterProxyModel(parent) { @@ -385,8 +163,3 @@ void TodoSortFilterProxyModel::filterTodoName(QString name, int showCompleted) invalidateFilter(); Q_EMIT layoutChanged(); } - - -Q_DECLARE_METATYPE(KCalendarCore::Incidence::Ptr) -#include "todosortfilterproxymodel.moc" - diff --git a/src/todosortfilterproxymodel.h b/src/todosortfilterproxymodel.h index 91d00293..34cfbe0e 100644 --- a/src/todosortfilterproxymodel.h +++ b/src/todosortfilterproxymodel.h @@ -3,19 +3,14 @@ #pragma once #include -#include #include #include -#include -#include -#include -#include #include #include #include +#include #include -class ExtraTodoModel; class TodoSortFilterProxyModel : public QSortFilterProxyModel { @@ -27,50 +22,6 @@ class TodoSortFilterProxyModel : public QSortFilterProxyModel Q_PROPERTY(int showCompleted READ showCompleted WRITE setShowCompleted NOTIFY showCompletedChanged) public: - enum BaseTodoModelColumns { - SummaryColumn = TodoModel::SummaryColumn, - PriorityColumn = TodoModel::PriorityColumn, - PercentColumn = TodoModel::PercentColumn, - StartDateColumn = TodoModel::StartDateColumn, - DueDateColumn = TodoModel::DueDateColumn, - CategoriesColumn = TodoModel::CategoriesColumn, - DescriptionColumn = TodoModel::DescriptionColumn, - CalendarColumn = TodoModel::CalendarColumn, - }; - Q_ENUM(BaseTodoModelColumns); - - enum ExtraTodoModelColumns { - StartTimeColumn = TodoModel::ColumnCount, - EndTimeColumn, - PriorityIntColumn - }; - Q_ENUM(ExtraTodoModelColumns); - - enum ExtraTodoModelRoles { - StartTimeRole = TodoModel::CalendarRole + 1, - EndTimeRole, - LocationRole, - AllDayRole, - CompletedRole, - PriorityRole, - ColorRole, - CollectionIdRole, - DurationStringRole, - RecursRole, - IsOverdueRole, - IncidenceIdRole, - IncidenceTypeRole, - IncidenceTypeStrRole, - IncidenceTypeIconRole, - IncidencePtrRole, - TagsRole, - ItemRole, - CategoriesRole, - CategoriesDisplayRole, - TreeDepthRole - }; - Q_ENUM(ExtraTodoModelRoles); - enum ShowComplete { ShowAll = 0, ShowCompleteOnly, -- GitLab From 18562bb12abb5ddaa6bc3f4b9f3f1d2da930ca93 Mon Sep 17 00:00:00 2001 From: Claudio Cambra Date: Wed, 15 Sep 2021 23:12:26 +0200 Subject: [PATCH 07/10] Re-fixed sorting --- src/extratodomodel.h | 1 + src/todosortfilterproxymodel.h | 19 +++++++++++++++++++ 2 files changed, 20 insertions(+) diff --git a/src/extratodomodel.h b/src/extratodomodel.h index ac811046..bda3c8c5 100644 --- a/src/extratodomodel.h +++ b/src/extratodomodel.h @@ -21,6 +21,7 @@ public: PriorityIntColumn }; Q_ENUM(Columns); + enum Roles { // Remember to update roles in todosortfilterproxymodel StartTimeRole = TodoModel::CalendarRole + 1, EndTimeRole, diff --git a/src/todosortfilterproxymodel.h b/src/todosortfilterproxymodel.h index 34cfbe0e..f346047d 100644 --- a/src/todosortfilterproxymodel.h +++ b/src/todosortfilterproxymodel.h @@ -22,6 +22,25 @@ class TodoSortFilterProxyModel : public QSortFilterProxyModel Q_PROPERTY(int showCompleted READ showCompleted WRITE setShowCompleted NOTIFY showCompletedChanged) public: + enum BaseTodoModelColumns { + SummaryColumn = TodoModel::SummaryColumn, + PriorityColumn = TodoModel::PriorityColumn, + PercentColumn = TodoModel::PercentColumn, + StartDateColumn = TodoModel::StartDateColumn, + DueDateColumn = TodoModel::DueDateColumn, + CategoriesColumn = TodoModel::CategoriesColumn, + DescriptionColumn = TodoModel::DescriptionColumn, + CalendarColumn = TodoModel::CalendarColumn, + }; + Q_ENUM(BaseTodoModelColumns); + + enum ExtraTodoModelColumns { + StartTimeColumn = TodoModel::ColumnCount, + EndTimeColumn, + PriorityIntColumn + }; + Q_ENUM(ExtraTodoModelColumns); + enum ShowComplete { ShowAll = 0, ShowCompleteOnly, -- GitLab From 1ee627e741129b73590ba289ec6735d99c0063dd Mon Sep 17 00:00:00 2001 From: Claudio Cambra Date: Wed, 15 Sep 2021 23:46:46 +0200 Subject: [PATCH 08/10] Fixed sizing with long tags in limited spaces --- src/contents/ui/Tag.qml | 3 +++ src/contents/ui/TodoTreeView.qml | 2 ++ 2 files changed, 5 insertions(+) diff --git a/src/contents/ui/Tag.qml b/src/contents/ui/Tag.qml index eb143383..e21a0011 100644 --- a/src/contents/ui/Tag.qml +++ b/src/contents/ui/Tag.qml @@ -15,6 +15,7 @@ Item { property alias icon: toolButton.icon property alias actionText: toolButton.text property bool showAction: true + property alias itemLayout: layout signal clicked() implicitWidth: layout.implicitWidth @@ -75,11 +76,13 @@ Item { id: label horizontalAlignment: Qt.AlignLeft verticalAlignment: Qt.AlignVCenter + Layout.fillWidth: true Layout.leftMargin: borderCover.anchors.leftMargin Layout.rightMargin: tagRoot.showAction ? 0 : Kirigami.Units.smallSpacing Layout.topMargin: tagRoot.showAction ? 0 : Kirigami.Units.smallSpacing Layout.bottomMargin: tagRoot.showAction ? 0 : Kirigami.Units.smallSpacing text: tagRoot.text + elide: Text.ElideRight } QQC2.ToolButton { id: toolButton diff --git a/src/contents/ui/TodoTreeView.qml b/src/contents/ui/TodoTreeView.qml index 7f4a7cb1..2e875fee 100644 --- a/src/contents/ui/TodoTreeView.qml +++ b/src/contents/ui/TodoTreeView.qml @@ -132,6 +132,7 @@ KirigamiAddonsTreeView.TreeListView { } Flow { + id: tagFlow Layout.fillWidth: true Layout.row: root.width < Kirigami.Units.gridUnit * 28 && (recurIcon.visible || dateLabel.visible || priorityLayout.visible) ? 1 : 0 Layout.column: 2 @@ -147,6 +148,7 @@ KirigamiAddonsTreeView.TreeListView { model: todoModel.data(todoModel.index(index, 0), Kalendar.ExtraTodoModel.CategoriesRole) // Getting categories from the model is *very* faulty Tag { + implicitWidth: itemLayout.implicitWidth > tagFlow.width ? tagFlow.width : itemLayout.implicitWidth text: modelData showAction: false } -- GitLab From 90810ece9f04457d7222132687ddc149939b2802 Mon Sep 17 00:00:00 2001 From: Claudio Cambra Date: Thu, 16 Sep 2021 14:03:48 +0200 Subject: [PATCH 09/10] Filtering tag in todo view heading is now also a tag --- src/contents/ui/Tag.qml | 16 ++++++++++++++++ src/contents/ui/TodoPage.qml | 30 ++++++++++++++---------------- 2 files changed, 30 insertions(+), 16 deletions(-) diff --git a/src/contents/ui/Tag.qml b/src/contents/ui/Tag.qml index e21a0011..24db5423 100644 --- a/src/contents/ui/Tag.qml +++ b/src/contents/ui/Tag.qml @@ -15,7 +15,10 @@ Item { property alias icon: toolButton.icon property alias actionText: toolButton.text property bool showAction: true + property bool isHeading: false property alias itemLayout: layout + property alias labelItem: label + property alias headingItem: heading signal clicked() implicitWidth: layout.implicitWidth @@ -83,6 +86,19 @@ Item { Layout.bottomMargin: tagRoot.showAction ? 0 : Kirigami.Units.smallSpacing text: tagRoot.text elide: Text.ElideRight + visible: !tagRoot.isHeading + } + Kirigami.Heading { + id: heading + horizontalAlignment: Qt.AlignLeft + verticalAlignment: Qt.AlignVCenter + Layout.fillWidth: true + Layout.leftMargin: borderCover.anchors.leftMargin + Layout.topMargin: Kirigami.Units.smallSpacing + Layout.bottomMargin: Kirigami.Units.smallSpacing + text: tagRoot.text + elide: Text.ElideRight + visible: tagRoot.isHeading } QQC2.ToolButton { id: toolButton diff --git a/src/contents/ui/TodoPage.qml b/src/contents/ui/TodoPage.qml index a10da221..0438affc 100644 --- a/src/contents/ui/TodoPage.qml +++ b/src/contents/ui/TodoPage.qml @@ -163,7 +163,7 @@ Kirigami.Page { Kirigami.Heading { Layout.row: 0 Layout.column: 0 - Layout.columnSpan: root.width < Kirigami.Units.gridUnit * 30 || tagLayout.visible ? 1 : 2 + Layout.columnSpan: root.width < Kirigami.Units.gridUnit * 30 || filterTag.visible ? 1 : 2 Layout.fillWidth: true text: root.filterCollectionDetails && root.filterCollectionId > -1 ? root.filterCollectionDetails.displayName : i18n("All Todos") @@ -173,31 +173,29 @@ Kirigami.Page { elide: Text.ElideRight } - RowLayout { - id: tagLayout + Tag { + id: filterTag Layout.row: 0 Layout.column: 1 Layout.alignment: Qt.AlignRight visible: root.filterCategoryString + text: root.filterCategoryString - Kirigami.Heading { - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - text: root.filterCategoryString - color: root.filterCollectionDetails ? - LabelUtils.getIncidenceLabelColor(root.filterCollectionDetails.color, root.isDark) : Kirigami.Theme.textColor - } + isHeading: true + headingItem.color: root.filterCollectionDetails ? + LabelUtils.getIncidenceLabelColor(root.filterCollectionDetails.color, root.isDark) : Kirigami.Theme.textColor + headingItem.font.weight: Font.Bold - QQC2.ToolButton { - icon.name: "edit-clear" - onClicked: root.filterCategoryString = "" - } + icon.name: "edit-delete-remove" + onClicked: root.filterCategoryString = "" + actionText: i18n("Remove filtering tag") } Kirigami.SearchField { id: searchField - Layout.column: root.width < Kirigami.Units.gridUnit * 30 || tagLayout.visible ? 0 : 1 - Layout.row: root.width < Kirigami.Units.gridUnit * 30 || tagLayout.visible ? 1 : 0 - Layout.columnSpan: root.width < Kirigami.Units.gridUnit * 30 || tagLayout.visible ? 2 : 1 + Layout.column: root.width < Kirigami.Units.gridUnit * 30 || filterTag.visible ? 0 : 1 + Layout.row: root.width < Kirigami.Units.gridUnit * 30 || filterTag.visible ? 1 : 0 + Layout.columnSpan: root.width < Kirigami.Units.gridUnit * 30 || filterTag.visible ? 2 : 1 Layout.fillWidth: Layout.row === 1 onTextChanged: incompleteView.model.filterTodoName(text); } -- GitLab From 54288348748059302e22f92a4bfb3d900da8a7f2 Mon Sep 17 00:00:00 2001 From: Claudio Cambra Date: Thu, 16 Sep 2021 14:26:43 +0200 Subject: [PATCH 10/10] Tag header now adjusts to available width --- src/contents/ui/TodoPage.qml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/contents/ui/TodoPage.qml b/src/contents/ui/TodoPage.qml index 0438affc..934720af 100644 --- a/src/contents/ui/TodoPage.qml +++ b/src/contents/ui/TodoPage.qml @@ -181,6 +181,8 @@ Kirigami.Page { visible: root.filterCategoryString text: root.filterCategoryString + implicitWidth: itemLayout.implicitWidth > headerLayout.width - Kirigami.Units.gridUnit * 6 ? + headerLayout.width - Kirigami.Units.gridUnit * 6 : itemLayout.implicitWidth isHeading: true headingItem.color: root.filterCollectionDetails ? LabelUtils.getIncidenceLabelColor(root.filterCollectionDetails.color, root.isDark) : Kirigami.Theme.textColor -- GitLab