File indexing completed on 2024-10-06 04:25:58
0001 /* 0002 SPDX-FileCopyrightText: 2008 Sebastian Trueg <trueg@k3b.org> 0003 SPDX-FileCopyrightText: 2009-2010 Michal Malek <michalm@jabster.pl> 0004 SPDX-FileCopyrightText: 1998-2008 Sebastian Trueg <trueg@k3b.org> 0005 SPDX-License-Identifier: GPL-2.0-or-later 0006 */ 0007 0008 #include "k3bdevicedelegate.h" 0009 #include "k3bdevicemodel.h" 0010 0011 #include <KIconEffect> 0012 #include <KIconLoader> 0013 0014 #include <QPainter> 0015 #include <QApplication> 0016 #include <QStyle> 0017 0018 0019 // FIXME: Get the whole animated hovering code from KFileItemDelegate and put it into a generic class which we can then reuse here 0020 // To keep KFileItemDelegate BC it could simply forward calls to a subclass of the new generic delegate. 0021 0022 0023 // A lot of code is from KFileItemDelegate. Sadly this is all hidden in the private stuff 0024 namespace { 0025 QPixmap decoration( const QStyleOptionViewItem& option, const QModelIndex& index, const QSize& size ) 0026 { 0027 QIcon icon = qvariant_cast<QIcon>( index.data( Qt::DecorationRole ) ); 0028 QPixmap pixmap = icon.pixmap( size ); 0029 if (!pixmap.isNull()) 0030 { 0031 // If the item is selected, and the selection rectangle only covers the 0032 // text label, blend the pixmap with the highlight color. 0033 if (!option.showDecorationSelected && option.state & QStyle::State_Selected) 0034 { 0035 QPainter p(&pixmap); 0036 QColor color = option.palette.color(QPalette::Highlight); 0037 color.setAlphaF(0.5); 0038 p.setCompositionMode(QPainter::CompositionMode_SourceAtop); 0039 p.fillRect(pixmap.rect(), color); 0040 } 0041 0042 if ( option.state & QStyle::State_MouseOver ) { 0043 KIconEffect *effect = KIconLoader::global()->iconEffect(); 0044 0045 // Note that in KIconLoader terminology, active = hover. 0046 // ### We're assuming that the icon group is desktop/filemanager, since this 0047 // is KFileItemDelegate. 0048 if (effect->hasEffect(KIconLoader::Desktop, KIconLoader::ActiveState)) 0049 return effect->apply(pixmap, KIconLoader::Desktop, KIconLoader::ActiveState); 0050 } 0051 } 0052 0053 return pixmap; 0054 } 0055 0056 QFont cloneFont( const QFont& font, int pointSize, bool bold, bool italic ) 0057 { 0058 QFont cloned( font ); 0059 cloned.setPointSize( pointSize ); 0060 cloned.setBold( bold ); 0061 cloned.setItalic( italic ); 0062 return cloned; 0063 } 0064 0065 struct FontsAndMetrics 0066 { 0067 FontsAndMetrics( const QFont& font ); 0068 0069 QFont mediumFont; 0070 QFont deviceFont; 0071 QFontMetrics fontM; 0072 QFontMetrics mediumFontM; 0073 QFontMetrics deviceFontM; 0074 int margin; 0075 int spacing; 0076 }; 0077 0078 FontsAndMetrics::FontsAndMetrics( const QFont& font ) 0079 : 0080 mediumFont( cloneFont( font, font.pointSize()+2, true, false ) ), 0081 deviceFont( cloneFont( font, font.pointSize()-2, false, true ) ), 0082 fontM( font ), 0083 mediumFontM( mediumFont ), 0084 deviceFontM( deviceFont ), 0085 margin( fontM.descent() ), 0086 spacing( 0 ) 0087 { 0088 } 0089 0090 } // namespace 0091 0092 0093 K3b::DeviceDelegate::DeviceDelegate( QObject* parent ) 0094 : KFileItemDelegate( parent ) 0095 { 0096 } 0097 0098 0099 K3b::DeviceDelegate::~DeviceDelegate() 0100 { 0101 } 0102 0103 0104 QSize K3b::DeviceDelegate::sizeHint( const QStyleOptionViewItem& option, const QModelIndex& index ) const 0105 { 0106 if ( index.data( K3b::DeviceModel::IsDevice ).toBool() ) { 0107 const FontsAndMetrics fam( option.font ); 0108 // It seems that width-part of size hint is not used anyway so 0109 // we're omitting here a computation of text's width 0110 return QSize( 0, fam.margin + fam.mediumFontM.height() + fam.spacing + fam.deviceFontM.height() + fam.margin ); 0111 } 0112 else { 0113 return KFileItemDelegate::sizeHint( option, index ); 0114 } 0115 } 0116 0117 0118 void K3b::DeviceDelegate::paint( QPainter* painter, const QStyleOptionViewItem& optionOrig, const QModelIndex& index ) const 0119 { 0120 if ( index.data( K3b::DeviceModel::IsDevice ).toBool() ) { 0121 painter->save(); 0122 painter->setRenderHint(QPainter::Antialiasing); 0123 0124 // HACK: we erase the branch 0125 QStyleOptionViewItem option( optionOrig ); 0126 option.rect.setLeft( 0 ); 0127 painter->fillRect( option.rect, option.palette.base() ); 0128 0129 QStyle* style = QApplication::style(); 0130 const FontsAndMetrics fam( option.font ); 0131 const QPalette::ColorRole textRole = (option.state & QStyle::State_Selected) ? 0132 QPalette::HighlightedText : QPalette::Text; 0133 0134 const QRect itemRect( option.rect.left() + fam.margin, option.rect.top() + fam.margin, 0135 option.rect.width() - 2*fam.margin, option.rect.height() - 2*fam.margin ); 0136 const QSize iconSize( itemRect.height(), itemRect.height() ); 0137 const QSize mediumSize( itemRect.width() - iconSize.width() - fam.margin, 0138 itemRect.height() - fam.spacing - fam.deviceFontM.height() ); 0139 const QSize devicemSize( itemRect.width() - iconSize.width() - fam.margin, 0140 itemRect.height() - fam.spacing - fam.mediumFontM.height() ); 0141 const QRect iconRect = style->alignedRect( option.direction, Qt::AlignLeft | Qt::AlignVCenter, iconSize, itemRect ); 0142 const QRect mediumRect = style->alignedRect( option.direction, Qt::AlignRight | Qt::AlignTop, mediumSize, itemRect ); 0143 const QRect deviceRect = style->alignedRect( option.direction, Qt::AlignRight | Qt::AlignBottom, devicemSize, itemRect ); 0144 0145 // draw background 0146 style->drawPrimitive( QStyle::PE_PanelItemViewItem, &option, painter ); 0147 0148 // draw decoration 0149 QPixmap pixmap = decoration( option, index, iconSize ); 0150 painter->drawPixmap( iconRect, pixmap ); 0151 0152 // draw medium text 0153 painter->setFont( fam.mediumFont ); 0154 QString text = index.data( Qt::DisplayRole ).toString(); 0155 style->drawItemText( painter, mediumRect, option.displayAlignment, option.palette, 0156 option.state & QStyle::State_Enabled, 0157 fam.mediumFontM.elidedText( text, option.textElideMode, mediumRect.width() ), 0158 textRole ); 0159 0160 // draw fixed device text 0161 painter->setFont( fam.deviceFont ); 0162 text = index.data( K3b::DeviceModel::Vendor ).toString() + " - " + index.data( K3b::DeviceModel::Description ).toString(); 0163 style->drawItemText( painter, deviceRect, option.displayAlignment, option.palette, 0164 option.state & QStyle::State_Enabled, 0165 fam.deviceFontM.elidedText( text, option.textElideMode, deviceRect.width() ), 0166 textRole ); 0167 0168 painter->restore(); 0169 } 0170 else { 0171 KFileItemDelegate::paint( painter, optionOrig, index ); 0172 } 0173 } 0174 0175 #include "moc_k3bdevicedelegate.cpp"