]> icculus.org git repositories - duncan/yast2-qt4.git/blob - src/pkg/YQPkgDiskUsageList.cc
make the layout half way working at least
[duncan/yast2-qt4.git] / src / pkg / YQPkgDiskUsageList.cc
1 /*---------------------------------------------------------------------\
2 |                                                                      |
3 |                      __   __    ____ _____ ____                      |
4 |                      \ \ / /_ _/ ___|_   _|___ \                     |
5 |                       \ V / _` \___ \ | |   __) |                    |
6 |                        | | (_| |___) || |  / __/                     |
7 |                        |_|\__,_|____/ |_| |_____|                    |
8 |                                                                      |
9 |                               core system                            |
10 |                                                        (C) SuSE GmbH |
11 \----------------------------------------------------------------------/
12
13   File:       YQPkgDiskUsageList.cc
14
15   Author:     Stefan Hundhammer <sh@suse.de>
16
17   Textdomain "packages-qt"
18
19 /-*/
20
21 #define QT3_SUPPORT 1
22
23 #define y2log_component "qt-pkg"
24 #include <ycp/y2log.h>
25
26 #include <q3header.h>
27 #include <qstyle.h>
28 #include <QHeaderView>
29 //Added by qt3to4:
30 #include <qevent.h>
31
32 #include <zypp/ZYppFactory.h>
33
34 #include "utf8.h"
35 #include "YQPkgDiskUsageList.h"
36 #include "YQPkgDiskUsageWarningDialog.h"
37 #include "YQi18n.h"
38
39
40 using std::set;
41
42
43 // Warning ranges for "disk space is running out" or "disk space overflow".
44 // The WARN value triggers a warning popup once ( ! ). The warning will not be
45 // displayed again until the value sinks below the PROXIMITY value and then
46 // increases again to the WARN value.
47 //
48 // See class YQPkgWarningRangeNotifier in file YQPkgDiskUsageList.h for details.
49
50 #define MIN_FREE_MB_WARN        400
51 #define MIN_FREE_MB_PROXIMITY   700
52
53 #define MIN_PERCENT_WARN        90
54 #define MIN_PERCENT_PROXIMITY   80
55
56 #define OVERFLOW_MB_WARN        0
57 #define OVERFLOW_MB_PROXIMITY   300
58
59
60 typedef zypp::DiskUsageCounter::MountPointSet           ZyppDuSet;
61 typedef zypp::DiskUsageCounter::MountPointSet::iterator ZyppDuSetIterator;
62
63
64
65 YQPkgDiskUsageList::YQPkgDiskUsageList( QWidget * parent, int thresholdPercent )
66     : QY2DiskUsageList( parent, true )
67 {
68     _debug = false;
69
70     ZyppDuSet diskUsage = zypp::getZYpp()->diskUsage();
71
72     if ( diskUsage.empty() )
73     {
74         zypp::getZYpp()->setPartitions( zypp::DiskUsageCounter::detectMountPoints() );
75         diskUsage = zypp::getZYpp()->diskUsage();
76     }
77
78
79     for ( ZyppDuSetIterator it = diskUsage.begin();
80           it != diskUsage.end();
81           ++it )
82     {
83         const ZyppPartitionDu & partitionDu = *it;
84
85         if ( ! partitionDu.readonly )
86         {
87             YQPkgDiskUsageListItem * item = new YQPkgDiskUsageListItem( this, partitionDu );
88             Q_CHECK_PTR( item );
89             item->updateData();
90             _items.insert( partitionDu.dir.c_str(), item );
91         }
92     }
93
94 }
95
96
97 void
98 YQPkgDiskUsageList::updateDiskUsage()
99 {
100     runningOutWarning.clear();
101     overflowWarning.clear();
102
103     ZyppDuSet diskUsage = zypp::getZYpp()->diskUsage();
104
105     for ( ZyppDuSetIterator it = diskUsage.begin();
106           it != diskUsage.end();
107           ++it )
108     {
109         const ZyppPartitionDu & partitionDu = *it;
110         YQPkgDiskUsageListItem * item = _items[ partitionDu.dir.c_str() ];
111
112         if ( item )
113             item->updateDuData( partitionDu );
114         else
115             y2error( "No entry for mount point %s", partitionDu.dir.c_str() );
116     }
117
118 #if FIXME
119     sort();
120 #endif
121     postPendingWarnings();
122 }
123
124
125 void
126 YQPkgDiskUsageList::postPendingWarnings()
127 {
128     if ( overflowWarning.needWarning() )
129     {
130         YQPkgDiskUsageWarningDialog::diskUsageWarning( _( "<b>Error:</b> Out of disk space!" ),
131                                                        100, _( "&OK" ) );
132
133         overflowWarning.warningPostedNotify();
134         runningOutWarning.warningPostedNotify(); // Suppress this ( now redundant ) other warning
135     }
136
137     if ( runningOutWarning.needWarning() )
138     {
139         YQPkgDiskUsageWarningDialog::diskUsageWarning( _( "<b>Warning:</b> Disk space is running out!" ) ,
140                                                        MIN_PERCENT_WARN, _( "&OK" ) );
141         runningOutWarning.warningPostedNotify();
142     }
143
144     if ( overflowWarning.leavingProximity() )
145         overflowWarning.clearHistory();
146
147     if ( runningOutWarning.leavingProximity() )
148         runningOutWarning.clearHistory();
149 }
150
151
152 QSize
153 YQPkgDiskUsageList::sizeHint() const
154 {
155
156 #ifdef FIXME
157         int width = header()->headerWidth()
158         + style().pixelMetric( QStyle::PM_ScrollBarExtent, verticalScrollBar() );
159 #else
160         int width = header()->sizeHint().width()
161         + 30;
162 #endif
163
164     return QSize( width, 100 );
165 }
166
167
168 void
169 YQPkgDiskUsageList::keyPressEvent( QKeyEvent * event )
170 {
171
172     if ( event )
173     {
174         unsigned special_combo = ( Qt::ControlButton | Qt::ShiftButton | Qt::AltButton );
175
176         if ( ( event->state() & special_combo ) == special_combo )
177         {
178             if ( event->key() == Qt::Key_Q )
179             {
180                 _debug = ! _debug;
181                 y2milestone( "Debug mode %s", _debug ? "on" : "off" );
182             }
183
184         }
185
186         if ( _debug && currentItem() )
187         {
188             YQPkgDiskUsageListItem * item = dynamic_cast<YQPkgDiskUsageListItem *> ( currentItem() );
189
190             if ( item )
191             {
192                 {
193                     int percent = item->usedPercent();
194
195                     switch ( event->ascii() )
196                     {
197                         case '1':       percent = 10;   break;
198                         case '2':       percent = 20;   break;
199                         case '3':       percent = 30;   break;
200                         case '4':       percent = 40;   break;
201                         case '5':       percent = 50;   break;
202                         case '6':       percent = 60;   break;
203                         case '7':       percent = 70;   break;
204                         case '8':       percent = 80;   break;
205                         case '9':       percent = 90;   break;
206                         case '0':       percent = 100;  break;
207                         case '+':       percent += 3;   break;
208                         case '-':       percent -= 3;   break;
209
210                         case 'w':
211                             // Only for testing, thus intentionally using no translations
212                             YQPkgDiskUsageWarningDialog::diskUsageWarning( "<b>Warning:</b> Disk space is running out!",
213                                                                            90, "&OK" );
214                             break;
215
216                         case 'f':
217                             YQPkgDiskUsageWarningDialog::diskUsageWarning( "<b>Error:</b> Out of disk space!",
218                                                                            100, "&Continue anyway", "&Cancel" );
219                             break;
220                     }
221
222                     if ( percent < 0   )
223                         percent = 0;
224
225                     ZyppPartitionDu partitionDu( item->partitionDu() );
226
227                     if ( percent != item->usedPercent() )
228                     {
229                         partitionDu.pkg_size = partitionDu.total_size * percent / 100;
230
231                         runningOutWarning.clear();
232                         overflowWarning.clear();
233
234                         item->updateDuData( partitionDu );
235                         postPendingWarnings();
236                     }
237                 }
238             }
239         }
240     }
241
242     QY2DiskUsageList::keyPressEvent( event );
243 }
244
245
246
247
248
249
250 YQPkgDiskUsageListItem::YQPkgDiskUsageListItem( YQPkgDiskUsageList *    parent,
251                                                 const ZyppPartitionDu & partitionDu )
252         : QY2DiskUsageListItem( parent )
253         , _partitionDu( partitionDu )
254         , _pkgDiskUsageList( parent )
255 {
256     y2debug( "disk usage list entry for %s", partitionDu.dir.c_str() );
257 }
258
259
260 FSize
261 YQPkgDiskUsageListItem::usedSize() const
262 {
263     return FSize( _partitionDu.pkg_size, FSize::K );
264 }
265
266
267 FSize
268 YQPkgDiskUsageListItem::totalSize() const
269 {
270     return FSize( _partitionDu.total_size, FSize::K );
271 }
272
273
274 QString
275 YQPkgDiskUsageListItem::name() const
276 {
277     return fromUTF8( _partitionDu.dir.c_str() );
278 }
279
280
281 void
282 YQPkgDiskUsageListItem::updateDuData( const ZyppPartitionDu & fromData )
283 {
284     _partitionDu = fromData;
285     updateData();
286     checkRemainingDiskSpace();
287 }
288
289
290 void
291 YQPkgDiskUsageListItem::checkRemainingDiskSpace()
292 {
293     int percent = usedPercent();
294     int free    = freeSize() / FSize::MB;
295
296     if ( percent > MIN_PERCENT_WARN )
297     {
298         // Modern hard disks can be huge, so a warning based on percentage only
299         // can be misleading - check the absolute value, too.
300
301         if ( free < MIN_FREE_MB_PROXIMITY )
302             _pkgDiskUsageList->runningOutWarning.enterProximity();
303
304         if ( free < MIN_FREE_MB_WARN )
305             _pkgDiskUsageList->runningOutWarning.enterRange();
306     }
307
308     if ( free < MIN_FREE_MB_PROXIMITY )
309     {
310         if ( percent > MIN_PERCENT_PROXIMITY )
311             _pkgDiskUsageList->runningOutWarning.enterProximity();
312     }
313
314     if ( free < OVERFLOW_MB_WARN )
315         _pkgDiskUsageList->overflowWarning.enterRange();
316
317     if ( free < OVERFLOW_MB_PROXIMITY )
318         _pkgDiskUsageList->overflowWarning.enterProximity();
319 }
320
321
322
323
324
325
326 YQPkgWarningRangeNotifier::YQPkgWarningRangeNotifier()
327 {
328     clearHistory();
329 }
330
331
332 void
333 YQPkgWarningRangeNotifier::clear()
334 {
335     _inRange            = false;
336     _hasBeenClose       = _isClose;
337     _isClose            = false;
338 }
339
340
341 void
342 YQPkgWarningRangeNotifier::clearHistory()
343 {
344     clear();
345     _hasBeenClose  = false;
346     _warningPosted = false;
347 }
348
349
350 void
351 YQPkgWarningRangeNotifier::enterRange()
352 {
353     _inRange = true;
354     enterProximity();
355 }
356
357
358 void
359 YQPkgWarningRangeNotifier::enterProximity()
360 {
361     _isClose      = true;
362     _hasBeenClose = true;
363 }
364
365
366 void
367 YQPkgWarningRangeNotifier::warningPostedNotify()
368 {
369     _warningPosted = true;
370 }
371
372
373 bool
374 YQPkgWarningRangeNotifier::inRange() const
375 {
376     return _inRange;
377 }
378
379
380 bool
381 YQPkgWarningRangeNotifier::leavingProximity() const
382 {
383     return ! _isClose && ! _hasBeenClose;
384 }
385
386
387 bool
388 YQPkgWarningRangeNotifier::needWarning() const
389 {
390     return _inRange && ! _warningPosted;
391 }
392
393
394
395
396 #include "YQPkgDiskUsageList.moc"