File indexing completed on 2024-11-17 04:40:41
0001 /* 0002 This file is part of Akonadi Contact. 0003 0004 SPDX-FileCopyrightText: 2009 Tobias Koenig <tokoe@kde.org> 0005 0006 SPDX-License-Identifier: LGPL-2.0-or-later 0007 */ 0008 0009 #include "contactgroupviewer.h" 0010 0011 #include "job/contactgroupexpandjob.h" 0012 #include "standardcontactgroupformatter.h" 0013 #include "textbrowser_p.h" 0014 0015 #include <Akonadi/CollectionFetchJob> 0016 #include <Akonadi/EntityDisplayAttribute> 0017 #include <Akonadi/Item> 0018 #include <Akonadi/ItemFetchScope> 0019 #include <KContacts/Addressee> 0020 #include <KContacts/ContactGroup> 0021 0022 #include <KLocalizedString> 0023 0024 #include <QIcon> 0025 #include <QVBoxLayout> 0026 0027 using namespace Akonadi; 0028 using namespace Akonadi; 0029 0030 class Akonadi::ContactGroupViewerPrivate 0031 { 0032 public: 0033 explicit ContactGroupViewerPrivate(ContactGroupViewer *parent) 0034 : mParent(parent) 0035 { 0036 mBrowser = new Akonadi::TextBrowser; 0037 0038 static QPixmap groupPixmap = QIcon::fromTheme(QStringLiteral("x-mail-distribution-list")).pixmap(QSize(100, 100)); 0039 mBrowser->document()->addResource(QTextDocument::ImageResource, QUrl(QStringLiteral("group_photo")), groupPixmap); 0040 0041 mStandardContactGroupFormatter = new StandardContactGroupFormatter; 0042 mContactGroupFormatter = mStandardContactGroupFormatter; 0043 } 0044 0045 ~ContactGroupViewerPrivate() 0046 { 0047 delete mStandardContactGroupFormatter; 0048 } 0049 0050 void updateView() 0051 { 0052 mParent->setWindowTitle(i18nc("@title:window", "Contact Group %1", mCurrentGroupName)); 0053 0054 KContacts::ContactGroup group; 0055 group.setName(mCurrentGroupName); 0056 for (const KContacts::Addressee &contact : std::as_const(mCurrentContacts)) { 0057 group.append(KContacts::ContactGroup::Data(contact.realName(), contact.preferredEmail())); 0058 } 0059 0060 mContactGroupFormatter->setContactGroup(group); 0061 0062 QList<QVariantMap> additionalFields; 0063 0064 if (!mCurrentAddressBookName.isEmpty()) { 0065 QVariantMap addressBookName; 0066 addressBookName.insert(QStringLiteral("title"), i18n("Address Book")); 0067 addressBookName.insert(QStringLiteral("value"), mCurrentAddressBookName); 0068 0069 additionalFields << addressBookName; 0070 } 0071 0072 mContactGroupFormatter->setAdditionalFields(additionalFields); 0073 0074 mBrowser->setHtml(mContactGroupFormatter->toHtml()); 0075 } 0076 0077 void _k_expandResult(KJob *job) 0078 { 0079 mExpandJob = nullptr; 0080 0081 if (!job->error()) { 0082 auto expandJob = qobject_cast<ContactGroupExpandJob *>(job); 0083 mCurrentContacts = expandJob->contacts(); 0084 } 0085 0086 // stop any running fetch job 0087 if (mParentCollectionFetchJob) { 0088 mParent->disconnect(mCollectionFetchJobConnection); 0089 delete mParentCollectionFetchJob; 0090 mParentCollectionFetchJob = nullptr; 0091 } 0092 0093 mParentCollectionFetchJob = new CollectionFetchJob(mCurrentItem.parentCollection(), CollectionFetchJob::Base, mParent); 0094 mCollectionFetchJobConnection = mParent->connect(mParentCollectionFetchJob, &CollectionFetchJob::result, mParent, [this](KJob *job) { 0095 slotParentCollectionFetched(job); 0096 }); 0097 } 0098 0099 void slotParentCollectionFetched(KJob *job) 0100 { 0101 mParentCollectionFetchJob = nullptr; 0102 mCurrentAddressBookName.clear(); 0103 0104 if (!job->error()) { 0105 auto fetchJob = qobject_cast<CollectionFetchJob *>(job); 0106 if (!fetchJob->collections().isEmpty()) { 0107 const Collection collection = fetchJob->collections().at(0); 0108 mCurrentAddressBookName = collection.displayName(); 0109 } 0110 } 0111 0112 updateView(); 0113 } 0114 0115 QMetaObject::Connection mCollectionFetchJobConnection; 0116 QMetaObject::Connection mJobConnection; 0117 ContactGroupViewer *const mParent; 0118 Akonadi::TextBrowser *mBrowser = nullptr; 0119 QString mCurrentGroupName; 0120 KContacts::Addressee::List mCurrentContacts; 0121 QString mCurrentAddressBookName; 0122 Item mCurrentItem; 0123 ContactGroupExpandJob *mExpandJob = nullptr; 0124 CollectionFetchJob *mParentCollectionFetchJob = nullptr; 0125 AbstractContactGroupFormatter *mStandardContactGroupFormatter = nullptr; 0126 AbstractContactGroupFormatter *mContactGroupFormatter = nullptr; 0127 }; 0128 0129 ContactGroupViewer::ContactGroupViewer(QWidget *parent) 0130 : QWidget(parent) 0131 , d(new ContactGroupViewerPrivate(this)) 0132 { 0133 auto layout = new QVBoxLayout(this); 0134 layout->setContentsMargins({}); 0135 0136 connect(d->mBrowser, &Akonadi::TextBrowser::anchorClicked, this, &ContactGroupViewer::urlClicked); 0137 0138 layout->addWidget(d->mBrowser); 0139 0140 // always fetch full payload for contact groups 0141 fetchScope().fetchFullPayload(); 0142 fetchScope().setAncestorRetrieval(ItemFetchScope::Parent); 0143 } 0144 0145 ContactGroupViewer::~ContactGroupViewer() = default; 0146 0147 Akonadi::Item ContactGroupViewer::contactGroup() const 0148 { 0149 return ItemMonitor::item(); 0150 } 0151 0152 void ContactGroupViewer::setContactGroup(const Akonadi::Item &group) 0153 { 0154 ItemMonitor::setItem(group); 0155 } 0156 0157 void ContactGroupViewer::setContactGroupFormatter(AbstractContactGroupFormatter *formatter) 0158 { 0159 if (formatter == nullptr) { 0160 d->mContactGroupFormatter = d->mStandardContactGroupFormatter; 0161 } else { 0162 d->mContactGroupFormatter = formatter; 0163 } 0164 } 0165 0166 void ContactGroupViewer::updateView() 0167 { 0168 itemChanged(d->mCurrentItem); 0169 } 0170 0171 void ContactGroupViewer::itemChanged(const Item &item) 0172 { 0173 if (!item.hasPayload<KContacts::ContactGroup>()) { 0174 return; 0175 } 0176 0177 const auto group = item.payload<KContacts::ContactGroup>(); 0178 d->mCurrentGroupName = group.name(); 0179 d->mCurrentItem = item; 0180 0181 if (d->mExpandJob) { 0182 disconnect(d->mJobConnection); 0183 d->mExpandJob->kill(); 0184 } 0185 0186 d->mExpandJob = new ContactGroupExpandJob(group); 0187 d->mJobConnection = connect(d->mExpandJob, &ContactGroupExpandJob::result, this, [this](KJob *job) { 0188 d->_k_expandResult(job); 0189 }); 0190 d->mExpandJob->start(); 0191 } 0192 0193 void ContactGroupViewer::itemRemoved() 0194 { 0195 d->mBrowser->clear(); 0196 } 0197 0198 #include "moc_contactgroupviewer.cpp"