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



commit 67f334a8ac90efab662bf91b3ada49c0010c6dd3
Author: Mike Fleetwood <mike fleetwood googlemail com>
Date:   Wed Jun 20 23:53:05 2012 +0100

    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 6c663ff..dc53d88 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 5d4b8a8..9d2c003 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<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>" ),
diff --git a/src/DrawingAreaVisualDisk.cc b/src/DrawingAreaVisualDisk.cc
index 6f58b05..75bd854 100644
--- a/src/DrawingAreaVisualDisk.cc
+++ b/src/DrawingAreaVisualDisk.cc
@@ -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 ;
diff --git a/src/Partition.cc b/src/Partition.cc
index faf648c..6b36c2e 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



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]