/src/sipconfigdelegate.cpp
C++ | 282 lines | 207 code | 40 blank | 35 comment | 21 complexity | a061bcc0d9efb1ee5a0bb0bd70c0fcf2 MD5 | raw file
1/* 2 Copyright (C) 2011 Leo Franchi <leo.franchi@kdab.com> 3 4 This program is free software: you can redistribute it and/or modify 5 it under the terms of the GNU General Public License as published by 6 the Free Software Foundation, either version 3 of the License, or 7 (at your option) any later version. 8 9 This program is distributed in the hope that it will be useful, 10 but WITHOUT ANY WARRANTY; without even the implied warranty of 11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 GNU General Public License for more details. 13 14 You should have received a copy of the GNU General Public License 15 along with this program. If not, see <http://www.gnu.org/licenses/>. 16*/ 17 18 19#include "sipconfigdelegate.h" 20 21#include <QApplication> 22#include <QPainter> 23 24#include "sip/SipModel.h" 25#include "sip/SipPlugin.h" 26 27#include "utils/tomahawkutils.h" 28#include "utils/logger.h" 29 30#define ICONSIZE 24 31#define CHECK_LEFT_EDGE 8 32 33 34SipConfigDelegate::SipConfigDelegate( QObject* parent ) 35 : ConfigDelegateBase ( parent ) 36{ 37 connect( this, SIGNAL( configPressed( QModelIndex ) ), this, SLOT( askedForEdit( QModelIndex ) ) ); 38} 39 40bool 41SipConfigDelegate::editorEvent ( QEvent* event, QAbstractItemModel* model, const QStyleOptionViewItem& option, const QModelIndex& index ) 42{ 43 return ConfigDelegateBase::editorEvent( event, model, option, index ); 44} 45 46void 47SipConfigDelegate::paint ( QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index ) const 48{ 49 QStyleOptionViewItemV4 opt = option; 50 initStyleOption( &opt, index ); 51 QRect itemRect = opt.rect; 52 int top = itemRect.top(); 53 int mid = itemRect.height() / 2; 54 55 // one line bold for account name 56 // space below it fro an error 57 // checkbox, icon, name, online/offline status, config icon 58 QFont name = opt.font; 59 name.setPointSize( name.pointSize() + 2 ); 60 name.setBold( true ); 61 62 QFont error = opt.font; 63 error.setItalic( true ); 64 error.setPointSize( error.pointSize() - 2 ); 65 66 // draw the background 67 const QWidget* w = opt.widget; 68 QStyle* style = w ? w->style() : QApplication::style(); 69 style->drawPrimitive( QStyle::PE_PanelItemViewItem, &opt, painter, w ); 70 71 int iconLeftEdge = CHECK_LEFT_EDGE + ICONSIZE + PADDING; 72 int textLeftEdge = iconLeftEdge + ICONSIZE + PADDING; 73 74 if( index.data( SipModel::FactoryRole ).toBool() ) { // this is the "add new account" row 75 // draw a border and background 76 painter->save(); 77 painter->setRenderHints( QPainter::Antialiasing ); 78 painter->setBrush( QApplication::palette().color( QPalette::Active, QPalette::Highlight ).lighter( 150 ) ); 79 QPainterPath roundedRect; 80 roundedRect.addRoundedRect( itemRect.adjusted( 1, 1, -1, -1 ), 3, 3 ); 81 painter->drawPath( roundedRect ); 82 painter->setBrush( QApplication::palette().color( QPalette::Active, QPalette::Highlight ).lighter( 170 ) ); 83 painter->fillPath( roundedRect, painter->brush() ); 84 painter->restore(); 85 86 // draw "+" icon in checkbox column 87 int rectW = 18; 88 int diff = ( ICONSIZE/ 2 ) - ( rectW / 2) ; 89 int pos = ( mid ) - ( rectW / 2 ); 90 QRect plusRect = QRect( CHECK_LEFT_EDGE + diff, pos + top, rectW, rectW ); 91 QPixmap p( RESPATH "images/list-add.png" ); 92 painter->drawPixmap( plusRect, p ); 93 94 // draw text 95 QFont f = opt.font; 96 f.setPointSize( f.pointSize() ); 97 f.setBold( true ); 98 QFontMetrics fm( f ); 99 QString text = index.data( Qt::DisplayRole ).toString(); 100 QRect textR = fm.boundingRect( text ); 101 textR.moveLeft( textLeftEdge ); 102 textR.moveTop( mid - ( textR.height() / 2 ) + top ); 103 textR.setRight( itemRect.right() ); 104 painter->setFont( f ); 105 painter->drawText( textR, text ); 106 } else if( index.data( SipModel::FactoryItemRole ).toBool() ) { // this is an account type 107 108// ConfigDelegateBase::paint( painter, opt, index ); 109// int indent = 10; 110 // draw a border and background 111 painter->save(); 112 painter->setRenderHints( QPainter::Antialiasing ); 113 painter->setBrush( QApplication::palette().color( QPalette::Active, QPalette::Highlight ).lighter( 170 ) ); 114 QPainterPath roundedRect; 115 roundedRect.addRoundedRect( itemRect.adjusted( 1, 1, -1, -1 ), 3, 3 ); 116 painter->drawPath( roundedRect ); 117 painter->setBrush( QApplication::palette().color( QPalette::Active, QPalette::Highlight ).lighter( 180 ) ); 118 painter->fillPath( roundedRect, painter->brush() ); 119 painter->restore(); 120 121 QIcon icon = index.data( SipModel::FactoryItemIcon ).value< QIcon >(); 122 if( !icon.isNull() ) { 123 int rectW = 18; 124 int diff = ( ICONSIZE/ 2 ) - ( rectW / 2) ; 125 int pos = ( mid ) - ( rectW / 2 ); 126 QRect rect = QRect( CHECK_LEFT_EDGE + diff, pos + top, rectW, rectW ); 127 QPixmap p( icon.pixmap( rect.size() ) ); 128 painter->drawPixmap( rect, p ); 129 } 130 131 // draw text 132 QFont f = opt.font; 133 f.setPointSize( f.pointSize() ); 134 f.setBold( true ); 135 QFontMetrics fm( f ); 136 QString text = index.data( Qt::DisplayRole ).toString(); 137 QRect textR = fm.boundingRect( text ); 138 textR.moveLeft( textLeftEdge ); 139 textR.moveTop( mid - ( textR.height() / 2 ) + top ); 140 textR.setRight( itemRect.right() ); 141 painter->setFont( f ); 142 painter->drawText( textR, text ); 143 } else { // this is an existing account to show 144 // draw checkbox first 145 int pos = ( mid ) - ( ICONSIZE / 2 ); 146 QRect checkRect = QRect( CHECK_LEFT_EDGE, pos + top, ICONSIZE, ICONSIZE ); 147 opt.rect = checkRect; 148 drawCheckBox( opt, painter, w ); 149 150 // draw the icon if it exists 151 pos = ( mid ) - ( ICONSIZE / 2 ); 152 if( !index.data( Qt::DecorationRole ).value< QIcon >().isNull() ) { 153 QRect prect = QRect( iconLeftEdge, pos + top, ICONSIZE, ICONSIZE ); 154 155 painter->save(); 156 painter->drawPixmap( prect, index.data( Qt::DecorationRole ).value< QIcon >().pixmap( prect.size() ) ); 157 painter->restore(); 158 } 159 160 // from the right edge--config status and online/offline 161 QRect confRect = QRect( itemRect.width() - ICONSIZE - 2 * PADDING, mid - ICONSIZE / 2 + top, ICONSIZE, ICONSIZE ); 162 if( index.data( SipModel::HasConfig ).toBool() ) { 163 164 QStyleOptionToolButton topt; 165 topt.rect = confRect; 166 topt.pos = confRect.topLeft(); 167 168 drawConfigWrench( painter, opt, topt ); 169 } 170 171 // draw the online/offline status 172 int statusIconSize = 18; 173 int statusX = confRect.left() - 2*PADDING - statusIconSize; 174 QFont statusF = opt.font; 175 statusF.setPointSize( statusF.pointSize() - 2 ); 176 QFontMetrics statusFM( statusF ); 177 178 QPixmap p; 179 QString statusText; 180 SipPlugin::ConnectionState state = static_cast< SipPlugin::ConnectionState >( index.data( SipModel::ConnectionStateRole ).toInt() ); 181 if( state == SipPlugin::Connected ) { 182 p = QPixmap( RESPATH "images/sipplugin-online.png" ); 183 statusText = tr( "Online" ); 184 } else if( state == SipPlugin::Connecting ) { 185 p = QPixmap( RESPATH "images/sipplugin-offline.png" ); 186 statusText = tr( "Connecting..." ); 187 } else { 188 p = QPixmap( RESPATH "images/sipplugin-offline.png" ); 189 statusText = tr( "Offline" ); 190 } 191 p = p.scaled( statusIconSize, statusIconSize, Qt::KeepAspectRatio, Qt::SmoothTransformation ); 192 painter->drawPixmap( statusX, mid - statusIconSize / 2 + top, statusIconSize, statusIconSize, p ); 193 int width = statusFM.width( statusText ); 194 statusX = statusX - PADDING - width; 195 painter->save(); 196 painter->setFont( statusF ); 197 painter->drawText( QRect( statusX, mid - statusFM.height() / 2 + top, width, statusFM.height() ), statusText ); 198 painter->restore(); 199 200 // name 201 painter->save(); 202 QFontMetrics namefm( name ); 203 int nameHeight = namefm.boundingRect( "test" ).height(); 204 // pos will the top-left point of the text rect 205 pos = mid - ( nameHeight / 2 ); 206 // TODO bound with config icon and offline/online status 207 width = itemRect.width() - textLeftEdge; 208 209 if( !index.data( SipModel::ErrorString ).toString().isEmpty() ) { // error, show that too 210 QRect errorRect( textLeftEdge, mid + top, width, mid - PADDING + 1 ); 211 212 QFontMetrics errorFm( error ); 213 QString str = errorFm.elidedText( index.data( SipModel::ErrorString ).toString(), Qt::ElideRight, errorRect.width() ); 214 painter->setFont( error ); 215 painter->drawText( errorRect, str ); 216 217 pos = mid - errorRect.height() - 2; // move the name rect up 218 } 219 QString nameStr = namefm.elidedText( index.data( Qt::DisplayRole ).toString(), Qt::ElideRight, width ); 220 painter->setFont( name ); 221 painter->drawText( QRect( textLeftEdge, pos + top, width, nameHeight + 1 ), nameStr ); 222 painter->restore(); 223 } 224} 225 226QRect 227SipConfigDelegate::checkRectForIndex( const QStyleOptionViewItem &option, const QModelIndex &idx ) const 228{ 229 if( !idx.data( SipModel::FactoryItemRole ).toBool() && !idx.data( SipModel::FactoryRole ).toBool() ) 230 { 231 QStyleOptionViewItemV4 opt = option; 232 initStyleOption( &opt, idx ); 233 int mid = opt.rect.height() / 2; 234 int pos = ( mid ) - ( ICONSIZE / 2 ); 235 QRect checkRect = QRect( CHECK_LEFT_EDGE, pos + opt.rect.top(), ICONSIZE, ICONSIZE ); 236 237 return checkRect; 238 } 239 return QRect(); 240} 241 242QRect 243SipConfigDelegate::configRectForIndex( const QStyleOptionViewItem& option, const QModelIndex& idx ) const 244{ 245 if( !idx.data( SipModel::FactoryItemRole ).toBool() && !idx.data( SipModel::FactoryRole ).toBool() ) 246 { 247 QStyleOptionViewItemV4 opt = option; 248 initStyleOption( &opt, idx ); 249 QRect itemRect = opt.rect; 250 QRect confRect = QRect( itemRect.width() - ICONSIZE - 2 * PADDING, (opt.rect.height() / 2) - ICONSIZE / 2 + opt.rect.top(), ICONSIZE, ICONSIZE ); 251 return confRect; 252 } 253 return QRect(); 254} 255 256 257QSize 258SipConfigDelegate::sizeHint( const QStyleOptionViewItem& option, const QModelIndex& index ) const 259{ 260 if( index.data( SipModel::FactoryRole ).toBool() || index.data( SipModel::FactoryItemRole ).toBool() ) { // this is the "add new account" row 261 // enough space for one line of text 262 QStyleOptionViewItemV4 opt = option; 263 initStyleOption( &opt, index ); 264 int width = QStyledItemDelegate::sizeHint( option, index ).width(); 265 266 QFont name = opt.font; 267 name.setPointSize( name.pointSize() + 1 ); 268 name.setBold( true ); 269 QFontMetrics sfm( name ); 270 return QSize( width, 3 * PADDING + sfm.height() ); 271 } else { // this is an existing account to show 272 return ConfigDelegateBase::sizeHint( option, index ); 273 } 274} 275 276void 277SipConfigDelegate::askedForEdit( const QModelIndex& idx ) 278{ 279 emit openConfig( qobject_cast< SipPlugin* >( idx.data( SipModel::SipPluginData ).value< QObject* >() ) ); 280} 281 282