P) It still needs a lot of love, but the foundations are laid =)

* Rewrote a large part of gparteds internal code. Filesystemssupport is now much more separated from the rest of gparted and
  adding support for other filesystems should be a piece of cake now (hope that's true :P)
  It still needs a lot of love, but the foundations are laid =)
This commit is contained in:
Bart Hakvoort 2004-11-17 13:00:25 +00:00
parent 60654dfcfc
commit 4ccf831ec7
34 changed files with 2044 additions and 912 deletions

View File

@ -1,3 +1,9 @@
2004-11-17 Bart Hakvoort <gparted@users.sf.net>
* Rewrote a large part of gparteds internal code. Filesystemssupport is now much more separated from the rest of gparted and
adding support for other filesystems should be a piece of cake now (hope that's true :P)
It still needs a lot of love, but the foundations are laid =)
2004-11-07 Bart Hakvoort <gparted@users.sf.net>
* include/Operation.h,

View File

@ -1,4 +1,4 @@
SUBDIRS = include src po
SUBDIRS = include src po
@INTLTOOL_DESKTOP_RULE@

View File

@ -15,30 +15,11 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/******************************************************
This class.... is a mess ;-)
It's does some kind of wrapping around libparted, but it's not very clear and it looks like shit.
The one thing i have to say in favor of it is: IT JUST WORKS :)
When i've time i will look into it and try to sort things out a bit.
Maybe building a small decent wrapper or so...
********************************************************/
#ifndef DEVICE
#define DEVICE
#include <parted/parted.h>
#include "../include/Partition.h"
#include <gtkmm/messagedialog.h>
#include <gtkmm/checkbutton.h>
#include <gtkmm/frame.h>
#include <gtkmm/label.h>
#include <gtkmm/stock.h>
#include <fstream>
namespace GParted
{
@ -47,45 +28,12 @@ class Device
public:
Device() ;
Device( const Glib::ustring & device_path, std::vector<FS> *filesystems );
~Device() ;
//this function creates a fresh list with al the partitions and free spaces
void Read_Disk_Layout( bool deep_scan = true ) ;
bool Delete_Partition( const Partition & partition ) ;
bool Create_Partition_With_Filesystem( Partition & new_part, PedTimer *timer) ;
bool Move_Resize_Partition( const Partition & partition_original, const Partition & partition_new, PedTimer *timer) ;
bool Set_Partition_Filesystem( const Partition & new_partition, PedTimer * timer);
bool Copy_Partition( Device *source_device, const Partition & source_partition, PedTimer * timer ) ;
int Create_Empty_Partition( const Partition & new_partition, PedConstraint * constraint = NULL ) ;
bool Commit() ;
PedPartition * Get_c_partition( int part_num );
std::vector<Partition> Get_Partitions() ;
Sector Get_Length() ;
long Get_Heads() ;
long Get_Sectors() ;
long Get_Cylinders() ;
Glib::ustring Get_Model() ;
Glib::ustring Get_Path() ;
Glib::ustring Get_RealPath() ;
Glib::ustring Get_DiskType() ;
bool Get_any_busy() ;
int Get_Max_Amount_Of_Primary_Partitions() ;
bool Get_any_busy( ) ;
int Get_Highest_Logical_Busy( ) ;
private:
//make a try to get the amount of used sectors on a filesystem ( see comments in implementation )
Sector Get_Used_Sectors( PedPartition *c_partition, const Glib::ustring & sym_path );
Glib::ustring Get_Flags( PedPartition *c_partition ) ;
bool open_device_and_disk() ;
void close_device_and_disk() ;
bool Resize_Extended( const Partition & partition, PedTimer *timer) ;
std::vector<Partition> device_partitions ;
std::vector<FS> * FILESYSTEMS ;
Sector length;
long heads ;
long sectors ;
@ -94,17 +42,13 @@ private:
Glib::ustring path;
Glib::ustring realpath;
Glib::ustring disktype;
//private variables
PedDevice *device ;
PedDisk *disk ;
PedPartition *c_partition ;
int max_prims ;
std::vector <PedPartitionFlag> flags;
Glib::ustring temp, error ; //error may contain an errormessage for an specific partition ( see Get_Used_Sectors() )
Partition partition_temp ;
};
private:
};
} //GParted
} //GParted
#endif //DEVICE

View File

@ -77,6 +77,7 @@ protected:
void on_signal_resize( int, int, Frame_Resizer_Base::ArrowType );
void on_spinbutton_value_changed( SPINBUTTON ) ;
std::vector<FS> FILESYSTEMS ;
bool fixed_start, GRIP ;
double before_value ;
int x_start, x_end ;

View File

@ -26,7 +26,7 @@ namespace GParted
class Dialog_Partition_Resize_Move : public Dialog_Base_Partition
{
public:
Dialog_Partition_Resize_Move( ) ;
Dialog_Partition_Resize_Move( std::vector<FS> FILESYSTEMS ) ;
void Set_Data( const Partition & selected_partition, const std::vector <Partition> & partitions ) ;
private:

View File

@ -25,6 +25,10 @@
#include <gtkmm/progressbar.h>
#include <gtkmm/stock.h>
#include <gtkmm/label.h>
#include <gtkmm/togglebutton.h>
#include <gtkmm/textview.h>
#include <gtkmm/textbuffer.h>
#include <gtkmm/scrolledwindow.h>
namespace GParted
{
@ -32,22 +36,30 @@ namespace GParted
class Dialog_Progress : public Gtk::Dialog
{
public:
Dialog_Progress( int, const Glib::ustring & );
Dialog_Progress( int count_operations, Glib::RefPtr<Gtk::TextBuffer> textbuffer );
~Dialog_Progress( );
void Set_Next_Operation( );
void Set_Progress_Current_Operation( );
void Set_Operation( );
Glib::ustring current_operation;
float fraction_current;
int time_left ;
int TIME_LEFT ;
private:
bool Show_Progress( ) ;
bool Pulse( ) { progressbar_current .pulse( ) ; return true ; }
void tglbtn_details_toggled( ) ;
Gtk::Label label_current ;
Gtk::ProgressBar progressbar_all, progressbar_current ;
Gtk::ToggleButton tglbtn_details ;
Gtk::TextView textview_details ;
Gtk::ScrolledWindow scrolledwindow ;
double fraction;
void signal_textbuffer_insert( const Gtk::TextBuffer::iterator & iter, const Glib::ustring & text, int ) ;
double fraction, fraction_current;
int count_operations, current_operation_number;
sigc::connection conn ;
};
}//GParted

106
include/FileSystem.h Normal file
View File

@ -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.
*/
#ifndef FILESYSTEM
#define FILESYSTEM
#include "../include/Partition.h"
#include <gtkmm/textbuffer.h>
#include <parted/parted.h>
//Some functions used by both (sub)Filesystems and GParted_Core-------------------------------------------------
inline bool open_device( const Glib::ustring & device_path, PedDevice *& device )
{
device = ped_device_get( device_path .c_str( ) );
return device ;
}
inline bool open_device_and_disk( const Glib::ustring & device_path, PedDevice *& device, PedDisk *& disk )
{
if ( open_device( device_path, device ) )
disk = ped_disk_new( device );
if ( ! disk )
{
ped_device_destroy( device ) ;
device = NULL ;
return false;
}
return true ;
}
inline void close_device_and_disk( PedDevice *& device, PedDisk *& disk )
{
if ( device )
ped_device_destroy( device ) ;
if ( disk )
ped_disk_destroy( disk ) ;
device = NULL ;
disk = NULL ;
}
inline bool Commit( PedDisk *& disk )
{
bool return_value = ped_disk_commit_to_dev( disk ) ;
ped_disk_commit_to_os( disk ) ;
return return_value ;
}
//---------------------------------------------------------------------------------------------------------------
namespace GParted
{
class FileSystem
{
public:
virtual ~FileSystem( ) { }
virtual FS get_filesystem_support( ) = 0 ;
virtual bool Create( const Glib::ustring device_path, const Partition & new_partition ) = 0 ;
virtual bool Resize( const Glib::ustring device_path, const Partition & partition_old, const Partition & partition_new ) = 0 ;
virtual bool Copy( const Glib::ustring & src_part_path, const Glib::ustring & dest_part_path ) = 0 ;
virtual int get_estimated_time( long MB_to_Consider ) = 0 ;
Glib::RefPtr<Gtk::TextBuffer> textbuffer ;
protected:
bool Execute_Command( Glib::ustring command ) ;
PedDevice *device ;
PedDisk *disk ;
private:
void Update_Textview( ) ;
Glib::ustring output ;
};
} //GParted
#endif //FILESYSTEM

81
include/GParted_Core.h Normal file
View File

@ -0,0 +1,81 @@
/* 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 GPARTED_CORE
#define GPARTED_CORE
#include "../include/Operation.h"
#include "../include/ext2.h"
#include "../include/ext3.h"
#include "../include/fat16.h"
#include "../include/fat32.h"
#include "../include/linux_swap.h"
#include "../include/reiserfs.h"
#include <glibmm/ustring.h>
#include <vector>
#include <fstream>
namespace GParted
{
class GParted_Core
{
public:
GParted_Core( ) ;
void find_supported_filesystems( ) ;
void get_devices( std::vector<Device> & devices, bool deep_scan ) ;
void get_partitions( std::vector<Partition> & partitions, const Glib::ustring & device_path, bool deep_scan = true ) ;
int get_estimated_time( Operation & operation ) ;
void Apply_Operation_To_Disk( Operation & operation );
bool Create( const Glib::ustring & device_path, Partition & new_partition ) ;
bool Convert_FS( const Glib::ustring & device_path, const Partition & partition ) ;
bool Delete( const Glib::ustring & device_path, const Partition & partition ) ;
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 ) ;
std::vector<FS> get_fs( ) ;
Glib::RefPtr<Gtk::TextBuffer> get_textbuffer( ) ;
private:
Glib::ustring get_sym_path( const Glib::ustring & real_path ) ;
Sector Get_Used_Sectors( PedPartition *c_partition, const Glib::ustring & sym_path );
Glib::ustring Get_Flags( PedPartition *c_partition ) ;
int Create_Empty_Partition( const Glib::ustring & device_path, Partition & new_partition ) ;
bool Resize_Extended( const Glib::ustring & device_path, const Partition & extended ) ;
void Show_Error( Glib::ustring message ) ;
void set_proper_filesystem( const Glib::ustring & filesystem ) ;
Glib::RefPtr<Gtk::TextBuffer> textbuffer;
std::vector<FS> FILESYSTEMS ;
FileSystem * p_filesystem ;
std::vector <PedPartitionFlag> flags;
PedDevice *device ;
PedDisk *disk ;
PedPartition *c_partition ;
Glib::ustring temp ;
};
} //GParted
#endif //GPARTED_CORE

View File

@ -39,21 +39,23 @@ class Operation
{
public:
Operation( Device *device, Device *source_device, const Partition &, const Partition &,OperationType );
Operation( const Glib::ustring device_path, Sector device_length, 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<Partition> & partitions );
void Apply_To_Disk( PedTimer * timer );
//public variables
Device *device, *source_device; //source_device is only used in copy operations
Glib::ustring device_path, source_device_path ;
Glib::ustring device_path ;
Sector device_length ;
OperationType operationtype;
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 ;
Glib::ustring copied_partition_path ; //for copy operation..
private:
void Insert_Unallocated( std::vector<Partition> & partitions, Sector start, Sector end );
int Get_Index_Original( std::vector<Partition> & partitions ) ;
@ -63,10 +65,7 @@ private:
void Apply_Resize_Move_To_Visual( std::vector<Partition> & partitions );
void Apply_Resize_Move_Extended_To_Visual( std::vector<Partition> & partitions );
Glib::ustring Get_String(); //only used during in c'tor
void Show_Error( Glib::ustring message ) ;
Partition partition_original; //the original situation
Glib::ustring Get_String( ); //only used in c'tor
};
} //GParted

View File

@ -43,9 +43,14 @@ typedef long long Sector;
struct FS
{
Glib::ustring filesystem ;
bool supported ; //open/resize/copy
bool create ; //create (duh =) )
bool create ;
bool resize ; //only endpoint
bool move ; //startpoint and endpoint
bool check ;
FS( ) {create = resize = move = check = false ;}
};
//globally used convenience functions
inline long Sector_To_MB( Sector sectors )
@ -91,13 +96,15 @@ inline Glib::ustring num_to_str( Sector number )
return os .str() ;
}
inline bool Supported( const Glib::ustring & filesystem, std::vector<FS> *FILESYSTEMS )
inline FS Get_FS( const Glib::ustring & filesystem, const std::vector<FS> & FILESYSTEMS )
{
for (unsigned int t=0 ; t < FILESYSTEMS ->size() ; t++ )
if ( (*FILESYSTEMS)[ t ] .filesystem == filesystem && (*FILESYSTEMS)[ t ] .supported )
return true ;
unsigned int t = 0 ;
return false ;
for ( t = 0 ; t < FILESYSTEMS .size( ) ; t++ )
if ( FILESYSTEMS[ t ] .filesystem == filesystem )
break ;
return FILESYSTEMS[ t ] ;
}
inline Glib::ustring Get_Color( const Glib::ustring & filesystem )

View File

@ -29,6 +29,7 @@
#include "../include/Dialog_Partition_Resize_Move.h"
#include "../include/Dialog_About.h"
#include "../include/Dialog_Partition_Copy.h"
#include "../include/GParted_Core.h"
#include <sigc++/class_slot.h>
#include <gtkmm/main.h>
@ -39,7 +40,6 @@
#include <gtkmm/statusbar.h>
#include <gtkmm/radiobutton.h>
#include <gtkmm/liststore.h>
#include <gtkmm/scrolledwindow.h>
#include <dlfcn.h>
#include <unistd.h> //should be included by gtkmm headers. but decided to include it anyway after getting some bugreports..
@ -61,7 +61,6 @@ private:
void init_operationslist() ;
void init_hpaned_main() ;
void Find_Supported_Filesystems() ;
void Find_Devices( bool deep_scan = true ) ;
void Refresh_OptionMenu( ) ;
void Show_Pulsebar( ) ;
@ -123,9 +122,9 @@ private:
void apply_operations_thread();
//private variables
unsigned int current_device, source_device; //source_device is used to store the device the copied_partition is from....
unsigned int current_device ;
Partition selected_partition, copied_partition;
std::vector <Device * > devices;
std::vector <Device> devices;
std::vector <Operation> operations;
//gui stuff
@ -176,11 +175,10 @@ private:
unsigned short new_count;//new_count keeps track of the new created partitions
Glib::ustring str_temp ; //mostly used for constructing dialogmessages
GParted_Core gparted_core ;
GParted::Device *temp_device ;
std::vector <Gtk::Label *> device_info ;
std::vector <FS> FILESYSTEMS ;
//stuff for progress overview and pulsebar
Dialog_Progress *dialog_progress;
Glib::Thread *thread ;

39
include/ext2.h Normal file
View File

@ -0,0 +1,39 @@
/* 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 EXT2
#define EXT2
#include "../include/FileSystem.h"
namespace GParted
{
class ext2 : public FileSystem
{
public:
FS get_filesystem_support( ) ;
bool Create( const Glib::ustring device_path, const Partition & new_partition ) ;
bool Resize( const Glib::ustring device_path, const Partition & partition_old, const Partition & partition_new ) ;
bool Copy( const Glib::ustring & src_part_path, const Glib::ustring & dest_part_path ) ;
int get_estimated_time( long MB_to_Consider ) ;
};
} //GParted
#endif //EXT2

40
include/ext3.h Normal file
View File

@ -0,0 +1,40 @@
/* 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 EXT3
#define EXT3
#include "../include/FileSystem.h"
namespace GParted
{
class ext3 : public FileSystem
{
public:
FS get_filesystem_support( ) ;
bool Create( const Glib::ustring device_path, const Partition & new_partition ) ;
bool Resize( const Glib::ustring device_path, const Partition & partition_old, const Partition & partition_new ) ;
bool Copy( const Glib::ustring & src_part_path, const Glib::ustring & dest_part_path ) ;
int get_estimated_time( long MB_to_Consider ) ;
};
} //GParted
#endif //EXT3

40
include/fat16.h Normal file
View File

@ -0,0 +1,40 @@
/* 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 FAT16
#define FAT16
#include "../include/FileSystem.h"
namespace GParted
{
class fat16 : public FileSystem
{
public:
FS get_filesystem_support( ) ;
bool Create( const Glib::ustring device_path, const Partition & new_partition ) ;
bool Resize( const Glib::ustring device_path, const Partition & partition_old, const Partition & partition_new ) ;
bool Copy( const Glib::ustring & src_part_path, const Glib::ustring & dest_part_path ) ;
int get_estimated_time( long MB_to_Consider ) ;
};
} //GParted
#endif //FAT16

39
include/fat32.h Normal file
View File

@ -0,0 +1,39 @@
/* 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 FAT32
#define FAT32
#include "../include/FileSystem.h"
namespace GParted
{
class fat32 : public FileSystem
{
public:
FS get_filesystem_support( );
bool Create( const Glib::ustring device_path, const Partition & new_partition ) ;
bool Resize( const Glib::ustring device_path, const Partition & partition_old, const Partition & partition_new ) ;
bool Copy( const Glib::ustring & src_part_path, const Glib::ustring & dest_part_path ) ;
int get_estimated_time( long MB_to_Consider ) ;
};
} //GParted
#endif //FAT32

39
include/linux_swap.h Normal file
View File

@ -0,0 +1,39 @@
/* 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 LINUX_SWAP
#define LINUX_SWAP
#include "../include/FileSystem.h"
namespace GParted
{
class linux_swap : public FileSystem
{
public:
FS get_filesystem_support( ) ;
bool Create( const Glib::ustring device_path, const Partition & new_partition ) ;
bool Resize( const Glib::ustring device_path, const Partition & partition_old, const Partition & partition_new ) ;
bool Copy( const Glib::ustring & src_part_path, const Glib::ustring & dest_part_path ) ;
int get_estimated_time( long MB_to_Consider ) ;
};
} //GParted
#endif //LINUX_SWAP

41
include/reiserfs.h Normal file
View File

@ -0,0 +1,41 @@
/* 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 REISERFS
#define REISERFS
#include "../include/FileSystem.h"
#include <dlfcn.h>
namespace GParted
{
class reiserfs : public FileSystem
{
public:
FS get_filesystem_support( ) ;
bool Create( const Glib::ustring device_path, const Partition & new_partition ) ;
bool Resize( const Glib::ustring device_path, const Partition & partition_old, const Partition & partition_new ) ;
bool Copy( const Glib::ustring & src_part_path, const Glib::ustring & dest_part_path ) ;
int get_estimated_time( long MB_to_Consider ) ;
};
} //GParted
#endif //REISERFS

View File

@ -20,441 +20,11 @@
namespace GParted
{
/*
* This is ridiculous!, if i use this one as a member function realpath starts complaining and won't compile :-S
*/
Glib::ustring get_sym_path( const Glib::ustring & real_path )
{
int major,minor,size;
char temp[4096], device_name[4096],short_path[4096] ;
FILE* proc_part_file = fopen ("/proc/partitions", "r");
if (!proc_part_file)
return real_path;
//skip first 2 useless rules of /proc/partitions
fgets (temp, 256, proc_part_file);fgets (temp, 256, proc_part_file);
while (fgets (temp, 4096, proc_part_file) && sscanf (temp, "%d %d %d %255s", &major, &minor, &size, device_name) == 4)
{
strcpy(short_path, "/dev/"); strcat( short_path, device_name );
realpath( short_path, device_name );
if ( real_path == device_name ) {
fclose (proc_part_file);
return (Glib::ustring(short_path));
}
}
//paranoia modus :)
fclose (proc_part_file);
return real_path;
}
//AFAIK it's not possible to use a C++ memberfunction as a callback for a C libary function (if you know otherwise, PLEASE contact me)
Glib::ustring error_message;
PedExceptionOption PedException_Handler (PedException* ex)
{
error_message = Glib::locale_to_utf8( ex ->message ) ;
std::cout << error_message << "\n---------------------------\n" ;
return PED_EXCEPTION_UNHANDLED ;
}
//--------------Device----------------------------------------------
Device::Device()
Device::Device( )
{
}
Device::Device( const Glib::ustring & device_path, std::vector<FS> *filesystems )
{
ped_exception_set_handler( PedException_Handler ) ;
this ->FILESYSTEMS = filesystems ;
this ->realpath = device_path ; //this one is used by open_device_and_disk
this ->length = 0;//lazy check.. if something goes wrong while reading the device, length will stay zero and i will know it ( see Win_GParted::Find_Devices )
if ( ! open_device_and_disk() )
return ;
this ->model = device ->model ;
this ->path = get_sym_path( device ->path ) ;
this ->disktype = disk ->type ->name ;
this ->heads = device ->bios_geom.heads ;
this ->sectors = device ->bios_geom.sectors ;
this ->cylinders= device ->bios_geom.cylinders ;
this ->length = heads * sectors * cylinders ;
//get valid flags for this device
for ( PedPartitionFlag flag = ped_partition_flag_next ( (PedPartitionFlag) 0 ) ; flag ; flag = ped_partition_flag_next ( flag ) )
flags .push_back( flag ) ;
}
void Device::Read_Disk_Layout( bool deep_scan )
{
Glib::ustring part_path ;
int EXT_INDEX = -1 ;
//clear partitions
this ->device_partitions .clear( ) ;
c_partition = ped_disk_next_partition( disk, NULL ) ;
while ( c_partition )
{
partition_temp .Reset( ) ;
part_path = this ->path + num_to_str( c_partition ->num ) ;
switch ( c_partition ->type )
{
case PED_PARTITION_NORMAL:
case PED_PARTITION_LOGICAL:
if ( c_partition ->fs_type )
temp = c_partition ->fs_type ->name ;
else
{
temp = "unknown" ;
this ->error = _( "Unable to detect filesystem! Possible reasons are:" ) ;
this ->error += "\n-";
this ->error += _( "The filesystem is damaged" ) ;
this ->error += "\n-" ;
this ->error += _( "The filesystem is unknown to libparted" ) ;
this ->error += "\n-";
this ->error += _( "There is no filesystem available (unformatted)" ) ;
}
partition_temp.Set( part_path,
c_partition ->num,
c_partition ->type == 0 ? GParted::PRIMARY : GParted::LOGICAL ,
temp, c_partition ->geom .start,
c_partition ->geom .end,
c_partition ->type,
ped_partition_is_busy( c_partition ) );
if ( deep_scan )
partition_temp .Set_Used( Get_Used_Sectors( c_partition, part_path ) ) ;
partition_temp .flags = Get_Flags( c_partition ) ;
partition_temp .error = this ->error ;//most likely useless, but paranoia me leaves it here.. =)
break ;
case PED_PARTITION_EXTENDED:
partition_temp.Set( part_path ,
c_partition ->num ,
GParted::EXTENDED ,
"extended" ,
c_partition ->geom .start ,
c_partition ->geom .end ,
false ,
ped_partition_is_busy( c_partition ) );
partition_temp .flags = Get_Flags( c_partition ) ;
EXT_INDEX = device_partitions .size ( ) ;
break ;
case PED_PARTITION_FREESPACE:
case 5: //freespace inside extended (there's no enumvalue for that..)
partition_temp.Set_Unallocated( c_partition ->geom .start, c_partition ->geom .end, c_partition ->type == 4 ? false : true );
break ;
case PED_PARTITION_METADATA:
if ( device_partitions .size( ) && device_partitions .back( ) .type == GParted::UNALLOCATED )
device_partitions .back( ) .sector_end = c_partition ->geom .end ;
break ;
case 9: //metadata inside extended (there's no enumvalue for that..)
if ( device_partitions[ EXT_INDEX ] .logicals .size( ) && device_partitions[ EXT_INDEX ] .logicals .back( ) .type == GParted::UNALLOCATED )
device_partitions[ EXT_INDEX ] .logicals .back( ) .sector_end = c_partition ->geom .end ;
break ;
default: break;
}
if ( partition_temp .Get_Length_MB( ) >= 1 ) // check for unallocated < 1MB, and metadatasituations (see PED_PARTITION_METADATA and 9 )
{
if ( ! partition_temp .inside_extended )
device_partitions.push_back( partition_temp );
else
device_partitions[ EXT_INDEX ] .logicals .push_back( partition_temp ) ;
}
//reset stuff..
this ->error = error_message = "" ;
//next partition (if any)
c_partition = ped_disk_next_partition ( disk, c_partition ) ;
}
}
bool Device::Delete_Partition( const Partition & partition )
{
if ( partition .type == GParted::EXTENDED )
c_partition = ped_disk_extended_partition( disk ) ;
else
c_partition = ped_disk_get_partition_by_sector( disk, (partition .sector_end + partition .sector_start) / 2 ) ;
if ( ! ped_disk_delete_partition( disk, c_partition ) )
return false;
return Commit() ;
}
int Device::Create_Empty_Partition( const Partition & new_partition, PedConstraint * constraint )
{
PedPartitionType type;
PedPartition *c_part = NULL ;
//create new partition
switch ( new_partition .type )
{
case 0 : type = PED_PARTITION_NORMAL; break;
case 1 : type = PED_PARTITION_LOGICAL; break;
case 2 : type = PED_PARTITION_EXTENDED; break;
default : type = PED_PARTITION_FREESPACE; break ; //will never happen ;)
}
c_part = ped_partition_new ( disk, type, NULL, new_partition .sector_start, new_partition .sector_end ) ;
//create constraint
if ( ! constraint )
constraint = ped_constraint_any ( device);
//and add the whole thingy to disk..
if ( ! constraint || ! ped_disk_add_partition (disk, c_part, constraint) || ! Commit() )
return 0 ;
ped_constraint_destroy (constraint);
return c_part ->num;
}
bool Device::Create_Partition_With_Filesystem( Partition & new_part, PedTimer * timer)
{
//no need to create a filesystem on an extended partition
if ( new_part .type == GParted::EXTENDED )
return Create_Empty_Partition( new_part ) ;
else
{
new_part .partition_number = Create_Empty_Partition( new_part ) ;
return Set_Partition_Filesystem( new_part, timer ) ;
}
}
bool Device::Move_Resize_Partition( const Partition & partition_original, const Partition & partition_new , PedTimer *timer )
{
PedPartition *c_part = NULL ;
PedFileSystem *fs = NULL ;
PedConstraint *constraint = NULL ;
//since resizing extended is a bit different i handle it elsewhere..
if ( partition_new.type == GParted::EXTENDED )
return Resize_Extended( partition_new, timer ) ;
//normal partitions....
c_part = ped_disk_get_partition_by_sector( disk, (partition_original .sector_end + partition_original .sector_start) / 2 ) ;
if ( ! c_part )
return false;
fs = ped_file_system_open (& c_part->geom );
if ( ! fs )
return false ;
constraint = ped_file_system_get_resize_constraint (fs);
if ( ! constraint )
{
ped_file_system_close (fs);
return false;
}
if ( ! ped_disk_set_partition_geom (disk, c_part, constraint, partition_new .sector_start, partition_new .sector_end ) )
{
ped_constraint_destroy (constraint);
ped_file_system_close (fs);
return false ;
}
if ( ! ped_file_system_resize (fs, & c_part->geom, timer) )
{
ped_constraint_destroy (constraint);
ped_file_system_close (fs);
return false ;
}
ped_constraint_destroy (constraint);
ped_file_system_close (fs);
return Commit() ;
}
bool Device::Set_Partition_Filesystem( const Partition & new_partition, PedTimer * timer)
{
if ( new_partition .partition_number <= 0 )
return false ;
PedPartition *c_part = NULL ;
PedFileSystemType *fs_type = NULL ;
PedFileSystem *fs = NULL ;
c_part = ped_disk_get_partition_by_sector( disk, (new_partition .sector_end + new_partition .sector_start) / 2 ) ;
if ( ! c_part )
return false;
fs_type = ped_file_system_type_get ( new_partition .filesystem .c_str() ) ;
if ( ! fs_type )
return false;
fs = ped_file_system_create ( & c_part ->geom, fs_type, timer);
if ( ! fs )
return false;
ped_file_system_close (fs);
if ( ! ped_partition_set_system (c_part, fs_type ) )
return false;
return Commit() ;
}
bool Device::Copy_Partition( Device *source_device, const Partition & source_partition, PedTimer * timer)
{
PedPartition *c_part_src = NULL;
PedFileSystem *src_fs = NULL;
PedPartition *c_part = NULL;
PedFileSystem *dst_fs = NULL;
PedFileSystemType *dst_fs_type = NULL;
//prepare source for reading
if ( source_device ->Get_Path() == this ->path )
c_part_src = ped_disk_get_partition( disk, source_partition .partition_number ) ;
else
c_part_src = source_device ->Get_c_partition( source_partition .partition_number ) ;
if ( ! c_part_src )
return false;
src_fs = ped_file_system_open ( &c_part_src ->geom );
if ( ! src_fs )
return false ;
//create new empty partition
c_part = ped_disk_get_partition( disk,Create_Empty_Partition( source_partition, ped_file_system_get_copy_constraint ( src_fs, device ) ) ) ;
if ( ! c_part )
return false ;
//and do the copy
dst_fs = ped_file_system_copy (src_fs, &c_part ->geom, timer);
if ( ! dst_fs )
{
ped_file_system_close (src_fs);
return false ;
}
dst_fs_type = dst_fs ->type; // may be different to src_fs->type
ped_file_system_close (src_fs);
ped_file_system_close (dst_fs);
if ( !ped_partition_set_system (c_part, dst_fs_type) )
return false ;
return Commit() ;
}
bool Device::Resize_Extended( const Partition & partition , PedTimer *timer)
{
PedPartition *c_part = NULL ;
PedConstraint *constraint = NULL ;
c_part = ped_disk_extended_partition( disk ) ;
if ( ! c_part )
return false;
constraint = ped_constraint_any ( device );
if ( ! constraint )
return false;
if ( ! ped_disk_set_partition_geom ( disk, c_part, constraint, partition.sector_start, partition.sector_end ) )
{
ped_constraint_destroy (constraint);
return false ;
}
ped_partition_set_system ( c_part, NULL);
ped_constraint_destroy (constraint);
return Commit() ;
}
bool Device::Commit()
{
bool return_value = ped_disk_commit_to_dev( disk ) ;
ped_disk_commit_to_os( disk ) ;
return return_value ;
}
PedPartition * Device::Get_c_partition( int part_num )
{
return ped_disk_get_partition( disk, part_num ) ;
}
std::vector<Partition> Device::Get_Partitions()
{
return device_partitions;
}
Sector Device::Get_Length()
{
return length ;
}
long Device::Get_Heads()
{
return heads ;
}
long Device::Get_Sectors()
{
return sectors ;
}
long Device:: Get_Cylinders()
{
return cylinders ;
}
Glib::ustring Device::Get_Model()
{
return model ;
}
Glib::ustring Device::Get_Path()
{
return path ;
}
Glib::ustring Device::Get_RealPath()
{
return realpath ;
}
Glib::ustring Device::Get_DiskType()
{
return disktype ;
}
bool Device::Get_any_busy()
bool Device::Get_any_busy( )
{
for ( unsigned int t=0;t<device_partitions.size(); t++ )
if ( device_partitions[t].busy )
@ -463,11 +33,6 @@ bool Device::Get_any_busy()
return false;
}
int Device::Get_Max_Amount_Of_Primary_Partitions()
{
return ped_disk_get_max_primary_partition_count( disk ) ;
}
int Device::Get_Highest_Logical_Busy( )
{
int highest_logic_busy = -1 ;
@ -485,116 +50,8 @@ int Device::Get_Highest_Logical_Busy( )
return highest_logic_busy ;
}
Sector Device::Get_Used_Sectors( PedPartition *c_partition, const Glib::ustring & sym_path)
{
/* This is quite an unreliable process, atm i try two different methods, but since both are far from perfect the results are
* questionable.
* - first i try geometry.get_used() in libpartedpp, i implemented this function to check the minimal size when resizing a partition. Disadvantage
* of this method is the fact it won't work on mounted filesystems. Besides that, its SLOW
* - if the former method fails ( result is -1 ) i'll try to read the output from the df command ( df -k --sync <partition path> )
* - if this fails the filesystem on the partition is ( more or less ) unknown to the operating system and therefore the unused sectors cannot be calcualted
* - as soon as i have my internetconnection back i should ask people with more experience on this stuff for advice !
*/
//check if there is a (known) filesystem
if ( ! c_partition ->fs_type )
return -1;
//used sectors are not relevant for swapspace
if ( (Glib::ustring) c_partition ->fs_type ->name == "linux-swap" )
return -1;
//METHOD #1
//the getused method doesn't work on mounted partitions and for some filesystems ( i *guess* this is called check by andrew )
if ( ! ped_partition_is_busy( c_partition ) && Supported( c_partition ->fs_type ->name, FILESYSTEMS ) )
{
PedFileSystem *fs = NULL;
PedConstraint *constraint = NULL;
fs = ped_file_system_open( & c_partition ->geom );
if ( fs )
{
constraint = ped_file_system_get_resize_constraint (fs);
ped_file_system_close (fs);
if ( constraint && constraint->min_size != -1 )
return constraint->min_size ;
}
else
this ->error = error_message ;
}
//METHOD #2
//this ony works for mounted ( and therefore known to the OS ) filesystems. My method is quite crude, keep in mind it's only temporary ;-)
if ( ped_partition_is_busy( c_partition ) )
{
Glib::ustring buf;
system( ("df -k --sync " + sym_path + " | grep " + sym_path + " > /tmp/.tmp_gparted").c_str() );
std::ifstream file_input( "/tmp/.tmp_gparted" );
file_input >> buf; //skip first value
file_input >> buf;
if ( buf != "0" && ! buf.empty() )
{
file_input >> buf;
file_input.close(); system( "rm -f /tmp/.tmp_gparted" );
return atoi( buf.c_str() ) * 1024/512 ;
}
file_input.close(); system( "rm -f /tmp/.tmp_gparted" );
}
return -1 ; //all methods were unsuccesfull
}
Glib::ustring Device::Get_Flags( PedPartition *c_partition )
{
temp = "";
for ( unsigned short t = 0; t < flags.size() ; t++ )
if ( ped_partition_get_flag ( c_partition, flags[ t ] ) )
temp += (Glib::ustring) ped_partition_flag_get_name ( flags[ t ] ) + " ";
return temp ;
}
bool Device::open_device_and_disk()
{
device = ped_device_get( this->realpath .c_str() );
if ( device )
disk = ped_disk_new( device );
if ( ! device || ! disk )
{
if ( device )
{ ped_device_destroy( device ) ; device = NULL ; }
return false;
}
return true ;
}
void Device::close_device_and_disk()
{
if ( device )
{
ped_device_destroy( device ) ;
device = NULL ;
}
if ( disk )
{
ped_disk_destroy( disk ) ;
disk = NULL ;
}
}
Device::~Device()
{
close_device_and_disk() ;
}

View File

@ -37,7 +37,7 @@ Dialog_About::Dialog_About()
button_credits.add_pixlabel( "/usr/share/icons/hicolor/16x16/stock/generic/stock_about.png", "Credits", 0, 0.5 ) ;
button_credits.signal_clicked() .connect( sigc::mem_fun( this, &Dialog_About::Show_Credits ) ) ;
this ->get_action_area() ->set_layout( Gtk::BUTTONBOX_EDGE ) ;
this ->get_action_area() ->set_layout( Gtk::BUTTONBOX_EDGE ) ;
this ->get_action_area() ->pack_start( button_credits ) ;
this ->add_button( Gtk::Stock::CLOSE, Gtk::RESPONSE_CLOSE );

View File

@ -145,12 +145,9 @@ void Dialog_Base_Partition::Set_Confirm_Button( CONFIRMBUTTON button_type )
{
switch( button_type )
{
case NEW : this->add_button( Gtk::Stock::ADD,Gtk::RESPONSE_OK );
case NEW : this->add_button( Gtk::Stock::ADD, Gtk::RESPONSE_OK );
break ;
case RESIZE_MOVE: if ( selected_partition.filesystem == "ext2" || selected_partition.filesystem == "ext3" || selected_partition.filesystem == "reiserfs")
str_temp = _("Resize") ;
else
str_temp = _("Resize/Move") ;
case RESIZE_MOVE: str_temp = fixed_start ? _("Resize") : _("Resize/Move") ;
image_temp = manage( new Gtk::Image( Gtk::Stock::GOTO_LAST, Gtk::ICON_SIZE_BUTTON ) );
hbox_resize_move .pack_start( *image_temp, Gtk::PACK_EXPAND_PADDING ) ;
@ -158,7 +155,7 @@ void Dialog_Base_Partition::Set_Confirm_Button( CONFIRMBUTTON button_type )
button_resize_move .add( hbox_resize_move ) ;
this ->add_action_widget ( button_resize_move,Gtk::RESPONSE_OK ) ;
button_resize_move .set_sensitive( false ) ;
button_resize_move .set_sensitive( false ) ;
break ;
case PASTE : this->add_button( Gtk::Stock::PASTE,Gtk::RESPONSE_OK );
@ -273,7 +270,6 @@ void Dialog_Base_Partition::on_spinbutton_value_changed( SPINBUTTON spinbutton )
{
if ( ! GRIP )
{
//i expect libparted soon to be able to move startpoint of ext2/3 as well, so everything is ready for it. Till then this rudimentary check
fixed_start ? before_value = 0 : before_value = spinbutton_before .get_value() ;
//Balance the spinbuttons

View File

@ -119,15 +119,15 @@ Partition Dialog_Partition_New::Get_New_Partition()
PartitionType part_type = GParted::UNALLOCATED; //paranoia ;P
Sector new_start, new_end;
switch ( optionmenu_type.get_history() )
switch ( optionmenu_type .get_history( ) )
{
case 0: part_type = GParted::PRIMARY; break;
case 1: part_type = GParted::LOGICAL; break;
case 2: part_type = GParted::EXTENDED; break;
}
new_start = START + (Sector) (spinbutton_before .get_value() * MEGABYTE) ;
new_end = new_start + (Sector) (spinbutton_size .get_value() * MEGABYTE) ;
new_start = START + (Sector) (spinbutton_before .get_value( ) * MEGABYTE) ;
new_end = new_start + (Sector) (spinbutton_size .get_value( ) * MEGABYTE) ;
//due to loss of precision during calcs from Sector -> MB and back, it is possible the new partition thinks it's bigger then it can be. Here we try to solve this.
if ( new_start < selected_partition.sector_start )
@ -136,7 +136,11 @@ Partition Dialog_Partition_New::Get_New_Partition()
new_end = selected_partition.sector_end ;
part_temp .status = GParted::STAT_NEW ;
part_temp .Set( String::ucompose( _("New Partition #%1"), new_count ), new_count, part_type , FILESYSTEMS[ optionmenu_filesystem.get_history() ] .filesystem, new_start, new_end, selected_partition.inside_extended, false) ;
part_temp .Set( String::ucompose( _("New Partition #%1"), new_count ),
new_count, part_type,
FILESYSTEMS[ optionmenu_filesystem .get_history( ) ] .filesystem,
new_start, new_end,
selected_partition .inside_extended, false) ;
//grow new partition a bit if freespaces are < 1 MB
if ( (part_temp.sector_start - selected_partition.sector_start) < MEGABYTE )

View File

@ -20,8 +20,9 @@
namespace GParted
{
Dialog_Partition_Resize_Move::Dialog_Partition_Resize_Move( )
Dialog_Partition_Resize_Move::Dialog_Partition_Resize_Move( std::vector<FS> FILESYSTEMS )
{
this ->FILESYSTEMS = FILESYSTEMS ;
BUF = 5 ;
}
@ -63,18 +64,18 @@ void Dialog_Partition_Resize_Move::Set_Data( const Partition & selected_partitio
void Dialog_Partition_Resize_Move::Resize_Move_Normal( const std::vector <Partition> & partitions )
{
//see if we need a fixed_start
if ( selected_partition.filesystem == "ext2" || selected_partition.filesystem == "ext3" || selected_partition.filesystem == "reiserfs" )
if ( Get_FS( selected_partition .filesystem, FILESYSTEMS ) .move )
{
this ->set_title( String::ucompose( _("Resize/Move %1"), selected_partition .partition ) ) ;
frame_resizer_base ->set_fixed_start( false ) ;
}
else
{
this ->set_title( String::ucompose( _("Resize %1"), selected_partition .partition) ) ;
this ->fixed_start = true;
frame_resizer_base ->set_fixed_start( true ) ;
spinbutton_before .set_sensitive( false ) ;
}
else
{
this ->set_title( String::ucompose( _("Resize/Move %1"), selected_partition .partition ) ) ;
frame_resizer_base ->set_fixed_start( false ) ;
}
//calculate total size in MB's of previous, current and next partition
//first find index of partition
@ -85,11 +86,8 @@ void Dialog_Partition_Resize_Move::Resize_Move_Normal( const std::vector <Partit
Sector previous, next ;
previous = next = 0 ;
//also check the partitions filesystem ( if this is ext2/3 or reiserfs then previous should be 0 )
if ( t >= 1 && partitions[t -1].type == GParted::UNALLOCATED &&
selected_partition.filesystem != "ext2" &&
selected_partition.filesystem != "ext3" &&
selected_partition.filesystem != "reiserfs" )
//also check the partitions filesystem ( if this is a 'resize-only' then previous should be 0 )
if ( t >= 1 && partitions[t -1].type == GParted::UNALLOCATED && ! this ->fixed_start )
{
previous = partitions[t -1] .sector_end - partitions[t -1] .sector_start ;
START = partitions[t -1] .sector_start ;

View File

@ -20,7 +20,7 @@
namespace GParted
{
Dialog_Progress::Dialog_Progress( int count_operations, const Glib::ustring & first_operation )
Dialog_Progress::Dialog_Progress( int count_operations, Glib::RefPtr<Gtk::TextBuffer> textbuffer )
{
this ->set_size_request( 600, 275 ) ;
this ->set_resizable( false ) ;
@ -28,11 +28,9 @@ Dialog_Progress::Dialog_Progress( int count_operations, const Glib::ustring & fi
this ->set_title( _("Applying pending operations") ) ;
this ->count_operations = count_operations ;
current_operation_number = 0;
current_operation_number = 0 ;
fraction = (double) 1 / count_operations ;
fraction -= 1E-8 ; //minus 1E-8 is to prevent fraction from ever reaching >=1, it needs to be 0.0 < fraction < 1.0
Glib::ustring str_temp = "<span weight=\"bold\" size=\"larger\">" ;
str_temp += _( "Applying pending operations" ) ;
str_temp += "</span>\n\n" ;
@ -40,51 +38,110 @@ Dialog_Progress::Dialog_Progress( int count_operations, const Glib::ustring & fi
str_temp += "\n";
str_temp += _("Clicking Cancel will prevent the next operations from being applied.") ;
str_temp += "\n";
this->get_vbox() ->pack_start( * mk_label( str_temp ), Gtk::PACK_SHRINK );
this ->get_vbox( ) ->pack_start( * mk_label( str_temp ), Gtk::PACK_SHRINK );
progressbar_current.set_text( _("initializing...") );
this->get_vbox() ->pack_start( progressbar_current , Gtk::PACK_SHRINK);
progressbar_current .set_pulse_step( 0.01 ) ;
this->get_vbox( ) ->pack_start( progressbar_current, Gtk::PACK_SHRINK );
label_current.set_alignment( Gtk::ALIGN_LEFT );
label_current.set_markup( "<i>" + first_operation + "</i>" ) ;
this->get_vbox() ->pack_start( label_current, Gtk::PACK_SHRINK );
label_current .set_alignment( Gtk::ALIGN_LEFT );
this ->get_vbox( ) ->pack_start( label_current, Gtk::PACK_SHRINK );
textview_details .set_sensitive( false ) ;
textview_details .set_size_request( -1, 100 ) ;
textview_details .set_wrap_mode( Gtk::WRAP_WORD ) ;
textbuffer ->signal_insert( ) .connect( sigc::mem_fun( this, &Dialog_Progress::signal_textbuffer_insert ) ) ;
textview_details .set_buffer( textbuffer ) ;
this->get_vbox() ->pack_start( * mk_label( "<b>\n" + (Glib::ustring) _( "Completed Operations" ) + ":</b>" ), Gtk::PACK_SHRINK );
scrolledwindow .set_shadow_type( Gtk::SHADOW_ETCHED_IN ) ;
scrolledwindow .set_policy( Gtk::POLICY_NEVER, Gtk::POLICY_AUTOMATIC ) ;
scrolledwindow .add( textview_details ) ;
progressbar_all.set_text( String::ucompose( _("%1 of %2 operations completed"), 0, count_operations ) ) ;
this->get_vbox() ->pack_start( progressbar_all, Gtk::PACK_SHRINK );
this ->get_vbox( ) ->pack_start( scrolledwindow, Gtk::PACK_SHRINK );
this ->get_vbox( ) ->pack_start( * mk_label( "<b>\n" + (Glib::ustring) _( "Completed Operations" ) + ":</b>" ), Gtk::PACK_SHRINK );
this ->get_vbox( ) ->pack_start( progressbar_all, Gtk::PACK_SHRINK );
this->get_vbox() ->set_spacing( 5 ) ;
this->get_vbox() ->set_border_width( 15 ) ;
this ->get_vbox( ) ->set_spacing( 5 ) ;
this ->get_vbox( ) ->set_border_width( 15 ) ;
this->add_button( Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL );
this->show_all_children() ;
tglbtn_details .set_label( _("Details") ) ;
tglbtn_details .signal_toggled( ) .connect( sigc::mem_fun( this, &Dialog_Progress::tglbtn_details_toggled ) ) ;
this ->get_action_area( ) ->set_layout( Gtk::BUTTONBOX_EDGE ) ;
this ->get_action_area( ) ->pack_start( tglbtn_details ) ;
this ->add_button( Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL );
this ->show_all_children( ) ;
scrolledwindow .hide( ) ;
}
void Dialog_Progress::Set_Next_Operation( )
{
progressbar_all.set_fraction( progressbar_all.get_fraction() + fraction );
progressbar_all.set_text( String::ucompose( _("%1 of %2 operations completed"), ++current_operation_number, count_operations ) ) ;
label_current.set_markup( "<i>" + current_operation + "</i>" ) ;
progressbar_current.set_fraction( 0 );
progressbar_current.set_text( "initializing..." );
}
void Dialog_Progress::Set_Progress_Current_Operation( )
void Dialog_Progress::Set_Operation( )
{
progressbar_current.set_fraction( fraction_current );
//all operations
if ( current_operation_number && (progressbar_all .get_fraction( ) + fraction) <= 1.0 )
progressbar_all .set_fraction( progressbar_all .get_fraction( ) + fraction );
progressbar_all .set_text( String::ucompose( _("%1 of %2 operations completed"), current_operation_number++, count_operations ) ) ;
if ( time_left > 59 && time_left < 120 )
progressbar_current.set_text( String::ucompose( _("about %1 minute and %2 seconds left"), time_left/60, time_left % 60 ) ) ;
//new operation
conn .disconnect( ) ;
label_current .set_markup( "<i>" + current_operation + "</i>" ) ;
progressbar_current .set_fraction( 0 );
progressbar_current .set_text( "initializing..." );
if ( TIME_LEFT > 0 )
{
fraction_current = (double) 1 / TIME_LEFT ;
conn = Glib::signal_timeout( ) .connect( sigc::mem_fun( *this, &Dialog_Progress::Show_Progress ), 1000 );
}
else
progressbar_current.set_text( String::ucompose( _("about %1 minutes and %2 seconds left"), time_left/60, time_left % 60 ) ) ;
conn = Glib::signal_timeout( ) .connect( sigc::mem_fun( *this, &Dialog_Progress::Pulse ), 10 );
}
bool Dialog_Progress::Show_Progress( )
{
if ( (progressbar_current .get_fraction( ) + fraction_current) <= 1.0 )
{
progressbar_current .set_fraction( progressbar_current .get_fraction( ) + fraction_current );
if ( TIME_LEFT > 59 && TIME_LEFT < 120 )
progressbar_current .set_text( String::ucompose( _("about %1 minute and %2 seconds left"), TIME_LEFT/60, TIME_LEFT % 60 ) ) ;
else
progressbar_current .set_text( String::ucompose( _("about %1 minutes and %2 seconds left"), TIME_LEFT/60, TIME_LEFT % 60 ) ) ;
TIME_LEFT-- ;
}
return true ;
}
void Dialog_Progress::tglbtn_details_toggled( )
{
if ( tglbtn_details .get_active( ) )
{
scrolledwindow .show( ) ;
this ->set_size_request( 600, 375 ) ;
}
else
{
scrolledwindow .hide( ) ;
this ->set_size_request( 600, 275 ) ;
}
}
void Dialog_Progress::signal_textbuffer_insert( const Gtk::TextBuffer::iterator & iter, const Glib::ustring & text, int )
{
Gtk::TextBuffer::iterator temp = iter ;
textview_details .scroll_to( temp, 0 ) ;
}
Dialog_Progress::~Dialog_Progress()
{
conn .disconnect( ) ;
}

60
src/FileSystem.cc Normal file
View File

@ -0,0 +1,60 @@
/* 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/FileSystem.h"
namespace GParted
{
bool FileSystem::Execute_Command( Glib::ustring command )
{
Glib::Dispatcher dispatcher;
sigc::connection conn = dispatcher .connect( sigc::mem_fun(*this, &FileSystem::Update_Textview) );
//stderr to stdout
command += " 2>&1" ;
output = command + "\n\n" ;
dispatcher ( ) ;
char c_buf[ 512 ] ;
FILE *f = popen( command .c_str( ), "r" ) ;
while ( fgets( c_buf, 512, f ) )
{
//output = Glib::locale_to_utf8( c_buf ) ;
//std::cout << output << std::endl ;
//dispatcher ( ) ;disabled for the moment. Hier moet ik nog eens fris naar kijken. (anjuta had zo'n ingebouwde terminal, hoe deed die dat?? !!!
}
pclose( f ) ;
output = "" ;
dispatcher ( ) ;
return true ;
}
void FileSystem::Update_Textview( )
{
//std::cout << output << std::endl;
textbuffer ->set_text( output ) ;
//textbuffer ->insert( textbuffer ->end( ), output ) ;
}
} //GParted

562
src/GParted_Core.cc Normal file
View File

@ -0,0 +1,562 @@
#include "../include/GParted_Core.h"
namespace GParted
{
//AFAIK it's not possible to use a C++ memberfunction as a callback for a C libary function (if you know otherwise, PLEASE contact me)
Glib::ustring error_message;
PedExceptionOption PedException_Handler (PedException* ex)
{
error_message = Glib::locale_to_utf8( ex ->message ) ;
std::cout << "\nLIBPARTED MESSAGE ----------------------\n" << error_message << "\n---------------------------\n";
return PED_EXCEPTION_UNHANDLED ;
}
GParted_Core::GParted_Core( )
{
device = NULL ;
disk = NULL ;
c_partition = NULL ;
ped_exception_set_handler( PedException_Handler ) ;
p_filesystem = NULL ;
textbuffer = Gtk::TextBuffer::create( ) ;
//get valid flags ...
for ( PedPartitionFlag flag = ped_partition_flag_next ( (PedPartitionFlag) 0 ) ; flag ; flag = ped_partition_flag_next ( flag ) )
flags .push_back( flag ) ;
}
void GParted_Core::find_supported_filesystems( )
{
FILESYSTEMS .clear( ) ;
ext2 fs_ext2;
FILESYSTEMS .push_back( fs_ext2 .get_filesystem_support( ) ) ;
ext3 fs_ext3;
FILESYSTEMS .push_back( fs_ext3 .get_filesystem_support( ) ) ;
fat16 fs_fat16;
FILESYSTEMS .push_back( fs_fat16 .get_filesystem_support( ) ) ;
fat32 fs_fat32;
FILESYSTEMS .push_back( fs_fat32 .get_filesystem_support( ) ) ;
linux_swap fs_linux_swap;
FILESYSTEMS .push_back( fs_linux_swap .get_filesystem_support( ) ) ;
reiserfs fs_reiserfs;
FILESYSTEMS .push_back( fs_reiserfs .get_filesystem_support( ) ) ;
}
void GParted_Core::get_devices( std::vector<Device> & devices, bool deep_scan )
{
devices .clear( ) ;
//try to find all available devices and put these in a list
ped_device_probe_all( );
Device temp_device ;
std::vector <Glib::ustring> device_paths ;
device = ped_device_get_next ( NULL );
//in certain cases (e.g. when there's a cd in the cdrom-drive) ped_device_probe_all will find a 'ghost' device that has no name or contains
//random garbage. Those 2 checks try to prevent such a ghostdevice from being initialized.. (tested over a 1000 times with and without cd)
while ( device && strlen( device ->path ) > 6 && ( (Glib::ustring) device ->path ). is_ascii( ) )
{
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 ) ;
//and sort the devices on name.. (this prevents some very weird errors ;) )
sort( device_paths .begin( ), device_paths .end( ) ) ;
for ( unsigned int t = 0 ; t < device_paths .size( ) ; t++ )
{
if ( open_device_and_disk( device_paths[ t ], device, disk ) )
{
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 ) ;
get_partitions( temp_device .device_partitions, temp_device .path, deep_scan ) ;
devices .push_back( temp_device ) ;
close_device_and_disk( device, disk ) ;
}
}
}
void GParted_Core::get_partitions( std::vector<Partition> & partitions, const Glib::ustring & device_path, bool deep_scan )
{
Partition partition_temp ;
Glib::ustring part_path, error ;
int EXT_INDEX = -1 ;
//clear partitions
partitions .clear( ) ;
c_partition = ped_disk_next_partition( disk, NULL ) ;
while ( c_partition )
{
partition_temp .Reset( ) ;
part_path = device_path + num_to_str( c_partition ->num ) ;
switch ( c_partition ->type )
{
case PED_PARTITION_NORMAL:
case PED_PARTITION_LOGICAL:
if ( c_partition ->fs_type )
temp = c_partition ->fs_type ->name ;
else
{
temp = "unknown" ;
error = _( "Unable to detect filesystem! Possible reasons are:" ) ;
error += "\n-";
error += _( "The filesystem is damaged" ) ;
error += "\n-" ;
error += _( "The filesystem is unknown to libparted" ) ;
error += "\n-";
error += _( "There is no filesystem available (unformatted)" ) ;
}
partition_temp.Set( part_path,
c_partition ->num,
c_partition ->type == 0 ? GParted::PRIMARY : GParted::LOGICAL ,
temp, c_partition ->geom .start,
c_partition ->geom .end,
c_partition ->type,
ped_partition_is_busy( c_partition ) );
if ( deep_scan )
partition_temp .Set_Used( Get_Used_Sectors( c_partition, part_path ) ) ;
partition_temp .flags = Get_Flags( c_partition ) ;
partition_temp .error = error .empty( ) ? error_message : error ;
break ;
case PED_PARTITION_EXTENDED:
partition_temp.Set( part_path ,
c_partition ->num ,
GParted::EXTENDED ,
"extended" ,
c_partition ->geom .start ,
c_partition ->geom .end ,
false ,
ped_partition_is_busy( c_partition ) );
partition_temp .flags = Get_Flags( c_partition ) ;
EXT_INDEX = partitions .size ( ) ;
break ;
case PED_PARTITION_FREESPACE:
case 5: //freespace inside extended (there's no enumvalue for that..)
partition_temp.Set_Unallocated( c_partition ->geom .start, c_partition ->geom .end, c_partition ->type == 4 ? false : true );
break ;
case PED_PARTITION_METADATA:
if ( partitions .size( ) && partitions .back( ) .type == GParted::UNALLOCATED )
partitions .back( ) .sector_end = c_partition ->geom .end ;
break ;
case 9: //metadata inside extended (there's no enumvalue for that..)
if ( partitions[ EXT_INDEX ] .logicals .size( ) && partitions[ EXT_INDEX ] .logicals .back( ) .type == GParted::UNALLOCATED )
partitions[ EXT_INDEX ] .logicals .back( ) .sector_end = c_partition ->geom .end ;
break ;
default: break;
}
if ( partition_temp .Get_Length_MB( ) >= 1 ) // check for unallocated < 1MB, and metadatasituations (see PED_PARTITION_METADATA and 9 )
{
if ( ! partition_temp .inside_extended )
partitions.push_back( partition_temp );
else
partitions[ EXT_INDEX ] .logicals .push_back( partition_temp ) ;
}
//reset stuff..
error = error_message = "" ;
//next partition (if any)
c_partition = ped_disk_next_partition ( disk, c_partition ) ;
}
}
int GParted_Core::get_estimated_time( Operation & operation )
{
switch ( operation .operationtype )
{
case GParted::DELETE:
return 2 ; //i guess it'll never take more then 2 secs to delete a partition ;)
case GParted::CREATE:
case GParted::CONVERT:
set_proper_filesystem( operation .partition_new .filesystem ) ;
if ( p_filesystem )
return p_filesystem ->get_estimated_time( operation .partition_new .Get_Length_MB( ) ) ;
break ;
case GParted::RESIZE_MOVE:
set_proper_filesystem( operation .partition_new .filesystem ) ;
if ( p_filesystem )
return p_filesystem ->get_estimated_time( Abs( operation .partition_original .Get_Length_MB( ) - operation .partition_new .Get_Length_MB( ) ) ) ;
break ;
case GParted::COPY:
//lets take 10MB/s for the moment..
return operation .partition_new .Get_Length_MB( ) / 10 ;
}
return -1 ; //pulsing
}
void GParted_Core::Apply_Operation_To_Disk( Operation & operation )
{
switch ( operation .operationtype )
{
case DELETE:
if ( ! Delete( operation .device_path, operation .partition_original ) )
Show_Error( String::ucompose( _("Error while deleting %1"), operation .partition_original .partition ) ) ;
break;
case CREATE:
if ( ! Create( operation .device_path, operation .partition_new ) )
Show_Error( String::ucompose( _("Error while creating %1"), operation .partition_new .partition ) );
break;
case RESIZE_MOVE:
if ( ! Resize( operation .device_path, operation .partition_original, operation .partition_new ) )
Show_Error( String::ucompose( _("Error while resizing/moving %1"), operation .partition_new .partition ) ) ;
break;
case CONVERT:
if ( ! Convert_FS( operation .device_path, operation .partition_new ) )
Show_Error( String::ucompose( _("Error while converting filesystem of %1"), operation .partition_new .partition ) ) ;
break;
case COPY:
if ( ! Copy( operation .device_path, operation .copied_partition_path, operation .partition_new ) )
Show_Error( String::ucompose( _("Error while copying %1"), operation .partition_new .partition ) ) ;
}
}
bool GParted_Core::Create( const Glib::ustring & device_path, Partition & new_partition )
{
if ( new_partition .type == GParted::EXTENDED )
return Create_Empty_Partition( device_path, new_partition ) ;
else if ( Create_Empty_Partition( device_path, new_partition ) > 0 )
{
set_proper_filesystem( new_partition .filesystem ) ;
return p_filesystem ->Create( device_path, new_partition ) ;
}
return false ;
}
bool GParted_Core::Convert_FS( const Glib::ustring & device_path, const Partition & partition )
{
set_proper_filesystem( partition .filesystem ) ;
return p_filesystem ->Create( device_path, partition ) ;
}
bool GParted_Core::Delete( const Glib::ustring & device_path, const Partition & partition )
{
bool return_value = false ;
if ( open_device_and_disk( device_path, device, disk ) )
{
if ( partition .type == GParted::EXTENDED )
c_partition = ped_disk_extended_partition( disk ) ;
else
c_partition = ped_disk_get_partition_by_sector( disk, (partition .sector_end + partition .sector_start) / 2 ) ;
return_value = ( ped_disk_delete_partition( disk, c_partition ) && Commit( disk ) ) ;
close_device_and_disk( device, disk ) ;
}
return return_value ;
}
bool GParted_Core::Resize(const Glib::ustring & device_path, const Partition & partition_old, const Partition & partition_new )
{
if ( partition_old .type == GParted::EXTENDED )
return Resize_Extended( device_path, partition_new ) ;
else
{
set_proper_filesystem( partition_new .filesystem ) ;
return p_filesystem ->Resize( device_path, partition_old, partition_new ) ;
}
return false ;
}
bool GParted_Core::Copy( const Glib::ustring & dest_device_path, const Glib::ustring & src_part_path, Partition & partition_dest )
{
if ( Create_Empty_Partition( dest_device_path, partition_dest ) > 0 )
{
set_proper_filesystem( partition_dest .filesystem ) ;
return p_filesystem ->Copy( src_part_path, partition_dest .partition ) ;
}
return false ;
}
std::vector<FS> GParted_Core::get_fs( )
{
return FILESYSTEMS ;
}
Glib::RefPtr<Gtk::TextBuffer> GParted_Core::get_textbuffer( )
{
return textbuffer ;
}
Glib::ustring GParted_Core::get_sym_path( const Glib::ustring & real_path )
{
int major, minor, size;
char temp[4096], device_name[4096], short_path[4096] ;
FILE* proc_part_file = fopen ( "/proc/partitions", "r" );
if ( ! proc_part_file )
return real_path;
//skip first 2 useless rules of /proc/partitions
fgets( temp, 256, proc_part_file ); fgets( temp, 256, proc_part_file );
while ( fgets( temp, 4096, proc_part_file ) && sscanf(temp, "%d %d %d %255s", &major, &minor, &size, device_name ) == 4 )
{
strcpy( short_path, "/dev/" ); strcat( short_path, device_name );
realpath( short_path, device_name );
if ( real_path == device_name ) {
fclose ( proc_part_file );
return ( Glib::ustring( short_path ) );
}
}
//paranoia modus :)
fclose ( proc_part_file );
return real_path;
}
Sector GParted_Core::Get_Used_Sectors( PedPartition *c_partition, const Glib::ustring & sym_path)
{
/* This is quite an unreliable process, atm i try two different methods, but since both are far from perfect the results are
* questionable.
* - first i try geometry.get_used() in libpartedpp, i implemented this function to check the minimal size when resizing a partition. Disadvantage
* of this method is the fact it won't work on mounted filesystems. Besides that, its SLOW
* - if the former method fails ( result is -1 ) i'll try to read the output from the df command ( df -k --sync <partition path> )
* - if this fails the filesystem on the partition is ( more or less ) unknown to the operating system and therefore the unused sectors cannot be calcualted
* - as soon as i have my internetconnection back i should ask people with more experience on this stuff for advice !
*/
//check if there is a (known) filesystem
if ( ! c_partition ->fs_type )
return -1;
//used sectors are not relevant for swapspace
if ( (Glib::ustring) c_partition ->fs_type ->name == "linux-swap" )
return -1;
//METHOD #1
//the getused method doesn't work on mounted partitions and for some filesystems ( i *guess* this is called check by andrew )
if ( ! ped_partition_is_busy( c_partition ) && Get_FS( c_partition ->fs_type ->name, FILESYSTEMS ) .create )
{
PedFileSystem *fs = NULL;
PedConstraint *constraint = NULL;
fs = ped_file_system_open( & c_partition ->geom );
if ( fs )
{
constraint = ped_file_system_get_resize_constraint (fs);
ped_file_system_close (fs);
if ( constraint && constraint->min_size != -1 )
return constraint->min_size ;
}
}
//METHOD #2
//this ony works for mounted ( and therefore known to the OS ) filesystems. My method is quite crude, keep in mind it's only temporary ;-)
if ( ped_partition_is_busy( c_partition ) )
{
Glib::ustring buf;
system( ("df -k --sync " + sym_path + " | grep " + sym_path + " > /tmp/.tmp_gparted") .c_str( ) );
std::ifstream file_input( "/tmp/.tmp_gparted" );
file_input >> buf; //skip first value
file_input >> buf;
if ( buf != "0" && ! buf .empty( ) )
{
file_input >> buf;
file_input .close( ); system( "rm -f /tmp/.tmp_gparted" );
return atoi( buf .c_str( ) ) * 1024/512 ;
}
file_input .close( ); system( "rm -f /tmp/.tmp_gparted" );
}
return -1 ; //all methods were unsuccesfull
}
int GParted_Core::Create_Empty_Partition( const Glib::ustring & device_path, Partition & new_partition )
{
new_partition .partition_number = 0 ;
if ( open_device_and_disk( device_path, device, disk ) )
{
PedPartitionType type;
PedPartition *c_part = NULL ;
PedConstraint *constraint = NULL ;
//create new partition
switch ( new_partition .type )
{
case 0 : type = PED_PARTITION_NORMAL; break ;
case 1 : type = PED_PARTITION_LOGICAL; break ;
case 2 : type = PED_PARTITION_EXTENDED; break ;
default : type = PED_PARTITION_FREESPACE; break ; //will never happen ;)
}
c_part = ped_partition_new ( disk, type, NULL, new_partition .sector_start, new_partition .sector_end ) ;
if ( c_part )
{
constraint = ped_constraint_any ( device );
if ( constraint )
{
if ( ped_disk_add_partition ( disk, c_part, constraint ) && Commit( disk ) )
{
sleep( 1 ) ;//the OS needs some time to create the devicenode in /dev
new_partition .partition = ped_partition_get_path( c_part ) ;
new_partition .partition_number = c_part ->num ;
}
ped_constraint_destroy ( constraint );
}
}
close_device_and_disk( device, disk ) ;
}
return new_partition .partition_number ;
}
bool GParted_Core::Resize_Extended( const Glib::ustring & device_path, const Partition & extended )
{
bool return_value = false ;
if ( open_device_and_disk( device_path, device, disk ) )
{
PedPartition *c_part = NULL ;
PedConstraint *constraint = NULL ;
c_part = ped_disk_extended_partition( disk ) ;
if ( c_part )
{
constraint = ped_constraint_any ( device );
if ( constraint )
{
if ( ped_disk_set_partition_geom ( disk, c_part, constraint, extended .sector_start, extended .sector_end ) )
{
ped_partition_set_system ( c_part, NULL );
return_value = Commit( disk ) ;
}
ped_constraint_destroy (constraint);
}
}
close_device_and_disk( device, disk ) ;
}
return return_value ;
}
Glib::ustring GParted_Core::Get_Flags( PedPartition *c_partition )
{
temp = "";
for ( unsigned short t = 0; t < flags .size( ) ; t++ )
if ( ped_partition_get_flag ( c_partition, flags[ t ] ) )
temp += (Glib::ustring) ped_partition_flag_get_name ( flags[ t ] ) + " ";
return temp ;
}
void GParted_Core::Show_Error( Glib::ustring message )
{
message = "<span weight=\"bold\" size=\"larger\">" + message + "</span>\n\n" ;
message += _( "Be aware that the failure to apply this operation could affect other operations on the list." ) ;
Gtk::MessageDialog dialog( message ,true, Gtk::MESSAGE_ERROR, Gtk::BUTTONS_OK, true );
gdk_threads_enter( );
dialog .run( );
gdk_threads_leave( );
}
void GParted_Core::set_proper_filesystem( const Glib::ustring & filesystem )
{
//ugly, stupid, *aaargh* :-)
if ( ! p_filesystem )
delete p_filesystem ;
if ( filesystem == "ext2" )
p_filesystem = new ext2( ) ;
else if ( filesystem == "ext3" )
p_filesystem = new ext3( ) ;
else if ( filesystem == "fat16" )
p_filesystem = new fat16( ) ;
else if ( filesystem == "fat32" )
p_filesystem = new fat32( ) ;
else if ( filesystem == "linux-swap" )
p_filesystem = new linux_swap( ) ;
else if ( filesystem == "reiserfs" )
p_filesystem = new reiserfs( ) ;
else
p_filesystem = NULL ;
if ( p_filesystem )
p_filesystem ->textbuffer = textbuffer ;
}
} //GParted

View File

@ -28,8 +28,16 @@ gparted_SOURCES = \
Dialog_About.cc\
Frame_Resizer_Base.cc\
Frame_Resizer_Extended.cc\
Dialog_Base_Partition.cc
Dialog_Base_Partition.cc\
GParted_Core.cc\
FileSystem.cc\
ext2.cc\
ext3.cc\
fat16.cc\
fat32.cc\
linux_swap.cc\
reiserfs.cc
gparted_LDFLAGS = -lparted -lgthread-2.0
gparted_LDADD = \

View File

@ -19,14 +19,10 @@
namespace GParted
{
Operation::Operation( Device *device, Device *source_device, const Partition & partition_original, const Partition & partition_new, OperationType operationtype )
Operation::Operation( const Glib::ustring device_path, Sector device_length, const Partition & partition_original, const Partition & partition_new, OperationType operationtype )
{
this ->device = device;
this ->device_path = device ->Get_Path( ) ;
//this is only used when operationtype == COPY
this ->source_device = source_device;
this ->source_device_path = source_device ->Get_Path( ) ;
this ->device_path = device_path ;
this ->device_length = device_length ;
this ->partition_original = partition_original;
this ->partition_new = partition_new;
@ -34,10 +30,11 @@ Operation::Operation( Device *device, Device *source_device, const Partition & p
str_operation = Get_String( ) ;
//not the nicest place to put this, but definetly the most efficient :)
if ( operationtype == COPY )
{
copied_partition_path = partition_new .partition ;
this ->partition_new .partition = String::ucompose( _("copy of %1"), this ->partition_new .partition );
}
}
@ -54,7 +51,7 @@ Glib::ustring Operation::Get_String( )
temp = partition_original .partition ;
/*TO TRANSLATORS: looks like Delete /dev/hda2 (ntfs, 2345 MB) from /dev/hda */
return String::ucompose( _("Delete %1 (%2, %3 MB) from %4"), temp, partition_original .filesystem, partition_original .Get_Length_MB(), device ->Get_Path() ) ;
return String::ucompose( _("Delete %1 (%2, %3 MB) from %4"), temp, partition_original .filesystem, partition_original .Get_Length_MB( ), device_path ) ;
case CREATE : switch( partition_new.type )
{
@ -64,7 +61,7 @@ Glib::ustring Operation::Get_String( )
default : break;
}
/*TO TRANSLATORS: looks like Create Logical Partition #1 (ntfs, 2345 MB) on /dev/hda */
return String::ucompose( _("Create %1 #%2 (%3, %4 MB) on %5"), temp, partition_new.partition_number, partition_new.filesystem , partition_new .Get_Length_MB(), device ->Get_Path() ) ;
return String::ucompose( _("Create %1 #%2 (%3, %4 MB) on %5"), temp, partition_new.partition_number, partition_new.filesystem , partition_new .Get_Length_MB( ), device_path ) ;
case RESIZE_MOVE: //if startsector has changed >= 1 MB we consider it a move
diff = Abs( partition_new .sector_start - partition_original .sector_start ) ;
if ( diff >= MEGABYTE )
@ -92,7 +89,7 @@ Glib::ustring Operation::Get_String( )
case CONVERT : /*TO TRANSLATORS: looks like Convert /dev/hda4 from ntfs to linux-swap */
return String::ucompose( _( "Convert %1 from %2 to %3"), partition_original .partition, partition_original .filesystem, partition_new .filesystem ) ;
case COPY : /*TO TRANSLATORS: looks like Copy /dev/hda4 to /dev/hdd (start at 2500 MB) */
return String::ucompose( _("Copy %1 to %2 (start at %3 MB)"), partition_new .partition, device ->Get_Path( ), Sector_To_MB( partition_new .sector_start ) ) ;
return String::ucompose( _("Copy %1 to %2 (start at %3 MB)"), partition_new .partition, device_path, Sector_To_MB( partition_new .sector_start ) ) ;
default : return "";
}
@ -111,42 +108,6 @@ void Operation::Apply_Operation_To_Visual( std::vector<Partition> & partitions )
}
}
void Operation::Apply_To_Disk( PedTimer * timer )
{
Glib::ustring buf;
bool result; //for some weird reason it won't work otherwise .. ( this one really beats me :-S )
switch ( operationtype )
{
case DELETE : result = device ->Delete_Partition( partition_original ) ;
if ( ! result )
Show_Error( String::ucompose( _("Error while deleting %1"), partition_original.partition ) ) ;
break;
case CREATE : result = device ->Create_Partition_With_Filesystem( partition_new, timer ) ;
if ( ! result )
Show_Error( String::ucompose( _("Error while creating %1"), partition_new.partition ) );
break;
case RESIZE_MOVE: result = device ->Move_Resize_Partition( partition_original, partition_new, timer ) ;
if ( ! result )
Show_Error( String::ucompose( _("Error while resizing/moving %1"), partition_new.partition ) ) ;
break;
case CONVERT : result = device ->Set_Partition_Filesystem( partition_new, timer ) ;
if ( ! result )
Show_Error( String::ucompose( _("Error while converting filesystem of %1"), partition_new.partition ) ) ;
break;
case COPY : result = device ->Copy_Partition( source_device, partition_new, timer ) ;
if ( ! result )
Show_Error( String::ucompose( _("Error while copying %1"), partition_new .partition ) ) ;
break;
}
}
void Operation::Insert_Unallocated( std::vector<Partition> & partitions, Sector start, Sector end )
{
Partition UNALLOCATED ;
@ -217,7 +178,7 @@ void Operation::Apply_Delete_To_Visual( std::vector<Partition> & partitions )
{
partitions .erase( partitions .begin( ) + Get_Index_Original( partitions ) );
Insert_Unallocated( partitions, 0, device ->Get_Length( ) -1 ) ;
Insert_Unallocated( partitions, 0, device_length -1 ) ;
}
else
{
@ -244,7 +205,7 @@ void Operation::Apply_Create_To_Visual( std::vector<Partition> & partitions )
{
partitions[ Get_Index_Original( partitions ) ] = partition_new ;
Insert_Unallocated( partitions, 0, device ->Get_Length( ) -1 ) ;
Insert_Unallocated( partitions, 0, device_length -1 ) ;
}
else
{
@ -271,7 +232,7 @@ void Operation::Apply_Resize_Move_Extended_To_Visual( std::vector<Partition> & p
partitions[ ext ] .sector_start = partition_new .sector_start ;
partitions[ ext ] .sector_end = partition_new .sector_end ;
Insert_Unallocated( partitions, 0, device ->Get_Length( ) -1 ) ;
Insert_Unallocated( partitions, 0, device_length -1 ) ;
//stuff INSIDE extended partition
ext = 0 ;
@ -286,16 +247,4 @@ void Operation::Apply_Resize_Move_Extended_To_Visual( std::vector<Partition> & p
Insert_Unallocated( partitions[ ext ] .logicals, partitions[ ext ] .sector_start, partitions[ ext ] .sector_end ) ;
}
void Operation::Show_Error( Glib::ustring message )
{
message = "<span weight=\"bold\" size=\"larger\">" + message + "</span>\n\n" ;
message += _( "Be aware that the failure to apply this operation could affect other operations on the list." ) ;
Gtk::MessageDialog dialog( message ,true, Gtk::MESSAGE_ERROR, Gtk::BUTTONS_OK, true );
gdk_threads_enter( );
dialog .run( );
gdk_threads_leave( );
}
} //GParted

View File

@ -24,13 +24,13 @@ Win_GParted::Win_GParted( )
{
copied_partition .partition = "NONE" ;
new_count = 1;
current_device = source_device = 0 ;
current_device = 0 ;
vbox_visual_disk = NULL;
pulse = false ;
//store filesystems in vector and find out if their respective libs are installed
Find_Supported_Filesystems() ;
gparted_core .find_supported_filesystems( ) ;
//locate all available devices and store them in devices vector
Find_Devices( false ) ;
Refresh_OptionMenu( ) ;
@ -86,7 +86,7 @@ Win_GParted::Win_GParted( )
close_operationslist( ) ;
conn = dispatcher .connect( sigc::mem_fun( *this, &Win_GParted::menu_gparted_refresh_devices ) );
dispatcher ( ) ;
dispatcher( ) ;
}
void Win_GParted::init_menubar()
@ -184,9 +184,9 @@ void Win_GParted::init_popupmenu()
void Win_GParted::init_convert_menu()
{
for ( unsigned int t=0; t < FILESYSTEMS .size() ; t++ )
for ( unsigned int t=0; t < gparted_core .get_fs( ) .size() ; t++ )
{
color .set( Get_Color( FILESYSTEMS[ t ] .filesystem ) );
color .set( Get_Color( gparted_core .get_fs( )[ t ] .filesystem ) );
hbox = manage( new Gtk::HBox() );
//the colored square
@ -197,11 +197,11 @@ void Win_GParted::init_convert_menu()
hbox ->pack_start( *entry, Gtk::PACK_SHRINK );
//the label...
hbox ->pack_start( * mk_label( " " + FILESYSTEMS[ t ] .filesystem ), Gtk::PACK_SHRINK );
hbox ->pack_start( * mk_label( " " + gparted_core .get_fs( )[ t ] .filesystem ), Gtk::PACK_SHRINK );
menu_item = manage( new Gtk::MenuItem( *hbox ) ) ;
menu_convert.items().push_back( *menu_item);
menu_convert.items() .back() .signal_activate() .connect( sigc::bind<Glib::ustring>(sigc::mem_fun(*this, &Win_GParted::activate_convert), FILESYSTEMS[ t ] .filesystem ) ) ;
menu_convert.items() .back() .signal_activate() .connect( sigc::bind<Glib::ustring>(sigc::mem_fun(*this, &Win_GParted::activate_convert), gparted_core .get_fs( )[ t ] .filesystem ) ) ;
}
menu_convert.show_all_children() ;
@ -235,7 +235,7 @@ void Win_GParted::init_device_info()
table ->attach( * device_info .back(), 1,2, top++, bottom++, Gtk::FILL);
//only show realpath if it's different from the short path
if ( devices[ current_device ] ->Get_Path() != devices[ current_device ] ->Get_RealPath() )
if ( devices[ current_device ] .path != devices[ current_device ] .realpath )
{
table ->attach( * mk_label( " <b>" + (Glib::ustring) _( "Real Path:" ) + "</b>" ) , 0,1,top, bottom ,Gtk::FILL);
device_info .push_back( mk_label( "" ) ) ;
@ -343,59 +343,22 @@ void Win_GParted::init_hpaned_main()
hpaned_main.pack2( *scrollwindow, true,true );
}
void Win_GParted::Find_Supported_Filesystems()
{
FS fs;
static void * test_handle = NULL ;
//built-in filesystems
fs .supported = true ;
fs .create = true ;
fs .filesystem = "ext2" ; FILESYSTEMS .push_back( fs ) ;
fs .filesystem = "ext3" ; FILESYSTEMS .push_back( fs ) ; FILESYSTEMS .back() .create = false ;
fs .filesystem = "fat16" ; FILESYSTEMS .push_back( fs ) ;
fs .filesystem = "fat32" ; FILESYSTEMS .push_back( fs ) ;
fs .filesystem = "linux-swap" ; FILESYSTEMS .push_back( fs ) ;
//optional filesystems (depends if fitting libary is installed)
fs .supported = fs .create = false ;
fs .filesystem = "reiserfs" ; FILESYSTEMS .push_back( fs ) ;
if ( (test_handle = dlopen("libreiserfs.so", RTLD_NOW)) )
{
FILESYSTEMS .back() .supported = FILESYSTEMS .back() .create = true ;
dlclose( test_handle ) ;
test_handle = NULL ;
}
}
void Win_GParted::Find_Devices( bool deep_scan )
{
for ( unsigned int t = 0 ; t < devices .size( ) ; t++ )
delete devices[ t ] ;
gparted_core .get_devices( devices, deep_scan ) ;
devices .clear( ) ;
//try to find all available devices and put these in a list
ped_device_probe_all( );
PedDevice *device = ped_device_get_next ( NULL );
//in certain cases (e.g. when there's a cd in the cdrom-drive) ped_device_probe_all will find a 'ghost' device that has no name or contains
//random garbage. Those 2 checks try to prevent such a ghostdevice from being initialized.. (tested over a 1000 times with and without cd)
while ( device && strlen( device ->path ) > 6 && ( (Glib::ustring) device ->path ). is_ascii( ) )
{
temp_device = new GParted::Device( device ->path, &FILESYSTEMS );
if ( temp_device ->Get_Length() > 0 )
{
temp_device ->Read_Disk_Layout( deep_scan ) ;
devices .push_back( temp_device ) ;
}
else
delete temp_device ;
//paranoia check.. :) <---NOT threadsave..
if ( devices .empty( ) )
{
str_temp = "<span weight=\"bold\" size=\"larger\">" ;
str_temp += _("No devices were detected") ;
str_temp += "</span>\n\n" ;
str_temp += _( "You have probably encountered a bug. GParted will quit now.") ;
Gtk::MessageDialog dialog( *this, str_temp, true, Gtk::MESSAGE_ERROR, Gtk::BUTTONS_OK, true ) ;
dialog .run( ) ;
device = ped_device_get_next ( device ) ;
exit( 0 ) ;
}
}
@ -412,7 +375,7 @@ void Win_GParted::Refresh_OptionMenu( )
hbox ->pack_start( *image, Gtk::PACK_SHRINK );
//the label...
hbox ->pack_start( *mk_label( " " + devices[i] ->Get_Path() + "\t(" + String::ucompose( _("%1 MB"), Sector_To_MB( devices[i] ->Get_Length() ) ) + ")" ), Gtk::PACK_SHRINK );
hbox ->pack_start( *mk_label( " " + devices[i] .path + "\t(" + String::ucompose( _("%1 MB"), Sector_To_MB( devices[i] .length ) ) + ")" ), Gtk::PACK_SHRINK );
menu_item = manage( new Gtk::MenuItem( *hbox ) ) ;
menu_devices .items().push_back( *menu_item );
@ -459,20 +422,20 @@ void Win_GParted::Fill_Label_Device_Info( )
short t=0;
//global info...
device_info[ t++ ] ->set_text( devices[ current_device ] ->Get_Model() ) ;
device_info[ t++ ] ->set_text( String::ucompose( _("%1 MB"), Sector_To_MB( devices[ current_device ] ->Get_Length() ) ) ) ;
device_info[ t++ ] ->set_text( devices[ current_device ] ->Get_Path() ) ;
device_info[ t++ ] ->set_text( devices[ current_device ] .model ) ;
device_info[ t++ ] ->set_text( String::ucompose( _("%1 MB"), Sector_To_MB( devices[ current_device ] .length ) ) ) ;
device_info[ t++ ] ->set_text( devices[ current_device ] .path ) ;
//only show realpath if it's diffent from the short path...
if ( devices[ current_device ] ->Get_Path() != devices[ current_device ] ->Get_RealPath() )
device_info[ t++ ] ->set_text( devices[ current_device ] ->Get_RealPath() ) ;
if ( devices[ current_device ] .path != devices[ current_device ] .realpath )
device_info[ t++ ] ->set_text( devices[ current_device ] .realpath ) ;
//detailed info
device_info[ t++ ] ->set_text( devices[ current_device ] ->Get_DiskType() ) ;
device_info[ t++ ] ->set_text( num_to_str( devices[ current_device ] ->Get_Heads() ) );
device_info[ t++ ] ->set_text( num_to_str( devices[ current_device ] ->Get_Sectors() ) );
device_info[ t++ ] ->set_text( num_to_str( devices[ current_device ] ->Get_Cylinders() ) );
device_info[ t++ ] ->set_text( num_to_str( devices[ current_device ] ->Get_Length() ) );
device_info[ t++ ] ->set_text( devices[ current_device ] .disktype ) ;
device_info[ t++ ] ->set_text( num_to_str( devices[ current_device ] .heads ) );
device_info[ t++ ] ->set_text( num_to_str( devices[ current_device ] .sectors ) );
device_info[ t++ ] ->set_text( num_to_str( devices[ current_device ] .cylinders ) );
device_info[ t++ ] ->set_text( num_to_str( devices[ current_device ] .length ) );
}
bool Win_GParted::on_delete_event(GdkEventAny *event)
@ -482,8 +445,8 @@ bool Win_GParted::on_delete_event(GdkEventAny *event)
void Win_GParted::Add_Operation( OperationType operationtype, const Partition & new_partition)
{
Operation operation( devices[ current_device ], devices[ source_device ], selected_partition, new_partition, operationtype );
Operation operation( devices[ current_device ] .path, devices[ current_device ] .length, selected_partition, new_partition, operationtype );
operations.push_back( operation );
allow_undo( true );
@ -502,13 +465,13 @@ void Win_GParted::Add_Operation( OperationType operationtype, const Partition &
void Win_GParted::Refresh_Visual( )
{
std::vector<Partition> partitions = devices[current_device] ->Get_Partitions() ;
std::vector<Partition> partitions = devices[current_device] .device_partitions ;
liststore_operations ->clear();
//make all operations visible
for ( unsigned int t = 0 ; t < operations .size( ); t++ )
{
if ( operations[ t ] .device ->Get_Path( ) == devices[ current_device ] ->Get_Path( ) )
if ( operations[ t ] .device_path == devices[ current_device ] .path )
operations[ t ] .Apply_Operation_To_Visual( partitions ) ;
treerow = *(liststore_operations ->append( ));
@ -570,7 +533,7 @@ void Win_GParted::Refresh_Visual( )
delete ( vbox_visual_disk );
}
vbox_visual_disk = new VBox_VisualDisk ( partitions, devices[ current_device ] ->Get_Length( ) ) ;
vbox_visual_disk = new VBox_VisualDisk ( partitions, devices[ current_device ] .length ) ;
vbox_visual_disk ->signal_mouse_click.connect( sigc::mem_fun( this, &Win_GParted::mouse_click ) ) ;
hbox_visual .pack_start( *vbox_visual_disk, Gtk::PACK_EXPAND_PADDING ) ;
hbox_visual .show_all_children( ) ;
@ -643,7 +606,7 @@ void Win_GParted::Set_Valid_Operations()
allow_convert( true ) ;
//find out if resizing/moving and copying is possible
if ( Supported( selected_partition .filesystem, &FILESYSTEMS ) )
if ( Get_FS( selected_partition .filesystem, gparted_core .get_fs( ) ) .resize )
{
allow_resize( true ) ;
@ -670,9 +633,9 @@ void Win_GParted::Set_Valid_Operations()
void Win_GParted::Set_Valid_Convert_Filesystems()
{
//disable conversion to the same filesystem
for ( unsigned int t=0;t<FILESYSTEMS .size() ; t++ )
for ( unsigned int t = 0 ; t < gparted_core .get_fs( ) .size( ) ; t++ )
{
if ( FILESYSTEMS[ t ] .filesystem == selected_partition .filesystem || ! FILESYSTEMS[ t ] .create )
if ( gparted_core .get_fs( )[ t ] .filesystem == selected_partition .filesystem || ! gparted_core .get_fs( )[ t ] .create )
menu_convert .items()[ t ] .set_sensitive( false ) ;
else
menu_convert .items()[ t ] .set_sensitive( true ) ;
@ -737,16 +700,6 @@ void Win_GParted::menu_gparted_refresh_devices()
Refresh_OptionMenu( ) ;
//refresh de pointer to the device in every operation
for ( unsigned int t=0; t< operations.size() ; t++ )
for ( unsigned int i=0; i< devices.size() ; i++ )
{
if ( operations[t] .device_path == devices[ i ] ->Get_Path() )
operations[t] .device = devices[ i ] ;
if ( operations[t] .source_device_path == devices[ i ] ->Get_Path() )
operations[t] .source_device = devices[ i ] ;
}
//check if current_device is still available (think about hotpluggable shit like usbdevices)
if ( current_device >= devices .size() )
current_device = 0 ;
@ -834,10 +787,10 @@ void Win_GParted::mouse_click( GdkEventButton *event, const Partition & partitio
bool Win_GParted::max_amount_prim_reached( )
{
//Display error if user tries to create more primary partitions than the partition table can hold.
if ( ! selected_partition .inside_extended && primary_count >= devices[ current_device ] ->Get_Max_Amount_Of_Primary_Partitions( ) )
if ( ! selected_partition .inside_extended && primary_count >= devices[ current_device ] .max_prims )
{
str_temp = "<span weight=\"bold\" size=\"larger\">" ;
str_temp += String::ucompose( _("It is not possible to create more than %1 primary partitions"), devices[ current_device ] ->Get_Max_Amount_Of_Primary_Partitions( ) ) ;
str_temp += String::ucompose( _("It is not possible to create more than %1 primary partitions"), devices[ current_device ] .max_prims ) ;
str_temp += "</span>\n\n" ;
str_temp += _( "If you want more partitions you should first create an extended partition. Such a partition can contain other partitions.") ;
@ -878,15 +831,15 @@ void Win_GParted::activate_resize()
}
std::vector <Partition> partitions = devices[ current_device ] ->Get_Partitions( ) ;
std::vector <Partition> partitions = devices[ current_device ] .device_partitions ;
if ( operations.size() )
for (unsigned int t=0;t<operations.size();t++ )
if ( operations[t]. device ->Get_Path( ) == devices[ current_device ] ->Get_Path( ) )
if ( operations[t]. device_path == devices[ current_device ] .path )
operations[ t ] .Apply_Operation_To_Visual( partitions ) ;
Dialog_Partition_Resize_Move dialog;
Dialog_Partition_Resize_Move dialog( gparted_core .get_fs( ) ) ;
if ( selected_partition .type == GParted::LOGICAL )
{
@ -929,7 +882,6 @@ void Win_GParted::activate_resize()
void Win_GParted::activate_copy()
{
copied_partition = selected_partition ;
source_device = current_device ;
}
void Win_GParted::activate_paste()
@ -953,7 +905,7 @@ void Win_GParted::activate_new()
if ( ! max_amount_prim_reached( ) )
{
Dialog_Partition_New dialog;
dialog .Set_Data( selected_partition, any_extended, new_count, FILESYSTEMS ) ;
dialog .Set_Data( selected_partition, any_extended, new_count, gparted_core .get_fs( ) ) ;
dialog .set_transient_for( *this );
if ( dialog.run() == Gtk::RESPONSE_OK )
@ -973,7 +925,7 @@ void Win_GParted::activate_delete()
//it seems best to check for this and prohibit deletion with some explanation to the user.
if ( selected_partition .type == GParted::LOGICAL &&
selected_partition .status != GParted::STAT_NEW &&
selected_partition .partition_number < devices [ current_device ] -> Get_Highest_Logical_Busy( ) )
selected_partition .partition_number < devices [ current_device ] .Get_Highest_Logical_Busy( ) )
{
str_temp = "<span weight=\"bold\" size=\"larger\">" ;
str_temp += _( "Unable to delete partition!") ;
@ -1005,11 +957,8 @@ void Win_GParted::activate_delete()
//if deleted partition was on the clipboard we erase it...
if ( selected_partition .partition == copied_partition .partition )
{
copied_partition .partition = "NONE" ;
source_device = current_device ;
}
//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 ;-)
if ( selected_partition .status == GParted::STAT_NEW )
@ -1155,22 +1104,6 @@ void Win_GParted::activate_undo()
}
//-------AFAIK it's not possible to use a C++ memberfunction as a callback for a C libary function (if you know otherwise, PLEASE contact me)------------
Dialog_Progress *dp;
Glib::Dispatcher dispatcher_set_progress;
void progress_callback( PedTimer * timer, void *context )
{
if ( time(NULL) - timer ->start > 0 )
{
dp ->time_left = timer ->predicted_end - time(NULL) ;
dp ->fraction_current = timer ->frac ;
dispatcher_set_progress() ;
}
}
//---------------------------------------------------------------------------------------
void Win_GParted::activate_apply()
{
str_temp = "<span weight=\"bold\" size=\"larger\">" ;
@ -1179,22 +1112,21 @@ void Win_GParted::activate_apply()
str_temp += _( "It is recommended to backup valueable data before proceeding.") ;
Gtk::MessageDialog dialog( *this, str_temp, true, Gtk::MESSAGE_WARNING, Gtk::BUTTONS_NONE, true);
dialog.set_title( _( "Apply operations to harddisk" ) );
dialog .set_title( _( "Apply operations to harddisk" ) );
dialog.add_button( Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL );
dialog.add_button( Gtk::Stock::APPLY, Gtk::RESPONSE_OK );
dialog .add_button( Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL );
dialog .add_button( Gtk::Stock::APPLY, Gtk::RESPONSE_OK );
dialog.show_all_children( ) ;
if ( dialog.run() == Gtk::RESPONSE_OK )
dialog .show_all_children( ) ;
if ( dialog.run( ) == Gtk::RESPONSE_OK )
{
dialog.hide() ; //hide confirmationdialog
dialog .hide( ) ; //hide confirmationdialog
apply = true;
dialog_progress = new Dialog_Progress ( operations.size(), operations.front() .str_operation ) ;
dp = dialog_progress ;
conn = dispatcher .connect( sigc::mem_fun(*dialog_progress, &Dialog_Progress::Set_Next_Operation) );
dispatcher_set_progress .connect( sigc::mem_fun( *dialog_progress, &Dialog_Progress::Set_Progress_Current_Operation ) );
dialog_progress = new Dialog_Progress ( operations .size( ), gparted_core .get_textbuffer( ) ) ;
conn = dispatcher .connect( sigc::mem_fun(*dialog_progress, &Dialog_Progress::Set_Operation) );
thread = Glib::Thread::create(SigC::slot_class(*this, &Win_GParted::apply_operations_thread), true);
dialog_progress ->set_transient_for( *this );
@ -1208,32 +1140,36 @@ void Win_GParted::activate_apply()
//make list of involved devices which have at least one busy partition..
std::vector <Glib::ustring> devicenames ;
for (unsigned int t=0; t<operations .size(); t++ )
if ( std::find( devicenames .begin(), devicenames .end() , operations[ t ] .device ->Get_Path() ) == devicenames .end() &&
operations[ t ] .device ->Get_any_busy()
)
devicenames .push_back( operations[ t ] .device ->Get_Path() ) ;
for ( unsigned int t = 0; t < devices .size( ); t++ )
if ( devices[ t ] .Get_any_busy( ) )
for (unsigned int i = 0; i < operations .size( ); i++ )
if ( operations[ i ] .device_path == devices[ t ] .path )
{
devicenames .push_back( devices[ t ] .path ) ;
break ;
}
//show warning if necessary
if ( devicenames .size() )
if ( devicenames .size( ) )
{
str_temp = "<span weight=\"bold\" size=\"larger\">" ;
/*TO TRANSLATORS: after the colon (:) a list of devices will be shown */
str_temp += _("The kernel was unable to re-read the partition table on:") ;
str_temp += "\n";
for (unsigned int t=0; t<devicenames .size(); t++ )
for (unsigned int t=0; t<devicenames .size( ); t++ )
str_temp += "- " + devicenames[ t ] + "\n";
str_temp += "</span>\n\n" ;
str_temp += _( "This means Linux won't know anything about the modifications you made until you reboot.") ;
str_temp += "\n\n" ;
if ( devicenames .size() > 1 )
if ( devicenames .size( ) > 1 )
str_temp += _( "You should reboot your computer before doing anything with these devices.") ;
else
str_temp += _( "You should reboot your computer before doing anything with this device.") ;
Gtk::MessageDialog dialog( *this, str_temp, true, Gtk::MESSAGE_WARNING, Gtk::BUTTONS_OK, true);
dialog.run() ;
Gtk::MessageDialog dialog( *this, str_temp, true, Gtk::MESSAGE_WARNING, Gtk::BUTTONS_OK, true );
dialog .run( ) ;
}
@ -1247,22 +1183,18 @@ void Win_GParted::activate_apply()
//reread devices and their layouts...
menu_gparted_refresh_devices( ) ;
}
}
void Win_GParted::apply_operations_thread( )
{
for ( unsigned int t=0;t<operations.size() && apply ;t++ )
{
operations[t] .Apply_To_Disk( ped_timer_new( progress_callback, NULL ) );
for ( unsigned int t = 0 ; t < operations .size( ) && apply ; t++ )
{
dialog_progress ->current_operation = operations[ t ] .str_operation ;
dialog_progress ->TIME_LEFT = gparted_core .get_estimated_time( operations[ t ] ) ;
dispatcher( ) ;
if ( t < operations .size() -1 )
{
dialog_progress ->current_operation = operations[ t +1 ] .str_operation ;
dispatcher( ) ;
}
gparted_core .Apply_Operation_To_Disk( operations[ t ] );
}
dialog_progress ->response( Gtk::RESPONSE_OK );

117
src/ext2.cc Normal file
View File

@ -0,0 +1,117 @@
/* 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/ext2.h"
namespace GParted
{
FS ext2::get_filesystem_support( )
{
FS fs ;
fs .filesystem = "ext2" ;
fs .create = true ;
fs .resize = true ;
return fs ;
}
bool ext2::Create( const Glib::ustring device_path, const Partition & new_partition )
{
bool return_value = false ;
if ( open_device_and_disk( device_path, device, disk ) )
{
PedPartition *c_part = NULL ;
PedFileSystemType *fs_type = NULL ;
PedFileSystem *fs = NULL ;
c_part = ped_disk_get_partition_by_sector( disk, (new_partition .sector_end + new_partition .sector_start) / 2 ) ;
if ( c_part )
{
fs_type = ped_file_system_type_get( "ext2" ) ;
if ( fs_type )
{
fs = ped_file_system_create( & c_part ->geom, fs_type, NULL );
if ( fs )
{
if ( ped_partition_set_system( c_part, fs_type ) )
return_value = Commit( disk ) ;
ped_file_system_close( fs );
}
}
}
close_device_and_disk( device, disk ) ;
}
return return_value ;
}
bool ext2::Resize( const Glib::ustring device_path, const Partition & partition_old, const Partition & partition_new )
{
bool return_value = false ;
PedPartition *c_part = NULL ;
PedFileSystem *fs = NULL ;
PedConstraint *constraint = NULL ;
if ( open_device_and_disk( device_path, device, disk ) )
{
c_part = ped_disk_get_partition_by_sector( disk, (partition_old .sector_end + partition_old .sector_start) / 2 ) ;
if ( c_part )
{
fs = ped_file_system_open ( & c_part->geom );
if ( fs )
{
constraint = ped_file_system_get_resize_constraint ( fs );
if ( constraint )
{
if ( ped_disk_set_partition_geom ( disk, c_part, constraint, partition_new .sector_start, partition_new .sector_end ) &&
ped_file_system_resize ( fs, & c_part->geom, NULL ) )
return_value = Commit( disk ) ;
ped_constraint_destroy ( constraint );
}
ped_file_system_close ( fs );
}
}
close_device_and_disk( device, disk ) ;
}
return return_value ;
}
bool ext2::Copy( const Glib::ustring & src_part_path, const Glib::ustring & dest_part_path )
{
return Execute_Command( "dd bs=8192 if=" + src_part_path + " of=" + dest_part_path ) ;
}
int ext2::get_estimated_time( long MB_to_Consider )
{
return 1 + MB_to_Consider / 500 ;
}
} //GParted

125
src/ext3.cc Normal file
View File

@ -0,0 +1,125 @@
/* 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/ext3.h"
namespace GParted
{
FS ext3::get_filesystem_support( )
{
FS fs ;
fs .filesystem = "ext3" ;
if ( ! system( "which tune2fs 1>/dev/null 2>/dev/null" ) ) ;
fs .create = true ;
fs .resize = true ;
return fs ;
}
bool ext3::Create( const Glib::ustring device_path, const Partition & new_partition )
{
bool return_value = false ;
if ( open_device_and_disk( device_path, device, disk ) )
{
PedPartition *c_part = NULL ;
PedFileSystemType *fs_type = NULL ;
PedFileSystem *fs = NULL ;
c_part = ped_disk_get_partition_by_sector( disk, (new_partition .sector_end + new_partition .sector_start) / 2 ) ;
if ( c_part )
{
fs_type = ped_file_system_type_get( "ext2" ) ;
if ( fs_type )
{
fs = ped_file_system_create( & c_part ->geom, fs_type, NULL );
if ( fs )
{
if ( ped_partition_set_system(c_part, fs_type ) )
{
return_value = Commit( disk ) ;
sleep( 1 ) ;
//system( ("tune2fs -j " + new_partition .partition) .c_str( ) ) ;
Execute_Command( "tune2fs -j " + new_partition .partition ) ;
}
ped_file_system_close( fs );
}
}
}
close_device_and_disk( device, disk) ;
}
return return_value ;
}
bool ext3::Resize( const Glib::ustring device_path, const Partition & partition_old, const Partition & partition_new )
{
bool return_value = false ;
PedPartition *c_part = NULL ;
PedFileSystem *fs = NULL ;
PedConstraint *constraint = NULL ;
if ( open_device_and_disk( device_path, device, disk ) )
{
c_part = ped_disk_get_partition_by_sector( disk, (partition_old .sector_end + partition_old .sector_start) / 2 ) ;
if ( c_part )
{
fs = ped_file_system_open ( & c_part->geom );
if ( fs )
{
constraint = ped_file_system_get_resize_constraint ( fs );
if ( constraint )
{
if ( ped_disk_set_partition_geom ( disk, c_part, constraint, partition_new .sector_start, partition_new .sector_end ) &&
ped_file_system_resize ( fs, & c_part->geom, NULL ) )
return_value = Commit( disk ) ;
ped_constraint_destroy ( constraint );
}
ped_file_system_close ( fs );
}
}
close_device_and_disk( device, disk ) ;
}
return return_value ;
}
bool ext3::Copy( const Glib::ustring & src_part_path, const Glib::ustring & dest_part_path )
{
return Execute_Command( "dd bs=8192 if=" + src_part_path + " of=" + dest_part_path ) ;
}
int ext3::get_estimated_time( long MB_to_Consider )
{
return 1 + MB_to_Consider / 400 ;
}
} //GParted

117
src/fat16.cc Normal file
View File

@ -0,0 +1,117 @@
/* 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/fat16.h"
namespace GParted
{
FS fat16::get_filesystem_support( )
{
FS fs ;
fs .filesystem = "fat16" ;
fs .create = true ;
fs .resize = true ;
fs .move = true ;
return fs ;
}
bool fat16::Create( const Glib::ustring device_path, const Partition & new_partition )
{
bool return_value = false ;
if ( open_device_and_disk( device_path, device, disk ) )
{
PedPartition *c_part = NULL ;
PedFileSystemType *fs_type = NULL ;
PedFileSystem *fs = NULL ;
c_part = ped_disk_get_partition_by_sector( disk, (new_partition .sector_end + new_partition .sector_start) / 2 ) ;
if ( c_part )
{
fs_type = ped_file_system_type_get( "fat16" ) ;
if ( fs_type )
{
fs = ped_file_system_create( & c_part ->geom, fs_type, NULL );
if ( fs )
{
if ( ped_partition_set_system(c_part, fs_type ) )
return_value = Commit( disk ) ;
ped_file_system_close( fs );
}
}
}
close_device_and_disk( device, disk) ;
}
return return_value ;
}
bool fat16::Resize( const Glib::ustring device_path, const Partition & partition_old, const Partition & partition_new )
{
bool return_value = false ;
PedPartition *c_part = NULL ;
PedFileSystem *fs = NULL ;
PedConstraint *constraint = NULL ;
if ( open_device_and_disk( device_path, device, disk ) )
{
c_part = ped_disk_get_partition_by_sector( disk, (partition_old .sector_end + partition_old .sector_start) / 2 ) ;
if ( c_part )
{
fs = ped_file_system_open ( & c_part->geom );
if ( fs )
{
constraint = ped_file_system_get_resize_constraint ( fs );
if ( constraint )
{
if ( ped_disk_set_partition_geom ( disk, c_part, constraint, partition_new .sector_start, partition_new .sector_end ) &&
ped_file_system_resize ( fs, & c_part->geom, NULL ) )
return_value = Commit( disk ) ;
ped_constraint_destroy ( constraint );
}
ped_file_system_close ( fs );
}
}
close_device_and_disk( device, disk) ;
}
return return_value ;
}
bool fat16::Copy( const Glib::ustring & src_part_path, const Glib::ustring & dest_part_path )
{
return Execute_Command( "dd bs=8192 if=" + src_part_path + " of=" + dest_part_path ) ;
}
int fat16::get_estimated_time( long MB_to_Consider )
{
return 1 ;
}
} //GParted

118
src/fat32.cc Normal file
View File

@ -0,0 +1,118 @@
/* 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/fat32.h"
namespace GParted
{
FS fat32::get_filesystem_support( )
{
FS fs ;
fs .filesystem = "fat32" ;
fs .create = true ;
fs .resize = true ;
fs .move = true ;
return fs ;
}
bool fat32::Create( const Glib::ustring device_path, const Partition & new_partition )
{
bool return_value = false ;
if ( open_device_and_disk( device_path, device, disk ) )
{
PedPartition *c_part = NULL ;
PedFileSystemType *fs_type = NULL ;
PedFileSystem *fs = NULL ;
c_part = ped_disk_get_partition_by_sector( disk, (new_partition .sector_end + new_partition .sector_start) / 2 ) ;
if ( c_part )
{
fs_type = ped_file_system_type_get( "fat32" ) ;
if ( fs_type )
{
fs = ped_file_system_create( & c_part ->geom, fs_type, NULL );
if ( fs )
{
if ( ped_partition_set_system(c_part, fs_type ) )
return_value = Commit( disk ) ;
ped_file_system_close( fs );
}
}
}
close_device_and_disk( device, disk ) ;
}
return return_value ;
}
bool fat32::Resize( const Glib::ustring device_path, const Partition & partition_old, const Partition & partition_new )
{
bool return_value = false ;
PedPartition *c_part = NULL ;
PedFileSystem *fs = NULL ;
PedConstraint *constraint = NULL ;
if ( open_device_and_disk( device_path, device, disk ) )
{
c_part = ped_disk_get_partition_by_sector( disk, (partition_old .sector_end + partition_old .sector_start) / 2 ) ;
if ( c_part )
{
fs = ped_file_system_open ( & c_part->geom );
if ( fs )
{
constraint = ped_file_system_get_resize_constraint ( fs );
if ( constraint )
{
if ( ped_disk_set_partition_geom ( disk, c_part, constraint, partition_new .sector_start, partition_new .sector_end ) &&
ped_file_system_resize ( fs, & c_part->geom, NULL ) )
return_value = Commit( disk ) ;
ped_constraint_destroy ( constraint );
}
ped_file_system_close ( fs );
}
}
close_device_and_disk( device, disk) ;
}
return return_value ;
}
bool fat32::Copy( const Glib::ustring & src_part_path, const Glib::ustring & dest_part_path )
{
return Execute_Command( "dd bs=8192 if=" + src_part_path + " of=" + dest_part_path ) ;
}
int fat32::get_estimated_time( long MB_to_Consider )
{
return 1 + MB_to_Consider / 5000 ;
}
} //GParted

116
src/linux_swap.cc Normal file
View File

@ -0,0 +1,116 @@
/* 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/linux_swap.h"
namespace GParted
{
FS linux_swap::get_filesystem_support( )
{
FS fs ;
fs .filesystem = "linux-swap" ;
fs .create = true ;
fs .resize = true ;
fs .move = true ;
return fs ;
}
bool linux_swap::Create( const Glib::ustring device_path, const Partition & new_partition )
{
bool return_value = false ;
if ( open_device_and_disk( device_path, device, disk ) )
{
PedPartition *c_part = NULL ;
PedFileSystemType *fs_type = NULL ;
PedFileSystem *fs = NULL ;
c_part = ped_disk_get_partition_by_sector( disk, (new_partition .sector_end + new_partition .sector_start) / 2 ) ;
if ( c_part )
{
fs_type = ped_file_system_type_get( "linux-swap" ) ;
if ( fs_type )
{
fs = ped_file_system_create( & c_part ->geom, fs_type, NULL );
if ( fs )
{
if ( ped_partition_set_system(c_part, fs_type ) )
return_value = Commit( disk ) ;
ped_file_system_close( fs );
}
}
}
close_device_and_disk( device, disk ) ;
}
return return_value ;
}
bool linux_swap::Resize( const Glib::ustring device_path, const Partition & partition_old, const Partition & partition_new )
{
bool return_value = false ;
PedPartition *c_part = NULL ;
PedFileSystem *fs = NULL ;
PedConstraint *constraint = NULL ;
if ( open_device_and_disk( device_path, device, disk ) )
{
c_part = ped_disk_get_partition_by_sector( disk, (partition_old .sector_end + partition_old .sector_start) / 2 ) ;
if ( c_part )
{
fs = ped_file_system_open ( & c_part->geom );
if ( fs )
{
constraint = ped_file_system_get_resize_constraint ( fs );
if ( constraint )
{
if ( ped_disk_set_partition_geom ( disk, c_part, constraint, partition_new .sector_start, partition_new .sector_end ) &&
ped_file_system_resize ( fs, & c_part->geom, NULL ) )
return_value = Commit( disk ) ;
ped_constraint_destroy ( constraint );
}
ped_file_system_close ( fs );
}
}
close_device_and_disk( device, disk ) ;
}
return return_value ;
}
bool linux_swap::Copy( const Glib::ustring & src_part_path, const Glib::ustring & dest_part_path )
{
return Execute_Command( "dd bs=8192 if=" + src_part_path + " of=" + dest_part_path ) ;
}
int linux_swap::get_estimated_time( long MB_to_Consider )
{
return 1 + MB_to_Consider / 5000 ;
}
} //GParted

124
src/reiserfs.cc Normal file
View File

@ -0,0 +1,124 @@
/* 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/reiserfs.h"
namespace GParted
{
FS reiserfs::get_filesystem_support( )
{
FS fs ;
fs .filesystem = "reiserfs" ;
static void * test_handle = NULL ;
if ( (test_handle = dlopen("libreiserfs.so", RTLD_NOW)) )
{
fs .create = true ;
fs .resize = true ;
dlclose( test_handle ) ;
test_handle = NULL ;
}
return fs ;
}
bool reiserfs::Create( const Glib::ustring device_path, const Partition & new_partition )
{
bool return_value = false ;
if ( open_device_and_disk( device_path, device, disk ) )
{
PedPartition *c_part = NULL ;
PedFileSystemType *fs_type = NULL ;
PedFileSystem *fs = NULL ;
c_part = ped_disk_get_partition_by_sector( disk, (new_partition .sector_end + new_partition .sector_start) / 2 ) ;
if ( c_part )
{
fs_type = ped_file_system_type_get( "reiserfs" ) ;
if ( fs_type )
{
fs = ped_file_system_create( & c_part ->geom, fs_type, NULL );
if ( fs )
{
if ( ped_partition_set_system(c_part, fs_type ) )
return_value = Commit( disk ) ;
ped_file_system_close( fs );
}
}
}
close_device_and_disk( device, disk ) ;
}
return return_value ;
}
bool reiserfs::Resize( const Glib::ustring device_path, const Partition & partition_old, const Partition & partition_new )
{
bool return_value = false ;
PedPartition *c_part = NULL ;
PedFileSystem *fs = NULL ;
PedConstraint *constraint = NULL ;
if ( open_device_and_disk( device_path, device, disk ) )
{
c_part = ped_disk_get_partition_by_sector( disk, (partition_old .sector_end + partition_old .sector_start) / 2 ) ;
if ( c_part )
{
fs = ped_file_system_open ( & c_part->geom );
if ( fs )
{
constraint = ped_file_system_get_resize_constraint ( fs );
if ( constraint )
{
if ( ped_disk_set_partition_geom ( disk, c_part, constraint, partition_new .sector_start, partition_new .sector_end ) &&
ped_file_system_resize ( fs, & c_part->geom, NULL ) )
return_value = Commit( disk ) ;
ped_constraint_destroy ( constraint );
}
ped_file_system_close ( fs );
}
}
close_device_and_disk( device, disk ) ;
}
return return_value ;
}
bool reiserfs::Copy( const Glib::ustring & src_part_path, const Glib::ustring & dest_part_path )
{
return Execute_Command( "dd bs=8192 if=" + src_part_path + " of=" + dest_part_path ) ;
}
int reiserfs::get_estimated_time( long MB_to_Consider )
{
return 1 + MB_to_Consider / 1000 ;
}
} //GParted