[gparted] Add mechanism to stop adding more child OperationDetails (#790842)



commit f8f9a72de699843a9a780f89d10d6ea615ed732b
Author: Mike Fleetwood <mike fleetwood googlemail com>
Date:   Sat Nov 25 10:37:52 2017 +0000

    Add mechanism to stop adding more child OperationDetails (#790842)
    
    Want functionality to prevent further child details being added to an
    OperationDetail.  This is so that the captured libparted error messages
    are always the last child in the list, and more details (at that point
    in the tree) can't be added.
    
    For example we want GParted to report like this:
    
      Move /dev/sdb3 to the right and shrink it from 1.14 GiB to...(SUCCESS)
      ...
      * shrink partition from 1.14 GiB to 1.00 GiB                 (SUCCESS)
        * old start: 4464640
          old end: 6856703
          old size: 2392064 (1.14 GiB)
        * new start: 4464640
          new end: 6561791
          new size: 2097152 (1.00 GiB)
        * libparted messages                                       (INFO)
          * DEBUG: GParted generated synthetic libparted excepti...
    
    and not like this:
    
      Move /dev/sdb3 to the right and shrink it from 1.14 GiB to...(SUCCESS)
      ...
      * shrink partition from 1.14 GiB to 1.00 GiB                 (SUCCESS)
        * old start: 4464640
          old end: 6856703
          old size: 2392064 (1.14 GiB)
        * libparted messages                                       (INFO)
          * DEBUG: GParted generated synthetic libparted excepti...
        * new start: 4464640
          new end: 6561791
          new size: 2097152 (1.00 GiB)
    
    So actually preventing the addition of more child details would stop
    users seeing information they should see.  So instead just report a bug
    message into the operation details.  This doesn't stop anything, but the
    bug message will be seen and allow us to fix GParted.
    
    So far nothing is enforced.  This patch just adds the mechanism to
    report a bug when a new child detail is added when prohibited.
    
    Bug 790842 - Report libparted messages into operation details at the
                 point at which they occur

 include/OperationDetail.h |    4 ++++
 src/OperationDetail.cc    |   40 +++++++++++++++++++++++++++-------------
 2 files changed, 31 insertions(+), 13 deletions(-)
---
diff --git a/include/OperationDetail.h b/include/OperationDetail.h
index 372b095..2fe4c5b 100644
--- a/include/OperationDetail.h
+++ b/include/OperationDetail.h
@@ -77,6 +77,7 @@ public:
        char cancelflag;
 
 private:
+       void add_child_implement( const OperationDetail & operationdetail );
        void on_update( const OperationDetail & operationdetail ) ;
        void cancel( bool force );
        ProgressBar & get_progressbar() const;
@@ -88,6 +89,9 @@ private:
        
        std::vector<OperationDetail*> sub_details;
        std::time_t time_start, time_elapsed ;
+       bool no_more_children;  // Disallow adding more children to ensure captured errors
+                               // remain the last child of this operation detail.
+
        sigc::connection cancelconnection;
 };
 
diff --git a/src/OperationDetail.cc b/src/OperationDetail.cc
index a8fe3a1..3a703a8 100644
--- a/src/OperationDetail.cc
+++ b/src/OperationDetail.cc
@@ -25,12 +25,13 @@ namespace GParted
 // The single progress bar for the current operation
 static ProgressBar single_progressbar;
 
-OperationDetail::OperationDetail() : cancelflag( 0 ), status( STATUS_NONE ), time_start( -1 ), time_elapsed( 
-1 )
+OperationDetail::OperationDetail() : cancelflag( 0 ), status( STATUS_NONE ), time_start( -1 ), time_elapsed( 
-1 ),
+                                     no_more_children( false )
 {
 }
 
 OperationDetail::OperationDetail( const Glib::ustring & description, OperationDetailStatus status, Font font 
) :
-       cancelflag( 0 ), status( STATUS_NONE ), time_start( -1 ), time_elapsed( -1 )
+       cancelflag( 0 ), status( STATUS_NONE ), time_start( -1 ), time_elapsed( -1 ), no_more_children( false 
)
 {
        set_description( description, font );
        set_status( status );
@@ -128,19 +129,19 @@ Glib::ustring OperationDetail::get_elapsed_time() const
        return "" ;
 }
 
-void OperationDetail::add_child( const OperationDetail & operationdetail ) 
+void OperationDetail::add_child( const OperationDetail & operationdetail )
 {
-       sub_details .push_back( new OperationDetail(operationdetail) );
-
-       sub_details.back()->set_treepath( treepath + ":" + Utils::num_to_str( sub_details .size() -1 ) );
-       sub_details.back()->signal_update.connect( sigc::mem_fun( this, &OperationDetail::on_update ) );
-       sub_details.back()->cancelconnection = signal_cancel.connect(
-                               sigc::mem_fun( sub_details.back(), &OperationDetail::cancel ) );
-       if ( cancelflag )
-               sub_details.back()->cancel( cancelflag == 2 );
-       on_update( *sub_details.back() );
+       if ( no_more_children )
+               // Adding a child after this OperationDetail has been set to prevent it is
+               // a programming bug.  However the best way to report it is by adding yet
+               // another child containing the bug report, and allowing the child to be
+               // added anyway.
+               add_child_implement( OperationDetail( "GParted Bug: Adding another child after 
no_more_children set "
+                                                     "on this OperationDetail",
+                                                     STATUS_ERROR, FONT_ITALIC ) );
+       add_child_implement( operationdetail );
 }
-       
+
 std::vector<OperationDetail*> & OperationDetail::get_childs()
 {
        return sub_details ;
@@ -179,6 +180,19 @@ void OperationDetail::stop_progressbar()
 
 // Private methods
 
+void OperationDetail::add_child_implement( const OperationDetail & operationdetail )
+{
+       sub_details .push_back( new OperationDetail( operationdetail ) );
+
+       sub_details.back()->set_treepath( treepath + ":" + Utils::num_to_str( sub_details .size() - 1 ) );
+       sub_details.back()->signal_update.connect( sigc::mem_fun( this, &OperationDetail::on_update ) );
+       sub_details.back()->cancelconnection = signal_cancel.connect(
+                               sigc::mem_fun( sub_details.back(), &OperationDetail::cancel ) );
+       if ( cancelflag )
+               sub_details.back()->cancel( cancelflag == 2 );
+       on_update( *sub_details.back() );
+}
+
 void OperationDetail::on_update( const OperationDetail & operationdetail ) 
 {
        if ( ! treepath .empty() )


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