diff --git a/ChangeLog b/ChangeLog index 8dae8fa4..160db24e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2004-11-28 Bart Hakvoort + + * Harddisks without disklabel are now properly initizalized and shown in the menu. When one tries to create a new partition on + such a disk a dialog pops up with some blabla about disklabels and offers to create a disklabel. sweet :P (special thanks to mantiena-baltix + for bringing this issue to my attention) + * fixed minor annoyance with refreshing detailed deviceinfo after a 'deep refresh' + 2004-11-24 Bart Hakvoort * src/Dialog_Partition_Resize_Move.cc: fixed small bug with resizing and lower limits. diff --git a/include/Device.h b/include/Device.h index a2cff78a..09c93905 100644 --- a/include/Device.h +++ b/include/Device.h @@ -44,7 +44,7 @@ public: Glib::ustring disktype; int max_prims ; bool busy ; - + private: diff --git a/include/Dialog_Disklabel.h b/include/Dialog_Disklabel.h new file mode 100644 index 00000000..d7f8bda7 --- /dev/null +++ b/include/Dialog_Disklabel.h @@ -0,0 +1,58 @@ +/* Copyright (C) 2004 Bart + * + * 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 Library General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + + + +#ifndef DIALOG_DISKLABEL +#define DIALOG_DISKLABEL + +#include "../include/i18n.h" +#include "../include/Utils.h" + +#include +#include +#include +#include +#include +#include + +namespace GParted +{ + +class Dialog_Disklabel : public Gtk::Dialog +{ +public: + Dialog_Disklabel( const Glib::ustring & device_path ) ; + + Glib::ustring Get_Disklabel( ) ; + +private: + Gtk::Expander expander_advanced ; + Gtk::HBox *hbox ; + Gtk::VBox *vbox ; + Gtk::Image image ; + Gtk::OptionMenu optionmenu_labeltypes ; + Gtk::Menu menu_labeltypes ; + + Glib::ustring str_temp ; + std::vector labeltypes ; +}; + +} //GParted + + +#endif //DIALOG_DISKLABEL diff --git a/include/FileSystem.h b/include/FileSystem.h index bc2ff5b7..e0e042f3 100644 --- a/include/FileSystem.h +++ b/include/FileSystem.h @@ -33,20 +33,20 @@ inline bool open_device( const Glib::ustring & device_path, PedDevice *& device return device ; } -inline bool open_device_and_disk( const Glib::ustring & device_path, PedDevice *& device, PedDisk *& disk ) +inline bool open_device_and_disk( const Glib::ustring & device_path, PedDevice *& device, PedDisk *& disk, bool strict = true ) { - if ( open_device( device_path, device ) ) disk = ped_disk_new( device ); - - if ( ! disk ) + + //if ! disk and writeable it's probably a HD without disklabel. We return true here and deal with them in GParted_Core::get_devices + if ( ! disk && ( strict || device ->read_only ) ) { ped_device_destroy( device ) ; device = NULL ; return false; - } - + } + return true ; } diff --git a/include/GParted_Core.h b/include/GParted_Core.h index f3d79c5b..d5479653 100644 --- a/include/GParted_Core.h +++ b/include/GParted_Core.h @@ -52,6 +52,8 @@ public: bool Resize( const Glib::ustring & device_path, const Partition & partition_old, const Partition & partition_new ) ; bool Copy( const Glib::ustring & dest_device_path, const Glib::ustring & src_part_path, Partition & partition_dest ) ; + bool Set_Disklabel( const Glib::ustring & device_path, const Glib::ustring & disklabel ) ; + std::vector get_fs( ) ; Glib::RefPtr get_textbuffer( ) ; diff --git a/include/Win_GParted.h b/include/Win_GParted.h index 27cc3522..84a135d2 100644 --- a/include/Win_GParted.h +++ b/include/Win_GParted.h @@ -30,6 +30,7 @@ #include "../include/Dialog_About.h" #include "../include/Dialog_Partition_Copy.h" #include "../include/GParted_Core.h" +#include "../include/Dialog_Disklabel.h" #include #include diff --git a/po/POTFILES.in b/po/POTFILES.in index becf1547..b3309100 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -3,6 +3,7 @@ gparted.desktop.in src/Dialog_About.cc src/Dialog_Base_Partition.cc +src/Dialog_Disklabel.cc src/Dialog_Partition_Copy.cc src/Dialog_Partition_Info.cc src/Dialog_Partition_New.cc diff --git a/src/Device.cc b/src/Device.cc index d21d5756..5186a5c2 100644 --- a/src/Device.cc +++ b/src/Device.cc @@ -30,7 +30,7 @@ void Device::Reset( ) device_partitions .clear( ) ; length = 0 ; heads = sectors = cylinders = 0 ; - model = path = realpath = disktype ; + model = path = realpath = disktype = "" ; max_prims = 0 ; busy = false ; } diff --git a/src/Dialog_Disklabel.cc b/src/Dialog_Disklabel.cc new file mode 100644 index 00000000..fb0e2544 --- /dev/null +++ b/src/Dialog_Disklabel.cc @@ -0,0 +1,106 @@ +/* Copyright (C) 2004 Bart + * + * 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 Library General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include "../include/Dialog_Disklabel.h" + +namespace GParted +{ + +Dialog_Disklabel::Dialog_Disklabel( const Glib::ustring & device_path ) +{ + this ->set_title( String::ucompose( _("No recognisable disklabel detected on %1"), device_path ) ); + this ->set_has_separator( false ) ; + this ->set_resizable( false ); + + hbox = manage( new Gtk::HBox( ) ) ; + this ->get_vbox( ) ->pack_start( *hbox, Gtk::PACK_SHRINK ); + + vbox = manage( new Gtk::VBox( ) ) ; + vbox ->set_border_width( 10 ) ; + hbox ->pack_start( *vbox, Gtk::PACK_SHRINK ); + + image .set( Gtk::Stock::DIALOG_WARNING, Gtk::ICON_SIZE_DIALOG ) ; + vbox ->pack_start( image, Gtk::PACK_SHRINK ); + + vbox = manage( new Gtk::VBox( ) ) ; + vbox ->set_border_width( 10 ) ; + hbox ->pack_start( *vbox, Gtk::PACK_SHRINK ); + + str_temp = "" ; + str_temp += String::ucompose( _("No recognisable disklabel detected on %1"), device_path ) ; + str_temp += "\n" ; + vbox ->pack_start( * mk_label( str_temp ), Gtk::PACK_SHRINK ); + + str_temp = _("A disklabel is a file at the beginning of the disk that indicates where each partition begins and how many sectors it occupies.") ; + str_temp += "\n" ; + str_temp += _("You need a disklabel if you want to create partitions on this disk.") ; + str_temp += "\n\n" ; + str_temp += _("By default GParted creates a msdos disklabel.") ; + str_temp += "\n" ; + vbox ->pack_start( * mk_label( str_temp, true, true, true ), Gtk::PACK_SHRINK ); + + //advanced + str_temp = "" ; + str_temp += _("Advanced") ; + expander_advanced .set_label( str_temp + "" ) ; + expander_advanced .set_use_markup( true ) ; + + vbox ->pack_start( expander_advanced, Gtk::PACK_SHRINK ) ; + + hbox = manage( new Gtk::HBox( false, 5 ) ) ; + hbox ->set_border_width( 5 ) ; + str_temp = _("Select new labeltype:") ; + str_temp += "\t" ; + hbox ->pack_start( * mk_label( str_temp ), Gtk::PACK_SHRINK ); + expander_advanced .add( *hbox ) ; + + //create and add optionmenu + labeltypes .push_back( "msdos" ) ; + labeltypes .push_back( "bsd" ) ; + labeltypes .push_back( "loop" ) ; + labeltypes .push_back( "gpt" ) ; + labeltypes .push_back( "mac" ) ; + labeltypes .push_back( "pc98" ) ; + labeltypes .push_back( "sun" ) ; + + for ( unsigned int t = 0 ; t < labeltypes .size( ) ; t++ ) + menu_labeltypes .items( ) .push_back( Gtk::Menu_Helpers::MenuElem( labeltypes[ t ] + "\t" ) ) ; + + optionmenu_labeltypes .set_menu( menu_labeltypes ) ; + hbox ->pack_start( optionmenu_labeltypes, Gtk::PACK_SHRINK ) ; + + //standard warning + str_temp = "\n " ; + str_temp += String::ucompose( _("WARNING: Creating a new disklabel will erase all data on %1!"), device_path ) ; + str_temp += "\n"; + + this ->get_vbox( ) ->pack_start( * mk_label( str_temp ), Gtk::PACK_SHRINK ); + + this ->add_button( Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL ); + this ->add_button( _("Create"), Gtk::RESPONSE_OK ); + + this ->show_all_children( ) ; +} + +Glib::ustring Dialog_Disklabel::Get_Disklabel( ) +{ + return labeltypes[ optionmenu_labeltypes .get_history( ) ] ; +} + + + +}//GParted diff --git a/src/Dialog_Partition_New.cc b/src/Dialog_Partition_New.cc index d8ea91c0..e142981a 100644 --- a/src/Dialog_Partition_New.cc +++ b/src/Dialog_Partition_New.cc @@ -179,7 +179,6 @@ void Dialog_Partition_New::optionmenu_changed( bool type ) optionmenu_filesystem .set_sensitive( true ) ; optionmenu_filesystem .set_history( 0 ) ; } - } //optionmenu_filesystem diff --git a/src/GParted_Core.cc b/src/GParted_Core.cc index 79ead530..6370a1aa 100644 --- a/src/GParted_Core.cc +++ b/src/GParted_Core.cc @@ -50,7 +50,7 @@ void GParted_Core::find_supported_filesystems( ) void GParted_Core::get_devices( std::vector & devices, bool deep_scan ) { devices .clear( ) ; - + //try to find all available devices and put these in a list ped_device_probe_all( ); @@ -65,7 +65,7 @@ void GParted_Core::get_devices( std::vector & devices, bool deep_scan ) { if ( open_device( device ->path, device ) ) device_paths .push_back( get_sym_path( device ->path ) ) ; - + device = ped_device_get_next ( device ) ; } close_device_and_disk( device, disk ) ; @@ -76,28 +76,44 @@ void GParted_Core::get_devices( std::vector & devices, bool deep_scan ) for ( unsigned int t = 0 ; t < device_paths .size( ) ; t++ ) { - if ( open_device_and_disk( device_paths[ t ], device, disk ) ) + if ( open_device_and_disk( device_paths[ t ], device, disk, false ) ) { temp_device .Reset( ) ; + //device info.. temp_device .path = device_paths[ t ] ; temp_device .realpath = device ->path ; temp_device .model = device ->model ; - temp_device .disktype = disk ->type ->name ; temp_device .heads = device ->bios_geom .heads ; temp_device .sectors = device ->bios_geom .sectors ; temp_device .cylinders = device ->bios_geom .cylinders ; temp_device .length = temp_device .heads * temp_device .sectors * temp_device .cylinders ; - temp_device .max_prims = ped_disk_get_max_primary_partition_count( disk ) ; - - set_device_partitions( temp_device, deep_scan ) ; - + + //normal harddisk + if ( disk ) + { + temp_device .disktype = disk ->type ->name ; + temp_device .max_prims = ped_disk_get_max_primary_partition_count( disk ) ; + + set_device_partitions( temp_device, deep_scan ) ; + + } + //harddisk without disklabel + else + { + temp_device .disktype = _("unrecognised") ; + temp_device .max_prims = -1 ; + + Partition partition_temp ; + partition_temp .Set_Unallocated( 0, temp_device .length, false ); + temp_device .device_partitions .push_back( partition_temp ); + } + devices .push_back( temp_device ) ; close_device_and_disk( device, disk ) ; } } - } void GParted_Core::set_device_partitions( Device & device, bool deep_scan ) @@ -381,6 +397,28 @@ bool GParted_Core::Copy( const Glib::ustring & dest_device_path, const Glib::ust return false ; } +bool GParted_Core::Set_Disklabel( const Glib::ustring & device_path, const Glib::ustring & disklabel ) +{ + bool return_value = false ; + + if ( open_device_and_disk( device_path, device, disk, false ) ) + { + PedDiskType *type = NULL ; + type = ped_disk_type_get( disklabel .c_str( ) ) ; + + if ( type ) + { + disk = ped_disk_new_fresh ( device, type); + + return_value = Commit( disk ) ; + } + + close_device_and_disk( device, disk ) ; + } + + return return_value ; +} + std::vector GParted_Core::get_fs( ) { return FILESYSTEMS ; diff --git a/src/Makefile.am b/src/Makefile.am index 6096efa5..f6207dc1 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -37,7 +37,8 @@ gparted_SOURCES = \ fat32.cc\ linux_swap.cc\ reiserfs.cc\ - ntfs.cc + ntfs.cc\ + Dialog_Disklabel.cc gparted_LDFLAGS = -lparted -lgthread-2.0 diff --git a/src/Win_GParted.cc b/src/Win_GParted.cc index 418443d5..757f23e0 100644 --- a/src/Win_GParted.cc +++ b/src/Win_GParted.cc @@ -714,11 +714,14 @@ void Win_GParted::menu_gparted_refresh_devices() Refresh_OptionMenu( ) ; //check if current_device is still available (think about hotpluggable shit like usbdevices) - if ( current_device >= devices .size() ) + if ( current_device >= devices .size( ) ) current_device = 0 ; //rebuild visualdisk and treeview Refresh_Visual( ); + + //and refresh the device info... + Fill_Label_Device_Info( ) ; } void Win_GParted::menu_gparted_quit() @@ -917,13 +920,31 @@ void Win_GParted::activate_paste() void Win_GParted::activate_new() { - if ( ! max_amount_prim_reached( ) ) + //if max_prims == -1 the current device has an unrecognised disklabel (see also GParted_Core::get_devices) + if ( devices [ current_device ] .max_prims == -1 ) + { + Dialog_Disklabel dialog( devices [ current_device ] .path ) ; + dialog .set_transient_for( *this ); + + if ( dialog .run( ) == Gtk::RESPONSE_OK ) + { + if ( ! gparted_core .Set_Disklabel( devices [ current_device ] .path, dialog .Get_Disklabel( ) ) ) + { + Gtk::MessageDialog dialog( *this, _("Error while setting new disklabel"), true, Gtk::MESSAGE_ERROR, Gtk::BUTTONS_OK, true ) ; + dialog .run( ) ; + } + + menu_gparted_refresh_devices( ) ; + } + } + + else if ( ! max_amount_prim_reached( ) ) { Dialog_Partition_New dialog; dialog .Set_Data( selected_partition, any_extended, new_count, gparted_core .get_fs( ) ) ; dialog .set_transient_for( *this ); - if ( dialog.run() == Gtk::RESPONSE_OK ) + if ( dialog .run( ) == Gtk::RESPONSE_OK ) { dialog .hide( ) ;//make sure the dialog is gone _before_ operationslist shows up (only matters if first operation) new_count++ ;