From f8f9a72de699843a9a780f89d10d6ea615ed732b Mon Sep 17 00:00:00 2001 From: Mike Fleetwood Date: Sat, 25 Nov 2017 10:37:52 +0000 Subject: [PATCH] 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 372b0953..2fe4c5b7 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 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 a8fe3a17..3a703a85 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::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() )