[gparted] Make support of naming for other partition table types possible (#746214)



commit 9b2c95bcd176e8507758811e64e56ed7655a3b1e
Author: Mike Fleetwood <mike fleetwood googlemail com>
Date:   Fri Mar 13 22:36:08 2015 +0000

    Make support of naming for other partition table types possible (#746214)
    
    Previously partition naming had only been implemented for gpt.  Make the
    code ready to support naming of the other partition table types for
    which libparted supports naming.  Specifically: amiga, dvh, mac and
    pc98 in addition to gpt.  Document issues found with some of these
    partition table types, which can relatively easily been worked around.
    
    Leave support of naming for partition table types other than gpt
    disabled, mostly just to reduce ongoing testing effort, at least until
    there is any user demand for it.
    
    Bug 746214 - Partition naming enhancements

 include/Device.h                |    8 ++++--
 include/Dialog_Partition_Name.h |    2 +-
 include/Utils.h                 |    1 +
 src/Device.cc                   |   20 +++++++++++++++++-
 src/Dialog_Partition_Name.cc    |   16 +++++++-------
 src/GParted_Core.cc             |   11 +++++----
 src/Utils.cc                    |   43 +++++++++++++++++++++++++++++++++++++++
 src/Win_GParted.cc              |    9 ++++---
 8 files changed, 88 insertions(+), 22 deletions(-)
---
diff --git a/include/Device.h b/include/Device.h
index 4939494..233923e 100644
--- a/include/Device.h
+++ b/include/Device.h
@@ -34,7 +34,10 @@ public:
        void add_paths( const std::vector<Glib::ustring> & paths, bool clear_paths = false ) ;
        Glib::ustring get_path() const ;
        std::vector<Glib::ustring> get_paths() const ;
-       
+       void enable_partition_naming( int length );  // > 0 => enable partition naming support
+       bool partition_naming_supported() const;
+       int get_max_partition_name_length() const;
+
        bool operator==( const Device & device ) const ;
        bool operator!=( const Device & device ) const ;
        
@@ -51,7 +54,6 @@ public:
        int max_prims ;
        int highest_busy ;
        bool readonly ; 
-       bool partition_naming;  // Is naming of partitions supported on this device?
 
 private:
        void sort_paths_and_remove_duplicates() ;
@@ -59,7 +61,7 @@ private:
        static bool compare_paths( const Glib::ustring & A, const Glib::ustring & B ) ;
        
        std::vector<Glib::ustring> paths ;
-               
+       int max_partition_name_length;  // > 0 => naming of partitions is supported on this device
 };
  
 } //GParted
diff --git a/include/Dialog_Partition_Name.h b/include/Dialog_Partition_Name.h
index 3e5f48e..d671fd3 100644
--- a/include/Dialog_Partition_Name.h
+++ b/include/Dialog_Partition_Name.h
@@ -31,7 +31,7 @@ namespace GParted
 class Dialog_Partition_Name: public Gtk::Dialog
 {
 public:
-       Dialog_Partition_Name( const Partition & partition );
+       Dialog_Partition_Name( const Partition & partition, int max_length );
        ~Dialog_Partition_Name();
        Glib::ustring get_new_name();
 
diff --git a/include/Utils.h b/include/Utils.h
index a26e17d..573d1cd 100644
--- a/include/Utils.h
+++ b/include/Utils.h
@@ -173,6 +173,7 @@ public:
        static Glib::ustring num_to_str( Sector number ) ;
        static Glib::ustring get_color( FILESYSTEM filesystem ) ;
        static Glib::RefPtr<Gdk::Pixbuf> get_color_as_pixbuf( FILESYSTEM filesystem, int width, int height ) ;
+       static int get_max_partition_name_length( Glib::ustring & tabletype );
        static int get_filesystem_label_maxlength( FILESYSTEM filesystem ) ;
        static Glib::ustring get_filesystem_string( FILESYSTEM filesystem ) ;
        static const Glib::ustring get_filesystem_kernel_name( FILESYSTEM fstype );
diff --git a/src/Device.cc b/src/Device.cc
index 797f2cb..9ce6e3c 100644
--- a/src/Device.cc
+++ b/src/Device.cc
@@ -32,9 +32,9 @@ void Device::Reset()
        length = cylsize = 0 ;
        heads = sectors = cylinders = 0 ;
        model = disktype = "" ;
-       partition_naming = false;
        sector_size = max_prims = highest_busy = 0 ;
        readonly = false ;      
+       max_partition_name_length = 0;
 }
        
 void Device::add_path( const Glib::ustring & path, bool clear_paths )
@@ -70,6 +70,24 @@ std::vector<Glib::ustring> Device::get_paths() const
        return paths ;
 }
 
+void Device::enable_partition_naming( int max_length )
+{
+       if ( max_length > 0 )
+               max_partition_name_length = max_length;
+       else
+               max_partition_name_length = 0;
+}
+
+bool Device::partition_naming_supported() const
+{
+       return max_partition_name_length > 0;
+}
+
+int Device::get_max_partition_name_length() const
+{
+       return max_partition_name_length;
+}
+
 bool Device::operator==( const Device & device ) const
 {
        return this ->get_path() == device .get_path() ;
diff --git a/src/Dialog_Partition_Name.cc b/src/Dialog_Partition_Name.cc
index f89bf44..46abcae 100644
--- a/src/Dialog_Partition_Name.cc
+++ b/src/Dialog_Partition_Name.cc
@@ -19,13 +19,7 @@
 namespace GParted
 {
 
-// NOTE: Limiting the Gtk::Entry to 36 UTF-8 characters doesn't guarantee that the
-// partition name won't be too long as GPT works in UTF-16LE code units.  Therefore
-// any character taking more that 1 UTF-16LE code unit won't be correctly counted.
-//     http://en.wikipedia.org/wiki/GUID_Partition_Table#Partition_entries
-static const int GPT_NAME_LENGTH = 36;
-
-Dialog_Partition_Name::Dialog_Partition_Name( const Partition & partition )
+Dialog_Partition_Name::Dialog_Partition_Name( const Partition & partition, int max_length )
 {
        this->set_resizable( false );
        this->set_has_separator( false );
@@ -49,7 +43,13 @@ Dialog_Partition_Name::Dialog_Partition_Name( const Partition & partition )
                               Gtk::FILL );
                // Create text entry box
                entry = manage( new Gtk::Entry() );
-               entry->set_max_length( GPT_NAME_LENGTH ) ;
+
+               // NOTE: This limits the Gtk::Entry size in UTF-8 characters but partition
+               // names are defined in terms of ASCII characters, or for GPT, UTF-16LE
+               // code points.  See Utils::get_max_partition_name_length().  So for
+               // certain extended characters this limit will be too generous.
+               entry->set_max_length( max_length );
+
                entry->set_width_chars( 20 );
                entry->set_activates_default( true );
                entry->set_text( partition.name );
diff --git a/src/GParted_Core.cc b/src/GParted_Core.cc
index 4733619..f4998b1 100644
--- a/src/GParted_Core.cc
+++ b/src/GParted_Core.cc
@@ -337,10 +337,11 @@ void GParted_Core::set_devices_thread( std::vector<Device> * pdevices )
                                temp_device .max_prims = ped_disk_get_max_primary_partition_count( lp_disk ) ;
 
                                // Determine if partition naming is supported.
-                               temp_device.partition_naming = ped_disk_type_check_feature( lp_disk->type,
-                                                                                           
PED_DISK_TYPE_PARTITION_NAME );
-                               // So far only GPTs are supported.
-                               temp_device.partition_naming &= ( temp_device.disktype == "gpt" );
+                               if ( ped_disk_type_check_feature( lp_disk->type, PED_DISK_TYPE_PARTITION_NAME 
) )
+                               {
+                                       temp_device.enable_partition_naming(
+                                                       Utils::get_max_partition_name_length( 
temp_device.disktype ) );
+                               }
 
                                set_device_partitions( temp_device, lp_device, lp_disk ) ;
                                set_mountpoints( temp_device .partitions ) ;
@@ -1265,7 +1266,7 @@ void GParted_Core::set_device_partitions( Device & device, PedDevice* lp_device,
                        set_partition_label_and_uuid( partition_temp );
 
                        // Retrieve partition name
-                       if ( device.partition_naming )
+                       if ( device.partition_naming_supported() )
                                partition_temp.name = Glib::ustring( ped_partition_get_name( lp_partition ) );
                }
 
diff --git a/src/Utils.cc b/src/Utils.cc
index f190688..b699683 100644
--- a/src/Utils.cc
+++ b/src/Utils.cc
@@ -129,6 +129,49 @@ Glib::RefPtr<Gdk::Pixbuf> Utils::get_color_as_pixbuf( FILESYSTEM filesystem, int
        return pixbuf ;
 }
 
+int Utils::get_max_partition_name_length( Glib::ustring & tabletype )
+{
+       // Partition name size found or confirmed by looking at *_partition_set_name()
+       // functions in the relevant libparted label modules:
+       //     dvh.c, gpt.c, mac.c, pc98.c, rdb.c (amiga)
+       // http://git.savannah.gnu.org/cgit/parted.git/tree/libparted/labels
+       //
+       //     Table   Max      Units
+       //     type    length   Reference
+       //     -----   ------   ---------
+       //     amiga       32   ASCII characters
+       //     dvh          8   ASCII characters
+       //     gpt         36   UTF-16LE code points
+       //                      http://en.wikipedia.org/wiki/GUID_Partition_Table#Partition_entries
+       //     mac         32   ASCII characters
+       //                      http://en.wikipedia.org/wiki/Apple_Partition_Map#Layout
+       //     pc98        16   ASCII characters
+       //
+       // Found issues:
+       // 1) amiga - Setting partition name to 32 chars is silent ignored.  Setting to 31
+       //            chars or less works.
+       // 2) dvh   - Probably by design, setting names on primary partitions is
+       //            successfully ignored with this libparted message:
+       //                failed to set dvh partition name to NAME:
+       //                Only logical partitions (boot files) have a name.
+       //            Setting names on logical partitions works.
+       // 3) mac   - Setting partition name to 32 chars core dumps in libparted.  Setting
+       //            to 31 chars or less works.
+       //
+       // Suspect usage of these partition tables types other than GPT is *VERY* low.
+       // Given the above issues which need a little coding around, leave support of
+       // naming for partition table types other than GPT disabled.  Mostly just to
+       // reduce ongoing testing effort, at least until there is any user demand for it.
+
+       if      ( tabletype == "amiga" ) return 0;   // Disabled
+       else if ( tabletype == "dvh"   ) return 0;   // Disabled
+       else if ( tabletype == "gpt"   ) return 36;
+       else if ( tabletype == "mac"   ) return 0;   // Disabled
+       else if ( tabletype == "pc98"  ) return 0;   // Disabled
+
+       return 0;
+}
+
 int Utils::get_filesystem_label_maxlength( FILESYSTEM filesystem )
 {
        switch( filesystem )
diff --git a/src/Win_GParted.cc b/src/Win_GParted.cc
index b8dbfbf..aff560d 100644
--- a/src/Win_GParted.cc
+++ b/src/Win_GParted.cc
@@ -1019,9 +1019,9 @@ void Win_GParted::set_valid_operations()
                allow_toggle_busy_state( true ) ;
 
        // Allow naming on devices that support it
-       if ( selected_partition.type != TYPE_UNALLOCATED &&
-            selected_partition.status == STAT_REAL      &&
-            devices[current_device].partition_naming       )
+       if ( selected_partition.type != TYPE_UNALLOCATED          &&
+            selected_partition.status == STAT_REAL               &&
+            devices[current_device].partition_naming_supported()    )
                allow_name_partition( true );
 
        // Manage flags
@@ -2563,7 +2563,8 @@ void Win_GParted::activate_label_filesystem()
 
 void Win_GParted::activate_name_partition()
 {
-       Dialog_Partition_Name dialog( selected_partition );
+       Dialog_Partition_Name dialog( selected_partition,
+                                     devices[current_device].get_max_partition_name_length() );
        dialog.set_transient_for( *this );
 
        if (    ( dialog.run() == Gtk::RESPONSE_OK )


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