File indexing completed on 2024-12-22 04:55:32

0001 /*
0002   SPDX-FileCopyrightText: 2009 Tobias Koenig <tokoe@kde.org>
0003   SPDX-FileCopyrightText: 2016-2024 Laurent Montel <montel@kde.org>
0004 
0005   SPDX-License-Identifier: LGPL-2.0-or-later
0006 */
0007 
0008 #include "contactselectionwidget.h"
0009 #include <QDebug>
0010 
0011 #include <Akonadi/CollectionComboBox>
0012 #include <Akonadi/EntityTreeModel>
0013 #include <Akonadi/ItemFetchJob>
0014 #include <Akonadi/ItemFetchScope>
0015 #include <Akonadi/RecursiveItemFetchJob>
0016 
0017 #include <KLocalizedString>
0018 
0019 #include <QApplication>
0020 #include <QButtonGroup>
0021 #include <QCheckBox>
0022 #include <QGridLayout>
0023 #include <QGroupBox>
0024 #include <QItemSelectionModel>
0025 #include <QLabel>
0026 #include <QProgressDialog>
0027 #include <QRadioButton>
0028 #include <QVBoxLayout>
0029 
0030 using namespace KAddressBookImportExport;
0031 
0032 ContactSelectionWidget::ContactSelectionWidget(QItemSelectionModel *selectionModel, QWidget *parent)
0033     : QWidget(parent)
0034     , mSelectionModel(selectionModel)
0035 {
0036     initGui();
0037 
0038     mSelectedContactsButton->setEnabled(mSelectionModel->hasSelection());
0039     mAddressBookSelection->setEnabled(false);
0040     mAddressBookSelectionRecursive->setEnabled(false);
0041 
0042     connect(mAddressBookContactsButton, &QRadioButton::toggled, mAddressBookSelection, &Akonadi::CollectionComboBox::setEnabled);
0043     connect(mAddressBookContactsButton, &QRadioButton::toggled, mAddressBookSelectionRecursive, &QCheckBox::setEnabled);
0044 
0045     // apply default configuration
0046     if (mSelectionModel->hasSelection()) {
0047         mSelectedContactsButton->setChecked(true);
0048     } else {
0049         mAllContactsButton->setChecked(true);
0050     }
0051 }
0052 
0053 void ContactSelectionWidget::setMessageText(const QString &message)
0054 {
0055     if (!message.isEmpty()) {
0056         mMessageLabel->setText(message);
0057         mMessageLabel->show();
0058     }
0059 }
0060 
0061 void ContactSelectionWidget::setDefaultAddressBook(const Akonadi::Collection &addressBook)
0062 {
0063     mAddressBookSelection->setDefaultCollection(addressBook);
0064 }
0065 
0066 Akonadi::Item::List ContactSelectionWidget::selectedItems() const
0067 {
0068     if (mAllContactsButton->isChecked()) {
0069         return collectAllItems();
0070     } else if (mSelectedContactsButton->isChecked()) {
0071         return collectSelectedItems();
0072     } else if (mAddressBookContactsButton->isChecked()) {
0073         return collectAddressBookItems();
0074     } else {
0075         qWarning() << " It's a bug here.";
0076     }
0077 
0078     return {};
0079 }
0080 
0081 ContactList ContactSelectionWidget::selectedContacts() const
0082 {
0083     if (mAllContactsButton->isChecked()) {
0084         return collectAllContacts();
0085     } else if (mSelectedContactsButton->isChecked()) {
0086         return collectSelectedContacts();
0087     } else if (mAddressBookContactsButton->isChecked()) {
0088         return collectAddressBookContacts();
0089     }
0090 
0091     return ContactList();
0092 }
0093 
0094 void ContactSelectionWidget::setAddGroupContact(bool addGroupContact)
0095 {
0096     mAddContactGroup = addGroupContact;
0097 }
0098 
0099 void ContactSelectionWidget::initGui()
0100 {
0101     auto layout = new QVBoxLayout(this);
0102     layout->setContentsMargins({});
0103 
0104     mMessageLabel = new QLabel;
0105     layout->addWidget(mMessageLabel);
0106     mMessageLabel->hide();
0107 
0108     auto group = new QButtonGroup(this);
0109 
0110     auto groupBox = new QGroupBox;
0111 
0112     auto boxLayout = new QGridLayout;
0113     groupBox->setLayout(boxLayout);
0114 
0115     mAllContactsButton = new QRadioButton(i18nc("@option:radio", "All contacts"));
0116     mAllContactsButton->setToolTip(i18nc("@info:tooltip", "All contacts from all your address books"));
0117     mAllContactsButton->setWhatsThis(i18nc("@info:whatsthis",
0118                                            "Choose this option you want to select all your contacts from "
0119                                            "all your address books."));
0120 
0121     mSelectedContactsButton = new QRadioButton(i18nc("@option:radio", "Selected contacts"));
0122     mSelectedContactsButton->setToolTip(i18nc("@info:tooltip", "Only the contacts currently selected"));
0123     mSelectedContactsButton->setWhatsThis(i18nc("@info:whatsthis",
0124                                                 "Choose this option if you want only the contacts you have already "
0125                                                 "selected in the graphical interface."));
0126 
0127     mAddressBookContactsButton = new QRadioButton(i18nc("@option:radio", "All contacts from:"));
0128     mAddressBookContactsButton->setToolTip(i18nc("@info:tooltip", "All contacts from a chosen address book"));
0129     mAddressBookContactsButton->setWhatsThis(i18nc("@info:whatsthis",
0130                                                    "Choose this option if you want to select all the contacts from only one "
0131                                                    "of your address books.  Once this option is clicked you will be provided "
0132                                                    "a drop down box listing all those address books and permitted to select "
0133                                                    "the one you want."));
0134 
0135     mAddressBookSelection = new Akonadi::CollectionComboBox;
0136     mAddressBookSelection->setMimeTypeFilter(QStringList() << KContacts::Addressee::mimeType());
0137     mAddressBookSelection->setAccessRightsFilter(Akonadi::Collection::ReadOnly);
0138     mAddressBookSelection->setExcludeVirtualCollections(true);
0139     mAddressBookSelectionRecursive = new QCheckBox(i18nc("@option:check", "Include Subfolders"));
0140     mAddressBookSelectionRecursive->setToolTip(i18nc("@info:tooltip", "Select all subfolders including the top-level folder"));
0141     mAddressBookSelectionRecursive->setWhatsThis(i18nc("@info:whatsthis",
0142                                                        "Check this box if you want to select all contacts from this folder, "
0143                                                        "including all subfolders.  If you only want the contacts from the "
0144                                                        "top-level folder then leave this box unchecked."));
0145 
0146     group->addButton(mAllContactsButton);
0147     group->addButton(mSelectedContactsButton);
0148     group->addButton(mAddressBookContactsButton);
0149 
0150     boxLayout->addWidget(mAllContactsButton, 0, 0, 1, 2);
0151     boxLayout->addWidget(mSelectedContactsButton, 1, 0, 1, 2);
0152     boxLayout->addWidget(mAddressBookContactsButton, 2, 0, Qt::AlignTop);
0153 
0154     auto addressBookLayout = new QVBoxLayout;
0155     addressBookLayout->setContentsMargins({});
0156     addressBookLayout->addWidget(mAddressBookSelection);
0157     addressBookLayout->addWidget(mAddressBookSelectionRecursive);
0158 
0159     boxLayout->addLayout(addressBookLayout, 2, 1);
0160 
0161     layout->addWidget(groupBox);
0162     layout->addStretch(1);
0163 }
0164 
0165 Akonadi::Item::List ContactSelectionWidget::collectAllItems() const
0166 {
0167     auto job = new Akonadi::RecursiveItemFetchJob(Akonadi::Collection::root(), QStringList() << KContacts::Addressee::mimeType());
0168     job->fetchScope().fetchFullPayload();
0169     QProgressDialog progressDialog(nullptr);
0170     progressDialog.setWindowTitle(i18nc("@title:window", "Collect Contacts"));
0171     progressDialog.setAutoClose(true);
0172     progressDialog.setMinimumDuration(1000);
0173     progressDialog.setLabelText(i18n("Fetch Contacts"));
0174     progressDialog.show();
0175 
0176     qApp->processEvents();
0177 
0178     if (!job->exec()) {
0179         return {};
0180     }
0181 
0182     return job->items();
0183 }
0184 
0185 ContactList ContactSelectionWidget::collectAllContacts() const
0186 {
0187     ContactList contacts;
0188     auto job = new Akonadi::RecursiveItemFetchJob(Akonadi::Collection::root(), QStringList() << KContacts::Addressee::mimeType());
0189     job->fetchScope().fetchFullPayload();
0190 
0191     if (!job->exec()) {
0192         return contacts;
0193     }
0194     const Akonadi::Item::List lstItems = job->items();
0195     for (const Akonadi::Item &item : lstItems) {
0196         if (item.isValid()) {
0197             if (item.hasPayload<KContacts::Addressee>()) {
0198                 contacts.append(item.payload<KContacts::Addressee>());
0199             }
0200         }
0201     }
0202 
0203     return contacts;
0204 }
0205 
0206 Akonadi::Item::List ContactSelectionWidget::collectSelectedItems() const
0207 {
0208     Akonadi::Item::List items;
0209 
0210     const QModelIndexList indexes = mSelectionModel->selectedRows(0);
0211     for (int i = 0, total = indexes.count(); i < total; ++i) {
0212         const QModelIndex index = indexes.at(i);
0213         if (index.isValid()) {
0214             const auto item = index.data(Akonadi::EntityTreeModel::ItemRole).value<Akonadi::Item>();
0215             if (item.isValid()) {
0216                 items.append(item);
0217             }
0218         }
0219     }
0220 
0221     return items;
0222 }
0223 
0224 ContactList ContactSelectionWidget::collectSelectedContacts() const
0225 {
0226     ContactList contacts;
0227 
0228     const QModelIndexList indexes = mSelectionModel->selectedRows(0);
0229     for (int i = 0, total = indexes.count(); i < total; ++i) {
0230         const QModelIndex index = indexes.at(i);
0231         if (index.isValid()) {
0232             const auto item = index.data(Akonadi::EntityTreeModel::ItemRole).value<Akonadi::Item>();
0233             if (item.isValid()) {
0234                 if (item.hasPayload<KContacts::Addressee>()) {
0235                     contacts.append(item.payload<KContacts::Addressee>());
0236                 }
0237             }
0238         }
0239     }
0240 
0241     return contacts;
0242 }
0243 
0244 Akonadi::Item::List ContactSelectionWidget::collectAddressBookItems() const
0245 {
0246     Akonadi::Item::List items;
0247 
0248     const Akonadi::Collection collection = mAddressBookSelection->currentCollection();
0249     if (!collection.isValid()) {
0250         return items;
0251     }
0252 
0253     if (mAddressBookSelectionRecursive->isChecked()) {
0254         auto job = new Akonadi::RecursiveItemFetchJob(collection, QStringList() << KContacts::Addressee::mimeType());
0255         job->fetchScope().fetchFullPayload();
0256 
0257         if (!job->exec()) {
0258             return items;
0259         }
0260 
0261         items = job->items();
0262     } else {
0263         auto job = new Akonadi::ItemFetchJob(collection);
0264         job->fetchScope().fetchFullPayload();
0265 
0266         if (!job->exec()) {
0267             return items;
0268         }
0269         items = job->items();
0270     }
0271 
0272     return items;
0273 }
0274 
0275 ContactList ContactSelectionWidget::collectAddressBookContacts() const
0276 {
0277     ContactList contacts;
0278 
0279     const Akonadi::Collection collection = mAddressBookSelection->currentCollection();
0280     if (!collection.isValid()) {
0281         return contacts;
0282     }
0283 
0284     if (mAddressBookSelectionRecursive->isChecked()) {
0285         auto job = new Akonadi::RecursiveItemFetchJob(collection, QStringList() << KContacts::Addressee::mimeType());
0286         job->fetchScope().fetchFullPayload();
0287 
0288         if (!job->exec()) {
0289             return contacts;
0290         }
0291 
0292         const Akonadi::Item::List lstItems = job->items();
0293         for (const Akonadi::Item &item : lstItems) {
0294             if (item.hasPayload<KContacts::Addressee>()) {
0295                 contacts.append(item.payload<KContacts::Addressee>());
0296             }
0297         }
0298     } else {
0299         auto job = new Akonadi::ItemFetchJob(collection);
0300         job->fetchScope().fetchFullPayload();
0301 
0302         if (!job->exec()) {
0303             return contacts;
0304         }
0305         const Akonadi::Item::List lstItems = job->items();
0306         for (const Akonadi::Item &item : lstItems) {
0307             if (item.hasPayload<KContacts::Addressee>()) {
0308                 contacts.append(item.payload<KContacts::Addressee>());
0309             }
0310         }
0311     }
0312 
0313     return contacts;
0314 }
0315 
0316 #include "moc_contactselectionwidget.cpp"