1 /*---------------------------------------------------------------------\
3 | __ __ ____ _____ ____ |
4 | \ \ / /_ _/ ___|_ _|___ \ |
5 | \ V / _` \___ \ | | __) | |
6 | | | (_| |___) || | / __/ |
7 | |_|\__,_|____/ |_| |_____| |
11 \----------------------------------------------------------------------/
13 File: QY2DiskUsageList.cc
15 Author: Stefan Hundhammer <sh@suse.de>
17 Textdomain "packages-qt"
19 This is a pure Qt widget - it can be used independently of YaST2.
24 #include "QY2DiskUsageList.h"
27 #include <QItemDelegate>
31 * Stolen from KDirStat::KDirTreeView with the author's permission.
34 contrastingColor( const QColor & desiredColor,
35 const QColor & contrastColor )
37 if ( desiredColor != contrastColor )
42 if ( contrastColor != contrastColor.light() )
44 // try a little lighter
45 return contrastColor.light();
49 // try a little darker
50 return contrastColor.dark();
55 * Interpolate ( translate ) a value 'from' in the range between 'minFrom'
56 * and 'maxFrom' to a range between 'minTo' and 'maxTo'.
59 interpolate( int from,
60 int minFrom, int maxFrom,
61 int minTo, int maxTo )
63 if ( minFrom > maxFrom )
65 // Swap min/max values
72 long x = from - minFrom;
74 x /= maxFrom - minFrom;
79 if ( x < minTo ) x = minTo;
80 if ( x > maxTo ) x = maxTo;
84 if ( x < maxTo ) x = maxTo;
85 if ( x > minTo ) x = minTo;
92 * Interpolate ( in the HSV color space ) a color between 'minColor' and
93 * 'maxColor' for a current value 'val' so that 'minVal' corresponds to
94 * 'minColor' and 'maxVal' to 'maxColor'.
96 * Returns the interpolated color.
99 interpolateColor( int val,
102 const QColor & minColor,
103 const QColor & maxColor )
109 minColor.getHsv( &minH, &minS, &minV );
110 maxColor.getHsv( &maxH, &maxS, &maxV );
112 return QColor::fromHsv( interpolate( val, minVal, maxVal, minH, maxH ),
113 interpolate( val, minVal, maxVal, minS, maxS ),
114 interpolate( val, minVal, maxVal, minV, maxV ) );
118 class QY2DiskUsagePercentageItem : public QItemDelegate
120 QY2DiskUsageList *_view;
123 QY2DiskUsagePercentageItem( QY2DiskUsageList *parent ) : QItemDelegate( parent ), _view( parent ) {
126 virtual void paint ( QPainter * painter, const QStyleOptionViewItem & option, const QModelIndex & index ) const
129 QColor background = option.palette.color(QPalette::Window);
130 painter->setBackground( background );
132 QY2DiskUsageListItem *item = dynamic_cast<QY2DiskUsageListItem *>(_view->itemFromIndex(index));
135 item->paintPercentageBar( item->usedPercent(),
138 interpolateColor( item->usedPercent(),
140 QColor( 0, 0x80, 0 ), // Medium dark green
141 QColor( 0xFF, 0, 0 ) ), // Bright red
142 background.dark( 115 ) );
148 QY2DiskUsageList::QY2DiskUsageList( QWidget * parent, bool addStdColumns )
149 : QY2ListView( parent )
152 _percentageBarCol = -42;
153 _percentageCol = -42;
157 _deviceNameCol = -42;
159 QStringList columnLabels;
163 columnLabels << _( "Name" ); _nameCol = numCol++;
164 // Translators: Please keep this short!
165 columnLabels << _("Disk Usage"); _percentageBarCol = numCol++;
166 columnLabels << ""; _percentageCol = numCol++;
167 setItemDelegateForColumn( _percentageBarCol, new QY2DiskUsagePercentageItem( this ) );
168 columnLabels << _("Used"); _usedSizeCol = numCol++;
169 columnLabels << _( "Free"); _freeSizeCol = numCol++;
170 columnLabels << _("Total"); _totalSizeCol = numCol++;
172 addColumn( _( "Device" ) ); _deviceNameCol = numCol++;
175 setColumnCount(numCol);
176 setHeaderLabels(columnLabels);
179 // setTextAlignment( percentageCol(), Qt::AlignRight );
180 // setTextAlignment( usedSizeCol(), Qt::AlignRight );
181 // setTextAlignment( freeSizeCol(), Qt::AlignRight );
182 // setTextAlignment( totalSizeCol(), Qt::AlignRight );
183 sortItems( percentageBarCol(), Qt::AscendingOrder );
187 setSelectionMode(QAbstractItemView::NoSelection);
191 QY2DiskUsageList::~QY2DiskUsageList()
196 void QY2DiskUsageList::drawRow( QPainter * painter, const QStyleOptionViewItem & option, const QModelIndex & index ) const
198 // Intentionally bypassing the direct parent class method, use the grandparent's:
199 // Don't let QY2ListViewItem::_textColor / _backgroundColor interfere with our colors.
201 QTreeWidget::drawRow( painter, option, index );
205 QY2DiskUsageListItem::QY2DiskUsageListItem( QY2DiskUsageList * parent )
206 : QY2ListViewItem( parent )
207 , _diskUsageList( parent )
214 QY2DiskUsageListItem::~QY2DiskUsageListItem()
223 QY2DiskUsageListItem::init( bool allFields )
225 if ( percentageCol() >= 0 )
227 QString percentageText;
228 percentageText.sprintf( "%d%%", usedPercent() );
229 setText( percentageCol(), percentageText );
232 if ( usedSizeCol() >= 0 ) setText( usedSizeCol(), usedSize() );
233 if ( freeSizeCol() >= 0 ) setText( freeSizeCol(), freeSize() );
237 if ( totalSizeCol() >= 0 ) setText( totalSizeCol(), totalSize() );
238 if ( nameCol() >= 0 ) setText( nameCol(), " " + name() );
239 if ( deviceNameCol() >= 0 ) setText( deviceNameCol(), deviceName() );
245 QY2DiskUsageListItem::setText( int column, const FSize & size )
247 QString sizeText = size.form( 0, 1, true ).c_str();
249 setText( column, sizeText );
254 QY2DiskUsageListItem::freeSize() const
256 return totalSize() - usedSize();
261 QY2DiskUsageListItem::usedPercent() const
265 if ( totalSize() != 0 )
266 percent = ( 100 * usedSize() ) / totalSize();
273 QY2DiskUsageListItem::updateStatus()
280 QY2DiskUsageListItem::updateData()
290 * Comparison function used for sorting the list.
297 QY2DiskUsageListItem::compare( QTreeWidgetItem * otherListViewItem,
299 bool ascending ) const
301 QY2DiskUsageListItem * other = dynamic_cast<QY2DiskUsageListItem *> (otherListViewItem);
305 if ( col == percentageCol() ||
306 col == percentageBarCol() )
308 // Intentionally reverting sort order: Fullest first
310 if ( this->usedPercent() < other->usedPercent() ) return 1;
311 if ( this->usedPercent() > other->usedPercent() ) return -1;
314 else if ( col == usedSizeCol() )
316 if ( this->usedSize() < other->usedSize() ) return -1;
317 if ( this->usedSize() > other->usedSize() ) return 1;
320 else if ( col == freeSizeCol() )
322 if ( this->freeSize() < other->freeSize() ) return -1;
323 if ( this->freeSize() > other->freeSize() ) return 1;
326 else if ( col == totalSizeCol() )
328 if ( this->totalSize() < other->totalSize() ) return -1;
329 if ( this->totalSize() > other->totalSize() ) return 1;
334 return QY2ListViewItem::compare( otherListViewItem, col, ascending );
338 * Stolen from KDirStat::KDirTreeView with the author's permission.
341 QY2DiskUsageListItem::paintPercentageBar( float percent,
343 QStyleOptionViewItem option,
344 const QColor & fillColor,
345 const QColor & barBackground )
347 if ( percent > 100.0 ) percent = 100.0;
348 if ( percent < 0.0 ) percent = 0.0;
351 int x = option.rect.left(); /*FIXME _diskUsageList->itemMargin(); */
352 int y = option.rect.top() + extraMargin;
353 int w = option.rect.width() - 2; /*FIXME * _diskUsageList->horizontalOffset(); */
354 int h = option.rect.height() - 2; /*FIXME * extraMargin; */
357 painter->eraseRect( option.rect );
364 QPen pen( painter->pen() );
366 painter->setPen( pen );
367 painter->setBrush( Qt::NoBrush );
368 fillWidth = (int) ( ( w - 2 * penWidth ) * percent / 100.0 );
371 // Fill bar background.
373 painter->fillRect( x + penWidth, y + penWidth,
374 w - 2 * penWidth + 1, h - 2 * penWidth + 1,
377 * Notice: The Xlib XDrawRectangle() function always fills one
378 * pixel less than specified. Altough this is very likely just a
379 * plain old bug, it is documented that way. Obviously, Qt just
380 * maps the fillRect() call directly to XDrawRectangle() so they
381 * inherited that bug ( although the Qt doc stays silent about
382 * it ). So it is really necessary to compensate for that missing
383 * pixel in each dimension.
385 * If you don't believe it, see for yourself.
386 * Hint: Try the xmag program to zoom into the drawn pixels.
389 // Fill the desired percentage.
391 painter->fillRect( x + penWidth, y + penWidth,
392 fillWidth+1, h - 2 * penWidth+1,
398 pen.setColor( contrastingColor ( Qt::black,
399 painter->background().color() ) );
400 painter->setPen( pen );
401 painter->drawLine( x, y, x+w, y );
402 painter->drawLine( x, y, x, y+h );
404 pen.setColor( contrastingColor( barBackground.dark(),
405 painter->background().color() ) );
406 painter->setPen( pen );
407 painter->drawLine( x+1, y+1, x+w-1, y+1 );
408 painter->drawLine( x+1, y+1, x+1, y+h-1 );
410 pen.setColor( contrastingColor( barBackground.light(),
411 painter->background().color() ) );
412 painter->setPen( pen );
413 painter->drawLine( x+1, y+h, x+w, y+h );
414 painter->drawLine( x+w, y, x+w, y+h );
416 pen.setColor( contrastingColor( Qt::white,
417 painter->background().color() ) );
418 painter->setPen( pen );
419 painter->drawLine( x+2, y+h-1, x+w-1, y+h-1 );
420 painter->drawLine( x+w-1, y+1, x+w-1, y+h-1 );
428 #include "QY2DiskUsageList.moc"