File indexing completed on 2024-11-24 04:43:04

0001 /*
0002     SPDX-FileCopyrightText: 2015-2024 Laurent Montel <montel@kde.org>
0003 
0004     SPDX-License-Identifier: LGPL-2.0-or-later
0005 */
0006 
0007 #include "resultduplicatetreewidget.h"
0008 #include <KLocalizedString>
0009 
0010 #include <KContacts/Addressee>
0011 
0012 using namespace KABMergeContacts;
0013 
0014 ResultDuplicateTreeWidget::ResultDuplicateTreeWidget(QWidget *parent)
0015     : QTreeWidget(parent)
0016 {
0017     setHeaderLabel(i18n("Contacts"));
0018     connect(this, &QTreeWidget::itemSelectionChanged, this, &ResultDuplicateTreeWidget::slotItemSelectionChanged);
0019     connect(this, &ResultDuplicateTreeWidget::itemChanged, this, &ResultDuplicateTreeWidget::slotItemChanged);
0020     setContextMenuPolicy(Qt::CustomContextMenu);
0021 }
0022 
0023 ResultDuplicateTreeWidget::~ResultDuplicateTreeWidget() = default;
0024 
0025 void ResultDuplicateTreeWidget::slotItemChanged(QTreeWidgetItem *item, int column)
0026 {
0027     if (column != 0) {
0028         return;
0029     }
0030     // Parent
0031     if (item->childCount() != 0) {
0032         changeState(item, item->checkState(0) == Qt::Checked);
0033     } else { // child
0034         QTreeWidgetItem *parent = item->parent();
0035         if (parent) {
0036             blockSignals(true);
0037             Qt::CheckState state = Qt::PartiallyChecked;
0038             for (int i = 0; i < parent->childCount(); ++i) {
0039                 if (i == 0) {
0040                     state = parent->child(i)->checkState(0);
0041                 } else {
0042                     if (state != parent->child(i)->checkState(0)) {
0043                         state = Qt::PartiallyChecked;
0044                         break;
0045                     }
0046                 }
0047             }
0048             parent->setCheckState(0, state);
0049             blockSignals(false);
0050         }
0051     }
0052 }
0053 
0054 void ResultDuplicateTreeWidget::changeState(QTreeWidgetItem *item, bool b)
0055 {
0056     blockSignals(true);
0057     item->setCheckState(0, b ? Qt::Checked : Qt::Unchecked);
0058     for (int i = 0; i < item->childCount(); ++i) {
0059         item->child(i)->setCheckState(0, b ? Qt::Checked : Qt::Unchecked);
0060     }
0061     blockSignals(false);
0062 }
0063 
0064 void ResultDuplicateTreeWidget::slotItemSelectionChanged()
0065 {
0066     auto resultItem = dynamic_cast<ResultDuplicateTreeWidgetItem *>(currentItem());
0067     if (resultItem) {
0068         Q_EMIT showContactPreview(resultItem->item());
0069     }
0070 }
0071 
0072 void ResultDuplicateTreeWidget::setContacts(const QList<Akonadi::Item::List> &lstItem)
0073 {
0074     clear();
0075     int i = 1;
0076     for (const Akonadi::Item::List &lst : lstItem) {
0077         auto topLevelItem = new ResultDuplicateTreeWidgetItem(this);
0078         topLevelItem->setText(
0079             0,
0080             i18n("Duplicate contact \"%1\" (%2 times)", ResultDuplicateTreeWidgetItem::displayName(lst.first()), QString::number(lst.count())));
0081         for (const Akonadi::Item &item : lst) {
0082             auto childItem = new ResultDuplicateTreeWidgetItem;
0083             topLevelItem->addChild(childItem);
0084             childItem->setItem(item);
0085         }
0086         ++i;
0087     }
0088     expandAll();
0089 }
0090 
0091 QList<Akonadi::Item::List> ResultDuplicateTreeWidget::selectedContactsToMerge() const
0092 {
0093     QList<Akonadi::Item::List> listItems;
0094     for (int i = 0; i < topLevelItemCount(); ++i) {
0095         QTreeWidgetItem *item = topLevelItem(i);
0096         const int childCount = item->childCount();
0097         if (childCount > 0) {
0098             Akonadi::Item::List items;
0099             for (int child = 0; child < childCount; ++child) {
0100                 auto childItem = static_cast<ResultDuplicateTreeWidgetItem *>(item->child(child));
0101                 if (childItem->checkState(0) == Qt::Checked) {
0102                     items << childItem->item();
0103                 }
0104             }
0105             if (items.count() > 1) {
0106                 listItems << items;
0107             }
0108         }
0109     }
0110     return listItems;
0111 }
0112 
0113 void ResultDuplicateTreeWidget::checkAllItems()
0114 {
0115     for (int i = 0; i < topLevelItemCount(); ++i) {
0116         QTreeWidgetItem *item = topLevelItem(i);
0117         item->setCheckState(0, Qt::Checked);
0118     }
0119 }
0120 
0121 void ResultDuplicateTreeWidget::uncheckAllItems()
0122 {
0123     for (int i = 0; i < topLevelItemCount(); ++i) {
0124         QTreeWidgetItem *item = topLevelItem(i);
0125         item->setCheckState(0, Qt::Unchecked);
0126     }
0127 }
0128 
0129 ResultDuplicateTreeWidgetItem::ResultDuplicateTreeWidgetItem(QTreeWidget *parent)
0130     : QTreeWidgetItem(parent)
0131 {
0132     setFlags(Qt::ItemIsSelectable | Qt::ItemIsUserCheckable | Qt::ItemIsEnabled);
0133     setCheckState(0, Qt::Unchecked);
0134 }
0135 
0136 ResultDuplicateTreeWidgetItem::~ResultDuplicateTreeWidgetItem() = default;
0137 
0138 Akonadi::Item ResultDuplicateTreeWidgetItem::item() const
0139 {
0140     return mItem;
0141 }
0142 
0143 void ResultDuplicateTreeWidgetItem::setItem(const Akonadi::Item &item)
0144 {
0145     mItem = item;
0146     setDisplayName();
0147 }
0148 
0149 QString ResultDuplicateTreeWidgetItem::contactName(const KContacts::Addressee &address)
0150 {
0151     const QString realName = address.realName();
0152     if (!realName.isEmpty()) {
0153         return realName;
0154     }
0155     const QString name = address.name();
0156     if (!name.isEmpty()) {
0157         return name;
0158     }
0159     return address.fullEmail();
0160 }
0161 
0162 void ResultDuplicateTreeWidgetItem::setDisplayName()
0163 {
0164     if (mItem.isValid()) {
0165         setText(0, displayName(mItem));
0166     }
0167 }
0168 
0169 QString ResultDuplicateTreeWidgetItem::displayName(const Akonadi::Item &item)
0170 {
0171     if (item.isValid()) {
0172         const auto address = item.payload<KContacts::Addressee>();
0173         return contactName(address);
0174     }
0175     return {};
0176 }
0177 
0178 #include "moc_resultduplicatetreewidget.cpp"