diff --git a/ChangeLog b/ChangeLog index 7d931139..f2001188 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2006-03-24 Bart Hakvoort + + * lots of cleanups in operationhandling. This resulted in cleaner/less + code and the fixing of some longstanding issues. + 2006-03-20 Bart Hakvoort * include/DrawingAreaVisualDisk.h, diff --git a/include/Dialog_Filesystems.h b/include/Dialog_Filesystems.h index a9f96d6e..ccdc4e87 100644 --- a/include/Dialog_Filesystems.h +++ b/include/Dialog_Filesystems.h @@ -17,12 +17,11 @@ #ifndef DIALOG_FILESYSTEMS #define DIALOG_FILESYSTEMS - +//FIXME add more info ( at least 'detect' which will be any filesystem we _can_ detect (and should therefore have +//it's own class) ) #include "../include/Utils.h" -#include "../include/i18n.h" #include -#include #include #include @@ -33,9 +32,9 @@ class Dialog_Filesystems : public Gtk::Dialog { public: - Dialog_Filesystems( ) ; + Dialog_Filesystems() ; void Load_Filesystems( const std::vector< FS > & FILESYSTEMS ) ; - ~Dialog_Filesystems( ) ; + ~Dialog_Filesystems() ; private: void Show_Filesystem( const FS & fs ) ; @@ -53,7 +52,11 @@ private: Gtk::TreeModelColumn< Glib::RefPtr > move; Gtk::TreeModelColumn< Glib::RefPtr > copy; - treeview_filesystems_Columns( ) { add( filesystem ); add( create ); add( grow ); add( shrink ); add( move ); add( copy ); } + treeview_filesystems_Columns() + { + add( filesystem ); add( create ); add( grow ); + add( shrink ); add( move ); add( copy ); + } }; treeview_filesystems_Columns treeview_filesystems_columns ; diff --git a/include/Dialog_Progress.h b/include/Dialog_Progress.h index b4f2460e..707f4e2e 100644 --- a/include/Dialog_Progress.h +++ b/include/Dialog_Progress.h @@ -37,10 +37,10 @@ namespace GParted class Dialog_Progress : public Gtk::Dialog { public: - Dialog_Progress( const std::vector & operations ) ; + Dialog_Progress( const std::vector & operations ) ; ~Dialog_Progress(); - sigc::signal< bool, Operation & > signal_apply_operation ; + sigc::signal< bool, Operation * > signal_apply_operation ; private: void update_operation_details( const Gtk::TreeRow & treerow, const OperationDetails & operation_details ) ; @@ -85,7 +85,7 @@ private: }; treeview_operations_Columns treeview_operations_columns; - std::vector operations ; + std::vector operations ; bool pulse, succes, cancel ; pthread_t pthread ; double fraction ; diff --git a/include/GParted_Core.h b/include/GParted_Core.h index ecbcbc66..cf7607ef 100644 --- a/include/GParted_Core.h +++ b/include/GParted_Core.h @@ -47,7 +47,7 @@ public: void set_user_devices( const std::vector & user_devices ) ; void get_devices( std::vector & devices ) ; - bool apply_operation_to_disk( Operation & operation ); + bool apply_operation_to_disk( Operation * operation ); bool create( const Device & device, Partition & new_partition, diff --git a/include/Makefile.am b/include/Makefile.am index 8b11794d..9274ff72 100644 --- a/include/Makefile.am +++ b/include/Makefile.am @@ -16,6 +16,11 @@ EXTRA_DIST = \ Frame_Resizer_Extended.h \ GParted_Core.h \ Operation.h \ + OperationCopy.h \ + OperationCreate.h \ + OperationDelete.h \ + OperationFormat.h \ + OperationResizeMove.h \ Partition.h \ TreeView_Detail.h \ Utils.h \ diff --git a/include/Operation.h b/include/Operation.h index 60981abb..e7648380 100644 --- a/include/Operation.h +++ b/include/Operation.h @@ -19,7 +19,7 @@ #define OPERATION #include "../include/Device.h" -//FIXME: i guess it's better to split Operation in several (sub)classes for increased efficiency/clearity + namespace GParted { @@ -62,37 +62,30 @@ class Operation public: Operation() ; - Operation( const Device & device, const Partition &, const Partition &, OperationType ); - - //this one can be a little confusing, it *DOES NOT* change any visual representation. - //It only applies the operation to the list with partitions. - //this new list can be used to change the visual representation. For real writing to disk, see Apply_To_Disk() - void Apply_Operation_To_Visual( std::vector & partitions ); + virtual ~Operation() {} + virtual void apply_to_visual( std::vector & partitions ) = 0 ; + //public variables Device device ; - OperationType operationtype; - Glib::RefPtr operation_icon ; - Partition partition_original; //the original situation - Partition partition_new; //the new situation ( can be an whole new partition or simply the old one with a new size or.... ) - Glib::ustring str_operation ; + OperationType type ; + Partition partition_original ; + Partition partition_new ; + + Glib::RefPtr icon ; + Glib::ustring description ; - //for copy operation.. - Glib::ustring copied_partition_path ; - OperationDetails operation_details ; -private: - void Insert_Unallocated( std::vector & partitions, Sector start, Sector end, bool inside_extended ); - int Get_Index_Original( std::vector & partitions ) ; - int get_index_extended( const std::vector & partitions ) ; +protected: + int find_index_original( const std::vector & partitions ) ; + int find_index_extended( const std::vector & partitions ) ; + void insert_unallocated( std::vector & partitions, Sector start, Sector end, bool inside_extended ); - void Apply_Delete_To_Visual( std::vector & partitions ); - void Apply_Create_To_Visual( std::vector & partitions ); - void Apply_Resize_Move_To_Visual( std::vector & partitions ); - void Apply_Resize_Move_Extended_To_Visual( std::vector & partitions ); - - Glib::ustring Get_String(); //only used in c'tor + virtual void create_description() = 0 ; + + int index ; + int index_extended ; }; } //GParted diff --git a/include/OperationCopy.h b/include/OperationCopy.h new file mode 100644 index 00000000..07e5a4a8 --- /dev/null +++ b/include/OperationCopy.h @@ -0,0 +1,44 @@ +/* Copyright (C) 2004 Bart 'plors' Hakvoort + * + * 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 OPERATION_COPY +#define OPERATION_COPY + +#include "../include/Operation.h" + +namespace GParted +{ + +class OperationCopy : public Operation +{ +public: + OperationCopy( const Device & device, + const Partition & partition_orig, + const Partition & partition_new, + const Partition & partition_copied) ; + + void apply_to_visual( std::vector & partitions ) ; + + Partition partition_copied ; + +private: + void create_description() ; +} ; + +} //GParted + +#endif //OPERATION_COPY diff --git a/include/OperationCreate.h b/include/OperationCreate.h new file mode 100644 index 00000000..58a4a6d2 --- /dev/null +++ b/include/OperationCreate.h @@ -0,0 +1,41 @@ +/* Copyright (C) 2004 Bart 'plors' Hakvoort + * + * 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 OPERATION_CREATE +#define OPERATION_CREATE + +#include "../include/Operation.h" + +namespace GParted +{ + +class OperationCreate : public Operation +{ +public: + OperationCreate( const Device & device, + const Partition & partition_orig, + const Partition & partition_new ) ; + + void apply_to_visual( std::vector & partitions ) ; + +private: + void create_description() ; +} ; + +} //GParted + +#endif //OPERATION_CREATE diff --git a/include/OperationDelete.h b/include/OperationDelete.h new file mode 100644 index 00000000..8a7ae2fb --- /dev/null +++ b/include/OperationDelete.h @@ -0,0 +1,40 @@ +/* Copyright (C) 2004 Bart 'plors' Hakvoort + * + * 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 OPERATION_DELETE +#define OPERATION_DELETE + +#include "../include/Operation.h" + +namespace GParted +{ + +class OperationDelete : public Operation +{ +public: + OperationDelete( const Device & device, const Partition & partition_orig ) ; + + void apply_to_visual( std::vector & partitions ) ; + +private: + void create_description() ; + void remove_original_and_adjacent_unallocated( std::vector & partitions, int index_orig ) ; +} ; + +} //GParted + +#endif //OPERATION_DELETE diff --git a/include/OperationFormat.h b/include/OperationFormat.h new file mode 100644 index 00000000..bf5494a1 --- /dev/null +++ b/include/OperationFormat.h @@ -0,0 +1,41 @@ +/* Copyright (C) 2004 Bart 'plors' Hakvoort + * + * 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 OPERATION_FORMAT +#define OPERATION_FORMAT + +#include "../include/Operation.h" + +namespace GParted +{ + +class OperationFormat : public Operation +{ +public: + OperationFormat( const Device & device, + const Partition & partition_orig, + const Partition & partition_new ) ; + + void apply_to_visual( std::vector & partitions ) ; + +private: + void create_description() ; +} ; + +} //GParted + +#endif //OPERATION_FORMAT diff --git a/include/OperationResizeMove.h b/include/OperationResizeMove.h new file mode 100644 index 00000000..9c7061d2 --- /dev/null +++ b/include/OperationResizeMove.h @@ -0,0 +1,46 @@ +/* Copyright (C) 2004 Bart 'plors' Hakvoort + * + * 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 OPERATION_RESIZEMOVE +#define OPERATION_RESIZEMOVE + +#include "../include/Operation.h" + +namespace GParted +{ + +class OperationResizeMove : public Operation +{ +public: + OperationResizeMove( const Device & device, + const Partition & partition_orig, + const Partition & partition_new ) ; + + void apply_to_visual( std::vector & partitions ) ; + +private: + void create_description() ; + + void apply_normal_to_visual( std::vector & partitions ) ; + void apply_extended_to_visual( std::vector & partitions ) ; + + void remove_adjacent_unallocated( std::vector & partitions, int index_orig ) ; +} ; + +} //GParted + +#endif //OPERATION_RESIZEMOVE diff --git a/include/Win_GParted.h b/include/Win_GParted.h index 974e31d6..86f5c0c0 100644 --- a/include/Win_GParted.h +++ b/include/Win_GParted.h @@ -63,10 +63,8 @@ private: //Fill txtview_device_info_buffer with some information about the selected device void Fill_Label_Device_Info( bool clear = false ); - //overridden signalhandler - bool on_delete_event( GdkEventAny* ) ; - void Add_Operation( OperationType, const Partition & ); + void Add_Operation( OperationType operationtype, const Partition & new_partition, int index = -1 ) ; void Refresh_Visual(); bool Quit_Check_Operations(); void set_valid_operations() ; @@ -124,6 +122,7 @@ private: void combo_devices_changed(); void radio_devices_changed( unsigned int item ) ; void on_signal_show() ; + bool on_delete_event( GdkEventAny* ) ; void menu_gparted_refresh_devices(); void menu_gparted_filesystems(); @@ -151,13 +150,14 @@ private: void activate_disklabel() ; void activate_undo(); + void remove_operation( int index = -1, bool remove_all = false ) ; void activate_apply(); //private variables unsigned int current_device ; Partition selected_partition, copied_partition; std::vector devices; - std::vector operations; + std::vector operations; //gui stuff Gtk::HPaned hpaned_main; @@ -219,7 +219,7 @@ private: treeview_operations_Columns treeview_operations_columns; //usefull variables which are used by many different functions... - bool any_extended;//used in some checks + int index_extended ; //position of the extended partition (-1 means there isn't one) unsigned short primary_count ;//primary_count checks for max. of 4 pimary partitions unsigned short new_count;//new_count keeps track of the new created partitions FS fs ; diff --git a/po/POTFILES.in b/po/POTFILES.in index 2b79b755..ab9ee93c 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -10,7 +10,11 @@ src/Dialog_Partition_New.cc src/Dialog_Partition_Resize_Move.cc src/Dialog_Progress.cc src/GParted_Core.cc -src/Operation.cc +src/OperationCopy.cc +src/OperationCreate.cc +src/OperationDelete.cc +src/OperationFormat.cc +src/OperationResizeMove.cc src/Partition.cc src/TreeView_Detail.cc src/Utils.cc diff --git a/src/Dialog_Base_Partition.cc b/src/Dialog_Base_Partition.cc index e11384b5..4b96cfea 100644 --- a/src/Dialog_Base_Partition.cc +++ b/src/Dialog_Base_Partition.cc @@ -20,10 +20,11 @@ namespace GParted { -Dialog_Base_Partition::Dialog_Base_Partition( ) +Dialog_Base_Partition::Dialog_Base_Partition() { this ->set_has_separator( false ) ; -//FIXME: somehow the 'off by a few' MiB's warning disappeared. I need to display it whenever the round to cylinders isn't checked. +//FIXME: somehow the 'off by a few' MiB's warning disappeared. +//I need to display it whenever the round to cylinders isn't checked. frame_resizer_base = NULL; GRIP = false ; this ->fixed_start = false ; @@ -128,14 +129,14 @@ Partition Dialog_Base_Partition::Get_New_Partition() //the new partition thinks it's bigger then it can be. Here we solve this. if ( selected_partition .sector_start < START ) selected_partition .sector_start = START ; - if ( selected_partition .sector_end > (START + total_length) ) - selected_partition .sector_end = START + total_length ; + if ( selected_partition .sector_end > (START + total_length -1) ) + selected_partition .sector_end = START + total_length -1 ; - //grow a bit into small freespace ( < 1MB ) - if ( (selected_partition .sector_start - START) < MEBIBYTE ) + //grow a bit into small freespace ( < 1MiB ) + if ( (selected_partition .sector_start - START) < MEBIBYTE ) selected_partition .sector_start = START ; - if ( ( START + total_length - selected_partition .sector_end ) < MEBIBYTE ) - selected_partition .sector_end = START + total_length ; + if ( ( START + total_length -1 - selected_partition .sector_end ) < MEBIBYTE ) + selected_partition .sector_end = START + total_length -1 ; //set new value of unused.. if ( selected_partition .sectors_used != -1 ) diff --git a/src/Dialog_Disklabel.cc b/src/Dialog_Disklabel.cc index 65541543..3ed62227 100644 --- a/src/Dialog_Disklabel.cc +++ b/src/Dialog_Disklabel.cc @@ -63,7 +63,7 @@ Dialog_Disklabel::Dialog_Disklabel( const Glib::ustring & device_path, const std hbox = manage( new Gtk::HBox( false, 5 ) ) ; hbox ->set_border_width( 5 ) ; - str_temp = _("Select new labeltype:") ; + str_temp = _("Select new labeltype:") ;//FIXME: this label shouldn't be topaligned.. str_temp += "\t" ; hbox ->pack_start( * Utils::mk_label( str_temp ), Gtk::PACK_SHRINK ); expander_advanced .add( *hbox ) ; diff --git a/src/Dialog_Filesystems.cc b/src/Dialog_Filesystems.cc index 77802ea0..106cdd64 100644 --- a/src/Dialog_Filesystems.cc +++ b/src/Dialog_Filesystems.cc @@ -17,10 +17,12 @@ #include "../include/Dialog_Filesystems.h" +#include + namespace GParted { -Dialog_Filesystems::Dialog_Filesystems( ) +Dialog_Filesystems::Dialog_Filesystems() { this ->set_title( _("Filesystems") ) ; this ->set_has_separator( false ) ; @@ -35,25 +37,25 @@ Dialog_Filesystems::Dialog_Filesystems( ) treeview_filesystems .append_column( _("Move"), treeview_filesystems_columns .move ); treeview_filesystems .append_column( _("Copy"), treeview_filesystems_columns .copy ); - treeview_filesystems .get_selection( ) ->set_mode( Gtk::SELECTION_NONE ); - this ->get_vbox( ) ->pack_start( treeview_filesystems ) ; + treeview_filesystems .get_selection() ->set_mode( Gtk::SELECTION_NONE ); + this ->get_vbox() ->pack_start( treeview_filesystems ) ; this ->add_button( Gtk::Stock::REFRESH, Gtk::RESPONSE_OK ); this ->add_button( Gtk::Stock::CLOSE, Gtk::RESPONSE_CLOSE ) ->grab_focus() ; - this ->show_all_children( ) ; + this ->show_all_children() ; } void Dialog_Filesystems::Load_Filesystems( const std::vector< FS > & FILESYSTEMS ) { - liststore_filesystems ->clear( ) ; + liststore_filesystems ->clear() ; - for ( unsigned short t = 0; t < FILESYSTEMS .size( ) -1 ; t++ ) + for ( unsigned short t = 0; t < FILESYSTEMS .size() -1 ; t++ ) Show_Filesystem( FILESYSTEMS[ t ] ) ; } void Dialog_Filesystems::Show_Filesystem( const FS & fs ) { - treerow = *( liststore_filesystems ->append( ) ); + treerow = *( liststore_filesystems ->append() ); treerow[ treeview_filesystems_columns .filesystem ] = Utils::Get_Filesystem_String( fs .filesystem ) ; treerow[ treeview_filesystems_columns .create ] = @@ -72,7 +74,7 @@ void Dialog_Filesystems::Show_Filesystem( const FS & fs ) render_icon( fs .copy ? Gtk::Stock::APPLY : Gtk::Stock::CANCEL, Gtk::ICON_SIZE_LARGE_TOOLBAR ); } -Dialog_Filesystems::~Dialog_Filesystems( ) +Dialog_Filesystems::~Dialog_Filesystems() { } diff --git a/src/Dialog_Partition_Resize_Move.cc b/src/Dialog_Partition_Resize_Move.cc index 2ec54519..003c3e48 100644 --- a/src/Dialog_Partition_Resize_Move.cc +++ b/src/Dialog_Partition_Resize_Move.cc @@ -27,7 +27,8 @@ Dialog_Partition_Resize_Move::Dialog_Partition_Resize_Move( const FS & fs, Secto BUF = cylinder_size * 2 ; } -void Dialog_Partition_Resize_Move::Set_Data( const Partition & selected_partition, const std::vector & partitions ) +void Dialog_Partition_Resize_Move::Set_Data( const Partition & selected_partition, + const std::vector & partitions ) { GRIP = true ; //prevents on spinbutton_changed from getting activated prematurely @@ -94,7 +95,7 @@ void Dialog_Partition_Resize_Move::Resize_Move_Normal( const std::vector 0 && partitions[t -1].type == GParted::TYPE_UNALLOCATED ) + if ( t > 0 && partitions[t -1] .type == GParted::TYPE_UNALLOCATED ) { previous = partitions[t -1] .get_length() ; START = partitions[t -1] .sector_start ; diff --git a/src/Dialog_Progress.cc b/src/Dialog_Progress.cc index e9501cae..93ecb2f9 100644 --- a/src/Dialog_Progress.cc +++ b/src/Dialog_Progress.cc @@ -25,7 +25,7 @@ namespace GParted { -Dialog_Progress::Dialog_Progress( const std::vector & operations ) +Dialog_Progress::Dialog_Progress( const std::vector & operations ) { this ->set_resizable( false ) ; this ->set_has_separator( false ) ; @@ -73,12 +73,12 @@ Dialog_Progress::Dialog_Progress( const std::vector & operations ) //fill 'er up for ( unsigned int t = 0 ; t < operations .size() ; t++ ) { - this ->operations[ t ] .operation_details .description = "" + operations[ t ] .str_operation + "" ; + this ->operations[ t ] ->operation_details .description = "" + operations[ t ] ->description + "" ; treerow = *( treestore_operations ->append() ); - treerow[ treeview_operations_columns .operation_icon ] = operations[ t ] .operation_icon ; + treerow[ treeview_operations_columns .operation_icon ] = operations[ t ] ->icon ; treerow[ treeview_operations_columns .operation_description ] = - this ->operations[ t ] .operation_details .description ; + this ->operations[ t ] ->operation_details .description ; treerow[ treeview_operations_columns .hidden_status ] = OperationDetails::NONE ; } @@ -155,7 +155,7 @@ void Dialog_Progress::on_signal_show() { for ( t = 0 ; t < operations .size() && succes && ! cancel ; t++ ) { - label_current .set_markup( "" + operations[ t ] .str_operation + "\n" ) ; + label_current .set_markup( "" + operations[ t ] ->description + "\n" ) ; progressbar_all .set_text( String::ucompose( _("%1 of %2 operations completed"), t, operations .size() ) ) ; progressbar_all .set_fraction( fraction * t ) ; @@ -163,8 +163,8 @@ void Dialog_Progress::on_signal_show() treerow = treestore_operations ->children()[ t ] ; //set status to 'execute' - operations[ t ] .operation_details .status = OperationDetails::EXECUTE ; - update_operation_details( treerow, operations[ t ] .operation_details ) ; + operations[ t ] ->operation_details .status = OperationDetails::EXECUTE ; + update_operation_details( treerow, operations[ t ] ->operation_details ) ; //set focus... treeview_operations .set_cursor( static_cast( treerow ) ) ; @@ -175,7 +175,7 @@ void Dialog_Progress::on_signal_show() while ( pulse ) { - update_operation_details( treerow, operations[ t ] .operation_details ) ; + update_operation_details( treerow, operations[ t ] ->operation_details ) ; progressbar_current .pulse() ; @@ -186,9 +186,9 @@ void Dialog_Progress::on_signal_show() } //set status (succes/error) for this operation - operations[ t ] .operation_details .status = + operations[ t ] ->operation_details .status = succes ? OperationDetails::SUCCES : OperationDetails::ERROR ; - update_operation_details( treerow, operations[ t ] .operation_details ) ; + update_operation_details( treerow, operations[ t ] ->operation_details ) ; } //add save button @@ -259,7 +259,7 @@ void * Dialog_Progress::static_pthread_apply_operation( void * p_dialog_progress Dialog_Progress *dp = static_cast( p_dialog_progress ) ; dp ->succes = dp ->signal_apply_operation .emit( dp ->operations[ dp ->t ] ) ; - + dp ->pulse = false ; return NULL ; @@ -306,7 +306,7 @@ void Dialog_Progress::on_save() out << "GParted " << VERSION << "

" << std::endl ; for ( unsigned int t = 0 ; t < operations .size() ; t++ ) { - echo_operation_details( operations[ t ] .operation_details, out ) ; + echo_operation_details( operations[ t ] ->operation_details, out ) ; out << "
========================================

" << std::endl ; } diff --git a/src/DrawingAreaVisualDisk.cc b/src/DrawingAreaVisualDisk.cc index c52cf478..28978a4e 100644 --- a/src/DrawingAreaVisualDisk.cc +++ b/src/DrawingAreaVisualDisk.cc @@ -19,7 +19,7 @@ #define MAIN_BORDER 5 #define BORDER 4 -#define SEP 5 +#define SEP 4 #define HEIGHT 70 + 2 * MAIN_BORDER namespace GParted diff --git a/src/GParted_Core.cc b/src/GParted_Core.cc index 0277fb7e..aefb4b0a 100644 --- a/src/GParted_Core.cc +++ b/src/GParted_Core.cc @@ -1,4 +1,27 @@ +/* Copyright (C) 2004 Bart 'plors' Hakvoort + * + * 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/Win_GParted.h" #include "../include/GParted_Core.h" +#include "../include/OperationCopy.h" +#include "../include/OperationCreate.h" +#include "../include/OperationDelete.h" +#include "../include/OperationFormat.h" +#include "../include/OperationResizeMove.h" #include #include @@ -542,28 +565,28 @@ void GParted_Core::insert_unallocated( const Glib::ustring & device_path, } } -bool GParted_Core::apply_operation_to_disk( Operation & operation ) +bool GParted_Core::apply_operation_to_disk( Operation * operation ) { - switch ( operation .operationtype ) + switch ( operation ->type ) { case DELETE: - return Delete( operation .partition_original, operation .operation_details .sub_details ) ; + return Delete( operation ->partition_original, operation ->operation_details .sub_details ) ; case CREATE: - return create( operation .device, - operation .partition_new, - operation .operation_details .sub_details ) ; + return create( operation ->device, + operation ->partition_new, + operation ->operation_details .sub_details ) ; case RESIZE_MOVE: - return resize( operation .device, - operation .partition_original, - operation .partition_new, - operation .operation_details .sub_details ) ; + return resize( operation ->device, + operation ->partition_original, + operation ->partition_new, + operation ->operation_details .sub_details ) ; case FORMAT: - return format( operation .partition_new, operation .operation_details .sub_details ) ; + return format( operation ->partition_new, operation ->operation_details .sub_details ) ; case COPY: - return copy( operation .copied_partition_path, - operation .partition_new, - operation .partition_new .get_length() - operation .device .cylsize, - operation .operation_details .sub_details ) ; + return copy( static_cast( operation ) ->partition_copied .get_path(), + operation ->partition_new, + static_cast( operation ) ->partition_copied .get_length(), + operation ->operation_details .sub_details ) ; } return false ; diff --git a/src/Makefile.am b/src/Makefile.am index 5d262107..8fb628a9 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -25,6 +25,11 @@ gparted_SOURCES = \ Frame_Resizer_Extended.cc \ GParted_Core.cc \ Operation.cc \ + OperationCopy.cc \ + OperationCreate.cc \ + OperationDelete.cc \ + OperationFormat.cc \ + OperationResizeMove.cc \ Partition.cc \ TreeView_Detail.cc \ Utils.cc \ diff --git a/src/Operation.cc b/src/Operation.cc index 6cfacf2a..c2ca581e 100644 --- a/src/Operation.cc +++ b/src/Operation.cc @@ -18,144 +18,31 @@ namespace GParted { - + Operation::Operation() { } -Operation::Operation( const Device & device, - const Partition & partition_original, - const Partition & partition_new, - OperationType operationtype ) +int Operation::find_index_original( const std::vector & partitions ) { - this ->device = device ; - this ->partition_original = partition_original; - this ->partition_new = partition_new; - this ->operationtype = operationtype; - - str_operation = Get_String() ; - - if ( operationtype == COPY ) - { - copied_partition_path = partition_new .get_path() ; - this ->partition_new .add_path( - String::ucompose( _("copy of %1"), this ->partition_new .get_path() ), - true ) ; - } + for ( unsigned int t = 0 ; t < partitions .size() ; t++ ) + if ( partition_original .sector_start >= partitions[ t ] .sector_start && + partition_original .sector_end <= partitions[ t ] .sector_end ) + return t ; + + return -1 ; } -Glib::ustring Operation::Get_String() +int Operation::find_index_extended( const std::vector & partitions ) { - Glib::ustring temp ; - Sector diff ; + for ( unsigned int t = 0 ; t < partitions .size() ; t++ ) + if ( partitions[ t ] .type == GParted::TYPE_EXTENDED ) + return t ; - switch ( operationtype ) - { - case DELETE : - if (partition_original.type == GParted::TYPE_LOGICAL) - temp = _("Logical Partition") ; - else - temp = partition_original .get_path() ; - - /*TO TRANSLATORS: looks like Delete /dev/hda2 (ntfs, 345 MiB) from /dev/hda */ - return String::ucompose( _("Delete %1 (%2, %3) from %4"), - temp, - Utils::Get_Filesystem_String( partition_original .filesystem ), - Utils::format_size( partition_original .get_length() ), - device .get_path() ) ; - - case CREATE : - switch( partition_new.type ) - { - case GParted::TYPE_PRIMARY : - temp = _("Primary Partition"); - break; - case GParted::TYPE_LOGICAL : - temp = _("Logical Partition") ; - break; - case GParted::TYPE_EXTENDED : - temp = _("Extended Partition"); - break; - - default : - break; - } - /*TO TRANSLATORS: looks like Create Logical Partition #1 (ntfs, 345 MiB) on /dev/hda */ - return String::ucompose( _("Create %1 #%2 (%3, %4) on %5"), - temp, - partition_new .partition_number, - Utils::Get_Filesystem_String( partition_new .filesystem ), - Utils::format_size( partition_new .get_length() ), - device .get_path() ) ; - - case RESIZE_MOVE: - //if startsector has changed we consider it a move - diff = std::abs( partition_new .sector_start - partition_original .sector_start ) ; - if ( diff ) - { - if ( partition_new .sector_start > partition_original .sector_start ) - temp = String::ucompose( _("Move %1 forward by %2"), - partition_new .get_path(), - Utils::format_size( diff ) ) ; - else - temp = String::ucompose( _("Move %1 backward by %2"), - partition_new .get_path(), - Utils::format_size( diff ) ) ; - } - - //check if size has changed - diff = std::abs( partition_original .get_length() - partition_new .get_length() ) ; - if ( diff ) - { - if ( temp .empty() ) - temp = String::ucompose( _("Resize %1 from %2 to %3"), - partition_new .get_path(), - Utils::format_size( partition_original .get_length() ), - Utils::format_size( partition_new .get_length() ) ) ; - else - temp += " " + String::ucompose( _("and Resize %1 from %2 to %3"), - partition_new .get_path(), - Utils::format_size( partition_original .get_length() ), - Utils::format_size( partition_new .get_length() ) ) ; - } - - return temp; - - case FORMAT : - /*TO TRANSLATORS: looks like Format /dev/hda4 as linux-swap */ - return String::ucompose( _("Format %1 as %2"), - partition_original .get_path(), - Utils::Get_Filesystem_String( partition_new .filesystem ) ) ; - - case COPY : - /*TO TRANSLATORS: looks like Copy /dev/hda4 to /dev/hdd (start at 250 MiB) */ - return String::ucompose( _("Copy %1 to %2 (start at %3)"), - partition_new .get_path(), - device .get_path(), - Utils::format_size( partition_new .sector_start ) ) ; - - default : - return ""; - } - + return -1 ; } -void Operation::Apply_Operation_To_Visual( std::vector & partitions ) -{ - switch ( operationtype ) - { - case DELETE : Apply_Delete_To_Visual( partitions ) ; - break ; - case RESIZE_MOVE: Apply_Resize_Move_To_Visual( partitions ) ; - break ; - case CREATE : - case FORMAT : - case COPY : Apply_Create_To_Visual( partitions ) ; - break ; - } -} - -void Operation::Insert_Unallocated( std::vector & partitions, Sector start, Sector end, bool inside_extended ) +void Operation::insert_unallocated( std::vector & partitions, Sector start, Sector end, bool inside_extended ) { Partition UNALLOCATED ; UNALLOCATED .Set_Unallocated( device .get_path(), 0, 0, inside_extended ) ; @@ -200,123 +87,4 @@ void Operation::Insert_Unallocated( std::vector & partitions, Sector } } -int Operation::Get_Index_Original( std::vector & partitions ) -{ - for ( int t = 0 ; t < static_cast( partitions .size() ) ; t++ ) - if ( partition_original .sector_start >= partitions[ t ] .sector_start && - partition_original .sector_end <= partitions[ t ] .sector_end ) - { - //remove unallocated space preceding the original partition - if ( t -1 >= 0 && partitions[ t -1 ] .type == GParted::TYPE_UNALLOCATED ) - partitions .erase( partitions .begin() + --t ); - - //remove unallocated space following the original partition - if ( t +1 < static_cast( partitions .size() ) && - partitions[ t +1 ] .type == GParted::TYPE_UNALLOCATED ) - partitions .erase( partitions .begin() + t +1 ); - - return t ; - } - - return -1 ; -} - -int Operation::get_index_extended( const std::vector & partitions ) -{ - for ( unsigned int t = 0 ; t < partitions .size() ; t++ ) - if ( partitions[ t ] .type == GParted::TYPE_EXTENDED ) - return t ; - - return -1 ; -} - -void Operation::Apply_Delete_To_Visual( std::vector & partitions ) -{ - if ( ! partition_original .inside_extended ) - { - partitions .erase( partitions .begin() + Get_Index_Original( partitions ) ); - - Insert_Unallocated( partitions, 0, device .length -1, false ) ; - } - else - { - unsigned int ext = get_index_extended( partitions ) ; - partitions[ ext ] .logicals .erase( partitions[ ext ] .logicals .begin() + Get_Index_Original( partitions[ ext ] .logicals ) ); - - //if deleted partition was logical we have to decrease the partitionnumbers of the logicals - //with higher numbers by one (only if its a real partition) - if ( partition_original .status != GParted::STAT_NEW ) - for ( unsigned int t = 0 ; t < partitions[ ext ] .logicals .size( ) ; t++ ) - if ( partitions[ ext ] .logicals[ t ] .partition_number > partition_original .partition_number ) - partitions[ ext ] .logicals[ t ] .Update_Number( partitions[ ext ] .logicals[ t ] .partition_number -1 ); - - - Insert_Unallocated( partitions[ ext ] .logicals, - partitions[ ext ] .sector_start, - partitions[ ext ] .sector_end, - true ) ; - } -} - -void Operation::Apply_Create_To_Visual( std::vector & partitions ) -{ - //FIXME (segfault): gdb bt suggest this function. steps to reproduce on 'voyager': - //-shrink /dev/hda5 - //-create a small partition in the middle of the new unallocated space - //-grow /dev/hda5 again - //-grow the new partition - //perform steps in sequence without applying - - if ( ! partition_original .inside_extended ) - { - partitions[ Get_Index_Original( partitions ) ] = partition_new ; - - Insert_Unallocated( partitions, 0, device .length -1, false ) ; - } - else - { - unsigned int ext = get_index_extended( partitions ) ; - partitions[ ext ] .logicals[ Get_Index_Original( partitions[ ext ] .logicals ) ] = partition_new ; - - Insert_Unallocated( partitions[ ext ] .logicals, - partitions[ ext ] .sector_start, - partitions[ ext ] .sector_end, - true ) ; - } -} - -void Operation::Apply_Resize_Move_To_Visual( std::vector & partitions) -{ - if ( partition_original .type == GParted::TYPE_EXTENDED ) - Apply_Resize_Move_Extended_To_Visual( partitions ) ; - else - Apply_Create_To_Visual( partitions ) ; -} - -void Operation::Apply_Resize_Move_Extended_To_Visual( std::vector & partitions ) -{ - //stuff OUTSIDE extended partition - unsigned int ext = Get_Index_Original( partitions ) ; - partitions[ ext ] .sector_start = partition_new .sector_start ; - partitions[ ext ] .sector_end = partition_new .sector_end ; - - Insert_Unallocated( partitions, 0, device .length -1, false ) ; - - //stuff INSIDE extended partition - ext = get_index_extended( partitions ) ; - - if ( partitions[ ext ] .logicals .size() && - partitions[ ext ] .logicals .front() .type == GParted::TYPE_UNALLOCATED ) - partitions[ ext ] .logicals .erase( partitions[ ext ] .logicals .begin() ) ; - - if ( partitions[ ext ] .logicals .size() && - partitions[ ext ] .logicals .back() .type == GParted::TYPE_UNALLOCATED ) - partitions[ ext ] .logicals .erase( partitions[ ext ] .logicals .end() -1 ) ; - - Insert_Unallocated( partitions[ ext ] .logicals, - partitions[ ext ] .sector_start, - partitions[ ext ] .sector_end, - true ) ; -} - } //GParted diff --git a/src/OperationCopy.cc b/src/OperationCopy.cc new file mode 100644 index 00000000..88ab5ec3 --- /dev/null +++ b/src/OperationCopy.cc @@ -0,0 +1,82 @@ +/* Copyright (C) 2004 Bart 'plors' Hakvoort + * + * 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/OperationCopy.h" + +namespace GParted +{ + +OperationCopy::OperationCopy( const Device & device, + const Partition & partition_orig, + const Partition & partition_new, + const Partition & partition_copied ) +{ + type = GParted::COPY ; + + this ->device = device ; + this ->partition_original = partition_orig ; + this ->partition_new = partition_new ; + this ->partition_copied = partition_copied ; + + create_description() ; +} + +void OperationCopy::apply_to_visual( std::vector & partitions ) +{ + index = index_extended = -1 ; + + 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 ; + + insert_unallocated( partitions[ index_extended ] .logicals, + partitions[ index_extended ] .sector_start, + partitions[ index_extended ] .sector_end, + true ) ; + } + } + else + { + index = find_index_original( partitions ) ; + + if ( index >= 0 ) + { + partitions[ index ] = partition_new ; + + insert_unallocated( partitions, 0, device .length -1, false ) ; + } + } +} + +void OperationCopy::create_description() +{ + /*TO TRANSLATORS: looks like Copy /dev/hda4 to /dev/hdd (start at 250 MiB) */ + description = String::ucompose( _("Copy %1 to %2 (start at %3)"), + partition_new .get_path(), + device .get_path(), + Utils::format_size( partition_new .sector_start ) ) ; +} + +} //GParted + diff --git a/src/OperationCreate.cc b/src/OperationCreate.cc new file mode 100644 index 00000000..0d348aaf --- /dev/null +++ b/src/OperationCreate.cc @@ -0,0 +1,97 @@ +/* Copyright (C) 2004 Bart 'plors' Hakvoort + * + * 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/OperationCreate.h" + +namespace GParted +{ + +OperationCreate::OperationCreate( const Device & device, + const Partition & partition_orig, + const Partition & partition_new ) +{ + type = GParted::CREATE ; + + this ->device = device ; + this ->partition_original = partition_orig ; + this ->partition_new = partition_new ; + + create_description() ; +} + +void OperationCreate::apply_to_visual( std::vector & partitions ) +{ + index = index_extended = -1 ; + + 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 ; + + insert_unallocated( partitions[ index_extended ] .logicals, + partitions[ index_extended ] .sector_start, + partitions[ index_extended ] .sector_end, + true ) ; + } + } + else + { + index = find_index_original( partitions ) ; + + if ( index >= 0 ) + { + partitions[ index ] = partition_new ; + + insert_unallocated( partitions, 0, device .length -1, false ) ; + } + } +} + +void OperationCreate::create_description() +{ + switch( partition_new .type ) + { + case GParted::TYPE_PRIMARY : + description = _("Primary Partition"); + break; + case GParted::TYPE_LOGICAL : + description = _("Logical Partition") ; + break; + case GParted::TYPE_EXTENDED : + description = _("Extended Partition"); + break; + + default : + break; + } + /*TO TRANSLATORS: looks like Create Logical Partition #1 (ntfs, 345 MiB) on /dev/hda */ + description = String::ucompose( _("Create %1 #%2 (%3, %4) on %5"), + description, + partition_new .partition_number, + Utils::Get_Filesystem_String( partition_new .filesystem ), + Utils::format_size( partition_new .get_length() ), + device .get_path() ) ; +} + +} //GParted + diff --git a/src/OperationDelete.cc b/src/OperationDelete.cc new file mode 100644 index 00000000..c1b59870 --- /dev/null +++ b/src/OperationDelete.cc @@ -0,0 +1,105 @@ +/* Copyright (C) 2004 Bart 'plors' Hakvoort + * + * 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/OperationDelete.h" + +namespace GParted +{ + +OperationDelete::OperationDelete( const Device & device, const Partition & partition_orig ) +{ + type = GParted::DELETE ; + + this ->device = device ; + this ->partition_original = partition_orig ; + + create_description() ; +} + +void OperationDelete::apply_to_visual( std::vector & 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 ) + { + remove_original_and_adjacent_unallocated( partitions[ index_extended ] .logicals, index ) ; + + insert_unallocated( partitions[ index_extended ] .logicals, + partitions[ index_extended ] .sector_start, + partitions[ index_extended ] .sector_end, + true ) ; + + //if deleted partition was logical we have to decrease the partitionnumbers of the logicals + //with higher numbers by one (only if its a real partition) + if ( partition_original .status != GParted::STAT_NEW ) + for ( unsigned int t = 0 ; t < partitions[ index_extended ] .logicals .size() ; t++ ) + if ( partitions[ index_extended ] .logicals[ t ] .partition_number > + partition_original .partition_number ) + partitions[ index_extended ] .logicals[ t ] .Update_Number( + partitions[ index_extended ] .logicals[ t ] .partition_number -1 ); + } + } + else + { + index = find_index_original( partitions ) ; + + if ( index >= 0 ) + { + remove_original_and_adjacent_unallocated( partitions, index ) ; + + insert_unallocated( partitions, 0, device .length -1, false ) ; + } + } +} + +void OperationDelete::create_description() +{ + if ( partition_original.type == GParted::TYPE_LOGICAL ) + description = _("Logical Partition") ; + else + description = partition_original .get_path() ; + + /*TO TRANSLATORS: looks like Delete /dev/hda2 (ntfs, 345 MiB) from /dev/hda */ + description = String::ucompose( _("Delete %1 (%2, %3) from %4"), + description, + Utils::Get_Filesystem_String( partition_original .filesystem ), + Utils::format_size( partition_original .get_length() ), + partition_original .device_path ) ; +} + +void OperationDelete::remove_original_and_adjacent_unallocated( std::vector & partitions, int index_orig ) +{ + //remove unallocated space following the original partition + if ( index_orig +1 < static_cast( partitions .size() ) && + partitions[ index_orig +1 ] .type == GParted::TYPE_UNALLOCATED ) + partitions .erase( partitions .begin() + index_orig +1 ); + + //remove unallocated space preceding the original partition and the original partition + if ( index_orig -1 >= 0 && partitions[ index_orig -1 ] .type == GParted::TYPE_UNALLOCATED ) + partitions .erase( partitions .begin() + --index_orig ) ; + + //and finally remove the original partition + partitions .erase( partitions .begin() + index_orig ) ; +} + +} //GParted + diff --git a/src/OperationFormat.cc b/src/OperationFormat.cc new file mode 100644 index 00000000..bffde475 --- /dev/null +++ b/src/OperationFormat.cc @@ -0,0 +1,66 @@ +/* Copyright (C) 2004 Bart 'plors' Hakvoort + * + * 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/OperationFormat.h" + +namespace GParted +{ + +OperationFormat::OperationFormat( const Device & device, + const Partition & partition_orig, + const Partition & partition_new ) +{ + type = GParted::FORMAT ; + + this ->device = device ; + this ->partition_original = partition_orig ; + this ->partition_new = partition_new ; + + create_description() ; +} + +void OperationFormat::apply_to_visual( std::vector & 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 OperationFormat::create_description() +{ + /*TO TRANSLATORS: looks like Format /dev/hda4 as linux-swap */ + description = String::ucompose( _("Format %1 as %2"), + partition_original .get_path(), + Utils::Get_Filesystem_String( partition_new .filesystem ) ) ; +} + +} //GParted + diff --git a/src/OperationResizeMove.cc b/src/OperationResizeMove.cc new file mode 100644 index 00000000..9e70e761 --- /dev/null +++ b/src/OperationResizeMove.cc @@ -0,0 +1,160 @@ +/* Copyright (C) 2004 Bart 'plors' Hakvoort + * + * 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/OperationResizeMove.h" + +namespace GParted +{ + +OperationResizeMove::OperationResizeMove( const Device & device, + const Partition & partition_orig, + const Partition & partition_new ) +{ + type = GParted::RESIZE_MOVE ; + this ->device = device ; + this ->partition_original = partition_orig ; + this ->partition_new = partition_new ; + + create_description() ; +} + +void OperationResizeMove::apply_to_visual( std::vector & partitions ) +{ + index = index_extended = -1 ; + + if ( partition_original .type == GParted::TYPE_EXTENDED ) + apply_extended_to_visual( partitions ) ; + else + apply_normal_to_visual( partitions ) ; +} + +void OperationResizeMove::create_description() +{ + //FIXME:make messages more informative by specifying shrink/grow instead of resize. + //if startsector has changed we consider it a move + Sector diff = std::abs( partition_new .sector_start - partition_original .sector_start ) ; + if ( diff ) + { + if ( diff > 0 ) + description = String::ucompose( _("Move %1 forward by %2"), + partition_new .get_path(), + Utils::format_size( diff ) ) ; + else + description = String::ucompose( _("Move %1 backward by %2"), + partition_new .get_path(), + Utils::format_size( diff ) ) ; + } + + //check if size has changed + diff = std::abs( partition_original .get_length() - partition_new .get_length() ) ; + if ( diff ) + { + if ( description .empty() ) + description = String::ucompose( _("Resize %1 from %2 to %3"), + partition_new .get_path(), + Utils::format_size( partition_original .get_length() ), + Utils::format_size( partition_new .get_length() ) ) ; + else + description += " " + String::ucompose( _("and Resize %1 from %2 to %3"), + partition_new .get_path(), + Utils::format_size( partition_original .get_length() ), + Utils::format_size( partition_new .get_length() ) ) ; + } +} + +void OperationResizeMove::apply_normal_to_visual( std::vector & 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 ; + remove_adjacent_unallocated( partitions[ index_extended ] .logicals, index ) ; + + insert_unallocated( partitions[ index_extended ] .logicals, + partitions[ index_extended ] .sector_start, + partitions[ index_extended ] .sector_end, + true ) ; + } + } + else + { + index = find_index_original( partitions ) ; + + if ( index >= 0 ) + { + partitions[ index ] = partition_new ; + remove_adjacent_unallocated( partitions, index ) ; + + insert_unallocated( partitions, 0, device .length -1, false ) ; + } + } +} + +void OperationResizeMove::apply_extended_to_visual( std::vector & partitions ) +{ + //stuff OUTSIDE extended partition + index_extended = find_index_extended( partitions ) ; + + if ( index_extended >= 0 ) + { + remove_adjacent_unallocated( partitions, index_extended ) ; + + partitions[ index_extended ] .sector_start = partition_new .sector_start ; + partitions[ index_extended ] .sector_end = partition_new .sector_end ; + + insert_unallocated( partitions, 0, device .length -1, false ) ; + } + + //stuff INSIDE extended partition + index_extended = find_index_extended( partitions ) ; + + if ( index_extended >= 0 ) + { + if ( partitions[ index_extended ] .logicals .size() > 0 && + partitions[ index_extended ] .logicals .front() .type == GParted::TYPE_UNALLOCATED ) + partitions[ index_extended ] .logicals .erase( partitions[ index_extended ] .logicals .begin() ) ; + + if ( partitions[ index_extended ] .logicals .size() && + partitions[ index_extended ] .logicals .back() .type == GParted::TYPE_UNALLOCATED ) + partitions[ index_extended ] .logicals .pop_back() ; + + insert_unallocated( partitions[ index_extended ] .logicals, + partitions[ index_extended ] .sector_start, + partitions[ index_extended ] .sector_end, + true ) ; + } +} + +void OperationResizeMove::remove_adjacent_unallocated( std::vector & partitions, int index_orig ) +{ + //remove unallocated space preceding the original partition + if ( index_orig -1 >= 0 && partitions[ index_orig -1 ] .type == GParted::TYPE_UNALLOCATED ) + partitions .erase( partitions .begin() + ( index_orig -1 ) ) ; + + //remove unallocated space following the original partition + if ( index_orig +1 < static_cast( partitions .size() ) && + partitions[ index_orig +1 ] .type == GParted::TYPE_UNALLOCATED ) + partitions .erase( partitions .begin() + index_orig +1 ); +} + +} //GParted diff --git a/src/TreeView_Detail.cc b/src/TreeView_Detail.cc index 0116ed1f..99188428 100644 --- a/src/TreeView_Detail.cc +++ b/src/TreeView_Detail.cc @@ -152,6 +152,7 @@ void TreeView_Detail::create_row( const Gtk::TreeRow & treerow, const Partition treerow[ treeview_detail_columns .status_icon ] = render_icon( Gtk::Stock::DIALOG_AUTHENTICATION, Gtk::ICON_SIZE_BUTTON ); + //FIXME: we should display warningicon in the same column as mounticon if partition is unmounted.. if ( ! partition .error .empty() ) treerow[ treeview_detail_columns .error_icon ] = render_icon( Gtk::Stock::DIALOG_WARNING, Gtk::ICON_SIZE_BUTTON ); diff --git a/src/Win_GParted.cc b/src/Win_GParted.cc index 8774f106..e2056f9c 100644 --- a/src/Win_GParted.cc +++ b/src/Win_GParted.cc @@ -23,6 +23,11 @@ #include "../include/Dialog_Partition_Copy.h" #include "../include/Dialog_Partition_New.h" #include "../include/Dialog_Partition_Info.h" +#include "../include/OperationCopy.h" +#include "../include/OperationCreate.h" +#include "../include/OperationDelete.h" +#include "../include/OperationFormat.h" +#include "../include/OperationResizeMove.h" #include #include @@ -531,41 +536,55 @@ void Win_GParted::Fill_Label_Device_Info( bool clear ) bool Win_GParted::on_delete_event( GdkEventAny *event ) { - return ! Quit_Check_Operations( ); + return ! Quit_Check_Operations(); } -void Win_GParted::Add_Operation( OperationType operationtype, const Partition & new_partition) +void Win_GParted::Add_Operation( OperationType operationtype, const Partition & new_partition, int index ) { - Operation operation( devices[ current_device ], selected_partition, new_partition, operationtype ); - + Operation * operation ; switch ( operationtype ) { case GParted::DELETE : - operation .operation_icon = - render_icon( Gtk::Stock::DELETE, Gtk::ICON_SIZE_MENU ); + operation = new OperationDelete( devices[ current_device ], selected_partition ) ; + operation ->icon = render_icon( Gtk::Stock::DELETE, Gtk::ICON_SIZE_MENU ) ; break; case GParted::CREATE : - operation .operation_icon = - render_icon( Gtk::Stock::NEW, Gtk::ICON_SIZE_MENU ); + operation = new OperationCreate( devices[ current_device ], + selected_partition, + new_partition ) ; + operation ->icon = render_icon( Gtk::Stock::NEW, Gtk::ICON_SIZE_MENU ); break; case GParted::RESIZE_MOVE: - operation .operation_icon = - render_icon( Gtk::Stock::GOTO_LAST, Gtk::ICON_SIZE_MENU ); + operation = new OperationResizeMove( devices[ current_device ], + selected_partition, + new_partition ); + operation ->icon = render_icon( Gtk::Stock::GOTO_LAST, Gtk::ICON_SIZE_MENU ); break; case GParted::FORMAT : - operation .operation_icon = - render_icon( Gtk::Stock::CONVERT, Gtk::ICON_SIZE_MENU ); + operation = new OperationFormat( devices[ current_device ], + selected_partition, + new_partition ); + operation ->icon = render_icon( Gtk::Stock::CONVERT, Gtk::ICON_SIZE_MENU ); break; case GParted::COPY : - operation .operation_icon = - render_icon( Gtk::Stock::COPY, Gtk::ICON_SIZE_MENU ); + operation = new OperationCopy( devices[ current_device ], + selected_partition, + new_partition, + copied_partition ) ; + operation ->icon = render_icon( Gtk::Stock::COPY, Gtk::ICON_SIZE_MENU ); break; } - - operations.push_back( operation ); - - allow_undo( true ); - allow_apply( true ); + + if ( operation ) + { + if ( index >= 0 && index < static_cast( operations .size() ) ) + operations .insert( operations .begin() + index, operation ) ; + else + operations .push_back( operation ); + + allow_undo( true ) ; + allow_apply( true ) ; + } Refresh_Visual(); @@ -573,9 +592,9 @@ void Win_GParted::Add_Operation( OperationType operationtype, const Partition & open_operationslist() ; //make scrollwindow focus on the last operation in the list - Gtk::TreeIter iter = liststore_operations ->children() .end() ; - iter-- ; - treeview_operations .set_cursor( static_cast( static_cast( *iter ) ) ) ; + treeview_operations .set_cursor( + static_cast( static_cast( + *(--liststore_operations ->children() .end()) ) ) ) ; } void Win_GParted::Refresh_Visual() @@ -586,12 +605,12 @@ void Win_GParted::Refresh_Visual() //make all operations visible for ( unsigned int t = 0 ; t < operations .size(); t++ ) { - if ( operations[ t ] .device == devices[ current_device ] ) - operations[ t ] .Apply_Operation_To_Visual( partitions ) ; + if ( operations[ t ] ->device == devices[ current_device ] ) + operations[ t ] ->apply_to_visual( partitions ) ; treerow = *( liststore_operations ->append() ); - treerow[ treeview_operations_columns .operation_description ] = operations[ t ] .str_operation ; - treerow[ treeview_operations_columns .operation_icon ] = operations[ t ] .operation_icon ; + treerow[ treeview_operations_columns .operation_description ] = operations[ t ] ->description ; + treerow[ treeview_operations_columns .operation_icon ] = operations[ t ] ->icon ; } //set new statusbartext @@ -608,7 +627,7 @@ void Win_GParted::Refresh_Visual() } //count primary's and check for extended - any_extended = false; + index_extended = -1 ; primary_count = 0; for ( unsigned int t = 0 ; t < partitions .size() ; t++ ) { @@ -622,7 +641,7 @@ void Win_GParted::Refresh_Visual() break; case GParted::TYPE_EXTENDED : - any_extended = true; + index_extended = t ; primary_count++; break; @@ -657,7 +676,8 @@ bool Win_GParted::Quit_Check_Operations() true ); if ( operations .size() != 1 ) - dialog .set_secondary_text( String::ucompose( _("%1 operations are currently pending."), operations .size() ) ) ; + dialog .set_secondary_text( String::ucompose( _("%1 operations are currently pending."), + operations .size() ) ) ; else dialog .set_secondary_text( _("1 operation is currently pending.") ) ; @@ -830,7 +850,8 @@ void Win_GParted::close_operationslist() void Win_GParted::clear_operationslist() { - operations .clear() ; + remove_operation( -1, true ) ; + Refresh_Visual() ; } @@ -917,10 +938,10 @@ void Win_GParted::menu_gparted_refresh_devices() unsigned int i ; for ( unsigned int t = 0 ; t < operations .size() ; t++ ) { - for ( i = 0 ; i < devices .size() && devices[ i ] != operations[ t ] .device ; i++ ) {} - + for ( i = 0 ; i < devices .size() && devices[ i ] != operations[ t ] ->device ; i++ ) {} + if ( i >= devices .size() ) - operations .erase( operations .begin() + t-- ) ;//decrease t bij one.. + remove_operation( t-- ) ; } //if no devices were detected we disable some stuff and show a message in the statusbar @@ -946,7 +967,7 @@ void Win_GParted::menu_gparted_refresh_devices() //hmzz, this is really paranoid, but i think it's the right thing to do ;) liststore_operations ->clear() ; close_operationslist() ; - operations .clear() ; + remove_operation( -1, true ) ; statusbar .pop() ; statusbar .push( _( "No devices detected" ) ); @@ -1129,8 +1150,8 @@ void Win_GParted::activate_resize() if ( operations .size() ) for (unsigned int t = 0 ; t < operations .size() ; t++ ) - if ( operations[ t ] .device == devices[ current_device ] ) - operations[ t ] .Apply_Operation_To_Visual( partitions ) ; + if ( operations[ t ] ->device == devices[ current_device ] ) + operations[ t ] ->apply_to_visual( partitions ) ; Dialog_Partition_Resize_Move dialog( gparted_core .get_fs( selected_partition .filesystem ), devices[ current_device ] .cylsize ) ; @@ -1138,7 +1159,7 @@ void Win_GParted::activate_resize() if ( selected_partition .type == GParted::TYPE_LOGICAL ) { unsigned int ext = 0 ; - while ( ext < partitions .size( ) && partitions[ ext ] .type != GParted::TYPE_EXTENDED ) ext++ ; + while ( ext < partitions .size() && partitions[ ext ] .type != GParted::TYPE_EXTENDED ) ext++ ; dialog .Set_Data( selected_partition, partitions[ ext ] .logicals ); } else @@ -1157,11 +1178,16 @@ void Win_GParted::activate_resize() //remove operation which creates this partition for ( unsigned int t = 0 ; t < operations .size() ; t++ ) { - if ( operations[ t ] .partition_new == selected_partition ) + if ( operations[ t ] ->partition_new == selected_partition ) { - operations.erase( operations .begin() + t ) ; + remove_operation( t ) ; //And add the new partition to the end of the operations list + //change 'selected_partition' into a suitable 'partition_original') + selected_partition .Set_Unallocated( devices[ current_device ] .get_path(), + selected_partition .sector_start, + selected_partition .sector_end, + selected_partition .inside_extended ) ; Add_Operation( GParted::CREATE, dialog .Get_New_Partition() ); break; @@ -1209,7 +1235,7 @@ void Win_GParted::activate_new() Dialog_Partition_New dialog; dialog .Set_Data( selected_partition, - any_extended, + index_extended > -1, new_count, gparted_core .get_filesystems(), devices[ current_device ] .readonly, @@ -1289,19 +1315,21 @@ void Win_GParted::activate_delete() /* if deleted one is NEW, it doesn't make sense to add it to the operationslist, * we erase its creation and possible modifications like resize etc.. from the operationslist. * Calling Refresh_Visual will wipe every memory of its existence ;-)*/ + //FIXME: afaik all allowed operation on STAT_NEW will replace the new partition + //therefore it's impossible to have >1 operations on a STAT_NEW and contains this check unnecessary overkill if ( selected_partition .status == GParted::STAT_NEW ) { //remove all operations done on this new partition (this includes creation) for ( int t = 0 ; t < static_cast( operations .size() ) ; t++ ) - if ( operations[ t ] .partition_new .get_path() == selected_partition .get_path() ) - operations.erase( operations .begin() + t-- ) ; + if ( operations[ t ] ->partition_new .get_path() == selected_partition .get_path() ) + remove_operation( t-- ) ; //determine lowest possible new_count new_count = 0 ; for ( unsigned int t = 0 ; t < operations .size() ; t++ ) - if ( operations[ t ] .partition_new .status == GParted::STAT_NEW && - operations[ t ] .partition_new .partition_number > new_count ) - new_count = operations[ t ] .partition_new .partition_number ; + if ( operations[ t ] ->partition_new .status == GParted::STAT_NEW && + operations[ t ] ->partition_new .partition_number > new_count ) + new_count = operations[ t ] ->partition_new .partition_number ; new_count += 1 ; @@ -1357,7 +1385,8 @@ void Win_GParted::activate_format( GParted::FILESYSTEM new_fs ) part_temp .Set( devices[ current_device ] .get_path(), selected_partition .get_path(), selected_partition .partition_number, - selected_partition .type, new_fs, + selected_partition .type, + new_fs, selected_partition .sector_start, selected_partition .sector_end, selected_partition .inside_extended, @@ -1372,14 +1401,15 @@ void Win_GParted::activate_format( GParted::FILESYSTEM new_fs ) //remove operation which creates this partition for ( unsigned int t = 0 ; t < operations .size() ; t++ ) { - if ( operations[ t ] .partition_new == selected_partition ) + if ( operations[ t ] ->partition_new == selected_partition ) { - operations .erase( operations .begin() +t ) ; + remove_operation( t ) ; //And add the new partition to the end of the operations list //(NOTE: in this case we set status to STAT_NEW) part_temp .status = STAT_NEW ; - Add_Operation( GParted::CREATE, part_temp ); + + Add_Operation( GParted::CREATE, part_temp, t ); break; } @@ -1583,16 +1613,37 @@ void Win_GParted::activate_disklabel() void Win_GParted::activate_undo() { //when undoing an creation it's safe to decrease the newcount by one - if ( operations .back() .operationtype == GParted::CREATE ) + if ( operations .back() ->type == GParted::CREATE ) new_count-- ; - - operations.erase( operations .end() ); + + remove_operation() ; Refresh_Visual(); if ( ! operations .size() ) close_operationslist() ; } + +void Win_GParted::remove_operation( int index, bool remove_all ) +{ + if ( remove_all ) + { + for ( unsigned int t = 0 ; t < operations .size() ; t++ ) + delete operations[ t ] ; + + operations .clear() ; + } + else if ( index == -1 && operations .size() > 0 ) + { + delete operations .back() ; + operations .pop_back() ; + } + else if ( index > -1 && index < static_cast( operations .size() ) ) + { + delete operations[ index ] ; + operations .erase( operations .begin() + index ) ; + } +} void Win_GParted::activate_apply() { @@ -1628,7 +1679,7 @@ void Win_GParted::activate_apply() dialog_progress .hide() ; //wipe operations... - operations.clear() ; + remove_operation( -1, true ) ; liststore_operations ->clear() ; close_operationslist() ;