Simplify use of the progress bar via OperationDetail (#760709)
Most of the file system specific command progress trackers followed this pattern: void {CLASS}::{NAME}_progress( OperationDetail *operationdetail ) { ProgressBar & progressbar = operationdetail->get_progressbar(); // parse output for progress and target values if ( // have progress and target values ) { if ( ! progressbar.running() ) progressbar.start( target ); progressbar.update( progress ); operationdetail->signal_update( *operationdetail ); } else if ( // found progress finished ) { if ( progressbar.running() ) progressbar.stop(); operationdetail->signal_update( *operationdetail ); } } That is a lot of repetition handling progress bar updates and OperationDetail object update signalling. Remove the need for direct access to the single ProgressBar object and provide these two OperationDetail methods instead: // Start and update in one run_progressbar( progress, target, optional text_mode ); stop_progressbar(); Now the file system specific command progress trackers can become: void {CLASS}::{NAME}_progress( OperationDetail *operationdetail ) { // parse output for progress and target values if ( // have progress and target values ) { operationdetail->run_progressbar( progress, target ); } else if ( // found progress finished ) { operationdetail->stop_progressbar(); } } Make ProgressBar::get_progressbar() a private method to enforce use of the new way to access the progress bar via the run_progress() and stop_progressbar() methods. Then make the Dialog_Progress a friend class to OperationDetail so that the Apply pending operations dialog can still access the single ProgressBar object for its querying needs. Bug 760709 - Add progress bars to XFS and EXT2/3/4 file system specific copy methods
This commit is contained in:
parent
32622f4d57
commit
b1313281bd
|
@ -47,6 +47,10 @@ enum Font {
|
|||
|
||||
class OperationDetail
|
||||
{
|
||||
|
||||
friend class Dialog_Progress; // To allow Dialog_Progress::on_signal_update() to call
|
||||
// get_progressbar() and get direct access to the progress bar.
|
||||
|
||||
public:
|
||||
OperationDetail() ;
|
||||
~OperationDetail();
|
||||
|
@ -65,7 +69,8 @@ public:
|
|||
std::vector<OperationDetail*> & get_childs() ;
|
||||
const std::vector<OperationDetail*> & get_childs() const ;
|
||||
OperationDetail & get_last_child() ;
|
||||
ProgressBar & get_progressbar() const;
|
||||
void run_progressbar( double progress, double target, ProgressBar_Text text_mode = PROGRESSBAR_TEXT_NONE );
|
||||
void stop_progressbar();
|
||||
|
||||
double fraction ;
|
||||
Glib::ustring progress_text ;
|
||||
|
@ -73,9 +78,12 @@ public:
|
|||
sigc::signal< void, const OperationDetail & > signal_update ;
|
||||
sigc::signal< void, bool > signal_cancel;
|
||||
char cancelflag;
|
||||
|
||||
private:
|
||||
void on_update( const OperationDetail & operationdetail ) ;
|
||||
void cancel( bool force );
|
||||
ProgressBar & get_progressbar() const;
|
||||
|
||||
Glib::ustring description ;
|
||||
OperationDetailStatus status ;
|
||||
|
||||
|
|
|
@ -62,7 +62,7 @@ copy_blocks::copy_blocks( const Glib::ustring & in_src_device,
|
|||
bool copy_blocks::set_progress_info()
|
||||
{
|
||||
Byte_Value done = llabs(this->done);
|
||||
operationdetail.get_progressbar().update( (double)done );
|
||||
operationdetail.run_progressbar( (double)done, (double)length, PROGRESSBAR_TEXT_COPY_BYTES );
|
||||
OperationDetail &operationdetail = this->operationdetail.get_last_child().get_last_child();
|
||||
operationdetail.fraction = done / static_cast<double>( length );
|
||||
|
||||
|
@ -166,7 +166,7 @@ bool copy_blocks::copy()
|
|||
String::ucompose( _("copy %1 using a block size of %2"),
|
||||
Utils::format_size( length, 1 ),
|
||||
Utils::format_size( blocksize, 1 ) ) ) );
|
||||
operationdetail.get_progressbar().start( (double)length, PROGRESSBAR_TEXT_COPY_BYTES );
|
||||
operationdetail.run_progressbar( 0.0, (double)length, PROGRESSBAR_TEXT_COPY_BYTES );
|
||||
|
||||
done = length % blocksize;
|
||||
|
||||
|
@ -202,7 +202,7 @@ bool copy_blocks::copy()
|
|||
else
|
||||
error_message = Glib::strerror( errno );
|
||||
|
||||
operationdetail.get_progressbar().stop();
|
||||
operationdetail.stop_progressbar();
|
||||
operationdetail.get_last_child().set_status( success ? STATUS_SUCCES : STATUS_ERROR );
|
||||
return success;
|
||||
}
|
||||
|
|
|
@ -160,9 +160,21 @@ OperationDetail & OperationDetail::get_last_child()
|
|||
return *sub_details[sub_details.size() - 1];
|
||||
}
|
||||
|
||||
ProgressBar & OperationDetail::get_progressbar() const
|
||||
void OperationDetail::run_progressbar( double progress, double target, ProgressBar_Text text_mode )
|
||||
{
|
||||
return single_progressbar;
|
||||
if ( ! single_progressbar.running() )
|
||||
single_progressbar.start( target, text_mode );
|
||||
single_progressbar.update( progress );
|
||||
signal_update.emit( *this );
|
||||
}
|
||||
|
||||
void OperationDetail::stop_progressbar()
|
||||
{
|
||||
if ( single_progressbar.running() )
|
||||
{
|
||||
single_progressbar.stop();
|
||||
signal_update.emit( *this );
|
||||
}
|
||||
}
|
||||
|
||||
// Private methods
|
||||
|
@ -182,4 +194,9 @@ void OperationDetail::cancel( bool force )
|
|||
signal_cancel(force);
|
||||
}
|
||||
|
||||
ProgressBar & OperationDetail::get_progressbar() const
|
||||
{
|
||||
return single_progressbar;
|
||||
}
|
||||
|
||||
} //GParted
|
||||
|
|
42
src/ext2.cc
42
src/ext2.cc
|
@ -296,7 +296,6 @@ bool ext2::copy( const Partition & src_part,
|
|||
|
||||
void ext2::resize_progress( OperationDetail *operationdetail )
|
||||
{
|
||||
ProgressBar & progressbar = operationdetail->get_progressbar();
|
||||
Glib::ustring line = Utils::last_line( output );
|
||||
size_t llen = line.length();
|
||||
// There may be multiple text progress bars on subsequent last lines which look
|
||||
|
@ -317,46 +316,34 @@ void ext2::resize_progress( OperationDetail *operationdetail )
|
|||
q = llen;
|
||||
size_t xlen = q - p;
|
||||
|
||||
if ( ! progressbar.running() )
|
||||
progressbar.start( (double)barlen );
|
||||
progressbar.update( (double)xlen );
|
||||
operationdetail->signal_update( *operationdetail );
|
||||
operationdetail->run_progressbar( (double)xlen, (double)barlen );
|
||||
}
|
||||
// Ending summary line looks like:
|
||||
// "The filesystem on /dev/sdb3 is now 256000 block long."
|
||||
else if ( output.find( " is now " ) != output.npos )
|
||||
{
|
||||
if ( progressbar.running() )
|
||||
progressbar.stop();
|
||||
operationdetail->signal_update( *operationdetail );
|
||||
operationdetail->stop_progressbar();
|
||||
}
|
||||
}
|
||||
|
||||
void ext2::create_progress( OperationDetail *operationdetail )
|
||||
{
|
||||
ProgressBar & progressbar = operationdetail->get_progressbar();
|
||||
Glib::ustring line = Utils::last_line( output );
|
||||
// Text progress on the LAST LINE looks like "Writing inode tables: 105/1600"
|
||||
long long progress, target;
|
||||
if ( sscanf( line.c_str(), "Writing inode tables: %Ld/%Ld", &progress, &target ) == 2 )
|
||||
{
|
||||
if ( ! progressbar.running() )
|
||||
progressbar.start( (double)target );
|
||||
progressbar.update( (double)progress );
|
||||
operationdetail->signal_update( *operationdetail );
|
||||
operationdetail->run_progressbar( (double)progress, (double)target );
|
||||
}
|
||||
// Or when finished, on any line, ...
|
||||
else if ( output.find( "Writing inode tables: done" ) != output.npos )
|
||||
{
|
||||
if ( progressbar.running() )
|
||||
progressbar.stop();
|
||||
operationdetail->signal_update( *operationdetail );
|
||||
operationdetail->stop_progressbar();
|
||||
}
|
||||
}
|
||||
|
||||
void ext2::check_repair_progress( OperationDetail *operationdetail )
|
||||
{
|
||||
ProgressBar & progressbar = operationdetail->get_progressbar();
|
||||
Glib::ustring line = Utils::last_line( output );
|
||||
// Text progress on the LAST LINE looks like
|
||||
// "/dev/sdd3: |===================================================== \ 95.1% "
|
||||
|
@ -367,10 +354,7 @@ void ext2::check_repair_progress( OperationDetail *operationdetail )
|
|||
float progress;
|
||||
if ( line.find( ": |" ) != line.npos && sscanf( pct.c_str(), "%f", &progress ) == 1 )
|
||||
{
|
||||
if ( ! progressbar.running() )
|
||||
progressbar.start( 100.0 );
|
||||
progressbar.update( progress );
|
||||
operationdetail->signal_update( *operationdetail );
|
||||
operationdetail->run_progressbar( progress, 100.0 );
|
||||
}
|
||||
// Only allow stopping the progress bar after seeing "non-contiguous" in the
|
||||
// summary at the end to prevent the GUI progress bar flashing back to pulsing
|
||||
|
@ -378,31 +362,25 @@ void ext2::check_repair_progress( OperationDetail *operationdetail )
|
|||
// output is fully updated when switching from one pass to the next.
|
||||
else if ( output.find( "non-contiguous" ) != output.npos )
|
||||
{
|
||||
if ( progressbar.running() )
|
||||
progressbar.stop();
|
||||
operationdetail->signal_update( *operationdetail );
|
||||
operationdetail->stop_progressbar();
|
||||
}
|
||||
}
|
||||
|
||||
void ext2::copy_progress( OperationDetail *operationdetail )
|
||||
{
|
||||
ProgressBar & progressbar = operationdetail->get_progressbar();
|
||||
Glib::ustring line = Utils::last_line( error );
|
||||
// Text progress on the LAST LINE of STDERR looks like "Copying 146483 / 258033 blocks ..."
|
||||
long long progress, target;
|
||||
if ( sscanf( line.c_str(), "Copying %Ld / %Ld blocks", &progress, &target ) == 2 )
|
||||
{
|
||||
if ( ! progressbar.running() )
|
||||
progressbar.start( (double)(target * fs_block_size), PROGRESSBAR_TEXT_COPY_BYTES );
|
||||
progressbar.update( (double)(progress * fs_block_size) );
|
||||
operationdetail->signal_update( *operationdetail );
|
||||
operationdetail->run_progressbar( (double)(progress * fs_block_size),
|
||||
(double)(target * fs_block_size),
|
||||
PROGRESSBAR_TEXT_COPY_BYTES );
|
||||
}
|
||||
// Or when finished, on any line of STDERR, looks like "Copied 258033 / 258033 blocks ..."
|
||||
else if ( error.find( "\nCopied " ) != error.npos )
|
||||
{
|
||||
if ( progressbar.running() )
|
||||
progressbar.stop();
|
||||
operationdetail->signal_update( *operationdetail );
|
||||
operationdetail->stop_progressbar();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
11
src/ntfs.cc
11
src/ntfs.cc
|
@ -19,7 +19,6 @@
|
|||
#include "../include/ntfs.h"
|
||||
#include "../include/OperationDetail.h"
|
||||
#include "../include/Partition.h"
|
||||
#include "../include/ProgressBar.h"
|
||||
#include "../include/Utils.h"
|
||||
|
||||
#include <glibmm/ustring.h>
|
||||
|
@ -274,7 +273,6 @@ bool ntfs::check_repair( const Partition & partition, OperationDetail & operatio
|
|||
|
||||
void ntfs::resize_progress( OperationDetail *operationdetail )
|
||||
{
|
||||
ProgressBar & progressbar = operationdetail->get_progressbar();
|
||||
Glib::ustring line = Utils::last_line( output );
|
||||
// Text progress on the LAST LINE looks like " 15.24 percent completed"
|
||||
// NOTE:
|
||||
|
@ -289,17 +287,12 @@ void ntfs::resize_progress( OperationDetail *operationdetail )
|
|||
float percent;
|
||||
if ( line.find( "percent completed" ) != line.npos && sscanf( line.c_str(), "%f", &percent ) == 1 )
|
||||
{
|
||||
if ( ! progressbar.running() )
|
||||
progressbar.start( 100.0 );
|
||||
progressbar.update( percent );
|
||||
operationdetail->signal_update( *operationdetail );
|
||||
operationdetail->run_progressbar( percent, 100.0 );
|
||||
}
|
||||
// Or when finished, on any line, ...
|
||||
else if ( output.find( "Successfully resized NTFS on device" ) != output.npos )
|
||||
{
|
||||
if ( progressbar.running() )
|
||||
progressbar.stop();
|
||||
operationdetail->signal_update( *operationdetail );
|
||||
operationdetail->stop_progressbar();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
13
src/xfs.cc
13
src/xfs.cc
|
@ -254,11 +254,10 @@ bool xfs::copy( const Partition & src_part,
|
|||
|
||||
if ( success )
|
||||
{
|
||||
ProgressBar & progressbar = operationdetail.get_progressbar();
|
||||
sigc::connection c;
|
||||
if ( src_used > 0LL )
|
||||
{
|
||||
progressbar.start( (double)src_used, PROGRESSBAR_TEXT_COPY_BYTES );
|
||||
operationdetail.run_progressbar( 0.0, (double)src_used, PROGRESSBAR_TEXT_COPY_BYTES );
|
||||
// Get xfs::copy_progress() called every 500 ms to update progress
|
||||
c = Glib::signal_timeout().connect(
|
||||
sigc::bind<OperationDetail*>( sigc::mem_fun( *this, &xfs::copy_progress ),
|
||||
|
@ -269,8 +268,7 @@ bool xfs::copy( const Partition & src_part,
|
|||
" | xfsrestore -J - " + dest_mount_point + "'",
|
||||
operationdetail, EXEC_CHECK_STATUS|EXEC_CANCEL_SAFE );
|
||||
c.disconnect();
|
||||
if ( progressbar.running() )
|
||||
progressbar.stop();
|
||||
operationdetail.stop_progressbar();
|
||||
|
||||
success &= ! execute_command( "umount -v " + dest_part.get_path(), operationdetail,
|
||||
EXEC_CHECK_STATUS );
|
||||
|
@ -298,20 +296,17 @@ bool xfs::check_repair( const Partition & partition, OperationDetail & operation
|
|||
// recorded source FS used bytes.
|
||||
bool xfs::copy_progress( OperationDetail * operationdetail )
|
||||
{
|
||||
ProgressBar & progressbar = operationdetail->get_progressbar();
|
||||
Byte_Value fs_size;
|
||||
Byte_Value fs_free;
|
||||
Byte_Value dst_used;
|
||||
if ( Utils::get_mounted_filesystem_usage( dest_mount_point, fs_size, fs_free, error ) != 0 )
|
||||
{
|
||||
if ( progressbar.running() )
|
||||
progressbar.stop();
|
||||
operationdetail->stop_progressbar();
|
||||
// Failed to get destination FS used bytes. Remove this timed callback early.
|
||||
return false;
|
||||
}
|
||||
dst_used = fs_size - fs_free;
|
||||
progressbar.update( (double)dst_used );
|
||||
operationdetail->signal_update.emit( *operationdetail );
|
||||
operationdetail->run_progressbar( (double)dst_used, (double)src_used, PROGRESSBAR_TEXT_COPY_BYTES );
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue