File indexing completed on 2024-04-28 05:11:33
0001 /* 0002 SPDX-FileCopyrightText: 2010 Bertjan Broeksema <broeksema@kde.org> 0003 SPDX-FileCopyrightText: 2010 Klarälvdalens Datakonsult AB, a KDAB Group company <info@kdab.com> 0004 0005 SPDX-License-Identifier: LGPL-2.0-or-later 0006 */ 0007 0008 #include "incidencecategories.h" 0009 0010 #include "incidenceeditor_debug.h" 0011 #include "ui_dialogdesktop.h" 0012 0013 #include <Akonadi/CalendarUtils> 0014 #include <Akonadi/TagAttribute> 0015 #include <Akonadi/TagCreateJob> 0016 #include <Akonadi/TagFetchJob> 0017 #include <Akonadi/TagFetchScope> 0018 0019 using namespace IncidenceEditorNG; 0020 0021 IncidenceCategories::IncidenceCategories(Ui::EventOrTodoDesktop *ui) 0022 : mUi(ui) 0023 { 0024 setObjectName(QLatin1StringView("IncidenceCategories")); 0025 0026 connect(mUi->mTagWidget, &Akonadi::TagWidget::selectionChanged, this, &IncidenceCategories::onSelectionChanged); 0027 } 0028 0029 void IncidenceCategories::onSelectionChanged(const Akonadi::Tag::List &list) 0030 { 0031 Q_UNUSED(list) 0032 mDirty = true; 0033 checkDirtyStatus(); 0034 } 0035 0036 void IncidenceCategories::load(const KCalendarCore::Incidence::Ptr &incidence) 0037 { 0038 Q_UNUSED(incidence) 0039 mDirty = false; 0040 mWasDirty = false; 0041 } 0042 0043 void IncidenceCategories::load(const Akonadi::Item &item) 0044 { 0045 mLoadedIncidence = Akonadi::CalendarUtils::incidence(item); 0046 mDirty = false; 0047 mWasDirty = false; 0048 0049 Q_ASSERT(mLoadedIncidence); 0050 if (mLoadedIncidence) { 0051 mMissingCategories = mLoadedIncidence->categories(); 0052 const auto tags = item.tags(); 0053 Akonadi::Tag::List selectedTags; 0054 selectedTags.reserve(mMissingCategories.count()); 0055 for (const auto &tag : tags) { 0056 if (mMissingCategories.removeAll(tag.name()) > 0) { 0057 selectedTags << tag; 0058 } 0059 } 0060 createMissingCategories(); 0061 mUi->mTagWidget->blockSignals(true); 0062 mUi->mTagWidget->setSelection(selectedTags); 0063 mUi->mTagWidget->blockSignals(false); 0064 } 0065 } 0066 0067 void IncidenceCategories::save(const KCalendarCore::Incidence::Ptr &incidence) 0068 { 0069 Q_ASSERT(incidence); 0070 if (mDirty) { 0071 incidence->setCategories(categories()); 0072 } 0073 } 0074 0075 void IncidenceCategories::save(Akonadi::Item &item) 0076 { 0077 const auto &selectedTags = mUi->mTagWidget->selection(); 0078 if (mDirty) { 0079 item.setTags(selectedTags); 0080 } 0081 } 0082 0083 QStringList IncidenceCategories::categories() const 0084 { 0085 QStringList list; 0086 const auto &selectedTags = mUi->mTagWidget->selection(); 0087 list.reserve(selectedTags.count() + mMissingCategories.count()); 0088 for (const Akonadi::Tag &tag : selectedTags) { 0089 list << tag.name(); 0090 } 0091 list << mMissingCategories; 0092 return list; 0093 } 0094 0095 void IncidenceCategories::createMissingCategories() 0096 { 0097 for (const QString &category : std::as_const(mMissingCategories)) { 0098 // Either the tag doesn't exist, or Akonadi doesn't have a tag <-> item 0099 // relation for this category and instance. Try to create a PLAIN tag. 0100 Akonadi::Tag missingTag = Akonadi::Tag(category); 0101 auto createJob = new Akonadi::TagCreateJob(missingTag, this); 0102 createJob->setMergeIfExisting(true); 0103 connect(createJob, &Akonadi::TagCreateJob::result, this, &IncidenceCategories::onMissingTagCreated); 0104 } 0105 } 0106 0107 bool IncidenceCategories::isDirty() const 0108 { 0109 return mDirty; 0110 } 0111 0112 void IncidenceCategories::printDebugInfo() const 0113 { 0114 qCDebug(INCIDENCEEDITOR_LOG) << "selected categories = " << categories(); 0115 qCDebug(INCIDENCEEDITOR_LOG) << "mMissingCategories = " << mMissingCategories; 0116 qCDebug(INCIDENCEEDITOR_LOG) << "mLoadedIncidence->categories() = " << mLoadedIncidence->categories(); 0117 } 0118 0119 void IncidenceCategories::onMissingTagCreated(KJob *job) 0120 { 0121 if (job->error()) { 0122 qCWarning(INCIDENCEEDITOR_LOG) << "Failed to create tag " << job->errorString(); 0123 return; 0124 } 0125 auto createJob = static_cast<Akonadi::TagCreateJob *>(job); 0126 int count = mMissingCategories.removeAll(createJob->tag().name()); 0127 0128 auto selectedTags{mUi->mTagWidget->selection()}; 0129 selectedTags += createJob->tag(); 0130 0131 // If the created tag was one of the instance's missing categories, 0132 // adding it to the widget doesn't make it dirty. 0133 mUi->mTagWidget->blockSignals(count > 0); 0134 mUi->mTagWidget->setSelection(selectedTags); 0135 mUi->mTagWidget->blockSignals(false); 0136 } 0137 0138 #include "moc_incidencecategories.cpp"