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.
291 * Reimplemented from QTreeWidgetItem
294 QY2DiskUsageListItem::operator<( const QTreeWidgetItem & otherListViewItem ) const
296 const QY2DiskUsageListItem * other = dynamic_cast<const QY2DiskUsageListItem *> (&otherListViewItem);
297 int col = treeWidget()->sortColumn();
301 if ( col == percentageCol() ||
302 col == percentageBarCol() )
304 // Intentionally reverting sort order: Fullest first
305 return ( this->usedPercent() < other->usedPercent() );
307 else if ( col == usedSizeCol() )
309 return ( this->usedSize() < other->usedSize() );
311 else if ( col == freeSizeCol() )
313 return ( this->freeSize() < other->freeSize() );
315 else if ( col == totalSizeCol() )
317 return ( this->totalSize() < other->totalSize() );
321 return QY2ListViewItem::operator<( otherListViewItem );
325 * Stolen from KDirStat::KDirTreeView with the author's permission.
328 QY2DiskUsageListItem::paintPercentageBar( float percent,
330 QStyleOptionViewItem option,
331 const QColor & fillColor,
332 const QColor & barBackground )
334 if ( percent > 100.0 ) percent = 100.0;
335 if ( percent < 0.0 ) percent = 0.0;
338 int x = option.rect.left(); /*FIXME _diskUsageList->itemMargin(); */
339 int y = option.rect.top() + extraMargin;
340 int w = option.rect.width() - 2; /*FIXME * _diskUsageList->horizontalOffset(); */
341 int h = option.rect.height() - 2; /*FIXME * extraMargin; */
344 painter->eraseRect( option.rect );
351 QPen pen( painter->pen() );
353 painter->setPen( pen );
354 painter->setBrush( Qt::NoBrush );
355 fillWidth = (int) ( ( w - 2 * penWidth ) * percent / 100.0 );
358 // Fill bar background.
360 painter->fillRect( x + penWidth, y + penWidth,
361 w - 2 * penWidth + 1, h - 2 * penWidth + 1,
364 * Notice: The Xlib XDrawRectangle() function always fills one
365 * pixel less than specified. Altough this is very likely just a
366 * plain old bug, it is documented that way. Obviously, Qt just
367 * maps the fillRect() call directly to XDrawRectangle() so they
368 * inherited that bug ( although the Qt doc stays silent about
369 * it ). So it is really necessary to compensate for that missing
370 * pixel in each dimension.
372 * If you don't believe it, see for yourself.
373 * Hint: Try the xmag program to zoom into the drawn pixels.
376 // Fill the desired percentage.
378 painter->fillRect( x + penWidth, y + penWidth,
379 fillWidth+1, h - 2 * penWidth+1,
385 pen.setColor( contrastingColor ( Qt::black,
386 painter->background().color() ) );
387 painter->setPen( pen );
388 painter->drawLine( x, y, x+w, y );
389 painter->drawLine( x, y, x, y+h );
391 pen.setColor( contrastingColor( barBackground.dark(),
392 painter->background().color() ) );
393 painter->setPen( pen );
394 painter->drawLine( x+1, y+1, x+w-1, y+1 );
395 painter->drawLine( x+1, y+1, x+1, y+h-1 );
397 pen.setColor( contrastingColor( barBackground.light(),
398 painter->background().color() ) );
399 painter->setPen( pen );
400 painter->drawLine( x+1, y+h, x+w, y+h );
401 painter->drawLine( x+w, y, x+w, y+h );
403 pen.setColor( contrastingColor( Qt::white,
404 painter->background().color() ) );
405 painter->setPen( pen );
406 painter->drawLine( x+2, y+h-1, x+w-1, y+h-1 );
407 painter->drawLine( x+w-1, y+1, x+w-1, y+h-1 );
415 #include "QY2DiskUsageList.moc"