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
This commit is contained in:
Michael Zimmermann 2014-12-12 08:00:02 +01:00 committed by Curtis Gedak
parent b278782ef6
commit 1f5841b4ad
19 changed files with 409 additions and 33 deletions

View File

@ -51,6 +51,7 @@ public:
int max_prims ; int max_prims ;
int highest_busy ; int highest_busy ;
bool readonly ; bool readonly ;
bool partition_naming; // Is naming of partitions supported on this device?
private: private:
void sort_paths_and_remove_duplicates() ; void sort_paths_and_remove_duplicates() ;

View File

@ -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 */

View File

@ -111,6 +111,8 @@ private:
bool label_filesystem( const Partition & partition, OperationDetail & operationdetail ); 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 change_uuid( const Partition & partition, OperationDetail & operation_detail ) ;
bool resize_move( const Device & device, bool resize_move( const Device & device,

View File

@ -11,6 +11,7 @@ EXTRA_DIST = \
Dialog_FileSystem_Label.h \ Dialog_FileSystem_Label.h \
Dialog_Partition_Copy.h \ Dialog_Partition_Copy.h \
Dialog_Partition_Info.h \ Dialog_Partition_Info.h \
Dialog_Partition_Name.h \
Dialog_Partition_New.h \ Dialog_Partition_New.h \
Dialog_Partition_Resize_Move.h \ Dialog_Partition_Resize_Move.h \
Dialog_Progress.h \ Dialog_Progress.h \
@ -32,6 +33,7 @@ EXTRA_DIST = \
OperationDetail.h \ OperationDetail.h \
OperationFormat.h \ OperationFormat.h \
OperationLabelFileSystem.h \ OperationLabelFileSystem.h \
OperationNamePartition.h \
OperationResizeMove.h \ OperationResizeMove.h \
Partition.h \ Partition.h \
PipeCapture.h \ PipeCapture.h \

View File

@ -32,7 +32,8 @@ enum OperationType {
OPERATION_FORMAT = 4, OPERATION_FORMAT = 4,
OPERATION_COPY = 5, OPERATION_COPY = 5,
OPERATION_LABEL_FILESYSTEM = 6, OPERATION_LABEL_FILESYSTEM = 6,
OPERATION_CHANGE_UUID = 7 OPERATION_CHANGE_UUID = 7,
OPERATION_NAME_PARTITION = 8
}; };
class Operation class Operation

View File

@ -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 */

View File

@ -116,6 +116,7 @@ public:
PartitionAlignment alignment; //ALIGN_CYLINDER, ALIGN_STRICT, etc PartitionAlignment alignment; //ALIGN_CYLINDER, ALIGN_STRICT, etc
FILESYSTEM filesystem ; FILESYSTEM filesystem ;
Glib::ustring uuid ; Glib::ustring uuid ;
Glib::ustring name;
Sector sector_start; Sector sector_start;
Sector sector_end; Sector sector_end;
Sector sectors_used; Sector sectors_used;

View File

@ -48,7 +48,8 @@ private:
void load_partitions( const std::vector<Partition> & partitions, void load_partitions( const std::vector<Partition> & partitions,
bool & mountpoints, bool & mountpoints,
bool & labels, bool & labels,
const Gtk::TreeRow & parent_row = Gtk::TreeRow() ) ; bool & names,
const Gtk::TreeRow & parent_row = Gtk::TreeRow() );
bool set_selected( Gtk::TreeModel::Children rows, const Partition & partition, bool inside_extended = false ) ; bool set_selected( Gtk::TreeModel::Children rows, const Partition & partition, bool inside_extended = false ) ;
void create_row( const Gtk::TreeRow & treerow, const Partition & partition ); void create_row( const Gtk::TreeRow & treerow, const Partition & partition );
@ -66,6 +67,7 @@ private:
struct treeview_detail_Columns : public Gtk::TreeModelColumnRecord struct treeview_detail_Columns : public Gtk::TreeModelColumnRecord
{ {
Gtk::TreeModelColumn<Glib::ustring> path; Gtk::TreeModelColumn<Glib::ustring> path;
Gtk::TreeModelColumn<Glib::ustring> name;
Gtk::TreeModelColumn<Glib::ustring> filesystem; Gtk::TreeModelColumn<Glib::ustring> filesystem;
Gtk::TreeModelColumn<Glib::ustring> mountpoint; Gtk::TreeModelColumn<Glib::ustring> mountpoint;
Gtk::TreeModelColumn<Glib::ustring> label ; Gtk::TreeModelColumn<Glib::ustring> label ;
@ -82,7 +84,7 @@ private:
treeview_detail_Columns() 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( size ); add( used ); add( unused ); add( color );
add( text_color ); add( mount_text_color ); add( icon1 ); add( text_color ); add( mount_text_color ); add( icon1 );
add( icon2 ) ; add( flags ); add( partition ); add( icon2 ) ; add( flags ); add( partition );

View File

@ -106,6 +106,9 @@ private:
void allow_label_filesystem( bool state ) { void allow_label_filesystem( bool state ) {
toggle_item( state, MENU_LABEL_PARTITION ) ; } toggle_item( state, MENU_LABEL_PARTITION ) ; }
void allow_name_partition( bool state ) {
toggle_item( state, MENU_NAME_PARTITION ); }
void allow_change_uuid( bool state ) { void allow_change_uuid( bool state ) {
toggle_item( state, MENU_CHANGE_UUID ) ; } toggle_item( state, MENU_CHANGE_UUID ) ; }
@ -169,6 +172,7 @@ private:
void activate_check() ; void activate_check() ;
void activate_change_uuid() ; void activate_change_uuid() ;
void activate_label_filesystem(); void activate_label_filesystem();
void activate_name_partition();
void activate_undo(); void activate_undo();
void remove_operation( int index = -1, bool remove_all = false ) ; void remove_operation( int index = -1, bool remove_all = false ) ;
@ -236,6 +240,7 @@ private:
MENU_FORMAT, MENU_FORMAT,
MENU_TOGGLE_BUSY, MENU_TOGGLE_BUSY,
MENU_MOUNT, MENU_MOUNT,
MENU_NAME_PARTITION,
MENU_FLAGS, MENU_FLAGS,
MENU_CHECK, MENU_CHECK,
MENU_LABEL_PARTITION, MENU_LABEL_PARTITION,

View File

@ -9,6 +9,7 @@ src/Dialog_Disklabel.cc
src/Dialog_FileSystem_Label.cc src/Dialog_FileSystem_Label.cc
src/Dialog_Partition_Copy.cc src/Dialog_Partition_Copy.cc
src/Dialog_Partition_Info.cc src/Dialog_Partition_Info.cc
src/Dialog_Partition_Name.cc
src/Dialog_Partition_New.cc src/Dialog_Partition_New.cc
src/Dialog_Partition_Resize_Move.cc src/Dialog_Partition_Resize_Move.cc
src/Dialog_Progress.cc src/Dialog_Progress.cc
@ -27,6 +28,7 @@ src/OperationCreate.cc
src/OperationDelete.cc src/OperationDelete.cc
src/OperationFormat.cc src/OperationFormat.cc
src/OperationLabelFileSystem.cc src/OperationLabelFileSystem.cc
src/OperationNamePartition.cc
src/OperationResizeMove.cc src/OperationResizeMove.cc
src/Partition.cc src/Partition.cc
src/TreeView_Detail.cc src/TreeView_Detail.cc

View File

@ -32,6 +32,7 @@ void Device::Reset()
length = cylsize = 0 ; length = cylsize = 0 ;
heads = sectors = cylinders = 0 ; heads = sectors = cylinders = 0 ;
model = disktype = "" ; model = disktype = "" ;
partition_naming = false;
sector_size = max_prims = highest_busy = 0 ; sector_size = max_prims = highest_busy = 0 ;
readonly = false ; readonly = false ;
} }

View File

@ -512,6 +512,16 @@ void Dialog_Partition_Info::Display_Info()
if ( partition .type != GParted::TYPE_UNALLOCATED && partition .status != GParted::STAT_NEW ) 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 // flags
table->attach( * Utils::mk_label( "<b>" + Glib::ustring( _("Flags:") ) + "</b>" ), table->attach( * Utils::mk_label( "<b>" + Glib::ustring( _("Flags:") ) + "</b>" ),
1, 2, 1, 2,

View File

@ -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

View File

@ -27,6 +27,7 @@
#include "../include/OperationResizeMove.h" #include "../include/OperationResizeMove.h"
#include "../include/OperationChangeUUID.h" #include "../include/OperationChangeUUID.h"
#include "../include/OperationLabelFileSystem.h" #include "../include/OperationLabelFileSystem.h"
#include "../include/OperationNamePartition.h"
#include "../include/Proc_Partitions_Info.h" #include "../include/Proc_Partitions_Info.h"
#include "../include/btrfs.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 .disktype = lp_disk ->type ->name ;
temp_device .max_prims = ped_disk_get_max_primary_partition_count( lp_disk ) ; 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_device_partitions( temp_device, lp_device, lp_disk ) ;
set_mountpoints( temp_device .partitions ) ; set_mountpoints( temp_device .partitions ) ;
set_used_sectors( temp_device .partitions, lp_disk ) ; 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: case OPERATION_LABEL_FILESYSTEM:
succes = label_filesystem( operation->partition_new, operation->operation_detail ); succes = label_filesystem( operation->partition_new, operation->operation_detail );
break ; break ;
case OPERATION_NAME_PARTITION:
succes = name_partition( operation->partition_new, operation->operation_detail );
break;
case OPERATION_CHANGE_UUID: case OPERATION_CHANGE_UUID:
succes = change_uuid( operation ->partition_new, operation ->operation_detail ) ; succes = change_uuid( operation ->partition_new, operation ->operation_detail ) ;
break ; break ;
@ -1188,6 +1198,10 @@ void GParted_Core::set_device_partitions( Device & device, PedDevice* lp_device,
{ {
read_uuid( partition_temp ) ; 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(), partition_temp .messages .insert( partition_temp .messages .end(),
@ -2101,6 +2115,34 @@ bool GParted_Core::label_filesystem( const Partition & partition, OperationDetai
return succes ; 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 ) bool GParted_Core::change_uuid( const Partition & partition, OperationDetail & operationdetail )
{ {
if ( partition .uuid == UUID_RANDOM_NTFS_HALF ) { if ( partition .uuid == UUID_RANDOM_NTFS_HALF ) {

View File

@ -22,6 +22,7 @@ gpartedbin_SOURCES = \
Dialog_FileSystem_Label.cc \ Dialog_FileSystem_Label.cc \
Dialog_Partition_Copy.cc \ Dialog_Partition_Copy.cc \
Dialog_Partition_Info.cc \ Dialog_Partition_Info.cc \
Dialog_Partition_Name.cc \
Dialog_Partition_New.cc \ Dialog_Partition_New.cc \
Dialog_Partition_Resize_Move.cc \ Dialog_Partition_Resize_Move.cc \
Dialog_Progress.cc \ Dialog_Progress.cc \
@ -43,6 +44,7 @@ gpartedbin_SOURCES = \
OperationDetail.cc \ OperationDetail.cc \
OperationFormat.cc \ OperationFormat.cc \
OperationLabelFileSystem.cc \ OperationLabelFileSystem.cc \
OperationNamePartition.cc \
OperationResizeMove.cc \ OperationResizeMove.cc \
Partition.cc \ Partition.cc \
PipeCapture.cc \ PipeCapture.cc \

View File

@ -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

View File

@ -42,6 +42,7 @@ void Partition::Reset()
filesystem = GParted::FS_UNALLOCATED ; filesystem = GParted::FS_UNALLOCATED ;
have_filesystem_label = false; have_filesystem_label = false;
uuid .clear() ; uuid .clear() ;
name.clear();
partition_number = sector_start = sector_end = sectors_used = sectors_unused = -1; partition_number = sector_start = sector_end = sectors_used = sectors_unused = -1;
sectors_unallocated = 0 ; sectors_unallocated = 0 ;
significant_threshold = 1 ; significant_threshold = 1 ;

View File

@ -32,6 +32,7 @@ TreeView_Detail::TreeView_Detail()
//append columns //append columns
append_column( _("Partition"), treeview_detail_columns .path ); append_column( _("Partition"), treeview_detail_columns .path );
append_column( _("Name"), treeview_detail_columns.name );
append_column( _("File System"), treeview_detail_columns .color ); append_column( _("File System"), treeview_detail_columns .color );
append_column( _("Mount Point"), treeview_detail_columns .mountpoint ); append_column( _("Mount Point"), treeview_detail_columns .mountpoint );
append_column( _("Label"), treeview_detail_columns .label ); append_column( _("Label"), treeview_detail_columns .label );
@ -53,30 +54,30 @@ TreeView_Detail::TreeView_Detail()
//FILE SYSTEM //FILE SYSTEM
//file system text //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 //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() ) ; cell_renderer_text = dynamic_cast<Gtk::CellRendererText*>( renderers .back() ) ;
get_column( 1 ) ->add_attribute( cell_renderer_text ->property_foreground(), get_column( 2 )->add_attribute( cell_renderer_text->property_foreground(),
treeview_detail_columns .text_color ); treeview_detail_columns.text_color );
//pixbuf and text are both left aligned //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 ; cell_renderer_text ->property_xalign() = Gtk::ALIGN_LEFT ;
//MOUNT POINT //MOUNT POINT
//colored text in mount point column //colored text in mount point column
cell_renderer_text = dynamic_cast<Gtk::CellRendererText*>( get_column( 2 ) ->get_first_cell_renderer() ); cell_renderer_text = dynamic_cast<Gtk::CellRendererText*>( get_column( 3 )->get_first_cell_renderer() );
get_column( 2 ) ->add_attribute( cell_renderer_text ->property_foreground(), get_column( 3 )->add_attribute( cell_renderer_text->property_foreground(),
treeview_detail_columns .mount_text_color ); treeview_detail_columns.mount_text_color );
//set alignment of numeric columns to right //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 ; get_column_cell_renderer( t ) ->property_xalign() = 1 ;
//expand columns and centeralign the headertext //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_expand( true ) ;
get_column( t ) ->set_alignment( 0.5 ) ; get_column( t ) ->set_alignment( 0.5 ) ;
@ -85,13 +86,14 @@ TreeView_Detail::TreeView_Detail()
void TreeView_Detail::load_partitions( const std::vector<Partition> & partitions ) 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() ; treestore_detail ->clear() ;
load_partitions( partitions, mountpoints, labels ) ; load_partitions( partitions, mountpoints, labels, names );
get_column( 2 ) ->set_visible( mountpoints ) ; get_column( 1 )->set_visible( names );
get_column( 3 ) ->set_visible( labels ) ; get_column( 3 )->set_visible( mountpoints );
get_column( 4 )->set_visible( labels );
columns_autosize(); columns_autosize();
expand_all() ; expand_all() ;
@ -112,6 +114,7 @@ void TreeView_Detail::clear()
void TreeView_Detail::load_partitions( const std::vector<Partition> & partitions, void TreeView_Detail::load_partitions( const std::vector<Partition> & partitions,
bool & mountpoints, bool & mountpoints,
bool & labels, bool & labels,
bool & names,
const Gtk::TreeRow & parent_row ) const Gtk::TreeRow & parent_row )
{ {
Gtk::TreeRow row ; Gtk::TreeRow row ;
@ -121,13 +124,16 @@ void TreeView_Detail::load_partitions( const std::vector<Partition> & partitions
create_row( row, partitions[ i ] ); create_row( row, partitions[ i ] );
if ( partitions[ i ] .type == GParted::TYPE_EXTENDED ) 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() ) if ( partitions[ i ] .get_mountpoints() .size() )
mountpoints = true ; mountpoints = true ;
if ( ! partitions[ i ].get_filesystem_label().empty() ) if ( ! partitions[ i ].get_filesystem_label().empty() )
labels = true ; 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 ) if ( partition .type == GParted::TYPE_EXTENDED && partition .busy )
treerow[ treeview_detail_columns .path ] = treerow[ treeview_detail_columns .path ] + " " ; 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 .color ] = Utils::get_color_as_pixbuf( partition .filesystem, 16, 16 ) ;
treerow[ treeview_detail_columns .filesystem ] = treerow[ treeview_detail_columns .filesystem ] =

View File

@ -25,6 +25,7 @@
#include "../include/Dialog_Partition_New.h" #include "../include/Dialog_Partition_New.h"
#include "../include/Dialog_Partition_Info.h" #include "../include/Dialog_Partition_Info.h"
#include "../include/Dialog_FileSystem_Label.h" #include "../include/Dialog_FileSystem_Label.h"
#include "../include/Dialog_Partition_Name.h"
#include "../include/DialogManageFlags.h" #include "../include/DialogManageFlags.h"
#include "../include/OperationCopy.h" #include "../include/OperationCopy.h"
#include "../include/OperationCheck.h" #include "../include/OperationCheck.h"
@ -34,6 +35,7 @@
#include "../include/OperationResizeMove.h" #include "../include/OperationResizeMove.h"
#include "../include/OperationChangeUUID.h" #include "../include/OperationChangeUUID.h"
#include "../include/OperationLabelFileSystem.h" #include "../include/OperationLabelFileSystem.h"
#include "../include/OperationNamePartition.h"
#include "../include/LVM2_PV_Info.h" #include "../include/LVM2_PV_Info.h"
#include "../config.h" #include "../config.h"
@ -63,6 +65,7 @@ Win_GParted::Win_GParted( const std::vector<Glib::ustring> & user_devices )
MENU_FORMAT = MENU_FORMAT =
MENU_TOGGLE_BUSY = MENU_TOGGLE_BUSY =
MENU_MOUNT = MENU_MOUNT =
MENU_NAME_PARTITION =
MENU_FLAGS = MENU_FLAGS =
MENU_INFO = MENU_INFO =
MENU_LABEL_PARTITION = MENU_LABEL_PARTITION =
@ -377,6 +380,11 @@ void Win_GParted::init_partition_menu()
menu_partition .items() .push_back( Gtk::Menu_Helpers::SeparatorElem() ) ; menu_partition .items() .push_back( Gtk::Menu_Helpers::SeparatorElem() ) ;
index++ ; 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( menu_partition .items() .push_back(
Gtk::Menu_Helpers::MenuElem( _("M_anage Flags"), Gtk::Menu_Helpers::MenuElem( _("M_anage Flags"),
sigc::mem_fun( *this, &Win_GParted::activate_manage_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_CHECK ||
operation ->type == OPERATION_CHANGE_UUID || operation ->type == OPERATION_CHANGE_UUID ||
operation ->type == OPERATION_LABEL_FILESYSTEM || operation ->type == OPERATION_LABEL_FILESYSTEM ||
operation ->type == OPERATION_NAME_PARTITION ||
gparted_core .snap_to_alignment( operation ->device, operation ->partition_new, error ) 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; 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 // Two change-uuid change operations on the same partition
else if ( operations[ first ]->type == OPERATION_CHANGE_UUID && else if ( operations[ first ]->type == OPERATION_CHANGE_UUID &&
operations[ second ]->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_new( false ); allow_delete( false ); allow_resize( false ); allow_copy( false );
allow_paste( false ); allow_format( false ); allow_toggle_busy_state( false ) ; allow_paste( false ); allow_format( false ); allow_toggle_busy_state( false ) ;
allow_manage_flags( false ) ; allow_check( false ) ; allow_label_filesystem( false ); allow_name_partition( false ); allow_manage_flags( false ); allow_check( false );
allow_change_uuid( false ); allow_info( false ) ; allow_label_filesystem( false ); allow_change_uuid( false ); allow_info( false );
dynamic_cast<Gtk::Label*>( menu_partition .items()[ MENU_TOGGLE_BUSY ] .get_child() ) dynamic_cast<Gtk::Label*>( menu_partition .items()[ MENU_TOGGLE_BUSY ] .get_child() )
->set_label( FileSystem::get_generic_text ( CTEXT_DEACTIVATE_FILESYSTEM ) ) ; ->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 ) if ( selected_partition .status == GParted::STAT_REAL && fs .write_label )
allow_label_filesystem( true ); 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 //only allow changing UUID of real partitions that support it
if ( selected_partition .status == GParted::STAT_REAL && fs .write_uuid ) if ( selected_partition .status == GParted::STAT_REAL && fs .write_uuid )
allow_change_uuid( true ) ; allow_change_uuid( true ) ;
@ -1695,9 +1720,11 @@ void Win_GParted::activate_paste()
{ {
Dialog_Partition_Copy dialog( gparted_core .get_fs( copied_partition .filesystem ), Dialog_Partition_Copy dialog( gparted_core .get_fs( copied_partition .filesystem ),
devices[ current_device ] .cylsize ) ; 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 .messages .clear() ;
copied_partition .clear_mountpoints() ; copied_partition .clear_mountpoints() ;
copied_partition .name.clear() ;
dialog .Set_Data( selected_partition, copied_partition ) ; dialog .Set_Data( selected_partition, copied_partition ) ;
dialog .set_transient_for( *this ); dialog .set_transient_for( *this );
@ -2505,6 +2532,40 @@ void Win_GParted::activate_label_filesystem()
} }
} }
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() void Win_GParted::activate_change_uuid()
{ {
if ( gparted_core .get_filesystem_object( selected_partition .filesystem ) ->get_custom_text ( CTEXT_CHANGE_UUID_WARNING ) != "" ) { if ( gparted_core .get_filesystem_object( selected_partition .filesystem ) ->get_custom_text ( CTEXT_CHANGE_UUID_WARNING ) != "" ) {