PageRenderTime 145ms CodeModel.GetById 40ms app.highlight 68ms RepoModel.GetById 33ms app.codeStats 0ms

/src/sipconfigdelegate.cpp

http://github.com/tomahawk-player/tomahawk
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