[gparted] Simplify use of the progress bar via OperationDetail (#760709)



commit b1313281bdaa40a7afc19687a14ac96c919f333c
Author: Mike Fleetwood <mike fleetwood googlemail com>
Date:   Sun Jan 17 12:38:58 2016 +0000

    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

 include/OperationDetail.h |   10 +++++++++-
 src/Copy_Blocks.cc        |    6 +++---
 src/OperationDetail.cc    |   21 +++++++++++++++++++--
 src/ext2.cc               |   42 ++++++++++--------------------------------
 src/ntfs.cc               |   11 ++---------
 src/xfs.cc                |   13 ++++---------
 6 files changed, 47 insertions(+), 56 deletions(-)
---
diff --git a/include/OperationDetail.h b/include/OperationDetail.h
index f119e00..4504ea6 100644
--- a/include/OperationDetail.h
+++ b/include/OperationDetail.h
@@ -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 ; 
 
diff --git a/src/Copy_Blocks.cc b/src/Copy_Blocks.cc
index b5d608d..73cfd4b 100644
--- a/src/Copy_Blocks.cc
+++ b/src/Copy_Blocks.cc
@@ -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;
 }
diff --git a/src/OperationDetail.cc b/src/OperationDetail.cc
index b66c4ef..33ac7e3 100644
--- a/src/OperationDetail.cc
+++ b/src/OperationDetail.cc
@@ -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
diff --git a/src/ext2.cc b/src/ext2.cc
index 4df034f..1e89a41 100644
--- a/src/ext2.cc
+++ b/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();
        }
 }
 
diff --git a/src/ntfs.cc b/src/ntfs.cc
index 5d2df89..0a75bdf 100644
--- a/src/ntfs.cc
+++ b/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();
        }
 }
 
diff --git a/src/xfs.cc b/src/xfs.cc
index 12021fb..ccc7b52 100644
--- a/src/xfs.cc
+++ b/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;
 }
 


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]