Leave commands with progress bars shown in the applying dialog (#760709)

For non-progress tracked external commands the command being executed is
displayed in the Apply pending operations dialog, just below the top
pulsing progress bar.  However for progress tracked external commands
the description of the parent operation detail is displayed instead.

Example 1: non-progress tracked xfs check repair:

                                                               TreePath
    Check and repair file system (xfs) on /dev/sdc1            0
    + calibrate /dev/sdc1                                      0:0
    + check file system on /dev/sdc1 for errors and (if po...  0:1
      + xfs_repair -v /dev/sdc1                                0:1:0
        + [empty stdout]                                       0:1:0:0
        + [stderr]Phase 1 - find and verify superblock...      0:1:0:1

"xfs_repair -v /dev/sdc1" (TreePath 0:1:0) is shown because it is the
latest updated operation detail which is timed (set to status
executing).

Example 2: progress tracked ext4 copy using e2image:

                                                               TreePath
    Copy /dev/sdc2 to /dev/sdc3                                0
    + calibrate /dev/sdc2                                      0:0
    + check file system on /dev/sdc2 for errors and (if po...  0:1
    + set partition type on /dev/sdc3                          0:2
    + copy file system of /dev/sdc2 to /dev/sdc3               0:3
      + e2image -ra -p /dev/sdc2 /dev/sdc3                     0:3:0
        + [stdout]Scanning inodes...                           0:3:0:0
        + [stderr]e2image 1.42.9 (28-Dec-2013)...              0:3:0:1

"copy file system of /dev/sdc2 to /dev/sdc3" (TreePath 0:3) is shown
because that operation detail is also timed and it is being constantly
updated by the progress bar updates via it.

Change execute_command() to update the progress bar via the operation
detail it creates to hold the command being executed, instead of the
parent operation detail, to resolve the above.  Also replaces calling
operationdetail.get_last_child() throughout the method.

Bug 760709 - Add progress bars to XFS and EXT2/3/4 file system specific
             copy methods
This commit is contained in:
Mike Fleetwood 2016-02-08 20:02:42 +00:00 committed by Curtis Gedak
parent 075154b4e8
commit 2a55c65876
1 changed files with 12 additions and 14 deletions

View File

@ -110,6 +110,7 @@ int FileSystem::execute_command_internal( const Glib::ustring & command, Operati
TimedSlot timed_progress_slot ) TimedSlot timed_progress_slot )
{ {
operationdetail.add_child( OperationDetail( command, STATUS_EXECUTE, FONT_BOLD_ITALIC ) ); operationdetail.add_child( OperationDetail( command, STATUS_EXECUTE, FONT_BOLD_ITALIC ) );
OperationDetail & cmd_operationdetail = operationdetail.get_last_child();
Glib::Pid pid; Glib::Pid pid;
// set up pipes for capture // set up pipes for capture
int out, err; int out, err;
@ -127,8 +128,7 @@ int FileSystem::execute_command_internal( const Glib::ustring & command, Operati
&err ); &err );
} catch (Glib::SpawnError &e) { } catch (Glib::SpawnError &e) {
std::cerr << e.what() << std::endl; std::cerr << e.what() << std::endl;
operationdetail.get_last_child().add_child( cmd_operationdetail.add_child( OperationDetail( e.what(), STATUS_ERROR, FONT_ITALIC ) );
OperationDetail( e.what(), STATUS_ERROR, FONT_ITALIC ) );
return Utils::get_failure_status( e ); return Utils::get_failure_status( e );
} }
fcntl( out, F_SETFL, O_NONBLOCK ); fcntl( out, F_SETFL, O_NONBLOCK );
@ -141,11 +141,9 @@ int FileSystem::execute_command_internal( const Glib::ustring & command, Operati
PipeCapture errorcapture( err, error ); PipeCapture errorcapture( err, error );
outputcapture.signal_eof.connect( sigc::mem_fun( *this, &FileSystem::execute_command_eof ) ); outputcapture.signal_eof.connect( sigc::mem_fun( *this, &FileSystem::execute_command_eof ) );
errorcapture.signal_eof.connect( sigc::mem_fun( *this, &FileSystem::execute_command_eof ) ); errorcapture.signal_eof.connect( sigc::mem_fun( *this, &FileSystem::execute_command_eof ) );
operationdetail.get_last_child().add_child( cmd_operationdetail.add_child( OperationDetail( output, STATUS_NONE, FONT_ITALIC ) );
OperationDetail( output, STATUS_NONE, FONT_ITALIC ) ); cmd_operationdetail.add_child( OperationDetail( error, STATUS_NONE, FONT_ITALIC ) );
operationdetail.get_last_child().add_child( std::vector<OperationDetail*> &children = cmd_operationdetail.get_childs();
OperationDetail( error, STATUS_NONE, FONT_ITALIC ) );
std::vector<OperationDetail*> &children = operationdetail.get_last_child().get_childs();
outputcapture.signal_update.connect( sigc::bind( sigc::ptr_fun( update_command_output ), outputcapture.signal_update.connect( sigc::bind( sigc::ptr_fun( update_command_output ),
children[children.size() - 2], children[children.size() - 2],
&output ) ); &output ) );
@ -155,17 +153,17 @@ int FileSystem::execute_command_internal( const Glib::ustring & command, Operati
sigc::connection timed_conn; sigc::connection timed_conn;
if ( flags & EXEC_PROGRESS_STDOUT && ! stream_progress_slot.empty() ) if ( flags & EXEC_PROGRESS_STDOUT && ! stream_progress_slot.empty() )
// Call progress tracking callback when stdout updates // Call progress tracking callback when stdout updates
outputcapture.signal_update.connect( sigc::bind( stream_progress_slot, &operationdetail ) ); outputcapture.signal_update.connect( sigc::bind( stream_progress_slot, &cmd_operationdetail ) );
else if ( flags & EXEC_PROGRESS_STDERR && ! stream_progress_slot.empty() ) else if ( flags & EXEC_PROGRESS_STDERR && ! stream_progress_slot.empty() )
// Call progress tracking callback when stderr updates // Call progress tracking callback when stderr updates
errorcapture.signal_update.connect( sigc::bind( stream_progress_slot, &operationdetail ) ); errorcapture.signal_update.connect( sigc::bind( stream_progress_slot, &cmd_operationdetail ) );
else if ( flags & EXEC_PROGRESS_TIMED && ! timed_progress_slot.empty() ) else if ( flags & EXEC_PROGRESS_TIMED && ! timed_progress_slot.empty() )
// Call progress tracking callback every 500 ms // Call progress tracking callback every 500 ms
timed_conn = Glib::signal_timeout().connect( sigc::bind( timed_progress_slot, &operationdetail ), 500 ); timed_conn = Glib::signal_timeout().connect( sigc::bind( timed_progress_slot, &cmd_operationdetail ), 500 );
outputcapture.connect_signal(); outputcapture.connect_signal();
errorcapture.connect_signal(); errorcapture.connect_signal();
operationdetail.get_last_child().signal_cancel.connect( cmd_operationdetail.signal_cancel.connect(
sigc::bind( sigc::bind(
sigc::ptr_fun( cancel_command ), sigc::ptr_fun( cancel_command ),
pid, pid,
@ -175,15 +173,15 @@ int FileSystem::execute_command_internal( const Glib::ustring & command, Operati
if ( flags & EXEC_CHECK_STATUS ) if ( flags & EXEC_CHECK_STATUS )
{ {
if ( !exit_status ) if ( !exit_status )
operationdetail.get_last_child().set_status( STATUS_SUCCES ); cmd_operationdetail.set_status( STATUS_SUCCES );
else else
operationdetail.get_last_child().set_status( STATUS_ERROR ); cmd_operationdetail.set_status( STATUS_ERROR );
} }
close( out ); close( out );
close( err ); close( err );
if ( timed_conn.connected() ) if ( timed_conn.connected() )
timed_conn.disconnect(); timed_conn.disconnect();
operationdetail.stop_progressbar(); cmd_operationdetail.stop_progressbar();
return exit_status; return exit_status;
} }