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"
30 * Stolen from KDirStat::KDirTreeView with the author's permission.
33 contrastingColor( const QColor & desiredColor,
34 const QColor & contrastColor )
36 if ( desiredColor != contrastColor )
41 if ( contrastColor != contrastColor.light() )
43 // try a little lighter
44 return contrastColor.light();
48 // try a little darker
49 return contrastColor.dark();
54 * Interpolate ( translate ) a value 'from' in the range between 'minFrom'
55 * and 'maxFrom' to a range between 'minTo' and 'maxTo'.
58 interpolate( int from,
59 int minFrom, int maxFrom,
60 int minTo, int maxTo )
62 if ( minFrom > maxFrom )
64 // Swap min/max values
71 long x = from - minFrom;
73 x /= maxFrom - minFrom;
78 if ( x < minTo ) x = minTo;
79 if ( x > maxTo ) x = maxTo;
83 if ( x < maxTo ) x = maxTo;
84 if ( x > minTo ) x = minTo;
91 * Interpolate ( in the HSV color space ) a color between 'minColor' and
92 * 'maxColor' for a current value 'val' so that 'minVal' corresponds to
93 * 'minColor' and 'maxVal' to 'maxColor'.
95 * Returns the interpolated color.
98 interpolateColor( int val,
101 const QColor & minColor,
102 const QColor & maxColor )
108 minColor.getHsv( &minH, &minS, &minV );
109 maxColor.getHsv( &maxH, &maxS, &maxV );
111 return QColor::fromHsv( interpolate( val, minVal, maxVal, minH, maxH ),
112 interpolate( val, minVal, maxVal, minS, maxS ),
113 interpolate( val, minVal, maxVal, minV, maxV ) );
117 QY2DiskUsageList::QY2DiskUsageList( QWidget * parent, bool addStdColumns )
118 : QY2ListView( parent )
121 _percentageBarCol = -42;
122 _percentageCol = -42;
126 _deviceNameCol = -42;
128 QStringList columnLabels;
132 columnLabels << _( "Name" ); _nameCol = numCol++;
133 // Translators: Please keep this short!
134 columnLabels << _("Disk Usage"); _percentageBarCol = numCol++;
135 columnLabels << ""; _percentageCol = numCol++;
136 columnLabels << _("Used"); _usedSizeCol = numCol++;
137 columnLabels << _( "Free"); _freeSizeCol = numCol++;
138 columnLabels << _("Total"); _totalSizeCol = numCol++;
140 addColumn( _( "Device" ) ); _deviceNameCol = numCol++;
143 setColumnCount(numCol);
144 setHeaderLabels(columnLabels);
147 // setTextAlignment( percentageCol(), Qt::AlignRight );
148 // setTextAlignment( usedSizeCol(), Qt::AlignRight );
149 // setTextAlignment( freeSizeCol(), Qt::AlignRight );
150 // setTextAlignment( totalSizeCol(), Qt::AlignRight );
151 sortItems( percentageBarCol(), Qt::AscendingOrder );
155 setSelectionMode(QAbstractItemView::NoSelection);
159 QY2DiskUsageList::~QY2DiskUsageList()
164 void QY2DiskUsageList::drawRow( QPainter * painter, const QStyleOptionViewItem & option, const QModelIndex & index ) const
166 if ( index.column() == percentageBarCol() )
168 QColor background = option.palette.color(QPalette::Base);
169 painter->setBackground( background );
171 QY2DiskUsageListItem *item = dynamic_cast<QY2DiskUsageListItem *>(itemFromIndex(index));
174 item->paintPercentageBar( item->usedPercent(),
177 interpolateColor( item->usedPercent(),
179 QColor( 0, 0x80, 0 ), // Medium dark green
180 QColor( 0xFF, 0, 0 ) ), // Bright red
181 background.dark( 115 ) );
186 //QColorGroup cg( colorGroup );
188 //if ( usedSize() > totalSize() )
189 // cg.setColor( QColorGroup::Text, Qt::red ); // Set red text foreground
191 // Intentionally bypassing the direct parent class method, use the grandparent's:
192 // Don't let QY2ListViewItem::_textColor / _backgroundColor interfere with our colors.
194 QTreeWidget::drawRow( painter, option, index );
200 QY2DiskUsageListItem::QY2DiskUsageListItem( QY2DiskUsageList * parent )
201 : QY2ListViewItem( parent )
202 , _diskUsageList( parent )
209 QY2DiskUsageListItem::~QY2DiskUsageListItem()
218 QY2DiskUsageListItem::init( bool allFields )
220 if ( percentageCol() >= 0 )
222 QString percentageText;
223 percentageText.sprintf( "%d%%", usedPercent() );
224 setText( percentageCol(), percentageText );
227 if ( usedSizeCol() >= 0 ) setText( usedSizeCol(), usedSize() );
228 if ( freeSizeCol() >= 0 ) setText( freeSizeCol(), freeSize() );
232 if ( totalSizeCol() >= 0 ) setText( totalSizeCol(), totalSize() );
233 if ( nameCol() >= 0 ) setText( nameCol(), " " + name() );
234 if ( deviceNameCol() >= 0 ) setText( deviceNameCol(), deviceName() );
240 QY2DiskUsageListItem::setText( int column, const FSize & size )
242 QString sizeText = size.form( 0, 1, true ).c_str();
244 setText( column, sizeText );
249 QY2DiskUsageListItem::freeSize() const
251 return totalSize() - usedSize();
256 QY2DiskUsageListItem::usedPercent() const
260 if ( totalSize() != 0 )
261 percent = ( 100 * usedSize() ) / totalSize();
268 QY2DiskUsageListItem::updateStatus()
275 QY2DiskUsageListItem::updateData()
285 * Comparison function used for sorting the list.
292 QY2DiskUsageListItem::compare( QTreeWidgetItem * otherListViewItem,
294 bool ascending ) const
296 QY2DiskUsageListItem * other = dynamic_cast<QY2DiskUsageListItem *> (otherListViewItem);
300 if ( col == percentageCol() ||
301 col == percentageBarCol() )
303 // Intentionally reverting sort order: Fullest first
305 if ( this->usedPercent() < other->usedPercent() ) return 1;
306 if ( this->usedPercent() > other->usedPercent() ) return -1;
309 else if ( col == usedSizeCol() )
311 if ( this->usedSize() < other->usedSize() ) return -1;
312 if ( this->usedSize() > other->usedSize() ) return 1;
315 else if ( col == freeSizeCol() )
317 if ( this->freeSize() < other->freeSize() ) return -1;
318 if ( this->freeSize() > other->freeSize() ) return 1;
321 else if ( col == totalSizeCol() )
323 if ( this->totalSize() < other->totalSize() ) return -1;
324 if ( this->totalSize() > other->totalSize() ) return 1;
329 return QY2ListViewItem::compare( otherListViewItem, col, ascending );
333 * Stolen from KDirStat::KDirTreeView with the author's permission.
336 QY2DiskUsageListItem::paintPercentageBar( float percent,
338 QStyleOptionViewItem option,
339 const QColor & fillColor,
340 const QColor & barBackground )
342 if ( percent > 100.0 ) percent = 100.0;
343 if ( percent < 0.0 ) percent = 0.0;
346 int x = 0; /*FIXME _diskUsageList->itemMargin(); */
348 int w = option.rect.width() - 2; /*FIXME * _diskUsageList->horizontalOffset(); */
349 int h = option.rect.height() - 2; /*FIXME * extraMargin; */
352 painter->eraseRect( 0, 0, option.rect.width(), option.rect.height() );
359 QPen pen( painter->pen() );
361 painter->setPen( pen );
362 painter->setBrush( Qt::NoBrush );
363 fillWidth = (int) ( ( w - 2 * penWidth ) * percent / 100.0 );
366 // Fill bar background.
368 painter->fillRect( x + penWidth, y + penWidth,
369 w - 2 * penWidth + 1, h - 2 * penWidth + 1,
372 * Notice: The Xlib XDrawRectangle() function always fills one
373 * pixel less than specified. Altough this is very likely just a
374 * plain old bug, it is documented that way. Obviously, Qt just
375 * maps the fillRect() call directly to XDrawRectangle() so they
376 * inherited that bug ( although the Qt doc stays silent about
377 * it ). So it is really necessary to compensate for that missing
378 * pixel in each dimension.
380 * If you don't believe it, see for yourself.
381 * Hint: Try the xmag program to zoom into the drawn pixels.
384 // Fill the desired percentage.
386 painter->fillRect( x + penWidth, y + penWidth,
387 fillWidth+1, h - 2 * penWidth+1,
393 pen.setColor( contrastingColor ( Qt::black,
394 painter->background().color() ) );
395 painter->setPen( pen );
396 painter->drawLine( x, y, x+w, y );
397 painter->drawLine( x, y, x, y+h );
399 pen.setColor( contrastingColor( barBackground.dark(),
400 painter->background().color() ) );
401 painter->setPen( pen );
402 painter->drawLine( x+1, y+1, x+w-1, y+1 );
403 painter->drawLine( x+1, y+1, x+1, y+h-1 );
405 pen.setColor( contrastingColor( barBackground.light(),
406 painter->background().color() ) );
407 painter->setPen( pen );
408 painter->drawLine( x+1, y+h, x+w, y+h );
409 painter->drawLine( x+w, y, x+w, y+h );
411 pen.setColor( contrastingColor( Qt::white,
412 painter->background().color() ) );
413 painter->setPen( pen );
414 painter->drawLine( x+2, y+h-1, x+w-1, y+h-1 );
415 painter->drawLine( x+w-1, y+1, x+w-1, y+h-1 );
423 #include "QY2DiskUsageList.moc"