[pim/eventviews] src: Move KCalUtils::RecurrenceAcctions here
Volker Krause <[email protected]>
| Newsgroups | gmane.comp.kde.cvs |
|---|---|
| Message-ID | <[email protected]> |
Git commit 8dfdefbf47428b4dbd4e04775eb7e35c69fd5f05 by Volker Krause.
Committed on 02/08/2026 at 07:49.
Pushed by vkrause into branch 'master'.
Move KCalUtils::RecurrenceAcctions here
This is the only user.
M +1 -0 src/CMakeLists.txt
M +5 -6 src/agenda/agenda.cpp
M +14 -15 src/eventview.cpp
M +5 -5 src/month/monthitem.cpp
A +116 -0 src/recurrenceactions.cpp [License: LGPL(v2.0+)]
A +125 -0 src/recurrenceactions.h [License: LGPL(v2.0+)]
https://invent.kde.org/pim/eventviews/-/commit/8dfdefbf47428b4dbd4e04775eb7e35c69fd5f05
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index fdc4f2b7..a32d687b 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -17,6 +17,7 @@ target_sources(
eventview.cpp
helper.cpp
prefs.cpp
+ recurrenceactions.cpp
# Agenda view specific code.
agenda/agenda.cpp
agenda/agendaitem.cpp
diff --git a/src/agenda/agenda.cpp b/src/agenda/agenda.cpp
index 4980e39a..385fad7e 100644
--- a/src/agenda/agenda.cpp
+++ b/src/agenda/agenda.cpp
@@ -13,6 +13,7 @@
#include "agenda.h"
#include "agendaview.h"
#include "prefs.h"
+#include "recurrenceactions.h"
#include <Akonadi/CalendarUtils>
#include <Akonadi/IncidenceChanger>
@@ -23,8 +24,6 @@
#include <KCalendarCore/MimeData>
#endif
-#include <KCalUtils/RecurrenceActions>
-
#include "calendarview_debug.h"
#include <KMessageBox>
@@ -1168,13 +1167,13 @@ void Agenda::endItemAction()
}
switch (res) {
- case KCalUtils::RecurrenceActions::AllOccurrences: // All occurrences
+ case RecurrenceActions::AllOccurrences: // All occurrences
// Moving the whole sequence of events is handled by the itemModified below.
modify = true;
break;
- case KCalUtils::RecurrenceActions::SelectedOccurrence:
- case KCalUtils::RecurrenceActions::FutureOccurrences: {
- const bool thisAndFuture = (res == KCalUtils::RecurrenceActions::FutureOccurrences);
+ case RecurrenceActions::SelectedOccurrence:
+ case RecurrenceActions::FutureOccurrences: {
+ const bool thisAndFuture = (res == RecurrenceActions::FutureOccurrences);
modify = true;
multiModify = true;
d->mChanger->startAtomicOperation(i18nc("@info/plain", "Dissociate event from recurrence"));
diff --git a/src/eventview.cpp b/src/eventview.cpp
index 9c405411..5c0e42f4 100644
--- a/src/eventview.cpp
+++ b/src/eventview.cpp
@@ -9,9 +9,9 @@
*/
#include "eventview_p.h"
-using namespace Qt::Literals::StringLiterals;
#include "prefs.h"
+#include "recurrenceactions.h"
#include <CalendarSupport/CollectionSelection>
#include <CalendarSupport/KCalPrefs>
@@ -23,8 +23,6 @@ using namespace Qt::Literals::StringLiterals;
#include <KCalendarCore/CalFilter>
-#include <KCalUtils/RecurrenceActions>
-
#include <KHolidays/HolidayCategories>
#include <KHolidays/HolidayRegion>
@@ -40,6 +38,7 @@ using namespace Qt::Literals::StringLiterals;
#include <QKeyEvent>
#include <QSortFilterProxyModel>
+using namespace Qt::Literals::StringLiterals;
using namespace KCalendarCore;
using namespace EventViews;
using namespace Akonadi;
@@ -116,7 +115,7 @@ int EventView::showMoveRecurDialog(const Incidence::Ptr &inc, QDate date)
{
QDateTime const dateTime(date, {}, QTimeZone::LocalTime);
- int const availableOccurrences = KCalUtils::RecurrenceActions::availableOccurrences(inc, dateTime);
+ int const availableOccurrences = RecurrenceActions::availableOccurrences(inc, dateTime);
const QString caption = i18nc("@title:window", "Changing Recurring Item");
KGuiItem const itemFuture(i18n("Also &Future Items"));
@@ -124,39 +123,39 @@ int EventView::showMoveRecurDialog(const Incidence::Ptr &inc, QDate date)
KGuiItem const itemAll(i18n("&All Occurrences"));
switch (availableOccurrences) {
- case KCalUtils::RecurrenceActions::NoOccurrence:
- return KCalUtils::RecurrenceActions::NoOccurrence;
+ case RecurrenceActions::NoOccurrence:
+ return RecurrenceActions::NoOccurrence;
- case KCalUtils::RecurrenceActions::SelectedOccurrence:
- return KCalUtils::RecurrenceActions::SelectedOccurrence;
+ case RecurrenceActions::SelectedOccurrence:
+ return RecurrenceActions::SelectedOccurrence;
- case KCalUtils::RecurrenceActions::AllOccurrences:
- Q_ASSERT(availableOccurrences & KCalUtils::RecurrenceActions::SelectedOccurrence);
+ case RecurrenceActions::AllOccurrences:
+ Q_ASSERT(availableOccurrences & RecurrenceActions::SelectedOccurrence);
// if there are all kinds of ooccurrences (i.e. past present and future) the user might
// want the option only apply to current and future occurrences, leaving the past ones
// provide a third choice for that ("Also future")
- if (availableOccurrences == KCalUtils::RecurrenceActions::AllOccurrences) {
+ if (availableOccurrences == RecurrenceActions::AllOccurrences) {
const QString message = i18n(
"The item you are trying to change is a recurring item. "
"Should the changes be applied only to this single occurrence, "
"also to future items, or to all items in the recurrence?");
- return KCalUtils::RecurrenceActions::questionSelectedFutureAllCancel(message, caption, itemSelected, itemFuture, itemAll, this);
+ return RecurrenceActions::questionSelectedFutureAllCancel(message, caption, itemSelected, itemFuture, itemAll, this);
}
[[fallthrough]];
default:
- Q_ASSERT(availableOccurrences & KCalUtils::RecurrenceActions::SelectedOccurrence);
+ Q_ASSERT(availableOccurrences & RecurrenceActions::SelectedOccurrence);
// selected occurrence and either past or future occurrences
const QString message = i18n(
"The item you are trying to change is a recurring item. "
"Should the changes be applied only to this single occurrence "
"or to all items in the recurrence?");
- return KCalUtils::RecurrenceActions::questionSelectedAllCancel(message, caption, itemSelected, itemAll, this);
+ return RecurrenceActions::questionSelectedAllCancel(message, caption, itemSelected, itemAll, this);
break;
}
- return KCalUtils::RecurrenceActions::NoOccurrence;
+ return RecurrenceActions::NoOccurrence;
}
void EventView::addCalendar(const Akonadi::CollectionCalendar::Ptr &calendar)
diff --git a/src/month/monthitem.cpp b/src/month/monthitem.cpp
index 65913768..f6a6cd25 100644
--- a/src/month/monthitem.cpp
+++ b/src/month/monthitem.cpp
@@ -11,6 +11,7 @@
#include "monthview.h"
#include "prefs.h"
#include "prefs_base.h" // Ugly, but needed for the Enums
+#include "recurrenceactions.h"
#include <Akonadi/CalendarUtils>
#include <Akonadi/EntityTreeModel>
@@ -20,7 +21,6 @@
#include <CalendarSupport/Utils>
#include <KCalUtils/IncidenceFormatter>
-#include <KCalUtils/RecurrenceActions>
#include "calendarview_debug.h"
#include <KMessageBox>
@@ -426,16 +426,16 @@ void IncidenceMonthItem::updateDates(int startOffset, int endOffset)
if (mIncidence->recurs()) {
const int res = monthScene()->mMonthView->showMoveRecurDialog(mIncidence, startDate());
switch (res) {
- case KCalUtils::RecurrenceActions::AllOccurrences: {
+ case RecurrenceActions::AllOccurrences: {
// All occurrences
KCalendarCore::Incidence::Ptr const oldIncidence(mIncidence->clone());
setNewDates(mIncidence, startOffset, endOffset);
changer->modifyIncidence(item, oldIncidence);
break;
}
- case KCalUtils::RecurrenceActions::SelectedOccurrence: // Just this occurrence
- case KCalUtils::RecurrenceActions::FutureOccurrences: { // All future occurrences
- const bool thisAndFuture = (res == KCalUtils::RecurrenceActions::FutureOccurrences);
+ case RecurrenceActions::SelectedOccurrence: // Just this occurrence
+ case RecurrenceActions::FutureOccurrences: { // All future occurrences
+ const bool thisAndFuture = (res == RecurrenceActions::FutureOccurrences);
QDateTime occurrenceDate(mIncidence->dtStart());
occurrenceDate.setDate(startDate());
KCalendarCore::Incidence::Ptr const newIncidence(KCalendarCore::Calendar::createException(mIncidence, occurrenceDate, thisAndFuture));
diff --git a/src/recurrenceactions.cpp b/src/recurrenceactions.cpp
new file mode 100644
index 00000000..d18132df
--- /dev/null
+++ b/src/recurrenceactions.cpp
@@ -0,0 +1,116 @@
+/*
+ This file is part of the kcal library.
+
+ SPDX-FileCopyrightText: Klarälvdalens Datakonsult AB, a KDAB Group company <[email protected]>
+ SPDX-FileContributor: Kevin Krammer <[email protected]>
+
+ SPDX-FileCopyrightText: 2015 Sérgio Martins <[email protected]>
+
+ SPDX-License-Identifier: LGPL-2.0-or-later
+*/
+
+#include "recurrenceactions.h"
+
+#include <KGuiItem>
+#include <KLocalizedString>
+#include <KMessageBox>
+
+#include <QDialog>
+#include <QDialogButtonBox>
+#include <QPointer>
+#include <QPushButton>
+
+using namespace EventViews;
+using namespace KCalendarCore;
+
+int RecurrenceActions::availableOccurrences(const Incidence::Ptr &incidence, const QDateTime &selectedOccurrence)
+{
+ int result = NoOccurrence;
+
+ if (incidence->recurrence()->recursOn(selectedOccurrence.date(), selectedOccurrence.timeZone())) {
+ result |= SelectedOccurrence;
+ }
+
+ if (incidence->recurrence()->getPreviousDateTime(selectedOccurrence).isValid()) {
+ result |= PastOccurrences;
+ }
+
+ if (incidence->recurrence()->getNextDateTime(selectedOccurrence).isValid()) {
+ result |= FutureOccurrences;
+ }
+
+ return result;
+}
+
+int RecurrenceActions::questionSelectedAllCancel(const QString &message,
+ const QString &caption,
+ const KGuiItem &actionSelected,
+ const KGuiItem &actionAll,
+ QWidget *parent)
+{
+ QPointer<QDialog> const dialog = new QDialog(parent);
+ dialog->setWindowTitle(caption);
+ auto buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel | QDialogButtonBox::No | QDialogButtonBox::Yes, parent);
+ dialog->setObjectName(QLatin1StringView("RecurrenceActions::questionSelectedAllCancel"));
+
+ KGuiItem::assign(buttonBox->button(QDialogButtonBox::Yes), actionSelected);
+ KGuiItem::assign(buttonBox->button(QDialogButtonBox::Ok), actionAll);
+
+ QPushButton *okButton = buttonBox->button(QDialogButtonBox::Ok);
+ okButton->setDefault(true);
+ okButton->setShortcut(Qt::CTRL | Qt::Key_Return);
+ buttonBox->button(QDialogButtonBox::Ok)->setDefault(true);
+
+ bool checkboxResult = false;
+ int const result =
+ KMessageBox::createKMessageBox(dialog, buttonBox, QMessageBox::Question, message, QStringList(), QString(), &checkboxResult, KMessageBox::Notify);
+
+ switch (result) {
+ case QDialogButtonBox::Yes:
+ return SelectedOccurrence;
+ case QDialogButtonBox::Ok:
+ return AllOccurrences;
+ default:
+ return NoOccurrence;
+ }
+}
+
+int RecurrenceActions::questionSelectedFutureAllCancel(const QString &message,
+ const QString &caption,
+ const KGuiItem &actionSelected,
+ const KGuiItem &actionFuture,
+ const KGuiItem &actionAll,
+ QWidget *parent)
+{
+ QPointer<QDialog> const dialog = new QDialog(parent);
+ dialog->setWindowTitle(caption);
+
+ auto buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel | QDialogButtonBox::No | QDialogButtonBox::Yes, parent);
+ dialog->setObjectName(QLatin1StringView("RecurrenceActions::questionSelectedFutureAllCancel"));
+ KGuiItem::assign(buttonBox->button(QDialogButtonBox::Yes), actionSelected);
+ KGuiItem::assign(buttonBox->button(QDialogButtonBox::No), actionFuture);
+ KGuiItem::assign(buttonBox->button(QDialogButtonBox::Ok), actionAll);
+ QPushButton *okButton = buttonBox->button(QDialogButtonBox::Ok);
+ okButton->setDefault(true);
+ okButton->setShortcut(Qt::CTRL | Qt::Key_Return);
+ buttonBox->button(QDialogButtonBox::Ok)->setDefault(true);
+
+ bool checkboxResult = false;
+ QDialogButtonBox::StandardButton const result =
+ KMessageBox::createKMessageBox(dialog, buttonBox, QMessageBox::Question, message, QStringList(), QString(), &checkboxResult, KMessageBox::Notify);
+
+ switch (result) {
+ case QDialogButtonBox::Yes:
+ return SelectedOccurrence;
+ case QDialogButtonBox::No:
+ return FutureOccurrences;
+ case QDialogButtonBox::Ok:
+ return AllOccurrences;
+ default:
+ return NoOccurrence;
+ }
+
+ return NoOccurrence;
+}
+
+#include "moc_recurrenceactions.cpp"
diff --git a/src/recurrenceactions.h b/src/recurrenceactions.h
new file mode 100644
index 00000000..6d831536
--- /dev/null
+++ b/src/recurrenceactions.h
@@ -0,0 +1,125 @@
+/*
+ SPDX-FileCopyrightText: 2010 Klarälvdalens Datakonsult AB, a KDAB Group company <[email protected]>
+ SPDX-FileContributor: Kevin Krammer <[email protected]>
+
+ SPDX-License-Identifier: LGPL-2.0-or-later
+*/
+
+#pragma once
+
+#include <KCalendarCore/Incidence>
+
+class QDateTime;
+class KGuiItem;
+class QWidget;
+
+namespace EventViews
+{
+/*!
+ \brief Utility functions for dealing with recurrences
+
+ Incidences with recurrencies need to be treated differently than single independent ones.
+ For example the user might be given the choice to not only modify a selected occurrence
+ of an incidence but also all that follow that one, etc.
+
+ \author Kevin Krammer, [email protected]
+ \since 4.6
+*/
+namespace RecurrenceActions
+{
+/*!
+ \brief Flags for indicating on which occurrences to work on
+
+ Flags can be OR'ed together to get a combined scope.
+*/
+enum Scope {
+ /*!
+ Scope does not apply to any occurrence
+ */
+ NoOccurrence = 0,
+
+ /*!
+ Scope does include the given/selected occurrence
+ */
+ SelectedOccurrence = 1,
+
+ /*!
+ Scope does include occurrences before the given/selected occurrence
+ */
+ PastOccurrences = 2,
+
+ /*!
+ Scope does include occurrences after the given/selected occurrence
+ */
+ FutureOccurrences = 4,
+
+ /*!
+ Scope does include all occurrences (past, present and future)
+ */
+ AllOccurrences = PastOccurrences | SelectedOccurrence | FutureOccurrences
+};
+
+/*!
+ \brief Checks what scope an action could be applied on for a given incidence
+
+ Checks whether the incidence is occurring on the given date and whether there
+ are occurrences in the past and future.
+
+ \a incidence the incidence of which to check recurrences.
+ \a selectedOccurrence the date (including timespec) to use as the base occurrence,
+ i.e., from which to check for past and future occurrences.
+
+ Returns the #Scope to which actions on the given @incidence can be applied to
+*/
+[[nodiscard]] int availableOccurrences(const KCalendarCore::Incidence::Ptr &incidence, const QDateTime &selectedOccurrence);
+
+/*!
+ \brief Presents a message box with two action choices and cancel to the user
+
+ Shows a message box style question dialog with two action scope buttons and cancel.
+ This is for quick decisions like whether to only modify a single occurrence or all occurrences.
+
+ \a message the message which explains the change and available options.
+ \a caption the dialog's caption.
+ \a actionSelected the GUI item to use for the button representing the
+ #SelectedOccurrence scope.
+ \a actionAll the GUI item to use for the button representing the #AllOccurrences scope.
+ \a parent QWidget parent for the dialog.
+
+ \a #NoOccurrence on cancel, #SelectedOccurrence or #AllOccurrences on the respective action.
+*/
+[[nodiscard]] int
+questionSelectedAllCancel(const QString &message, const QString &caption, const KGuiItem &actionSelected, const KGuiItem &actionAll, QWidget *parent);
+
+/*!
+ \brief Presents a message box with three action choices and cancel to the user
+
+ Shows a message box style question dialog with three action scope buttons and cancel.
+ This is for quick decisions like whether to only modify a single occurrence, to include
+ future or all occurrences.
+
+ Note The calling application code can of course decide to word the future action text
+ in a way that it includes the selected occurrence, e.g. "Also Future Items".
+ The returned value will still just be #FutureOccurrences so the calling code
+ has to include #SelectedOccurrence itself if it passes the value further on
+
+ \a message the message which explains the change and available options.
+ \a caption the dialog's caption.
+ \a actionSelected the GUI item to use for the button representing the
+ #SelectedOccurrence scope.
+ \a actionSelected the GUI item to use for the button representing the
+ #FutureOccurrences scope.
+ \a actionAll the GUI item to use for the button representing the #AllOccurrences scope.
+ \a parent QWidget parent for the dialog.
+
+ \a #NoOccurrence on cancel, #SelectedOccurrence, #FutureOccurrences or #AllOccurrences
+ on the respective action.
+*/
+[[nodiscard]] int questionSelectedFutureAllCancel(const QString &message,
+ const QString &caption,
+ const KGuiItem &actionSelected,
+ const KGuiItem &actionFuture,
+ const KGuiItem &actionAll,
+ QWidget *parent);
+}
+}