00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "blogdelegate.h"
00021 #include "blogdelegate.moc"
00022
00023 #include "checkboxview.h"
00024 #include "../blokkalaccount.h"
00025 #include "../blokkalblog.h"
00026 #include "../blokkalutils.h"
00027 #include "../blokkalio/categorymanager.h"
00028
00029 #include <kdebug.h>
00030 #include <klocale.h>
00031 #include <kdialog.h>
00032 #include <kglobalsettings.h>
00033
00034 #include <QPainter>
00035 #include <QModelIndex>
00036 #include <QApplication>
00037
00038 class Blokkal::Ui::BlogDelegate::Private {
00039 public:
00040 Private( unsigned int displayOptions ):
00041 displayOptions( displayOptions ){}
00042
00043 const unsigned int displayOptions;
00044
00045 static QString blogDescription( const Blokkal::Blog * blog ) {
00046 return i18n( "%1 (%2)", blog->id(), blog->type() );
00047 }
00048
00049 static QString blogCount( const Blokkal::Account * account ) {
00050 return i18n( "(%1)", account->blogs().size() );
00051 }
00052 };
00053
00054 Blokkal::Ui::BlogDelegate::BlogDelegate( unsigned int displayOptions ):
00055 CheckBoxDelegate(),
00056 d( new Private( displayOptions ) )
00057 {
00058 }
00059
00060 Blokkal::Ui::BlogDelegate::~BlogDelegate( void )
00061 {
00062 delete d;
00063 }
00064
00065 void Blokkal::Ui::BlogDelegate::paint( QPainter * painter,
00066 const QStyleOptionViewItem & option,
00067 const QModelIndex & index ) const
00068 {
00069 CheckBoxDelegate::paint( painter, option, index );
00070 painter->save();
00071
00072 Blokkal::Account * account = dynamic_cast<Blokkal::Account*>( (QObject*) index.data().toULongLong() );
00073 if( account ) {
00074 QRect iconRect;
00075 QRect textRect;
00076 QRect countRect;
00077 layoutAccount( option, account, iconRect, textRect, countRect );
00078 if( iconRect.isValid() ) {
00079 if( displayOptions() & DisplayAccountStates ) {
00080 if( account->connectionStatus() != Account::Connecting ) {
00081 view()->disconnectIndex( index );
00082 drawDecoration( painter, option, iconRect, account->isConnected() ? account->icon().pixmap( 16 ) : Utils::fadePixmap( account->icon().pixmap( 16 ) ) );
00083 }
00084 else {
00085 view()->connectIndex( index, 300 );
00086 drawDecoration( painter,
00087 option,
00088 iconRect,
00089 view()->toogleBlinkState( index ) ? Utils::fadePixmap( account->icon().pixmap( 16 ) ) : account->icon().pixmap( 16 ) );
00090 }
00091 }
00092 else {
00093 drawDecoration( painter, option, iconRect, account->icon().pixmap( 16 ) );
00094 }
00095 }
00096
00097 QStyleOptionViewItem myOption = option;
00098 if( displayOptions() & DisplayAccountStates
00099 && !account->isConnected() )
00100 {
00101 myOption.palette.setBrush( QPalette::Active, QPalette::Text,
00102 myOption.palette.brush( QPalette::Disabled, QPalette::Text ) );
00103 myOption.palette.setBrush( QPalette::Inactive, QPalette::Text,
00104 myOption.palette.brush( QPalette::Disabled, QPalette::Text ) );
00105 }
00106
00107 if( textRect.isValid() ) {
00108 drawDisplay( painter, myOption, textRect, account->id() );
00109 }
00110
00111 if( countRect.isValid() ) {
00112 QStyleOptionViewItem countOption = myOption;
00113 countOption.font = KGlobalSettings::smallestReadableFont();
00114 countOption.fontMetrics = QFontMetrics( countOption.font );
00115 drawDisplay( painter, countOption, countRect, d->blogCount( account ) );
00116 }
00117
00118 painter->restore();
00119 return;
00120 }
00121 Blokkal::Blog * blog = dynamic_cast<Blokkal::Blog*>( (QObject*) index.data().toULongLong() );
00122 if( blog ) {
00123 QString title = blog->title().isEmpty() ? blog->id() : blog->title();
00124 QString idTypeString = d->blogDescription( blog );
00125 QRect iconRect;
00126 QRect textRect;
00127 QRect infoRect;
00128 layoutBlog( option, index, blog, iconRect, textRect, infoRect );
00129 if( iconRect.isValid() ) {
00130 if( displayOptions() & DisplayAccountStates
00131 && !blog->account()->isConnected() )
00132 {
00133 drawDecoration( painter, option, iconRect, Utils::fadePixmap( blog->icon().pixmap( 16 ) ) );
00134 }
00135 else {
00136 drawDecoration( painter, option, iconRect, blog->icon().pixmap( 16 ) );
00137 }
00138 }
00139
00140 QStyleOptionViewItem myOption = option;
00141 if( displayOptions() & DisplayAccountStates
00142 && !blog->account()->isConnected() )
00143 {
00144 myOption.palette.setBrush( QPalette::Active, QPalette::Text,
00145 myOption.palette.brush( QPalette::Disabled, QPalette::Text ) );
00146 myOption.palette.setBrush( QPalette::Inactive, QPalette::Text,
00147 myOption.palette.brush( QPalette::Disabled, QPalette::Text ) );
00148 }
00149
00150 if( textRect.isValid() ) {
00151 drawDisplay( painter, myOption, textRect, title );
00152 }
00153
00154 if( infoRect.isValid() ) {
00155 QStyleOptionViewItem infoOption = myOption;
00156 infoOption.font = KGlobalSettings::smallestReadableFont();
00157 infoOption.fontMetrics = QFontMetrics( infoOption.font );
00158 drawDisplay( painter, infoOption, infoRect, idTypeString );
00159 }
00160
00161 painter->restore();
00162 return;
00163 }
00164
00165 Blokkal::Io::Category * category = dynamic_cast<Blokkal::Io::Category*>( (QObject*) index.data().toULongLong() );
00166 if( category ) {
00167 QRect textRect;
00168 layoutPlainItem( option, index, textRect );
00169 if( textRect.isValid() ) {
00170 drawDisplay( painter, option, textRect, category->name() );
00171 }
00172
00173 painter->restore();
00174 return;
00175 }
00176
00177 painter->restore();
00178 }
00179
00180 QSize Blokkal::Ui::BlogDelegate::sizeHint( const QStyleOptionViewItem & option,
00181 const QModelIndex & index ) const
00182 {
00183 Blokkal::Account * account = dynamic_cast<Blokkal::Account*>( (QObject*) index.data().toULongLong() );
00184 if( account ) {
00185 QRect iconRect;
00186 QRect textRect;
00187 QRect countRect;
00188 layoutAccount( option, account, iconRect, textRect, countRect );
00189 return (iconRect|textRect|countRect).size();
00190 }
00191
00192 Blokkal::Blog * blog = dynamic_cast<Blokkal::Blog*>( (QObject*) index.data().toULongLong() );
00193 if( blog ) {
00194 QRect iconRect;
00195 QRect textRect;
00196 QRect infoRect;
00197 layoutBlog( option, index, blog, iconRect, textRect, infoRect );
00198 return ( iconRect|textRect|infoRect).size();
00199 }
00200
00201 Blokkal::Io::Category * category = dynamic_cast<Blokkal::Io::Category*>( (QObject*) index.data().toULongLong() );
00202 if( category ) {
00203 QRect textRect;
00204 layoutPlainItem( option, index, textRect );
00205 return textRect.size();
00206 }
00207
00208
00209 kWarning() << "encountered invalid data type" << endl;
00210 return QSize( 20,20 );
00211 }
00212
00213
00214 unsigned int Blokkal::Ui::BlogDelegate::displayOptions( void ) const
00215 {
00216 return d->displayOptions;
00217 }
00218
00219 QRect Blokkal::Ui::BlogDelegate::checkBoxRect( const QStyleOptionViewItem & option, const QModelIndex & index ) const
00220 {
00221 if( displayOptions() & DisplayCheckBoxes ) {
00222 Blokkal::Account * account = dynamic_cast<Blokkal::Account*>( (QObject*) index.data().toULongLong() );
00223 if( account ) {
00224 return QRect();
00225 }
00226 }
00227 else {
00228 return QRect();
00229 }
00230
00231 return CheckBoxDelegate::checkBoxRect( option, index );
00232 }
00233
00234 void Blokkal::Ui::BlogDelegate::layoutAccount( const QStyleOptionViewItem & option,
00235 const Blokkal::Account * account,
00236 QRect & iconRect,
00237 QRect & textRect,
00238 QRect & countRect ) const
00239 {
00240 QStyle * const style = QApplication::style();
00241 const int margin = style->pixelMetric( QStyle::PM_FocusFrameHMargin ) + 1;
00242 const int height = option.fontMetrics.height();
00243 const int width = option.rect.width();
00244 const int x = option.rect.x();
00245 const int y = option.rect.y();
00246
00247 if( displayOptions() & DisplayAccountIcon
00248 || displayOptions() & DisplayAccountStates )
00249 {
00250 if( option.direction == Qt::LeftToRight ) {
00251
00252 iconRect.setRect( x, y, height, height );
00253 }
00254 else {
00255 iconRect.setRect( x + width - height, y, height, height );
00256 }
00257 }
00258
00259 textRect.setRect( x, y, width, height );
00260 if( option.direction == Qt::LeftToRight ) {
00261 if( iconRect.isValid() ) {
00262 textRect.setLeft( iconRect.right() );
00263 }
00264 textRect.setWidth( option.fontMetrics.width( account->id() ) + 2*margin );
00265 }
00266 else {
00267 if( iconRect.isValid() ) {
00268 textRect.setRight( iconRect.left() );
00269 }
00270 textRect.setLeft( textRect.right() - option.fontMetrics.width( account->id() ) - 2*margin );
00271 }
00272
00273
00274 if( displayOptions() & DisplayBlogCount ) {
00275 const int countWidth = QFontMetrics( KGlobalSettings::smallestReadableFont() ).width( d->blogCount( account ) ) + 2*margin;
00276 if( option.direction == Qt::LeftToRight ) {
00277 int countX = x + width - countWidth;
00278 if( textRect.right() + countWidth < x + width ) {
00279 countX = textRect.right() ;
00280 }
00281 countRect.setRect( countX,
00282 y,
00283 countWidth,
00284 height );
00285 }
00286 else {
00287 int countX = x;
00288 if( textRect.left() - countWidth > x ) {
00289 countX = textRect.left() ;
00290 }
00291 countRect.setRect( countX, y, countWidth, height );
00292 }
00293 }
00294
00295 if( option.direction == Qt::LeftToRight ) {
00296 if( countRect.isValid() ) {
00297 textRect.setRight( countRect.left() );
00298 }
00299 else {
00300 textRect.setRight( x + width );
00301 }
00302 }
00303 else {
00304 if( countRect.isValid() ) {
00305 textRect.setLeft( countRect.right() );
00306 }
00307 else {
00308 textRect.setLeft( x );
00309 }
00310 }
00311 }
00312
00313 void Blokkal::Ui::BlogDelegate::layoutBlog( const QStyleOptionViewItem & option,
00314 const QModelIndex & index,
00315 const Blokkal::Blog * blog,
00316 QRect & iconRect,
00317 QRect & textRect,
00318 QRect & infoRect ) const
00319 {
00320 Q_UNUSED( blog );
00321
00322
00323 const int height = option.fontMetrics.height();
00324 const int width = option.rect.width();
00325 const int x = option.rect.x();
00326 const int y = option.rect.y();
00327
00328 QRect checkBoxRect;
00329
00330 if( displayOptions() & DisplayCheckBoxes ) {
00331 checkBoxRect = this->checkBoxRect( option, index );
00332 }
00333
00334
00335 if( displayOptions() & DisplayBlogIcon ) {
00336 const int iconHeight = height;
00337 if( option.direction == Qt::LeftToRight ) {
00338 if( checkBoxRect.isValid() ) {
00339 iconRect.setRect( checkBoxRect.right(), y, iconHeight, iconHeight );
00340 }
00341 else {
00342 iconRect.setRect( x, y, iconHeight, iconHeight );
00343 }
00344 }
00345 else {
00346 if( checkBoxRect.isValid() ) {
00347 iconRect.setRect( checkBoxRect.left() - iconHeight, y, iconHeight, iconHeight );
00348 }
00349 else {
00350 iconRect.setRect( x + width - iconHeight, y, iconHeight, iconHeight );
00351 }
00352 }
00353 }
00354
00355 textRect.setRect( x, y, width, height );
00356 if( option.direction == Qt::LeftToRight ) {
00357 if( iconRect.isValid() ) {
00358 textRect.setLeft( iconRect.right() );
00359 }
00360 else if( checkBoxRect.isValid() ) {
00361 textRect.setLeft( checkBoxRect.right() );
00362 }
00363
00364 }
00365 else {
00366 if( iconRect.isValid() ) {
00367 textRect.setRight( iconRect.left() );
00368 }
00369 else if( checkBoxRect.isValid() ) {
00370 textRect.setLeft( checkBoxRect.left() );
00371 }
00372
00373 }
00374
00375 if( displayOptions() & DisplayBlogDescription ) {
00376
00377
00378
00379
00380
00381
00382 if( checkBoxRect.isValid() ) {
00383 infoRect.setRect( checkBoxRect.right(),
00384 y + height,
00385 width,
00386 QFontMetrics( KGlobalSettings::smallestReadableFont() ).height() );
00387 }
00388 else {
00389 infoRect.setRect( x,
00390 y + height,
00391 width,
00392 QFontMetrics( KGlobalSettings::smallestReadableFont() ).height() );
00393 }
00394 }
00395 }