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 "searchduplicateresultwidget.h" 0008 #include "job/mergecontactsjob.h" 0009 #include "widgets/mergecontactloseinformationwarning.h" 0010 0011 #include "resultduplicatetreewidget.h" 0012 #include <Akonadi/CollectionComboBox> 0013 #include <Akonadi/GrantleeContactViewer> 0014 #include <KLocalizedString> 0015 #include <KTreeWidgetSearchLine> 0016 #include <KTreeWidgetSearchLineWidget> 0017 #include <QHBoxLayout> 0018 #include <QLabel> 0019 #include <QMenu> 0020 #include <QPushButton> 0021 #include <QSplitter> 0022 0023 namespace KABMergeContacts 0024 { 0025 KADDRESSBOOKMERGELIB_EXPORT QAbstractItemModel *_k_searchDuplicateResultStubModel = nullptr; 0026 } 0027 0028 using namespace KABMergeContacts; 0029 SearchDuplicateResultWidget::SearchDuplicateResultWidget(QWidget *parent) 0030 : QWidget(parent) 0031 , mResultTreeWidget(new ResultDuplicateTreeWidget(this)) 0032 , mContactViewer(new KAddressBookGrantlee::GrantleeContactViewer(this)) 0033 , mMergeContactWarning(new MergeContactLoseInformationWarning(this)) 0034 { 0035 auto mainLayout = new QVBoxLayout(this); 0036 mainLayout->setContentsMargins({}); 0037 0038 auto splitter = new QSplitter; 0039 splitter->setObjectName(QLatin1StringView("splitter")); 0040 splitter->setChildrenCollapsible(false); 0041 mainLayout->addWidget(splitter); 0042 mResultTreeWidget->setObjectName(QLatin1StringView("result_treewidget")); 0043 mContactViewer->setObjectName(QLatin1StringView("contact_viewer")); 0044 0045 mSearchInResultLineEdit = new KTreeWidgetSearchLineWidget(this, mResultTreeWidget); 0046 mSearchInResultLineEdit->setObjectName(QLatin1StringView("searchinresultlineedit")); 0047 mSearchInResultLineEdit->searchLine()->setClearButtonEnabled(true); 0048 mSearchInResultLineEdit->searchLine()->setPlaceholderText(i18n("Search in result...")); 0049 0050 auto resultWidget = new QWidget(this); 0051 auto resultWidgetLayout = new QVBoxLayout(resultWidget); 0052 resultWidgetLayout->setContentsMargins({}); 0053 resultWidgetLayout->addWidget(mSearchInResultLineEdit); 0054 resultWidgetLayout->addWidget(mResultTreeWidget); 0055 splitter->addWidget(resultWidget); 0056 splitter->addWidget(mContactViewer); 0057 connect(mResultTreeWidget, &ResultDuplicateTreeWidget::showContactPreview, mContactViewer, &KAddressBookGrantlee::GrantleeContactViewer::setContact); 0058 connect(mResultTreeWidget, &ResultDuplicateTreeWidget::customContextMenuRequested, this, &SearchDuplicateResultWidget::slotCustomContextMenuRequested); 0059 0060 mMergeContactWarning->setObjectName(QLatin1StringView("mergecontactwarning")); 0061 connect(mMergeContactWarning, &MergeContactLoseInformationWarning::continueMerging, this, &SearchDuplicateResultWidget::slotAutomaticMerging); 0062 connect(mMergeContactWarning, 0063 &MergeContactLoseInformationWarning::customizeMergingContacts, 0064 this, 0065 &SearchDuplicateResultWidget::slotCustomizeMergingContacts); 0066 mainLayout->addWidget(mMergeContactWarning); 0067 0068 auto mergeLayout = new QHBoxLayout; 0069 mainLayout->addLayout(mergeLayout); 0070 mergeLayout->addStretch(); 0071 0072 auto lab = new QLabel(i18n("Select AddressBook:")); 0073 lab->setObjectName(QLatin1StringView("select_addressbook_label")); 0074 mergeLayout->addWidget(lab); 0075 0076 mCollectionCombobox = new Akonadi::CollectionComboBox(_k_searchDuplicateResultStubModel, this); 0077 mCollectionCombobox->setAccessRightsFilter(Akonadi::Collection::CanCreateItem); 0078 mCollectionCombobox->setMinimumWidth(250); 0079 mCollectionCombobox->setMimeTypeFilter(QStringList() << KContacts::Addressee::mimeType()); 0080 mCollectionCombobox->setObjectName(QLatin1StringView("akonadicombobox")); 0081 connect(mCollectionCombobox, &Akonadi::CollectionComboBox::currentIndexChanged, this, &SearchDuplicateResultWidget::slotUpdateMergeButton); 0082 connect(mCollectionCombobox, &Akonadi::CollectionComboBox::activated, this, &SearchDuplicateResultWidget::slotUpdateMergeButton); 0083 mergeLayout->addWidget(mCollectionCombobox); 0084 0085 mMergeContact = new QPushButton(i18n("Merge"), this); 0086 mMergeContact->setObjectName(QLatin1StringView("merge_contact_button")); 0087 connect(mMergeContact, &QPushButton::clicked, this, &SearchDuplicateResultWidget::slotMergeContact); 0088 mergeLayout->addWidget(mMergeContact); 0089 mMergeContact->setEnabled(false); 0090 // TODO make mMergeContact enable when selected item and collection valid 0091 } 0092 0093 SearchDuplicateResultWidget::~SearchDuplicateResultWidget() = default; 0094 0095 void SearchDuplicateResultWidget::slotCustomContextMenuRequested(const QPoint &) 0096 { 0097 QMenu menu(this); 0098 menu.addAction(i18n("Expand All"), this, &SearchDuplicateResultWidget::slotExpandAll); 0099 menu.addAction(i18n("Collapse All"), this, &SearchDuplicateResultWidget::slotCollapseAll); 0100 menu.addSeparator(); 0101 menu.addAction(i18n("Select All"), this, &SearchDuplicateResultWidget::slotSelectAll); 0102 menu.addAction(i18n("Deselect All"), this, &SearchDuplicateResultWidget::slotDeselectAll); 0103 menu.exec(QCursor::pos()); 0104 } 0105 0106 void SearchDuplicateResultWidget::slotExpandAll() 0107 { 0108 mResultTreeWidget->expandAll(); 0109 } 0110 0111 void SearchDuplicateResultWidget::slotCollapseAll() 0112 { 0113 mResultTreeWidget->collapseAll(); 0114 } 0115 0116 void SearchDuplicateResultWidget::slotSelectAll() 0117 { 0118 mResultTreeWidget->checkAllItems(); 0119 } 0120 0121 void SearchDuplicateResultWidget::slotDeselectAll() 0122 { 0123 mResultTreeWidget->uncheckAllItems(); 0124 } 0125 0126 void SearchDuplicateResultWidget::setContacts(const QList<Akonadi::Item::List> &lstItem) 0127 { 0128 mResultTreeWidget->setContacts(lstItem); 0129 } 0130 0131 void SearchDuplicateResultWidget::slotMergeContact() 0132 { 0133 mIndexListContact = 0; 0134 mListContactToMerge = mResultTreeWidget->selectedContactsToMerge(); 0135 if (!mListContactToMerge.isEmpty()) { 0136 KABMergeContacts::MergeContacts mergeContacts; 0137 bool conflictFound = false; 0138 mResultConflictList.clear(); 0139 for (const Akonadi::Item::List &lst : std::as_const(mListContactToMerge)) { 0140 mergeContacts.setItems(lst); 0141 const MergeContacts::ConflictInformations conflicts = mergeContacts.requiresManualSelectionOfInformation(); 0142 if (conflicts != MergeContacts::None) { 0143 conflictFound = true; 0144 } 0145 MergeConflictResult result; 0146 result.list = lst; 0147 result.conflictInformation = conflicts; 0148 mResultConflictList.append(result); 0149 } 0150 0151 mMergeContact->setEnabled(false); 0152 if (conflictFound) { 0153 mMergeContactWarning->animatedShow(); 0154 } else { 0155 // Detect if conflict. 0156 mergeContact(); 0157 } 0158 } 0159 } 0160 0161 void SearchDuplicateResultWidget::mergeContact() 0162 { 0163 if (mIndexListContact < mListContactToMerge.count()) { 0164 auto job = new KABMergeContacts::MergeContactsJob(this); 0165 job->setListItem(mListContactToMerge.at(mIndexListContact)); 0166 job->setDestination(mCollectionCombobox->currentCollection()); 0167 connect(job, &KABMergeContacts::MergeContactsJob::finished, this, &SearchDuplicateResultWidget::slotMergeDone); 0168 job->start(); 0169 } else { 0170 Q_EMIT mergeDone(); 0171 } 0172 } 0173 0174 void SearchDuplicateResultWidget::slotMergeDone(const Akonadi::Item &item) 0175 { 0176 ++mIndexListContact; 0177 Q_EMIT contactMerged(item); 0178 mergeContact(); 0179 } 0180 0181 void SearchDuplicateResultWidget::slotUpdateMergeButton() 0182 { 0183 mMergeContact->setEnabled(mCollectionCombobox->currentCollection().isValid()); 0184 } 0185 0186 void SearchDuplicateResultWidget::slotAutomaticMerging() 0187 { 0188 mergeContact(); 0189 } 0190 0191 void SearchDuplicateResultWidget::slotCustomizeMergingContacts() 0192 { 0193 Q_EMIT customizeMergeContact(mResultConflictList, mCollectionCombobox->currentCollection()); 0194 } 0195 0196 #include "moc_searchduplicateresultwidget.cpp"