Fix minor unallocated space display issue in the Info dialog (#499202)

For specific partition usage values the right hand border of the
partition graphic in the Information dialog would be displayed as grey
rather than the color assigned to the partition.

Steps to reproduce fault:
    Create 1024 MiB partition
    # lvm pvcreate /dev/sda12
    # lvm vgcreate GParted-VG1 /dev/sda12
    View partition information

Fragment from Dialog_Partition_Info::init_drawingarea():
    139  else if ( partition .sector_usage_known() )
    140  {
    141          used        = Utils::round( ( 400 - BORDER *2 ) / ( dlength / partition .get_sectors_used()   ) ) ;
    142          unused      = Utils::round( ( 400 - BORDER *2 ) / ( dlength / partition .get_sectors_unused() ) ) ;
    143          unallocated = 400 - BORDER *2 - used - unused ;
    144  }

For this issue the above values are both exactly x.5 and both round
upwards, resulting in unallocated being -1.
    used        = round((400 - 8*2)/(2097152.0/8192))    = round(1.5)
    unused      = round((400 - 8*2)/(2097152.0/2088960)) = round(382.5)
    unallocated = 400 - 8*2 - 2 - 383 = -1

The simple fix would be to use floor() instead of round() in the
calculation of either used or unused.  The same fix would also need to
be applied in Display_Info() for the calculation of the percentage
figures.  Unfortunately this simple fix can lead to odd figures when the
used or unused is close to zero and floor() or ceil() is effectively
applied rather than round().  For example:
    Size:           227.23 GiB
    Used:           28.00 KiB   ( 1% )
    Unused:         180.00 GiB  ( 79% )
    Unallocated:    47.23 GiB   ( 20% )
Used figure of 28 KiB in 227 GiB partition should be rounded to 0% but
wasn't.

Write Partition::calc_usage_triple() which calculates the "best" figures
by rounding the smaller two figures and subtracts them from the desired
total for the largest figure.  Apply to the calculation of the partition
usage percentage figures in the Information dialog and the partition
usage graphic in the same dialog and the main window.

Bug #499202 - gparted does not see the difference if partition size
              differs from filesystem size
This commit is contained in:
Mike Fleetwood 2012-06-20 23:53:05 +01:00 committed by Curtis Gedak
parent 747d08f2e4
commit 67f334a8ac
4 changed files with 75 additions and 21 deletions

View File

@ -133,7 +133,11 @@ public:
Byte_Value sector_size ; //Sector size of the disk device needed for converting to/from sectors and bytes.
static void calc_usage_triple( double d1, double d2, double d3, int imax, int & i1, int & i2, int & i3 ) ;
private:
static void calc_usage_triple_helper( double dtot, double d1, double d2, double d3, int imax, int & i1, int & i2, int & i3 ) ;
void sort_paths_and_remove_duplicates() ;
Sector calc_significant_unallocated_sectors() const ;

View File

@ -127,8 +127,6 @@ void Dialog_Partition_Info::init_drawingarea()
this ->get_vbox() ->pack_start( *hbox, Gtk::PACK_SHRINK ) ;
//calculate proportional width of used, unused and unallocated
used = unused = unallocated = 0 ;
double dlength = static_cast<double>( partition .get_sector_length() ) ;
if ( partition .type == GParted::TYPE_EXTENDED )
{
//Specifically show extended partitions as unallocated
@ -138,9 +136,11 @@ void Dialog_Partition_Info::init_drawingarea()
}
else if ( partition .sector_usage_known() )
{
used = Utils::round( ( 400 - BORDER *2 ) / ( dlength / partition .get_sectors_used() ) ) ;
unused = Utils::round( ( 400 - BORDER *2 ) / ( dlength / partition .get_sectors_unused() ) ) ;
unallocated = 400 - BORDER *2 - used - unused ;
Partition::calc_usage_triple( partition .get_sectors_used(),
partition .get_sectors_unused(),
partition .get_sectors_unallocated(),
( 400 - BORDER *2 ),
used, unused, unallocated ) ;
}
else
{
@ -208,9 +208,9 @@ void Dialog_Partition_Info::Display_Info()
Sector unused = partition .get_sectors_unused() ;
Sector unallocated = partition .get_sectors_unallocated() ;
//calculate relative diskusage
int percent_unused = Utils::round( unused * 100.0 / ptn_sectors ) ;
int percent_unallocated = Utils::round( unallocated * 100.0 / ptn_sectors ) ;
int percent_used = 100 - percent_unallocated - percent_unused ;
int percent_used, percent_unused, percent_unallocated ;
Partition::calc_usage_triple( used, unused, unallocated, 100,
percent_used, percent_unused, percent_unallocated ) ;
//Used
table ->attach( * Utils::mk_label( "<b>" + Glib::ustring( _("Used:") ) + "</b>" ),

View File

@ -183,24 +183,25 @@ void DrawingAreaVisualDisk::calc_usage( std::vector<visual_partition> & visual_p
{
if ( visual_partitions[ t ] .fraction_used >= 0.0 )
{
int inner_length = visual_partitions[ t ] .length - BORDER *2 ;
Partition::calc_usage_triple( visual_partitions[ t ] .fraction_used,
1.0 - visual_partitions[ t ] .fraction_used
- visual_partitions[ t ] .fraction_unallocated,
visual_partitions[ t ] .fraction_unallocated,
visual_partitions[ t ] .length - BORDER *2,
visual_partitions[ t ] .used_length,
visual_partitions[ t ] .unused_length,
visual_partitions[ t ] .unallocated_length ) ;
//used
visual_partitions[ t ] .used_length = Utils::round( inner_length * visual_partitions[ t ] .fraction_used ) ;
visual_partitions[ t ] .x_used_start = visual_partitions[ t ] .x_start + BORDER ;
//unallocated
visual_partitions[ t ] .unallocated_length = Utils::round( inner_length * visual_partitions[ t ] .fraction_unallocated ) ;
visual_partitions[ t ] .x_unallocated_start = visual_partitions[ t ] .x_start
+ visual_partitions[ t ] .length
- BORDER
- visual_partitions[ t ] .unallocated_length ;
//unused
visual_partitions[ t ] .unused_length = inner_length
- visual_partitions[ t ] .used_length
- visual_partitions[ t ] .unallocated_length ;
visual_partitions[ t ] .x_unused_start = visual_partitions[ t ] .x_used_start + visual_partitions[ t ] .used_length ;
visual_partitions[ t ] .x_unused_start = visual_partitions[ t ] .x_used_start
+ visual_partitions[ t ] .used_length ;
//unallocated
visual_partitions[ t ] .x_unallocated_start = visual_partitions[ t ] .x_unused_start
+ visual_partitions[ t ] .unused_length ;
//y position and height
visual_partitions[ t ] .y_usage_start = visual_partitions[ t ] .y_start + BORDER ;

View File

@ -262,6 +262,55 @@ bool Partition::operator!=( const Partition & partition ) const
return ! ( *this == partition ) ;
}
//Calculate the "best" display integers (pixels or percentages) from
// partition usage figures. Rounds the smaller two figures and then
// subtracts them from the desired total for the largest figure.
void Partition::calc_usage_triple( double d1, double d2, double d3, int imax, int & i1, int & i2, int & i3 )
{
if ( d1 < 0.0 ) d1 = 0.0 ;
if ( d2 < 0.0 ) d2 = 0.0 ;
if ( d3 < 0.0 ) d3 = 0.0 ;
double dtot = d1 + d2 + d3 ;
if ( d1 <= d2 && d1 <= d3 )
calc_usage_triple_helper( dtot, d1, d2, d3, imax, i1, i2, i3 ) ;
else if ( d2 < d1 && d2 <= d3 )
calc_usage_triple_helper( dtot, d2, d1, d3, imax, i2, i1, i3 ) ;
else if ( d3 < d1 && d3 < d2 )
calc_usage_triple_helper( dtot, d3, d1, d2, imax, i3, i1, i2 ) ;
}
//Calculate the "best" display integers when d1 <= d2 and d1 <= d3.
// Ensure i1 <= i2 and i1 <= i3.
void Partition::calc_usage_triple_helper( double dtot, double d1, double d2, double d3, int imax, int & i1, int & i2, int & i3 )
{
int t ;
i1 = Utils::round( d1 / dtot * imax ) ;
if ( d2 <= d3 )
{
i2 = Utils::round( d2 / dtot * imax ) ;
i3 = imax - i1 - i2 ;
if ( i1 > i3 )
{
// i1 rounded up making it larger than i3. Swap i1 with i3.
t = i1 ;
i1 = i3 ;
i3 = t ;
}
}
else
{
i3 = Utils::round( d3 / dtot * imax ) ;
i2 = imax - i1 - i3 ;
if ( i1 > i2 )
{
// i1 rounded up making it larger than i2. Swap i1 with i2.
t = i1 ;
i1 = i2 ;
i2 = t ;
}
}
}
void Partition::sort_paths_and_remove_duplicates()
{
//remove duplicates