diff --git a/examples/contactlistwidgets.cpp b/examples/contactlistwidgets.cpp index b07e546..2c2e876 100644 --- a/examples/contactlistwidgets.cpp +++ b/examples/contactlistwidgets.cpp @@ -1,167 +1,167 @@ /* Persons Model Example Copyright (C) 2012 Aleix Pol Gonzalez This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include #include #include #include #include #include #include using namespace KPeople; const int SPACING = 8; const int PHOTO_SIZE = 32; class PersonsDelegate : public QStyledItemDelegate { public: PersonsDelegate(QObject *parent = nullptr); ~PersonsDelegate(); void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const override; QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const override; }; PersonsDelegate::PersonsDelegate(QObject *parent) : QStyledItemDelegate(parent) { } PersonsDelegate::~PersonsDelegate() { } void PersonsDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const { QStyleOptionViewItem optV4 = option; initStyleOption(&optV4, index); painter->save(); - painter->setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform | QPainter::HighQualityAntialiasing); + painter->setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform); painter->setClipRect(optV4.rect); QStyle *style = QApplication::style(); style->drawPrimitive(QStyle::PE_PanelItemViewItem, &option, painter); QRect contactPhotoRect = optV4.rect; contactPhotoRect.adjust(SPACING, SPACING, SPACING, SPACING); contactPhotoRect.setWidth(PHOTO_SIZE); contactPhotoRect.setHeight(PHOTO_SIZE); QImage avatar = index.data(Qt::DecorationRole).value(); painter->drawImage(contactPhotoRect, avatar); painter->drawRect(contactPhotoRect); QRect nameRect = optV4.rect; nameRect.adjust(SPACING + PHOTO_SIZE + SPACING, SPACING, 0, 0); painter->drawText(nameRect, index.data(Qt::DisplayRole).toString()); QRect idRect = optV4.rect; idRect.adjust(SPACING + PHOTO_SIZE + SPACING, SPACING + 15, 0, 0); painter->drawText(idRect, index.data(PersonsModel::PersonUriRole).toString()); painter->restore(); } QSize PersonsDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const { Q_UNUSED(option) Q_UNUSED(index) return QSize(128, 48); } class ContactListApp : public QWidget { Q_OBJECT public: ContactListApp(); private Q_SLOTS: void onMergeClicked(); void onUnmergeClicked(); private: PersonsModel *m_model; QTreeView *m_view; }; ContactListApp::ContactListApp() { m_view = new QTreeView(this); m_model = new PersonsModel(this); QVBoxLayout *layout = new QVBoxLayout(this); QSortFilterProxyModel *sortFilter = new QSortFilterProxyModel(m_view); sortFilter->setDynamicSortFilter(true); sortFilter->setSourceModel(m_model); sortFilter->sort(0); m_view->setRootIsDecorated(false); m_view->setModel(sortFilter); m_view->setItemDelegate(new PersonsDelegate(this)); m_view->setSelectionMode(QAbstractItemView::ExtendedSelection); layout->addWidget(m_view); QPushButton *mergeButton = new QPushButton(QStringLiteral("Merge"), this); connect(mergeButton, SIGNAL(released()), SLOT(onMergeClicked())); layout->addWidget(mergeButton); QPushButton *unmergeButton = new QPushButton(QStringLiteral("Unmerge"), this); connect(unmergeButton, SIGNAL(released()), SLOT(onUnmergeClicked())); layout->addWidget(unmergeButton); } void ContactListApp::onMergeClicked() { const QModelIndexList indexes = m_view->selectionModel()->selectedIndexes(); QStringList ids; for (const QModelIndex &index : indexes) { ids << index.data(PersonsModel::PersonUriRole).toString(); } if (!ids.isEmpty()) { KPeople::mergeContacts(ids); } } void ContactListApp::onUnmergeClicked() { QModelIndexList indexes = m_view->selectionModel()->selectedIndexes(); if (!indexes.isEmpty()) { QString id = indexes.first().data(PersonsModel::PersonUriRole).toString(); KPeople::unmergeContact(id); } } int main(int argc, char **argv) { QApplication app(argc, argv); ContactListApp widget; widget.show(); app.exec(); } #include "contactlistwidgets.moc" diff --git a/src/widgets/mergedelegate.cpp b/src/widgets/mergedelegate.cpp index 01659d3..2095b82 100644 --- a/src/widgets/mergedelegate.cpp +++ b/src/widgets/mergedelegate.cpp @@ -1,130 +1,132 @@ /* KPeople - Duplicates Copyright (C) 2013 Franck Arrecot This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "mergedelegate.h" #include "personsmodel.h" #include "mergedialog.h" #include #include #include #include #include #include #include #include #include "kpeople_widgets_debug.h" #include #include #define MAX_MATCHING_CONTACTS_ICON 5 #define SIZE_STANDARD_PIXMAP 35 using namespace KPeople; //TODO: use proper, runtime values there QSize MergeDelegate::s_decorationSize(SIZE_STANDARD_PIXMAP, SIZE_STANDARD_PIXMAP); QSize MergeDelegate::s_arrowSize(15, 15); QSize MergeDelegate::pictureSize() { return s_decorationSize; } MergeDelegate::MergeDelegate(QAbstractItemView *parent) : KExtendableItemDelegate(parent) { static QIcon arrowD = QIcon::fromTheme(QStringLiteral("arrow-down")); setContractPixmap(arrowD.pixmap(s_arrowSize)); static QIcon arrowR = QIcon::fromTheme(QStringLiteral("arrow-right")); setExtendPixmap(arrowR.pixmap(s_arrowSize)); } MergeDelegate::~MergeDelegate() {} void MergeDelegate::onClickContactParent(const QModelIndex &parent) { if (isExtended(parent)) { contractItem(parent); } else { QItemSelection item = QItemSelection(parent, parent); onSelectedContactsChanged(item, QItemSelection()); } } void MergeDelegate::onSelectedContactsChanged(const QItemSelection &now , const QItemSelection &old) { if (!old.indexes().isEmpty()) { QModelIndex oldIdx = old.indexes().first(); if (isExtended(oldIdx)) { contractItem(oldIdx); } } if (!now.indexes().isEmpty()) { QModelIndex idx = now.indexes().first(); extendItem(buildMultipleLineLabel(idx), idx); } } QWidget *MergeDelegate::buildMultipleLineLabel(const QModelIndex &idx) { QString contents; - int rows = idx.model()->rowCount(idx); + const QAbstractItemModel *model = idx.model(); + const int rows = model->rowCount(idx); for (int i = 0 ; i < rows; ++i) { - QModelIndex child = idx.child(i, 0); + const QModelIndex child = model->index(i, 0, idx); Match m = child.data(MergeDialog::MergeReasonRole).value(); QString name = m.indexB.data(Qt::DisplayRole).toString(); QString display = i18nc("name: merge reasons", "%1: %2", name, m.matchReasons().join(i18nc("reasons join", ", "))); contents += display + QLatin1String("

"); } QLabel *childDisplay = new QLabel(contents, dynamic_cast(parent())); childDisplay->setAlignment(Qt::AlignRight); childDisplay->setFrameStyle(QFrame::StyledPanel | QFrame::Sunken); return childDisplay; } void MergeDelegate::paint(QPainter *painter, const QStyleOptionViewItem &optionOld, const QModelIndex &index) const { QStyleOptionViewItem option(optionOld); QStyleOptionViewItem opt(option); KExtendableItemDelegate::paint(painter, option, index); const int separation = 5; - int facesRows = qMin(index.model()->rowCount(index), MAX_MATCHING_CONTACTS_ICON); + const QAbstractItemModel *model = index.model(); + int facesRows = qMin(model->rowCount(index), MAX_MATCHING_CONTACTS_ICON); for (int i = 0; i < facesRows; i++) { // Children Icon Displaying Loop - const QModelIndex child = index.child(i, 0); + const QModelIndex child = model->index(i, 0, index); QVariant decoration = child.data(Qt::DecorationRole); Q_ASSERT(decoration.type() == (QVariant::Icon)); QIcon pix = decoration.value(); QPoint pixmapPoint = {option.rect.width() / 2 + i *(s_decorationSize.width() + separation), option.rect.top()}; painter->drawPixmap(pixmapPoint, pix.pixmap(s_decorationSize)); } // draw a vertical line to separate the original person and the merging contacts int midWidth = option.rect.width() / 2; painter->setPen(opt.palette.color(QPalette::Window)); painter->drawLine(option.rect.left() + midWidth - SIZE_STANDARD_PIXMAP, option.rect.bottom() - 5, option.rect.left() + midWidth - SIZE_STANDARD_PIXMAP, option.rect.top() + 5); }