8#include "editoritemmanager.h"
11#include "individualmailcomponentfactory.h"
13#include <CalendarSupport/KCalPrefs>
15#include <Akonadi/CalendarUtils>
16#include <Akonadi/Item>
17#include <Akonadi/ItemDeleteJob>
18#include <Akonadi/ItemFetchJob>
19#include <Akonadi/ItemFetchScope>
20#include <Akonadi/ItemMoveJob>
21#include <Akonadi/Monitor>
22#include <Akonadi/Session>
23#include <Akonadi/TagFetchScope>
25#include "incidenceeditor_debug.h"
27#include <KLocalizedString>
34static void updateIncidenceChangerPrivacyFlags(Akonadi::IncidenceChanger *changer, IncidenceEditorNG::EditorItemManager::ItipPrivacyFlags flags)
37 Akonadi::IncidenceChanger::InvitationPrivacyFlags privacyFlags;
38 privacyFlags.setFlag(Akonadi::IncidenceChanger::InvitationPrivacySign, (flags & EditorItemManager::ItipPrivacySign) == EditorItemManager::ItipPrivacySign);
39 privacyFlags.setFlag(Akonadi::IncidenceChanger::InvitationPrivacyEncrypt,
40 (flags & EditorItemManager::ItipPrivacyEncrypt) == EditorItemManager::ItipPrivacyEncrypt);
41 changer->setInvitationPrivacy(privacyFlags);
44namespace IncidenceEditorNG
46class ItemEditorPrivate
48 EditorItemManager *q_ptr;
49 Q_DECLARE_PUBLIC(EditorItemManager)
53 Akonadi::Item mPrevItem;
54 Akonadi::ItemFetchScope mFetchScope;
55 Akonadi::Monitor *mItemMonitor =
nullptr;
56 ItemEditorUi *mItemUi =
nullptr;
57 bool mIsCounterProposal =
false;
59 Akonadi::IncidenceChanger *mChanger =
nullptr;
62 ItemEditorPrivate(Akonadi::IncidenceChanger *changer, EditorItemManager *qq);
63 void itemChanged(
const Akonadi::Item &,
const QSet<QByteArray> &);
64 void itemFetchResult(KJob *job);
65 void itemMoveResult(KJob *job);
66 void onModifyFinished(
const Akonadi::Item &item, Akonadi::IncidenceChanger::ResultCode resultCode,
const QString &errorString);
68 void onCreateFinished(
const Akonadi::Item &item, Akonadi::IncidenceChanger::ResultCode resultCode,
const QString &errorString);
71 void moveJobFinished(KJob *job);
72 void setItem(
const Akonadi::Item &item);
75ItemEditorPrivate::ItemEditorPrivate(Akonadi::IncidenceChanger *changer,
EditorItemManager *qq)
79 mFetchScope.fetchFullPayload();
81 mFetchScope.setFetchTags(
true);
82 mFetchScope.tagFetchScope().setFetchIdOnly(
false);
83 mFetchScope.setFetchRemoteIdentification(
false);
85 mChanger = changer ? changer :
new Akonadi::IncidenceChanger(
new IndividualMailComponentFactory(qq), qq);
89 &Akonadi::IncidenceChanger::modifyFinished,
91 [
this](
int,
const Akonadi::Item &item, Akonadi::IncidenceChanger::ResultCode resultCode,
const QString &errorString) {
92 onModifyFinished(item, resultCode, errorString); });
95 &Akonadi::IncidenceChanger::createFinished,
97 [
this](
int,
const Akonadi::Item &item, Akonadi::IncidenceChanger::ResultCode resultCode,
const QString &errorString) {
98 onCreateFinished(item, resultCode, errorString); });
102void ItemEditorPrivate::moveJobFinished(
KJob *job)
104 Q_Q(EditorItemManager);
106 qCCritical(INCIDENCEEDITOR_LOG) <<
"Error while moving and modifying " << job->
errorString();
107 mItemUi->reject(ItemEditorUi::ItemMoveFailed, job->
errorString());
110 currentAction = EditorItemManager::MoveAndModify;
115void ItemEditorPrivate::itemFetchResult(
KJob *job)
118 Q_Q(EditorItemManager);
120 EditorItemManager::SaveAction action = currentAction;
121 currentAction = EditorItemManager::None;
124 mItemUi->reject(ItemEditorUi::ItemFetchFailed, job->
errorString());
128 auto fetchJob = qobject_cast<Akonadi::ItemFetchJob *>(job);
129 if (fetchJob->items().isEmpty()) {
130 mItemUi->reject(ItemEditorUi::ItemFetchFailed);
135 if (mItemUi->hasSupportedPayload(item)) {
137 if (action != EditorItemManager::None) {
139 Q_EMIT q->itemSaveFinished(action);
142 mItemUi->reject(ItemEditorUi::ItemHasInvalidPayload);
155void ItemEditorPrivate::itemMoveResult(
KJob *job)
158 Q_Q(EditorItemManager);
161 auto moveJob = qobject_cast<Akonadi::ItemMoveJob *>(job);
166 qCCritical(INCIDENCEEDITOR_LOG) <<
"Error while moving item ";
168 Q_EMIT q->itemSaveFailed(EditorItemManager::Move, job->
errorString());
175 currentAction = EditorItemManager::Move;
180void ItemEditorPrivate::onModifyFinished(
const Akonadi::Item &item, Akonadi::IncidenceChanger::ResultCode resultCode,
const QString &errorString)
182 Q_Q(EditorItemManager);
183 if (resultCode == Akonadi::IncidenceChanger::ResultCodeSuccess) {
184 if (mItem.parentCollection() == mItemUi->selectedCollection() || mItem.storageCollectionId() == mItemUi->selectedCollection().id()) {
186 Q_EMIT q->itemSaveFinished(EditorItemManager::Modify);
191 moveJobFinished(job);
194 }
else if (resultCode == Akonadi::IncidenceChanger::ResultCodeUserCanceled) {
195 Q_EMIT q->itemSaveFailed(EditorItemManager::Modify,
QString());
198 qCCritical(INCIDENCEEDITOR_LOG) <<
"Modify failed " << errorString;
199 Q_EMIT q->itemSaveFailed(EditorItemManager::Modify, errorString);
203void ItemEditorPrivate::onCreateFinished(
const Akonadi::Item &item, Akonadi::IncidenceChanger::ResultCode resultCode,
const QString &errorString)
205 Q_Q(EditorItemManager);
206 if (resultCode == Akonadi::IncidenceChanger::ResultCodeSuccess) {
207 currentAction = EditorItemManager::Create;
211 qCCritical(INCIDENCEEDITOR_LOG) <<
"Creation failed " << errorString;
212 Q_EMIT q->itemSaveFailed(EditorItemManager::Create, errorString);
216void ItemEditorPrivate::setupMonitor()
223 mItemMonitor->itemFetchScope().fetchFullPayload();
224 if (mItem.isValid()) {
225 mItemMonitor->setItemMonitored(mItem);
234 Q_Q(EditorItemManager);
235 if (mItemUi->containsPayloadIdentifiers(partIdentifiers)) {
238 dlg->setInformativeText(
239 i18n(
"The item has been changed by another application.\n"
240 "What should be done?"));
246 job->setFetchScope(mFetchScope);
267 : d_ptr(new ItemEditorPrivate(changer, this))
277 Q_D(
const ItemEditor);
281 if (d->mItem.hasPayload()) {
284 qCDebug(INCIDENCEEDITOR_LOG) <<
"Won't return mItem because isValid = " << d->mItem.isValid() <<
"; and haPayload is " << d->mItem.hasPayload();
288 if (d->mPrevItem.hasPayload()) {
291 qCDebug(INCIDENCEEDITOR_LOG) <<
"Won't return mPrevItem because isValid = " << d->mPrevItem.isValid() <<
"; and haPayload is "
292 << d->mPrevItem.hasPayload();
296 qCDebug(INCIDENCEEDITOR_LOG) <<
"state = " << state;
297 Q_ASSERT_X(
false,
"EditorItemManager::item",
"Unknown enum value");
307 job->setFetchScope(d->mFetchScope);
309 d->itemFetchResult(job);
317 if (!d->mItemUi->isValid()) {
322 if (!d->mItemUi->isDirty() && d->mItemUi->selectedCollection() == d->mItem.parentCollection()) {
328 d->mChanger->setGroupwareCommunication(CalendarSupport::KCalPrefs::instance()->useGroupwareCommunication());
329 updateIncidenceChangerPrivacyFlags(d->mChanger, itipPrivacy);
332 Q_ASSERT(updateItem.
id() == d->mItem.id());
333 d->mItem = updateItem;
335 if (d->mItem.isValid()) {
336 Q_ASSERT(d->mItem.parentCollection().isValid());
338 if (d->mItem.parentCollection() == d->mItemUi->selectedCollection() || d->mItem.storageCollectionId() == d->mItemUi->selectedCollection().id()) {
339 (void)d->mChanger->modifyIncidence(d->mItem, oldPayload);
341 Q_ASSERT(d->mItemUi->selectedCollection().isValid());
342 Q_ASSERT(d->mItem.parentCollection().isValid());
344 qCDebug(INCIDENCEEDITOR_LOG) <<
"Moving from" << d->mItem.parentCollection().id() <<
"to" << d->mItemUi->selectedCollection().id();
346 if (d->mItemUi->isDirty()) {
347 (void)d->mChanger->modifyIncidence(d->mItem, oldPayload);
351 d->itemMoveResult(job);
356 if (d->mIsCounterProposal) {
360 Q_ASSERT(d->mItemUi->selectedCollection().isValid());
361 (void)d->mChanger->createFromItem(d->mItem, d->mItemUi->selectedCollection());
366void EditorItemManager::setIsCounterProposal(
bool isCounterProposal)
369 d->mIsCounterProposal = isCounterProposal;
372ItemEditorUi::~ItemEditorUi() =
default;
374bool ItemEditorUi::isValid()
const
380#include "moc_editoritemmanager.cpp"
static Session * defaultSession()
Helper class for creating dialogs that let the user create and edit the payload of Akonadi items (e....
~EditorItemManager() override
Destructs the ItemEditor.
void load(const Akonadi::Item &item)
Loads the.
void save(ItipPrivacyFlags itipPrivacy=ItipPrivacyPlain)
Saves the new or modified item.
EditorItemManager(ItemEditorUi *ui, Akonadi::IncidenceChanger *changer=nullptr)
Creates an ItemEditor for a new Item.
@ Modify
An existing item was modified.
@ Create
A new item was created.
Akonadi::Item item(ItemState state=AfterSave) const
Returns the last saved item with payload or an invalid item when save is not called yet.
@ AfterSave
Returns the last saved item.
@ BeforeSave
Returns an item with the original payload before the last save call.
QSharedPointer< Incidence > Ptr
virtual QString errorString() const
QString i18nc(const char *context, const char *text, const TYPE &arg...)
QString i18n(const char *text, const TYPE &arg...)
AKONADI_CALENDAR_EXPORT KCalendarCore::Incidence::Ptr incidence(const Akonadi::Item &item)
QMetaObject::Connection connect(const QObject *sender, PointerToMemberFunction signal, Functor functor)
void setObjectName(QAnyStringView name)