libyui-qt-pkg  2.47.5
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 #include <QtGlobal>
49 
50 #include <zypp/ZYppFactory.h>
51 
52 #include "utf8.h"
53 #include "YQPkgDiskUsageList.h"
54 #include "YQPkgDiskUsageWarningDialog.h"
55 #include "YQi18n.h"
56 
57 // arbitrary precision integer
58 #include <boost/multiprecision/cpp_int.hpp>
59 
60 using std::set;
61 using std::endl;
62 
63 
64 // Warning ranges for "disk space is running out" or "disk space overflow".
65 // The WARN value triggers a warning popup once ( ! ). The warning will not be
66 // displayed again until the value sinks below the PROXIMITY value and then
67 // increases again to the WARN value.
68 //
69 // See class YQPkgWarningRangeNotifier in file YQPkgDiskUsageList.h for details.
70 
71 #define MIN_FREE_MB_WARN 400
72 #define MIN_FREE_MB_PROXIMITY 700
73 
74 #define MIN_PERCENT_WARN 90
75 #define MIN_PERCENT_PROXIMITY 80
76 
77 #define OVERFLOW_MB_WARN 0
78 #define OVERFLOW_MB_PROXIMITY 300
79 
80 
81 typedef zypp::DiskUsageCounter::MountPointSet ZyppDuSet;
82 typedef zypp::DiskUsageCounter::MountPointSet::iterator ZyppDuSetIterator;
83 
84 
85 
86 YQPkgDiskUsageList::YQPkgDiskUsageList( QWidget * parent, int thresholdPercent )
87  : QY2DiskUsageList( parent, true )
88 {
89  _debug = false;
90 
91  ZyppDuSet diskUsage = zypp::getZYpp()->diskUsage();
92 
93  if ( diskUsage.empty() )
94  {
95  zypp::getZYpp()->setPartitions( zypp::DiskUsageCounter::detectMountPoints() );
96  diskUsage = zypp::getZYpp()->diskUsage();
97  }
98 
99 
100  for ( ZyppDuSetIterator it = diskUsage.begin();
101  it != diskUsage.end();
102  ++it )
103  {
104  const ZyppPartitionDu & partitionDu = *it;
105 
106  if ( ! partitionDu.readonly )
107  {
108  YQPkgDiskUsageListItem * item = new YQPkgDiskUsageListItem( this, partitionDu );
109  Q_CHECK_PTR( item );
110  item->updateData();
111  _items.insert( QString::fromUtf8(partitionDu.dir.c_str()), item );
112  }
113  }
114 
115  resizeColumnToContents( nameCol() );
116  resizeColumnToContents( totalSizeCol() );
117  //resizeColumnToContents( usedSizeCol() );
118  resizeColumnToContents( freeSizeCol() );
119 
120  sortByColumn( percentageBarCol(), Qt::DescendingOrder );
121 
122  header()->setSectionResizeMode( nameCol(), QHeaderView::Stretch );
123  header()->setSectionResizeMode( QHeaderView::Interactive );
124 }
125 
126 
127 void
129 {
132 
133  ZyppDuSet diskUsage = zypp::getZYpp()->diskUsage();
134 
135  for ( ZyppDuSetIterator it = diskUsage.begin();
136  it != diskUsage.end();
137  ++it )
138  {
139  const ZyppPartitionDu & partitionDu = *it;
140  YQPkgDiskUsageListItem * item = _items[ QString::fromUtf8(partitionDu.dir.c_str()) ];
141 
142  if ( item )
143  item->updateDuData( partitionDu );
144  else
145  yuiError() << "No entry for mount point " << partitionDu.dir << endl;
146  }
147 
148  resizeColumnToContents( totalSizeCol() );
150 }
151 
152 
153 void
155 {
157  {
158  YQPkgDiskUsageWarningDialog::diskUsageWarning( _( "<b>Error:</b> Out of disk space!" ),
159  100, _( "&OK" ) );
160 
162  runningOutWarning.warningPostedNotify(); // Suppress this ( now redundant ) other warning
163  }
164 
166  {
167  YQPkgDiskUsageWarningDialog::diskUsageWarning( _( "<b>Warning:</b> Disk space is running out!" ) ,
168  MIN_PERCENT_WARN, _( "&OK" ) );
170  }
171 
174 
177 }
178 
179 
180 QSize
182 {
183  QFontMetrics fms( font() );
184 #if QT_VERSION >= QT_VERSION_CHECK(5, 11, 0)
185  return QSize( fms.horizontalAdvance( "/var/usr/home 100% 100.32GB 100.3GB" ) + 50, 100 );
186 #else
187  return QSize( fms.width( "/var/usr/home 100% 100.32GB 100.3GB" ) + 50, 100 );
188 #endif
189 
190 #ifdef FIXME
191  int width = header()->headerWidth()
192  + style().pixelMetric( QStyle::PM_ScrollBarExtent, verticalScrollBar() );
193 #else
194  int width = header()->sizeHint().width()
195  + 30;
196 #endif
197 
198  return QSize( width, 100 );
199 }
200 
201 
202 void
204 {
205 
206  if ( event )
207  {
208  Qt::KeyboardModifiers special_combo = ( Qt::ControlModifier| Qt::ShiftModifier | Qt::AltModifier );
209 
210  if ( ( event->modifiers() & special_combo ) == special_combo )
211  {
212  if ( event->key() == Qt::Key_Q )
213  {
214  _debug = ! _debug;
215  yuiMilestone() << "Debug mode: " << _debug << endl;
216  }
217 
218  }
219 
220  if ( _debug && currentItem() )
221  {
222  YQPkgDiskUsageListItem * item = dynamic_cast<YQPkgDiskUsageListItem *> ( currentItem() );
223 
224  if ( item )
225  {
226  {
227  int percent = item->usedPercent();
228 
229  switch ( event->key() )
230  {
231  case Qt::Key_1: percent = 10; break;
232  case Qt::Key_2: percent = 20; break;
233  case Qt::Key_3: percent = 30; break;
234  case Qt::Key_4: percent = 40; break;
235  case Qt::Key_5: percent = 50; break;
236  case Qt::Key_6: percent = 60; break;
237  case Qt::Key_7: percent = 70; break;
238  case Qt::Key_8: percent = 80; break;
239  case Qt::Key_9: percent = 90; break;
240  case Qt::Key_0: percent = 100; break;
241  case Qt::Key_Plus: percent += 3; break;
242  case Qt::Key_Minus: percent -= 3; break;
243 
244  case 'w':
245  // Only for testing, thus intentionally using no translations
246  YQPkgDiskUsageWarningDialog::diskUsageWarning( "<b>Warning:</b> Disk space is running out!",
247  90, "&OK" );
248  break;
249 
250  case 'f':
251  YQPkgDiskUsageWarningDialog::diskUsageWarning( "<b>Error:</b> Out of disk space!",
252  100, "&Continue anyway", "&Cancel" );
253  break;
254  }
255 
256  if ( percent < 0 )
257  percent = 0;
258 
259  ZyppPartitionDu partitionDu( item->partitionDu() );
260 
261  if ( percent != item->usedPercent() )
262  {
263  partitionDu.pkg_size = partitionDu.total_size / 100 * percent;
264 
267 
268  item->updateDuData( partitionDu );
270  }
271  }
272  }
273  }
274  }
275 
276  QY2DiskUsageList::keyPressEvent( event );
277 }
278 
279 
280 
281 
282 
283 
285  const ZyppPartitionDu & partitionDu )
286  : QY2DiskUsageListItem( parent )
287  , _partitionDu( partitionDu )
288  , _pkgDiskUsageList( parent )
289 {
290  yuiDebug() << "disk usage list entry for " << partitionDu.dir << endl;
291 }
292 
293 
294 FSize
296 {
297  // the libzypp size is in KiB
298  return FSize( _partitionDu.pkg_size, FSize::Unit::K );
299 }
300 
301 
302 FSize
304 {
305  // the libzypp size is in KiB
306  return FSize( _partitionDu.total_size, FSize::Unit::K );
307 }
308 
309 
310 QString
312 {
313  return fromUTF8( _partitionDu.dir.c_str() );
314 }
315 
316 
317 void
318 YQPkgDiskUsageListItem::updateDuData( const ZyppPartitionDu & fromData )
319 {
320  _partitionDu = fromData;
321  updateData();
323 }
324 
325 
326 void
328 {
329  int percent = usedPercent();
330  // free size in MiB
331  boost::multiprecision::cpp_int free = freeSize().in_unit(FSize::Unit::M);
332 
333  yuiDebug() << "Partition " << _partitionDu.dir << " free percent: " <<
334  percent << "%, " << " free: " << freeSize() << " (" << free << "MiB)" << endl;
335 
336  if ( percent > MIN_PERCENT_WARN )
337  {
338  // Modern hard disks can be huge, so a warning based on percentage only
339  // can be misleading - check the absolute value, too.
340 
341  if ( free < MIN_FREE_MB_PROXIMITY )
342  _pkgDiskUsageList->runningOutWarning.enterProximity();
343 
344  if ( free < MIN_FREE_MB_WARN )
345  _pkgDiskUsageList->runningOutWarning.enterRange();
346  }
347 
348  if ( free < MIN_FREE_MB_PROXIMITY )
349  {
350  if ( percent > MIN_PERCENT_PROXIMITY )
351  _pkgDiskUsageList->runningOutWarning.enterProximity();
352  }
353 
354  if ( free < OVERFLOW_MB_WARN )
355  _pkgDiskUsageList->overflowWarning.enterRange();
356 
357  if ( free < OVERFLOW_MB_PROXIMITY )
358  _pkgDiskUsageList->overflowWarning.enterProximity();
359 }
360 
361 
362 
363 
364 
365 
367 {
368  clearHistory();
369 }
370 
371 
372 void
374 {
375  _inRange = false;
376  _hasBeenClose = _isClose;
377  _isClose = false;
378 }
379 
380 
381 void
383 {
384  clear();
385  _hasBeenClose = false;
386  _warningPosted = false;
387 }
388 
389 
390 void
392 {
393  _inRange = true;
394  enterProximity();
395 }
396 
397 
398 void
400 {
401  _isClose = true;
402  _hasBeenClose = true;
403 }
404 
405 
406 void
408 {
409  _warningPosted = true;
410 }
411 
412 
413 bool
415 {
416  return _inRange;
417 }
418 
419 
420 bool
422 {
423  return ! _isClose && ! _hasBeenClose;
424 }
425 
426 
427 bool
429 {
430  return _inRange && ! _warningPosted;
431 }
432 
433 
434 
435 
YQPkgWarningRangeNotifier overflowWarning
Warning range notifier about disk space overflow warning.
YQPkgDiskUsageListItem(YQPkgDiskUsageList *parent, const ZyppPartitionDu &partitionDu)
Constructor.
YQPkgDiskUsageList(QWidget *parent, int thresholdPercent=0)
Constructor.
static bool diskUsageWarning(const QString &message, int thresholdPercent, const QString &acceptButtonLabel, const QString &rejectButtonLabel=QString())
Static convenience method: Post a disk usage warning with text &#39;message&#39;, a list of partitions that a...
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.
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.