Warning, file /network/ktp-contact-list/contact-delegate-compact.cpp was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).
0001 /* 0002 * Contact Delegate - compact version 0003 * 0004 * Copyright (C) 2011 Martin Klapetek <martin.klapetek@gmail.com> 0005 * Copyright (C) 2012 Dominik Cermak <d.cermak@arcor.de> 0006 * 0007 * This library is free software; you can redistribute it and/or 0008 * modify it under the terms of the GNU Lesser General Public 0009 * License as published by the Free Software Foundation; either 0010 * version 2.1 of the License, or (at your option) any later version. 0011 * 0012 * This library is distributed in the hope that it will be useful, 0013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 0014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 0015 * Lesser General Public License for more details. 0016 * 0017 * You should have received a copy of the GNU Lesser General Public 0018 * License along with this library; if not, write to the Free Software 0019 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 0020 */ 0021 0022 #include "contact-delegate-compact.h" 0023 0024 #include <QPainter> 0025 #include <QPainterPath> 0026 #include <QToolTip> 0027 #include <QApplication> 0028 #include <QStyle> 0029 #include <QHelpEvent> 0030 #include <QFontDatabase> 0031 #include <QPixmapCache> 0032 #include <QCryptographicHash> 0033 #include <QStyleOptionViewItem> 0034 0035 #include <KIconLoader> 0036 0037 #include <KTp/types.h> 0038 0039 ContactDelegateCompact::ContactDelegateCompact(ContactDelegateCompact::ListSize size, QObject *parent) 0040 : AbstractContactDelegate(parent) 0041 { 0042 setListMode(size); 0043 QPixmapCache::setCacheLimit(102400); 0044 } 0045 0046 ContactDelegateCompact::~ContactDelegateCompact() 0047 { 0048 0049 } 0050 0051 void ContactDelegateCompact::paintContact(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const 0052 { 0053 QStyleOptionViewItem opt = option; 0054 initStyleOption(&opt, index); 0055 0056 bool isSubcontact = index.parent().isValid() && index.parent().data(KTp::RowTypeRole).toUInt() == KTp::PersonRowType; 0057 0058 painter->save(); 0059 0060 painter->setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform | QPainter::HighQualityAntialiasing); 0061 painter->setClipRect(opt.rect); 0062 0063 QStyle *style = QApplication::style(); 0064 style->drawPrimitive(QStyle::PE_PanelItemViewItem, &opt, painter); 0065 0066 QRect iconRect = opt.rect; 0067 iconRect.setSize(QSize(m_avatarSize, m_avatarSize)); 0068 iconRect.moveTo(QPoint(iconRect.x() + m_spacing, iconRect.y() + m_spacing)); 0069 0070 QPixmap avatar(qvariant_cast<QPixmap>(index.data(KTp::ContactAvatarPixmapRole))); 0071 0072 if (index.data(KTp::ContactUnreadMessageCountRole).toInt() > 0) { 0073 avatar = SmallIcon("mail-unread-new", KIconLoader::SizeMedium); 0074 } 0075 0076 //if the contact is offline, gray it out 0077 if (index.data(KTp::ContactPresenceTypeRole).toUInt() == Tp::ConnectionPresenceTypeOffline) { 0078 if (!QPixmapCache::find(index.data(KTp::IdRole).toString() + QStringLiteral("gray"), &avatar)) { 0079 avatarToGray(avatar); 0080 QPixmapCache::insert(index.data(KTp::IdRole).toString() + QStringLiteral("gray"), avatar); 0081 } 0082 } 0083 0084 if (!avatar.isNull()) { 0085 style->drawItemPixmap(painter, iconRect, Qt::AlignCenter, avatar.scaled(iconRect.size(), Qt::KeepAspectRatio, Qt::SmoothTransformation)); 0086 } 0087 0088 // This value is used to set the correct width for the username and the presence message. 0089 int rightIconsWidth = m_presenceIconSize + m_spacing; 0090 0091 QPixmap icon = QIcon::fromTheme(index.data(KTp::ContactPresenceIconRole).toString()).pixmap(KIconLoader::SizeSmallMedium); 0092 0093 QRect statusIconRect = opt.rect; 0094 0095 statusIconRect.setSize(QSize(m_presenceIconSize, m_presenceIconSize)); 0096 statusIconRect.moveTo(QPoint(opt.rect.right() - (rightIconsWidth), 0097 opt.rect.top() + (opt.rect.height() - m_presenceIconSize) / 2)); 0098 0099 painter->drawPixmap(statusIconRect, icon); 0100 0101 // Right now we only check for 'phone', as that's the most interesting type. 0102 if (index.data(KTp::ContactClientTypesRole).toStringList().contains(QLatin1String("phone"))) { 0103 // Additional space is needed for the icons, don't add too much spacing between the two icons 0104 rightIconsWidth += m_clientTypeIconSize + m_spacing; 0105 0106 QPixmap phone = QIcon::fromTheme("phone").pixmap(m_clientTypeIconSize); 0107 QRect phoneIconRect = opt.rect; 0108 phoneIconRect.setSize(QSize(m_clientTypeIconSize, m_clientTypeIconSize)); 0109 phoneIconRect.moveTo(QPoint(opt.rect.right() - rightIconsWidth, 0110 opt.rect.top() + (opt.rect.height() - m_clientTypeIconSize) / 2)); 0111 painter->drawPixmap(phoneIconRect, phone); 0112 } 0113 0114 const Tp::AccountPtr &account = index.data(KTp::AccountRole).value<Tp::AccountPtr>(); 0115 if (account && isSubcontact) { 0116 rightIconsWidth += m_clientTypeIconSize + m_spacing; 0117 0118 const QPixmap accountIcon = QIcon::fromTheme(account->iconName()).pixmap(m_clientTypeIconSize); 0119 QRect accountIconRect = opt.rect; 0120 accountIconRect.setSize(QSize(m_clientTypeIconSize, m_clientTypeIconSize)); 0121 accountIconRect.moveTo(QPoint(opt.rect.right() - rightIconsWidth, 0122 opt.rect.top() + (opt.rect.height() - m_clientTypeIconSize) / 2)); 0123 painter->drawPixmap(accountIconRect, accountIcon); 0124 } 0125 0126 QFont nameFont; 0127 0128 if (m_listSize == ContactDelegateCompact::Mini) { 0129 nameFont = QFontDatabase::systemFont(QFontDatabase::SmallestReadableFont); 0130 } else { 0131 nameFont = QFontDatabase::systemFont(QFontDatabase::GeneralFont); 0132 } 0133 0134 const QFontMetrics nameFontMetrics(nameFont); 0135 0136 if (option.state & QStyle::State_Selected) { 0137 painter->setPen(option.palette.color(option.palette.currentColorGroup(), QPalette::HighlightedText)); 0138 } else { 0139 painter->setPen(option.palette.color(option.palette.currentColorGroup(), QPalette::Text)); 0140 } 0141 0142 painter->setFont(nameFont); 0143 0144 QRect userNameRect = opt.rect; 0145 userNameRect.setX(iconRect.x() + iconRect.width() + m_spacing * 2); 0146 userNameRect.setY(userNameRect.y() + (userNameRect.height()/2 - nameFontMetrics.height()/2)); 0147 userNameRect.setWidth(userNameRect.width() - rightIconsWidth); 0148 0149 QString nameText = index.data(Qt::DisplayRole).toString(); 0150 0151 painter->drawText(userNameRect, 0152 nameFontMetrics.elidedText(nameText, Qt::ElideRight, userNameRect.width())); 0153 0154 QRect presenceMessageRect = opt.rect; 0155 presenceMessageRect.setX(userNameRect.x() + nameFontMetrics.boundingRect(opt.text).width() + m_spacing * 2); 0156 presenceMessageRect.setWidth(opt.rect.width() - presenceMessageRect.x() - rightIconsWidth); 0157 presenceMessageRect.setY(presenceMessageRect.y() + (presenceMessageRect.height()/2 - nameFontMetrics.height()/2)); 0158 0159 if (option.state & QStyle::State_Selected) { 0160 painter->setPen(option.palette.color(QPalette::Disabled, QPalette::HighlightedText)); 0161 } else { 0162 painter->setPen(option.palette.color(QPalette::Disabled, QPalette::Text)); 0163 } 0164 0165 painter->drawText(presenceMessageRect, 0166 nameFontMetrics.elidedText(index.data(KTp::ContactPresenceMessageRole).toString().trimmed(), 0167 Qt::ElideRight, presenceMessageRect.width())); 0168 0169 painter->restore(); 0170 } 0171 0172 QSize ContactDelegateCompact::sizeHintContact(const QStyleOptionViewItem &option, const QModelIndex &index) const 0173 { 0174 Q_UNUSED(option); 0175 Q_UNUSED(index); 0176 0177 return QSize(0, qMax(m_avatarSize + 2 * m_spacing, QFontDatabase::systemFont(QFontDatabase::SmallestReadableFont).pixelSize() + m_spacing)); 0178 } 0179 0180 QSize ContactDelegateCompact::sizeHintHeader(const QStyleOptionViewItem& option, const QModelIndex& index) const 0181 { 0182 Q_UNUSED(option); 0183 Q_UNUSED(index); 0184 0185 if (m_listSize == ContactDelegateCompact::Mini) { 0186 return QSize(0, qMax(m_avatarSize + 2 * m_spacing, QFontDatabase::systemFont(QFontDatabase::SmallestReadableFont).pixelSize() + m_spacing)); 0187 } else { 0188 return AbstractContactDelegate::sizeHintHeader(option, index); 0189 } 0190 } 0191 0192 void ContactDelegateCompact::setListMode(ContactDelegateCompact::ListSize size) 0193 { 0194 if (size == ContactDelegateCompact::Mini) { 0195 m_spacing = 1; 0196 int iconSize = qMax(KIconLoader::global()->currentSize(KIconLoader::Small), 0197 QFontDatabase::systemFont(QFontDatabase::SmallestReadableFont).pixelSize() + m_spacing); 0198 m_avatarSize = iconSize; 0199 m_presenceIconSize = iconSize; 0200 m_clientTypeIconSize = iconSize; 0201 } else if (size == ContactDelegateCompact::Normal) { 0202 m_spacing = 4; 0203 m_avatarSize = IconSize(KIconLoader::Toolbar); 0204 m_presenceIconSize = IconSize(KIconLoader::Small); 0205 m_clientTypeIconSize = IconSize(KIconLoader::Small); 0206 } 0207 0208 m_listSize = size; 0209 }