File indexing completed on 2024-05-05 16:16:35

0001 /*
0002     KPeople - Duplicates
0003     SPDX-FileCopyrightText: 2013 Franck Arrecot <franck.arrecot@gmail.com>
0004 
0005     SPDX-License-Identifier: LGPL-2.1-or-later
0006 */
0007 
0008 #include "mergedelegate.h"
0009 #include "mergedialog.h"
0010 #include "personsmodel.h"
0011 #include <match_p.h>
0012 
0013 #include "kpeople_widgets_debug.h"
0014 #include <KLocalizedString>
0015 #include <QAbstractItemView>
0016 #include <QCheckBox>
0017 #include <QIcon>
0018 #include <QLabel>
0019 #include <QModelIndex>
0020 #include <QPainter>
0021 #include <QStyleOptionViewItem>
0022 
0023 #define MAX_MATCHING_CONTACTS_ICON 5
0024 #define SIZE_STANDARD_PIXMAP 35
0025 
0026 using namespace KPeople;
0027 
0028 // TODO: use proper, runtime values there
0029 QSize MergeDelegate::s_decorationSize(SIZE_STANDARD_PIXMAP, SIZE_STANDARD_PIXMAP);
0030 QSize MergeDelegate::s_arrowSize(15, 15);
0031 
0032 QSize MergeDelegate::pictureSize()
0033 {
0034     return s_decorationSize;
0035 }
0036 
0037 MergeDelegate::MergeDelegate(QAbstractItemView *parent)
0038     : KExtendableItemDelegate(parent)
0039 {
0040     static QIcon arrowD = QIcon::fromTheme(QStringLiteral("arrow-down"));
0041     setContractPixmap(arrowD.pixmap(s_arrowSize));
0042 
0043     static QIcon arrowR = QIcon::fromTheme(QStringLiteral("arrow-right"));
0044     setExtendPixmap(arrowR.pixmap(s_arrowSize));
0045 }
0046 
0047 MergeDelegate::~MergeDelegate()
0048 {
0049 }
0050 
0051 void MergeDelegate::onClickContactParent(const QModelIndex &parent)
0052 {
0053     if (isExtended(parent)) {
0054         contractItem(parent);
0055     } else {
0056         QItemSelection item = QItemSelection(parent, parent);
0057         onSelectedContactsChanged(item, QItemSelection());
0058     }
0059 }
0060 
0061 void MergeDelegate::onSelectedContactsChanged(const QItemSelection &now, const QItemSelection &old)
0062 {
0063     if (!old.indexes().isEmpty()) {
0064         QModelIndex oldIdx = old.indexes().first();
0065 
0066         if (isExtended(oldIdx)) {
0067             contractItem(oldIdx);
0068         }
0069     }
0070     if (!now.indexes().isEmpty()) {
0071         QModelIndex idx = now.indexes().first();
0072         extendItem(buildMultipleLineLabel(idx), idx);
0073     }
0074 }
0075 
0076 QWidget *MergeDelegate::buildMultipleLineLabel(const QModelIndex &idx)
0077 {
0078     QString contents;
0079     const QAbstractItemModel *model = idx.model();
0080     const int rows = model->rowCount(idx);
0081     for (int i = 0; i < rows; ++i) {
0082         const QModelIndex child = model->index(i, 0, idx);
0083         Match m = child.data(MergeDialog::MergeReasonRole).value<Match>();
0084 
0085         QString name = m.indexB.data(Qt::DisplayRole).toString();
0086         QString display = i18nc("name: merge reasons", "%1: %2", name, m.matchReasons().join(i18nc("reasons join", ", ")));
0087         contents += display + QLatin1String("<p/>");
0088     }
0089     QLabel *childDisplay = new QLabel(contents, dynamic_cast<QWidget *>(parent()));
0090     childDisplay->setAlignment(Qt::AlignRight);
0091     childDisplay->setFrameStyle(QFrame::StyledPanel | QFrame::Sunken);
0092     return childDisplay;
0093 }
0094 
0095 void MergeDelegate::paint(QPainter *painter, const QStyleOptionViewItem &optionOld, const QModelIndex &index) const
0096 {
0097     QStyleOptionViewItem option(optionOld);
0098     QStyleOptionViewItem opt(option);
0099     KExtendableItemDelegate::paint(painter, option, index);
0100 
0101     const int separation = 5;
0102 
0103     const QAbstractItemModel *model = index.model();
0104     int facesRows = qMin(model->rowCount(index), MAX_MATCHING_CONTACTS_ICON);
0105     for (int i = 0; i < facesRows; i++) { // Children Icon Displaying Loop
0106         const QModelIndex child = model->index(i, 0, index);
0107 
0108         QVariant decoration = child.data(Qt::DecorationRole);
0109         Q_ASSERT(decoration.type() == (QVariant::Icon));
0110 
0111         QIcon pix = decoration.value<QIcon>();
0112         QPoint pixmapPoint = {option.rect.width() / 2 + i * (s_decorationSize.width() + separation), option.rect.top()};
0113         painter->drawPixmap(pixmapPoint, pix.pixmap(s_decorationSize));
0114     }
0115     // draw a vertical line to separate the original person and the merging contacts
0116     int midWidth = option.rect.width() / 2;
0117     painter->setPen(opt.palette.color(QPalette::Window));
0118     painter->drawLine(option.rect.left() + midWidth - SIZE_STANDARD_PIXMAP,
0119                       option.rect.bottom() - 5,
0120                       option.rect.left() + midWidth - SIZE_STANDARD_PIXMAP,
0121                       option.rect.top() + 5);
0122 }
0123 
0124 #include "moc_mergedelegate.cpp"