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