File indexing completed on 2023-11-26 04:55:35
0001 /* 0002 * This file is part of telepathy-accounts-kcm 0003 * 0004 * Copyright (C) 2011 David Edmundson <kde@davidedmundson.co.uk> 0005 * Copyright (C) 2012 Daniele E. Domenichelli <daniele.domenichelli@gmail.com> 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 "accounts-list-delegate.h" 0023 0024 #include "edit-display-name-button.h" 0025 #include "change-icon-button.h" 0026 0027 #include <KTp/presence.h> 0028 #include <KTp/Models/accounts-list-model.h> 0029 0030 #include <KDE/KLocale> 0031 #include <KDE/KIconButton> 0032 #include <KDE/KMenu> 0033 #include <KDE/KAction> 0034 #include <KDE/KDebug> 0035 0036 #include <QtGui/QApplication> 0037 #include <QtGui/QPainter> 0038 #include <QtGui/QCheckBox> 0039 #include <QtGui/QAbstractItemView> 0040 #include <QtGui/QSortFilterProxyModel> 0041 #include <QtGui/QLabel> 0042 #include <sys/stat.h> 0043 0044 0045 AccountsListDelegate::AccountsListDelegate(QAbstractItemView *itemView, QObject *parent) 0046 : KWidgetItemDelegate(itemView, parent) 0047 { 0048 } 0049 0050 QSize AccountsListDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const 0051 { 0052 Q_UNUSED(index); 0053 0054 int iconHeight = option.decorationSize.height() + (m_vpadding*2); //icon height + padding either side 0055 int textHeight = option.fontMetrics.height()*2 + (m_vpadding*2) + 10; // text height * 2 + padding + some space between the lines 0056 0057 return QSize(-1,qMax(iconHeight, textHeight)); //any width,the view should give us the whole thing. 0058 } 0059 0060 QList<QWidget*> AccountsListDelegate::createItemWidgets() const 0061 { 0062 // Items created by this method and added to the list returned will be 0063 // deleted by KWidgetItemDelegate 0064 0065 QCheckBox *checkbox = new QCheckBox(); 0066 connect(checkbox, SIGNAL(clicked(bool)), SLOT(onCheckBoxToggled(bool))); 0067 0068 ChangeIconButton *changeIconButton = new ChangeIconButton(); 0069 changeIconButton->setFlat(true); 0070 changeIconButton->setToolTip(i18n("Change account icon")); 0071 changeIconButton->setWhatsThis(i18n("This button allows you to change the icon for your account.<br />" 0072 "This icon is just used locally on your computer, your contacts will not be able to see it.")); 0073 0074 QLabel *statusTextLabel = new QLabel(); 0075 QLabel *statusIconLabel = new QLabel(); 0076 0077 EditDisplayNameButton *displayNameButton = new EditDisplayNameButton(); 0078 displayNameButton->setFlat(true); 0079 displayNameButton->setToolTip(i18n("Change account display name")); 0080 displayNameButton->setWhatsThis(i18n("This button allows you to change the display name for your account.<br />" 0081 "The display name is an alias for your account and is just used locally " 0082 "on your computer, your contacts will not be able to see it.")); 0083 0084 QLabel *connectionErrorLabel = new QLabel(); 0085 0086 return QList<QWidget*>() << checkbox 0087 << changeIconButton 0088 << statusTextLabel 0089 << statusIconLabel 0090 << displayNameButton 0091 << connectionErrorLabel; 0092 } 0093 0094 0095 void AccountsListDelegate::updateItemWidgets(const QList<QWidget *> widgets, const QStyleOptionViewItem &option, const QPersistentModelIndex &index) const 0096 { 0097 // draws: 0098 // AccountName 0099 // Checkbox | Icon | | ConnectionIcon | ConnectionState 0100 // errorMessage 0101 0102 if (!index.isValid()) { 0103 return; 0104 } 0105 0106 Q_ASSERT(widgets.size() == 6); 0107 0108 // Get the widgets 0109 QCheckBox* checkbox = qobject_cast<QCheckBox*>(widgets.at(0)); 0110 ChangeIconButton* changeIconButton = qobject_cast<ChangeIconButton*>(widgets.at(1)); 0111 QLabel *statusTextLabel = qobject_cast<QLabel*>(widgets.at(2)); 0112 QLabel *statusIconLabel = qobject_cast<QLabel*>(widgets.at(3)); 0113 EditDisplayNameButton *displayNameButton = qobject_cast<EditDisplayNameButton*>(widgets.at(4)); 0114 QLabel *connectionErrorLabel = qobject_cast<QLabel*>(widgets.at(5)); 0115 0116 Q_ASSERT(checkbox); 0117 Q_ASSERT(changeIconButton); 0118 Q_ASSERT(statusTextLabel); 0119 Q_ASSERT(statusIconLabel); 0120 Q_ASSERT(displayNameButton); 0121 Q_ASSERT(connectionErrorLabel); 0122 0123 0124 bool isSelected(itemView()->selectionModel()->isSelected(index) && itemView()->hasFocus()); 0125 bool isEnabled(index.data(KTp::AccountsListModel::EnabledRole).toBool()); 0126 KIcon accountIcon(index.data(Qt::DecorationRole).value<QIcon>()); 0127 KIcon statusIcon(index.data(KTp::AccountsListModel::ConnectionStateIconRole).value<QIcon>()); 0128 QString statusText(index.data(KTp::AccountsListModel::ConnectionStateDisplayRole).toString()); 0129 QString displayName(index.data(Qt::DisplayRole).toString()); 0130 QString connectionError(index.data(KTp::AccountsListModel::ConnectionErrorMessageDisplayRole).toString()); 0131 Tp::AccountPtr account(index.data(KTp::AccountsListModel::AccountRole).value<Tp::AccountPtr>()); 0132 0133 if (!account->isEnabled()) { 0134 connectionError = i18n("Click checkbox to enable"); 0135 } 0136 0137 QRect outerRect(0, 0, option.rect.width(), option.rect.height()); 0138 QRect contentRect = outerRect.adjusted(m_hpadding,m_vpadding,-m_hpadding,-m_vpadding); //add some padding 0139 0140 0141 // checkbox 0142 if (isEnabled) { 0143 checkbox->setChecked(true);; 0144 checkbox->setToolTip(i18n("Disable account")); 0145 } else { 0146 checkbox->setChecked(false); 0147 checkbox->setToolTip(i18n("Enable account")); 0148 } 0149 0150 int checkboxLeftMargin = contentRect.left(); 0151 int checkboxTopMargin = (outerRect.height() - checkbox->height()) / 2; 0152 checkbox->move(checkboxLeftMargin, checkboxTopMargin); 0153 0154 0155 // changeIconButton 0156 changeIconButton->setIcon(accountIcon); 0157 changeIconButton->setAccount(account); 0158 // At the moment (KDE 4.8.1) decorationSize is not passed from KWidgetItemDelegate 0159 // through the QStyleOptionViewItem, therefore we leave default size unless 0160 // the user has a more recent version. 0161 if (option.decorationSize.width() > -1) { 0162 changeIconButton->setButtonIconSize(option.decorationSize.width()); 0163 } 0164 0165 int changeIconButtonLeftMargin = checkboxLeftMargin + checkbox->width(); 0166 int changeIconButtonTopMargin = (outerRect.height() - changeIconButton->height()) / 2; 0167 changeIconButton->move(changeIconButtonLeftMargin, changeIconButtonTopMargin); 0168 0169 0170 // statusTextLabel 0171 QFont statusTextFont = option.font; 0172 QPalette statusTextLabelPalette = option.palette; 0173 if (isEnabled) { 0174 statusTextLabel->setEnabled(true); 0175 statusTextFont.setItalic(false); 0176 } else { 0177 statusTextLabel->setDisabled(true); 0178 statusTextFont.setItalic(true); 0179 } 0180 if (isSelected) { 0181 statusTextLabelPalette.setColor(QPalette::Text, statusTextLabelPalette.color(QPalette::Active, QPalette::HighlightedText)); 0182 } 0183 statusTextLabel->setPalette(statusTextLabelPalette); 0184 statusTextLabel->setFont(statusTextFont); 0185 statusTextLabel->setText(statusText); 0186 statusTextLabel->setFixedSize(statusTextLabel->fontMetrics().boundingRect(statusText).width(), 0187 statusTextLabel->height()); 0188 int statusTextLabelLeftMargin = contentRect.right() - statusTextLabel->width(); 0189 int statusTextLabelTopMargin = (outerRect.height() - statusTextLabel->height()) / 2; 0190 statusTextLabel->move(statusTextLabelLeftMargin, statusTextLabelTopMargin); 0191 0192 0193 // statusIconLabel 0194 statusIconLabel->setPixmap(statusIcon.pixmap(KIconLoader::SizeSmall)); 0195 statusIconLabel->setFixedSize(statusIconLabel->minimumSizeHint()); 0196 int statusIconLabelLeftMargin = contentRect.right() - statusTextLabel->width() - statusIconLabel->width() - 6; 0197 int statusIconLabelTopMargin = (outerRect.height() - statusIconLabel->height()) / 2; 0198 statusIconLabel->move(statusIconLabelLeftMargin, statusIconLabelTopMargin); 0199 0200 0201 QRect innerRect = contentRect.adjusted(changeIconButton->geometry().right() - contentRect.left(), 0202 0, 0203 -statusTextLabel->width() - statusIconLabel->width() - 6, 0204 0); // rect containing account name and error message 0205 0206 0207 // displayNameButton 0208 QFont displayNameButtonFont = option.font; 0209 QPalette displayNameButtonPalette = option.palette; 0210 if (isEnabled) { 0211 displayNameButtonPalette.setColor(QPalette::WindowText, displayNameButtonPalette.color(QPalette::Active, QPalette::Text)); 0212 displayNameButtonFont.setBold(true); 0213 } else { 0214 displayNameButtonFont.setItalic(true); 0215 // NOTE: Flat QPushButton use WindowText instead of ButtonText for button text color 0216 displayNameButtonPalette.setColor(QPalette::WindowText, displayNameButtonPalette.color(QPalette::Disabled, QPalette::Text)); 0217 } 0218 if (isSelected) { 0219 // Account is selected 0220 displayNameButtonPalette.setColor(QPalette::WindowText, displayNameButtonPalette.color(QPalette::Active, QPalette::HighlightedText)); 0221 } 0222 displayNameButton->setFont(displayNameButtonFont); 0223 displayNameButton->setPalette(displayNameButtonPalette); 0224 0225 QString displayNameButtonText = displayNameButton->fontMetrics().elidedText(displayName, 0226 Qt::ElideRight, 0227 innerRect.width() - (m_hpadding*2)); 0228 displayNameButton->setText(displayNameButtonText); 0229 displayNameButton->setFixedSize(displayNameButton->fontMetrics().boundingRect(displayNameButtonText).width() + (m_hpadding*2), 0230 displayNameButton->minimumSizeHint().height()); 0231 displayNameButton->setAccount(account); 0232 0233 int displayNameButtonLeftMargin = innerRect.left(); 0234 int displayNameButtonTopMargin = innerRect.top(); 0235 displayNameButton->move(displayNameButtonLeftMargin, displayNameButtonTopMargin); 0236 0237 0238 // connectionErrorLabel 0239 QFont connectionErrorLabelFont = option.font; 0240 QPalette connectionErrorLabelPalette = option.palette; 0241 if (isEnabled) { 0242 connectionErrorLabelPalette.setColor(QPalette::WindowText, connectionErrorLabelPalette.color(QPalette::Active, QPalette::Text)); 0243 } else { 0244 connectionErrorLabelFont.setItalic(true); 0245 connectionErrorLabelPalette.setColor(QPalette::Text, connectionErrorLabelPalette.color(QPalette::Disabled, QPalette::Text)); 0246 } 0247 if (isSelected) { 0248 // Account is selected 0249 connectionErrorLabelPalette.setColor(QPalette::Text, connectionErrorLabelPalette.color(QPalette::Active, QPalette::HighlightedText)); 0250 } 0251 connectionErrorLabel->setFont(connectionErrorLabelFont); 0252 connectionErrorLabel->setPalette(connectionErrorLabelPalette); 0253 0254 QString connectionErrorLabelText = connectionErrorLabel->fontMetrics().elidedText(connectionError, 0255 Qt::ElideRight, 0256 innerRect.width() - (m_hpadding*2)); 0257 connectionErrorLabel->setText(connectionErrorLabelText); 0258 connectionErrorLabel->setFixedSize(connectionErrorLabel->fontMetrics().boundingRect(connectionErrorLabelText).width(), 0259 displayNameButton->height()); 0260 0261 int connectionErrorLabelLeftMargin = innerRect.left() + m_hpadding; 0262 int connectionErrorLabelTopMargin = contentRect.bottom() - displayNameButton->height(); 0263 connectionErrorLabel->move(connectionErrorLabelLeftMargin, connectionErrorLabelTopMargin); 0264 } 0265 0266 void AccountsListDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const 0267 { 0268 if (!index.isValid()) { 0269 return; 0270 } 0271 0272 QApplication::style()->drawPrimitive(QStyle::PE_PanelItemViewItem, &option, painter, 0); 0273 } 0274 0275 0276 void AccountsListDelegate::onCheckBoxToggled(bool checked) 0277 { 0278 QModelIndex index = focusedIndex(); 0279 Q_EMIT itemChecked(index, checked); 0280 }