]> icculus.org git repositories - duncan/yast2-qt4.git/blob - src/QY2DiskUsageList.cc
compile
[duncan/yast2-qt4.git] / src / QY2DiskUsageList.cc
1 /*---------------------------------------------------------------------\
2 |                                                                      |
3 |                      __   __    ____ _____ ____                      |
4 |                      \ \ / /_ _/ ___|_   _|___ \                     |
5 |                       \ V / _` \___ \ | |   __) |                    |
6 |                        | | (_| |___) || |  / __/                     |
7 |                        |_|\__,_|____/ |_| |_____|                    |
8 |                                                                      |
9 |                               core system                            |
10 |                                                        (C) SuSE GmbH |
11 \----------------------------------------------------------------------/
12
13   File:       QY2DiskUsageList.cc
14
15   Author:     Stefan Hundhammer <sh@suse.de>
16
17   Textdomain "packages-qt"
18
19   This is a pure Qt widget - it can be used independently of YaST2.
20
21
22 /-*/
23
24 #include "QY2DiskUsageList.h"
25 #include "YQi18n.h"
26 #include "qpainter.h"
27
28
29 QY2DiskUsageList::QY2DiskUsageList( QWidget * parent, bool addStdColumns )
30     : QY2ListView( parent )
31 {
32     _nameCol            = -42;
33     _percentageBarCol   = -42;
34     _percentageCol      = -42;
35     _usedSizeCol        = -42;
36     _freeSizeCol        = -42;
37     _totalSizeCol       = -42;
38     _deviceNameCol      = -42;
39
40     QStringList columnLabels;
41     if ( addStdColumns )
42     {
43         int numCol = 0;
44         columnLabels << _( "Name"               );      _nameCol                = numCol++;
45         // Translators: Please keep this short!
46         columnLabels <<  _("Disk Usage");       _percentageBarCol       = numCol++;
47         columnLabels << ""; _percentageCol = numCol++;
48         columnLabels << _("Used"); _usedSizeCol         = numCol++;
49         columnLabels << _( "Free"); _freeSizeCol                = numCol++;
50         columnLabels << _("Total"); _totalSizeCol               = numCol++;
51 #if 0
52         addColumn( _( "Device"          ) );    _deviceNameCol          = numCol++;
53 #endif
54         // needed?
55         setColumnCount(numCol);
56         setHeaderLabels(columnLabels);
57         
58         //FIXME
59 //         setTextAlignment( percentageCol(), Qt::AlignRight );
60 //         setTextAlignment( usedSizeCol(), Qt::AlignRight );
61 //         setTextAlignment( freeSizeCol(), Qt::AlignRight );
62 //         setTextAlignment( totalSizeCol(), Qt::AlignRight );
63         sortItems( percentageBarCol(), Qt::AscendingOrder );
64     }
65
66     saveColumnWidths();
67     setSelectionMode(QAbstractItemView::NoSelection);
68 }
69
70
71 QY2DiskUsageList::~QY2DiskUsageList()
72 {
73 }
74
75
76
77
78
79
80 QY2DiskUsageListItem::QY2DiskUsageListItem( QY2DiskUsageList * parent )
81     : QY2ListViewItem( parent )
82     , _diskUsageList( parent )
83 {
84 }
85
86
87
88
89 QY2DiskUsageListItem::~QY2DiskUsageListItem()
90 {
91     // NOP
92 }
93
94
95
96
97 void
98 QY2DiskUsageListItem::init( bool allFields )
99 {
100     if ( percentageCol()        >= 0 )
101     {
102         QString percentageText;
103         percentageText.sprintf( "%d%%", usedPercent() );
104         setText( percentageCol(), percentageText );
105     }
106
107     if ( usedSizeCol()          >= 0 ) setText( usedSizeCol(),          usedSize()      );
108     if ( freeSizeCol()          >= 0 ) setText( freeSizeCol(),          freeSize()      );
109
110     if ( allFields )
111     {
112         if ( totalSizeCol()     >= 0 ) setText( totalSizeCol(),         totalSize()     );
113         if ( nameCol()          >= 0 ) setText( nameCol(),              " " + name()    );
114         if ( deviceNameCol()    >= 0 ) setText( deviceNameCol(),        deviceName()    );
115     }
116 }
117
118
119 void
120 QY2DiskUsageListItem::setText( int column, const FSize & size )
121 {
122     QString sizeText = size.form( 0, 1, true ).c_str();
123     sizeText += " ";
124     setText( column, sizeText );
125 }
126
127
128 FSize
129 QY2DiskUsageListItem::freeSize() const
130 {
131     return totalSize() - usedSize();
132 }
133
134
135 int
136 QY2DiskUsageListItem::usedPercent() const
137 {
138     int percent = 0;
139
140     if ( totalSize() != 0 )
141         percent = ( 100 * usedSize() ) / totalSize();
142
143     return percent;
144 }
145
146
147 void
148 QY2DiskUsageListItem::updateStatus()
149 {
150     init( false );
151 }
152
153
154 void
155 QY2DiskUsageListItem::updateData()
156 {
157     init( true );
158 }
159
160
161
162
163
164 /**
165  * Comparison function used for sorting the list.
166  * Returns:
167  * -1 if this <  other
168  *  0 if this == other
169  * +1 if this >  other
170  **/
171 int
172 QY2DiskUsageListItem::compare( QTreeWidgetItem *        otherListViewItem,
173                                int              col,
174                                bool             ascending ) const
175 {
176     QY2DiskUsageListItem * other = dynamic_cast<QY2DiskUsageListItem *> (otherListViewItem);
177
178     if ( other )
179     {
180         if ( col == percentageCol()    ||
181              col == percentageBarCol()   )
182         {
183             // Intentionally reverting sort order: Fullest first
184
185             if ( this->usedPercent() < other->usedPercent() )   return  1;
186             if ( this->usedPercent() > other->usedPercent() )   return -1;
187             return 0;
188         }
189         else if ( col == usedSizeCol() )
190         {
191             if ( this->usedSize() < other->usedSize() )         return -1;
192             if ( this->usedSize() > other->usedSize() )         return  1;
193             return 0;
194         }
195         else if ( col == freeSizeCol() )
196         {
197             if ( this->freeSize() < other->freeSize() )         return -1;
198             if ( this->freeSize() > other->freeSize() )         return  1;
199             return 0;
200         }
201         else if ( col == totalSizeCol() )
202         {
203             if ( this->totalSize() < other->totalSize() )       return -1;
204             if ( this->totalSize() > other->totalSize() )       return  1;
205             return 0;
206         }
207     }
208
209     return QY2ListViewItem::compare( otherListViewItem, col, ascending );
210 }
211
212 /*
213 void
214 QY2DiskUsageListItem::paintCell( QPainter *             painter,
215                                  const QColorGroup &    colorGroup,
216                                  int                    column,
217                                  int                    width,
218                                  int                    alignment )
219 {
220     if ( column == percentageBarCol() )
221     {
222         QColor background = colorGroup.base();
223         painter->setBackgroundColor( background );
224
225         paintPercentageBar( usedPercent(),
226                             painter,
227                             _diskUsageList->treeStepSize() * depth(),
228                             width,
229                             interpolateColor( usedPercent(),
230                                               60, 95,
231                                               QColor( 0, 0x80, 0 ),     // Medium dark green
232                                               QColor( 0xFF, 0, 0 ) ),   // Bright red
233                             background.dark( 115 ) );
234
235     }
236     else
237     {
238         QColorGroup cg( colorGroup );
239
240         if ( usedSize() > totalSize() )
241             cg.setColor( QColorGroup::Text, Qt::red );          // Set red text foreground
242
243         // Intentionally bypassing the direct parent class method, use the grandparent's:
244         // Don't let QY2ListViewItem::_textColor / _backgroundColor interfere with our colors.
245
246         Q3ListViewItem::paintCell( painter, cg, column, width, alignment );
247     }
248 }
249 */
250
251 /**
252  * Stolen from KDirStat::KDirTreeView with the author's permission.
253  **/
254 void
255 QY2DiskUsageListItem::paintPercentageBar( float                 percent,
256                                           QPainter *            painter,
257                                           int                   indent,
258                                           int                   width,
259                                           const QColor &        fillColor,
260                                           const QColor &        barBackground )
261 {
262 //     if ( percent > 100.0 )   percent = 100.0;
263 //     if ( percent < 0.0   )   percent = 0.0;
264 //     int penWidth = 2;
265 //     int extraMargin = 3;
266 //     int x = 0; /*FIXME _diskUsageList->itemMargin(); */
267 //     int y = extraMargin;
268 //     int w = width    - 2; /*FIXME * _diskUsageList->horizontalOffset(); */
269 //     int h = height() - 2; /*FIXME * extraMargin; */
270 //     int fillWidth;
271 // 
272 //     painter->eraseRect( 0, 0, width, height() );
273 //     w -= indent;
274 //     x += indent;
275 // 
276 //     if ( w > 0 )
277 //     {
278 //      QPen pen( painter->pen() );
279 //      pen.setWidth(0);
280 //      painter->setPen( pen );
281 //      painter->setBrush( Qt::NoBrush );
282 //      fillWidth = (int) ( ( w - 2 * penWidth ) * percent / 100.0 );
283 // 
284 // 
285 //      // Fill bar background.
286 // 
287 //      painter->fillRect( x + penWidth, y + penWidth,
288 //                         w - 2 * penWidth + 1, h - 2 * penWidth + 1,
289 //                         barBackground );
290 //      /*
291 //       * Notice: The Xlib XDrawRectangle() function always fills one
292 //       * pixel less than specified. Altough this is very likely just a
293 //       * plain old bug, it is documented that way. Obviously, Qt just
294 //       * maps the fillRect() call directly to XDrawRectangle() so they
295 //       * inherited that bug ( although the Qt doc stays silent about
296 //       * it ). So it is really necessary to compensate for that missing
297 //       * pixel in each dimension.
298 //       *
299 //       * If you don't believe it, see for yourself.
300 //       * Hint: Try the xmag program to zoom into the drawn pixels.
301 //       **/
302 // 
303 //      // Fill the desired percentage.
304 // 
305 //      painter->fillRect( x + penWidth, y + penWidth,
306 //                         fillWidth+1, h - 2 * penWidth+1,
307 //                         fillColor );
308 // 
309 // 
310 //      // Draw 3D shadows.
311 // 
312 //      pen.setColor( contrastingColor ( Qt::black,
313 //                                       painter->backgroundColor() ) );
314 //      painter->setPen( pen );
315 //      painter->drawLine( x, y, x+w, y );
316 //      painter->drawLine( x, y, x, y+h );
317 // 
318 //      pen.setColor( contrastingColor( barBackground.dark(),
319 //                                      painter->backgroundColor() ) );
320 //      painter->setPen( pen );
321 //      painter->drawLine( x+1, y+1, x+w-1, y+1 );
322 //      painter->drawLine( x+1, y+1, x+1, y+h-1 );
323 // 
324 //      pen.setColor( contrastingColor( barBackground.light(),
325 //                                      painter->backgroundColor() ) );
326 //      painter->setPen( pen );
327 //      painter->drawLine( x+1, y+h, x+w, y+h );
328 //      painter->drawLine( x+w, y, x+w, y+h );
329 // 
330 //      pen.setColor( contrastingColor( Qt::white,
331 //                                      painter->backgroundColor() ) );
332 //      painter->setPen( pen );
333 //      painter->drawLine( x+2, y+h-1, x+w-1, y+h-1 );
334 //      painter->drawLine( x+w-1, y+1, x+w-1, y+h-1 );
335 //    }
336 }
337
338
339 /**
340  * Stolen from KDirStat::KDirTreeView with the author's permission.
341  **/
342 QColor
343 QY2DiskUsageListItem::contrastingColor( const QColor & desiredColor,
344                                         const QColor & contrastColor )
345 {
346     if ( desiredColor != contrastColor )
347     {
348         return desiredColor;
349     }
350
351     if ( contrastColor != contrastColor.light() )
352     {
353         // try a little lighter
354         return contrastColor.light();
355     }
356     else
357     {
358         // try a little darker
359         return contrastColor.dark();
360     }
361 }
362
363
364 QColor
365 QY2DiskUsageListItem::interpolateColor( int             val,
366                                         int             minVal,
367                                         int             maxVal,
368                                         const QColor &  minColor,
369                                         const QColor &  maxColor )
370 {
371     int minH, maxH;
372     int minS, maxS;
373     int minV, maxV;
374
375     minColor.getHsv( &minH, &minS, &minV );
376     maxColor.getHsv( &maxH, &maxS, &maxV );
377
378     return QColor::fromHsv( interpolate( val, minVal, maxVal, minH, maxH ),
379                    interpolate( val, minVal, maxVal, minS, maxS ),
380                    interpolate( val, minVal, maxVal, minV, maxV ) );
381 }
382
383
384 int
385 QY2DiskUsageListItem::interpolate( int from,
386                                    int minFrom, int maxFrom,
387                                    int minTo,   int maxTo       )
388 {
389     if ( minFrom > maxFrom )
390     {
391         // Swap min/max values
392
393         int tmp = maxFrom;
394         maxFrom = minFrom;
395         minFrom = tmp;
396     }
397
398     long x = from - minFrom;
399     x *= maxTo - minTo;
400     x /= maxFrom - minFrom;
401     x += minTo;
402
403     if ( minTo < maxTo )
404     {
405         if ( x < minTo )        x = minTo;
406         if ( x > maxTo )        x = maxTo;
407     }
408     else
409     {
410         if ( x < maxTo )        x = maxTo;
411         if ( x > minTo )        x = minTo;
412     }
413
414     return (int) x;
415 }
416
417
418
419 #include "QY2DiskUsageList.moc"