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
This commit is contained in:
Mike Fleetwood 2017-11-25 10:37:52 +00:00 committed by Curtis Gedak
parent 3c1fdd14f4
commit f8f9a72de6
2 changed files with 31 additions and 13 deletions

View File

@ -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;
};

View File

@ -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() )