[gparted] Add support for GPT partition names (#741424)



commit 1f5841b4adc44be7f41d7a3e155774a464a49d2b
Author: Michael Zimmermann <sigmaepsilon92 gmail com>
Date:   Fri Dec 12 08:00:02 2014 +0100

    Add support for GPT partition names (#741424)
    
    Embedded devices (Android) use GPT partition names to identify
    partitions, instead of file system labels.  Add support for viewing and
    changing them.
    
    As partition names are used to provide unique identification they are
    never copied when copying the contents of one partition to another.
    
    Note that GNU/Linux uses file system labels, UUIDs or device names for
    identification during the boot process and afterwards so while partition
    names can be used, they are optional and purely for user information.
    
    Bug 741424 - Add support for GPT partition names

 include/Device.h                 |    3 +-
 include/Dialog_Partition_Name.h  |   44 +++++++++++++++++++++
 include/GParted_Core.h           |    2 +
 include/Makefile.am              |    2 +
 include/Operation.h              |    3 +-
 include/OperationNamePartition.h |   40 +++++++++++++++++++
 include/Partition.h              |    1 +
 include/TreeView_Detail.h        |   10 +++--
 include/Win_GParted.h            |    5 ++
 po/POTFILES.in                   |    2 +
 src/Device.cc                    |    1 +
 src/Dialog_Partition_Info.cc     |   10 +++++
 src/Dialog_Partition_Name.cc     |   79 ++++++++++++++++++++++++++++++++++++++
 src/GParted_Core.cc              |   42 ++++++++++++++++++++
 src/Makefile.am                  |    2 +
 src/OperationNamePartition.cc    |   71 ++++++++++++++++++++++++++++++++++
 src/Partition.cc                 |    1 +
 src/TreeView_Detail.cc           |   55 +++++++++++++++-----------
 src/Win_GParted.cc               |   69 +++++++++++++++++++++++++++++++--
 19 files changed, 409 insertions(+), 33 deletions(-)
---
diff --git a/include/Device.h b/include/Device.h
index b948284..4939494 100644
--- a/include/Device.h
+++ b/include/Device.h
@@ -51,7 +51,8 @@ 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() ;
 
diff --git a/include/Dialog_Partition_Name.h b/include/Dialog_Partition_Name.h
new file mode 100644
index 0000000..3e5f48e
--- /dev/null
+++ b/include/Dialog_Partition_Name.h
@@ -0,0 +1,44 @@
+/* Copyright (C) 2015 Michael Zimmermann
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GPARTED_DIALOG_PARTITION_NAME_H
+#define GPARTED_DIALOG_PARTITION_NAME_H
+
+#include "../include/Partition.h"
+#include "../include/i18n.h"
+
+#include <gtkmm/dialog.h>
+#include <gtkmm/stock.h>
+#include <gtkmm/table.h>
+#include <gtkmm/entry.h>
+
+namespace GParted
+{
+
+class Dialog_Partition_Name: public Gtk::Dialog
+{
+public:
+       Dialog_Partition_Name( const Partition & partition );
+       ~Dialog_Partition_Name();
+       Glib::ustring get_new_name();
+
+private:
+       Gtk::Entry *entry;
+};
+
+} //GParted
+
+#endif /* GPARTED_DIALOG_PARTITION_NAME_H */
diff --git a/include/GParted_Core.h b/include/GParted_Core.h
index dfb37ed..819cfdf 100644
--- a/include/GParted_Core.h
+++ b/include/GParted_Core.h
@@ -111,6 +111,8 @@ private:
 
        bool label_filesystem( const Partition & partition, OperationDetail & operationdetail );
 
+       bool name_partition( const Partition & partition, OperationDetail & operationdetail );
+
        bool change_uuid( const Partition & partition, OperationDetail & operation_detail ) ;
 
        bool resize_move( const Device & device,
diff --git a/include/Makefile.am b/include/Makefile.am
index 6ecd054..4b00f1c 100644
--- a/include/Makefile.am
+++ b/include/Makefile.am
@@ -11,6 +11,7 @@ EXTRA_DIST = \
        Dialog_FileSystem_Label.h       \
        Dialog_Partition_Copy.h         \
        Dialog_Partition_Info.h         \
+       Dialog_Partition_Name.h         \
        Dialog_Partition_New.h          \
        Dialog_Partition_Resize_Move.h  \
        Dialog_Progress.h               \
@@ -32,6 +33,7 @@ EXTRA_DIST = \
        OperationDetail.h               \
        OperationFormat.h               \
        OperationLabelFileSystem.h      \
+       OperationNamePartition.h        \
        OperationResizeMove.h           \
        Partition.h                     \
        PipeCapture.h                   \
diff --git a/include/Operation.h b/include/Operation.h
index 247a0a4..a377a2c 100644
--- a/include/Operation.h
+++ b/include/Operation.h
@@ -32,7 +32,8 @@ enum OperationType {
        OPERATION_FORMAT           = 4,
        OPERATION_COPY             = 5,
        OPERATION_LABEL_FILESYSTEM = 6,
-       OPERATION_CHANGE_UUID      = 7
+       OPERATION_CHANGE_UUID      = 7,
+       OPERATION_NAME_PARTITION   = 8
 };
 
 class Operation
diff --git a/include/OperationNamePartition.h b/include/OperationNamePartition.h
new file mode 100644
index 0000000..955fbaf
--- /dev/null
+++ b/include/OperationNamePartition.h
@@ -0,0 +1,40 @@
+/* Copyright (C) 2015 Michael Zimmermann
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GPARTED_OPERATIONNAMEPARTITION_H
+#define GPARTED_OPERATIONNAMEPARTITION_H
+
+#include "../include/Operation.h"
+
+namespace GParted
+{
+
+class OperationNamePartition: public Operation
+{
+public:
+       OperationNamePartition( const Device & device,
+                               const Partition & partition_orig,
+                               const Partition & partition_new );
+
+       void apply_to_visual( std::vector<Partition> & partitions );
+
+private:
+       void create_description();
+};
+
+} //GParted
+
+#endif /* GPARTED_OPERATIONNAMEPARTITION_H */
diff --git a/include/Partition.h b/include/Partition.h
index 4b32e1f..132b709 100644
--- a/include/Partition.h
+++ b/include/Partition.h
@@ -116,6 +116,7 @@ public:
        PartitionAlignment alignment;   //ALIGN_CYLINDER, ALIGN_STRICT, etc
        FILESYSTEM filesystem ;
        Glib::ustring uuid ;
+       Glib::ustring name;
        Sector sector_start;
        Sector sector_end;
        Sector sectors_used;
diff --git a/include/TreeView_Detail.h b/include/TreeView_Detail.h
index 0097b6a..24d1cb4 100644
--- a/include/TreeView_Detail.h
+++ b/include/TreeView_Detail.h
@@ -46,9 +46,10 @@ public:
 
 private:
        void load_partitions( const std::vector<Partition> & partitions,
-                             bool & mountpoints,
-                             bool & labels,
-                             const Gtk::TreeRow & parent_row = Gtk::TreeRow() ) ;
+                             bool & mountpoints,
+                             bool & labels,
+                             bool & names,
+                             const Gtk::TreeRow & parent_row = Gtk::TreeRow() );
        bool set_selected( Gtk::TreeModel::Children rows, const Partition & partition, bool inside_extended = 
false ) ;
        void create_row( const Gtk::TreeRow & treerow, const Partition & partition );
 
@@ -66,6 +67,7 @@ private:
        struct treeview_detail_Columns : public Gtk::TreeModelColumnRecord             
        {
                Gtk::TreeModelColumn<Glib::ustring> path;
+               Gtk::TreeModelColumn<Glib::ustring> name;
                Gtk::TreeModelColumn<Glib::ustring> filesystem;
                Gtk::TreeModelColumn<Glib::ustring> mountpoint;
                Gtk::TreeModelColumn<Glib::ustring> label ;
@@ -82,7 +84,7 @@ private:
                
                treeview_detail_Columns()
                {
-                       add( path ); add( filesystem ); add( mountpoint ) ; add( label ) ;
+                       add( path ); add( name ); add( filesystem ); add( mountpoint ); add( label );
                        add( size ); add( used ); add( unused ); add( color );
                        add( text_color ); add( mount_text_color ); add( icon1 );
                        add( icon2 ) ; add( flags ); add( partition );
diff --git a/include/Win_GParted.h b/include/Win_GParted.h
index 0c3275d..da341cd 100644
--- a/include/Win_GParted.h
+++ b/include/Win_GParted.h
@@ -106,6 +106,9 @@ private:
        void allow_label_filesystem( bool state ) {
                toggle_item( state, MENU_LABEL_PARTITION ) ; } 
 
+       void allow_name_partition( bool state ) {
+               toggle_item( state, MENU_NAME_PARTITION ); }
+
        void allow_change_uuid( bool state )    {
                toggle_item( state, MENU_CHANGE_UUID ) ; }
 
@@ -169,6 +172,7 @@ private:
        void activate_check() ;
        void activate_change_uuid() ;
        void activate_label_filesystem();
+       void activate_name_partition();
 
        void activate_undo();
        void remove_operation( int index = -1, bool remove_all = false ) ;
@@ -236,6 +240,7 @@ private:
         MENU_FORMAT,
         MENU_TOGGLE_BUSY,
         MENU_MOUNT,
+       MENU_NAME_PARTITION,
         MENU_FLAGS,
         MENU_CHECK,
        MENU_LABEL_PARTITION,
diff --git a/po/POTFILES.in b/po/POTFILES.in
index cf5ca7f..38bf0f6 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -9,6 +9,7 @@ src/Dialog_Disklabel.cc
 src/Dialog_FileSystem_Label.cc
 src/Dialog_Partition_Copy.cc
 src/Dialog_Partition_Info.cc
+src/Dialog_Partition_Name.cc
 src/Dialog_Partition_New.cc
 src/Dialog_Partition_Resize_Move.cc
 src/Dialog_Progress.cc
@@ -27,6 +28,7 @@ src/OperationCreate.cc
 src/OperationDelete.cc
 src/OperationFormat.cc
 src/OperationLabelFileSystem.cc
+src/OperationNamePartition.cc
 src/OperationResizeMove.cc
 src/Partition.cc
 src/TreeView_Detail.cc
diff --git a/src/Device.cc b/src/Device.cc
index a24e249..797f2cb 100644
--- a/src/Device.cc
+++ b/src/Device.cc
@@ -32,6 +32,7 @@ void Device::Reset()
        length = cylsize = 0 ;
        heads = sectors = cylinders = 0 ;
        model = disktype = "" ;
+       partition_naming = false;
        sector_size = max_prims = highest_busy = 0 ;
        readonly = false ;      
 }
diff --git a/src/Dialog_Partition_Info.cc b/src/Dialog_Partition_Info.cc
index 79a49c7..f76c5f2 100644
--- a/src/Dialog_Partition_Info.cc
+++ b/src/Dialog_Partition_Info.cc
@@ -512,6 +512,16 @@ void Dialog_Partition_Info::Display_Info()
 
        if ( partition .type != GParted::TYPE_UNALLOCATED && partition .status != GParted::STAT_NEW )
        {
+               // name
+               table->attach( * Utils::mk_label( "<b>" + Glib::ustring( _("Name:") ) + "</b>"),
+                              1, 2,
+                              top, bottom,
+                              Gtk::FILL );
+               table->attach( * Utils::mk_label( partition.name, true, false, true ),
+                              2, 3,
+                              top++, bottom++,
+                              Gtk::FILL );
+
                // flags
                table->attach( * Utils::mk_label( "<b>" + Glib::ustring( _("Flags:") ) + "</b>" ),
                               1, 2,
diff --git a/src/Dialog_Partition_Name.cc b/src/Dialog_Partition_Name.cc
new file mode 100644
index 0000000..f89bf44
--- /dev/null
+++ b/src/Dialog_Partition_Name.cc
@@ -0,0 +1,79 @@
+/* Copyright (C) 2015 Michael Zimmermann
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "../include/Dialog_Partition_Name.h"
+
+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 )
+{
+       this->set_resizable( false );
+       this->set_has_separator( false );
+       this->set_size_request( 300, 80 );
+
+       /* TO TRANSLATORS: dialog title, looks like   Set partition name on /dev/hda3 */
+       this->set_title( String::ucompose( _("Set partition name on %1"), partition.get_path() ) );
+
+       {
+               int top = 0, bottom = 1;
+
+               // Create table to hold name and entry box
+               Gtk::Table *table( manage( new Gtk::Table() ) );
+
+               table->set_border_width( 5 );
+               table->set_col_spacings( 10 );
+               get_vbox()->pack_start( *table, Gtk::PACK_SHRINK );
+               table->attach( *Utils::mk_label( "<b>" + Glib::ustring(_("Name:")) + "</b>" ),
+                              0, 1,
+                              top, bottom,
+                              Gtk::FILL );
+               // Create text entry box
+               entry = manage( new Gtk::Entry() );
+               entry->set_max_length( GPT_NAME_LENGTH ) ;
+               entry->set_width_chars( 20 );
+               entry->set_activates_default( true );
+               entry->set_text( partition.name );
+               entry->select_region( 0, entry->get_text_length() );
+               // Add entry box to table
+               table->attach( *entry,
+                              1, 2,
+                              top++, bottom++,
+                              Gtk::FILL );
+       }
+
+       this->add_button( Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL );
+       this->add_button( Gtk::Stock::OK, Gtk::RESPONSE_OK );
+       this->set_default_response( Gtk::RESPONSE_OK );
+       this->show_all_children() ;
+}
+
+Dialog_Partition_Name::~Dialog_Partition_Name()
+{
+}
+
+Glib::ustring Dialog_Partition_Name::get_new_name()
+{
+       return Utils::trim( Glib::ustring( entry->get_text() ) );
+}
+
+} //GParted
diff --git a/src/GParted_Core.cc b/src/GParted_Core.cc
index 07850b7..3f8b45b 100644
--- a/src/GParted_Core.cc
+++ b/src/GParted_Core.cc
@@ -27,6 +27,7 @@
 #include "../include/OperationResizeMove.h"
 #include "../include/OperationChangeUUID.h"
 #include "../include/OperationLabelFileSystem.h"
+#include "../include/OperationNamePartition.h"
 #include "../include/Proc_Partitions_Info.h"
 
 #include "../include/btrfs.h"
@@ -314,6 +315,12 @@ void GParted_Core::set_devices_thread( std::vector<Device> * pdevices )
                                temp_device .disktype = lp_disk ->type ->name ;
                                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" );
+
                                set_device_partitions( temp_device, lp_device, lp_disk ) ;
                                set_mountpoints( temp_device .partitions ) ;
                                set_used_sectors( temp_device .partitions, lp_disk ) ;
@@ -730,6 +737,9 @@ bool GParted_Core::apply_operation_to_disk( Operation * operation )
                        case OPERATION_LABEL_FILESYSTEM:
                                succes = label_filesystem( operation->partition_new, 
operation->operation_detail );
                                break ;
+                       case OPERATION_NAME_PARTITION:
+                               succes = name_partition( operation->partition_new, 
operation->operation_detail );
+                               break;
                        case OPERATION_CHANGE_UUID:
                                succes = change_uuid( operation ->partition_new, operation ->operation_detail 
) ;
                                break ;
@@ -1188,6 +1198,10 @@ void GParted_Core::set_device_partitions( Device & device, PedDevice* lp_device,
                        {
                                read_uuid( partition_temp ) ;
                        }
+
+                       // Retrieve partition name
+                       if ( device.partition_naming )
+                               partition_temp.name = Glib::ustring( ped_partition_get_name( lp_partition ) );
                }
 
                partition_temp .messages .insert( partition_temp .messages .end(),
@@ -2101,6 +2115,34 @@ bool GParted_Core::label_filesystem( const Partition & partition, OperationDetai
        return succes ; 
 }
 
+bool GParted_Core::name_partition( const Partition & partition, OperationDetail & operationdetail )
+{
+       if ( partition.name.empty() )
+               operationdetail.add_child( OperationDetail(
+                               String::ucompose( _("Clear partition name on %1"), partition.get_path() ) ) );
+       else
+               operationdetail.add_child( OperationDetail(
+                               String::ucompose( _("Set partition name to \"%1\" on %2"),
+                                                 partition.name, partition.get_path() ) ) );
+
+       bool success = false;
+       PedDevice *lp_device = NULL;
+       PedDisk *lp_disk = NULL;
+       if ( get_device_and_disk( partition.device_path, lp_device, lp_disk ) )
+       {
+               PedPartition *lp_partition = ped_disk_get_partition_by_sector( lp_disk, 
partition.get_sector() );
+               if ( lp_partition )
+               {
+                       success =    ped_partition_set_name( lp_partition, partition.name.c_str() )
+                                 && commit( lp_disk );
+               }
+       }
+
+       operationdetail.get_last_child().set_status( success ? STATUS_SUCCES : STATUS_ERROR );
+
+       return success;
+}
+
 bool GParted_Core::change_uuid( const Partition & partition, OperationDetail & operationdetail )
 {
        if ( partition .uuid == UUID_RANDOM_NTFS_HALF ) {
diff --git a/src/Makefile.am b/src/Makefile.am
index b1f0764..cd11213 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -22,6 +22,7 @@ gpartedbin_SOURCES = \
        Dialog_FileSystem_Label.cc      \
        Dialog_Partition_Copy.cc        \
        Dialog_Partition_Info.cc        \
+       Dialog_Partition_Name.cc        \
        Dialog_Partition_New.cc         \
        Dialog_Partition_Resize_Move.cc \
        Dialog_Progress.cc              \
@@ -43,6 +44,7 @@ gpartedbin_SOURCES = \
        OperationDetail.cc              \
        OperationFormat.cc              \
        OperationLabelFileSystem.cc     \
+       OperationNamePartition.cc       \
        OperationResizeMove.cc          \
        Partition.cc                    \
        PipeCapture.cc                  \
diff --git a/src/OperationNamePartition.cc b/src/OperationNamePartition.cc
new file mode 100644
index 0000000..c206628
--- /dev/null
+++ b/src/OperationNamePartition.cc
@@ -0,0 +1,71 @@
+/* Copyright (C) 2015 Michael Zimmermann
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "../include/OperationNamePartition.h"
+
+namespace GParted
+{
+
+OperationNamePartition::OperationNamePartition( const Device & device,
+                                                const Partition & partition_orig,
+                                                const Partition & partition_new )
+{
+       type = OPERATION_NAME_PARTITION;
+
+       this->device = device;
+       this->partition_original = partition_orig;
+       this->partition_new = partition_new;
+}
+
+void OperationNamePartition::apply_to_visual( std::vector<Partition> & partitions )
+{
+       if ( partition_original.inside_extended )
+       {
+               index_extended = find_index_extended( partitions );
+
+               if ( index_extended >= 0 )
+                       index = find_index_original( partitions[index_extended].logicals );
+
+               if ( index >= 0 )
+                       partitions[index_extended].logicals[index] = partition_new;
+       }
+       else
+       {
+               index = find_index_original( partitions );
+
+               if ( index >= 0 )
+                       partitions[index] = partition_new;
+       }
+}
+
+void OperationNamePartition::create_description()
+{
+       if( partition_new.name.empty() )
+       {
+               /* TO TRANSLATORS: looks like   Clear partition name on /dev/hda3 */
+               description = String::ucompose( _("Clear partition name on %1"),
+                                               partition_new.get_path() );
+       }
+       else
+       {
+               /* TO TRANSLATORS: looks like   Set partition name "My Name" on /dev/hda3 */
+               description = String::ucompose( _("Set partition name \"%1\" on %2"),
+                                               partition_new.name,
+                                               partition_new.get_path() );
+       }
+}
+
+} //GParted
diff --git a/src/Partition.cc b/src/Partition.cc
index 26da4c9..c51a73b 100644
--- a/src/Partition.cc
+++ b/src/Partition.cc
@@ -42,6 +42,7 @@ void Partition::Reset()
        filesystem = GParted::FS_UNALLOCATED ;
        have_filesystem_label = false;
        uuid .clear() ;
+       name.clear();
        partition_number = sector_start = sector_end = sectors_used = sectors_unused = -1;
        sectors_unallocated = 0 ;
        significant_threshold = 1 ;
diff --git a/src/TreeView_Detail.cc b/src/TreeView_Detail.cc
index 1101dfc..11ed160 100644
--- a/src/TreeView_Detail.cc
+++ b/src/TreeView_Detail.cc
@@ -32,6 +32,7 @@ TreeView_Detail::TreeView_Detail()
 
        //append columns
        append_column( _("Partition"), treeview_detail_columns .path );
+       append_column( _("Name"), treeview_detail_columns.name );
        append_column( _("File System"), treeview_detail_columns .color );
        append_column( _("Mount Point"), treeview_detail_columns .mountpoint );
        append_column( _("Label"), treeview_detail_columns .label );
@@ -53,30 +54,30 @@ TreeView_Detail::TreeView_Detail()
        
        //FILE SYSTEM
        //file system text
-       get_column( 1 ) ->pack_start( treeview_detail_columns .filesystem, true );
-       
+       get_column( 2 )->pack_start( treeview_detail_columns.filesystem, true );
+
        //colored text in File System column 
-       std::vector<Gtk::CellRenderer*> renderers = get_column( 1 ) ->get_cell_renderers() ;
+       std::vector<Gtk::CellRenderer*> renderers = get_column( 2 )->get_cell_renderers();
        cell_renderer_text = dynamic_cast<Gtk::CellRendererText*>( renderers .back() ) ;
-       get_column( 1 ) ->add_attribute( cell_renderer_text ->property_foreground(),
-                                        treeview_detail_columns .text_color );
-       
+       get_column( 2 )->add_attribute( cell_renderer_text->property_foreground(),
+                                       treeview_detail_columns.text_color );
+
        //pixbuf and text are both left aligned
-       get_column( 1 ) ->get_first_cell_renderer() ->property_xalign() = Gtk::ALIGN_LEFT ;
+       get_column( 2 )->get_first_cell_renderer()->property_xalign() = Gtk::ALIGN_LEFT;
        cell_renderer_text ->property_xalign() = Gtk::ALIGN_LEFT ;
        
        //MOUNT POINT
        //colored text in mount point column 
-       cell_renderer_text = dynamic_cast<Gtk::CellRendererText*>( get_column( 2 ) 
->get_first_cell_renderer() );
-       get_column( 2 ) ->add_attribute( cell_renderer_text ->property_foreground(), 
-                                        treeview_detail_columns .mount_text_color );
+       cell_renderer_text = dynamic_cast<Gtk::CellRendererText*>( get_column( 3 )->get_first_cell_renderer() 
);
+       get_column( 3 )->add_attribute( cell_renderer_text->property_foreground(),
+                                       treeview_detail_columns.mount_text_color );
 
        //set alignment of numeric columns to right
-       for( short t = 4 ; t < 7 ; t++ )
+       for( short t = 5 ; t < 8 ; t++ )
                get_column_cell_renderer( t ) ->property_xalign() = 1 ;
 
        //expand columns and centeralign the headertext
-       for( short t = 4 ; t < 8 ; t++ )
+       for( short t = 5 ; t < 9 ; t++ )
        {
                get_column( t ) ->set_expand( true ) ;
                get_column( t ) ->set_alignment( 0.5 ) ;
@@ -85,14 +86,15 @@ TreeView_Detail::TreeView_Detail()
 
 void TreeView_Detail::load_partitions( const std::vector<Partition> & partitions ) 
 {
-       bool mountpoints = false, labels = false ;
+       bool mountpoints = false, labels = false, names = false;
        treestore_detail ->clear() ;
-       
-       load_partitions( partitions, mountpoints, labels ) ;
 
-       get_column( 2 ) ->set_visible( mountpoints ) ;
-       get_column( 3 ) ->set_visible( labels ) ;
-       
+       load_partitions( partitions, mountpoints, labels, names );
+
+       get_column( 1 )->set_visible( names );
+       get_column( 3 )->set_visible( mountpoints );
+       get_column( 4 )->set_visible( labels );
+
        columns_autosize();
        expand_all() ;
 }
@@ -110,9 +112,10 @@ void TreeView_Detail::clear()
 }
 
 void TreeView_Detail::load_partitions( const std::vector<Partition> & partitions,
-                                      bool & mountpoints,
-                                      bool & labels,
-                                      const Gtk::TreeRow & parent_row ) 
+                                       bool & mountpoints,
+                                       bool & labels,
+                                       bool & names,
+                                       const Gtk::TreeRow & parent_row )
 {
        Gtk::TreeRow row ;
        for ( unsigned int i = 0 ; i < partitions .size() ; i++ ) 
@@ -121,13 +124,16 @@ void TreeView_Detail::load_partitions( const std::vector<Partition> & partitions
                create_row( row, partitions[ i ] );
                
                if ( partitions[ i ] .type == GParted::TYPE_EXTENDED )
-                       load_partitions( partitions[ i ] .logicals, mountpoints, labels, row ) ;
-                       
+                       load_partitions( partitions[i].logicals, mountpoints, labels, names, row );
+
                if ( partitions[ i ] .get_mountpoints() .size() )
                        mountpoints = true ;
                                        
                if ( ! partitions[ i ].get_filesystem_label().empty() )
                        labels = true ;
+
+               if ( ! partitions[i].name.empty() )
+                       names = true;
        }
 }
 
@@ -174,6 +180,9 @@ void TreeView_Detail::create_row( const Gtk::TreeRow & treerow, const Partition
        if ( partition .type == GParted::TYPE_EXTENDED && partition .busy ) 
                treerow[ treeview_detail_columns .path ] = treerow[ treeview_detail_columns .path ] + "   " ;
 
+       // name
+       treerow[treeview_detail_columns.name] = partition.name;
+
        treerow[ treeview_detail_columns .color ] = Utils::get_color_as_pixbuf( partition .filesystem, 16, 16 
) ; 
 
        treerow[ treeview_detail_columns .filesystem ] = 
diff --git a/src/Win_GParted.cc b/src/Win_GParted.cc
index 9c4a6ba..18919fd 100644
--- a/src/Win_GParted.cc
+++ b/src/Win_GParted.cc
@@ -25,6 +25,7 @@
 #include "../include/Dialog_Partition_New.h"
 #include "../include/Dialog_Partition_Info.h"
 #include "../include/Dialog_FileSystem_Label.h"
+#include "../include/Dialog_Partition_Name.h"
 #include "../include/DialogManageFlags.h"
 #include "../include/OperationCopy.h"
 #include "../include/OperationCheck.h"
@@ -34,6 +35,7 @@
 #include "../include/OperationResizeMove.h"
 #include "../include/OperationChangeUUID.h"
 #include "../include/OperationLabelFileSystem.h"
+#include "../include/OperationNamePartition.h"
 #include "../include/LVM2_PV_Info.h"
 #include "../config.h"
 
@@ -63,6 +65,7 @@ Win_GParted::Win_GParted( const std::vector<Glib::ustring> & user_devices )
         MENU_FORMAT =
         MENU_TOGGLE_BUSY =
         MENU_MOUNT =
+        MENU_NAME_PARTITION =
         MENU_FLAGS =
         MENU_INFO =
         MENU_LABEL_PARTITION =
@@ -377,6 +380,11 @@ void Win_GParted::init_partition_menu()
        menu_partition .items() .push_back( Gtk::Menu_Helpers::SeparatorElem() ) ;
        index++ ;
 
+       menu_partition.items().push_back(
+                       Gtk::Menu_Helpers::MenuElem( _("_Name Partition"),
+                                                    sigc::mem_fun( *this, 
&Win_GParted::activate_name_partition ) ) );
+       MENU_NAME_PARTITION = index++;
+
        menu_partition .items() .push_back(
                        Gtk::Menu_Helpers::MenuElem( _("M_anage Flags"),
                                                     sigc::mem_fun( *this, 
&Win_GParted::activate_manage_flags ) ) );
@@ -699,6 +707,7 @@ void Win_GParted::Add_Operation( Operation * operation, int index )
                     operation ->type == OPERATION_CHECK ||
                     operation ->type == OPERATION_CHANGE_UUID ||
                     operation ->type == OPERATION_LABEL_FILESYSTEM ||
+                    operation ->type == OPERATION_NAME_PARTITION ||
                     gparted_core .snap_to_alignment( operation ->device, operation ->partition_new, error )
                   )
                {
@@ -754,6 +763,18 @@ bool Win_GParted::Merge_Operations( unsigned int first, unsigned int second )
 
                return true;
        }
+       // Two name change operations on the same partition
+       else if ( operations[first]->type == OPERATION_NAME_PARTITION &&
+                 operations[second]->type == OPERATION_NAME_PARTITION &&
+                 operations[first]->partition_new == operations[second]->partition_original
+               )
+       {
+               operations[first]->partition_new.name = operations[second]->partition_new.name;
+               operations[first]->create_description();
+               remove_operation( second );
+
+               return true;
+       }
        // Two change-uuid change operations on the same partition
        else if ( operations[ first ]->type == OPERATION_CHANGE_UUID &&
                  operations[ second ]->type == OPERATION_CHANGE_UUID &&
@@ -935,8 +956,8 @@ void Win_GParted::set_valid_operations()
 {
        allow_new( false ); allow_delete( false ); allow_resize( false ); allow_copy( false );
        allow_paste( false ); allow_format( false ); allow_toggle_busy_state( false ) ;
-       allow_manage_flags( false ) ; allow_check( false ) ; allow_label_filesystem( false );
-       allow_change_uuid( false ); allow_info( false ) ;
+       allow_name_partition( false ); allow_manage_flags( false ); allow_check( false );
+       allow_label_filesystem( false ); allow_change_uuid( false ); allow_info( false );
 
        dynamic_cast<Gtk::Label*>( menu_partition .items()[ MENU_TOGGLE_BUSY ] .get_child() )
                ->set_label( FileSystem::get_generic_text ( CTEXT_DEACTIVATE_FILESYSTEM ) ) ;
@@ -1104,6 +1125,10 @@ void Win_GParted::set_valid_operations()
                if ( selected_partition .status == GParted::STAT_REAL && fs .write_label )
                        allow_label_filesystem( true );
 
+               // only allow naming of real partitions on devices that support naming
+               if ( selected_partition.status == STAT_REAL && devices[current_device].partition_naming )
+                       allow_name_partition( true );
+
                //only allow changing UUID of real partitions that support it
                if ( selected_partition .status == GParted::STAT_REAL && fs .write_uuid )
                        allow_change_uuid( true ) ;
@@ -1695,9 +1720,11 @@ void Win_GParted::activate_paste()
                {
                        Dialog_Partition_Copy dialog( gparted_core .get_fs( copied_partition .filesystem ),
                                                      devices[ current_device ] .cylsize ) ;
-                       //we don't need the messages/mount points of the source partition.
+                       // We don't want the messages, mount points or name of the source
+                       // partition for the new partition being created.
                        copied_partition .messages .clear() ;
                        copied_partition .clear_mountpoints() ;
+                       copied_partition .name.clear() ;
                        dialog .Set_Data( selected_partition, copied_partition ) ;
                        dialog .set_transient_for( *this );
                
@@ -2504,7 +2531,41 @@ void Win_GParted::activate_label_filesystem()
                show_operationslist() ;
        }
 }
-       
+
+void Win_GParted::activate_name_partition()
+{
+       Dialog_Partition_Name dialog( selected_partition );
+       dialog.set_transient_for( *this );
+
+       if (    ( dialog.run() == Gtk::RESPONSE_OK )
+            && ( dialog.get_new_name() != selected_partition.name ) )
+       {
+               dialog.hide();
+               // Make a duplicate of the selected partition (used in UNDO)
+               Partition part_temp = selected_partition;
+
+               part_temp.name = dialog.get_new_name();
+
+               Operation * operation = new OperationNamePartition( devices[current_device],
+                                                                   selected_partition, part_temp );
+               operation->icon = render_icon( Gtk::Stock::EXECUTE, Gtk::ICON_SIZE_MENU );
+
+               Add_Operation( operation );
+
+               // Verify if the two operations can be merged
+               for ( unsigned int t = 0 ; t < operations.size() - 1 ; t++ )
+               {
+                       if ( operations[t]->type == OPERATION_NAME_PARTITION )
+                       {
+                               if( Merge_Operations( t, operations.size() - 1 ) )
+                                       break;
+                       }
+               }
+
+               show_operationslist();
+       }
+}
+
 void Win_GParted::activate_change_uuid()
 {
        if ( gparted_core .get_filesystem_object( selected_partition .filesystem ) ->get_custom_text ( 
CTEXT_CHANGE_UUID_WARNING ) != "" ) {


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