libyui-qt-pkg  2.45.27
YQPkgDiskUsageList.cc
1 /**************************************************************************
2 Copyright (C) 2000 - 2010 Novell, Inc.
3 All Rights Reserved.
4 
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
9 
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14 
15 You should have received a copy of the GNU General Public License along
16 with this program; if not, write to the Free Software Foundation, Inc.,
17 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 
19 **************************************************************************/
20 
21 
22 /*---------------------------------------------------------------------\
23 | |
24 | __ __ ____ _____ ____ |
25 | \ \ / /_ _/ ___|_ _|___ \ |
26 | \ V / _` \___ \ | | __) | |
27 | | | (_| |___) || | / __/ |
28 | |_|\__,_|____/ |_| |_____| |
29 | |
30 | core system |
31 | (C) SuSE GmbH |
32 \----------------------------------------------------------------------/
33 
34  File: YQPkgDiskUsageList.cc
35 
36  Author: Stefan Hundhammer <sh@suse.de>
37 
38  Textdomain "qt-pkg"
39 
40 /-*/
41 
42 #define YUILogComponent "qt-pkg"
43 #include "YUILog.h"
44 
45 #include <QStyle>
46 #include <QHeaderView>
47 #include <QEvent>
48 
49 #include <zypp/ZYppFactory.h>
50 
51 #include "utf8.h"
52 #include "YQPkgDiskUsageList.h"
53 #include "YQPkgDiskUsageWarningDialog.h"
54 #include "YQi18n.h"
55 
56 // arbitrary precision integer
57 #include <boost/multiprecision/cpp_int.hpp>
58 
59 using std::set;
60 using std::endl;
61 
62 
63 // Warning ranges for "disk space is running out" or "disk space overflow".
64 // The WARN value triggers a warning popup once ( ! ). The warning will not be
65 // displayed again until the value sinks below the PROXIMITY value and then
66 // increases again to the WARN value.
67 //
68 // See class YQPkgWarningRangeNotifier in file YQPkgDiskUsageList.h for details.
69 
70 #define MIN_FREE_MB_WARN 400
71 #define MIN_FREE_MB_PROXIMITY 700
72 
73 #define MIN_PERCENT_WARN 90
74 #define MIN_PERCENT_PROXIMITY 80
75 
76 #define OVERFLOW_MB_WARN 0
77 #define OVERFLOW_MB_PROXIMITY 300
78 
79 
80 typedef zypp::DiskUsageCounter::MountPointSet ZyppDuSet;
81 typedef zypp::DiskUsageCounter::MountPointSet::iterator ZyppDuSetIterator;
82 
83 
84 
85 YQPkgDiskUsageList::YQPkgDiskUsageList( QWidget * parent, int thresholdPercent )
86  : QY2DiskUsageList( parent, true )
87 {
88  _debug = false;
89 
90  ZyppDuSet diskUsage = zypp::getZYpp()->diskUsage();
91 
92  if ( diskUsage.empty() )
93  {
94  zypp::getZYpp()->setPartitions( zypp::DiskUsageCounter::detectMountPoints() );
95  diskUsage = zypp::getZYpp()->diskUsage();
96  }
97 
98 
99  for ( ZyppDuSetIterator it = diskUsage.begin();
100  it != diskUsage.end();
101  ++it )
102  {
103  const ZyppPartitionDu & partitionDu = *it;
104 
105  if ( ! partitionDu.readonly )
106  {
107  YQPkgDiskUsageListItem * item = new YQPkgDiskUsageListItem( this, partitionDu );
108  Q_CHECK_PTR( item );
109  item->updateData();
110  _items.insert( QString::fromUtf8(partitionDu.dir.c_str()), item );
111  }
112  }
113 
114  resizeColumnToContents( nameCol() );
115  resizeColumnToContents( totalSizeCol() );
116  //resizeColumnToContents( usedSizeCol() );
117  resizeColumnToContents( freeSizeCol() );
118 
119  sortByColumn( percentageBarCol(), Qt::DescendingOrder );
120 
121  header()->setSectionResizeMode( nameCol(), QHeaderView::Stretch );
122  header()->setSectionResizeMode( QHeaderView::Interactive );
123 }
124 
125 
126 void
128 {
131 
132  ZyppDuSet diskUsage = zypp::getZYpp()->diskUsage();
133 
134  for ( ZyppDuSetIterator it = diskUsage.begin();
135  it != diskUsage.end();
136  ++it )
137  {
138  const ZyppPartitionDu & partitionDu = *it;
139  YQPkgDiskUsageListItem * item = _items[ QString::fromUtf8(partitionDu.dir.c_str()) ];
140 
141  if ( item )
142  item->updateDuData( partitionDu );
143  else
144  yuiError() << "No entry for mount point " << partitionDu.dir << endl;
145  }
146 
147  resizeColumnToContents( totalSizeCol() );
149 }
150 
151 
152 void
154 {
156  {
157  YQPkgDiskUsageWarningDialog::diskUsageWarning( _( "<b>Error:</b> Out of disk space!" ),
158  100, _( "&OK" ) );
159 
161  runningOutWarning.warningPostedNotify(); // Suppress this ( now redundant ) other warning
162  }
163 
165  {
166  YQPkgDiskUsageWarningDialog::diskUsageWarning( _( "<b>Warning:</b> Disk space is running out!" ) ,
167  MIN_PERCENT_WARN, _( "&OK" ) );
169  }
170 
173 
176 }
177 
178 
179 QSize
181 {
182  QFontMetrics fms( font() );
183  return QSize( fms.width( "/var/usr/home 100% 100.32GB 100.3GB" ) + 50, 100 );
184 
185 #ifdef FIXME
186  int width = header()->headerWidth()
187  + style().pixelMetric( QStyle::PM_ScrollBarExtent, verticalScrollBar() );
188 #else
189  int width = header()->sizeHint().width()
190  + 30;
191 #endif
192 
193  return QSize( width, 100 );
194 }
195 
196 
197 void
199 {
200 
201  if ( event )
202  {
203  Qt::KeyboardModifiers special_combo = ( Qt::ControlModifier| Qt::ShiftModifier | Qt::AltModifier );
204 
205  if ( ( event->modifiers() & special_combo ) == special_combo )
206  {
207  if ( event->key() == Qt::Key_Q )
208  {
209  _debug = ! _debug;
210  yuiMilestone() << "Debug mode: " << _debug << endl;
211  }
212 
213  }
214 
215  if ( _debug && currentItem() )
216  {
217  YQPkgDiskUsageListItem * item = dynamic_cast<YQPkgDiskUsageListItem *> ( currentItem() );
218 
219  if ( item )
220  {
221  {
222  int percent = item->usedPercent();
223 
224  switch ( event->key() )
225  {
226  case Qt::Key_1: percent = 10; break;
227  case Qt::Key_2: percent = 20; break;
228  case Qt::Key_3: percent = 30; break;
229  case Qt::Key_4: percent = 40; break;
230  case Qt::Key_5: percent = 50; break;
231  case Qt::Key_6: percent = 60; break;
232  case Qt::Key_7: percent = 70; break;
233  case Qt::Key_8: percent = 80; break;
234  case Qt::Key_9: percent = 90; break;
235  case Qt::Key_0: percent = 100; break;
236  case Qt::Key_Plus: percent += 3; break;
237  case Qt::Key_Minus: percent -= 3; break;
238 
239  case 'w':
240  // Only for testing, thus intentionally using no translations
241  YQPkgDiskUsageWarningDialog::diskUsageWarning( "<b>Warning:</b> Disk space is running out!",
242  90, "&OK" );
243  break;
244 
245  case 'f':
246  YQPkgDiskUsageWarningDialog::diskUsageWarning( "<b>Error:</b> Out of disk space!",
247  100, "&Continue anyway", "&Cancel" );
248  break;
249  }
250 
251  if ( percent < 0 )
252  percent = 0;
253 
254  ZyppPartitionDu partitionDu( item->partitionDu() );
255 
256  if ( percent != item->usedPercent() )
257  {
258  partitionDu.pkg_size = partitionDu.total_size / 100 * percent;
259 
262 
263  item->updateDuData( partitionDu );
265  }
266  }
267  }
268  }
269  }
270 
271  QY2DiskUsageList::keyPressEvent( event );
272 }
273 
274 
275 
276 
277 
278 
280  const ZyppPartitionDu & partitionDu )
281  : QY2DiskUsageListItem( parent )
282  , _partitionDu( partitionDu )
283  , _pkgDiskUsageList( parent )
284 {
285  yuiDebug() << "disk usage list entry for " << partitionDu.dir << endl;
286 }
287 
288 
289 FSize
291 {
292  // the libzypp size is in KiB
293  return FSize( _partitionDu.pkg_size, FSize::Unit::K );
294 }
295 
296 
297 FSize
299 {
300  // the libzypp size is in KiB
301  return FSize( _partitionDu.total_size, FSize::Unit::K );
302 }
303 
304 
305 QString
307 {
308  return fromUTF8( _partitionDu.dir.c_str() );
309 }
310 
311 
312 void
313 YQPkgDiskUsageListItem::updateDuData( const ZyppPartitionDu & fromData )
314 {
315  _partitionDu = fromData;
316  updateData();
318 }
319 
320 
321 void
323 {
324  int percent = usedPercent();
325  // free size in MiB
326  boost::multiprecision::cpp_int free = freeSize().in_unit(FSize::Unit::M);
327 
328  yuiDebug() << "Partition " << _partitionDu.dir << " free percent: " <<
329  percent << "%, " << " free: " << freeSize() << " (" << free << "MiB)" << endl;
330 
331  if ( percent > MIN_PERCENT_WARN )
332  {
333  // Modern hard disks can be huge, so a warning based on percentage only
334  // can be misleading - check the absolute value, too.
335 
336  if ( free < MIN_FREE_MB_PROXIMITY )
337  _pkgDiskUsageList->runningOutWarning.enterProximity();
338 
339  if ( free < MIN_FREE_MB_WARN )
340  _pkgDiskUsageList->runningOutWarning.enterRange();
341  }
342 
343  if ( free < MIN_FREE_MB_PROXIMITY )
344  {
345  if ( percent > MIN_PERCENT_PROXIMITY )
346  _pkgDiskUsageList->runningOutWarning.enterProximity();
347  }
348 
349  if ( free < OVERFLOW_MB_WARN )
350  _pkgDiskUsageList->overflowWarning.enterRange();
351 
352  if ( free < OVERFLOW_MB_PROXIMITY )
353  _pkgDiskUsageList->overflowWarning.enterProximity();
354 }
355 
356 
357 
358 
359 
360 
362 {
363  clearHistory();
364 }
365 
366 
367 void
369 {
370  _inRange = false;
371  _hasBeenClose = _isClose;
372  _isClose = false;
373 }
374 
375 
376 void
378 {
379  clear();
380  _hasBeenClose = false;
381  _warningPosted = false;
382 }
383 
384 
385 void
387 {
388  _inRange = true;
389  enterProximity();
390 }
391 
392 
393 void
395 {
396  _isClose = true;
397  _hasBeenClose = true;
398 }
399 
400 
401 void
403 {
404  _warningPosted = true;
405 }
406 
407 
408 bool
410 {
411  return _inRange;
412 }
413 
414 
415 bool
417 {
418  return ! _isClose && ! _hasBeenClose;
419 }
420 
421 
422 bool
424 {
425  return _inRange && ! _warningPosted;
426 }
427 
428 
429 
430 
YQPkgWarningRangeNotifier overflowWarning
Warning range notifier about disk space overflow warning.
YQPkgDiskUsageListItem(YQPkgDiskUsageList *parent, const ZyppPartitionDu &partitionDu)
Constructor.
YQPkgDiskUsageList(QWidget *parent, int thresholdPercent=0)
Constructor.
void postPendingWarnings()
Post all pending disk space warnings based on the warning range notifiers.
void checkRemainingDiskSpace()
Check the remaining disk space of this partition based on percentage and absolute free MB...
bool leavingProximity() const
Check if the value is leaving the proximity range.
virtual void keyPressEvent(QKeyEvent *ev)
Event handler for keyboard input - for debugging and testing.
virtual QSize sizeHint() const
Suggest reasonable default size.
void updateDiskUsage()
Update all statistical data in the list.
bool needWarning() const
Check if a warning should be posted, i.e.
virtual QString name() const
The name to display for this partition ( the mount point ).
virtual FSize totalSize() const
The total size of this partition.
bool inRange() const
Check if the value is in range, i.e.
void enterProximity()
Notification that the proximity range is entered, i.e.
YQPkgWarningRangeNotifier()
Constructor.
void clear()
Clear the current values, i.e.
YQPkgWarningRangeNotifier runningOutWarning
Warning range notifier about running out of disk space warning.
static bool diskUsageWarning(const QString &message, int thresholdPercent, const QString &acceptButtonLabel, const QString &rejectButtonLabel=QString::null)
Static convenience method: Post a disk usage warning with text &#39;message&#39;, a list of partitions that a...
void enterRange()
Notification that the inner range is entered.
void clearHistory()
Clear everything, including all history values such as if a warning has been posted.
virtual FSize usedSize() const
The currently used size of this partition.
ZyppPartitionDu partitionDu() const
Returns the corresponding disk usage data.
void warningPostedNotify()
Notification that a warning has been posted.
List of disk usage of all attached partitions.
void updateDuData(const ZyppPartitionDu &fromData)
Update the disk usage data.