From 67f334a8ac90efab662bf91b3ada49c0010c6dd3 Mon Sep 17 00:00:00 2001 From: Mike Fleetwood Date: Wed, 20 Jun 2012 23:53:05 +0100 Subject: [PATCH] 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 --- include/Partition.h | 4 +++ src/Dialog_Partition_Info.cc | 16 ++++++------ src/DrawingAreaVisualDisk.cc | 27 ++++++++++---------- src/Partition.cc | 49 ++++++++++++++++++++++++++++++++++++ 4 files changed, 75 insertions(+), 21 deletions(-) diff --git a/include/Partition.h b/include/Partition.h index 6c663ff6..dc53d88b 100644 --- a/include/Partition.h +++ b/include/Partition.h @@ -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 ; diff --git a/src/Dialog_Partition_Info.cc b/src/Dialog_Partition_Info.cc index 5d4b8a87..9d2c003b 100644 --- a/src/Dialog_Partition_Info.cc +++ b/src/Dialog_Partition_Info.cc @@ -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( 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( "" + Glib::ustring( _("Used:") ) + "" ), diff --git a/src/DrawingAreaVisualDisk.cc b/src/DrawingAreaVisualDisk.cc index 6f58b057..75bd854d 100644 --- a/src/DrawingAreaVisualDisk.cc +++ b/src/DrawingAreaVisualDisk.cc @@ -183,24 +183,25 @@ void DrawingAreaVisualDisk::calc_usage( std::vector & 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 ; diff --git a/src/Partition.cc b/src/Partition.cc index faf648ca..6b36c2e9 100644 --- a/src/Partition.cc +++ b/src/Partition.cc @@ -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