libyui-qt
2.43.5
|
00001 /* 00002 Copyright (C) 2000-2012 Novell, Inc 00003 This library is free software; you can redistribute it and/or modify 00004 it under the terms of the GNU Lesser General Public License as 00005 published by the Free Software Foundation; either version 2.1 of the 00006 License, or (at your option) version 3.0 of the License. This library 00007 is distributed in the hope that it will be useful, but WITHOUT ANY 00008 WARRANTY; without even the implied warranty of MERCHANTABILITY or 00009 FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public 00010 License for more details. You should have received a copy of the GNU 00011 Lesser General Public License along with this library; if not, write 00012 to the Free Software Foundation, Inc., 51 Franklin Street, Fifth 00013 Floor, Boston, MA 02110-1301 USA 00014 */ 00015 00016 00017 /*-/ 00018 00019 File: QY2DiskUsageList.cc 00020 00021 Author: Stefan Hundhammer <sh@suse.de> 00022 00023 Textdomain "qt" 00024 00025 This is a pure Qt widget - it can be used independently of YaST2. 00026 00027 00028 /-*/ 00029 00030 #include "QY2DiskUsageList.h" 00031 #include "YQi18n.h" 00032 #include <QPainter> 00033 #include <QItemDelegate> 00034 #include <QDebug> 00035 00036 #ifdef TEXTDOMAIN 00037 # undef TEXTDOMAIN 00038 #endif 00039 00040 #define TEXTDOMAIN "qt" 00041 00042 00043 00044 /** 00045 * Stolen from KDirStat::KDirTreeView with the author's permission. 00046 **/ 00047 QColor 00048 contrastingColor( const QColor & desiredColor, 00049 const QColor & contrastColor ) 00050 { 00051 if ( desiredColor != contrastColor ) 00052 { 00053 return desiredColor; 00054 } 00055 00056 if ( contrastColor != contrastColor.light() ) 00057 { 00058 // try a little lighter 00059 return contrastColor.light(); 00060 } 00061 else 00062 { 00063 // try a little darker 00064 return contrastColor.dark(); 00065 } 00066 } 00067 00068 /** 00069 * Interpolate ( translate ) a value 'from' in the range between 'minFrom' 00070 * and 'maxFrom' to a range between 'minTo' and 'maxTo'. 00071 **/ 00072 static int 00073 interpolate( int from, 00074 int minFrom, int maxFrom, 00075 int minTo, int maxTo ) 00076 { 00077 if ( minFrom > maxFrom ) 00078 { 00079 // Swap min/max values 00080 00081 int tmp = maxFrom; 00082 maxFrom = minFrom; 00083 minFrom = tmp; 00084 } 00085 00086 long x = from - minFrom; 00087 x *= maxTo - minTo; 00088 x /= maxFrom - minFrom; 00089 x += minTo; 00090 00091 if ( minTo < maxTo ) 00092 { 00093 if ( x < minTo ) x = minTo; 00094 if ( x > maxTo ) x = maxTo; 00095 } 00096 else 00097 { 00098 if ( x < maxTo ) x = maxTo; 00099 if ( x > minTo ) x = minTo; 00100 } 00101 00102 return (int) x; 00103 } 00104 00105 /** 00106 * Interpolate ( in the HSV color space ) a color between 'minColor' and 00107 * 'maxColor' for a current value 'val' so that 'minVal' corresponds to 00108 * 'minColor' and 'maxVal' to 'maxColor'. 00109 * 00110 * Returns the interpolated color. 00111 **/ 00112 static QColor 00113 interpolateColor( int val, 00114 int minVal, 00115 int maxVal, 00116 const QColor & minColor, 00117 const QColor & maxColor ) 00118 { 00119 int minH, maxH; 00120 int minS, maxS; 00121 int minV, maxV; 00122 00123 minColor.getHsv( &minH, &minS, &minV ); 00124 maxColor.getHsv( &maxH, &maxS, &maxV ); 00125 00126 return QColor::fromHsv( interpolate( val, minVal, maxVal, minH, maxH ), 00127 interpolate( val, minVal, maxVal, minS, maxS ), 00128 interpolate( val, minVal, maxVal, minV, maxV ) ); 00129 } 00130 00131 00132 class QY2DiskUsagePercentageItem : public QItemDelegate 00133 { 00134 QY2DiskUsageList *_view; 00135 00136 public: 00137 QY2DiskUsagePercentageItem( QY2DiskUsageList *parent ) : QItemDelegate( parent ), _view( parent ) { 00138 } 00139 00140 virtual void paint ( QPainter * painter, const QStyleOptionViewItem & option, const QModelIndex & index ) const 00141 { 00142 painter->save(); 00143 QColor background = option.palette.color(QPalette::Window); 00144 painter->setBackground( background ); 00145 00146 QY2DiskUsageListItem *item = dynamic_cast<QY2DiskUsageListItem *>(_view->itemFromIndex(index)); 00147 if ( item ) 00148 { 00149 item->paintPercentageBar( painter, 00150 option, 00151 interpolateColor( item->usedPercent(), 00152 60, 95, 00153 QColor( 0, 0xa0, 0 ), // Medium dark green 00154 QColor( 0xFF, 0, 0 ) ) ); // Bright red 00155 } 00156 painter->restore(); 00157 } 00158 }; 00159 00160 QY2DiskUsageList::QY2DiskUsageList( QWidget * parent, bool addStdColumns ) 00161 : QY2ListView( parent ) 00162 { 00163 _nameCol = -42; 00164 _percentageBarCol = -42; 00165 _usedSizeCol = -42; 00166 _freeSizeCol = -42; 00167 _totalSizeCol = -42; 00168 _deviceNameCol = -42; 00169 00170 // set temporary textdomain to enable translations 00171 // in inherit classed (e.g. YQPkgDiskUsageList) 00172 // see bnc #445716 00173 QString savedtextdomain = textdomain(NULL); 00174 textdomain(TEXTDOMAIN); 00175 00176 QStringList columnLabels; 00177 if ( addStdColumns ) 00178 { 00179 int numCol = 0; 00180 columnLabels << _( "Name" ); _nameCol = numCol++; 00181 // Translators: Please keep this short! 00182 columnLabels << _("Disk Usage"); _percentageBarCol = numCol++; 00183 setItemDelegateForColumn( _percentageBarCol, new QY2DiskUsagePercentageItem( this ) ); 00184 //columnLabels << _("Used"); _usedSizeCol = numCol++; 00185 columnLabels << _( "Free"); _freeSizeCol = numCol++; 00186 columnLabels << _("Total"); _totalSizeCol = numCol++; 00187 #if 0 00188 addColumn( _( "Device" ) ); _deviceNameCol = numCol++; 00189 #endif 00190 // needed? 00191 setColumnCount(numCol); 00192 setHeaderLabels(columnLabels); 00193 00194 sortItems( percentageBarCol(), Qt::AscendingOrder ); 00195 setSizePolicy( QSizePolicy::Minimum, QSizePolicy::Minimum ); 00196 } 00197 00198 textdomain(savedtextdomain.toAscii()); 00199 00200 saveColumnWidths(); 00201 setSelectionMode(QAbstractItemView::NoSelection); 00202 } 00203 00204 00205 QY2DiskUsageList::~QY2DiskUsageList() 00206 { 00207 } 00208 00209 00210 void QY2DiskUsageList::drawRow( QPainter * painter, const QStyleOptionViewItem & option, const QModelIndex & index ) const 00211 { 00212 // Intentionally bypassing the direct parent class method, use the grandparent's: 00213 // Don't let QY2ListViewItem::_textColor / _backgroundColor interfere with our colors. 00214 00215 QTreeWidget::drawRow( painter, option, index ); 00216 } 00217 00218 00219 QY2DiskUsageListItem::QY2DiskUsageListItem( QY2DiskUsageList * parent ) 00220 : QY2ListViewItem( parent ) 00221 , _diskUsageList( parent ) 00222 { 00223 } 00224 00225 00226 00227 00228 QY2DiskUsageListItem::~QY2DiskUsageListItem() 00229 { 00230 // NOP 00231 } 00232 00233 00234 00235 00236 void 00237 QY2DiskUsageListItem::init( bool allFields ) 00238 { 00239 setSizeHint( percentageBarCol(), QSize( 20, 10 ) ); 00240 00241 setTextAlignment( usedSizeCol(), Qt::AlignRight ); 00242 setTextAlignment( freeSizeCol(), Qt::AlignRight ); 00243 setTextAlignment( totalSizeCol(), Qt::AlignRight ); 00244 00245 if ( usedSizeCol() >= 0 ) setText( usedSizeCol(), usedSize() ); 00246 if ( freeSizeCol() >= 0 ) setText( freeSizeCol(), freeSize() ); 00247 00248 if ( allFields ) 00249 { 00250 if ( totalSizeCol() >= 0 ) setText( totalSizeCol(), totalSize() ); 00251 if ( nameCol() >= 0 ) setText( nameCol(), name() ); 00252 if ( deviceNameCol() >= 0 ) setText( deviceNameCol(), deviceName() ); 00253 } 00254 00255 if ( usedSizeCol() < 0 ) 00256 setToolTip( freeSizeCol(), _( "Used %1" ).arg( usedSize().form( 0, 1, true ).c_str() ) ); 00257 } 00258 00259 00260 void 00261 QY2DiskUsageListItem::setText( int column, const FSize & size ) 00262 { 00263 QString sizeText = size.form( 0, 1, true ).c_str(); 00264 setText( column, sizeText ); 00265 } 00266 00267 00268 FSize 00269 QY2DiskUsageListItem::freeSize() const 00270 { 00271 return totalSize() - usedSize(); 00272 } 00273 00274 00275 int 00276 QY2DiskUsageListItem::usedPercent() const 00277 { 00278 int percent = 0; 00279 00280 if ( totalSize() != 0 ) 00281 percent = ( 100 * usedSize() ) / totalSize(); 00282 00283 return percent; 00284 } 00285 00286 00287 void 00288 QY2DiskUsageListItem::updateStatus() 00289 { 00290 init( false ); 00291 } 00292 00293 00294 void 00295 QY2DiskUsageListItem::updateData() 00296 { 00297 init( true ); 00298 } 00299 00300 00301 00302 00303 00304 /** 00305 * Comparison function used for sorting the list. 00306 * Reimplemented from QTreeWidgetItem 00307 **/ 00308 bool 00309 QY2DiskUsageListItem::operator<( const QTreeWidgetItem & otherListViewItem ) const 00310 { 00311 const QY2DiskUsageListItem * other = dynamic_cast<const QY2DiskUsageListItem *> (&otherListViewItem); 00312 int col = treeWidget()->sortColumn(); 00313 00314 if ( other ) 00315 { 00316 if ( col == percentageBarCol() ) 00317 { 00318 // Intentionally reverting sort order: Fullest first 00319 return ( this->usedPercent() < other->usedPercent() ); 00320 } 00321 else if ( col == usedSizeCol() ) 00322 { 00323 return ( this->usedSize() < other->usedSize() ); 00324 } 00325 else if ( col == freeSizeCol() ) 00326 { 00327 return ( this->freeSize() < other->freeSize() ); 00328 } 00329 else if ( col == totalSizeCol() ) 00330 { 00331 return ( this->totalSize() < other->totalSize() ); 00332 } 00333 } 00334 00335 return QY2ListViewItem::operator<( otherListViewItem ); 00336 } 00337 00338 /** 00339 * Stolen from KDirStat::KDirTreeView with the author's permission. 00340 **/ 00341 void 00342 QY2DiskUsageListItem::paintPercentageBar( QPainter * painter, 00343 QStyleOptionViewItem option, 00344 const QColor & fillColor ) 00345 { 00346 float percent = usedPercent(); 00347 if ( percent > 100.0 ) percent = 100.0; 00348 if ( percent < 0.0 ) percent = 0.0; 00349 int x = option.rect.left() + 1; 00350 int y = option.rect.top() + 1; 00351 int w = option.rect.width() - 2; 00352 int h = option.rect.height() - 2; 00353 int fillWidth = 0; 00354 00355 if ( w > 0 ) 00356 { 00357 fillWidth = (int) ( w * percent / 100.0 ); 00358 00359 // Fill the desired percentage. 00360 00361 painter->fillRect( x, y, fillWidth, h, 00362 fillColor ); 00363 00364 QString percentageText; 00365 percentageText.sprintf( "%d%%", usedPercent() ); 00366 00367 if ( usedPercent() > 50 ) { 00368 painter->setPen( treeWidget()->palette().color( QPalette::Base ) ); 00369 painter->drawText( QRect( x, y, 00370 fillWidth - 3, h ), 00371 Qt::AlignRight, percentageText ); 00372 } else { 00373 painter->setPen( treeWidget()->palette().color( QPalette::Text ) ); 00374 painter->drawText( QRect( x + fillWidth + 3, y, 00375 w - fillWidth - 3, h ), 00376 Qt::AlignLeft, percentageText ); 00377 00378 } 00379 } 00380 } 00381 00382 #include "QY2DiskUsageList.moc"