libyui-qt  2.49.2
QY2DiskUsageList.cc
1 /*
2  Copyright (C) 2000-2012 Novell, Inc
3  This library is free software; you can redistribute it and/or modify
4  it under the terms of the GNU Lesser General Public License as
5  published by the Free Software Foundation; either version 2.1 of the
6  License, or (at your option) version 3.0 of the License. This library
7  is distributed in the hope that it will be useful, but WITHOUT ANY
8  WARRANTY; without even the implied warranty of MERCHANTABILITY or
9  FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
10  License for more details. You should have received a copy of the GNU
11  Lesser General Public License along with this library; if not, write
12  to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
13  Floor, Boston, MA 02110-1301 USA
14 */
15 
16 
17 /*-/
18 
19  File: QY2DiskUsageList.cc
20 
21  Author: Stefan Hundhammer <sh@suse.de>
22 
23  Textdomain "qt"
24 
25  This is a pure Qt widget - it can be used independently of YaST2.
26 
27 
28 /-*/
29 
30 #include "QY2DiskUsageList.h"
31 #include "YQi18n.h"
32 #include <QPainter>
33 #include <QItemDelegate>
34 #include <QDebug>
35 
36 #ifdef TEXTDOMAIN
37 # undef TEXTDOMAIN
38 #endif
39 
40 #define TEXTDOMAIN "qt"
41 
42 
43 
44 /**
45  * Stolen from KDirStat::KDirTreeView with the author's permission.
46  **/
47 QColor
48 contrastingColor( const QColor & desiredColor,
49  const QColor & contrastColor )
50 {
51  if ( desiredColor != contrastColor )
52  {
53  return desiredColor;
54  }
55 
56  if ( contrastColor != contrastColor.light() )
57  {
58  // try a little lighter
59  return contrastColor.light();
60  }
61  else
62  {
63  // try a little darker
64  return contrastColor.dark();
65  }
66 }
67 
68 /**
69  * Interpolate ( translate ) a value 'from' in the range between 'minFrom'
70  * and 'maxFrom' to a range between 'minTo' and 'maxTo'.
71  **/
72 static int
73 interpolate( int from,
74  int minFrom, int maxFrom,
75  int minTo, int maxTo )
76 {
77  if ( minFrom > maxFrom )
78  {
79  // Swap min/max values
80 
81  int tmp = maxFrom;
82  maxFrom = minFrom;
83  minFrom = tmp;
84  }
85 
86  long x = from - minFrom;
87  x *= maxTo - minTo;
88  x /= maxFrom - minFrom;
89  x += minTo;
90 
91  if ( minTo < maxTo )
92  {
93  if ( x < minTo ) x = minTo;
94  if ( x > maxTo ) x = maxTo;
95  }
96  else
97  {
98  if ( x < maxTo ) x = maxTo;
99  if ( x > minTo ) x = minTo;
100  }
101 
102  return (int) x;
103 }
104 
105 /**
106  * Interpolate ( in the HSV color space ) a color between 'minColor' and
107  * 'maxColor' for a current value 'val' so that 'minVal' corresponds to
108  * 'minColor' and 'maxVal' to 'maxColor'.
109  *
110  * Returns the interpolated color.
111  **/
112 static QColor
113 interpolateColor( int val,
114  int minVal,
115  int maxVal,
116  const QColor & minColor,
117  const QColor & maxColor )
118 {
119  int minH, maxH;
120  int minS, maxS;
121  int minV, maxV;
122 
123  minColor.getHsv( &minH, &minS, &minV );
124  maxColor.getHsv( &maxH, &maxS, &maxV );
125 
126  return QColor::fromHsv( interpolate( val, minVal, maxVal, minH, maxH ),
127  interpolate( val, minVal, maxVal, minS, maxS ),
128  interpolate( val, minVal, maxVal, minV, maxV ) );
129 }
130 
131 
132 class QY2DiskUsagePercentageItem : public QItemDelegate
133 {
134  QY2DiskUsageList *_view;
135 
136 public:
137  QY2DiskUsagePercentageItem( QY2DiskUsageList *parent ) : QItemDelegate( parent ), _view( parent ) {
138  }
139 
140  virtual void paint ( QPainter * painter, const QStyleOptionViewItem & option, const QModelIndex & index ) const
141  {
142  painter->save();
143  QColor background = option.palette.color(QPalette::Window);
144  painter->setBackground( background );
145 
146  QY2DiskUsageListItem *item = dynamic_cast<QY2DiskUsageListItem *>(_view->itemFromIndex(index));
147  if ( item )
148  {
149  item->paintPercentageBar( painter,
150  option,
151  interpolateColor( item->usedPercent(),
152  60, 95,
153  QColor( 0, 0xa0, 0 ), // Medium dark green
154  QColor( 0xFF, 0, 0 ) ) ); // Bright red
155  }
156  painter->restore();
157  }
158 };
159 
160 QY2DiskUsageList::QY2DiskUsageList( QWidget * parent, bool addStdColumns )
161  : QY2ListView( parent )
162 {
163  _nameCol = -42;
164  _percentageBarCol = -42;
165  _usedSizeCol = -42;
166  _freeSizeCol = -42;
167  _totalSizeCol = -42;
168  _deviceNameCol = -42;
169 
170  // set temporary textdomain to enable translations
171  // in inherit classed (e.g. YQPkgDiskUsageList)
172  // see bnc #445716
173  QString savedtextdomain = textdomain(NULL);
174  textdomain(TEXTDOMAIN);
175 
176  QStringList columnLabels;
177  if ( addStdColumns )
178  {
179  int numCol = 0;
180  columnLabels << _( "Name" ); _nameCol = numCol++;
181  // Translators: Please keep this short!
182  columnLabels << _("Disk Usage"); _percentageBarCol = numCol++;
183  setItemDelegateForColumn( _percentageBarCol, new QY2DiskUsagePercentageItem( this ) );
184  //columnLabels << _("Used"); _usedSizeCol = numCol++;
185  columnLabels << _( "Free"); _freeSizeCol = numCol++;
186  columnLabels << _("Total"); _totalSizeCol = numCol++;
187 #if 0
188  addColumn( _( "Device" ) ); _deviceNameCol = numCol++;
189 #endif
190  // needed?
191  setColumnCount(numCol);
192  setHeaderLabels(columnLabels);
193 
194  sortItems( percentageBarCol(), Qt::AscendingOrder );
195  setSizePolicy( QSizePolicy::Minimum, QSizePolicy::Minimum );
196  }
197 
198  textdomain(savedtextdomain.toLatin1());
199 
201  setSelectionMode(QAbstractItemView::NoSelection);
202 }
203 
204 
206 {
207 }
208 
209 
210 void QY2DiskUsageList::drawRow( QPainter * painter, const QStyleOptionViewItem & option, const QModelIndex & index ) const
211 {
212  // Intentionally bypassing the direct parent class method, use the grandparent's:
213  // Don't let QY2ListViewItem::_textColor / _backgroundColor interfere with our colors.
214 
215  QTreeWidget::drawRow( painter, option, index );
216 }
217 
218 
220  : QY2ListViewItem( parent )
221  , _diskUsageList( parent )
222 {
223 }
224 
225 
226 
227 
229 {
230  // NOP
231 }
232 
233 
234 
235 
236 void
237 QY2DiskUsageListItem::init( bool allFields )
238 {
239  setSizeHint( percentageBarCol(), QSize( 20, 10 ) );
240 
241  setTextAlignment( usedSizeCol(), Qt::AlignRight );
242  setTextAlignment( freeSizeCol(), Qt::AlignRight );
243  setTextAlignment( totalSizeCol(), Qt::AlignRight );
244 
245  if ( usedSizeCol() >= 0 ) setText( usedSizeCol(), usedSize() );
246  if ( freeSizeCol() >= 0 ) setText( freeSizeCol(), freeSize() );
247 
248  if ( allFields )
249  {
250  if ( totalSizeCol() >= 0 ) setText( totalSizeCol(), totalSize() );
251  if ( nameCol() >= 0 ) setText( nameCol(), name() );
252  if ( deviceNameCol() >= 0 ) setText( deviceNameCol(), deviceName() );
253  }
254 
255  if ( usedSizeCol() < 0 )
256  setToolTip( freeSizeCol(), _( "Used %1" ).arg( usedSize().form( 0, 1, true ).c_str() ) );
257 }
258 
259 
260 void
261 QY2DiskUsageListItem::setText( int column, const FSize & size )
262 {
263  QString sizeText = size.form( 0, 1, true ).c_str();
264  setText( column, sizeText );
265 }
266 
267 
268 FSize
270 {
271  return totalSize() - usedSize();
272 }
273 
274 
275 int
277 {
278  int percent = 0;
279 
280  if ( totalSize() != 0 )
281  percent = ( 100 * usedSize() ) / totalSize();
282 
283  return percent;
284 }
285 
286 
287 void
289 {
290  init( false );
291 }
292 
293 
294 void
296 {
297  init( true );
298 }
299 
300 
301 
302 
303 
304 /**
305  * Comparison function used for sorting the list.
306  * Reimplemented from QTreeWidgetItem
307  **/
308 bool
309 QY2DiskUsageListItem::operator<( const QTreeWidgetItem & otherListViewItem ) const
310 {
311  const QY2DiskUsageListItem * other = dynamic_cast<const QY2DiskUsageListItem *> (&otherListViewItem);
312  int col = treeWidget()->sortColumn();
313 
314  if ( other )
315  {
316  if ( col == percentageBarCol() )
317  {
318  // Intentionally reverting sort order: Fullest first
319  return ( this->usedPercent() < other->usedPercent() );
320  }
321  else if ( col == usedSizeCol() )
322  {
323  return ( this->usedSize() < other->usedSize() );
324  }
325  else if ( col == freeSizeCol() )
326  {
327  return ( this->freeSize() < other->freeSize() );
328  }
329  else if ( col == totalSizeCol() )
330  {
331  return ( this->totalSize() < other->totalSize() );
332  }
333  }
334 
335  return QY2ListViewItem::operator<( otherListViewItem );
336 }
337 
338 /**
339  * Stolen from KDirStat::KDirTreeView with the author's permission.
340  **/
341 void
343  QStyleOptionViewItem option,
344  const QColor & fillColor )
345 {
346  float percent = usedPercent();
347  if ( percent > 100.0 ) percent = 100.0;
348  if ( percent < 0.0 ) percent = 0.0;
349  int x = option.rect.left() + 1;
350  int y = option.rect.top() + 1;
351  int w = option.rect.width() - 2;
352  int h = option.rect.height() - 2;
353  int fillWidth = 0;
354 
355  if ( w > 0 )
356  {
357  fillWidth = (int) ( w * percent / 100.0 );
358 
359  // Fill the desired percentage.
360 
361  painter->fillRect( x, y, fillWidth, h,
362  fillColor );
363 
364  QString percentageText;
365  percentageText.sprintf( "%d%%", usedPercent() );
366 
367  if ( usedPercent() > 50 ) {
368  painter->setPen( treeWidget()->palette().color( QPalette::Base ) );
369  painter->drawText( QRect( x, y,
370  fillWidth - 3, h ),
371  Qt::AlignRight, percentageText );
372  } else {
373  painter->setPen( treeWidget()->palette().color( QPalette::Text ) );
374  painter->drawText( QRect( x + fillWidth + 3, y,
375  w - fillWidth - 3, h ),
376  Qt::AlignLeft, percentageText );
377 
378  }
379  }
380 }
381 
382 #include "QY2DiskUsageList.moc"
virtual FSize totalSize() const =0
The total size of this partition.
QY2DiskUsageList(QWidget *parent, bool addStdColumns=true)
Constructor.
virtual bool operator<(const QTreeWidgetItem &other) const
Comparison function used for sorting the list.
Definition: QY2ListView.cc:396
virtual FSize usedSize() const =0
The currently used size of this partition.
virtual void updateStatus()
Update this item&#39;s status ( here: the numeric fields ).
QY2DiskUsageListItem(QY2DiskUsageList *parent)
Constructor.
virtual QString deviceName() const
The device name of this partition.
virtual void updateData()
Update this item&#39;s data completely.
void saveColumnWidths()
Save the current column widths.
Definition: QY2ListView.cc:170
virtual QString name() const =0
The name to display for this partition.
Abstract base class for one partition ( mount point ) to display in a QY2DiskUsageList.
void init(bool allFields)
( Re- ) initialize fields - all displayed fields ( if &#39;allFields&#39; is &#39;true&#39; ) or only the varying fie...
Generic scrollable list of disk usage for any number of partitions.
virtual FSize freeSize() const
The current free size of this partition.
virtual int usedPercent() const
The currently used percentage ( 0..100 ) of this partition.
Enhanced QTreeWidget.
Definition: QY2ListView.h:47
void setText(int column, const QString &text)
Re-declare ordinary setText() method so the compiler doesn&#39;t get confused which one to use...
virtual ~QY2DiskUsageListItem()
Destructor.
void paintPercentageBar(QPainter *painter, QStyleOptionViewItem option, const QColor &fillColor)
Paint a percentage bar into a QListViewItem cell.
Enhanced QTreeWidgetItem.
Definition: QY2ListView.h:233
virtual ~QY2DiskUsageList()
Destructor.
virtual bool operator<(const QTreeWidgetItem &other) const
Comparison function used for sorting the list.