libyui-qt-pkg  2.47.2
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
203 YQPkgDiskUsageList::keyPressEvent( QKeyEvent * event )
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 
YQPkgDiskUsageListItem::totalSize
virtual FSize totalSize() const
The total size of this partition.
Definition: YQPkgDiskUsageList.cc:302
YQPkgWarningRangeNotifier::clear
void clear()
Clear the current values, i.e.
Definition: YQPkgDiskUsageList.cc:372
YQPkgWarningRangeNotifier::clearHistory
void clearHistory()
Clear everything, including all history values such as if a warning has been posted.
Definition: YQPkgDiskUsageList.cc:381
YQPkgDiskUsageList::sizeHint
virtual QSize sizeHint() const
Suggest reasonable default size.
Definition: YQPkgDiskUsageList.cc:180
YQPkgDiskUsageListItem::checkRemainingDiskSpace
void checkRemainingDiskSpace()
Check the remaining disk space of this partition based on percentage and absolute free MB.
Definition: YQPkgDiskUsageList.cc:326
YQPkgDiskUsageList::overflowWarning
YQPkgWarningRangeNotifier overflowWarning
Warning range notifier about disk space overflow warning.
Definition: YQPkgDiskUsageList.h:182
YQPkgWarningRangeNotifier::inRange
bool inRange() const
Check if the value is in range, i.e.
Definition: YQPkgDiskUsageList.cc:413
YQPkgDiskUsageListItem::YQPkgDiskUsageListItem
YQPkgDiskUsageListItem(YQPkgDiskUsageList *parent, const ZyppPartitionDu &partitionDu)
Constructor.
Definition: YQPkgDiskUsageList.cc:283
YQPkgDiskUsageList::keyPressEvent
virtual void keyPressEvent(QKeyEvent *ev)
Event handler for keyboard input - for debugging and testing.
Definition: YQPkgDiskUsageList.cc:202
YQPkgDiskUsageList::YQPkgDiskUsageList
YQPkgDiskUsageList(QWidget *parent, int thresholdPercent=0)
Constructor.
Definition: YQPkgDiskUsageList.cc:85
YQPkgDiskUsageListItem
Definition: YQPkgDiskUsageList.h:218
YQPkgDiskUsageListItem::name
virtual QString name() const
The name to display for this partition ( the mount point ).
Definition: YQPkgDiskUsageList.cc:310
YQPkgDiskUsageList::updateDiskUsage
void updateDiskUsage()
Update all statistical data in the list.
Definition: YQPkgDiskUsageList.cc:127
YQPkgDiskUsageList::runningOutWarning
YQPkgWarningRangeNotifier runningOutWarning
Warning range notifier about running out of disk space warning.
Definition: YQPkgDiskUsageList.h:177
YQPkgDiskUsageWarningDialog::diskUsageWarning
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 'message', a list of partitions that a...
Definition: YQPkgDiskUsageWarningDialog.cc:161
YQPkgWarningRangeNotifier::YQPkgWarningRangeNotifier
YQPkgWarningRangeNotifier()
Constructor.
Definition: YQPkgDiskUsageList.cc:365
YQPkgWarningRangeNotifier::needWarning
bool needWarning() const
Check if a warning should be posted, i.e.
Definition: YQPkgDiskUsageList.cc:427
YQPkgDiskUsageListItem::partitionDu
ZyppPartitionDu partitionDu() const
Returns the corresponding disk usage data.
Definition: YQPkgDiskUsageList.h:237
YQPkgDiskUsageList
List of disk usage of all attached partitions.
Definition: YQPkgDiskUsageList.h:148
YQPkgWarningRangeNotifier::enterRange
void enterRange()
Notification that the inner range is entered.
Definition: YQPkgDiskUsageList.cc:390
YQPkgDiskUsageListItem::usedSize
virtual FSize usedSize() const
The currently used size of this partition.
Definition: YQPkgDiskUsageList.cc:294
YQPkgWarningRangeNotifier::leavingProximity
bool leavingProximity() const
Check if the value is leaving the proximity range.
Definition: YQPkgDiskUsageList.cc:420
YQPkgWarningRangeNotifier::enterProximity
void enterProximity()
Notification that the proximity range is entered, i.e.
Definition: YQPkgDiskUsageList.cc:398
YQPkgDiskUsageListItem::updateDuData
void updateDuData(const ZyppPartitionDu &fromData)
Update the disk usage data.
Definition: YQPkgDiskUsageList.cc:317
YQPkgDiskUsageList::postPendingWarnings
void postPendingWarnings()
Post all pending disk space warnings based on the warning range notifiers.
Definition: YQPkgDiskUsageList.cc:153
YQPkgWarningRangeNotifier::warningPostedNotify
void warningPostedNotify()
Notification that a warning has been posted.
Definition: YQPkgDiskUsageList.cc:406